Django

Code

Ticket #5457: full_diff.2.diff

File full_diff.2.diff, 11.8 kB (added by Florian Apolloner, 2 years ago)

full diff including docs and tests (I hope everything works, as I am really tired now XD) [last one missed the tests...]

  • django/contrib/auth/backends.py

    old new  
     1from django.db import connection, models 
    12from django.contrib.auth.models import User 
    23 
    34class ModelBackend: 
     
    1415        except User.DoesNotExist: 
    1516            return None 
    1617 
     18    def get_group_permissions(self, user_obj): 
     19        "Returns a list of permission strings that this user has through his/her groups." 
     20        if not hasattr(user_obj, '_group_perm_cache'): 
     21            cursor = connection.cursor() 
     22            # The SQL below works out to the following, after DB quoting: 
     23            # cursor.execute(""" 
     24            #     SELECT ct."app_label", p."codename" 
     25            #     FROM "auth_permission" p, "auth_group_permissions" gp, "auth_user_groups" ug, "django_content_type" ct 
     26            #     WHERE p."id" = gp."permission_id" 
     27            #         AND gp."group_id" = ug."group_id" 
     28            #         AND ct."id" = p."content_type_id" 
     29            #         AND ug."user_id" = %s, [self.id]) 
     30            qn = connection.ops.quote_name 
     31            sql = """ 
     32                SELECT ct.%s, p.%s 
     33                FROM %s p, %s gp, %s ug, %s ct 
     34                WHERE p.%s = gp.%s 
     35                    AND gp.%s = ug.%s 
     36                    AND ct.%s = p.%s 
     37                    AND ug.%s = %%s""" % ( 
     38                qn('app_label'), qn('codename'), 
     39                qn('auth_permission'), qn('auth_group_permissions'), 
     40                qn('auth_user_groups'), qn('django_content_type'), 
     41                qn('id'), qn('permission_id'), 
     42                qn('group_id'), qn('group_id'), 
     43                qn('id'), qn('content_type_id'), 
     44                qn('user_id'),) 
     45            cursor.execute(sql, [user_obj.id]) 
     46            user_obj._group_perm_cache = set(["%s.%s" % (row[0], row[1]) for row in cursor.fetchall()]) 
     47        return user_obj._group_perm_cache 
     48     
     49    def get_all_permissions(self, user_obj): 
     50        if not hasattr(user_obj, '_perm_cache'): 
     51            user_obj._perm_cache = set([u"%s.%s" % (p.content_type.app_label, p.codename) for p in user_obj.user_permissions.select_related()]) 
     52            user_obj._perm_cache.update(self.get_group_permissions(user_obj)) 
     53        return user_obj._perm_cache 
     54 
     55    def has_perm(self, user_obj, perm): 
     56        return perm in self.get_all_permissions(user_obj) 
     57 
     58    def has_module_perms(self, user_obj, app_label): 
     59        return bool(len([p for p in self.get_all_permissions(user_obj) if p[:p.index('.')] == app_label])) 
     60 
     61 
     62 
    1763    def get_user(self, user_id): 
    1864        try: 
    1965            return User.objects.get(pk=user_id) 
  • django/contrib/auth/models.py

    old new  
     1from django.contrib.auth import get_backends 
    12from django.core import validators 
    23from django.core.exceptions import ImproperlyConfigured 
    34from django.db import connection, models 
     
    177178        return self.password != UNUSABLE_PASSWORD 
    178179 
    179180    def get_group_permissions(self): 
    180         "Returns a list of permission strings that this user has through his/her groups." 
    181         if not hasattr(self, '_group_perm_cache'): 
    182             cursor = connection.cursor() 
    183             # The SQL below works out to the following, after DB quoting: 
    184             # cursor.execute(""" 
    185             #     SELECT ct."app_label", p."codename" 
    186             #     FROM "auth_permission" p, "auth_group_permissions" gp, "auth_user_groups" ug, "django_content_type" ct 
    187             #     WHERE p."id" = gp."permission_id" 
    188             #         AND gp."group_id" = ug."group_id" 
    189             #         AND ct."id" = p."content_type_id" 
    190             #         AND ug."user_id" = %s, [self.id]) 
    191             qn = connection.ops.quote_name 
    192             sql = """ 
    193                 SELECT ct.%s, p.%s 
    194                 FROM %s p, %s gp, %s ug, %s ct 
    195                 WHERE p.%s = gp.%s 
    196                     AND gp.%s = ug.%s 
    197                     AND ct.%s = p.%s 
    198                     AND ug.%s = %%s""" % ( 
    199                 qn('app_label'), qn('codename'), 
    200                 qn('auth_permission'), qn('auth_group_permissions'), 
    201                 qn('auth_user_groups'), qn('django_content_type'), 
    202                 qn('id'), qn('permission_id'), 
    203                 qn('group_id'), qn('group_id'), 
    204                 qn('id'), qn('content_type_id'), 
    205                 qn('user_id'),) 
    206             cursor.execute(sql, [self.id]) 
    207             self._group_perm_cache = set(["%s.%s" % (row[0], row[1]) for row in cursor.fetchall()]) 
    208         return self._group_perm_cache 
     181        """ 
     182        Returns a list of permission strings that this user has through his/her groups. 
     183        This method queries the available backends. 
     184        """ 
     185        group_permissions = set([]) 
     186        for backend in get_backends(): 
     187            # Backend does not support this method, so skip it 
     188            if not hasattr(backend, "get_group_permissions"): continue 
     189            group_permissions.update(backend.get_group_permissions(self)) 
     190        return group_permissions 
    209191 
    210192    def get_all_permissions(self): 
    211         if not hasattr(self, '_perm_cache'): 
    212             self._perm_cache = set([u"%s.%s" % (p.content_type.app_label, p.codename) for p in self.user_permissions.select_related()]) 
    213             self._perm_cache.update(self.get_group_permissions()) 
    214         return self._perm_cache 
     193        permissions = set([]) 
     194        for backend in get_backends(): 
     195            # Backend does not support this method, so skip it 
     196            if not hasattr(backend, "get_all_permissions"): continue 
     197            permissions.update(backend.get_all_permissions(self)) 
     198        return permissions  
    215199 
    216200    def has_perm(self, perm): 
    217         "Returns True if the user has the specified permission." 
     201        """ 
     202        Returns True if the user has the specified permission. 
     203        This method queries the available backends and stops on 
     204        the first "True". 
     205        """ 
    218206        if not self.is_active: 
    219207            return False 
    220208        if self.is_superuser: 
    221209            return True 
    222         return perm in self.get_all_permissions() 
     210        for backend in get_backends(): 
     211            # Backend does not support this method, so skip it 
     212            if not hasattr(backend, "has_perm"): continue 
     213            if backend.has_perm(self, perm): 
     214                return True 
     215        return False 
    223216 
    224217    def has_perms(self, perm_list): 
    225218        "Returns True if the user has each of the specified permissions." 
     
    229222        return True 
    230223 
    231224    def has_module_perms(self, app_label): 
    232         "Returns True if the user has any permissions in the given app label." 
     225        """ 
     226        Returns True if the user has any permissions in the given app label. 
     227        This method queries the available backends and stops on 
     228        the first "True". 
     229        """ 
    233230        if not self.is_active: 
    234231            return False 
    235232        if self.is_superuser: 
    236233            return True 
    237         return bool(len([p for p in self.get_all_permissions() if p[:p.index('.')] == app_label])) 
     234        for backend in get_backends(): 
     235            # Backend does not support this method, so skip it 
     236            if not hasattr(backend, "has_module_perms"): continue 
     237            if backend.has_module_perms(self, app_label): 
     238                return True 
     239        return False 
    238240 
    239241    def get_and_delete_messages(self): 
    240242        messages = [] 
  • tests/regressiontests/auth_permission_backend/tests.py

    old new  
     1# -*- coding: utf-8 -*- 
     2 
     3from django.contrib.auth.models import User, Group, Permission 
     4from django.contrib.contenttypes.models import ContentType 
     5 
     6auth_tests = r""" 
     7# No Permissions assigned yet, should return False except for superuser 
     8 
     9>>> user = User.objects.create_user('test', 'test@example.com', 'test') 
     10>>> user.has_perm("auth.test") 
     11False 
     12>>> user.is_staff=True 
     13>>> user.save() 
     14>>> user.has_perm("auth.test") 
     15False 
     16>>> user.is_superuser=True 
     17>>> user.save() 
     18>>> user.has_perm("auth.test") 
     19True 
     20>>> user.is_staff = False 
     21>>> user.is_superuser = False 
     22>>> user.save() 
     23>>> user.has_perm("auth.test") 
     24False 
     25>>> content_type=ContentType.objects.get_for_model(Group) 
     26>>> perm = Permission.objects.create(name="test", content_type=content_type, codename="test") 
     27>>> user.user_permissions.add(perm) 
     28>>> user.save() 
     29 
     30# reloading user to purge the _perm_cache 
     31 
     32>>> user = User.objects.get(username="test") 
     33>>> user.get_all_permissions() 
     34set([u'auth.test']) 
     35>>> user.get_group_permissions() 
     36set([]) 
     37>>> user.has_module_perms("Group") 
     38False 
     39>>> user.has_module_perms("auth") 
     40True 
     41>>> perm = Permission.objects.create(name="test2", content_type=content_type, codename="test2") 
     42>>> user.user_permissions.add(perm) 
     43>>> user.save() 
     44>>> perm = Permission.objects.create(name="test3", content_type=content_type, codename="test3") 
     45>>> user.user_permissions.add(perm) 
     46>>> user.save() 
     47>>> user = User.objects.get(username="test") 
     48>>> user.get_all_permissions() 
     49set([u'auth.test2', u'auth.test', u'auth.test3']) 
     50>>> user.has_perm('test') 
     51False 
     52>>> user.has_perm('auth.test') 
     53True 
     54>>> user.has_perms(['auth.test2', 'auth.test3']) 
     55True 
     56>>> perm = Permission.objects.create(name="test_group", content_type=content_type, codename="test_group") 
     57>>> group = Group.objects.create(name='test_group') 
     58>>> group.permissions.add(perm) 
     59>>> group.save() 
     60>>> user.groups.add(group) 
     61>>> user = User.objects.get(username="test") 
     62>>> user.get_all_permissions() 
     63set([u'auth.test2', u'auth.test', u'auth.test3', u'auth.test_group']) 
     64>>> user.get_group_permissions() 
     65set([u'auth.test_group']) 
     66>>> user.has_perms(['auth.test3', 'auth.test_group']) 
     67True 
     68""" 
     69 
     70__test__ = { 
     71    'auth_permission_test': auth_tests, 
     72} 
     73 
     74if __name__ == "__main__": 
     75    import doctest 
     76    doctest.testmod() 
  • docs/authentication.txt

    old new  
    10411041                return User.objects.get(pk=user_id) 
    10421042            except User.DoesNotExist: 
    10431043                return None 
     1044 
     1045Optionally the Backend allows you to specify any of the permission methods of 
     1046the ``User`` object (except from ``has_perms`` which calls ``has_perm`` for each 
     1047perm in the list, and ``has_perm`` can be specified in the backend). 
     1048This will allow your backend to handle the permissions, if one backend return 
     1049``True`` in a permission check, the user will have the permission. 
     1050 
     1051Here is an sample implementation for ``has_perm`` extending the above exmaple:: 
     1052         
     1053        # The permission functions all take the user_obj as first (besides the self of  
     1054        # the backend, of course) argument and the rest 
     1055        # is as you would call it with ``User.*`` 
     1056        def has_perm(self, user_obj, perm): 
     1057            # we give the user admin the right to do everything. 
     1058            if user_obj.username == "admin": 
     1059                return True 
     1060            else: 
     1061                return False 
     1062 
     1063A full implementation can be found in ``django/contrib/auth/backends.py`` _, which is the 
     1064default backend and queries the ``auth_permission``-table most of the time. 
     1065 
     1066.. _django/contrib/auth/backends.py: http://code.djangoproject.com/browser/django/trunk/django/contrib/auth/backends.py