Skip to content

Commit 9b77bd0

Browse files
committed
Refactor permission classes to use asset and organization-specific permissions, enhancing clarity and maintainability.
1 parent 71ad98d commit 9b77bd0

3 files changed

Lines changed: 150 additions & 35 deletions

File tree

dojo/api_v2/permissions.py

Lines changed: 143 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -33,20 +33,10 @@
3333

3434
def check_post_permission(request: Request, post_model: Model, post_pk: str | list[str], post_permission: int) -> bool:
3535
if request.method == "POST":
36-
eligible_post_pk = None
37-
# Support both single PK string and list of PK strings
38-
searchable_post_pks = post_pk if isinstance(post_pk, list) else [post_pk]
39-
# Iterate until we find a matching PK in the request data
40-
for pk in searchable_post_pks:
41-
if request.data.get(pk) is not None:
42-
eligible_post_pk = pk
43-
break
44-
# Raise an error if we never find anything
45-
if eligible_post_pk is None:
46-
msg = f"Unable to check for permissions: No valid attribute in '{post_pk}' is required"
36+
if request.data.get(post_pk) is None:
37+
msg = f"Unable to check for permissions: Attribute '{post_pk}' is required"
4738
raise ParseError(msg)
48-
# Attempt to get the object
49-
obj = get_object_or_404(post_model, pk=request.data.get(eligible_post_pk))
39+
obj = get_object_or_404(post_model, pk=request.data.get(post_pk))
5040
return user_has_permission(request.user, obj, post_permission)
5141
return True
5242

@@ -73,7 +63,7 @@ def check_object_permission(
7363
class UserHasAppAnalysisPermission(permissions.BasePermission):
7464
def has_permission(self, request, view):
7565
return check_post_permission(
76-
request, Product, ["product", "asset"], Permissions.Technology_Add,
66+
request, Product, "product", Permissions.Technology_Add,
7767
)
7868

7969
def has_object_permission(self, request, view, obj):
@@ -90,7 +80,7 @@ class UserHasCredentialPermission(permissions.BasePermission):
9080
def has_permission(self, request, view):
9181
if request.data.get("product") is not None:
9282
return check_post_permission(
93-
request, Cred_Mapping, ["product", "asset"], Permissions.Credential_Add,
83+
request, Cred_Mapping, "product", Permissions.Credential_Add,
9484
)
9585
if request.data.get("engagement") is not None:
9686
return check_post_permission(
@@ -105,7 +95,7 @@ def has_permission(self, request, view):
10595
request, Cred_Mapping, "finding", Permissions.Credential_Add,
10696
)
10797
return check_post_permission(
108-
request, Cred_Mapping, ["product", "asset"], Permissions.Credential_Add,
98+
request, Cred_Mapping, "product", Permissions.Credential_Add,
10999
)
110100

111101
def has_object_permission(self, request, view, obj):
@@ -243,7 +233,7 @@ def has_object_permission(self, request, view, obj):
243233
class UserHasToolProductSettingsPermission(permissions.BasePermission):
244234
def has_permission(self, request, view):
245235
return check_post_permission(
246-
request, Product, ["product", "asset"], Permissions.Product_Edit,
236+
request, Product, "product", Permissions.Product_Edit,
247237
)
248238

249239
def has_object_permission(self, request, view, obj):
@@ -259,7 +249,7 @@ def has_object_permission(self, request, view, obj):
259249
class UserHasEndpointPermission(permissions.BasePermission):
260250
def has_permission(self, request, view):
261251
return check_post_permission(
262-
request, Product, ["product", "asset"], Permissions.Endpoint_Add,
252+
request, Product, "product", Permissions.Endpoint_Add,
263253
)
264254

265255
def has_object_permission(self, request, view, obj):
@@ -299,7 +289,7 @@ def has_permission(self, request, view):
299289
request.path,
300290
) or UserHasEngagementPermission.path_engagement.match(request.path):
301291
return check_post_permission(
302-
request, Product, ["product", "asset"], Permissions.Engagement_Add,
292+
request, Product, "product", Permissions.Engagement_Add,
303293
)
304294
# related object only need object permission
305295
return True
@@ -338,7 +328,7 @@ def has_permission(self, request, view):
338328
request.path,
339329
):
340330
return check_post_permission(
341-
request, Product, ["product", "asset"], Permissions.Risk_Acceptance,
331+
request, Product, "product", Permissions.Risk_Acceptance,
342332
)
343333
# related object only need object permission
344334
return True
@@ -505,7 +495,26 @@ def has_permission(self, request, view):
505495
return check_post_permission(
506496
request,
507497
Product_Type,
508-
["prod_type", "organization"],
498+
"prod_type",
499+
Permissions.Product_Type_Add_Product,
500+
)
501+
502+
def has_object_permission(self, request, view, obj):
503+
return check_object_permission(
504+
request,
505+
obj,
506+
Permissions.Product_View,
507+
Permissions.Product_Edit,
508+
Permissions.Product_Delete,
509+
)
510+
511+
512+
class UserHasAssetPermission(permissions.BasePermission):
513+
def has_permission(self, request, view):
514+
return check_post_permission(
515+
request,
516+
Product_Type,
517+
"organization",
509518
Permissions.Product_Type_Add_Product,
510519
)
511520

@@ -522,7 +531,23 @@ def has_object_permission(self, request, view, obj):
522531
class UserHasProductMemberPermission(permissions.BasePermission):
523532
def has_permission(self, request, view):
524533
return check_post_permission(
525-
request, Product, ["product", "asset"], Permissions.Product_Manage_Members,
534+
request, Product, "product", Permissions.Product_Manage_Members,
535+
)
536+
537+
def has_object_permission(self, request, view, obj):
538+
return check_object_permission(
539+
request,
540+
obj,
541+
Permissions.Product_View,
542+
Permissions.Product_Manage_Members,
543+
Permissions.Product_Member_Delete,
544+
)
545+
546+
547+
class UserHasAssetMemberPermission(permissions.BasePermission):
548+
def has_permission(self, request, view):
549+
return check_post_permission(
550+
request, Product, "asset", Permissions.Product_Manage_Members,
526551
)
527552

528553
def has_object_permission(self, request, view, obj):
@@ -538,7 +563,23 @@ def has_object_permission(self, request, view, obj):
538563
class UserHasProductGroupPermission(permissions.BasePermission):
539564
def has_permission(self, request, view):
540565
return check_post_permission(
541-
request, Product, ["product", "asset"], Permissions.Product_Group_Add,
566+
request, Product, "product", Permissions.Product_Group_Add,
567+
)
568+
569+
def has_object_permission(self, request, view, obj):
570+
return check_object_permission(
571+
request,
572+
obj,
573+
Permissions.Product_Group_View,
574+
Permissions.Product_Group_Edit,
575+
Permissions.Product_Group_Delete,
576+
)
577+
578+
579+
class UserHasAssetGroupPermission(permissions.BasePermission):
580+
def has_permission(self, request, view):
581+
return check_post_permission(
582+
request, Product, "asset", Permissions.Product_Group_Add,
542583
)
543584

544585
def has_object_permission(self, request, view, obj):
@@ -569,12 +610,49 @@ def has_object_permission(self, request, view, obj):
569610
)
570611

571612

613+
class UserHasOrganizationPermission(permissions.BasePermission):
614+
def has_permission(self, request, view):
615+
if request.method == "POST":
616+
return user_has_global_permission(
617+
request.user, Permissions.Product_Type_Add,
618+
)
619+
return True
620+
621+
def has_object_permission(self, request, view, obj):
622+
return check_object_permission(
623+
request,
624+
obj,
625+
Permissions.Product_Type_View,
626+
Permissions.Product_Type_Edit,
627+
Permissions.Product_Type_Delete,
628+
)
629+
630+
572631
class UserHasProductTypeMemberPermission(permissions.BasePermission):
573632
def has_permission(self, request, view):
574633
return check_post_permission(
575634
request,
576635
Product_Type,
577-
["product_type", "organization"],
636+
"product_type",
637+
Permissions.Product_Type_Manage_Members,
638+
)
639+
640+
def has_object_permission(self, request, view, obj):
641+
return check_object_permission(
642+
request,
643+
obj,
644+
Permissions.Product_Type_View,
645+
Permissions.Product_Type_Manage_Members,
646+
Permissions.Product_Type_Member_Delete,
647+
)
648+
649+
650+
class UserHasOrganizationMemberPermission(permissions.BasePermission):
651+
def has_permission(self, request, view):
652+
return check_post_permission(
653+
request,
654+
Product_Type,
655+
"organization",
578656
Permissions.Product_Type_Manage_Members,
579657
)
580658

@@ -593,7 +671,25 @@ def has_permission(self, request, view):
593671
return check_post_permission(
594672
request,
595673
Product_Type,
596-
["product_type", "organization"],
674+
"product_type",
675+
Permissions.Product_Type_Group_Add,
676+
)
677+
678+
def has_object_permission(self, request, view, obj):
679+
return check_object_permission(
680+
request,
681+
obj,
682+
Permissions.Product_Type_Group_View,
683+
Permissions.Product_Type_Group_Edit,
684+
Permissions.Product_Type_Group_Delete,
685+
)
686+
687+
class UserHasOrganizationGroupPermission(permissions.BasePermission):
688+
def has_permission(self, request, view):
689+
return check_post_permission(
690+
request,
691+
Product_Type,
692+
"organization",
597693
Permissions.Product_Type_Group_Add,
598694
)
599695

@@ -719,7 +815,7 @@ def has_object_permission(self, request, view, obj):
719815
class UserHasLanguagePermission(permissions.BasePermission):
720816
def has_permission(self, request, view):
721817
return check_post_permission(
722-
request, Product, ["product", "asset"], Permissions.Language_Add,
818+
request, Product, "product", Permissions.Language_Add,
723819
)
724820

725821
def has_object_permission(self, request, view, obj):
@@ -737,7 +833,26 @@ def has_permission(self, request, view):
737833
return check_post_permission(
738834
request,
739835
Product,
740-
["product", "asset"],
836+
"product",
837+
Permissions.Product_API_Scan_Configuration_Add,
838+
)
839+
840+
def has_object_permission(self, request, view, obj):
841+
return check_object_permission(
842+
request,
843+
obj,
844+
Permissions.Product_API_Scan_Configuration_View,
845+
Permissions.Product_API_Scan_Configuration_Edit,
846+
Permissions.Product_API_Scan_Configuration_Delete,
847+
)
848+
849+
850+
class UserHasAssetAPIScanConfigurationPermission(permissions.BasePermission):
851+
def has_permission(self, request, view):
852+
return check_post_permission(
853+
request,
854+
Product,
855+
"asset",
741856
Permissions.Product_API_Scan_Configuration_Add,
742857
)
743858

@@ -893,7 +1008,7 @@ def has_permission(self, request, view):
8931008
class UserHasEngagementPresetPermission(permissions.BasePermission):
8941009
def has_permission(self, request, view):
8951010
return check_post_permission(
896-
request, Product, ["product", "asset"], Permissions.Product_Edit,
1011+
request, Product, "product", Permissions.Product_Edit,
8971012
)
8981013

8991014
def has_object_permission(self, request, view, obj):

dojo/asset/api/views.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ class AssetAPIScanConfigurationViewSet(
4343
filterset_class = AssetAPIScanConfigurationFilterSet
4444
permission_classes = (
4545
IsAuthenticated,
46-
permissions.UserHasProductAPIScanConfigurationPermission,
46+
permissions.UserHasAssetAPIScanConfigurationPermission,
4747
)
4848

4949
def get_queryset(self):
@@ -68,7 +68,7 @@ class AssetViewSet(
6868
filterset_class = ApiAssetFilter
6969
permission_classes = (
7070
IsAuthenticated,
71-
permissions.UserHasProductPermission,
71+
permissions.UserHasAssetPermission,
7272
)
7373

7474
def get_queryset(self):
@@ -138,7 +138,7 @@ class AssetMemberViewSet(
138138
filterset_class = AssetMemberFilterSet
139139
permission_classes = (
140140
IsAuthenticated,
141-
permissions.UserHasProductMemberPermission,
141+
permissions.UserHasAssetMemberPermission,
142142
)
143143

144144
def get_queryset(self):
@@ -166,7 +166,7 @@ class AssetGroupViewSet(
166166
filterset_class = AssetGroupFilterSet
167167
permission_classes = (
168168
IsAuthenticated,
169-
permissions.UserHasProductGroupPermission,
169+
permissions.UserHasAssetGroupPermission,
170170
)
171171

172172
def get_queryset(self):

dojo/organization/api/views.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ class OrganizationViewSet(
4040
filterset_class = OrganizationFilterSet
4141
permission_classes = (
4242
IsAuthenticated,
43-
permissions.UserHasProductTypePermission,
43+
permissions.UserHasOrganizationPermission,
4444
)
4545

4646
def get_queryset(self):
@@ -121,7 +121,7 @@ class OrganizationMemberViewSet(
121121
filterset_class = OrganizationMemberFilterSet
122122
permission_classes = (
123123
IsAuthenticated,
124-
permissions.UserHasProductTypeMemberPermission,
124+
permissions.UserHasOrganizationMemberPermission,
125125
)
126126

127127
def get_queryset(self):
@@ -163,7 +163,7 @@ class OrganizationGroupViewSet(
163163
filterset_class = OrganizationGroupFilterSet
164164
permission_classes = (
165165
IsAuthenticated,
166-
permissions.UserHasProductTypeGroupPermission,
166+
permissions.UserHasOrganizationGroupPermission,
167167
)
168168

169169
def get_queryset(self):

0 commit comments

Comments
 (0)