Ticket #11010: rowlevel_perms@12123_#11010.diff
File rowlevel_perms@12123_#11010.diff, 16.6 KB (added by , 15 years ago) |
---|
-
django/contrib/auth/backends.py
diff --git a/django/contrib/auth/backends.py b/django/contrib/auth/backends.py index 05f9835..df73a29 100644
a b class ModelBackend(object): 11 11 """ 12 12 Authenticates against django.contrib.auth.models.User. 13 13 """ 14 supports_object_perms = False 15 14 16 # TODO: Model, login attribute name and password attribute name should be 15 17 # configurable. 16 18 def authenticate(self, username=None, password=None): -
django/contrib/auth/models.py
diff --git a/django/contrib/auth/models.py b/django/contrib/auth/models.py index e337bec..e969cdd 100644
a b 1 1 import datetime 2 2 import urllib 3 3 4 from warnings import warn as warn_ 5 4 6 from django.contrib import auth 5 7 from django.core.exceptions import ImproperlyConfigured 6 8 from django.db import models … … from django.utils.translation import ugettext_lazy as _ 12 14 13 15 UNUSABLE_PASSWORD = '!' # This will never be a valid hash 14 16 17 def check_and_warn(backend): 18 if getattr(backend, 'supports_object_perms', False): 19 return True 20 else: 21 warn_("%s should define `supports_object_perms`." % backend, 22 PendingDeprecationWarning, stacklevel=3) 23 return False 24 15 25 try: 16 26 set 17 27 except NameError: … … class User(models.Model): 194 204 def has_usable_password(self): 195 205 return self.password != UNUSABLE_PASSWORD 196 206 197 def get_group_permissions(self ):207 def get_group_permissions(self, obj=None): 198 208 """ 199 209 Returns a list of permission strings that this user has through 200 210 his/her groups. This method queries all available auth backends. 211 If an object is passed in, only permissions matching this object 212 are returned. 201 213 """ 202 214 permissions = set() 203 215 for backend in auth.get_backends(): 204 216 if hasattr(backend, "get_group_permissions"): 205 permissions.update(backend.get_group_permissions(self)) 217 if obj: 218 if check_and_warn(backend): 219 permissions.update(backend.get_group_permissions(self, obj)) 220 else: 221 permissions.update(backend.get_group_permissions(self)) 206 222 return permissions 207 223 208 def get_all_permissions(self ):224 def get_all_permissions(self, obj=None): 209 225 permissions = set() 210 226 for backend in auth.get_backends(): 211 227 if hasattr(backend, "get_all_permissions"): 212 permissions.update(backend.get_all_permissions(self)) 228 if obj: 229 if check_and_warn(backend): 230 permissions.update(backend.get_all_permissions(self, obj)) 231 else: 232 permissions.update(backend.get_all_permissions(self)) 213 233 return permissions 214 234 215 def has_perm(self, perm ):235 def has_perm(self, perm, obj=None): 216 236 """ 217 237 Returns True if the user has the specified permission. This method 218 238 queries all available auth backends, but returns immediately if any 219 239 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. 221 242 """ 222 243 # Inactive users have no permissions. 223 244 if not self.is_active: … … class User(models.Model): 230 251 # Otherwise we need to check the backends. 231 252 for backend in auth.get_backends(): 232 253 if hasattr(backend, "has_perm"): 233 if backend.has_perm(self, perm): 234 return True 254 if obj: 255 if check_and_warn(backend): 256 if backend.has_perm(self, perm, obj): 257 return True 258 else: 259 if backend.has_perm(self, perm): 260 return True 235 261 return False 236 262 237 def has_perms(self, perm_list): 238 """Returns True if the user has each of the specified permissions.""" 263 def has_perms(self, perm_list, obj=None): 264 """Returns True if the user has each of the specified permissions. 265 If object is passed, it checks if the user has all required perms 266 for this object. 267 """ 239 268 for perm in perm_list: 240 if not self.has_perm(perm ):269 if not self.has_perm(perm, obj): 241 270 return False 242 271 return True 243 272 -
django/contrib/auth/tests/__init__.py
diff --git a/django/contrib/auth/tests/__init__.py b/django/contrib/auth/tests/__init__.py index 14428d0..9a078cf 100644
a b from django.contrib.auth.tests.views \ 4 4 from django.contrib.auth.tests.forms import FORM_TESTS 5 5 from django.contrib.auth.tests.remote_user \ 6 6 import RemoteUserTest, RemoteUserNoCreateTest, RemoteUserCustomTest 7 from django.contrib.auth.tests.auth_backends import BackendTest, RowlevelBackendTest 7 8 from django.contrib.auth.tests.tokens import TOKEN_GENERATOR_TESTS 8 9 9 10 # The password for the fixture data users is 'password' -
new file django/contrib/auth/tests/auth_backends.py
diff --git a/django/contrib/auth/tests/auth_backends.py b/django/contrib/auth/tests/auth_backends.py new file mode 100644 index 0000000..3ee07a2
- + 1 from django.conf import settings 2 from django.contrib.auth.backends import ModelBackend 3 from django.contrib.auth.models import User, Group, Permission, AnonymousUser 4 from django.contrib.contenttypes.models import ContentType 5 6 from django.test import TestCase 7 8 try: 9 set 10 except NameError: 11 from sets import Set as set # Python 2.3 fallback 12 13 class BackendTest(TestCase): 14 15 backend = 'django.contrib.auth.backends.ModelBackend' 16 17 def setUp(self): 18 self.curr_auth = settings.AUTHENTICATION_BACKENDS 19 settings.AUTHENTICATION_BACKENDS = (self.backend,) 20 User.objects.create_user('test', 'test@example.com', 'test') 21 22 23 def tearDown(self): 24 settings.AUTHENTICATION_BACKENDS = self.curr_auth 25 26 def test_has_perm(self): 27 user = User.objects.get(username="test") 28 self.assertEqual(user.has_perm("auth.test"), False) 29 user.is_staff = True 30 user.save() 31 self.assertEqual(user.has_perm("auth.test"), False) 32 user.is_superuser = True 33 user.save() 34 self.assertEqual(user.has_perm("auth.test"), True) 35 user.is_staff = False 36 user.is_superuser = False 37 user.save() 38 self.assertEqual(user.has_perm("auth.test"), False) 39 40 def test_custom_perms(self): 41 user = User.objects.get(username="test") 42 content_type=ContentType.objects.get_for_model(Group) 43 perm = Permission.objects.create(name="test", content_type=content_type, codename="test") 44 user.user_permissions.add(perm) 45 user.save() 46 47 # reloading user to purge the _perm_cache 48 49 user = User.objects.get(username="test") 50 self.assertEqual(user.get_all_permissions() == set([u'auth.test']), True) 51 self.assertEqual(user.get_group_permissions(), set([])) 52 self.assertEqual(user.has_module_perms("Group"), False) 53 self.assertEqual(user.has_module_perms("auth"), True) 54 perm = Permission.objects.create(name="test2", content_type=content_type, codename="test2") 55 user.user_permissions.add(perm) 56 user.save() 57 perm = Permission.objects.create(name="test3", content_type=content_type, codename="test3") 58 user.user_permissions.add(perm) 59 user.save() 60 user = User.objects.get(username="test") 61 self.assertEqual(user.get_all_permissions(), set([u'auth.test2', u'auth.test', u'auth.test3'])) 62 self.assertEqual(user.has_perm('test'), False) 63 self.assertEqual(user.has_perm('auth.test'), True) 64 self.assertEqual(user.has_perms(['auth.test2', 'auth.test3']), True) 65 perm = Permission.objects.create(name="test_group", content_type=content_type, codename="test_group") 66 group = Group.objects.create(name='test_group') 67 group.permissions.add(perm) 68 group.save() 69 user.groups.add(group) 70 user = User.objects.get(username="test") 71 exp = set([u'auth.test2', u'auth.test', u'auth.test3', u'auth.test_group']) 72 self.assertEqual(user.get_all_permissions(), exp) 73 self.assertEqual(user.get_group_permissions(), set([u'auth.test_group'])) 74 self.assertEqual(user.has_perms(['auth.test3', 'auth.test_group']), True) 75 76 user = AnonymousUser() 77 self.assertEqual(user.has_perm('test'), False) 78 self.assertEqual(user.has_perms(['auth.test2', 'auth.test3']), False) 79 80 class TestObj(object): 81 pass 82 83 class SimpleRowlevelBackend(object): 84 supports_object_perms = True 85 86 def has_perm(self, user, perm, obj=None): 87 if not obj: 88 return # We only support row level perms 89 90 if isinstance(obj, TestObj) and user.username == "apollo13": 91 return True 92 else: 93 return False 94 95 def get_all_permissions(self, user, obj=None): 96 if not obj: 97 return [] # We only support row level perms 98 99 if not isinstance(obj, TestObj): 100 return ["none"] 101 102 if user.username == "apollo13": 103 return ["simple", "advanced"] 104 else: 105 return ["simple"] 106 107 class RowlevelBackendTest(TestCase): 108 109 backend = 'django.contrib.auth.tests.auth_backends.SimpleRowlevelBackend' 110 111 def setUp(self): 112 self.curr_auth = settings.AUTHENTICATION_BACKENDS 113 settings.AUTHENTICATION_BACKENDS = self.curr_auth + (self.backend,) 114 self.user1 = User.objects.create_user('test', 'test@example.com', 'test') 115 self.user2 = User.objects.create_user('apollo13', 'test2@example.com', 'test') 116 117 def tearDown(self): 118 settings.AUTHENTICATION_BACKENDS = self.curr_auth 119 120 def test_has_perm(self): 121 self.assertEqual(self.user1.has_perm('perm', TestObj()), False) 122 self.assertEqual(self.user2.has_perm('perm', TestObj()), True) 123 self.assertEqual(self.user2.has_perm('perm'), False) 124 125 def test_get_all_permissions(self): 126 self.assertEqual(self.user1.get_all_permissions(TestObj()), set(["simple"])) 127 self.assertEqual(self.user2.get_all_permissions(TestObj()), set(["simple", "advanced"])) 128 self.assertEqual(self.user2.get_all_permissions(), set([])) -
docs/topics/auth.txt
diff --git a/docs/topics/auth.txt b/docs/topics/auth.txt index 33461a0..9baa732 100644
a b Methods 199 199 :meth:`~django.contrib.auth.models.User.set_unusable_password()` has 200 200 been called for this user. 201 201 202 .. method:: models.User.get_group_permissions( )202 .. method:: models.User.get_group_permissions(obj=None) 203 203 204 204 Returns a list of permission strings that the user has, through his/her 205 groups. 205 groups. If ``obj`` is passed in, only returns the group permissions for 206 this specific object. 206 207 207 .. method:: models.User.get_all_permissions( )208 .. method:: models.User.get_all_permissions(obj=None) 208 209 209 210 Returns a list of permission strings that the user has, both through 210 group and user permissions. 211 group and user permissions. If ``obj`` is passed in, only returns the 212 permissions for this specific object. 211 213 212 .. method:: models.User.has_perm(perm) 214 215 .. method:: models.User.has_perm(perm, obj=None) 213 216 214 217 Returns ``True`` if the user has the specified permission, where perm is 215 218 in the format ``"<app label>.<permission codename>"``. 216 If the user is inactive, this method will always return ``False``. 219 If the user is inactive, this method will always return ``False``. If 220 ``obj`` is passed in this method won't check the permissions for the model, 221 but the object. 217 222 218 .. method:: models.User.has_perms(perm_list )223 .. method:: models.User.has_perms(perm_list, obj=None) 219 224 220 225 Returns ``True`` if the user has each of the specified permissions, 221 226 where each perm is in the format 222 227 ``"<app label>.<permission codename>"``. If the user is inactive, 223 this method will always return ``False``. 228 this method will always return ``False``. If ``obj`` is passed in 229 this method won't check the permissions for the model, but the object. 224 230 225 231 .. method:: models.User.has_module_perms(package_name) 226 232 … … A full authorization implementation can be found in 1510 1516 the ``auth_permission`` table most of the time. 1511 1517 1512 1518 .. _django/contrib/auth/backends.py: http://code.djangoproject.com/browser/django/trunk/django/contrib/auth/backends.py 1519 1520 Handling object permissions 1521 --------------------------- 1522 1523 Django's permission framework has a foundation for object permissions, though 1524 there is no implementation for it in the core. This means, that checking for 1525 object permissions will always return ``False`` or an empty list (depending on 1526 the check performed). To enable object permissions you will have to write your 1527 own Backend which does support them, the only change you have to do is to add 1528 an ``obj`` parameter to the permission functions and set ``supports_objects_perms`` 1529 to ``True``. In Django 1.2 a non existing ``supports_objects_perms`` will raise a 1530 ``PendingDeprecationWarning``. In 1.3 a non existant ``support_object_perms`` 1531 attribute will raise an error and setting it to ``False`` will raise a 1532 ``DeprecationWarning``. In 1.4 it's assumed that every backend supports object 1533 permissions and no checking is performed, which means not supporting ``obj`` as 1534 parameter will raise a ``TypeError``. -
deleted file tests/regressiontests/auth_backends/tests.py
diff --git a/tests/regressiontests/auth_backends/__init__.py b/tests/regressiontests/auth_backends/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/tests/regressiontests/auth_backends/models.py b/tests/regressiontests/auth_backends/models.py deleted file mode 100644 index e69de29..0000000 diff --git a/tests/regressiontests/auth_backends/tests.py b/tests/regressiontests/auth_backends/tests.py deleted file mode 100644 index d22f0bf..0000000
+ - 1 try:2 set3 except NameError:4 from sets import Set as set # Python 2.3 fallback5 6 __test__ = {'API_TESTS': """7 >>> from django.contrib.auth.models import User, Group, Permission, AnonymousUser8 >>> from django.contrib.contenttypes.models import ContentType9 10 # No Permissions assigned yet, should return False except for superuser11 12 >>> user = User.objects.create_user('test', 'test@example.com', 'test')13 >>> user.has_perm("auth.test")14 False15 >>> user.is_staff=True16 >>> user.save()17 >>> user.has_perm("auth.test")18 False19 >>> user.is_superuser=True20 >>> user.save()21 >>> user.has_perm("auth.test")22 True23 >>> user.is_staff = False24 >>> user.is_superuser = False25 >>> user.save()26 >>> user.has_perm("auth.test")27 False28 >>> content_type=ContentType.objects.get_for_model(Group)29 >>> perm = Permission.objects.create(name="test", content_type=content_type, codename="test")30 >>> user.user_permissions.add(perm)31 >>> user.save()32 33 # reloading user to purge the _perm_cache34 35 >>> user = User.objects.get(username="test")36 >>> user.get_all_permissions() == set([u'auth.test'])37 True38 >>> user.get_group_permissions() == set([])39 True40 >>> user.has_module_perms("Group")41 False42 >>> user.has_module_perms("auth")43 True44 >>> perm = Permission.objects.create(name="test2", content_type=content_type, codename="test2")45 >>> user.user_permissions.add(perm)46 >>> user.save()47 >>> perm = Permission.objects.create(name="test3", content_type=content_type, codename="test3")48 >>> user.user_permissions.add(perm)49 >>> user.save()50 >>> user = User.objects.get(username="test")51 >>> user.get_all_permissions() == set([u'auth.test2', u'auth.test', u'auth.test3'])52 True53 >>> user.has_perm('test')54 False55 >>> user.has_perm('auth.test')56 True57 >>> user.has_perms(['auth.test2', 'auth.test3'])58 True59 >>> perm = Permission.objects.create(name="test_group", content_type=content_type, codename="test_group")60 >>> group = Group.objects.create(name='test_group')61 >>> group.permissions.add(perm)62 >>> group.save()63 >>> user.groups.add(group)64 >>> user = User.objects.get(username="test")65 >>> exp = set([u'auth.test2', u'auth.test', u'auth.test3', u'auth.test_group'])66 >>> user.get_all_permissions() == exp67 True68 >>> user.get_group_permissions() == set([u'auth.test_group'])69 True70 >>> user.has_perms(['auth.test3', 'auth.test_group'])71 True72 73 >>> user = AnonymousUser()74 >>> user.has_perm('test')75 False76 >>> user.has_perms(['auth.test2', 'auth.test3'])77 False78 """}