Loading django/contrib/auth/decorators.py +5 −1 Original line number Diff line number Diff line Loading @@ -64,8 +64,12 @@ def permission_required(perm, login_url=None, raise_exception=False): is raised. """ def check_perms(user): if not isinstance(perm, (list, tuple)): perms = (perm, ) else: perms = perm # First check if the user has the permission (even anon users) if user.has_perm(perm): if user.has_perms(perms): return True # In case the 403 handler should be called raise the exception if raise_exception: Loading django/contrib/auth/tests/test_decorators.py +57 −1 Original line number Diff line number Diff line from django.conf import settings from django.contrib.auth.decorators import login_required from django.contrib.auth import models from django.contrib.auth.decorators import login_required, permission_required from django.contrib.auth.tests.test_views import AuthViewsTestCase from django.contrib.auth.tests.utils import skipIfCustomUser from django.core.exceptions import PermissionDenied from django.http import HttpResponse from django.test import TestCase from django.test.client import RequestFactory @skipIfCustomUser Loading Loading @@ -49,3 +54,54 @@ class LoginRequiredTestCase(AuthViewsTestCase): """ self.testLoginRequired(view_url='/login_required_login_url/', login_url='/somewhere/') class PermissionsRequiredDecoratorTest(TestCase): """ Tests for the permission_required decorator """ def setUp(self): self.user = models.User.objects.create(username='joe', password='qwerty') self.factory = RequestFactory() # Add permissions auth.add_customuser and auth.change_customuser perms = models.Permission.objects.filter(codename__in=('add_customuser', 'change_customuser')) self.user.user_permissions.add(*perms) def test_many_permissions_pass(self): @permission_required(['auth.add_customuser', 'auth.change_customuser']) def a_view(request): return HttpResponse() request = self.factory.get('/rand') request.user = self.user resp = a_view(request) self.assertEqual(resp.status_code, 200) def test_single_permission_pass(self): @permission_required('auth.add_customuser') def a_view(request): return HttpResponse() request = self.factory.get('/rand') request.user = self.user resp = a_view(request) self.assertEqual(resp.status_code, 200) def test_permissioned_denied_redirect(self): @permission_required(['auth.add_customuser', 'auth.change_customuser', 'non-existant-permission']) def a_view(request): return HttpResponse() request = self.factory.get('/rand') request.user = self.user resp = a_view(request) self.assertEqual(resp.status_code, 302) def test_permissioned_denied_exception_raised(self): @permission_required(['auth.add_customuser', 'auth.change_customuser', 'non-existant-permission'], raise_exception=True) def a_view(request): return HttpResponse() request = self.factory.get('/rand') request.user = self.user self.assertRaises(PermissionDenied, a_view, request) docs/releases/1.7.txt +3 −0 Original line number Diff line number Diff line Loading @@ -135,6 +135,9 @@ Minor features ``Meta`` option allows you to customize (or disable) creation of the default add, change, and delete permissions. * The :func:`~django.contrib.auth.decorators.permission_required` decorator can take a list of permissions as well as a single permission. Backwards incompatible changes in 1.7 ===================================== Loading docs/topics/auth/default.txt +5 −0 Original line number Diff line number Diff line Loading @@ -528,6 +528,11 @@ The permission_required decorator (HTTP Forbidden) view<http_forbidden_view>` instead of redirecting to the login page. .. versionchanged:: 1.7 The :func:`~django.contrib.auth.decorators.permission_required` decorator can take a list of permissions as well as a single permission. Applying permissions to generic views ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Loading Loading
django/contrib/auth/decorators.py +5 −1 Original line number Diff line number Diff line Loading @@ -64,8 +64,12 @@ def permission_required(perm, login_url=None, raise_exception=False): is raised. """ def check_perms(user): if not isinstance(perm, (list, tuple)): perms = (perm, ) else: perms = perm # First check if the user has the permission (even anon users) if user.has_perm(perm): if user.has_perms(perms): return True # In case the 403 handler should be called raise the exception if raise_exception: Loading
django/contrib/auth/tests/test_decorators.py +57 −1 Original line number Diff line number Diff line from django.conf import settings from django.contrib.auth.decorators import login_required from django.contrib.auth import models from django.contrib.auth.decorators import login_required, permission_required from django.contrib.auth.tests.test_views import AuthViewsTestCase from django.contrib.auth.tests.utils import skipIfCustomUser from django.core.exceptions import PermissionDenied from django.http import HttpResponse from django.test import TestCase from django.test.client import RequestFactory @skipIfCustomUser Loading Loading @@ -49,3 +54,54 @@ class LoginRequiredTestCase(AuthViewsTestCase): """ self.testLoginRequired(view_url='/login_required_login_url/', login_url='/somewhere/') class PermissionsRequiredDecoratorTest(TestCase): """ Tests for the permission_required decorator """ def setUp(self): self.user = models.User.objects.create(username='joe', password='qwerty') self.factory = RequestFactory() # Add permissions auth.add_customuser and auth.change_customuser perms = models.Permission.objects.filter(codename__in=('add_customuser', 'change_customuser')) self.user.user_permissions.add(*perms) def test_many_permissions_pass(self): @permission_required(['auth.add_customuser', 'auth.change_customuser']) def a_view(request): return HttpResponse() request = self.factory.get('/rand') request.user = self.user resp = a_view(request) self.assertEqual(resp.status_code, 200) def test_single_permission_pass(self): @permission_required('auth.add_customuser') def a_view(request): return HttpResponse() request = self.factory.get('/rand') request.user = self.user resp = a_view(request) self.assertEqual(resp.status_code, 200) def test_permissioned_denied_redirect(self): @permission_required(['auth.add_customuser', 'auth.change_customuser', 'non-existant-permission']) def a_view(request): return HttpResponse() request = self.factory.get('/rand') request.user = self.user resp = a_view(request) self.assertEqual(resp.status_code, 302) def test_permissioned_denied_exception_raised(self): @permission_required(['auth.add_customuser', 'auth.change_customuser', 'non-existant-permission'], raise_exception=True) def a_view(request): return HttpResponse() request = self.factory.get('/rand') request.user = self.user self.assertRaises(PermissionDenied, a_view, request)
docs/releases/1.7.txt +3 −0 Original line number Diff line number Diff line Loading @@ -135,6 +135,9 @@ Minor features ``Meta`` option allows you to customize (or disable) creation of the default add, change, and delete permissions. * The :func:`~django.contrib.auth.decorators.permission_required` decorator can take a list of permissions as well as a single permission. Backwards incompatible changes in 1.7 ===================================== Loading
docs/topics/auth/default.txt +5 −0 Original line number Diff line number Diff line Loading @@ -528,6 +528,11 @@ The permission_required decorator (HTTP Forbidden) view<http_forbidden_view>` instead of redirecting to the login page. .. versionchanged:: 1.7 The :func:`~django.contrib.auth.decorators.permission_required` decorator can take a list of permissions as well as a single permission. Applying permissions to generic views ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Loading