-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathpermissions.py
More file actions
123 lines (93 loc) · 3.89 KB
/
permissions.py
File metadata and controls
123 lines (93 loc) · 3.89 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
from rest_framework.permissions import BasePermission
from .models import AccessRoleRule, BusinessElement, Role
class CanAccessAccessRules(BasePermission):
"""
Allow Admin always, or roles explicitly given permission for Access Rules.
"""
def has_permission(self, request, view):
user = request.user
if not user or not user.is_authenticated:
return False
if user.role.name == "Admin":
return True
try:
element = BusinessElement.objects.get(name="Access Rules")
rule = AccessRoleRule.objects.get(role=user.role, element=element)
return rule.read_permission or rule.read_all_permission
except (BusinessElement.DoesNotExist, AccessRoleRule.DoesNotExist):
return False
class RoleBasedPermission(BasePermission):
action_map = {
'list': ('read_permission', 'read_all_permission'),
'retrieve': ('read_permission', 'read_all_permission'),
'create': ('create_permission', None),
'update': ('update_permission', 'update_all_permission'),
'partial_update': ('update_permission', 'update_all_permission'),
'destroy': ('delete_permission', 'delete_all_permission'),
}
def has_permission(self, request, view):
user = request.user
if not user or not user.is_authenticated:
return False # DRF will return 401
element_name = getattr(view, 'business_element', None)
if not element_name:
return False
# Admin shortcut
if user.role.name == "Admin":
return True
try:
rule = AccessRoleRule.objects.get(role=user.role, element__name=element_name)
except AccessRoleRule.DoesNotExist:
return False
action = getattr(view, 'action', None)
if not action or action not in self.action_map:
return False
permission_field, all_permission_field = self.action_map[action]
if action == 'create' and getattr(rule, permission_field, False):
return True
return True
def has_object_permission(self, request, view, obj):
"""
Object-level permission check for ownership.
"""
user = request.user
if not user or not user.is_authenticated:
return False
element_name = getattr(view, 'business_element', None)
if not element_name:
return False
if user.role.name == "Admin":
return True
try:
rule = AccessRoleRule.objects.get(role=user.role, element__name=element_name)
except AccessRoleRule.DoesNotExist:
return False
action = getattr(view, 'action', None)
if not action or action not in self.action_map:
return False
permission_field, all_permission_field = self.action_map[action]
if all_permission_field and getattr(rule, all_permission_field, False):
return True
if permission_field and getattr(rule, permission_field, False):
if hasattr(obj, 'owner') and obj.owner == user:
return True
return False
class MockRoleBasedPermission(BasePermission):
"""
Simulates role-based access control for mock endpoints.
Returns the rule object, the view can filter the mock list.
"""
def has_permission(self, request, view):
user_role = getattr(request.user, "role_id", None)
if not user_role:
return False
try:
element_pk = BusinessElement.objects.get(name=view.business_element).pk
except BusinessElement.DoesNotExist:
return False
try:
rule = AccessRoleRule.objects.get(role_id=user_role, element_id=element_pk)
except AccessRoleRule.DoesNotExist:
return False
view.access_rule = rule
return rule.read_permission or rule.read_all_permission