-
-
Notifications
You must be signed in to change notification settings - Fork 91
Expand file tree
/
Copy pathpermissions.py
More file actions
102 lines (80 loc) · 3.56 KB
/
permissions.py
File metadata and controls
102 lines (80 loc) · 3.56 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
from django.utils.translation import gettext_lazy as _
from rest_framework.permissions import BasePermission, DjangoModelPermissions
from swapper import load_model
Organization = load_model('openwisp_users', 'Organization')
class BaseOrganizationPermission(BasePermission):
def has_object_permission(self, request, view, obj):
organization = self.get_object_organization(view, obj)
return self.validate_membership(request.user, organization)
def has_permission(self, request, view):
return request.user and request.user.is_authenticated
def get_object_organization(self, view, obj):
organization_field = getattr(view, 'organization_field', 'organization')
fields = organization_field.split('__')
accessed_object = obj
for field in fields:
accessed_object = getattr(accessed_object, field, None)
if not accessed_object:
raise AttributeError(
_(
'Organization not found, `organization_field` '
'not implemented correctly.'
)
)
return accessed_object
def validate_membership(self, user, org):
raise NotImplementedError(
_(
'View\'s permission_classes not implemented correctly.'
'Please use one of the child classes: IsOrganizationMember, '
'IsOrganizationManager or IsOrganizationOwner.'
)
)
class IsOrganizationMember(BaseOrganizationPermission):
message = _(
'User is not a member of the organization to which the '
'requested resource belongs.'
)
def validate_membership(self, user, org):
return org and (user.is_superuser or user.is_member(org))
class IsOrganizationManager(BaseOrganizationPermission):
message = _(
'User is not a manager of the organization to which the '
'requested resource belongs.'
)
def validate_membership(self, user, org):
return org and (user.is_superuser or user.is_manager(org))
class IsOrganizationOwner(BaseOrganizationPermission):
message = _(
'User is not a owner of the organization to which the '
'requested resource belongs.'
)
def validate_membership(self, user, org):
return org and (user.is_superuser or user.is_owner(org))
class ViewDjangoModelPermissions(DjangoModelPermissions):
perms_map = {
'GET': ['%(app_label)s.view_%(model_name)s'],
'OPTIONS': [],
'HEAD': ['%(app_label)s.view_%(model_name)s'],
'POST': ['%(app_label)s.add_%(model_name)s'],
'PUT': ['%(app_label)s.change_%(model_name)s'],
'PATCH': ['%(app_label)s.change_%(model_name)s'],
'DELETE': ['%(app_label)s.delete_%(model_name)s'],
}
def has_permission(self, request, view):
# Workaround to ensure DjangoModelPermissions are not applied
# to the root view when using DefaultRouter.
if getattr(view, '_ignore_model_permissions', False):
return True
user = request.user
if not user or (not user.is_authenticated and self.authenticated_users_only):
return False
queryset = self._queryset(view)
perms = self.get_required_permissions(request.method, queryset.model)
change_perm = self.get_required_permissions('PUT', queryset.model)
if request.method == 'GET':
if user.has_perms(perms) or user.has_perms(change_perm):
return True
else:
return False
return user.has_perms(perms)