|
32 | 32 | BurpRawRequestResponse, FileUpload, Product_Type_Member, Product_Member, Dojo_Group, \
|
33 | 33 | Product_Group, Product_Type_Group, Role, Global_Role, Dojo_Group_Member, Engagement_Presets, Network_Locations, \
|
34 | 34 | UserContactInfo, Product_API_Scan_Configuration, Cred_Mapping, Cred_User, Question, Answer, \
|
35 |
| - Engagement_Survey, Answered_Survey, General_Survey |
| 35 | + Engagement_Survey, Answered_Survey, General_Survey, Check_List |
36 | 36 | from dojo.endpoint.views import get_endpoint_ids
|
37 | 37 | from dojo.reports.views import report_url_resolver, prefetch_related_findings_for_report
|
38 | 38 | from dojo.finding.views import set_finding_as_original_internal, reset_finding_duplicate_status_internal, \
|
@@ -258,7 +258,9 @@ class EngagementViewSet(prefetch.PrefetchListMixin,
|
258 | 258 | queryset = Engagement.objects.none()
|
259 | 259 | filter_backends = (DjangoFilterBackend,)
|
260 | 260 | filterset_class = ApiEngagementFilter
|
261 |
| - swagger_schema = prefetch.get_prefetch_schema(["engagements_list", "engagements_read"], serializers.EngagementSerializer).to_schema() |
| 261 | + swagger_schema = prefetch.get_prefetch_schema(["engagements_list", "engagements_read"], serializers.EngagementSerializer).composeWith( |
| 262 | + prefetch.get_prefetch_schema(["engagements_complete_checklist_read"], serializers.EngagementCheckListSerializer) |
| 263 | + ).to_schema() |
262 | 264 | permission_classes = (IsAuthenticated, permissions.UserHasEngagementPermission)
|
263 | 265 |
|
264 | 266 | @property
|
@@ -429,6 +431,41 @@ def files(self, request, pk=None):
|
429 | 431 | })
|
430 | 432 | return Response(serialized_files.data, status=status.HTTP_200_OK)
|
431 | 433 |
|
| 434 | + @extend_schema( |
| 435 | + methods=['POST'], |
| 436 | + request=serializers.EngagementCheckListSerializer, |
| 437 | + responses={status.HTTP_201_CREATED: serializers.EngagementCheckListSerializer} |
| 438 | + ) |
| 439 | + @swagger_auto_schema( |
| 440 | + method='post', |
| 441 | + request_body=serializers.EngagementCheckListSerializer, |
| 442 | + responses={status.HTTP_201_CREATED: serializers.EngagementCheckListSerializer} |
| 443 | + ) |
| 444 | + @action(detail=True, methods=["get", "post"]) |
| 445 | + def complete_checklist(self, request, pk=None): |
| 446 | + from dojo.api_v2.prefetch.prefetcher import _Prefetcher |
| 447 | + engagement = self.get_object() |
| 448 | + check_lists = Check_List.objects.filter(engagement=engagement) |
| 449 | + if request.method == 'POST': |
| 450 | + if check_lists.count() > 0: |
| 451 | + return Response({"message": "A completed checklist for this engagement already exists."}, status=status.HTTP_400_BAD_REQUEST) |
| 452 | + check_list = serializers.EngagementCheckListSerializer(data=request.data) |
| 453 | + if not check_list.is_valid(): |
| 454 | + return Response(check_list.errors, status=status.HTTP_400_BAD_REQUEST) |
| 455 | + check_list = Check_List(**check_list.data) |
| 456 | + check_list.engagement = engagement |
| 457 | + check_list.save() |
| 458 | + serialized_check_list = serializers.EngagementCheckListSerializer(check_list) |
| 459 | + return Response(serialized_check_list.data, status=status.HTTP_201_CREATED) |
| 460 | + prefetch_params = request.GET.get("prefetch", "").split(",") |
| 461 | + prefetcher = _Prefetcher() |
| 462 | + entry = check_lists.first() |
| 463 | + # Get the queried object representation |
| 464 | + result = serializers.EngagementCheckListSerializer(entry).data |
| 465 | + prefetcher._prefetch(entry, prefetch_params) |
| 466 | + result["prefetch"] = prefetcher.prefetched_data |
| 467 | + return Response(result, status=status.HTTP_200_OK) |
| 468 | + |
432 | 469 | @extend_schema(
|
433 | 470 | methods=['GET'],
|
434 | 471 | responses={
|
@@ -482,6 +519,35 @@ def get_queryset(self):
|
482 | 519 | 'owner',
|
483 | 520 | 'accepted_findings').distinct()
|
484 | 521 |
|
| 522 | + @extend_schema( |
| 523 | + methods=['GET'], |
| 524 | + responses={ |
| 525 | + status.HTTP_200_OK: serializers.RiskAcceptanceProofSerializer, |
| 526 | + } |
| 527 | + ) |
| 528 | + @swagger_auto_schema( |
| 529 | + method='get', |
| 530 | + responses={ |
| 531 | + status.HTTP_200_OK: serializers.RiskAcceptanceProofSerializer, |
| 532 | + } |
| 533 | + ) |
| 534 | + @action(detail=True, methods=["get"]) |
| 535 | + def download_proof(self, request, pk=None): |
| 536 | + risk_acceptance = self.get_object() |
| 537 | + # Get the file object |
| 538 | + file_object = risk_acceptance.path |
| 539 | + if file_object is None: |
| 540 | + return Response({"error": "Proof has not provided to this risk acceptance..."}, status=status.HTTP_404_NOT_FOUND) |
| 541 | + # Get the path of the file in media root |
| 542 | + file_path = f'{settings.MEDIA_ROOT}/{file_object.name}' |
| 543 | + file_handle = open(file_path, "rb") |
| 544 | + # send file |
| 545 | + response = FileResponse(file_handle, content_type=f'{mimetypes.guess_type(file_path)}', status=status.HTTP_200_OK) |
| 546 | + response['Content-Length'] = file_object.size |
| 547 | + response['Content-Disposition'] = f'attachment; filename="{risk_acceptance.filename()}"' |
| 548 | + |
| 549 | + return response |
| 550 | + |
485 | 551 |
|
486 | 552 | # These are technologies in the UI and the API!
|
487 | 553 | # Authorization: object-based
|
@@ -2770,6 +2836,25 @@ def get_queryset(self):
|
2770 | 2836 | return get_authorized_engagement_presets(Permissions.Product_View)
|
2771 | 2837 |
|
2772 | 2838 |
|
| 2839 | +class EngagementCheckListViewset(prefetch.PrefetchListMixin, |
| 2840 | + prefetch.PrefetchRetrieveMixin, |
| 2841 | + mixins.ListModelMixin, |
| 2842 | + mixins.RetrieveModelMixin, |
| 2843 | + mixins.UpdateModelMixin, |
| 2844 | + mixins.DestroyModelMixin, |
| 2845 | + mixins.CreateModelMixin, |
| 2846 | + viewsets.GenericViewSet, |
| 2847 | + dojo_mixins.DeletePreviewModelMixin): |
| 2848 | + serializer_class = serializers.EngagementCheckListSerializer |
| 2849 | + queryset = Check_List.objects.none() |
| 2850 | + filter_backends = (DjangoFilterBackend,) |
| 2851 | + swagger_schema = prefetch.get_prefetch_schema(["engagement_checklists_list", "engagement_checklists_read"], serializers.EngagementCheckListSerializer).to_schema() |
| 2852 | + permission_classes = (IsAuthenticated, permissions.UserHasEngagementPermission) |
| 2853 | + |
| 2854 | + def get_queryset(self): |
| 2855 | + return get_authorized_engagement_checklists(Permissions.Product_View) |
| 2856 | + |
| 2857 | + |
2773 | 2858 | class NetworkLocationsViewset(mixins.ListModelMixin,
|
2774 | 2859 | mixins.RetrieveModelMixin,
|
2775 | 2860 | mixins.UpdateModelMixin,
|
@@ -2811,7 +2896,7 @@ class QuestionnaireQuestionViewSet(mixins.ListModelMixin,
|
2811 | 2896 | mixins.RetrieveModelMixin,
|
2812 | 2897 | viewsets.GenericViewSet,
|
2813 | 2898 | dojo_mixins.QuestionSubClassFieldsMixin):
|
2814 |
| - serializer_class = serializers.QuestionSerializer |
| 2899 | + serializer_class = serializers.QuestionnaireQuestionSerializer |
2815 | 2900 | queryset = Question.objects.all()
|
2816 | 2901 | filter_backends = (DjangoFilterBackend,)
|
2817 | 2902 | permission_classes = (permissions.UserHasEngagementPermission, DjangoModelPermissions)
|
|
0 commit comments