mirror of
https://github.com/django/django.git
synced 2025-07-05 10:19:20 +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:
parent
71b57627ad
commit
bf629e5a4d
@ -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()
|
||||
|
0
tests/regressiontests/authorization/__init__.py
Normal file
0
tests/regressiontests/authorization/__init__.py
Normal file
50
tests/regressiontests/authorization/models.py
Normal file
50
tests/regressiontests/authorization/models.py
Normal 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
|
||||
|
||||
"""
|
Loading…
x
Reference in New Issue
Block a user