Use the new AddRemove View for the Role's group and permissions views as well as the Group's role views. Convert the API to use viewsets. Add more tests. Add role created and edited events. Add event subscription support to roles. Signed-off-by: Roberto Rosario <Roberto.Rosario@mayan-edms.com>
146 lines
4.1 KiB
Python
146 lines
4.1 KiB
Python
from __future__ import unicode_literals
|
|
|
|
import itertools
|
|
import logging
|
|
|
|
from django.apps import apps
|
|
from django.core.exceptions import PermissionDenied
|
|
from django.utils.encoding import force_text, python_2_unicode_compatible
|
|
from django.utils.translation import ugettext_lazy as _
|
|
|
|
from .exceptions import InvalidNamespace
|
|
|
|
logger = logging.getLogger(__name__)
|
|
|
|
|
|
@python_2_unicode_compatible
|
|
class PermissionNamespace(object):
|
|
_registry = {}
|
|
|
|
@classmethod
|
|
def all(cls):
|
|
return cls._registry.values()
|
|
|
|
@classmethod
|
|
def get(cls, name):
|
|
try:
|
|
return cls._registry[name]
|
|
except KeyError:
|
|
raise InvalidNamespace(
|
|
'Invalid namespace name. This is probably an obsolete '
|
|
'permission namespace, execute the management command '
|
|
'"purgepermissions" and try again.'
|
|
)
|
|
|
|
def __init__(self, label, name):
|
|
self.label = label
|
|
self.name = name
|
|
self.permissions = []
|
|
self.__class__._registry[name] = self
|
|
|
|
def __str__(self):
|
|
return force_text(self.label)
|
|
|
|
def add_permission(self, name, label):
|
|
permission = Permission(namespace=self, name=name, label=label)
|
|
self.permissions.append(permission)
|
|
return permission
|
|
|
|
def get_permissions(self):
|
|
result = {}
|
|
for permission in self.permissions:
|
|
result[permission.pk] = permission
|
|
|
|
return result
|
|
|
|
|
|
@python_2_unicode_compatible
|
|
class Permission(object):
|
|
_permissions = {}
|
|
_stored_permissions_cache = {}
|
|
|
|
@classmethod
|
|
def all(cls, as_choices=False):
|
|
if as_choices:
|
|
results = []
|
|
|
|
for namespace, permissions in itertools.groupby(cls.all(), lambda entry: entry.namespace):
|
|
permission_options = [
|
|
(force_text(permission.pk), permission) for permission in permissions
|
|
]
|
|
results.append(
|
|
(namespace, permission_options)
|
|
)
|
|
|
|
return results
|
|
else:
|
|
# Return sorted permisions by namespace.name
|
|
return sorted(
|
|
cls._permissions.values(), key=lambda x: x.namespace.name
|
|
)
|
|
|
|
@classmethod
|
|
def check_user_permission(cls, permission, user):
|
|
if permission.stored_permission.user_has_this(user=user):
|
|
return True
|
|
|
|
raise PermissionDenied(_('Insufficient permissions.'))
|
|
|
|
@classmethod
|
|
def get(cls, pk, proxy_only=False):
|
|
# TODO: Split into .get which returns the stored permission model and
|
|
# .get_volatile which returns the class of type Permission
|
|
if proxy_only:
|
|
return cls._permissions[pk]
|
|
else:
|
|
return cls._permissions[pk].stored_permission
|
|
|
|
@classmethod
|
|
def get_for_holder(cls, holder):
|
|
StoredPermission = apps.get_model(
|
|
app_label='permissions', model_name='StoredPermission'
|
|
)
|
|
|
|
return StoredPermission.get_for_holder(holder)
|
|
|
|
@classmethod
|
|
def invalidate_cache(cls):
|
|
cls._stored_permissions_cache = {}
|
|
|
|
@classmethod
|
|
def refresh(cls):
|
|
for permission in cls.all():
|
|
permission.stored_permission
|
|
|
|
def __init__(self, namespace, name, label):
|
|
self.namespace = namespace
|
|
self.name = name
|
|
self.label = label
|
|
self.pk = self.get_pk()
|
|
self.__class__._permissions[self.pk] = self
|
|
|
|
def __repr__(self):
|
|
return self.pk
|
|
|
|
def __str__(self):
|
|
return force_text(self.label)
|
|
|
|
def get_pk(self):
|
|
return '%s.%s' % (self.namespace.name, self.name)
|
|
|
|
@property
|
|
def stored_permission(self):
|
|
try:
|
|
return self.__class__._stored_permissions_cache[self.pk]
|
|
except KeyError:
|
|
StoredPermission = apps.get_model(
|
|
app_label='permissions', model_name='StoredPermission'
|
|
)
|
|
|
|
stored_permission, created = StoredPermission.objects.get_or_create(
|
|
namespace=self.namespace.name,
|
|
name=self.name,
|
|
)
|
|
self.__class__._stored_permissions_cache[self.pk] = stored_permission
|
|
return stored_permission
|