Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 27 additions & 0 deletions docs/content/releases/os_upgrading/2.56.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
---
title: 'Upgrading to DefectDojo Version 2.56.x'
toc_hide: true
weight: -20260215
description: Deprecation of Questionnaire API Endpoints
---

## Deprecation: Questionnaire API Endpoints

The following Questionnaire API endpoints are being deprecated and will be removed in DefectDojo 2.59.0 on June 1st, 2026:

- `/api/v2/questionnaire_answered_questionnaires/`
- `/api/v2/questionnaire_answers/`
- `/api/v2/questionnaire_engagement_questionnaires/`
- `/api/v2/questionnaire_general_questionnaires/`
- `/api/v2/questionnaire_questions`

### Required Actions

Support for these endpoints will be fully removed in DefectDojo 2.59.0 (scheduled for June 1st, 2026). After this date, any requests to these endpoints will return a 404 Not Found error.

### Timeline

- **DefectDojo 2.56.x onwards**: Endpoints are deprecated with deprecation headers
- **DefectDojo 2.59.0 (June 1st, 2026)**: Endpoints will be removed entirely

For more information, check the [Release Notes](https://github.com/DefectDojo/django-DefectDojo/releases/tag/2.56.0).
22 changes: 22 additions & 0 deletions docs/content/releases/os_upgrading/2.59.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
---
title: 'Upgrading to DefectDojo Version 2.59.x'
toc_hide: true
weight: -20260602
description: Removal of Questionnaire API Endpoints
---

## Removal: Questionnaire API Endpoints

As announced in DefectDojo 2.56.0, the following Questionnaire API endpoints have been removed:

- `/api/v2/questionnaire_answered_questionnaires/`
- `/api/v2/questionnaire_answers/`
- `/api/v2/questionnaire_engagement_questionnaires/`
- `/api/v2/questionnaire_general_questionnaires/`
- `/api/v2/questionnaire_questions`

### Required Actions

Any requests to these endpoints will now return a 404 Not Found error.

For more information, check the [Release Notes](https://github.com/DefectDojo/django-DefectDojo/releases/tag/2.59.0).
114 changes: 107 additions & 7 deletions dojo/api_v2/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -242,6 +242,19 @@ class PrefetchDojoModelViewSet(
pass


class DeprecationNoticeMixin:

deprecated: bool | None = None
end_of_life_date: datetime | None = None

def finalize_response(self, request, response, *args, **kwargs):
if self.deprecated is not None:
response["X-Deprecated"] = self.deprecated
if self.end_of_life_date is not None:
response["X-End-Of-Life-Date"] = self.end_of_life_date.isoformat()
return super().finalize_response(request, response, *args, **kwargs)


# Authorization: authenticated users
class RoleViewSet(viewsets.ReadOnlyModelViewSet):
serializer_class = serializers.RoleSerializer
Expand Down Expand Up @@ -3171,7 +3184,10 @@ def get_queryset(self):
class QuestionnaireQuestionViewSet(
viewsets.ReadOnlyModelViewSet,
dojo_mixins.QuestionSubClassFieldsMixin,
DeprecationNoticeMixin,
):
deprecated = True
end_of_life_date = datetime(2026, 6, 1)
serializer_class = serializers.QuestionnaireQuestionSerializer
queryset = Question.objects.none()
filter_backends = (DjangoFilterBackend,)
Expand All @@ -3183,11 +3199,28 @@ class QuestionnaireQuestionViewSet(
def get_queryset(self):
return Question.objects.all().order_by("id")

@extend_schema(
deprecated=True,
description="This endpoint is deprecated and will be removed on 2026-06-01.",
)
def list(self, request, *args, **kwargs):
return super().list(request, *args, **kwargs)

@extend_schema(
deprecated=True,
description="This endpoint is deprecated and will be removed on 2026-06-01.",
)
def retrieve(self, request, *args, **kwargs):
return super().retrieve(request, *args, **kwargs)


class QuestionnaireAnswerViewSet(
viewsets.ReadOnlyModelViewSet,
dojo_mixins.AnswerSubClassFieldsMixin,
DeprecationNoticeMixin,
):
deprecated = True
end_of_life_date = datetime(2026, 6, 1)
serializer_class = serializers.QuestionnaireAnswerSerializer
queryset = Answer.objects.none()
filter_backends = (DjangoFilterBackend,)
Expand All @@ -3199,10 +3232,27 @@ class QuestionnaireAnswerViewSet(
def get_queryset(self):
return Answer.objects.all().order_by("id")

@extend_schema(
deprecated=True,
description="This endpoint is deprecated and will be removed on 2026-06-01.",
)
def list(self, request, *args, **kwargs):
return super().list(request, *args, **kwargs)

@extend_schema(
deprecated=True,
description="This endpoint is deprecated and will be removed on 2026-06-01.",
)
def retrieve(self, request, *args, **kwargs):
return super().retrieve(request, *args, **kwargs)


class QuestionnaireGeneralSurveyViewSet(
viewsets.ReadOnlyModelViewSet,
DeprecationNoticeMixin,
):
deprecated = True
end_of_life_date = datetime(2026, 6, 1)
serializer_class = serializers.QuestionnaireGeneralSurveySerializer
queryset = General_Survey.objects.none()
filter_backends = (DjangoFilterBackend,)
Expand All @@ -3214,10 +3264,27 @@ class QuestionnaireGeneralSurveyViewSet(
def get_queryset(self):
return General_Survey.objects.all().order_by("id")

@extend_schema(
deprecated=True,
description="This endpoint is deprecated and will be removed on 2026-06-01.",
)
def list(self, request, *args, **kwargs):
return super().list(request, *args, **kwargs)

@extend_schema(
deprecated=True,
description="This endpoint is deprecated and will be removed on 2026-06-01.",
)
def retrieve(self, request, *args, **kwargs):
return super().retrieve(request, *args, **kwargs)


class QuestionnaireEngagementSurveyViewSet(
viewsets.ReadOnlyModelViewSet,
DeprecationNoticeMixin,
):
deprecated = True
end_of_life_date = datetime(2026, 6, 1)
serializer_class = serializers.QuestionnaireEngagementSurveySerializer
queryset = Engagement_Survey.objects.none()
filter_backends = (DjangoFilterBackend,)
Expand All @@ -3230,13 +3297,29 @@ def get_queryset(self):
return Engagement_Survey.objects.all().order_by("id")

@extend_schema(
request=OpenApiTypes.NONE,
parameters=[
OpenApiParameter(
"engagement_id", OpenApiTypes.INT, OpenApiParameter.PATH,
),
],
responses={status.HTTP_200_OK: serializers.QuestionnaireAnsweredSurveySerializer},
deprecated=True,
description="This endpoint is deprecated and will be removed on 2026-06-01.",
)
def list(self, request, *args, **kwargs):
return super().list(request, *args, **kwargs)

@extend_schema(
deprecated=True,
description="This endpoint is deprecated and will be removed on 2026-06-01.",
)
def retrieve(self, request, *args, **kwargs):
return super().retrieve(request, *args, **kwargs)

@extend_schema(
deprecated=True,
description="This endpoint is deprecated and will be removed on 2026-06-01.",
request=OpenApiTypes.NONE,
parameters=[
OpenApiParameter(
"engagement_id", OpenApiTypes.INT, OpenApiParameter.PATH,
),
],
responses={status.HTTP_200_OK: serializers.QuestionnaireAnsweredSurveySerializer},
)
@action(
detail=True, methods=["post"], url_path=r"link_engagement/(?P<engagement_id>\d+)",
Expand All @@ -3258,7 +3341,10 @@ class QuestionnaireAnsweredSurveyViewSet(
prefetch.PrefetchListMixin,
prefetch.PrefetchRetrieveMixin,
viewsets.ReadOnlyModelViewSet,
DeprecationNoticeMixin,
):
deprecated = True
end_of_life_date = datetime(2026, 6, 1)
serializer_class = serializers.QuestionnaireAnsweredSurveySerializer
queryset = Answered_Survey.objects.none()
filter_backends = (DjangoFilterBackend,)
Expand All @@ -3270,6 +3356,20 @@ class QuestionnaireAnsweredSurveyViewSet(
def get_queryset(self):
return Answered_Survey.objects.all().order_by("id")

@extend_schema(
deprecated=True,
description="This endpoint is deprecated and will be removed on 2026-06-01.",
)
def list(self, request, *args, **kwargs):
return super().list(request, *args, **kwargs)

@extend_schema(
deprecated=True,
description="This endpoint is deprecated and will be removed on 2026-06-01.",
)
def retrieve(self, request, *args, **kwargs):
return super().retrieve(request, *args, **kwargs)


# Authorization: configuration
class AnnouncementViewSet(
Expand Down