Ticket #11010: rowlevel_permissions-r10674.diff

File rowlevel_permissions-r10674.diff, 8.2 KB (added by apollo13, 6 years ago)
  • django/contrib/auth/backends.py

    diff --git a/django/contrib/auth/backends.py b/django/contrib/auth/backends.py
    index 05f9835..6a5df18 100644
    a b class ModelBackend(object): 
    2121        except User.DoesNotExist:
    2222            return None
    2323
    24     def get_group_permissions(self, user_obj):
     24    def get_group_permissions(self, user_obj, obj=None):
    2525        """
    2626        Returns a set of permission strings that this user has through his/her
    2727        groups.
    2828        """
     29        if obj: return [] # We don't support rowlevel permissions with this backend.
    2930        if not hasattr(user_obj, '_group_perm_cache'):
    3031            cursor = connection.cursor()
    3132            # The SQL below works out to the following, after DB quoting:
    class ModelBackend(object): 
    5556            user_obj._group_perm_cache = set(["%s.%s" % (row[0], row[1]) for row in cursor.fetchall()])
    5657        return user_obj._group_perm_cache
    5758
    58     def get_all_permissions(self, user_obj):
     59    def get_all_permissions(self, user_obj, obj=None):
     60        if obj: return [] # We don't support rowlevel permissions with this backend.
    5961        if not hasattr(user_obj, '_perm_cache'):
    6062            user_obj._perm_cache = set([u"%s.%s" % (p.content_type.app_label, p.codename) for p in user_obj.user_permissions.select_related()])
    6163            user_obj._perm_cache.update(self.get_group_permissions(user_obj))
    6264        return user_obj._perm_cache
    6365
    64     def has_perm(self, user_obj, perm):
    65         return perm in self.get_all_permissions(user_obj)
     66    def has_perm(self, user_obj, perm, obj=None):
     67        return perm in self.get_all_permissions(user_obj, obj)
    6668
    6769    def has_module_perms(self, user_obj, app_label):
    6870        """
    6971        Returns True if user_obj has any permissions in the given app_label.
    7072        """
    71         for perm in self.get_all_permissions(user_obj):
     73        for perm in self.get_all_permissions(user_obj, None):
    7274            if perm[:perm.index('.')] == app_label:
    7375                return True
    7476        return False
  • django/contrib/auth/models.py

    diff --git a/django/contrib/auth/models.py b/django/contrib/auth/models.py
    index e337bec..06d591b 100644
    a b  
    11import datetime
    22import urllib
    33
     4from warnings import warn as warn_
     5
    46from django.contrib import auth
    57from django.core.exceptions import ImproperlyConfigured
    68from django.db import models
    from django.utils.translation import ugettext_lazy as _ 
    1214
    1315UNUSABLE_PASSWORD = '!' # This will never be a valid hash
    1416
     17def warn(method_name):
     18    warn_("Backend.%s needs to support obj as last parameter.",
     19          PendingDeprecationWarning, stacklevel=3)
     20
    1521try:
    1622    set
    1723except NameError:
    class User(models.Model): 
    194200    def has_usable_password(self):
    195201        return self.password != UNUSABLE_PASSWORD
    196202
    197     def get_group_permissions(self):
     203    def get_group_permissions(self, obj=None):
    198204        """
    199205        Returns a list of permission strings that this user has through
    200206        his/her groups. This method queries all available auth backends.
     207        If an object is passed in, only permissions matching this object
     208        are returned.
    201209        """
    202210        permissions = set()
    203211        for backend in auth.get_backends():
    204212            if hasattr(backend, "get_group_permissions"):
    205                 permissions.update(backend.get_group_permissions(self))
     213                try:
     214                    permissions.update(backend.get_group_permissions(self, obj))
     215                except TypeError:
     216                    # Backend doesn't support rowlevel perms, but still call it for now.
     217                    warn('get_group_permissions')
     218                    if not obj:
     219                        permissions.update(backend.get_group_permissions(self))
    206220        return permissions
    207221
    208     def get_all_permissions(self):
     222    def get_all_permissions(self, obj=None):
    209223        permissions = set()
    210224        for backend in auth.get_backends():
    211225            if hasattr(backend, "get_all_permissions"):
    212                 permissions.update(backend.get_all_permissions(self))
     226                try:
     227                    permissions.update(backend.get_all_permissions(self, obj))
     228                except TypeError:
     229                    # Backend doesn't support rowlevel perms
     230                    warn('get_all_permissions')
     231                    if not obj:
     232                        permissions.update(backend.get_all_permissions(self))
    213233        return permissions
    214234
    215     def has_perm(self, perm):
     235    def has_perm(self, perm, obj=None):
    216236        """
    217237        Returns True if the user has the specified permission. This method
    218238        queries all available auth backends, but returns immediately if any
    219239        backend returns True. Thus, a user who has permission from a single
    220         auth backend is assumed to have permission in general.
     240        auth backend is assumed to have permission in general. If an object
     241        is provided, permissions for this specific object are checked.
    221242        """
    222243        # Inactive users have no permissions.
    223244        if not self.is_active:
    class User(models.Model): 
    230251        # Otherwise we need to check the backends.
    231252        for backend in auth.get_backends():
    232253            if hasattr(backend, "has_perm"):
    233                 if backend.has_perm(self, perm):
    234                     return True
     254                try:
     255                    if backend.has_perm(self, perm, obj):
     256                        return True
     257                except TypeError:
     258                    # Backend doesn't support rowlevel perms
     259                    warn('has_perm')
     260                    if not obj:
     261                        if backend.has_perm(self, perm):
     262                            return True
    235263        return False
    236264
    237     def has_perms(self, perm_list):
    238         """Returns True if the user has each of the specified permissions."""
     265    def has_perms(self, perm_list, obj=None):
     266        """Returns True if the user has each of the specified permissions.
     267        If object is passed, it checks if the user has all required perms
     268        for this object.
     269        """
    239270        for perm in perm_list:
    240             if not self.has_perm(perm):
     271            if not self.has_perm(perm, obj):
    241272                return False
    242273        return True
    243274
  • docs/topics/auth.txt

    diff --git a/docs/topics/auth.txt b/docs/topics/auth.txt
    index 0fdf8b3..8409016 100644
    a b Methods 
    196196        :meth:`~django.contrib.auth.models.User.set_unusable_password()` has
    197197        been called for this user.
    198198
    199     .. method:: models.User.get_group_permissions()
     199    .. method:: models.User.get_group_permissions(obj=None)
    200200
    201201        Returns a list of permission strings that the user has, through his/her
    202         groups.
     202        groups. If obj is passed in, only returns the group permissions for this
     203        specific object.
    203204
    204     .. method:: models.User.get_all_permissions()
     205    .. method:: models.User.get_all_permissions(obj=None)
    205206
    206207        Returns a list of permission strings that the user has, both through
    207         group and user permissions.
     208        group and user permissions. If obj is passed in, only returns the
     209        permissions for this specific object.
    208210
    209     .. method:: models.User.has_perm(perm)
     211    .. method:: models.User.has_perm(perm, obj)
    210212
    211213        Returns ``True`` if the user has the specified permission, where perm is
    212214        in the format ``"<application name>.<lowercased model name>"``. If the
    213         user is inactive, this method will always return ``False``.
     215        user is inactive, this method will always return ``False``. If obj is
     216        passed in this method won't check the permissions for the model, but
     217        the object.
    214218
    215219    .. method:: models.User.has_perms(perm_list)
    216220
    217221        Returns ``True`` if the user has each of the specified permissions,
    218222        where each perm is in the format ``"package.codename"``. If the user is
    219         inactive, this method will always return ``False``.
     223        inactive, this method will always return ``False``. If obj is passed in
     224        this method won't check the permissions for the model, but the object.
    220225
    221226    .. method:: models.User.has_module_perms(package_name)
    222227
Back to Top