Loading django/contrib/auth/decorators.py +2 −1 Original line number Diff line number Diff line Loading @@ -4,6 +4,7 @@ from django.conf import settings from django.contrib.auth import REDIRECT_FIELD_NAME from django.core.exceptions import PermissionDenied from django.shortcuts import resolve_url from django.utils import six from django.utils.decorators import available_attrs from django.utils.six.moves.urllib.parse import urlparse Loading Loading @@ -59,7 +60,7 @@ def permission_required(perm, login_url=None, raise_exception=False): is raised. """ def check_perms(user): if not isinstance(perm, (list, tuple)): if isinstance(perm, six.string_types): perms = (perm, ) else: perms = perm Loading docs/releases/1.9.txt +4 −0 Original line number Diff line number Diff line Loading @@ -114,6 +114,10 @@ Minor features a deprecation warning in older versions and is no longer supported in Django 1.9). * The permission argument of :func:`~django.contrib.auth.decorators.permission_required()` accepts all kinds of iterables, not only list and tuples. :mod:`django.contrib.gis` ^^^^^^^^^^^^^^^^^^^^^^^^^^ Loading docs/topics/auth/default.txt +6 −1 Original line number Diff line number Diff line Loading @@ -580,7 +580,7 @@ The permission_required decorator (i.e. ``polls.can_vote`` for a permission on a model in the ``polls`` application). The decorator may also take a list of permissions. The decorator may also take an iterable of permissions. Note that :func:`~django.contrib.auth.decorators.permission_required()` also takes an optional ``login_url`` parameter. Example:: Loading @@ -599,6 +599,11 @@ The permission_required decorator (HTTP Forbidden) view<http_forbidden_view>` instead of redirecting to the login page. .. versionchanged:: 1.9 In older versions, the ``permission`` parameter only worked with strings, lists, and tuples instead of strings and any iterable. .. _applying-permissions-to-generic-views: Applying permissions to generic views Loading tests/auth_tests/test_decorators.py +10 −0 Original line number Diff line number Diff line Loading @@ -76,6 +76,16 @@ class PermissionsRequiredDecoratorTest(TestCase): resp = a_view(request) self.assertEqual(resp.status_code, 200) def test_many_permissions_in_set_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') Loading Loading
django/contrib/auth/decorators.py +2 −1 Original line number Diff line number Diff line Loading @@ -4,6 +4,7 @@ from django.conf import settings from django.contrib.auth import REDIRECT_FIELD_NAME from django.core.exceptions import PermissionDenied from django.shortcuts import resolve_url from django.utils import six from django.utils.decorators import available_attrs from django.utils.six.moves.urllib.parse import urlparse Loading Loading @@ -59,7 +60,7 @@ def permission_required(perm, login_url=None, raise_exception=False): is raised. """ def check_perms(user): if not isinstance(perm, (list, tuple)): if isinstance(perm, six.string_types): perms = (perm, ) else: perms = perm Loading
docs/releases/1.9.txt +4 −0 Original line number Diff line number Diff line Loading @@ -114,6 +114,10 @@ Minor features a deprecation warning in older versions and is no longer supported in Django 1.9). * The permission argument of :func:`~django.contrib.auth.decorators.permission_required()` accepts all kinds of iterables, not only list and tuples. :mod:`django.contrib.gis` ^^^^^^^^^^^^^^^^^^^^^^^^^^ Loading
docs/topics/auth/default.txt +6 −1 Original line number Diff line number Diff line Loading @@ -580,7 +580,7 @@ The permission_required decorator (i.e. ``polls.can_vote`` for a permission on a model in the ``polls`` application). The decorator may also take a list of permissions. The decorator may also take an iterable of permissions. Note that :func:`~django.contrib.auth.decorators.permission_required()` also takes an optional ``login_url`` parameter. Example:: Loading @@ -599,6 +599,11 @@ The permission_required decorator (HTTP Forbidden) view<http_forbidden_view>` instead of redirecting to the login page. .. versionchanged:: 1.9 In older versions, the ``permission`` parameter only worked with strings, lists, and tuples instead of strings and any iterable. .. _applying-permissions-to-generic-views: Applying permissions to generic views Loading
tests/auth_tests/test_decorators.py +10 −0 Original line number Diff line number Diff line Loading @@ -76,6 +76,16 @@ class PermissionsRequiredDecoratorTest(TestCase): resp = a_view(request) self.assertEqual(resp.status_code, 200) def test_many_permissions_in_set_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') Loading