From 88d49848de5c15d91b375097f971ff5fab0fd3dc Mon Sep 17 00:00:00 2001 From: Denis Untevskiy Date: Fri, 25 Aug 2017 22:14:33 +0200 Subject: [PATCH] + Rejecting anonymous in DjangoModelPermissions *before* the .get_queryset call --- rest_framework/permissions.py | 14 +++++++++----- tests/test_permissions.py | 12 +++++++++--- 2 files changed, 18 insertions(+), 8 deletions(-) diff --git a/rest_framework/permissions.py b/rest_framework/permissions.py index 57de3a35cb..f2db921981 100644 --- a/rest_framework/permissions.py +++ b/rest_framework/permissions.py @@ -120,6 +120,14 @@ def has_permission(self, request, view): if getattr(view, '_ignore_model_permissions', False): 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'): queryset = view.get_queryset() assert queryset is not None, ( @@ -135,11 +143,7 @@ def has_permission(self, request, view): perms = self.get_required_permissions(request.method, queryset.model) - return ( - request.user and - (is_authenticated(request.user) or not self.authenticated_users_only) and - request.user.has_perms(perms) - ) + return request.user.has_perms(perms) class DjangoModelPermissionsOrAnonReadOnly(DjangoModelPermissions): diff --git a/tests/test_permissions.py b/tests/test_permissions.py index 6fbf766a02..e2c8ee81c6 100644 --- a/tests/test_permissions.py +++ b/tests/test_permissions.py @@ -201,11 +201,15 @@ def test_empty_view_does_not_assert(self): self.assertEqual(response.status_code, status.HTTP_200_OK) 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) 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') self.assertEqual(response.status_code, status.HTTP_405_METHOD_NOT_ALLOWED) @@ -396,7 +400,9 @@ def test_cannot_read_list_permissions(self): self.assertListEqual(response.data, []) 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) self.assertEqual(response.status_code, status.HTTP_405_METHOD_NOT_ALLOWED)