Revert "Fix Respect can_read_model permission in DjangoModelPermissions (#8…" (#9332)

This reverts commit 0618fa88e1.
This commit is contained in:
Tom Christie 2024-03-21 22:45:12 +00:00 committed by GitHub
parent a4d58077a0
commit 4f10c4e43e
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 5 additions and 30 deletions

View File

@ -173,12 +173,11 @@ This permission is suitable if you want to your API to allow read permissions to
This permission class ties into Django's standard `django.contrib.auth` [model permissions][contribauth]. This permission must only be applied to views that have a `.queryset` property or `get_queryset()` method. Authorization will only be granted if the user *is authenticated* and has the *relevant model permissions* assigned. The appropriate model is determined by checking `get_queryset().model` or `queryset.model`. This permission class ties into Django's standard `django.contrib.auth` [model permissions][contribauth]. This permission must only be applied to views that have a `.queryset` property or `get_queryset()` method. Authorization will only be granted if the user *is authenticated* and has the *relevant model permissions* assigned. The appropriate model is determined by checking `get_queryset().model` or `queryset.model`.
* `GET` requests require the user to have the `view` or `change` permission on the model
* `POST` requests require the user to have the `add` permission on the model. * `POST` requests require the user to have the `add` permission on the model.
* `PUT` and `PATCH` requests require the user to have the `change` permission on the model. * `PUT` and `PATCH` requests require the user to have the `change` permission on the model.
* `DELETE` requests require the user to have the `delete` permission on the model. * `DELETE` requests require the user to have the `delete` permission on the model.
The default behaviour can also be overridden to support custom model permissions. The default behavior can also be overridden to support custom model permissions. For example, you might want to include a `view` model permission for `GET` requests.
To use custom model permissions, override `DjangoModelPermissions` and set the `.perms_map` property. Refer to the source code for details. To use custom model permissions, override `DjangoModelPermissions` and set the `.perms_map` property. Refer to the source code for details.

View File

@ -186,9 +186,9 @@ class DjangoModelPermissions(BasePermission):
# Override this if you need to also provide 'view' permissions, # Override this if you need to also provide 'view' permissions,
# or if you want to provide custom permission codes. # or if you want to provide custom permission codes.
perms_map = { perms_map = {
'GET': ['%(app_label)s.view_%(model_name)s'], 'GET': [],
'OPTIONS': [], 'OPTIONS': [],
'HEAD': ['%(app_label)s.view_%(model_name)s'], 'HEAD': [],
'POST': ['%(app_label)s.add_%(model_name)s'], 'POST': ['%(app_label)s.add_%(model_name)s'],
'PUT': ['%(app_label)s.change_%(model_name)s'], 'PUT': ['%(app_label)s.change_%(model_name)s'],
'PATCH': ['%(app_label)s.change_%(model_name)s'], 'PATCH': ['%(app_label)s.change_%(model_name)s'],
@ -239,13 +239,8 @@ class DjangoModelPermissions(BasePermission):
queryset = self._queryset(view) queryset = self._queryset(view)
perms = self.get_required_permissions(request.method, queryset.model) perms = self.get_required_permissions(request.method, queryset.model)
change_perm = self.get_required_permissions('PUT', queryset.model)
user = request.user return request.user.has_perms(perms)
if request.method == 'GET':
return user.has_perms(perms) or user.has_perms(change_perm)
return user.has_perms(perms)
class DjangoModelPermissionsOrAnonReadOnly(DjangoModelPermissions): class DjangoModelPermissionsOrAnonReadOnly(DjangoModelPermissions):

View File

@ -80,8 +80,7 @@ class ModelPermissionsIntegrationTests(TestCase):
user.user_permissions.set([ user.user_permissions.set([
Permission.objects.get(codename='add_basicmodel'), Permission.objects.get(codename='add_basicmodel'),
Permission.objects.get(codename='change_basicmodel'), Permission.objects.get(codename='change_basicmodel'),
Permission.objects.get(codename='delete_basicmodel'), Permission.objects.get(codename='delete_basicmodel')
Permission.objects.get(codename='view_basicmodel')
]) ])
user = User.objects.create_user('updateonly', 'updateonly@example.com', 'password') user = User.objects.create_user('updateonly', 'updateonly@example.com', 'password')
@ -140,15 +139,6 @@ class ModelPermissionsIntegrationTests(TestCase):
response = get_queryset_list_view(request, pk=1) response = get_queryset_list_view(request, pk=1)
self.assertEqual(response.status_code, status.HTTP_201_CREATED) self.assertEqual(response.status_code, status.HTTP_201_CREATED)
def test_has_get_permissions(self):
request = factory.get('/', HTTP_AUTHORIZATION=self.permitted_credentials)
response = root_view(request)
self.assertEqual(response.status_code, status.HTTP_200_OK)
request = factory.get('/1', HTTP_AUTHORIZATION=self.updateonly_credentials)
response = root_view(request, pk=1)
self.assertEqual(response.status_code, status.HTTP_200_OK)
def test_has_put_permissions(self): def test_has_put_permissions(self):
request = factory.put('/1', {'text': 'foobar'}, format='json', request = factory.put('/1', {'text': 'foobar'}, format='json',
HTTP_AUTHORIZATION=self.permitted_credentials) HTTP_AUTHORIZATION=self.permitted_credentials)
@ -166,15 +156,6 @@ class ModelPermissionsIntegrationTests(TestCase):
response = root_view(request, pk=1) response = root_view(request, pk=1)
self.assertEqual(response.status_code, status.HTTP_403_FORBIDDEN) self.assertEqual(response.status_code, status.HTTP_403_FORBIDDEN)
def test_does_not_have_get_permissions(self):
request = factory.get('/', HTTP_AUTHORIZATION=self.disallowed_credentials)
response = root_view(request)
self.assertEqual(response.status_code, status.HTTP_403_FORBIDDEN)
request = factory.get('/1', HTTP_AUTHORIZATION=self.disallowed_credentials)
response = root_view(request, pk=1)
self.assertEqual(response.status_code, status.HTTP_403_FORBIDDEN)
def test_does_not_have_put_permissions(self): def test_does_not_have_put_permissions(self):
request = factory.put('/1', {'text': 'foobar'}, format='json', request = factory.put('/1', {'text': 'foobar'}, format='json',
HTTP_AUTHORIZATION=self.disallowed_credentials) HTTP_AUTHORIZATION=self.disallowed_credentials)