diff options
| author | Raphael Michel <mail@raphaelmichel.de> | 2015-06-05 10:08:19 +0200 |
|---|---|---|
| committer | Tim Graham <timograham@gmail.com> | 2015-06-08 13:44:39 -0400 |
| commit | 39937de7e60052d3ffa9f07fdbb9262aced35d61 (patch) | |
| tree | a49b4fd14a34fb0c68825f978031d56b390fe350 | |
| parent | 8b1f39a727be91aab40bdb37235718ed63ae1d50 (diff) | |
Fixed #24929 -- Allowed permission_required decorator to take any iterable
| -rw-r--r-- | django/contrib/auth/decorators.py | 3 | ||||
| -rw-r--r-- | docs/releases/1.9.txt | 4 | ||||
| -rw-r--r-- | docs/topics/auth/default.txt | 7 | ||||
| -rw-r--r-- | tests/auth_tests/test_decorators.py | 10 |
4 files changed, 22 insertions, 2 deletions
diff --git a/django/contrib/auth/decorators.py b/django/contrib/auth/decorators.py index 9b2504b33c..6ab428e9cd 100644 --- a/django/contrib/auth/decorators.py +++ b/django/contrib/auth/decorators.py @@ -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 @@ -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 diff --git a/docs/releases/1.9.txt b/docs/releases/1.9.txt index a3fb56c6c0..55906864ef 100644 --- a/docs/releases/1.9.txt +++ b/docs/releases/1.9.txt @@ -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` ^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/docs/topics/auth/default.txt b/docs/topics/auth/default.txt index 2df53816de..9e2d549fd1 100644 --- a/docs/topics/auth/default.txt +++ b/docs/topics/auth/default.txt @@ -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:: @@ -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 diff --git a/tests/auth_tests/test_decorators.py b/tests/auth_tests/test_decorators.py index ff1b1f52a2..61c1962a74 100644 --- a/tests/auth_tests/test_decorators.py +++ b/tests/auth_tests/test_decorators.py @@ -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') |
