Kaydet (Commit) 9b1125bf authored tarafından Dylan Verheul's avatar Dylan Verheul Kaydeden (comit) Tim Graham

Fixed #28379 -- Made AccessMixin raise Permissiondenied for authenticated users.

üst e307ff29
...@@ -39,7 +39,7 @@ class AccessMixin: ...@@ -39,7 +39,7 @@ class AccessMixin:
return self.redirect_field_name return self.redirect_field_name
def handle_no_permission(self): def handle_no_permission(self):
if self.raise_exception: if self.raise_exception or self.request.user.is_authenticated:
raise PermissionDenied(self.get_permission_denied_message()) raise PermissionDenied(self.get_permission_denied_message())
return redirect_to_login(self.request.get_full_path(), self.get_login_url(), self.get_redirect_field_name()) return redirect_to_login(self.request.get_full_path(), self.get_login_url(), self.get_redirect_field_name())
......
...@@ -757,8 +757,17 @@ Redirecting unauthorized requests in class-based views ...@@ -757,8 +757,17 @@ Redirecting unauthorized requests in class-based views
------------------------------------------------------ ------------------------------------------------------
To ease the handling of access restrictions in :doc:`class-based views To ease the handling of access restrictions in :doc:`class-based views
</ref/class-based-views/index>`, the ``AccessMixin`` can be used to redirect a </ref/class-based-views/index>`, the ``AccessMixin`` can be used to configure
user to the login page or issue an HTTP 403 Forbidden response. the behavior of a view when access is denied. Authenticated users are denied
access with an HTTP 403 Forbidden response. Anonymous users are redirected to
the login page or shown an HTTP 403 Forbidden response, depending on the
:attr:`~django.contrib.auth.mixins.AccessMixin.raise_exception` attribute.
.. versionchanged:: 2.1
In older versions, authenticated users who lacked permissions were
redirected to the login page (which resulted in a loop) instead of
receiving an HTTP 403 Forbidden response.
.. class:: AccessMixin .. class:: AccessMixin
...@@ -781,8 +790,9 @@ user to the login page or issue an HTTP 403 Forbidden response. ...@@ -781,8 +790,9 @@ user to the login page or issue an HTTP 403 Forbidden response.
.. attribute:: raise_exception .. attribute:: raise_exception
If this attribute is set to ``True``, a If this attribute is set to ``True``, a
:class:`~django.core.exceptions.PermissionDenied` exception will be :class:`~django.core.exceptions.PermissionDenied` exception is raised
raised instead of the redirect. Defaults to ``False``. when the conditions are not met. When ``False`` (the default),
anonymous users are redirected to the login page.
.. method:: get_login_url() .. method:: get_login_url()
......
...@@ -80,6 +80,20 @@ class AccessMixinTests(TestCase): ...@@ -80,6 +80,20 @@ class AccessMixinTests(TestCase):
with self.assertRaises(PermissionDenied): with self.assertRaises(PermissionDenied):
view(request) view(request)
def test_access_mixin_permission_denied_response(self):
user = models.User.objects.create(username='joe', password='qwerty')
# Authenticated users receive PermissionDenied.
request = self.factory.get('/rand')
request.user = user
view = AlwaysFalseView.as_view()
with self.assertRaises(PermissionDenied):
view(request)
# Anonymous users are redirected to the login page.
request.user = AnonymousUser()
response = view(request)
self.assertEqual(response.status_code, 302)
self.assertEqual(response.url, '/accounts/login/?next=/rand')
@mock.patch.object(models.User, 'is_authenticated', False) @mock.patch.object(models.User, 'is_authenticated', False)
def test_stacked_mixins_not_logged_in(self): def test_stacked_mixins_not_logged_in(self):
user = models.User.objects.create(username='joe', password='qwerty') user = models.User.objects.create(username='joe', password='qwerty')
...@@ -241,8 +255,13 @@ class PermissionsRequiredMixinTests(TestCase): ...@@ -241,8 +255,13 @@ class PermissionsRequiredMixinTests(TestCase):
'auth_tests.add_customuser', 'auth_tests.change_customuser', 'nonexistent-permission', 'auth_tests.add_customuser', 'auth_tests.change_customuser', 'nonexistent-permission',
] ]
# Authenticated users receive PermissionDenied.
request = self.factory.get('/rand') request = self.factory.get('/rand')
request.user = self.user request.user = self.user
with self.assertRaises(PermissionDenied):
AView.as_view()(request)
# Anonymous users are redirected to the login page.
request.user = AnonymousUser()
resp = AView.as_view()(request) resp = AView.as_view()(request)
self.assertEqual(resp.status_code, 302) self.assertEqual(resp.status_code, 302)
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment