Update ACL app to compy with MERC 5 and 6
Update the entire with keyword arguments. Update the views to comply with MERC 6 by returning error 404 on access failure. API are untouched. Add icon to the ACL delete button. Add additional view tests. Use the new filtered choice form to display a select2 enabled role selection widget. Update the ACL creation view to not redirect to an existing ACL in case of duplication but to instead stop and display an error with a suggestion to the user to instead edit the existing ACL. Signed-off-by: Roberto Rosario <Roberto.Rosario@mayan-edms.com>
This commit is contained in:
@@ -2,6 +2,7 @@ from __future__ import absolute_import, unicode_literals
|
||||
|
||||
from django.contrib.contenttypes.models import ContentType
|
||||
from django.shortcuts import get_object_or_404
|
||||
|
||||
from rest_framework import generics
|
||||
|
||||
from .models import AccessControlList
|
||||
@@ -25,7 +26,7 @@ class APIObjectACLListView(generics.ListCreateAPIView):
|
||||
)
|
||||
|
||||
content_object = get_object_or_404(
|
||||
klass=content_type.model_class(), pk=self.kwargs['object_pk']
|
||||
klass=content_type.model_class(), pk=self.kwargs['object_id']
|
||||
)
|
||||
|
||||
if self.request.method == 'GET':
|
||||
@@ -89,7 +90,7 @@ class APIObjectACLView(generics.RetrieveDestroyAPIView):
|
||||
)
|
||||
|
||||
content_object = get_object_or_404(
|
||||
klass=content_type.model_class(), pk=self.kwargs['object_pk']
|
||||
klass=content_type.model_class(), pk=self.kwargs['object_id']
|
||||
)
|
||||
|
||||
AccessControlList.objects.check_access(
|
||||
@@ -110,7 +111,7 @@ class APIObjectACLPermissionListView(generics.ListCreateAPIView):
|
||||
"""
|
||||
def get_acl(self):
|
||||
return get_object_or_404(
|
||||
klass=self.get_content_object().acls, pk=self.kwargs['pk']
|
||||
klass=self.get_content_object().acls, pk=self.kwargs['acl_pk']
|
||||
)
|
||||
|
||||
def get_content_object(self):
|
||||
@@ -120,7 +121,7 @@ class APIObjectACLPermissionListView(generics.ListCreateAPIView):
|
||||
)
|
||||
|
||||
content_object = get_object_or_404(
|
||||
klass=content_type.model_class(), pk=self.kwargs['object_pk']
|
||||
klass=content_type.model_class(), pk=self.kwargs['object_id']
|
||||
)
|
||||
|
||||
AccessControlList.objects.check_access(
|
||||
@@ -167,7 +168,7 @@ class APIObjectACLPermissionView(generics.RetrieveDestroyAPIView):
|
||||
|
||||
def get_acl(self):
|
||||
return get_object_or_404(
|
||||
klass=self.get_content_object().acls, pk=self.kwargs['pk']
|
||||
klass=self.get_content_object().acls, pk=self.kwargs['acl_pk']
|
||||
)
|
||||
|
||||
def get_content_object(self):
|
||||
@@ -177,7 +178,7 @@ class APIObjectACLPermissionView(generics.RetrieveDestroyAPIView):
|
||||
)
|
||||
|
||||
content_object = get_object_or_404(
|
||||
klass=content_type.model_class(), pk=self.kwargs['object_pk']
|
||||
klass=content_type.model_class(), pk=self.kwargs['object_id']
|
||||
)
|
||||
|
||||
AccessControlList.objects.check_access(
|
||||
|
||||
@@ -19,14 +19,15 @@ class ACLsApp(MayanAppConfig):
|
||||
def ready(self):
|
||||
super(ACLsApp, self).ready()
|
||||
|
||||
AccessControlList = self.get_model('AccessControlList')
|
||||
AccessControlList = self.get_model(model_name='AccessControlList')
|
||||
|
||||
SourceColumn(
|
||||
source=AccessControlList, label=_('Role'), attribute='role'
|
||||
attribute='role', is_identifier=True, is_sortable=True,
|
||||
source=AccessControlList
|
||||
)
|
||||
SourceColumn(
|
||||
source=AccessControlList, label=_('Permissions'),
|
||||
attribute='get_permission_titles'
|
||||
attribute='get_permission_titles', include_label=True,
|
||||
source=AccessControlList
|
||||
)
|
||||
|
||||
menu_object.bind_links(
|
||||
|
||||
13
mayan/apps/acls/forms.py
Normal file
13
mayan/apps/acls/forms.py
Normal file
@@ -0,0 +1,13 @@
|
||||
from __future__ import unicode_literals
|
||||
|
||||
from django import forms
|
||||
|
||||
from mayan.apps.common.forms import FilteredSelectionForm
|
||||
|
||||
from .models import AccessControlList
|
||||
|
||||
|
||||
class ACLCreateForm(FilteredSelectionForm, forms.ModelForm):
|
||||
class Meta:
|
||||
fields = ('role',)
|
||||
model = AccessControlList
|
||||
@@ -2,6 +2,7 @@ from __future__ import absolute_import, unicode_literals
|
||||
|
||||
from mayan.apps.appearance.classes import Icon
|
||||
|
||||
icon_acl_delete = Icon(driver_name='fontawesome', symbol='minus')
|
||||
icon_acl_list = Icon(driver_name='fontawesome', symbol='lock')
|
||||
icon_acl_new = Icon(
|
||||
driver_name='fontawesome-dual', primary_symbol='lock',
|
||||
|
||||
@@ -4,8 +4,9 @@ from django.apps import apps
|
||||
from django.utils.translation import ugettext_lazy as _
|
||||
|
||||
from mayan.apps.navigation import Link
|
||||
from mayan.apps.permissions.icons import icon_permission
|
||||
|
||||
from .icons import icon_acl_list, icon_acl_new
|
||||
from .icons import icon_acl_delete, icon_acl_list, icon_acl_new
|
||||
from .permissions import permission_acl_edit, permission_acl_view
|
||||
|
||||
|
||||
@@ -28,9 +29,9 @@ def get_kwargs_factory(variable_name):
|
||||
|
||||
|
||||
link_acl_delete = Link(
|
||||
args='resolved_object.pk', permissions=(permission_acl_edit,),
|
||||
permissions_related='content_object', tags='dangerous', text=_('Delete'),
|
||||
view='acls:acl_delete',
|
||||
args='resolved_object.pk', icon_class=icon_acl_delete,
|
||||
permissions=(permission_acl_edit,), permissions_related='content_object',
|
||||
tags='dangerous', text=_('Delete'), view='acls:acl_delete',
|
||||
)
|
||||
link_acl_list = Link(
|
||||
icon_class=icon_acl_list, kwargs=get_kwargs_factory('resolved_object'),
|
||||
@@ -42,7 +43,7 @@ link_acl_create = Link(
|
||||
view='acls:acl_create'
|
||||
)
|
||||
link_acl_permissions = Link(
|
||||
args='resolved_object.pk', permissions=(permission_acl_edit,),
|
||||
permissions_related='content_object', text=_('Permissions'),
|
||||
view='acls:acl_permissions',
|
||||
args='resolved_object.pk', icon_class=icon_permission,
|
||||
permissions=(permission_acl_edit,), permissions_related='content_object',
|
||||
text=_('Permissions'), view='acls:acl_permissions',
|
||||
)
|
||||
|
||||
@@ -55,7 +55,9 @@ class AccessControlListManager(models.Manager):
|
||||
except AttributeError:
|
||||
# AttributeError means non model objects: ie Statistics
|
||||
# These can't have ACLs so we raise PermissionDenied
|
||||
raise PermissionDenied(_('Insufficient access for: %s') % obj)
|
||||
raise PermissionDenied(
|
||||
_('Insufficient access for: %(object)s') % {'object': obj}
|
||||
)
|
||||
except KeyError:
|
||||
pass
|
||||
else:
|
||||
@@ -89,7 +91,7 @@ class AccessControlListManager(models.Manager):
|
||||
|
||||
user_roles.append(role)
|
||||
|
||||
if not self.filter(content_type=ContentType.objects.get_for_model(obj), object_id=obj.pk, permissions__in=stored_permissions, role__in=user_roles).exists():
|
||||
if not self.filter(content_type=ContentType.objects.get_for_model(model=obj), object_id=obj.pk, permissions__in=stored_permissions, role__in=user_roles).exists():
|
||||
logger.debug(
|
||||
'Permissions "%s" on "%s" denied for user "%s"',
|
||||
permissions, obj, user
|
||||
@@ -104,8 +106,8 @@ class AccessControlListManager(models.Manager):
|
||||
def filter_by_access(self, permission, user, queryset):
|
||||
if user.is_superuser or user.is_staff:
|
||||
logger.debug(
|
||||
'Unfiltered queryset returned to user "%s" as superuser or staff',
|
||||
user
|
||||
'Unfiltered queryset returned to user "%s" as superuser '
|
||||
'or staff', user
|
||||
)
|
||||
return queryset
|
||||
|
||||
@@ -138,10 +140,11 @@ class AccessControlListManager(models.Manager):
|
||||
except TypeError:
|
||||
# Is not a function, try it as a field
|
||||
parent_content_type = ContentType.objects.get_for_model(
|
||||
parent_object
|
||||
model=parent_object
|
||||
)
|
||||
parent_queryset = self.filter(
|
||||
content_type=parent_content_type, role__in=user_roles,
|
||||
content_type=parent_content_type,
|
||||
role__in=user_roles,
|
||||
permissions=permission.stored_permission
|
||||
)
|
||||
parent_acl_query = Q(
|
||||
@@ -159,7 +162,10 @@ class AccessControlListManager(models.Manager):
|
||||
result = []
|
||||
for entry in queryset:
|
||||
try:
|
||||
self.check_access(permissions=permission, user=user, obj=entry)
|
||||
self.check_access(
|
||||
obj=entry, permissions=permission,
|
||||
user=user
|
||||
)
|
||||
except PermissionDenied:
|
||||
pass
|
||||
else:
|
||||
@@ -170,7 +176,9 @@ class AccessControlListManager(models.Manager):
|
||||
parent_acl_query = Q()
|
||||
|
||||
# Directly granted access
|
||||
content_type = ContentType.objects.get_for_model(queryset.model)
|
||||
content_type = ContentType.objects.get_for_model(
|
||||
model=queryset.model
|
||||
)
|
||||
acl_query = Q(pk__in=self.filter(
|
||||
content_type=content_type, role__in=user_roles,
|
||||
permissions=permission.stored_permission
|
||||
@@ -194,7 +202,9 @@ class AccessControlListManager(models.Manager):
|
||||
return StoredPermission.objects.none()
|
||||
|
||||
try:
|
||||
parent_accessor = ModelPermission.get_inheritance(type(instance))
|
||||
parent_accessor = ModelPermission.get_inheritance(
|
||||
model=type(instance)
|
||||
)
|
||||
except KeyError:
|
||||
return StoredPermission.objects.none()
|
||||
else:
|
||||
@@ -230,6 +240,8 @@ class AccessControlListManager(models.Manager):
|
||||
|
||||
acl.permissions.add(permission.stored_permission)
|
||||
|
||||
return acl
|
||||
|
||||
def revoke(self, permission, role, obj):
|
||||
content_type = ContentType.objects.get_for_model(model=obj)
|
||||
acl, created = self.get_or_create(
|
||||
|
||||
@@ -5,6 +5,7 @@ import logging
|
||||
from django.contrib.contenttypes.fields import GenericForeignKey
|
||||
from django.contrib.contenttypes.models import ContentType
|
||||
from django.db import models
|
||||
from django.urls import reverse
|
||||
from django.utils.encoding import force_text, python_2_unicode_compatible
|
||||
from django.utils.translation import ugettext_lazy as _
|
||||
|
||||
@@ -64,6 +65,11 @@ class AccessControlList(models.Model):
|
||||
'role': self.role
|
||||
}
|
||||
|
||||
def get_absolute_url(self):
|
||||
return reverse(
|
||||
viewname='acls:acl_permissions', kwargs={'acl_pk': self.pk}
|
||||
)
|
||||
|
||||
def get_inherited_permissions(self):
|
||||
return AccessControlList.objects.get_inherited_permissions(
|
||||
role=self.role, obj=self.content_object
|
||||
@@ -78,3 +84,4 @@ class AccessControlList(models.Model):
|
||||
)
|
||||
|
||||
return result or _('None')
|
||||
get_permission_titles.short_description = _('Permissions')
|
||||
|
||||
@@ -7,8 +7,8 @@ from mayan.apps.permissions import PermissionNamespace
|
||||
namespace = PermissionNamespace(label=_('Access control lists'), name='acls')
|
||||
|
||||
permission_acl_edit = namespace.add_permission(
|
||||
name='acl_edit', label=_('Edit ACLs')
|
||||
label=_('Edit ACLs'), name='acl_edit'
|
||||
)
|
||||
permission_acl_view = namespace.add_permission(
|
||||
name='acl_view', label=_('View ACLs')
|
||||
label=_('View ACLs'), name='acl_view'
|
||||
)
|
||||
|
||||
@@ -38,18 +38,22 @@ class AccessControlListSerializer(serializers.ModelSerializer):
|
||||
|
||||
def get_permissions_url(self, instance):
|
||||
return reverse(
|
||||
'rest_api:accesscontrollist-permission-list', args=(
|
||||
instance.content_type.app_label, instance.content_type.model,
|
||||
instance.object_id, instance.pk
|
||||
), request=self.context['request'], format=self.context['format']
|
||||
viewname='rest_api:accesscontrollist-permission-list', kwargs={
|
||||
'app_label': instance.content_type.app_label,
|
||||
'model': instance.content_type.model,
|
||||
'object_id': instance.object_id,
|
||||
'acl_pk': instance.pk
|
||||
}, request=self.context['request'], format=self.context['format']
|
||||
)
|
||||
|
||||
def get_url(self, instance):
|
||||
return reverse(
|
||||
'rest_api:accesscontrollist-detail', args=(
|
||||
instance.content_type.app_label, instance.content_type.model,
|
||||
instance.object_id, instance.pk
|
||||
), request=self.context['request'], format=self.context['format']
|
||||
'rest_api:accesscontrollist-detail', kwargs={
|
||||
'app_label': instance.content_type.app_label,
|
||||
'model': instance.content_type.model,
|
||||
'object_id': instance.object_id,
|
||||
'acl_pk': instance.pk
|
||||
}, request=self.context['request'], format=self.context['format']
|
||||
)
|
||||
|
||||
|
||||
@@ -65,21 +69,23 @@ class AccessControlListPermissionSerializer(PermissionSerializer):
|
||||
|
||||
def get_acl_permission_url(self, instance):
|
||||
return reverse(
|
||||
'rest_api:accesscontrollist-permission-detail', args=(
|
||||
self.context['acl'].content_type.app_label,
|
||||
self.context['acl'].content_type.model,
|
||||
self.context['acl'].object_id, self.context['acl'].pk,
|
||||
instance.stored_permission.pk
|
||||
), request=self.context['request'], format=self.context['format']
|
||||
'rest_api:accesscontrollist-permission-detail', kwargs={
|
||||
'app_label': self.context['acl'].content_type.app_label,
|
||||
'model': self.context['acl'].content_type.model,
|
||||
'object_id': self.context['acl'].object_id,
|
||||
'acl_pk': self.context['acl'].pk,
|
||||
'permission_pk': instance.stored_permission.pk
|
||||
}, request=self.context['request'], format=self.context['format']
|
||||
)
|
||||
|
||||
def get_acl_url(self, instance):
|
||||
return reverse(
|
||||
'rest_api:accesscontrollist-detail', args=(
|
||||
self.context['acl'].content_type.app_label,
|
||||
self.context['acl'].content_type.model,
|
||||
self.context['acl'].object_id, self.context['acl'].pk
|
||||
), request=self.context['request'], format=self.context['format']
|
||||
'rest_api:accesscontrollist-detail', kwargs={
|
||||
'app_label': self.context['acl'].content_type.app_label,
|
||||
'model': self.context['acl'].content_type.model,
|
||||
'object_id': self.context['acl'].object_id,
|
||||
'acl_pk': self.context['acl'].pk
|
||||
}, request=self.context['request'], format=self.context['format']
|
||||
)
|
||||
|
||||
|
||||
@@ -153,18 +159,22 @@ class WritableAccessControlListSerializer(serializers.ModelSerializer):
|
||||
|
||||
def get_permissions_url(self, instance):
|
||||
return reverse(
|
||||
'rest_api:accesscontrollist-permission-list', args=(
|
||||
instance.content_type.app_label, instance.content_type.model,
|
||||
instance.object_id, instance.pk
|
||||
), request=self.context['request'], format=self.context['format']
|
||||
'rest_api:accesscontrollist-permission-list', kwargs={
|
||||
'app_label': instance.content_type.app_label,
|
||||
'model': instance.content_type.model,
|
||||
'object_id': instance.object_id,
|
||||
'acl_pk': instance.pk
|
||||
}, request=self.context['request'], format=self.context['format']
|
||||
)
|
||||
|
||||
def get_url(self, instance):
|
||||
return reverse(
|
||||
'rest_api:accesscontrollist-detail', args=(
|
||||
instance.content_type.app_label, instance.content_type.model,
|
||||
instance.object_id, instance.pk
|
||||
), request=self.context['request'], format=self.context['format']
|
||||
'rest_api:accesscontrollist-detail', kwargs={
|
||||
'app_label': instance.content_type.app_label,
|
||||
'model': instance.content_type.model,
|
||||
'object_id': instance.object_id,
|
||||
'acl_pk': instance.pk
|
||||
}, request=self.context['request'], format=self.context['format']
|
||||
)
|
||||
|
||||
def validate(self, attrs):
|
||||
|
||||
@@ -35,13 +35,12 @@ class ACLAPITestCase(DocumentTestMixin, BaseAPITestCase):
|
||||
|
||||
response = self.get(
|
||||
viewname='rest_api:accesscontrollist-list',
|
||||
args=(
|
||||
self.document_content_type.app_label,
|
||||
self.document_content_type.model,
|
||||
self.document.pk
|
||||
)
|
||||
kwargs={
|
||||
'app_label': self.document_content_type.app_label,
|
||||
'model': self.document_content_type.model,
|
||||
'object_id': self.document.pk
|
||||
}
|
||||
)
|
||||
|
||||
self.assertEqual(
|
||||
response.data['results'][0]['content_type']['app_label'],
|
||||
self.document_content_type.app_label
|
||||
@@ -55,11 +54,12 @@ class ACLAPITestCase(DocumentTestMixin, BaseAPITestCase):
|
||||
|
||||
response = self.delete(
|
||||
viewname='rest_api:accesscontrollist-detail',
|
||||
args=(
|
||||
self.document_content_type.app_label,
|
||||
self.document_content_type.model,
|
||||
self.document.pk, self.acl.pk
|
||||
)
|
||||
kwargs={
|
||||
'app_label': self.document_content_type.app_label,
|
||||
'model': self.document_content_type.model,
|
||||
'object_id': self.document.pk,
|
||||
'acl_pk': self.acl.pk
|
||||
}
|
||||
)
|
||||
|
||||
self.assertEqual(response.status_code, status.HTTP_204_NO_CONTENT)
|
||||
@@ -70,11 +70,12 @@ class ACLAPITestCase(DocumentTestMixin, BaseAPITestCase):
|
||||
|
||||
response = self.get(
|
||||
viewname='rest_api:accesscontrollist-detail',
|
||||
args=(
|
||||
self.document_content_type.app_label,
|
||||
self.document_content_type.model,
|
||||
self.document.pk, self.acl.pk
|
||||
)
|
||||
kwargs={
|
||||
'app_label': self.document_content_type.app_label,
|
||||
'model': self.document_content_type.model,
|
||||
'object_id': self.document.pk,
|
||||
'acl_pk': self.acl.pk
|
||||
}
|
||||
)
|
||||
self.assertEqual(
|
||||
response.data['content_type']['app_label'],
|
||||
@@ -90,12 +91,12 @@ class ACLAPITestCase(DocumentTestMixin, BaseAPITestCase):
|
||||
|
||||
response = self.delete(
|
||||
viewname='rest_api:accesscontrollist-permission-detail',
|
||||
args=(
|
||||
self.document_content_type.app_label,
|
||||
self.document_content_type.model,
|
||||
self.document.pk, self.acl.pk,
|
||||
permission.pk
|
||||
)
|
||||
kwargs={
|
||||
'app_label': self.document_content_type.app_label,
|
||||
'model': self.document_content_type.model,
|
||||
'object_id': self.document.pk,
|
||||
'acl_pk': self.acl.pk, 'permission_pk': permission.pk
|
||||
}
|
||||
)
|
||||
self.assertEqual(response.status_code, status.HTTP_204_NO_CONTENT)
|
||||
self.assertEqual(self.acl.permissions.count(), 0)
|
||||
@@ -106,16 +107,16 @@ class ACLAPITestCase(DocumentTestMixin, BaseAPITestCase):
|
||||
|
||||
response = self.get(
|
||||
viewname='rest_api:accesscontrollist-permission-detail',
|
||||
args=(
|
||||
self.document_content_type.app_label,
|
||||
self.document_content_type.model,
|
||||
self.document.pk, self.acl.pk,
|
||||
permission.pk
|
||||
)
|
||||
kwargs={
|
||||
'app_label': self.document_content_type.app_label,
|
||||
'model': self.document_content_type.model,
|
||||
'object_id': self.document.pk, 'acl_pk': self.acl.pk,
|
||||
'permission_pk': permission.pk
|
||||
}
|
||||
)
|
||||
|
||||
self.assertEqual(
|
||||
response.data['pk'], permission_document_view.pk
|
||||
response.data['permission_pk'], permission_document_view.pk
|
||||
)
|
||||
|
||||
def test_object_acl_permission_list_view(self):
|
||||
@@ -123,15 +124,16 @@ class ACLAPITestCase(DocumentTestMixin, BaseAPITestCase):
|
||||
|
||||
response = self.get(
|
||||
viewname='rest_api:accesscontrollist-permission-list',
|
||||
args=(
|
||||
self.document_content_type.app_label,
|
||||
self.document_content_type.model,
|
||||
self.document.pk, self.acl.pk
|
||||
)
|
||||
kwargs={
|
||||
'app_label': self.document_content_type.app_label,
|
||||
'model': self.document_content_type.model,
|
||||
'object_id': self.document.pk,
|
||||
'acl_pk': self.acl.pk
|
||||
}
|
||||
)
|
||||
|
||||
self.assertEqual(
|
||||
response.data['results'][0]['pk'],
|
||||
response.data['results'][0]['permission_pk'],
|
||||
permission_document_view.pk
|
||||
)
|
||||
|
||||
@@ -140,11 +142,11 @@ class ACLAPITestCase(DocumentTestMixin, BaseAPITestCase):
|
||||
|
||||
response = self.post(
|
||||
viewname='rest_api:accesscontrollist-permission-list',
|
||||
args=(
|
||||
self.document_content_type.app_label,
|
||||
self.document_content_type.model,
|
||||
self.document.pk, self.acl.pk
|
||||
), data={'permission_pk': permission_acl_view.pk}
|
||||
kwargs={
|
||||
'app_label': self.document_content_type.app_label,
|
||||
'model': self.document_content_type.model,
|
||||
'object_id': self.document.pk, 'acl_pk': self.acl.pk
|
||||
}, data={'permission_pk': permission_acl_view.pk}
|
||||
)
|
||||
|
||||
self.assertEqual(response.status_code, status.HTTP_201_CREATED)
|
||||
@@ -158,11 +160,11 @@ class ACLAPITestCase(DocumentTestMixin, BaseAPITestCase):
|
||||
def test_object_acl_post_no_permissions_added_view(self):
|
||||
response = self.post(
|
||||
viewname='rest_api:accesscontrollist-list',
|
||||
args=(
|
||||
self.document_content_type.app_label,
|
||||
self.document_content_type.model,
|
||||
self.document.pk
|
||||
), data={'role_pk': self.role.pk}
|
||||
kwargs={
|
||||
'app_label': self.document_content_type.app_label,
|
||||
'model': self.document_content_type.model,
|
||||
'object_id': self.document.pk
|
||||
}, data={'role_pk': self.role.pk}
|
||||
)
|
||||
|
||||
self.assertEqual(response.status_code, status.HTTP_201_CREATED)
|
||||
@@ -179,11 +181,11 @@ class ACLAPITestCase(DocumentTestMixin, BaseAPITestCase):
|
||||
def test_object_acl_post_with_permissions_added_view(self):
|
||||
response = self.post(
|
||||
viewname='rest_api:accesscontrollist-list',
|
||||
args=(
|
||||
self.document_content_type.app_label,
|
||||
self.document_content_type.model,
|
||||
self.document.pk
|
||||
), data={
|
||||
kwargs={
|
||||
'app_label': self.document_content_type.app_label,
|
||||
'model': self.document_content_type.model,
|
||||
'object_id': self.document.pk
|
||||
}, data={
|
||||
'role_pk': self.role.pk,
|
||||
'permissions_pk_list': permission_acl_view.pk
|
||||
|
||||
|
||||
@@ -35,7 +35,7 @@ class ACLsLinksTestCase(GenericDocumentViewTestCase):
|
||||
}
|
||||
|
||||
self.assertEqual(
|
||||
resolved_link.url, reverse('acls:acl_create', kwargs=kwargs)
|
||||
resolved_link.url, reverse(viewname='acls:acl_create', kwargs=kwargs)
|
||||
)
|
||||
|
||||
def test_document_acl_delete_link(self):
|
||||
@@ -53,7 +53,7 @@ class ACLsLinksTestCase(GenericDocumentViewTestCase):
|
||||
self.assertNotEqual(resolved_link, None)
|
||||
|
||||
self.assertEqual(
|
||||
resolved_link.url, reverse('acls:acl_delete', args=(acl.pk,))
|
||||
resolved_link.url, reverse(viewname='acls:acl_delete', kwargs={'acl_pk': acl.pk})
|
||||
)
|
||||
|
||||
def test_document_acl_edit_link(self):
|
||||
@@ -71,7 +71,7 @@ class ACLsLinksTestCase(GenericDocumentViewTestCase):
|
||||
self.assertNotEqual(resolved_link, None)
|
||||
|
||||
self.assertEqual(
|
||||
resolved_link.url, reverse('acls:acl_permissions', args=(acl.pk,))
|
||||
resolved_link.url, reverse(viewname='acls:acl_permissions', kwargs={'acl_pk': acl.pk})
|
||||
)
|
||||
|
||||
def test_document_acl_list_link(self):
|
||||
@@ -96,5 +96,5 @@ class ACLsLinksTestCase(GenericDocumentViewTestCase):
|
||||
}
|
||||
|
||||
self.assertEqual(
|
||||
resolved_link.url, reverse('acls:acl_list', kwargs=kwargs)
|
||||
resolved_link.url, reverse(viewname='acls:acl_list', kwargs=kwargs)
|
||||
)
|
||||
|
||||
@@ -1,191 +1,178 @@
|
||||
from __future__ import absolute_import, unicode_literals
|
||||
|
||||
from django.contrib.contenttypes.models import ContentType
|
||||
from django.utils.encoding import force_text
|
||||
|
||||
from mayan.apps.documents.tests import GenericDocumentViewTestCase
|
||||
from mayan.apps.permissions.tests.mixins import RoleTestMixin
|
||||
|
||||
from ..models import AccessControlList
|
||||
from ..permissions import permission_acl_edit, permission_acl_view
|
||||
|
||||
|
||||
class AccessControlListViewTestCase(GenericDocumentViewTestCase):
|
||||
class AccessControlListViewTestCase(RoleTestMixin, GenericDocumentViewTestCase):
|
||||
def setUp(self):
|
||||
super(AccessControlListViewTestCase, self).setUp()
|
||||
self.login_user()
|
||||
self._create_test_role()
|
||||
|
||||
content_type = ContentType.objects.get_for_model(self.document)
|
||||
self.test_object = self.document
|
||||
|
||||
self.view_arguments = {
|
||||
content_type = ContentType.objects.get_for_model(self.test_object)
|
||||
|
||||
self.view_content_object_arguments = {
|
||||
'app_label': content_type.app_label,
|
||||
'model': content_type.model,
|
||||
'object_id': self.document.pk
|
||||
'object_id': self.test_object.pk
|
||||
}
|
||||
|
||||
def test_acl_create_view_no_permission(self):
|
||||
self.login_user()
|
||||
|
||||
response = self.get(
|
||||
viewname='acls:acl_create', kwargs=self.view_arguments, data={
|
||||
'role': self.role.pk
|
||||
def _request_get_acl_create_view(self):
|
||||
return self.get(
|
||||
viewname='acls:acl_create',
|
||||
kwargs=self.view_content_object_arguments, data={
|
||||
'role': self.test_role.pk
|
||||
}
|
||||
)
|
||||
|
||||
self.assertEquals(response.status_code, 403)
|
||||
def test_acl_create_view_get_no_permission(self):
|
||||
response = self._request_get_acl_create_view()
|
||||
|
||||
self.assertEqual(response.status_code, 404)
|
||||
self.assertEqual(AccessControlList.objects.count(), 0)
|
||||
|
||||
def test_acl_create_view_with_permission(self):
|
||||
self.login_user()
|
||||
def test_acl_create_view_get_with_document_access(self):
|
||||
self.grant_access(obj=self.test_object, permission=permission_acl_edit)
|
||||
|
||||
self.role.permissions.add(
|
||||
permission_acl_edit.stored_permission
|
||||
)
|
||||
|
||||
response = self.get(
|
||||
viewname='acls:acl_create', kwargs=self.view_arguments, data={
|
||||
'role': self.role.pk
|
||||
}, follow=True
|
||||
)
|
||||
response = self._request_get_acl_create_view()
|
||||
|
||||
self.assertContains(
|
||||
response, text=self.document.label, status_code=200
|
||||
response=response, text=force_text(self.test_object),
|
||||
status_code=200
|
||||
)
|
||||
|
||||
def _request_post_acl_create_view(self):
|
||||
return self.post(
|
||||
viewname='acls:acl_create',
|
||||
kwargs=self.view_content_object_arguments, data={
|
||||
'role': self.test_role.pk
|
||||
}
|
||||
)
|
||||
|
||||
def test_acl_create_view_post_no_permission(self):
|
||||
self.login_user()
|
||||
response = self._request_post_acl_create_view()
|
||||
|
||||
response = self.post(
|
||||
viewname='acls:acl_create', kwargs=self.view_arguments, data={
|
||||
'role': self.role.pk
|
||||
}
|
||||
)
|
||||
|
||||
self.assertEquals(response.status_code, 403)
|
||||
self.assertEqual(response.status_code, 404)
|
||||
self.assertEqual(AccessControlList.objects.count(), 0)
|
||||
|
||||
def test_acl_create_view_with_post_permission(self):
|
||||
self.login_user()
|
||||
def test_acl_create_view_post_with_document_access(self):
|
||||
self.grant_access(obj=self.test_object, permission=permission_acl_edit)
|
||||
response = self._request_post_acl_create_view()
|
||||
|
||||
self.role.permissions.add(
|
||||
permission_acl_edit.stored_permission
|
||||
)
|
||||
|
||||
response = self.post(
|
||||
viewname='acls:acl_create', kwargs=self.view_arguments, data={
|
||||
'role': self.role.pk
|
||||
}, follow=True
|
||||
)
|
||||
|
||||
self.assertContains(response, text='created', status_code=200)
|
||||
self.assertEqual(AccessControlList.objects.count(), 1)
|
||||
self.assertEqual(response.status_code, 302)
|
||||
# 2 ACLs: 1 created by the test and the other by the self.grant_access
|
||||
self.assertEqual(AccessControlList.objects.count(), 2)
|
||||
|
||||
def test_acl_create_duplicate_view_with_permission(self):
|
||||
"""
|
||||
Test creating a duplicate ACL entry: same object & role
|
||||
Result: Should redirect to existing ACL for object + role combination
|
||||
"""
|
||||
acl = AccessControlList.objects.create(
|
||||
content_object=self.document, role=self.role
|
||||
self._create_test_acl()
|
||||
|
||||
self.grant_access(obj=self.test_object, permission=permission_acl_edit)
|
||||
|
||||
response = self._request_post_acl_create_view()
|
||||
self.assertNotContains(
|
||||
response=response, text=force_text(self.test_acl.role),
|
||||
status_code=200
|
||||
)
|
||||
|
||||
self.login_user()
|
||||
|
||||
self.role.permissions.add(
|
||||
permission_acl_edit.stored_permission
|
||||
self.assertEqual(AccessControlList.objects.count(), 2)
|
||||
self.assertEqual(
|
||||
AccessControlList.objects.first().pk, self.test_acl.pk
|
||||
)
|
||||
|
||||
response = self.post(
|
||||
viewname='acls:acl_create', kwargs=self.view_arguments, data={
|
||||
'role': self.role.pk
|
||||
}, follow=True
|
||||
def _create_test_acl(self):
|
||||
self.test_acl = AccessControlList.objects.create(
|
||||
content_object=self.test_object, role=self.test_role
|
||||
)
|
||||
|
||||
self.assertContains(
|
||||
response, text='vailable permissions', status_code=200
|
||||
)
|
||||
self.assertEqual(AccessControlList.objects.count(), 1)
|
||||
self.assertEqual(AccessControlList.objects.first().pk, acl.pk)
|
||||
|
||||
def test_orphan_acl_create_view_with_permission(self):
|
||||
"""
|
||||
Test creating an ACL entry for an object with no model permissions.
|
||||
Result: Should display a blank permissions list (not optgroup)
|
||||
"""
|
||||
self.login_user()
|
||||
|
||||
self.role.permissions.add(
|
||||
permission_acl_edit.stored_permission
|
||||
def _request_acl_delete_view(self):
|
||||
return self.post(
|
||||
viewname='acls:acl_delete', kwargs={'acl_pk': self.test_acl.pk}
|
||||
)
|
||||
|
||||
recent_entry = self.document.add_as_recent_document_for_user(self.user)
|
||||
def test_acl_delete_view_no_permission(self):
|
||||
self._create_test_acl()
|
||||
|
||||
content_type = ContentType.objects.get_for_model(recent_entry)
|
||||
|
||||
view_arguments = {
|
||||
'app_label': content_type.app_label,
|
||||
'model': content_type.model,
|
||||
'object_id': recent_entry.pk
|
||||
}
|
||||
|
||||
response = self.post(
|
||||
viewname='acls:acl_create', kwargs=view_arguments, data={
|
||||
'role': self.role.pk
|
||||
}, follow=True
|
||||
response = self._request_acl_delete_view()
|
||||
self.assertNotContains(
|
||||
response=response, text=force_text(self.test_object),
|
||||
status_code=404
|
||||
)
|
||||
# 1 ACL: the test one
|
||||
self.assertQuerysetEqual(
|
||||
qs=AccessControlList.objects.all(), values=(repr(self.test_acl),)
|
||||
)
|
||||
|
||||
self.assertNotContains(response, text='optgroup', status_code=200)
|
||||
self.assertEqual(AccessControlList.objects.count(), 1)
|
||||
def test_acl_delete_view_with_access(self):
|
||||
self._create_test_acl()
|
||||
|
||||
acl = self.grant_access(
|
||||
obj=self.test_object, permission=permission_acl_edit
|
||||
)
|
||||
response = self._request_acl_delete_view()
|
||||
self.assertEqual(response.status_code, 302)
|
||||
# 1 ACL: the one created by the self.grant_access
|
||||
self.assertQuerysetEqual(
|
||||
qs=AccessControlList.objects.all(), values=(repr(acl),)
|
||||
)
|
||||
|
||||
def _request_acl_list_view(self):
|
||||
return self.get(
|
||||
viewname='acls:acl_list', kwargs=self.view_content_object_arguments
|
||||
)
|
||||
|
||||
def test_acl_list_view_no_permission(self):
|
||||
self.login_user()
|
||||
response = self._request_acl_list_view()
|
||||
|
||||
document = self.document.add_as_recent_document_for_user(
|
||||
self.user
|
||||
).document
|
||||
|
||||
acl = AccessControlList.objects.create(
|
||||
content_object=document, role=self.role
|
||||
)
|
||||
acl.permissions.add(permission_acl_edit.stored_permission)
|
||||
|
||||
content_type = ContentType.objects.get_for_model(document)
|
||||
|
||||
view_arguments = {
|
||||
'app_label': content_type.app_label,
|
||||
'model': content_type.model,
|
||||
'object_id': document.pk
|
||||
}
|
||||
|
||||
response = self.get(
|
||||
viewname='acls:acl_list', kwargs=view_arguments
|
||||
self.assertNotContains(
|
||||
response=response, text=force_text(self.test_object),
|
||||
status_code=404
|
||||
)
|
||||
|
||||
self.assertNotContains(response, text=document.label, status_code=403)
|
||||
self.assertNotContains(response, text='otal: 1', status_code=403)
|
||||
def test_acl_list_view_with_access(self):
|
||||
self.grant_access(obj=self.test_object, permission=permission_acl_view)
|
||||
|
||||
def test_acl_list_view_with_permission(self):
|
||||
self.login_user()
|
||||
response = self._request_acl_list_view()
|
||||
|
||||
self.role.permissions.add(
|
||||
permission_acl_view.stored_permission
|
||||
self.assertContains(
|
||||
response=response, text=force_text(self.test_object),
|
||||
status_code=200
|
||||
)
|
||||
|
||||
document = self.document.add_as_recent_document_for_user(
|
||||
self.user
|
||||
).document
|
||||
|
||||
acl = AccessControlList.objects.create(
|
||||
content_object=document, role=self.role
|
||||
def _request_get_acl_permissions_view(self):
|
||||
return self.get(
|
||||
viewname='acls:acl_permissions',
|
||||
kwargs={'acl_pk': self.test_acl.pk}
|
||||
)
|
||||
acl.permissions.add(permission_acl_view.stored_permission)
|
||||
|
||||
content_type = ContentType.objects.get_for_model(document)
|
||||
def test_acl_permissions_view_get_no_permission(self):
|
||||
self._create_test_acl()
|
||||
|
||||
view_arguments = {
|
||||
'app_label': content_type.app_label,
|
||||
'model': content_type.model,
|
||||
'object_id': document.pk
|
||||
}
|
||||
|
||||
response = self.get(
|
||||
viewname='acls:acl_list', kwargs=view_arguments
|
||||
response = self._request_get_acl_permissions_view()
|
||||
self.assertNotContains(
|
||||
response=response, text=force_text(self.test_object),
|
||||
status_code=404
|
||||
)
|
||||
|
||||
def test_acl_permissions_view_get_with_access(self):
|
||||
self._create_test_acl()
|
||||
|
||||
self.grant_access(obj=self.test_object, permission=permission_acl_edit)
|
||||
|
||||
response = self._request_get_acl_permissions_view()
|
||||
self.assertContains(
|
||||
response=response, text=force_text(self.test_object),
|
||||
status_code=200
|
||||
)
|
||||
self.assertContains(response, text=document.label, status_code=200)
|
||||
|
||||
@@ -12,35 +12,40 @@ from .views import (
|
||||
|
||||
urlpatterns = [
|
||||
url(
|
||||
r'^(?P<app_label>[-\w]+)/(?P<model>[-\w]+)/(?P<object_id>\d+)/create/$',
|
||||
ACLCreateView.as_view(), name='acl_create'
|
||||
regex=r'^objects/(?P<app_label>[-\w]+)/(?P<model>[-\w]+)/(?P<object_id>\d+)/create/$',
|
||||
name='acl_create', view=ACLCreateView.as_view()
|
||||
),
|
||||
url(
|
||||
r'^(?P<app_label>[-\w]+)/(?P<model>[-\w]+)/(?P<object_id>\d+)/list/$',
|
||||
ACLListView.as_view(), name='acl_list'
|
||||
regex=r'^objects/(?P<app_label>[-\w]+)/(?P<model>[-\w]+)/(?P<object_id>\d+)/list/$',
|
||||
name='acl_list', view=ACLListView.as_view()
|
||||
),
|
||||
url(r'^(?P<pk>\d+)/delete/$', ACLDeleteView.as_view(), name='acl_delete'),
|
||||
url(
|
||||
r'^(?P<pk>\d+)/permissions/$', ACLPermissionsView.as_view(),
|
||||
name='acl_permissions'
|
||||
regex=r'^acls/(?P<acl_pk>\d+)/delete/$', name='acl_delete',
|
||||
view=ACLDeleteView.as_view()
|
||||
),
|
||||
url(
|
||||
regex=r'^acls/(?P<acl_pk>\d+)/permissions/$', name='acl_permissions',
|
||||
view=ACLPermissionsView.as_view()
|
||||
),
|
||||
]
|
||||
|
||||
api_urls = [
|
||||
url(
|
||||
r'^objects/(?P<app_label>[-\w]+)/(?P<model>[-\w]+)/(?P<object_pk>\d+)/acls/$',
|
||||
APIObjectACLListView.as_view(), name='accesscontrollist-list'
|
||||
regex=r'^objects/(?P<app_label>[-\w]+)/(?P<model>[-\w]+)/(?P<object_id>\d+)/acls/$',
|
||||
name='accesscontrollist-list', view=APIObjectACLListView.as_view()
|
||||
),
|
||||
url(
|
||||
r'^objects/(?P<app_label>[-\w]+)/(?P<model>[-\w]+)/(?P<object_pk>\d+)/acls/(?P<pk>\d+)/$',
|
||||
APIObjectACLView.as_view(), name='accesscontrollist-detail'
|
||||
regex=r'^objects/(?P<app_label>[-\w]+)/(?P<model>[-\w]+)/(?P<object_id>\d+)/acls/(?P<acl_pk>\d+)/$',
|
||||
name='accesscontrollist-detail', view=APIObjectACLView.as_view()
|
||||
),
|
||||
url(
|
||||
r'^objects/(?P<app_label>[-\w]+)/(?P<model>[-\w]+)/(?P<object_pk>\d+)/acls/(?P<pk>\d+)/permissions/$',
|
||||
APIObjectACLPermissionListView.as_view(), name='accesscontrollist-permission-list'
|
||||
regex=r'^objects/(?P<app_label>[-\w]+)/(?P<model>[-\w]+)/(?P<object_id>\d+)/acls/(?P<acl_pk>\d+)/permissions/$',
|
||||
name='accesscontrollist-permission-list',
|
||||
view=APIObjectACLPermissionListView.as_view()
|
||||
),
|
||||
url(
|
||||
r'^objects/(?P<app_label>[-\w]+)/(?P<model>[-\w]+)/(?P<object_pk>\d+)/acls/(?P<pk>\d+)/permissions/(?P<permission_pk>\d+)/$',
|
||||
APIObjectACLPermissionView.as_view(), name='accesscontrollist-permission-detail'
|
||||
regex=r'^objects/(?P<app_label>[-\w]+)/(?P<model>[-\w]+)/(?P<object_id>\d+)/acls/(?P<acl_pk>\d+)/permissions/(?P<permission_pk>\d+)/$',
|
||||
name='accesscontrollist-permission-detail',
|
||||
view=APIObjectACLPermissionView.as_view()
|
||||
),
|
||||
]
|
||||
|
||||
@@ -3,22 +3,23 @@ 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.core.exceptions import PermissionDenied
|
||||
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.mixins import ContentTypeViewMixin, ExternalObjectViewMixin
|
||||
from mayan.apps.common.views import (
|
||||
AssignRemoveView, SingleObjectCreateView, SingleObjectDeleteView,
|
||||
SingleObjectListView
|
||||
)
|
||||
from mayan.apps.permissions import Permission, PermissionNamespace
|
||||
from mayan.apps.permissions.models import StoredPermission
|
||||
from mayan.apps.permissions.models import Role, StoredPermission
|
||||
|
||||
from .classes import ModelPermission
|
||||
from .forms import ACLCreateForm
|
||||
from .icons import icon_acl_list
|
||||
from .links import link_acl_create
|
||||
from .models import AccessControlList
|
||||
@@ -27,76 +28,58 @@ from .permissions import permission_acl_edit, permission_acl_view
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class ACLCreateView(SingleObjectCreateView):
|
||||
fields = ('role',)
|
||||
model = AccessControlList
|
||||
class ACLCreateView(ContentTypeViewMixin, ExternalObjectViewMixin, SingleObjectCreateView):
|
||||
external_object_permission = permission_acl_edit
|
||||
external_object_pk_url_kwarg = 'object_id'
|
||||
form_class = ACLCreateForm
|
||||
|
||||
def dispatch(self, request, *args, **kwargs):
|
||||
self.object_content_type = get_object_or_404(
|
||||
klass=ContentType, app_label=self.kwargs['app_label'],
|
||||
model=self.kwargs['model']
|
||||
)
|
||||
def get_error_message_duplicate(self):
|
||||
return _(
|
||||
'An ACL for "%(object)s" using role "%(role)s" already exists. '
|
||||
'Edit that ACL entry instead.'
|
||||
) % {'object': self.get_external_object(), 'role': self.object.role}
|
||||
|
||||
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_external_object_queryset(self):
|
||||
# Here we get a queryset the object model for which an ACL will be
|
||||
# created.
|
||||
return self.get_content_type().model_class().objects.all()
|
||||
|
||||
def get_extra_context(self):
|
||||
return {
|
||||
'object': self.content_object,
|
||||
'object': self.get_external_object(),
|
||||
'title': _(
|
||||
'New access control lists for: %s'
|
||||
) % self.content_object
|
||||
) % self.get_external_object()
|
||||
}
|
||||
|
||||
def get_form_extra_kwargs(self):
|
||||
return {
|
||||
'field_name': 'role',
|
||||
'label': _('Role'),
|
||||
'queryset': Role.objects.exclude(
|
||||
pk__in=self.get_external_object().acls.values('role')
|
||||
),
|
||||
'widget_attributes': {'class': 'select2'}
|
||||
}
|
||||
|
||||
def get_instance_extra_data(self):
|
||||
return {
|
||||
'content_object': self.get_external_object()
|
||||
}
|
||||
|
||||
def get_queryset(self):
|
||||
self.get_external_object().acls.all()
|
||||
|
||||
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()
|
||||
return self.object.get_absolute_url()
|
||||
|
||||
|
||||
class ACLDeleteView(SingleObjectDeleteView):
|
||||
object_permission = permission_acl_edit
|
||||
object_permission_related = 'content_object'
|
||||
object_permission_raise_404 = True
|
||||
model = AccessControlList
|
||||
|
||||
def dispatch(self, request, *args, **kwargs):
|
||||
acl = get_object_or_404(klass=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)
|
||||
pk_url_kwarg = 'acl_pk'
|
||||
|
||||
def get_extra_context(self):
|
||||
return {
|
||||
@@ -107,33 +90,22 @@ class ACLDeleteView(SingleObjectDeleteView):
|
||||
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
|
||||
)
|
||||
'acls:acl_list', kwargs={
|
||||
'app_label': instance.content_type.app_label,
|
||||
'model': instance.content_type.model,
|
||||
'object_id': instance.object_id
|
||||
}
|
||||
)
|
||||
|
||||
|
||||
class ACLListView(SingleObjectListView):
|
||||
def dispatch(self, request, *args, **kwargs):
|
||||
self.object_content_type = get_object_or_404(
|
||||
klass=ContentType, app_label=self.kwargs['app_label'],
|
||||
model=self.kwargs['model']
|
||||
)
|
||||
class ACLListView(ContentTypeViewMixin, ExternalObjectViewMixin, SingleObjectListView):
|
||||
external_object_permission = permission_acl_view
|
||||
external_object_pk_url_kwarg = 'object_id'
|
||||
|
||||
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_external_object_queryset(self):
|
||||
# Here we get a queryset the object model for which an ACL will be
|
||||
# created.
|
||||
return self.get_content_type().model_class().objects.all()
|
||||
|
||||
def get_extra_context(self):
|
||||
return {
|
||||
@@ -141,7 +113,9 @@ class ACLListView(SingleObjectListView):
|
||||
'no_results_icon': icon_acl_list,
|
||||
'no_results_main_link': link_acl_create.resolve(
|
||||
context=RequestContext(
|
||||
self.request, {'resolved_object': self.content_object}
|
||||
self.request, {
|
||||
'resolved_object': self.get_external_object()
|
||||
}
|
||||
)
|
||||
),
|
||||
'no_results_title': _(
|
||||
@@ -149,17 +123,18 @@ class ACLListView(SingleObjectListView):
|
||||
),
|
||||
'no_results_text': _(
|
||||
'ACL stands for Access Control List and is a precise method '
|
||||
' to control user access to objects in the system.'
|
||||
' to control user access to objects in the system. ACLs '
|
||||
'allow granting a permission to a role but only for a '
|
||||
'specific object or set of objects.'
|
||||
),
|
||||
'object': self.get_external_object(),
|
||||
'title': _(
|
||||
'Access control lists for: %s' % self.get_external_object()
|
||||
),
|
||||
'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
|
||||
)
|
||||
return self.get_external_object().acls.all()
|
||||
|
||||
|
||||
class ACLPermissionsView(AssignRemoveView):
|
||||
@@ -192,18 +167,6 @@ class ACLPermissionsView(AssignRemoveView):
|
||||
permission = get_object_or_404(klass=StoredPermission, pk=item)
|
||||
self.get_object().permissions.add(permission)
|
||||
|
||||
def dispatch(self, request, *args, **kwargs):
|
||||
acl = get_object_or_404(klass=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
|
||||
@@ -235,22 +198,45 @@ class ACLPermissionsView(AssignRemoveView):
|
||||
|
||||
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
|
||||
Merge of 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)
|
||||
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(klass=AccessControlList, pk=self.kwargs['pk'])
|
||||
acl = get_object_or_404(
|
||||
klass=AccessControlList, pk=self.kwargs['acl_pk']
|
||||
)
|
||||
|
||||
# Get the ACL, from this get the object of the ACL, from the object
|
||||
# get all ACLs it holds as a filtered queryset by access.
|
||||
|
||||
try:
|
||||
AccessControlList.objects.check_access(
|
||||
permissions=(permission_acl_edit,), obj=acl.content_object,
|
||||
user=self.request.user
|
||||
)
|
||||
except PermissionDenied:
|
||||
queryset = AccessControlList.objects.none()
|
||||
else:
|
||||
queryset = acl.content_object.acls.all()
|
||||
|
||||
return get_object_or_404(klass=queryset, pk=self.kwargs['acl_pk'])
|
||||
|
||||
def get_right_list_help_text(self):
|
||||
if self.get_object().get_inherited_permissions():
|
||||
return _(
|
||||
'Disabled permissions are inherited from a parent object.'
|
||||
'Disabled permissions are inherited from a parent object and '
|
||||
'can\'t be removed from this view, they need to be removed '
|
||||
'from the parent object\'s ACL view.'
|
||||
)
|
||||
|
||||
return None
|
||||
return self.right_list_help_text
|
||||
|
||||
def left_list(self):
|
||||
Permission.refresh()
|
||||
|
||||
@@ -98,7 +98,9 @@ class GrantAccessAction(WorkflowAction):
|
||||
|
||||
def get_form_schema(self, *args, **kwargs):
|
||||
self.fields['content_type']['kwargs']['queryset'] = ModelPermission.get_classes(as_content_type=True)
|
||||
self.fields['permissions']['kwargs']['choices'] = Permission.all(as_choices=True)
|
||||
self.fields['permissions']['kwargs']['choices'] = Permission.all(
|
||||
as_choices=True
|
||||
)
|
||||
return super(GrantAccessAction, self).get_form_schema(*args, **kwargs)
|
||||
|
||||
def get_execute_data(self):
|
||||
|
||||
Reference in New Issue
Block a user