|
19 | 19 | from dojo.importers.auto_create_context import AutoCreateContextManager |
20 | 20 | from dojo.models import ( |
21 | 21 | Cred_Mapping, |
| 22 | + Development_Environment, |
22 | 23 | Dojo_Group, |
23 | 24 | Endpoint, |
24 | 25 | Engagement, |
25 | 26 | Finding, |
26 | 27 | Finding_Group, |
27 | 28 | Product, |
28 | 29 | Product_Type, |
| 30 | + Regulation, |
| 31 | + SLA_Configuration, |
29 | 32 | Test, |
30 | 33 | ) |
31 | 34 |
|
@@ -59,6 +62,71 @@ def check_object_permission( |
59 | 62 | return False |
60 | 63 |
|
61 | 64 |
|
| 65 | +class BaseRelatedObjectPermission(permissions.BasePermission): |
| 66 | + |
| 67 | + """ |
| 68 | + An "abstract" base class for related object permissions (like notes, metadata, etc.) |
| 69 | + that only need object permissions, not general permissions. This class will serve as |
| 70 | + the base class for other more aptly named permission classes. |
| 71 | + """ |
| 72 | + |
| 73 | + permission_map: dict[str, int] = { |
| 74 | + "get_permission": None, |
| 75 | + "put_permission": None, |
| 76 | + "delete_permission": None, |
| 77 | + "post_permission": None, |
| 78 | + } |
| 79 | + |
| 80 | + def has_permission(self, request: Request, view): |
| 81 | + # related object only need object permission |
| 82 | + return True |
| 83 | + |
| 84 | + def has_object_permission(self, request: Request, view, obj): |
| 85 | + return check_object_permission( |
| 86 | + request, |
| 87 | + obj, |
| 88 | + **self.permission_map, |
| 89 | + ) |
| 90 | + |
| 91 | + |
| 92 | +class BaseDjangoModelPermission(permissions.BasePermission): |
| 93 | + |
| 94 | + """ |
| 95 | + An "abstract" base class for Django model permissions. |
| 96 | + This class will serve as the base class for other more aptly named permission classes. |
| 97 | + """ |
| 98 | + |
| 99 | + django_model: Model = None |
| 100 | + request_method_permission_map: dict[str, str] = { |
| 101 | + "GET": "view", |
| 102 | + "POST": "add", |
| 103 | + "PUT": "change", |
| 104 | + "PATCH": "change", |
| 105 | + "DELETE": "delete", |
| 106 | + } |
| 107 | + |
| 108 | + def _evaluate_permissions(self, request: Request, permissions: dict[str, str]) -> bool: |
| 109 | + for method, permission in permissions.items(): |
| 110 | + if request.method == method: |
| 111 | + return user_has_configuration_permission( |
| 112 | + request.user, |
| 113 | + f"{self.django_model._meta.app_label}.{permission}_{self.django_model._meta.model_name}", |
| 114 | + ) |
| 115 | + return False |
| 116 | + |
| 117 | + def has_permission(self, request: Request, view): |
| 118 | + # First restrict the mapping got GET/POST only |
| 119 | + expected_request_method_permission_map = {k: v for k, v in self.request_method_permission_map.items() if k in {"GET", "POST"}} |
| 120 | + # Short circuit if the request method is not in the expected methods |
| 121 | + if request.method not in expected_request_method_permission_map: |
| 122 | + return True |
| 123 | + # Evaluate the permissions |
| 124 | + return self._evaluate_permissions(request, expected_request_method_permission_map) |
| 125 | + |
| 126 | + def has_object_permission(self, request: Request, view, obj): |
| 127 | + return self._evaluate_permissions(request, self.request_method_permission_map) |
| 128 | + |
| 129 | + |
62 | 130 | class UserHasAppAnalysisPermission(permissions.BasePermission): |
63 | 131 | def has_permission(self, request, view): |
64 | 132 | return check_post_permission( |
@@ -277,33 +345,6 @@ def has_object_permission(self, request, view, obj): |
277 | 345 | ) |
278 | 346 |
|
279 | 347 |
|
280 | | -class BaseRelatedObjectPermission(permissions.BasePermission): |
281 | | - |
282 | | - """ |
283 | | - An "abstract" base class for related object permissions (like notes, metadata, etc.) |
284 | | - that only need object permissions, not general permissions. This class will serve as |
285 | | - the base class for other more aptly named permission classes. |
286 | | - """ |
287 | | - |
288 | | - permission_map = { |
289 | | - "get_permission": None, |
290 | | - "put_permission": None, |
291 | | - "delete_permission": None, |
292 | | - "post_permission": None, |
293 | | - } |
294 | | - |
295 | | - def has_permission(self, request, view): |
296 | | - # related object only need object permission |
297 | | - return True |
298 | | - |
299 | | - def has_object_permission(self, request, view, obj): |
300 | | - return check_object_permission( |
301 | | - request, |
302 | | - obj, |
303 | | - **self.permission_map, |
304 | | - ) |
305 | | - |
306 | | - |
307 | 348 | class UserHasEngagementPermission(permissions.BasePermission): |
308 | 349 | def has_permission(self, request, view): |
309 | 350 | return check_post_permission( |
@@ -987,6 +1028,36 @@ def has_object_permission(self, request, view, obj): |
987 | 1028 | ) |
988 | 1029 |
|
989 | 1030 |
|
| 1031 | +class UserHasSLAPermission(BaseDjangoModelPermission): |
| 1032 | + django_model = SLA_Configuration |
| 1033 | + |
| 1034 | + |
| 1035 | +class UserHasDevelopmentEnvironmentPermission(BaseDjangoModelPermission): |
| 1036 | + django_model = Development_Environment |
| 1037 | + # https://github.com/DefectDojo/django-DefectDojo/blob/963d4a35bfd8f5138330f0d70595a755fa4999b0/dojo/user/utils.py#L93 |
| 1038 | + # It looks like view permission was explicitly not supported, so I assume |
| 1039 | + # reading these endpoints are not necessarily restricted (unless you're auth'd of course) |
| 1040 | + request_method_permission_map = { |
| 1041 | + "POST": "add", |
| 1042 | + "PUT": "change", |
| 1043 | + "PATCH": "change", |
| 1044 | + "DELETE": "delete", |
| 1045 | + } |
| 1046 | + |
| 1047 | + |
| 1048 | +class UserHasRegulationPermission(BaseDjangoModelPermission): |
| 1049 | + django_model = Regulation |
| 1050 | + # https://github.com/DefectDojo/django-DefectDojo/blob/963d4a35bfd8f5138330f0d70595a755fa4999b0/dojo/user/utils.py#L104 |
| 1051 | + # It looks like view permission was explicitly not supported, so I assume |
| 1052 | + # reading these endpoints are not necessarily restricted (unless you're auth'd of course) |
| 1053 | + request_method_permission_map = { |
| 1054 | + "POST": "add", |
| 1055 | + "PUT": "change", |
| 1056 | + "PATCH": "change", |
| 1057 | + "DELETE": "delete", |
| 1058 | + } |
| 1059 | + |
| 1060 | + |
990 | 1061 | def raise_no_auto_create_import_validation_error( |
991 | 1062 | test_title, |
992 | 1063 | scan_type, |
|
0 commit comments