Skip to content

Commit 7bc3488

Browse files
committed
Add basic permission in dref
1 parent cf96a10 commit 7bc3488

File tree

4 files changed

+198
-8
lines changed

4 files changed

+198
-8
lines changed

api/drf_views.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1095,6 +1095,7 @@ class GoHistoricalViewSet(viewsets.ReadOnlyModelViewSet):
10951095
def get_queryset(self):
10961096
return Event.objects.filter(appeals__isnull=False)
10971097

1098+
10981099
class CountryOfFieldReportToReviewViewset(viewsets.ReadOnlyModelViewSet):
10991100
queryset = CountryOfFieldReportToReview.objects.order_by('country')
11001101
serializer_class = CountryOfFieldReportToReviewSerializer

dref/permissions.py

Lines changed: 53 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2,20 +2,66 @@
22

33
from rest_framework import permissions
44

5-
from dref.models import Dref
5+
from dref.models import (
6+
Dref,
7+
DrefOperationalUpdate,
8+
)
9+
10+
11+
class IsSuperAdmin(permissions.BasePermission):
12+
"""
13+
Allow super user to view and perform all actions
14+
"""
15+
def has_object_permission(self, request, view, obj):
16+
if request.method in permissions.SAFE_METHODS:
17+
return True
18+
return request.user.is_superuser
19+
20+
21+
class DrefViewUpdatePermission(IsSuperAdmin):
22+
message = "Can view and update Dref"
23+
24+
def has_permission(self, request, view):
25+
if request.method == "POST":
26+
return True
27+
return True
28+
29+
def has_object_permission(self, request, view, obj):
30+
user = request.user
31+
if user.is_superuser:
32+
return True
33+
if request.method in ["PUT", "DELETE", "PATCH"]:
34+
return Dref.objects.filter(
35+
models.Q(id=obj.id, users=user) |
36+
models.Q(id=obj.id, created_by=user)
37+
).exists()
38+
return True
639

740

841
class DrefOperationalUpdateCreatePermission(permissions.BasePermission):
942
message = "Can create Operational Update for whom dref is shared with"
1043

1144
def has_permission(self, request, view):
12-
if request.method != "POST":
13-
return True
1445
user = request.user
1546
dref = request.data.get('dref')
16-
if dref:
17-
return Dref.objects.filter(
18-
models.Q(id=dref, users=user) |
19-
models.Q(id=dref, created_by=user)
47+
if request.method == "POST":
48+
if user.is_superuser:
49+
return True
50+
if dref:
51+
return Dref.objects.filter(
52+
models.Q(id=dref, users=user) |
53+
models.Q(id=dref, created_by=user),
54+
is_published=True
55+
).exists()
56+
return True
57+
58+
def has_object_permission(self, request, view, obj):
59+
user = request.user
60+
if user.is_superuser:
61+
return True
62+
if request.method in ["PUT", "DELETE", "PATCH"]:
63+
return DrefOperationalUpdate.objects.filter(
64+
models.Q(id=obj.id, users=user) |
65+
models.Q(id=obj.id, created_by=user)
2066
).exists()
2167
return True

dref/test_views.py

Lines changed: 139 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -986,3 +986,142 @@ def test_optimistic_lock_in_final_report(self):
986986
data['modified_at'] = datetime.now() + timedelta(days=2)
987987
response = self.client.patch(url, data=data)
988988
self.assert_200(response)
989+
def test_dref_permission(self):
990+
user1 = UserFactory.create(
991+
username='[email protected]',
992+
first_name='Test',
993+
last_name='User1',
994+
password='admin123',
995+
996+
is_superuser=True,
997+
)
998+
user2 = UserFactory.create(
999+
username='[email protected]',
1000+
first_name='Test',
1001+
last_name='User2',
1002+
password='admin123',
1003+
1004+
)
1005+
user3 = UserFactory.create(
1006+
username='[email protected]',
1007+
first_name='Test',
1008+
last_name='User3',
1009+
password='admin123',
1010+
1011+
)
1012+
user4 = UserFactory.create(
1013+
username='[email protected]',
1014+
first_name='Test',
1015+
last_name='User4',
1016+
password='admin123',
1017+
1018+
)
1019+
dref1 = DrefFactory.create(
1020+
title='Test Title',
1021+
created_by=user1,
1022+
)
1023+
dref1.users.add(user2)
1024+
DrefFactory.create(
1025+
title='Test Title New',
1026+
created_by=user3
1027+
)
1028+
get_url = '/api/v2/dref/'
1029+
# authenticate with superuser
1030+
# should be able to view all drefs
1031+
self.client.force_authenticate(user1)
1032+
response = self.client.get(get_url)
1033+
self.assertEqual(response.status_code, 200)
1034+
self.assertEqual(len(response.data['results']), 2)
1035+
1036+
# # let superuser patch the dref
1037+
patch_url = f'/api/v2/dref/{dref1.id}/'
1038+
data = {
1039+
"title": "New test title",
1040+
"modified_at": datetime.now()
1041+
}
1042+
response = self.client.patch(patch_url, data=data)
1043+
self.assertEqual(response.status_code, 200)
1044+
1045+
# # lets authenticate with user for whom dref is shared with
1046+
self.client.force_authenticate(user2)
1047+
response = self.client.get(get_url)
1048+
self.assertEqual(response.status_code, 200)
1049+
self.assertEqual(len(response.data['results']), 1)
1050+
1051+
# # try to patch by user
1052+
self.client.force_authenticate(user2)
1053+
data = {
1054+
"title": "New test title",
1055+
"modified_at": datetime.now() + timedelta(days=1),
1056+
}
1057+
response = self.client.patch(patch_url, data=data)
1058+
self.assertEqual(response.status_code, 200)
1059+
1060+
# # try to authenticate with user who is neither assigned nor created_by
1061+
self.client.force_authenticate(user4)
1062+
response = self.client.get(get_url)
1063+
self.assertEqual(response.status_code, 200)
1064+
self.assertEqual(len(response.data['results']), 0)
1065+
1066+
def test_dref_operational_update_permission(self):
1067+
super_user = UserFactory.create(
1068+
username='[email protected]',
1069+
first_name='Test',
1070+
last_name='User1',
1071+
password='admin123',
1072+
1073+
is_superuser=True,
1074+
)
1075+
user1, user2 = UserFactory.create_batch(2)
1076+
dref = DrefFactory.create(
1077+
title='Test Title',
1078+
is_published=True,
1079+
)
1080+
dref.users.add(user1)
1081+
self.country1 = Country.objects.create(name='abc')
1082+
self.district1 = District.objects.create(name='test district1', country=self.country1)
1083+
old_op_count = DrefOperationalUpdate.objects.filter(dref=dref).count()
1084+
url = '/api/v2/dref-op-update/'
1085+
data = {
1086+
'dref': dref.id,
1087+
'country': self.country1.id,
1088+
'district': [self.district1.id],
1089+
}
1090+
# authenticate with user for whom dref is not shared
1091+
self.authenticate(self.user)
1092+
response = self.client.post(url, data=data)
1093+
self.assert_403(response)
1094+
# authenticate with user for whom dref is shared
1095+
self.authenticate(user1)
1096+
response = self.client.post(url, data=data)
1097+
self.assert_201(response)
1098+
self.assertEqual(
1099+
DrefOperationalUpdate.objects.filter(dref=dref).count(),
1100+
old_op_count + 1
1101+
)
1102+
1103+
def test_superuser_permisssion_operational_update(self):
1104+
super_user = UserFactory.create(
1105+
username='[email protected]',
1106+
first_name='Test',
1107+
last_name='User1',
1108+
password='admin123',
1109+
1110+
is_superuser=True,
1111+
)
1112+
dref = DrefFactory.create(
1113+
title='Test Title',
1114+
is_published=True,
1115+
)
1116+
self.country1 = Country.objects.create(name='abc')
1117+
self.district1 = District.objects.create(name='test district1', country=self.country1)
1118+
url = '/api/v2/dref-op-update/'
1119+
data = {
1120+
'dref': dref.id,
1121+
'country': self.country1.id,
1122+
'district': [self.district1.id],
1123+
}
1124+
# authenticate with superuser
1125+
self.authenticate(super_user)
1126+
response = self.client.post(url, data=data)
1127+
self.assert_201(response)

dref/views.py

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,11 +32,15 @@
3232
DrefFilter,
3333
DrefOperationalUpdateFilter
3434
)
35+
from dref.permissions import (
36+
DrefViewUpdatePermission,
37+
DrefOperationalUpdateCreatePermission,
38+
)
3539

3640

3741
class DrefViewSet(RevisionMixin, viewsets.ModelViewSet):
3842
serializer_class = DrefSerializer
39-
permission_classes = [permissions.IsAuthenticated]
43+
permission_classes = [permissions.IsAuthenticated, DrefViewUpdatePermission]
4044
filterset_class = DrefFilter
4145

4246
def get_queryset(self):

0 commit comments

Comments
 (0)