Skip to content

Commit 636c712

Browse files
committed
Fix Respect can_read_model permission in DjangoModelPermissions
FIXES: #6324
1 parent bc07521 commit 636c712

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
@@ -175,9 +175,9 @@ class DjangoModelPermissions(BasePermission):
175175
# Override this if you need to also provide 'view' permissions,
176176
# or if you want to provide custom permission codes.
177177
perms_map = {
178-
'GET': [],
178+
'GET': ['%(app_label)s.view_%(model_name)s'],
179179
'OPTIONS': [],
180-
'HEAD': [],
180+
'HEAD': ['%(app_label)s.view_%(model_name)s'],
181181
'POST': ['%(app_label)s.add_%(model_name)s'],
182182
'PUT': ['%(app_label)s.change_%(model_name)s'],
183183
'PATCH': ['%(app_label)s.change_%(model_name)s'],
@@ -228,8 +228,16 @@ def has_permission(self, request, view):
228228

229229
queryset = self._queryset(view)
230230
perms = self.get_required_permissions(request.method, queryset.model)
231+
change_perm = self.get_required_permissions('PUT', queryset.model)
232+
233+
user = request.user
234+
if request.method == 'GET':
235+
if user.has_perms(perms) or user.has_perms(change_perm):
236+
return True
237+
else:
238+
return False
231239

232-
return request.user.has_perms(perms)
240+
return user.has_perms(perms)
233241

234242

235243
class DjangoModelPermissionsOrAnonReadOnly(DjangoModelPermissions):

tests/test_permissions.py

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,8 @@ def setUp(self):
7575
user.user_permissions.set([
7676
Permission.objects.get(codename='add_basicmodel'),
7777
Permission.objects.get(codename='change_basicmodel'),
78-
Permission.objects.get(codename='delete_basicmodel')
78+
Permission.objects.get(codename='delete_basicmodel'),
79+
Permission.objects.get(codename='view_basicmodel')
7980
])
8081

8182
user = User.objects.create_user('updateonly', '[email protected]', 'password')
@@ -113,6 +114,15 @@ def test_get_queryset_has_create_permissions(self):
113114
response = get_queryset_list_view(request, pk=1)
114115
self.assertEqual(response.status_code, status.HTTP_201_CREATED)
115116

117+
def test_has_get_permissions(self):
118+
request = factory.get('/', HTTP_AUTHORIZATION=self.permitted_credentials)
119+
response = root_view(request)
120+
self.assertEqual(response.status_code, status.HTTP_200_OK)
121+
122+
request = factory.get('/1', HTTP_AUTHORIZATION=self.updateonly_credentials)
123+
response = root_view(request, pk=1)
124+
self.assertEqual(response.status_code, status.HTTP_200_OK)
125+
116126
def test_has_put_permissions(self):
117127
request = factory.put('/1', {'text': 'foobar'}, format='json',
118128
HTTP_AUTHORIZATION=self.permitted_credentials)
@@ -130,6 +140,15 @@ def test_does_not_have_create_permissions(self):
130140
response = root_view(request, pk=1)
131141
self.assertEqual(response.status_code, status.HTTP_403_FORBIDDEN)
132142

143+
def test_does_not_have_get_permissions(self):
144+
request = factory.get('/', HTTP_AUTHORIZATION=self.disallowed_credentials)
145+
response = root_view(request)
146+
self.assertEqual(response.status_code, status.HTTP_403_FORBIDDEN)
147+
148+
request = factory.get('/1', HTTP_AUTHORIZATION=self.disallowed_credentials)
149+
response = root_view(request, pk=1)
150+
self.assertEqual(response.status_code, status.HTTP_403_FORBIDDEN)
151+
133152
def test_does_not_have_put_permissions(self):
134153
request = factory.put('/1', {'text': 'foobar'}, format='json',
135154
HTTP_AUTHORIZATION=self.disallowed_credentials)

0 commit comments

Comments
 (0)