Update permission app to the new class based permissions
This commit is contained in:
@@ -7,14 +7,16 @@ from navigation.api import register_links, register_multi_item_links
|
||||
from project_setup.api import register_setup
|
||||
|
||||
from permissions.conf.settings import DEFAULT_ROLES
|
||||
from permissions.models import Role
|
||||
from permissions.models import Role, Permission, PermissionNamespace
|
||||
|
||||
PERMISSION_ROLE_VIEW = {'namespace': 'permissions', 'name': 'role_view', 'label': _(u'View roles')}
|
||||
PERMISSION_ROLE_EDIT = {'namespace': 'permissions', 'name': 'role_edit', 'label': _(u'Edit roles')}
|
||||
PERMISSION_ROLE_CREATE = {'namespace': 'permissions', 'name': 'role_create', 'label': _(u'Create roles')}
|
||||
PERMISSION_ROLE_DELETE = {'namespace': 'permissions', 'name': 'role_delete', 'label': _(u'Delete roles')}
|
||||
PERMISSION_PERMISSION_GRANT = {'namespace': 'permissions', 'name': 'permission_grant', 'label': _(u'Grant permissions')}
|
||||
PERMISSION_PERMISSION_REVOKE = {'namespace': 'permissions', 'name': 'permission_revoke', 'label': _(u'Revoke permissions')}
|
||||
permissions_namespace = PermissionNamespace('permissions', _(u'Permissions'))
|
||||
|
||||
PERMISSION_ROLE_VIEW = Permission.objects.register(permissions_namespace, 'role_view', _(u'View roles'))
|
||||
PERMISSION_ROLE_EDIT = Permission.objects.register(permissions_namespace, 'role_edit', _(u'Edit roles'))
|
||||
PERMISSION_ROLE_CREATE = Permission.objects.register(permissions_namespace, 'role_create', _(u'Create roles'))
|
||||
PERMISSION_ROLE_DELETE = Permission.objects.register(permissions_namespace, 'role_delete', _(u'Delete roles'))
|
||||
PERMISSION_PERMISSION_GRANT = Permission.objects.register(permissions_namespace, 'permission_grant', _(u'Grant permissions'))
|
||||
PERMISSION_PERMISSION_REVOKE = Permission.objects.register(permissions_namespace, 'permission_revoke', _(u'Revoke permissions'))
|
||||
|
||||
role_list = {'text': _(u'roles'), 'view': 'role_list', 'famfam': 'medal_gold_1', 'icon': 'medal_gold_1.png', 'permissions': [PERMISSION_ROLE_VIEW]}
|
||||
role_create = {'text': _(u'create new role'), 'view': 'role_create', 'famfam': 'medal_gold_add', 'permissions': [PERMISSION_ROLE_CREATE]}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
from django.contrib import admin
|
||||
|
||||
from permissions.models import Permission, PermissionHolder, Role, RoleMember
|
||||
from permissions.models import StoredPermission, PermissionHolder, Role, RoleMember
|
||||
|
||||
|
||||
class PermissionHolderInline(admin.StackedInline):
|
||||
@@ -27,5 +27,5 @@ class RoleAdmin(admin.ModelAdmin):
|
||||
inlines = [RoleMemberInline]
|
||||
|
||||
|
||||
admin.site.register(Permission, PermissionAdmin)
|
||||
admin.site.register(StoredPermission, PermissionAdmin)
|
||||
admin.site.register(Role, RoleAdmin)
|
||||
|
||||
@@ -1,69 +1 @@
|
||||
try:
|
||||
from psycopg2 import OperationalError
|
||||
except ImportError:
|
||||
class OperationalError(Exception):
|
||||
pass
|
||||
|
||||
from django.core.exceptions import ImproperlyConfigured
|
||||
from django.db import transaction
|
||||
from django.db.utils import DatabaseError
|
||||
from django.shortcuts import get_object_or_404
|
||||
from django.utils.translation import ugettext
|
||||
from django.core.exceptions import PermissionDenied
|
||||
from django.utils.translation import ugettext_lazy as _
|
||||
|
||||
from permissions import PERMISSION_ROLE_VIEW, PERMISSION_ROLE_EDIT, \
|
||||
PERMISSION_ROLE_CREATE, PERMISSION_ROLE_DELETE, \
|
||||
PERMISSION_PERMISSION_GRANT, PERMISSION_PERMISSION_REVOKE
|
||||
|
||||
from permissions.models import Permission
|
||||
from permissions.runtime import namespace_titles, permission_titles
|
||||
|
||||
|
||||
def set_namespace_title(namespace, title):
|
||||
namespace_titles.setdefault(namespace, title)
|
||||
|
||||
|
||||
@transaction.commit_manually
|
||||
def register_permission(permission):
|
||||
try:
|
||||
permission_obj, created = Permission.objects.get_or_create(
|
||||
namespace=permission['namespace'], name=permission['name'])
|
||||
permission_obj.label = unicode(permission['label'])
|
||||
permission_obj.save()
|
||||
permission_titles['%s.%s' % (permission['namespace'], permission['name'])] = permission['label']
|
||||
except DatabaseError:
|
||||
transaction.rollback()
|
||||
# Special case for ./manage.py syncdb
|
||||
except (OperationalError, ImproperlyConfigured):
|
||||
transaction.rollback()
|
||||
# Special for DjangoZoom, which executes collectstatic media
|
||||
# doing syncdb and creating the database tables
|
||||
else:
|
||||
transaction.commit()
|
||||
|
||||
|
||||
def check_permissions(requester, permission_list):
|
||||
for permission_item in permission_list:
|
||||
permission = get_object_or_404(Permission,
|
||||
namespace=permission_item['namespace'], name=permission_item['name'])
|
||||
if permission.has_permission(requester):
|
||||
return True
|
||||
|
||||
raise PermissionDenied(ugettext(u'Insufficient permissions.'))
|
||||
|
||||
|
||||
def get_permission_label(permission):
|
||||
return unicode(permission_titles.get('%s.%s' % (permission.namespace, permission.name), permission.label))
|
||||
|
||||
|
||||
def get_permission_namespace_label(permission):
|
||||
return namespace_titles[permission.namespace] if permission.namespace in namespace_titles else permission.namespace
|
||||
|
||||
|
||||
register_permission(PERMISSION_ROLE_VIEW)
|
||||
register_permission(PERMISSION_ROLE_EDIT)
|
||||
register_permission(PERMISSION_ROLE_CREATE)
|
||||
register_permission(PERMISSION_ROLE_DELETE)
|
||||
register_permission(PERMISSION_PERMISSION_GRANT)
|
||||
register_permission(PERMISSION_PERMISSION_REVOKE)
|
||||
|
||||
@@ -1,7 +1,14 @@
|
||||
import logging
|
||||
|
||||
from django.db import models
|
||||
from django.contrib.contenttypes.models import ContentType
|
||||
from django.db import transaction
|
||||
from django.core.exceptions import PermissionDenied
|
||||
from django.shortcuts import get_object_or_404
|
||||
from django.db.utils import IntegrityError
|
||||
from django.core.exceptions import ImproperlyConfigured
|
||||
|
||||
from permissions.runtime import permission_titles
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class RoleMemberManager(models.Manager):
|
||||
@@ -10,19 +17,7 @@ class RoleMemberManager(models.Manager):
|
||||
return [role_member.role for role_member in self.model.objects.filter(member_type=member_type, member_id=member_obj.pk)]
|
||||
|
||||
|
||||
class PermissionManager(models.Manager):
|
||||
class StoredPermissionManager(models.Manager):
|
||||
def get_for_holder(self, holder):
|
||||
ct = ContentType.objects.get_for_model(holder)
|
||||
return self.model.objects.active_only().filter(permissionholder__holder_type=ct).filter(permissionholder__holder_id=holder.pk)
|
||||
|
||||
def active_only(self):
|
||||
namespaces = []
|
||||
names = []
|
||||
for key in permission_titles:
|
||||
namespace, name = key.split(u'.')
|
||||
if namespace:
|
||||
namespaces.append(namespace)
|
||||
if name:
|
||||
names.append(name)
|
||||
|
||||
return super(PermissionManager, self).get_query_set().filter(namespace__in=namespaces).filter(name__in=names).exclude(label=u'')
|
||||
return self.model.objects.filter(permissionholder__holder_type=ct).filter(permissionholder__holder_id=holder.pk)
|
||||
|
||||
@@ -1,33 +1,140 @@
|
||||
import logging
|
||||
|
||||
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
|
||||
from django.core.exceptions import PermissionDenied
|
||||
|
||||
from permissions.managers import RoleMemberManager, PermissionManager
|
||||
from permissions.runtime import namespace_titles, permission_titles
|
||||
from permissions.managers import (RoleMemberManager, StoredPermissionManager)
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class Permission(models.Model):
|
||||
class PermissionNamespace(object):
|
||||
def __init__(self, name, label):
|
||||
self.name = name
|
||||
self.label = label
|
||||
|
||||
def __unicode__(self):
|
||||
return unicode(self.label)
|
||||
|
||||
#class LazyQuerySet(list):
|
||||
# def __init__(self, model, items):
|
||||
# self.model = model
|
||||
# self.items = items
|
||||
#
|
||||
# def get(self, *args, **kwargs):
|
||||
# print args
|
||||
# print kwargs
|
||||
|
||||
class PermissionDoesNotExists(Exception):
|
||||
pass
|
||||
|
||||
|
||||
class PermissionManager(object):
|
||||
_permissions = {}
|
||||
DoesNotExist = PermissionDoesNotExists()
|
||||
|
||||
@classmethod
|
||||
def register(cls, namespace, name, label):
|
||||
permission = Permission(namespace, name, label)
|
||||
cls._permissions[permission.uuid] = permission
|
||||
return permission
|
||||
|
||||
@classmethod
|
||||
def check_permissions(cls, requester, permission_list):
|
||||
for permission in permission_list:
|
||||
if permission.requester_has_this(requester):
|
||||
return True
|
||||
|
||||
raise PermissionDenied(ugettext(u'Insufficient permissions.'))
|
||||
|
||||
@classmethod
|
||||
def get_for_holder(cls, holder):
|
||||
return StoredPermission.objects.get_for_holder(holder)
|
||||
|
||||
@classmethod
|
||||
def all(cls):
|
||||
return cls._permissions.values()
|
||||
#return LazyQuerySet(cls, cls._permissions)
|
||||
|
||||
@classmethod
|
||||
def get(cls, get_dict):
|
||||
if 'pk' in get_dict:
|
||||
try:
|
||||
return cls._permissions[get_dict['pk']].get_stored_permission()
|
||||
except KeyError:
|
||||
raise Permission.DoesNotExist
|
||||
|
||||
|
||||
def __init__(self, model):
|
||||
self.model = model
|
||||
|
||||
|
||||
class Permission(object):
|
||||
DoesNotExist = PermissionDoesNotExists
|
||||
|
||||
def __init__(self, namespace, name, label):
|
||||
self.namespace = namespace
|
||||
self.name = name
|
||||
self.label = label
|
||||
self.pk = self.uuid
|
||||
|
||||
def __unicode__(self):
|
||||
return unicode(self.label)
|
||||
|
||||
@property
|
||||
def uuid(self):
|
||||
return u'%s.%s' % (self.namespace.name, self.name)
|
||||
|
||||
def get_stored_permission(self):
|
||||
stored_permission, created = StoredPermission.objects.get_or_create(
|
||||
namespace=self.namespace.name,
|
||||
name=self.name,
|
||||
defaults={
|
||||
'label': self.label
|
||||
}
|
||||
)
|
||||
stored_permission.label = self.label
|
||||
stored_permission.save()
|
||||
stored_permission.volatile_permission = self
|
||||
return stored_permission
|
||||
|
||||
def requester_has_this(self, requester):
|
||||
stored_permission = self.get_stored_permission(
|
||||
)
|
||||
return stored_permission.requester_has_this(requester)
|
||||
|
||||
def save(self, *args, **kwargs):
|
||||
return self.get_stored_permission(
|
||||
)
|
||||
|
||||
Permission.objects = PermissionManager(Permission)
|
||||
Permission._default_manager = Permission.objects
|
||||
|
||||
|
||||
class StoredPermission(models.Model):
|
||||
namespace = models.CharField(max_length=64, verbose_name=_(u'namespace'))
|
||||
name = models.CharField(max_length=64, verbose_name=_(u'name'))
|
||||
label = models.CharField(max_length=96, verbose_name=_(u'label'))
|
||||
|
||||
objects = PermissionManager()
|
||||
objects = StoredPermissionManager()
|
||||
|
||||
class Meta:
|
||||
ordering = ('namespace', 'label')
|
||||
unique_together = ('namespace', 'name')
|
||||
verbose_name = _(u'permission')
|
||||
verbose_name_plural = _(u'permissions')
|
||||
|
||||
|
||||
def __unicode__(self):
|
||||
return u'%s: %s' % (self.get_namespace_label(), self.get_label())
|
||||
return unicode(self.volatile_permission)
|
||||
|
||||
def get_holders(self):
|
||||
return [holder.holder_object for holder in self.permissionholder_set.all()]
|
||||
|
||||
def has_permission(self, requester):
|
||||
def requester_has_this(self, requester):
|
||||
if isinstance(requester, User):
|
||||
if requester.is_superuser or requester.is_staff:
|
||||
return True
|
||||
@@ -60,16 +167,10 @@ class Permission(models.Model):
|
||||
return True
|
||||
except PermissionHolder.DoesNotExist:
|
||||
return False
|
||||
|
||||
def get_label(self):
|
||||
return unicode(permission_titles.get('%s.%s' % (self.namespace, self.name), self.label))
|
||||
|
||||
def get_namespace_label(self):
|
||||
return unicode(namespace_titles[self.namespace]) if self.namespace in namespace_titles else self.namespace
|
||||
|
||||
|
||||
class PermissionHolder(models.Model):
|
||||
permission = models.ForeignKey(Permission, verbose_name=_(u'permission'))
|
||||
permission = models.ForeignKey(StoredPermission, verbose_name=_(u'permission'))
|
||||
holder_type = models.ForeignKey(ContentType,
|
||||
related_name='permission_holder',
|
||||
limit_choices_to={'model__in': ('user', 'group', 'role')})
|
||||
|
||||
@@ -1,8 +1 @@
|
||||
from django.utils.translation import ugettext_lazy as _
|
||||
|
||||
|
||||
namespace_titles = {
|
||||
'permissions': _(u'Permissions')
|
||||
}
|
||||
|
||||
permission_titles = {}
|
||||
|
||||
@@ -2,7 +2,7 @@ import operator
|
||||
import itertools
|
||||
|
||||
from django.utils.translation import ugettext_lazy as _
|
||||
from django.http import HttpResponseRedirect
|
||||
from django.http import HttpResponseRedirect, Http404
|
||||
from django.shortcuts import render_to_response, get_object_or_404
|
||||
from django.template import RequestContext
|
||||
from django.contrib import messages
|
||||
@@ -22,12 +22,11 @@ from permissions.forms import RoleForm, RoleForm_view
|
||||
from permissions import PERMISSION_ROLE_VIEW, PERMISSION_ROLE_EDIT, \
|
||||
PERMISSION_ROLE_CREATE, PERMISSION_ROLE_DELETE, PERMISSION_PERMISSION_GRANT, \
|
||||
PERMISSION_PERMISSION_REVOKE
|
||||
from permissions.api import check_permissions, namespace_titles, get_permission_label, get_permission_namespace_label
|
||||
from permissions.widgets import role_permission_link
|
||||
|
||||
|
||||
def role_list(request):
|
||||
check_permissions(request.user, [PERMISSION_ROLE_VIEW])
|
||||
Permission.objects.check_permissions(request.user, [PERMISSION_ROLE_VIEW])
|
||||
|
||||
return object_list(
|
||||
request,
|
||||
@@ -41,7 +40,7 @@ def role_list(request):
|
||||
|
||||
|
||||
def role_permissions(request, role_id):
|
||||
check_permissions(request.user, [PERMISSION_PERMISSION_GRANT, PERMISSION_PERMISSION_REVOKE])
|
||||
Permission.objects.check_permissions(request.user, [PERMISSION_PERMISSION_GRANT, PERMISSION_PERMISSION_REVOKE])
|
||||
|
||||
role = get_object_or_404(Role, pk=role_id)
|
||||
form = RoleForm_view(instance=role)
|
||||
@@ -52,13 +51,13 @@ def role_permissions(request, role_id):
|
||||
'name': u'generic_list_subtemplate.html',
|
||||
'context': {
|
||||
'title': _(u'permissions'),
|
||||
'object_list': Permission.objects.active_only(),
|
||||
'object_list': Permission.objects.all(),
|
||||
'extra_columns': [
|
||||
{'name': _(u'namespace'), 'attribute': encapsulate(lambda x: get_permission_namespace_label(x))},
|
||||
{'name': _(u'name'), 'attribute': encapsulate(lambda x: get_permission_label(x))},
|
||||
{'name': _(u'namespace'), 'attribute': encapsulate(lambda x: x.namespace)},
|
||||
{'name': _(u'name'), 'attribute': encapsulate(lambda x: x.label)},
|
||||
{
|
||||
'name':_(u'has permission'),
|
||||
'attribute': encapsulate(lambda x: two_state_template(x.has_permission(role))),
|
||||
'attribute': encapsulate(lambda x: two_state_template(x.requester_has_this(role))),
|
||||
},
|
||||
],
|
||||
'hide_link': True,
|
||||
@@ -83,7 +82,7 @@ def role_permissions(request, role_id):
|
||||
|
||||
|
||||
def role_edit(request, role_id):
|
||||
check_permissions(request.user, [PERMISSION_ROLE_EDIT])
|
||||
Permission.objects.check_permissions(request.user, [PERMISSION_ROLE_EDIT])
|
||||
|
||||
return update_object(request, template_name='generic_form.html',
|
||||
form_class=RoleForm, object_id=role_id, extra_context={
|
||||
@@ -91,7 +90,7 @@ def role_edit(request, role_id):
|
||||
|
||||
|
||||
def role_create(request):
|
||||
check_permissions(request.user, [PERMISSION_ROLE_CREATE])
|
||||
Permission.objects.check_permissions(request.user, [PERMISSION_ROLE_CREATE])
|
||||
|
||||
return create_object(request, model=Role,
|
||||
template_name='generic_form.html',
|
||||
@@ -99,7 +98,7 @@ def role_create(request):
|
||||
|
||||
|
||||
def role_delete(request, role_id):
|
||||
check_permissions(request.user, [PERMISSION_ROLE_DELETE])
|
||||
Permission.objects.check_permissions(request.user, [PERMISSION_ROLE_DELETE])
|
||||
|
||||
next = request.POST.get('next', request.GET.get('next', request.META.get('HTTP_REFERER', '/')))
|
||||
previous = request.POST.get('previous', request.GET.get('previous', request.META.get('HTTP_REFERER', '/')))
|
||||
@@ -117,7 +116,7 @@ def role_delete(request, role_id):
|
||||
|
||||
|
||||
def permission_grant(request):
|
||||
check_permissions(request.user, [PERMISSION_PERMISSION_GRANT])
|
||||
Permission.objects.check_permissions(request.user, [PERMISSION_PERMISSION_GRANT])
|
||||
items_property_list = loads(request.GET.get('items_property_list', []))
|
||||
post_action_redirect = None
|
||||
|
||||
@@ -126,7 +125,12 @@ def permission_grant(request):
|
||||
|
||||
items = []
|
||||
for item_properties in items_property_list:
|
||||
permission = get_object_or_404(Permission, pk=item_properties['permission_id'])
|
||||
#permission = get_object_or_404(Permission, pk=item_properties['permission_id'])
|
||||
try:
|
||||
permission = Permission.objects.get({'pk': item_properties['permission_id']})
|
||||
except Permission.DoesNotExist:
|
||||
raise Http404
|
||||
|
||||
ct = get_object_or_404(ContentType, app_label=item_properties['requester_app_label'], model=item_properties['requester_model'])
|
||||
requester_model = ct.model_class()
|
||||
requester = get_object_or_404(requester_model, pk=item_properties['requester_id'])
|
||||
@@ -176,7 +180,7 @@ def permission_grant(request):
|
||||
|
||||
|
||||
def permission_revoke(request):
|
||||
check_permissions(request.user, [PERMISSION_PERMISSION_REVOKE])
|
||||
Permission.objects.check_permissions(request.user, [PERMISSION_PERMISSION_REVOKE])
|
||||
items_property_list = loads(request.GET.get('items_property_list', []))
|
||||
post_action_redirect = None
|
||||
|
||||
@@ -185,7 +189,12 @@ def permission_revoke(request):
|
||||
|
||||
items = []
|
||||
for item_properties in items_property_list:
|
||||
permission = get_object_or_404(Permission, pk=item_properties['permission_id'])
|
||||
#permission = get_object_or_404(Permission, pk=item_properties['permission_id'])
|
||||
try:
|
||||
permission = Permission.objects.get({'pk': item_properties['permission_id']})
|
||||
except Permission.DoesNotExist:
|
||||
raise Http404
|
||||
|
||||
ct = get_object_or_404(ContentType, app_label=item_properties['requester_app_label'], model=item_properties['requester_model'])
|
||||
requester_model = ct.model_class()
|
||||
requester = get_object_or_404(requester_model, pk=item_properties['requester_id'])
|
||||
@@ -265,7 +274,7 @@ def remove_role_member(role, selection):
|
||||
|
||||
|
||||
def role_members(request, role_id):
|
||||
check_permissions(request.user, [PERMISSION_ROLE_EDIT])
|
||||
Permission.objects.check_permissions(request.user, [PERMISSION_ROLE_EDIT])
|
||||
role = get_object_or_404(Role, pk=role_id)
|
||||
|
||||
return assign_remove(
|
||||
|
||||
Reference in New Issue
Block a user