Skip to content

Commit ecae64f

Browse files
committed
Fix Respect can_read_model permission in DjangoModelPermissions
FIXES: #6324
1 parent 2d19f23 commit ecae64f

File tree

2 files changed

+31
-4
lines changed

2 files changed

+31
-4
lines changed

rest_framework/permissions.py

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -186,9 +186,9 @@ class DjangoModelPermissions(BasePermission):
186186
# Override this if you need to also provide 'view' permissions,
187187
# or if you want to provide custom permission codes.
188188
perms_map = {
189-
'GET': [],
189+
'GET': ['%(app_label)s.view_%(model_name)s'],
190190
'OPTIONS': [],
191-
'HEAD': [],
191+
'HEAD': ['%(app_label)s.view_%(model_name)s'],
192192
'POST': ['%(app_label)s.add_%(model_name)s'],
193193
'PUT': ['%(app_label)s.change_%(model_name)s'],
194194
'PATCH': ['%(app_label)s.change_%(model_name)s'],
@@ -239,8 +239,16 @@ def has_permission(self, request, view):
239239

240240
queryset = self._queryset(view)
241241
perms = self.get_required_permissions(request.method, queryset.model)
242+
change_perm = self.get_required_permissions('PUT', queryset.model)
243+
244+
user = request.user
245+
if request.method == 'GET':
246+
if user.has_perms(perms) or user.has_perms(change_perm):
247+
return True
248+
else:
249+
return False
242250

243-
return request.user.has_perms(perms)
251+
return user.has_perms(perms)
244252

245253

246254
class DjangoModelPermissionsOrAnonReadOnly(DjangoModelPermissions):

tests/test_permissions.py

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,8 @@ def setUp(self):
8080
user.user_permissions.set([
8181
Permission.objects.get(codename='add_basicmodel'),
8282
Permission.objects.get(codename='change_basicmodel'),
83-
Permission.objects.get(codename='delete_basicmodel')
83+
Permission.objects.get(codename='delete_basicmodel'),
84+
Permission.objects.get(codename='view_basicmodel')
8485
])
8586

8687
user = User.objects.create_user('updateonly', '[email protected]', 'password')
@@ -139,6 +140,15 @@ def test_get_queryset_has_create_permissions(self):
139140
response = get_queryset_list_view(request, pk=1)
140141
self.assertEqual(response.status_code, status.HTTP_201_CREATED)
141142

143+
def test_has_get_permissions(self):
144+
request = factory.get('/', HTTP_AUTHORIZATION=self.permitted_credentials)
145+
response = root_view(request)
146+
self.assertEqual(response.status_code, status.HTTP_200_OK)
147+
148+
request = factory.get('/1', HTTP_AUTHORIZATION=self.updateonly_credentials)
149+
response = root_view(request, pk=1)
150+
self.assertEqual(response.status_code, status.HTTP_200_OK)
151+
142152
def test_has_put_permissions(self):
143153
request = factory.put('/1', {'text': 'foobar'}, format='json',
144154
HTTP_AUTHORIZATION=self.permitted_credentials)
@@ -156,6 +166,15 @@ def test_does_not_have_create_permissions(self):
156166
response = root_view(request, pk=1)
157167
self.assertEqual(response.status_code, status.HTTP_403_FORBIDDEN)
158168

169+
def test_does_not_have_get_permissions(self):
170+
request = factory.get('/', HTTP_AUTHORIZATION=self.disallowed_credentials)
171+
response = root_view(request)
172+
self.assertEqual(response.status_code, status.HTTP_403_FORBIDDEN)
173+
174+
request = factory.get('/1', HTTP_AUTHORIZATION=self.disallowed_credentials)
175+
response = root_view(request, pk=1)
176+
self.assertEqual(response.status_code, status.HTTP_403_FORBIDDEN)
177+
159178
def test_does_not_have_put_permissions(self):
160179
request = factory.put('/1', {'text': 'foobar'}, format='json',
161180
HTTP_AUTHORIZATION=self.disallowed_credentials)

0 commit comments

Comments
 (0)