Moved permission checking logic to model, simplyfing it and adding group support too

This commit is contained in:
Roberto Rosario
2011-05-08 03:06:34 -04:00
parent 30a32c0aff
commit 2cacae7551
2 changed files with 41 additions and 38 deletions

View File

@@ -2,6 +2,7 @@ from django.db import models
from django.utils.translation import ugettext_lazy as _
from django.contrib.contenttypes.models import ContentType
from django.contrib.contenttypes import generic
from django.contrib.auth.models import User, Group
class PermissionManager(models.Manager):
@@ -25,7 +26,34 @@ class Permission(models.Model):
def __unicode__(self):
return self.label
def get_holders(self):
return [holder.holder_object for holder in self.permissionholder_set.all()]
def has_permission(self, requester):
if isinstance(requester, User):
if requester.is_superuser or requester.is_staff:
return True
# Request is one of the permission's holders?
if requester in self.get_holders():
return True
# If not check if the requesters memberships objects is one of
# the permission's holder?
roles = RoleMember.objects.get_roles_for_member(requester)
if isinstance(requester, User):
groups = requester.groups.all()
else:
groups = []
result = False
for membership in list(set(roles) | set(groups)):
result |= self.has_permission(membership)
return result
class PermissionHolder(models.Model):
permission = models.ForeignKey(Permission, verbose_name=_(u'permission'))
@@ -40,7 +68,7 @@ class PermissionHolder(models.Model):
verbose_name_plural = _(u'permission holders')
def __unicode__(self):
return unicode(self.holder_object)
return u'%s: %s' % (self.holder_type, self.holder_object)
class Role(models.Model):
@@ -66,6 +94,12 @@ class Role(models.Model):
return ('role_list',)
class RoleMemberManager(models.Manager):
def get_roles_for_member(self, member_obj):
member_type = ContentType.objects.get_for_model(member_obj)
return [role_member.role for role_member in RoleMember.objects.filter(member_type=member_type, member_id=member_obj.pk)]
class RoleMember(models.Model):
role = models.ForeignKey(Role, verbose_name=_(u'role'))
member_type = models.ForeignKey(ContentType,
@@ -74,6 +108,8 @@ class RoleMember(models.Model):
member_id = models.PositiveIntegerField()
member_object = generic.GenericForeignKey(ct_field='member_type', fk_field='member_id')
objects = RoleMemberManager()
class Meta:
#ordering = ('label',)
verbose_name = _(u'role member')