Instead of inserting the path of the apps into the Python app, the apps are now referenced by their full import path. This app name claves with external or native Python libraries. Example: Mayan statistics app vs. Python new statistics library. Every app reference is now prepended with 'mayan.apps'. Existing config.yml files need to be updated manually. Signed-off-by: Roberto Rosario <roberto.rosario.gonzalez@gmail.com>
265 lines
8.6 KiB
Python
265 lines
8.6 KiB
Python
from __future__ import absolute_import, unicode_literals
|
|
|
|
import itertools
|
|
import logging
|
|
|
|
from django.contrib.contenttypes.models import ContentType
|
|
from django.http import Http404, HttpResponseRedirect
|
|
from django.shortcuts import get_object_or_404
|
|
from django.template import RequestContext
|
|
from django.urls import reverse
|
|
from django.utils.encoding import force_text
|
|
from django.utils.translation import ugettext_lazy as _
|
|
|
|
from mayan.apps.common.views import (
|
|
AssignRemoveView, SingleObjectCreateView, SingleObjectDeleteView,
|
|
SingleObjectListView
|
|
)
|
|
from mayan.apps.permissions import PermissionNamespace, Permission
|
|
from mayan.apps.permissions.models import StoredPermission
|
|
|
|
from .classes import ModelPermission
|
|
from .icons import icon_acl_list
|
|
from .links import link_acl_create
|
|
from .models import AccessControlList
|
|
from .permissions import permission_acl_edit, permission_acl_view
|
|
|
|
logger = logging.getLogger(__name__)
|
|
|
|
|
|
class ACLCreateView(SingleObjectCreateView):
|
|
fields = ('role',)
|
|
model = AccessControlList
|
|
|
|
def dispatch(self, request, *args, **kwargs):
|
|
self.object_content_type = get_object_or_404(
|
|
ContentType, app_label=self.kwargs['app_label'],
|
|
model=self.kwargs['model']
|
|
)
|
|
|
|
try:
|
|
self.content_object = self.object_content_type.get_object_for_this_type(
|
|
pk=self.kwargs['object_id']
|
|
)
|
|
except self.object_content_type.model_class().DoesNotExist:
|
|
raise Http404
|
|
|
|
AccessControlList.objects.check_access(
|
|
permissions=permission_acl_edit, user=request.user,
|
|
obj=self.content_object
|
|
)
|
|
|
|
return super(ACLCreateView, self).dispatch(request, *args, **kwargs)
|
|
|
|
def get_instance_extra_data(self):
|
|
return {
|
|
'content_object': self.content_object
|
|
}
|
|
|
|
def form_valid(self, form):
|
|
try:
|
|
acl = AccessControlList.objects.get(
|
|
content_type=self.object_content_type,
|
|
object_id=self.content_object.pk,
|
|
role=form.cleaned_data['role']
|
|
)
|
|
except AccessControlList.DoesNotExist:
|
|
return super(ACLCreateView, self).form_valid(form)
|
|
else:
|
|
return HttpResponseRedirect(
|
|
reverse('acls:acl_permissions', args=(acl.pk,))
|
|
)
|
|
|
|
def get_extra_context(self):
|
|
return {
|
|
'object': self.content_object,
|
|
'title': _(
|
|
'New access control lists for: %s'
|
|
) % self.content_object
|
|
}
|
|
|
|
def get_success_url(self):
|
|
if self.object.pk:
|
|
return reverse('acls:acl_permissions', args=(self.object.pk,))
|
|
else:
|
|
return super(ACLCreateView, self).get_success_url()
|
|
|
|
|
|
class ACLDeleteView(SingleObjectDeleteView):
|
|
model = AccessControlList
|
|
|
|
def dispatch(self, request, *args, **kwargs):
|
|
acl = get_object_or_404(AccessControlList, pk=self.kwargs['pk'])
|
|
|
|
AccessControlList.objects.check_access(
|
|
permissions=permission_acl_edit, user=request.user,
|
|
obj=acl.content_object
|
|
)
|
|
|
|
return super(ACLDeleteView, self).dispatch(request, *args, **kwargs)
|
|
|
|
def get_extra_context(self):
|
|
return {
|
|
'object': self.get_object().content_object,
|
|
'title': _('Delete ACL: %s') % self.get_object(),
|
|
}
|
|
|
|
def get_post_action_redirect(self):
|
|
instance = self.get_object()
|
|
return reverse(
|
|
'acls:acl_list', args=(
|
|
instance.content_type.app_label,
|
|
instance.content_type.model, instance.object_id
|
|
)
|
|
)
|
|
|
|
|
|
class ACLListView(SingleObjectListView):
|
|
def dispatch(self, request, *args, **kwargs):
|
|
self.object_content_type = get_object_or_404(
|
|
ContentType, app_label=self.kwargs['app_label'],
|
|
model=self.kwargs['model']
|
|
)
|
|
|
|
try:
|
|
self.content_object = self.object_content_type.get_object_for_this_type(
|
|
pk=self.kwargs['object_id']
|
|
)
|
|
except self.object_content_type.model_class().DoesNotExist:
|
|
raise Http404
|
|
|
|
AccessControlList.objects.check_access(
|
|
permissions=permission_acl_view, user=request.user,
|
|
obj=self.content_object
|
|
)
|
|
|
|
return super(ACLListView, self).dispatch(request, *args, **kwargs)
|
|
|
|
def get_extra_context(self):
|
|
return {
|
|
'hide_object': True,
|
|
'no_results_icon': icon_acl_list,
|
|
'no_results_main_link': link_acl_create.resolve(
|
|
context=RequestContext(
|
|
self.request, {'resolved_object': self.content_object}
|
|
)
|
|
),
|
|
'no_results_title': _(
|
|
'There are no ACLs for this object'
|
|
),
|
|
'no_results_text': _(
|
|
'ACL stands for Access Control List and is a precise method '
|
|
' to control user access to objects in the system.'
|
|
),
|
|
'object': self.content_object,
|
|
'title': _('Access control lists for: %s' % self.content_object),
|
|
}
|
|
|
|
def get_object_list(self):
|
|
return AccessControlList.objects.filter(
|
|
content_type=self.object_content_type,
|
|
object_id=self.content_object.pk
|
|
)
|
|
|
|
|
|
class ACLPermissionsView(AssignRemoveView):
|
|
grouped = True
|
|
left_list_title = _('Available permissions')
|
|
right_list_title = _('Granted permissions')
|
|
|
|
@staticmethod
|
|
def generate_choices(entries):
|
|
results = []
|
|
|
|
entries = sorted(
|
|
entries, key=lambda x: (
|
|
x.get_volatile_permission().namespace.label,
|
|
x.get_volatile_permission().label
|
|
)
|
|
)
|
|
|
|
for namespace, permissions in itertools.groupby(entries, lambda entry: entry.namespace):
|
|
permission_options = [
|
|
(force_text(permission.pk), permission) for permission in permissions
|
|
]
|
|
results.append(
|
|
(PermissionNamespace.get(namespace), permission_options)
|
|
)
|
|
|
|
return results
|
|
|
|
def add(self, item):
|
|
permission = get_object_or_404(StoredPermission, pk=item)
|
|
self.get_object().permissions.add(permission)
|
|
|
|
def dispatch(self, request, *args, **kwargs):
|
|
acl = get_object_or_404(AccessControlList, pk=self.kwargs['pk'])
|
|
|
|
AccessControlList.objects.check_access(
|
|
permissions=permission_acl_edit, user=request.user,
|
|
obj=acl.content_object
|
|
)
|
|
|
|
return super(
|
|
ACLPermissionsView, self
|
|
).dispatch(request, *args, **kwargs)
|
|
|
|
def get_available_list(self):
|
|
return ModelPermission.get_for_instance(
|
|
instance=self.get_object().content_object
|
|
).exclude(id__in=self.get_granted_list().values_list('pk', flat=True))
|
|
|
|
def get_disabled_choices(self):
|
|
"""
|
|
Get permissions from a parent's acls but remove the permissions we
|
|
already hold for this object
|
|
"""
|
|
return map(
|
|
str, set(
|
|
self.get_object().get_inherited_permissions().values_list(
|
|
'pk', flat=True
|
|
)
|
|
).difference(
|
|
self.get_object().permissions.values_list('pk', flat=True)
|
|
)
|
|
)
|
|
|
|
def get_extra_context(self):
|
|
return {
|
|
'object': self.get_object().content_object,
|
|
'title': _('Role "%(role)s" permission\'s for "%(object)s"') % {
|
|
'role': self.get_object().role,
|
|
'object': self.get_object().content_object,
|
|
},
|
|
}
|
|
|
|
def get_granted_list(self):
|
|
"""
|
|
Merge or permissions we hold for this object and the permissions we
|
|
hold for this object's parent via another ACL
|
|
"""
|
|
merged_pks = self.get_object().permissions.values_list('pk', flat=True) | self.get_object().get_inherited_permissions().values_list('pk', flat=True)
|
|
return StoredPermission.objects.filter(pk__in=merged_pks)
|
|
|
|
def get_object(self):
|
|
return get_object_or_404(AccessControlList, pk=self.kwargs['pk'])
|
|
|
|
def get_right_list_help_text(self):
|
|
if self.get_object().get_inherited_permissions():
|
|
return _(
|
|
'Disabled permissions are inherited from a parent object.'
|
|
)
|
|
|
|
return None
|
|
|
|
def left_list(self):
|
|
Permission.refresh()
|
|
return ACLPermissionsView.generate_choices(self.get_available_list())
|
|
|
|
def remove(self, item):
|
|
permission = get_object_or_404(StoredPermission, pk=item)
|
|
self.get_object().permissions.remove(permission)
|
|
|
|
def right_list(self):
|
|
return ACLPermissionsView.generate_choices(self.get_granted_list())
|