3
3
4
4
from nxtbn .users import UserRole
5
5
6
- class NxtbnAdminPermission (BasePermission ):
6
+
7
+ import functools
8
+ from graphql import GraphQLError
9
+ class GranularPermission (BasePermission ):
10
+ def get_permission_name (self , model_name , action ):
11
+
12
+ return f"{ model_name } .{ action } "
13
+
7
14
def has_permission (self , request , view ):
8
- user = request .user
9
- if not user .is_authenticated :
15
+ if not request .user .is_authenticated :
10
16
return False
11
17
12
- if user .is_superuser :
18
+ if request .user .is_superuser :
19
+ return True
20
+
21
+ if request .user .method in SAFE_METHODS and request .user .is_staff : # Every staff can view
13
22
return True
23
+
24
+ model_name = view .queryset .model .__name__ .lower () # Get model name dynamically
25
+ action = view .action .required_perm
14
26
15
- return False
27
+ permission_name = self . get_permission_name ( model_name , action )
16
28
29
+ # Check if the user has the generated permission
30
+ return request .user .has_perm (permission_name )
31
+
17
32
18
- class RoleBasedPermission (BasePermission ):
19
- """
20
- Custom permission that grants or denies access based on the role and action.
21
- """
22
- def has_permission (self , request , view ):
23
- user = request .user
33
+ class ModelPermissions (BasePermission ):
24
34
25
- # Ensure user is authenticated
26
- if not user .is_authenticated :
35
+ def has_permission ( self , request , view ):
36
+ if not request . user .is_authenticated :
27
37
return False
28
38
29
- if user .role == UserRole .ADMIN :
39
+ if request .user .is_superuser :
40
+ return True
41
+
42
+ if request .user .method in SAFE_METHODS and request .user .is_staff : # Every staff can view
30
43
return True
31
44
32
45
33
- action = getattr (view , 'role_action' , None ) or getattr (view , 'action' , None )
34
46
47
+ model_cls = getattr (view , 'queryset' , None )
48
+ if model_cls is None :
49
+ return False
35
50
51
+ model_meta = model_cls .model ._meta
36
52
37
- # Check if action exists in the permissions for the user's role
38
- role_permissions = view .ROLE_PERMISSIONS .get (user .role , set ())
53
+ method_permissions_map = {
54
+ 'GET' : f'{ model_meta .app_label } .view_{ model_meta .model_name } ' ,
55
+ 'OPTIONS' : f'{ model_meta .app_label } .view_{ model_meta .model_name } ' ,
56
+ 'HEAD' : f'{ model_meta .app_label } .view_{ model_meta .model_name } ' ,
57
+ 'POST' : f'{ model_meta .app_label } .add_{ model_meta .model_name } ' ,
58
+ 'PUT' : f'{ model_meta .app_label } .change_{ model_meta .model_name } ' ,
59
+ 'PATCH' : f'{ model_meta .app_label } .change_{ model_meta .model_name } ' ,
60
+ 'DELETE' : f'{ model_meta .app_label } .delete_{ model_meta .model_name } ' ,
61
+ }
39
62
40
- if "all" in role_permissions :
41
- return True
63
+ required_permission = method_permissions_map .get (request .method )
42
64
43
- # Grant permission if the action is allowed for the user's role
44
- if action in role_permissions :
45
- return True
65
+ if required_permission is None :
66
+ return False
46
67
47
- return False
48
-
68
+ return request .user .has_perm (required_permission )
49
69
50
- def check_user_permissions (info , any_staff = False , allowed_roles = []):
51
- if not info .context .user .is_authenticated :
52
- raise Exception ("You must be logged in to perform this action" )
53
-
54
- if not info .context .user .is_staff :
55
- raise Exception ("You must be a staff to perform this action" )
56
-
57
- if info .context .user .is_superuser :
58
- return True
59
-
60
- if any_staff :
61
- return True
62
-
63
- if info .context .user .role not in allowed_roles :
64
- raise Exception ("You do not have permission to perform this action" )
70
+
71
+
72
+
73
+ def required_perm (code : str ): # Used in graphql only
74
+ def decorator (func ):
75
+ @functools .wraps (func )
76
+ def wrapper (self , info , * args , ** kwargs ):
77
+ operation = info .operation .operation
78
+ user = info .context .user
79
+
80
+ if user .is_anonymous :
81
+ raise GraphQLError ("Authentication required" )
82
+
83
+ if operation == "query" :
84
+ return func (self , info , * args , ** kwargs )
85
+
86
+
87
+
88
+ if not user .has_perm (code ): # Check if user has the required permission
89
+ raise GraphQLError ("Permission denied" ) # Block unauthorized access
90
+
91
+ return func (self , info , * args , ** kwargs ) # Call the actual resolver
92
+
93
+ return wrapper
65
94
66
- return True
95
+ return decorator
96
+
97
+
98
+ def staff_required (func ):
99
+ @functools .wraps (func )
100
+ def wrapper (self , info , * args , ** kwargs ):
101
+ user = info .context .user
102
+
103
+ if user .is_anonymous :
104
+ raise GraphQLError ("Authentication required" )
105
+
106
+ if not user .is_staff : # Check if the user is a staff member
107
+ raise GraphQLError ("Permission denied" ) # Block access if the user is not staff
108
+
109
+ return func (self , info , * args , ** kwargs ) # Call the actual resolver
110
+
111
+ return wrapper
0 commit comments