11import re
2+ from collections .abc import Iterable
23
4+ from django .db .models import Model
35from django .shortcuts import get_object_or_404
46from rest_framework import permissions , serializers
57from rest_framework .exceptions import (
68 ParseError ,
79 PermissionDenied ,
810 ValidationError ,
911)
12+ from rest_framework .request import Request
1013
1114from dojo .authorization .authorization import (
1215 user_has_configuration_permission ,
2932)
3033
3134
32- def check_post_permission (request , post_model , post_pk , post_permission ) :
35+ def check_post_permission (request : Request , post_model : Model , post_pk : str | Iterable [ str ] , post_permission : int ) -> bool :
3336 if request .method == "POST" :
34- if request .data .get (post_pk ) is None :
35- msg = f"Unable to check for permissions: Attribute '{ post_pk } ' is required"
37+ eligible_post_pk = None
38+ # Support both single PK string and list of PK strings
39+ searchable_post_pks = post_pk if isinstance (post_pk , Iterable ) else [post_pk ]
40+ # Iterate until we find a matching PK in the request data
41+ for pk in searchable_post_pks :
42+ if request .data .get (pk ) is not None :
43+ eligible_post_pk = pk
44+ break
45+ # Raise an error if we never find anything
46+ if eligible_post_pk is None :
47+ msg = f"Unable to check for permissions: No valid attribute in '{ post_pk } ' is required"
3648 raise ParseError (msg )
37- obj = get_object_or_404 (post_model , pk = request .data .get (post_pk ))
49+ # Attempt to get the object
50+ obj = get_object_or_404 (post_model , pk = request .data .get (eligible_post_pk ))
3851 return user_has_permission (request .user , obj , post_permission )
3952 return True
4053
4154
4255def check_object_permission (
43- request ,
44- obj ,
45- get_permission ,
46- put_permission ,
47- delete_permission ,
48- post_permission = None ,
49- ):
56+ request : Request ,
57+ obj : Model ,
58+ get_permission : int ,
59+ put_permission : int ,
60+ delete_permission : int ,
61+ post_permission : int | None = None ,
62+ ) -> bool :
5063 if request .method == "GET" :
5164 return user_has_permission (request .user , obj , get_permission )
5265 if request .method in {"PUT" , "PATCH" }:
@@ -61,7 +74,7 @@ def check_object_permission(
6174class UserHasAppAnalysisPermission (permissions .BasePermission ):
6275 def has_permission (self , request , view ):
6376 return check_post_permission (
64- request , Product , "product" , Permissions .Technology_Add ,
77+ request , Product , [ "product" , "asset" ] , Permissions .Technology_Add ,
6578 )
6679
6780 def has_object_permission (self , request , view , obj ):
@@ -78,7 +91,7 @@ class UserHasCredentialPermission(permissions.BasePermission):
7891 def has_permission (self , request , view ):
7992 if request .data .get ("product" ) is not None :
8093 return check_post_permission (
81- request , Cred_Mapping , "product" , Permissions .Credential_Add ,
94+ request , Cred_Mapping , [ "product" , "asset" ] , Permissions .Credential_Add ,
8295 )
8396 if request .data .get ("engagement" ) is not None :
8497 return check_post_permission (
@@ -93,7 +106,7 @@ def has_permission(self, request, view):
93106 request , Cred_Mapping , "finding" , Permissions .Credential_Add ,
94107 )
95108 return check_post_permission (
96- request , Cred_Mapping , "product" , Permissions .Credential_Add ,
109+ request , Cred_Mapping , [ "product" , "asset" ] , Permissions .Credential_Add ,
97110 )
98111
99112 def has_object_permission (self , request , view , obj ):
@@ -231,7 +244,7 @@ def has_object_permission(self, request, view, obj):
231244class UserHasToolProductSettingsPermission (permissions .BasePermission ):
232245 def has_permission (self , request , view ):
233246 return check_post_permission (
234- request , Product , "product" , Permissions .Product_Edit ,
247+ request , Product , [ "product" , "asset" ] , Permissions .Product_Edit ,
235248 )
236249
237250 def has_object_permission (self , request , view , obj ):
@@ -247,7 +260,7 @@ def has_object_permission(self, request, view, obj):
247260class UserHasEndpointPermission (permissions .BasePermission ):
248261 def has_permission (self , request , view ):
249262 return check_post_permission (
250- request , Product , "product" , Permissions .Endpoint_Add ,
263+ request , Product , [ "product" , "asset" ] , Permissions .Endpoint_Add ,
251264 )
252265
253266 def has_object_permission (self , request , view , obj ):
@@ -287,7 +300,7 @@ def has_permission(self, request, view):
287300 request .path ,
288301 ) or UserHasEngagementPermission .path_engagement .match (request .path ):
289302 return check_post_permission (
290- request , Product , "product" , Permissions .Engagement_Add ,
303+ request , Product , [ "product" , "asset" ] , Permissions .Engagement_Add ,
291304 )
292305 # related object only need object permission
293306 return True
@@ -326,7 +339,7 @@ def has_permission(self, request, view):
326339 request .path ,
327340 ):
328341 return check_post_permission (
329- request , Product , "product" , Permissions .Risk_Acceptance ,
342+ request , Product , [ "product" , "asset" ] , Permissions .Risk_Acceptance ,
330343 )
331344 # related object only need object permission
332345 return True
@@ -493,7 +506,7 @@ def has_permission(self, request, view):
493506 return check_post_permission (
494507 request ,
495508 Product_Type ,
496- "prod_type" ,
509+ [ "prod_type" , "organization" ] ,
497510 Permissions .Product_Type_Add_Product ,
498511 )
499512
@@ -510,7 +523,7 @@ def has_object_permission(self, request, view, obj):
510523class UserHasProductMemberPermission (permissions .BasePermission ):
511524 def has_permission (self , request , view ):
512525 return check_post_permission (
513- request , Product , "product" , Permissions .Product_Manage_Members ,
526+ request , Product , [ "product" , "asset" ] , Permissions .Product_Manage_Members ,
514527 )
515528
516529 def has_object_permission (self , request , view , obj ):
@@ -526,7 +539,7 @@ def has_object_permission(self, request, view, obj):
526539class UserHasProductGroupPermission (permissions .BasePermission ):
527540 def has_permission (self , request , view ):
528541 return check_post_permission (
529- request , Product , "product" , Permissions .Product_Group_Add ,
542+ request , Product , [ "product" , "asset" ] , Permissions .Product_Group_Add ,
530543 )
531544
532545 def has_object_permission (self , request , view , obj ):
@@ -562,7 +575,7 @@ def has_permission(self, request, view):
562575 return check_post_permission (
563576 request ,
564577 Product_Type ,
565- "product_type" ,
578+ [ "product_type" , "organization" ] ,
566579 Permissions .Product_Type_Manage_Members ,
567580 )
568581
@@ -581,7 +594,7 @@ def has_permission(self, request, view):
581594 return check_post_permission (
582595 request ,
583596 Product_Type ,
584- "product_type" ,
597+ [ "product_type" , "organization" ] ,
585598 Permissions .Product_Type_Group_Add ,
586599 )
587600
@@ -707,7 +720,7 @@ def has_object_permission(self, request, view, obj):
707720class UserHasLanguagePermission (permissions .BasePermission ):
708721 def has_permission (self , request , view ):
709722 return check_post_permission (
710- request , Product , "product" , Permissions .Language_Add ,
723+ request , Product , [ "product" , "asset" ] , Permissions .Language_Add ,
711724 )
712725
713726 def has_object_permission (self , request , view , obj ):
@@ -725,7 +738,7 @@ def has_permission(self, request, view):
725738 return check_post_permission (
726739 request ,
727740 Product ,
728- "product" ,
741+ [ "product" , "asset" ] ,
729742 Permissions .Product_API_Scan_Configuration_Add ,
730743 )
731744
@@ -881,7 +894,7 @@ def has_permission(self, request, view):
881894class UserHasEngagementPresetPermission (permissions .BasePermission ):
882895 def has_permission (self , request , view ):
883896 return check_post_permission (
884- request , Product , "product" , Permissions .Product_Edit ,
897+ request , Product , [ "product" , "asset" ] , Permissions .Product_Edit ,
885898 )
886899
887900 def has_object_permission (self , request , view , obj ):
0 commit comments