From 182d1b14dcfdf99e58f5ec0e53c9affaf6a37d5c Mon Sep 17 00:00:00 2001 From: Cody Maffucci <46459665+Maffooch@users.noreply.github.com> Date: Mon, 9 Feb 2026 13:45:48 -0700 Subject: [PATCH 1/2] Fix response status codes in DojoMetaViewSet for POST and PATCH methods --- dojo/api_v2/views.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/dojo/api_v2/views.py b/dojo/api_v2/views.py index 15ba41e3d01..9bbe0d2df46 100644 --- a/dojo/api_v2/views.py +++ b/dojo/api_v2/views.py @@ -1707,10 +1707,12 @@ def batch(self, request, pk=None): if serialized_data.is_valid(raise_exception=True): if request.method == "POST": self.process_post(request.data) + status_code = status.HTTP_201_CREATED if request.method == "PATCH": self.process_patch(request.data) + status_code = status.HTTP_200_OK - return Response(status=status.HTTP_201_CREATED, data=serialized_data.data) + return Response(status=status_code, data=serialized_data.data) def process_post(self: object, data: dict): product = Product.objects.filter(id=data.get("product")).first() From a81a53e836aa5c03658aa99cf96657ddb699fada Mon Sep 17 00:00:00 2001 From: Cody Maffucci <46459665+Maffooch@users.noreply.github.com> Date: Mon, 9 Feb 2026 13:47:15 -0700 Subject: [PATCH 2/2] Refactor UserHasDojoMetaPermission to use a permission map for cleaner permission checks --- dojo/api_v2/permissions.py | 158 +++++++++++++++++-------------------- 1 file changed, 71 insertions(+), 87 deletions(-) diff --git a/dojo/api_v2/permissions.py b/dojo/api_v2/permissions.py index 2fdd1eb48f9..08dadc359ef 100644 --- a/dojo/api_v2/permissions.py +++ b/dojo/api_v2/permissions.py @@ -226,103 +226,87 @@ def has_object_permission(self, request, view, obj): class UserHasDojoMetaPermission(permissions.BasePermission): + permission_map = { + "product": { + "model": Product, + "permissions": { + "get_permission": Permissions.Product_View, + "put_permission": Permissions.Product_Edit, + "delete_permission": Permissions.Product_Edit, + "post_permission": Permissions.Product_Edit, + }, + }, + "finding": { + "model": Finding, + "permissions": { + "get_permission": Permissions.Finding_View, + "put_permission": Permissions.Finding_Edit, + "delete_permission": Permissions.Finding_Edit, + "post_permission": Permissions.Finding_Edit, + }, + }, + "location": { + "model": Location, + "permissions": { + "get_permission": Permissions.Location_View, + "put_permission": Permissions.Location_Edit, + "delete_permission": Permissions.Location_Edit, + "post_permission": Permissions.Location_Edit, + }, + }, + # TODO: Delete this after the move to Locations + "endpoint": { + "model": Endpoint if not settings.V3_FEATURE_LOCATIONS else Location, + "permissions": { + "get_permission": Permissions.Location_View, + "put_permission": Permissions.Location_Edit, + "delete_permission": Permissions.Location_Edit, + "post_permission": Permissions.Location_Edit, + }, + }, + } + def has_permission(self, request, view): - if request.method == "POST": - has_permission_result = True - product_id = request.data.get("product", None) - if product_id: - obj = get_object_or_404(Product, pk=product_id) - has_permission_result = ( - has_permission_result - and user_has_permission( - request.user, obj, Permissions.Product_Edit, - ) - ) - finding_id = request.data.get("finding", None) - if finding_id: - obj = get_object_or_404(Finding, pk=finding_id) - has_permission_result = ( - has_permission_result - and user_has_permission( - request.user, obj, Permissions.Finding_Edit, - ) - ) - location_id = request.data.get("location", None) - if location_id: - obj = get_object_or_404(Location, pk=location_id) - has_permission_result = ( - has_permission_result - and user_has_permission( - request.user, obj, Permissions.Location_Edit, - ) - ) - # TODO: Delete this after the move to Locations - endpoint_id = request.data.get("endpoint", None) - if endpoint_id: - if settings.V3_FEATURE_LOCATIONS: - obj = get_object_or_404(Location, pk=endpoint_id) - else: - obj = get_object_or_404(Endpoint, pk=endpoint_id) - has_permission_result = ( - has_permission_result - and user_has_permission( - request.user, obj, Permissions.Location_Edit, - ) - ) - return has_permission_result + method_to_permission_map = { + "GET": "get_permission", + "POST": "post_permission", + # PATCH is generally not used here, but this endpoint is sorta odd... + "PATCH": "put_permission", + } + for request_method, permission_type in method_to_permission_map.items(): + if request.method == request_method: + has_permission_result = True + for model_field, schema in self.permission_map.items(): + if (object_id := request.data.get(model_field)) is not None: + obj = get_object_or_404( + schema["model"], + pk=object_id, + ) + has_permission_result = ( + has_permission_result + and user_has_permission( + request.user, + obj, + schema["permissions"][permission_type], + ) + ) + return has_permission_result + # If we exit the loop at some point, we must not checking perms for that request method return True def has_object_permission(self, request, view, obj): has_permission_result = True - product = obj.product - if product: - has_permission_result = ( - has_permission_result - and check_object_permission( - request, - product, - Permissions.Product_View, - Permissions.Product_Edit, - Permissions.Product_Edit, - ) - ) - finding = obj.finding - if finding: - has_permission_result = ( - has_permission_result - and check_object_permission( - request, - finding, - Permissions.Finding_View, - Permissions.Finding_Edit, - Permissions.Finding_Edit, - ) - ) - location = obj.location - if location: - has_permission_result = ( - has_permission_result - and check_object_permission( - request, - location, - Permissions.Location_View, - Permissions.Location_Edit, - Permissions.Location_Edit, - ) - ) - # TODO: Delete this after the move to Locations - endpoint = obj.endpoint - if endpoint: - has_permission_result = ( + for model_field, schema in self.permission_map.items(): + if (object_model := getattr(obj, model_field, None)) is not None: + has_permission_result = ( has_permission_result and check_object_permission( request, - endpoint, - Permissions.Location_View, - Permissions.Location_Edit, - Permissions.Location_Edit, + object_model, + **schema["permissions"], ) ) + return has_permission_result