Commit 39937de7 authored by Raphael Michel's avatar Raphael Michel Committed by Tim Graham
Browse files

Fixed #24929 -- Allowed permission_required decorator to take any iterable

parent 8b1f39a7
Loading
Loading
Loading
Loading
+2 −1
Original line number Diff line number Diff line
@@ -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
+4 −0
Original line number Diff line number Diff line
@@ -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`
^^^^^^^^^^^^^^^^^^^^^^^^^^

+6 −1
Original line number Diff line number Diff line
@@ -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
+10 −0
Original line number Diff line number Diff line
@@ -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')