+ Rejecting anonymous in DjangoModelPermissions *before* the .get_queryset call

This commit is contained in:
Denis Untevskiy 2017-08-25 22:14:33 +02:00
parent 1c4d277f53
commit 88d49848de
2 changed files with 18 additions and 8 deletions

View File

@ -120,6 +120,14 @@ class DjangoModelPermissions(BasePermission):
if getattr(view, '_ignore_model_permissions', False): if getattr(view, '_ignore_model_permissions', False):
return True return True
# For `.get_queryset` to assume that anonymous check was passed
# when `authenticated_users_only` is `True`.
if (
not request.user or
(not is_authenticated(request.user) and self.authenticated_users_only)
):
return False
if hasattr(view, 'get_queryset'): if hasattr(view, 'get_queryset'):
queryset = view.get_queryset() queryset = view.get_queryset()
assert queryset is not None, ( assert queryset is not None, (
@ -135,11 +143,7 @@ class DjangoModelPermissions(BasePermission):
perms = self.get_required_permissions(request.method, queryset.model) perms = self.get_required_permissions(request.method, queryset.model)
return ( return request.user.has_perms(perms)
request.user and
(is_authenticated(request.user) or not self.authenticated_users_only) and
request.user.has_perms(perms)
)
class DjangoModelPermissionsOrAnonReadOnly(DjangoModelPermissions): class DjangoModelPermissionsOrAnonReadOnly(DjangoModelPermissions):

View File

@ -201,11 +201,15 @@ class ModelPermissionsIntegrationTests(TestCase):
self.assertEqual(response.status_code, status.HTTP_200_OK) self.assertEqual(response.status_code, status.HTTP_200_OK)
def test_calling_method_not_allowed(self): def test_calling_method_not_allowed(self):
request = factory.generic('METHOD_NOT_ALLOWED', '/') request = factory.generic(
'METHOD_NOT_ALLOWED', '/', HTTP_AUTHORIZATION=self.permitted_credentials
)
response = root_view(request) response = root_view(request)
self.assertEqual(response.status_code, status.HTTP_405_METHOD_NOT_ALLOWED) self.assertEqual(response.status_code, status.HTTP_405_METHOD_NOT_ALLOWED)
request = factory.generic('METHOD_NOT_ALLOWED', '/1') request = factory.generic(
'METHOD_NOT_ALLOWED', '/1', HTTP_AUTHORIZATION=self.permitted_credentials
)
response = instance_view(request, pk='1') response = instance_view(request, pk='1')
self.assertEqual(response.status_code, status.HTTP_405_METHOD_NOT_ALLOWED) self.assertEqual(response.status_code, status.HTTP_405_METHOD_NOT_ALLOWED)
@ -396,7 +400,9 @@ class ObjectPermissionsIntegrationTests(TestCase):
self.assertListEqual(response.data, []) self.assertListEqual(response.data, [])
def test_cannot_method_not_allowed(self): def test_cannot_method_not_allowed(self):
request = factory.generic('METHOD_NOT_ALLOWED', '/') request = factory.generic(
'METHOD_NOT_ALLOWED', '/', HTTP_AUTHORIZATION=self.credentials['readonly']
)
response = object_permissions_list_view(request) response = object_permissions_list_view(request)
self.assertEqual(response.status_code, status.HTTP_405_METHOD_NOT_ALLOWED) self.assertEqual(response.status_code, status.HTTP_405_METHOD_NOT_ALLOWED)