from __future__ import unicode_literals import logging from django.contrib.auth.models import Group from django.core.urlresolvers import reverse from django.db import models from django.utils.encoding import python_2_unicode_compatible from django.utils.translation import ugettext_lazy as _ from .classes import Permission from .managers import RoleManager, StoredPermissionManager logger = logging.getLogger(__name__) @python_2_unicode_compatible class StoredPermission(models.Model): namespace = models.CharField(max_length=64, verbose_name=_('Namespace')) name = models.CharField(max_length=64, verbose_name=_('Name')) objects = StoredPermissionManager() def __init__(self, *args, **kwargs): super(StoredPermission, self).__init__(*args, **kwargs) try: self.volatile_permission = Permission.get( {'pk': '%s.%s' % (self.namespace, self.name)}, proxy_only=True ) except KeyError: # Must be a deprecated permission in the database that is no # longer used in the current code pass def __str__(self): return unicode(getattr(self, 'volatile_permission', self.name)) def natural_key(self): return (self.namespace, self.name) class Meta: ordering = ('namespace',) unique_together = ('namespace', 'name') verbose_name = _('Permission') verbose_name_plural = _('Permissions') def requester_has_this(self, user): if user.is_superuser or user.is_staff: logger.debug('Permission "%s" granted to user "%s" as superuser or staff', self, user) return True # Request is one of the permission's holders? for group in user.groups.all(): for role in group.roles.all(): if self in role.permissions.all(): logger.debug('Permission "%s" granted to user "%s" through role "%s"', self, user, role) return True logger.debug('Fallthru: Permission "%s" not granted to user "%s"', self, user) return False @python_2_unicode_compatible class Role(models.Model): label = models.CharField( max_length=64, unique=True, verbose_name=_('Label') ) permissions = models.ManyToManyField( StoredPermission, related_name='roles', verbose_name=_('Permissions') ) groups = models.ManyToManyField( Group, related_name='roles', verbose_name=_('Groups') ) objects = RoleManager() def __str__(self): return self.label def get_absolute_url(self): return reverse('permissions:role_list') def natural_key(self): return (self.label,) natural_key.dependencies = ['auth.Group', 'permissions.StoredPermission'] class Meta: ordering = ('label',) verbose_name = _('Role') verbose_name_plural = _('Roles')