1
0
mirror of https://github.com/django/django.git synced 2025-07-05 18:29:11 +00:00

generic-auth: Initial implementation and tests for the new has_permission function

git-svn-id: http://code.djangoproject.com/svn/django/branches/generic-auth@3222 bcc190cf-cafb-0310-a4f2-bffc1f526a37
This commit is contained in:
Joseph Kocherhans 2006-06-28 03:57:40 +00:00
parent 71b57627ad
commit bf629e5a4d
3 changed files with 77 additions and 0 deletions

View File

@ -1,2 +1,29 @@
LOGIN_URL = '/accounts/login/'
REDIRECT_FIELD_NAME = 'next'
class NoMatchFound(Exception): pass
class HasPermission(object):
"""
Function that supports multiple implementations via a type registry. The
implemetation called depends on the argument types.
"""
def __init__(self):
self.registry = {}
def __call__(self, user, permission, obj=None):
# TODO: this isn't very robust. Only matches on exact types. Support
# for matching subclasses and caching registry hits would be helpful,
# but we'll add that later
types = (type(user), type(permission), type(obj))
func = self.registry.get(types)
if func is not None:
return func(user, permission, obj)
else:
raise NoMatchFound, "%s\n%s" % (self.registry, types)
def register(self, user_type, permission_type, obj_type, func):
types = (user_type, permission_type, obj_type)
self.registry[types] = func
has_permission = HasPermission()

View File

@ -0,0 +1,50 @@
from django.db import models
class TestModel(models.Model):
name = models.CharField(maxlength=255)
class Admin:
pass
API_TESTS = """
# Let's create a default implementation of has_permission. For now, It should
# just call user.has_permission(permission) for the given django.contrib.auth.models.User.
# Eventually the user.has_permission implementation should be extracted here.
>>> from django.contrib.auth import has_permission
>>> def user_has_permission(user, permission, object=None):
... return user.has_perm(permission)
# Then let's register that function to be called when we get an instance of
# django.contrib.auth.models.User and a string as the permission. We use str
# as the permission type for convenience. It would be annoying to grab the
# actual Permission object instead of just using the codename. This feels kind
# of limiting, but can be revisited later.
>>> from django.contrib.auth.models import User
>>> has_permission.register(User, str, TestModel, user_has_permission)
# Now make sure it works.
>>> admin = User(username='admin', password='test', email='test@example.com', is_superuser=True)
>>> admin.save()
>>> has_permission(admin, 'testmodel.add', TestModel())
True
# Now let's create an implemetation for AnonymousUsers... it should always
# return False.
>>> def anon_has_permission(user, permission, object=None):
... return False
# Register it like before, but for AnonymousUser rather than User.
>>> from django.contrib.auth.models import AnonymousUser
>>> has_permission.register(AnonymousUser, str, TestModel, anon_has_permission)
# And make sure it works.
>>> anonymous = AnonymousUser()
>>> has_permission(anonymous, 'testmodel.add', TestModel())
False
# Let's double check that the function we registered for User still works (we're
# not just replacing the implementation of has_permission)
>>> has_permission(admin, 'testmodel.add', TestModel())
True
"""