Backport ACL computation improvements
Signed-off-by: Roberto Rosario <roberto.rosario.gonzalez@gmail.com>
This commit is contained in:
10
HISTORY.rst
10
HISTORY.rst
@@ -212,6 +212,16 @@
|
|||||||
* Add new app to handle all dependencies.
|
* Add new app to handle all dependencies.
|
||||||
* Remove the licenses.py module and replace
|
* Remove the licenses.py module and replace
|
||||||
it with a dependencies.py module.
|
it with a dependencies.py module.
|
||||||
|
* Backport ACL computation improvements.
|
||||||
|
* Remove model permission proxy models.
|
||||||
|
* Remove related access control argument. This is
|
||||||
|
now handled by the related field registration.
|
||||||
|
* Allow nested access control checking.
|
||||||
|
* check_access's permissions argument must now be
|
||||||
|
an interable.
|
||||||
|
* Remove permissions_related from links.
|
||||||
|
* Remove mayan_permission_attribute_check from
|
||||||
|
API permission.
|
||||||
|
|
||||||
3.1.11 (2019-04-XX)
|
3.1.11 (2019-04-XX)
|
||||||
===================
|
===================
|
||||||
|
|||||||
@@ -245,6 +245,16 @@ Other changes
|
|||||||
* Add new app to handle all dependencies.
|
* Add new app to handle all dependencies.
|
||||||
* Remove the licenses.py module and replace
|
* Remove the licenses.py module and replace
|
||||||
it with a dependencies.py module.
|
it with a dependencies.py module.
|
||||||
|
* Backport ACL computation improvements.
|
||||||
|
* Remove model permission proxy models.
|
||||||
|
* Remove related access control argument. This is
|
||||||
|
now handled by the related field registration.
|
||||||
|
* Allow nested access control checking.
|
||||||
|
* check_access's permissions argument must now be
|
||||||
|
an interable.
|
||||||
|
* Remove permissions_related from links.
|
||||||
|
* Remove mayan_permission_attribute_check from
|
||||||
|
API permission.
|
||||||
|
|
||||||
Removals
|
Removals
|
||||||
--------
|
--------
|
||||||
|
|||||||
@@ -35,8 +35,8 @@ class APIObjectACLListView(generics.ListCreateAPIView):
|
|||||||
permission_required = permission_acl_edit
|
permission_required = permission_acl_edit
|
||||||
|
|
||||||
AccessControlList.objects.check_access(
|
AccessControlList.objects.check_access(
|
||||||
permissions=permission_required, user=self.request.user,
|
obj=content_object, permissions=(permission_required,),
|
||||||
obj=content_object
|
user=self.request.user
|
||||||
)
|
)
|
||||||
|
|
||||||
return content_object
|
return content_object
|
||||||
@@ -94,8 +94,8 @@ class APIObjectACLView(generics.RetrieveDestroyAPIView):
|
|||||||
)
|
)
|
||||||
|
|
||||||
AccessControlList.objects.check_access(
|
AccessControlList.objects.check_access(
|
||||||
permissions=permission_required, user=self.request.user,
|
obj=content_object, permissions=(permission_required,),
|
||||||
obj=content_object
|
user=self.request.user
|
||||||
)
|
)
|
||||||
|
|
||||||
return content_object
|
return content_object
|
||||||
@@ -130,7 +130,8 @@ class APIObjectACLPermissionListView(generics.ListCreateAPIView):
|
|||||||
permission = permission_acl_edit
|
permission = permission_acl_edit
|
||||||
|
|
||||||
AccessControlList.objects.check_access(
|
AccessControlList.objects.check_access(
|
||||||
obj=content_object, permissions=permission, user=self.request.user
|
obj=content_object, permissions=(permission,),
|
||||||
|
user=self.request.user
|
||||||
)
|
)
|
||||||
|
|
||||||
return content_object
|
return content_object
|
||||||
@@ -191,7 +192,8 @@ class APIObjectACLPermissionView(generics.RetrieveDestroyAPIView):
|
|||||||
permission = permission_acl_edit
|
permission = permission_acl_edit
|
||||||
|
|
||||||
AccessControlList.objects.check_access(
|
AccessControlList.objects.check_access(
|
||||||
obj=content_object, permissions=permission, user=self.request.user
|
obj=content_object, permissions=(permission,),
|
||||||
|
user=self.request.user
|
||||||
)
|
)
|
||||||
|
|
||||||
return content_object
|
return content_object
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ from mayan.apps.events.links import (
|
|||||||
)
|
)
|
||||||
from mayan.apps.navigation.classes import SourceColumn
|
from mayan.apps.navigation.classes import SourceColumn
|
||||||
|
|
||||||
|
from .classes import ModelPermission
|
||||||
from .events import event_acl_created, event_acl_edited
|
from .events import event_acl_created, event_acl_edited
|
||||||
from .links import link_acl_create, link_acl_delete, link_acl_permissions
|
from .links import link_acl_create, link_acl_delete, link_acl_permissions
|
||||||
|
|
||||||
@@ -33,6 +34,10 @@ class ACLsApp(MayanAppConfig):
|
|||||||
model=AccessControlList
|
model=AccessControlList
|
||||||
)
|
)
|
||||||
|
|
||||||
|
ModelPermission.register_inheritance(
|
||||||
|
model=AccessControlList, related='content_object',
|
||||||
|
)
|
||||||
|
|
||||||
SourceColumn(
|
SourceColumn(
|
||||||
attribute='role', is_sortable=True, source=AccessControlList,
|
attribute='role', is_sortable=True, source=AccessControlList,
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -8,8 +8,8 @@ logger = logging.getLogger(__name__)
|
|||||||
|
|
||||||
|
|
||||||
class ModelPermission(object):
|
class ModelPermission(object):
|
||||||
|
_functions = {}
|
||||||
_inheritances = {}
|
_inheritances = {}
|
||||||
_proxies = {}
|
|
||||||
_registry = {}
|
_registry = {}
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
@@ -63,24 +63,23 @@ class ModelPermission(object):
|
|||||||
if class_permissions:
|
if class_permissions:
|
||||||
permissions.extend(class_permissions)
|
permissions.extend(class_permissions)
|
||||||
|
|
||||||
proxy = cls._proxies.get(type(instance))
|
|
||||||
|
|
||||||
if proxy:
|
|
||||||
permissions.extend(cls._registry.get(proxy))
|
|
||||||
|
|
||||||
pks = [
|
pks = [
|
||||||
permission.stored_permission.pk for permission in set(permissions)
|
permission.stored_permission.pk for permission in set(permissions)
|
||||||
]
|
]
|
||||||
return StoredPermission.objects.filter(pk__in=pks)
|
return StoredPermission.objects.filter(pk__in=pks)
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def register_proxy(cls, source, model):
|
def get_function(cls, model):
|
||||||
cls._proxies[model] = source
|
return cls._functions[model]
|
||||||
|
|
||||||
@classmethod
|
|
||||||
def register_inheritance(cls, model, related):
|
|
||||||
cls._inheritances[model] = related
|
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def get_inheritance(cls, model):
|
def get_inheritance(cls, model):
|
||||||
return cls._inheritances[model]
|
return cls._inheritances[model]
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def register_function(cls, model, function):
|
||||||
|
cls._functions[model] = function
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def register_inheritance(cls, model, related):
|
||||||
|
cls._inheritances[model] = related
|
||||||
|
|||||||
@@ -29,23 +29,22 @@ def get_kwargs_factory(variable_name):
|
|||||||
return get_kwargs
|
return get_kwargs
|
||||||
|
|
||||||
|
|
||||||
link_acl_delete = Link(
|
|
||||||
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'),
|
|
||||||
permissions=(permission_acl_view,), text=_('ACLs'), view='acls:acl_list'
|
|
||||||
)
|
|
||||||
link_acl_create = Link(
|
link_acl_create = Link(
|
||||||
icon_class=icon_acl_new, kwargs=get_kwargs_factory('resolved_object'),
|
icon_class=icon_acl_new, kwargs=get_kwargs_factory('resolved_object'),
|
||||||
permissions=(permission_acl_edit,), text=_('New ACL'),
|
permissions=(permission_acl_edit,), text=_('New ACL'),
|
||||||
view='acls:acl_create'
|
view='acls:acl_create'
|
||||||
)
|
)
|
||||||
|
link_acl_delete = Link(
|
||||||
|
args='resolved_object.pk', icon_class=icon_acl_delete,
|
||||||
|
permissions=(permission_acl_edit,), tags='dangerous', text=_('Delete'),
|
||||||
|
view='acls:acl_delete'
|
||||||
|
)
|
||||||
|
link_acl_list = Link(
|
||||||
|
icon_class=icon_acl_list, kwargs=get_kwargs_factory('resolved_object'),
|
||||||
|
permissions=(permission_acl_view,), text=_('ACLs'), view='acls:acl_list'
|
||||||
|
)
|
||||||
link_acl_permissions = Link(
|
link_acl_permissions = Link(
|
||||||
args='resolved_object.pk', icon_class=icon_acl_permissions,
|
args='resolved_object.pk', icon_class=icon_acl_permissions,
|
||||||
permissions=(permission_acl_edit,),
|
permissions=(permission_acl_edit,),
|
||||||
permissions_related='content_object', text=_('Permissions'),
|
text=_('Permissions'), view='acls:acl_permissions'
|
||||||
view='acls:acl_permissions',
|
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -1,17 +1,23 @@
|
|||||||
from __future__ import absolute_import, unicode_literals
|
from __future__ import absolute_import, unicode_literals
|
||||||
|
|
||||||
|
from functools import reduce
|
||||||
import logging
|
import logging
|
||||||
|
import operator
|
||||||
|
import warnings
|
||||||
|
|
||||||
|
from django.contrib.contenttypes.fields import GenericForeignKey
|
||||||
from django.contrib.contenttypes.models import ContentType
|
from django.contrib.contenttypes.models import ContentType
|
||||||
from django.core.exceptions import PermissionDenied
|
from django.core.exceptions import PermissionDenied
|
||||||
from django.db import models
|
from django.db import models
|
||||||
from django.db.models import Q
|
from django.db.models import CharField, Value as V, Q
|
||||||
|
from django.db.models.functions import Concat
|
||||||
from django.utils.encoding import force_text
|
from django.utils.encoding import force_text
|
||||||
from django.utils.translation import ugettext
|
from django.utils.translation import ugettext
|
||||||
|
|
||||||
from mayan.apps.common.utils import (
|
from mayan.apps.common.utils import (
|
||||||
resolve_attribute, return_attrib, return_related
|
get_related_field, resolve_attribute, return_related
|
||||||
)
|
)
|
||||||
|
from mayan.apps.common.warnings import InterfaceWarning
|
||||||
from mayan.apps.permissions import Permission
|
from mayan.apps.permissions import Permission
|
||||||
from mayan.apps.permissions.models import StoredPermission
|
from mayan.apps.permissions.models import StoredPermission
|
||||||
|
|
||||||
@@ -26,170 +32,235 @@ class AccessControlListManager(models.Manager):
|
|||||||
Implement a 3 tier permission system, involving a permissions, an actor
|
Implement a 3 tier permission system, involving a permissions, an actor
|
||||||
and an object
|
and an object
|
||||||
"""
|
"""
|
||||||
def check_access(self, permissions, user, obj, related=None):
|
def _get_acl_filters(self, queryset, stored_permission, user, related_field_name=None):
|
||||||
if user.is_superuser or user.is_staff:
|
"""
|
||||||
logger.debug(
|
This method does the bulk of the work. It generates filters for the
|
||||||
'Permissions "%s" on "%s" granted to user "%s" as superuser '
|
AccessControlList model to determine if there are ACL entries for the
|
||||||
'or staff', permissions, obj, user
|
members of the queryset's model provided.
|
||||||
|
"""
|
||||||
|
# Determine which of the cases we need to address
|
||||||
|
# 1: No related field
|
||||||
|
# 2: Related field
|
||||||
|
# 3: Related field that is Generic Foreign Key
|
||||||
|
# 4: No related field, but has an inherited related field, solved by
|
||||||
|
# recursion, branches to #2 or #3.
|
||||||
|
# 5: Inherited field of a related field
|
||||||
|
# -- Not addressed yet --
|
||||||
|
# 6: Inherited field of a related field that is Generic Foreign Key
|
||||||
|
# 7: Has a related function
|
||||||
|
result = []
|
||||||
|
|
||||||
|
if related_field_name:
|
||||||
|
related_field = get_related_field(
|
||||||
|
model=queryset.model, related_field_name=related_field_name
|
||||||
)
|
)
|
||||||
return True
|
|
||||||
|
|
||||||
try:
|
if isinstance(related_field, GenericForeignKey):
|
||||||
return Permission.check_permissions(
|
# Case 3: Generic Foreign Key, multiple ContentTypes + object
|
||||||
permissions=permissions, user=user
|
# id combinations
|
||||||
|
content_type_object_id_queryset = queryset.annotate(
|
||||||
|
ct_fk_combination=Concat(
|
||||||
|
related_field.ct_field, V('-'), related_field.fk_field,
|
||||||
|
output_field=CharField()
|
||||||
)
|
)
|
||||||
except PermissionDenied:
|
).values('ct_fk_combination')
|
||||||
try:
|
|
||||||
stored_permissions = [
|
|
||||||
permission.stored_permission for permission in permissions
|
|
||||||
]
|
|
||||||
except TypeError:
|
|
||||||
# Not a list of permissions, just one
|
|
||||||
stored_permissions = (permissions.stored_permission,)
|
|
||||||
|
|
||||||
if related:
|
acl_filter = self.annotate(
|
||||||
obj = return_attrib(obj, related)
|
ct_fk_combination=Concat(
|
||||||
|
'content_type', V('-'), 'object_id', output_field=CharField()
|
||||||
try:
|
|
||||||
parent_accessor = ModelPermission.get_inheritance(
|
|
||||||
model=obj._meta.model
|
|
||||||
)
|
)
|
||||||
except AttributeError:
|
).filter(
|
||||||
# AttributeError means non model objects: ie Statistics
|
permissions=stored_permission, role__groups__user=user,
|
||||||
# These can't have ACLs so we raise PermissionDenied
|
ct_fk_combination__in=content_type_object_id_queryset
|
||||||
|
).values('object_id')
|
||||||
|
|
||||||
# Force object to text to avoid UnicodeDecodeError
|
field_lookup = 'object_id__in'
|
||||||
raise PermissionDenied(
|
|
||||||
ugettext('Insufficient access for: %s') % force_text(obj)
|
result.append(Q(**{field_lookup: acl_filter}))
|
||||||
|
else:
|
||||||
|
# Case 2: Related field of a single type, single ContentType,
|
||||||
|
# multiple object id
|
||||||
|
content_type = ContentType.objects.get_for_model(
|
||||||
|
model=related_field.related_model
|
||||||
|
)
|
||||||
|
field_lookup = '{}_id__in'.format(related_field_name)
|
||||||
|
acl_filter = self.filter(
|
||||||
|
content_type=content_type, permissions=stored_permission,
|
||||||
|
role__groups__user=user
|
||||||
|
).values('object_id')
|
||||||
|
# Don't add empty filters otherwise the default AND operator
|
||||||
|
# of the Q object will return an empty queryset when reduced
|
||||||
|
# and filter out objects that should be in the final queryset.
|
||||||
|
if acl_filter:
|
||||||
|
result.append(Q(**{field_lookup: acl_filter}))
|
||||||
|
|
||||||
|
# Case 5: Related field, has an inherited related field itself
|
||||||
|
# Bubble up permssion check
|
||||||
|
# TODO: Add relationship support: OR or AND
|
||||||
|
# TODO: OR for document pages, version, doc, and types
|
||||||
|
# TODO: AND for new cabinet levels ACLs
|
||||||
|
try:
|
||||||
|
related_field_model_related_fields = (
|
||||||
|
ModelPermission.get_inheritance(
|
||||||
|
model=related_field.related_model
|
||||||
|
),
|
||||||
)
|
)
|
||||||
except KeyError:
|
except KeyError:
|
||||||
pass
|
pass
|
||||||
else:
|
else:
|
||||||
try:
|
relation_result = []
|
||||||
return self.check_access(
|
for related_field_model_related_field_name in related_field_model_related_fields:
|
||||||
obj=getattr(obj, parent_accessor),
|
related_field_name = '{}__{}'.format(related_field_name, related_field_model_related_field_name)
|
||||||
permissions=permissions, user=user
|
related_field_inherited_acl_queries = self._get_acl_filters(
|
||||||
|
queryset=queryset, stored_permission=stored_permission,
|
||||||
|
user=user, related_field_name=related_field_name
|
||||||
)
|
)
|
||||||
except AttributeError:
|
if related_field_inherited_acl_queries:
|
||||||
# Has no such attribute, try it as a related field
|
relation_result.append(reduce(operator.and_, related_field_inherited_acl_queries))
|
||||||
|
|
||||||
|
if relation_result:
|
||||||
|
result.append(reduce(operator.or_, relation_result))
|
||||||
|
else:
|
||||||
|
# Case 1: Original model, single ContentType, multiple object id
|
||||||
|
content_type = ContentType.objects.get_for_model(model=queryset.model)
|
||||||
|
field_lookup = 'id__in'
|
||||||
|
acl_filter = self.filter(
|
||||||
|
content_type=content_type, permissions=stored_permission,
|
||||||
|
role__groups__user=user
|
||||||
|
).values('object_id')
|
||||||
|
result.append(Q(**{field_lookup: acl_filter}))
|
||||||
|
|
||||||
|
# Case 4: Original model, has an inherited related field
|
||||||
try:
|
try:
|
||||||
return self.check_access(
|
related_fields = (
|
||||||
obj=return_related(
|
ModelPermission.get_inheritance(
|
||||||
instance=obj, related_field=parent_accessor
|
model=queryset.model
|
||||||
), permissions=permissions, user=user
|
),
|
||||||
)
|
)
|
||||||
except PermissionDenied:
|
except KeyError:
|
||||||
pass
|
|
||||||
except PermissionDenied:
|
|
||||||
pass
|
pass
|
||||||
|
else:
|
||||||
|
relation_result = []
|
||||||
|
|
||||||
user_roles = []
|
for related_field_name in related_fields:
|
||||||
for group in user.groups.all():
|
inherited_acl_queries = self._get_acl_filters(
|
||||||
for role in group.roles.all():
|
queryset=queryset, stored_permission=stored_permission,
|
||||||
if set(stored_permissions).intersection(set(self.get_inherited_permissions(role=role, obj=obj))):
|
related_field_name=related_field_name, user=user
|
||||||
logger.debug(
|
|
||||||
'Permissions "%s" on "%s" granted to user "%s" through role "%s" via inherited ACL',
|
|
||||||
permissions, obj, user, role
|
|
||||||
)
|
)
|
||||||
return True
|
if inherited_acl_queries:
|
||||||
|
relation_result.append(reduce(operator.and_, inherited_acl_queries))
|
||||||
|
|
||||||
user_roles.append(role)
|
if relation_result:
|
||||||
|
result.append(reduce(operator.or_, relation_result))
|
||||||
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():
|
|
||||||
logger.debug(
|
|
||||||
'Permissions "%s" on "%s" denied for user "%s"',
|
|
||||||
permissions, obj, user
|
|
||||||
)
|
|
||||||
raise PermissionDenied(
|
|
||||||
ugettext('Insufficient access for: %s') % force_text(obj)
|
|
||||||
)
|
|
||||||
|
|
||||||
logger.debug(
|
|
||||||
'Permissions "%s" on "%s" granted to user "%s" through roles "%s" by direct ACL',
|
|
||||||
permissions, obj, user, user_roles
|
|
||||||
)
|
|
||||||
|
|
||||||
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
|
|
||||||
)
|
|
||||||
return queryset
|
|
||||||
|
|
||||||
|
# Case 7: Has a function
|
||||||
try:
|
try:
|
||||||
Permission.check_permissions(
|
field_query_function = ModelPermission.get_function(
|
||||||
permissions=(permission,), user=user
|
|
||||||
)
|
|
||||||
except PermissionDenied:
|
|
||||||
user_roles = []
|
|
||||||
for group in user.groups.all():
|
|
||||||
for role in group.roles.all():
|
|
||||||
user_roles.append(role)
|
|
||||||
|
|
||||||
try:
|
|
||||||
parent_accessor = ModelPermission.get_inheritance(
|
|
||||||
model=queryset.model
|
model=queryset.model
|
||||||
)
|
)
|
||||||
except KeyError:
|
except KeyError:
|
||||||
parent_acl_query = Q()
|
|
||||||
else:
|
|
||||||
instance = queryset.first()
|
|
||||||
if instance:
|
|
||||||
parent_object = return_related(
|
|
||||||
instance=instance, related_field=parent_accessor
|
|
||||||
)
|
|
||||||
|
|
||||||
try:
|
|
||||||
# Try to see if parent_object is a function
|
|
||||||
parent_object()
|
|
||||||
except TypeError:
|
|
||||||
# Is not a function, try it as a field
|
|
||||||
parent_content_type = ContentType.objects.get_for_model(
|
|
||||||
parent_object
|
|
||||||
)
|
|
||||||
parent_queryset = self.filter(
|
|
||||||
content_type=parent_content_type, role__in=user_roles,
|
|
||||||
permissions=permission.stored_permission
|
|
||||||
)
|
|
||||||
parent_acl_query = Q(
|
|
||||||
**{
|
|
||||||
'{}__pk__in'.format(
|
|
||||||
parent_accessor
|
|
||||||
): parent_queryset.values_list(
|
|
||||||
'object_id', flat=True
|
|
||||||
)
|
|
||||||
}
|
|
||||||
)
|
|
||||||
else:
|
|
||||||
# Is a function. Can't perform Q object filtering.
|
|
||||||
# Perform iterative filtering.
|
|
||||||
result = []
|
|
||||||
for entry in queryset:
|
|
||||||
try:
|
|
||||||
self.check_access(permissions=permission, user=user, obj=entry)
|
|
||||||
except PermissionDenied:
|
|
||||||
pass
|
pass
|
||||||
else:
|
else:
|
||||||
result.append(entry.pk)
|
function_results = field_query_function()
|
||||||
|
|
||||||
return queryset.filter(pk__in=result)
|
# Filter by the model's content type
|
||||||
else:
|
content_type = ContentType.objects.get_for_model(
|
||||||
parent_acl_query = Q()
|
model=queryset.model
|
||||||
|
)
|
||||||
|
acl_filter = self.filter(
|
||||||
|
content_type=content_type, permissions=stored_permission,
|
||||||
|
role__groups__user=user
|
||||||
|
).values('object_id')
|
||||||
|
# Obtain an queryset of filtered, authorized model instances
|
||||||
|
acl_queryset = queryset.model._meta.default_manager.filter(
|
||||||
|
id__in=acl_filter
|
||||||
|
).filter(**function_results['acl_filter'])
|
||||||
|
|
||||||
# Directly granted access
|
if 'acl_values' in function_results:
|
||||||
content_type = ContentType.objects.get_for_model(queryset.model)
|
acl_queryset = acl_queryset.values(
|
||||||
acl_query = Q(pk__in=self.filter(
|
*function_results['acl_values']
|
||||||
content_type=content_type, role__in=user_roles,
|
|
||||||
permissions=permission.stored_permission
|
|
||||||
).values_list('object_id', flat=True))
|
|
||||||
logger.debug(
|
|
||||||
'Filtered queryset returned to user "%s" based on roles "%s"',
|
|
||||||
user, user_roles
|
|
||||||
)
|
)
|
||||||
|
|
||||||
return queryset.filter(parent_acl_query | acl_query)
|
# Get the final query using the filtered queryset as the
|
||||||
|
# reference
|
||||||
|
result.append(
|
||||||
|
Q(**{function_results['field_lookup']: acl_queryset})
|
||||||
|
)
|
||||||
|
|
||||||
|
return result
|
||||||
|
|
||||||
|
def check_access(self, obj, permissions, user, related=None):
|
||||||
|
"""
|
||||||
|
The `related` argument is ignored.
|
||||||
|
"""
|
||||||
|
if related:
|
||||||
|
warnings.warn(
|
||||||
|
'Passing the argument `related` to check_access() is '
|
||||||
|
'deprecated. Use the ModelPermission\'s class '
|
||||||
|
'.register_inheritance() class method to register the access '
|
||||||
|
'relationship between two models. The registered relationship '
|
||||||
|
'will be automatically used by check_access().',
|
||||||
|
InterfaceWarning
|
||||||
|
)
|
||||||
|
|
||||||
|
meta = getattr(obj, '_meta', None)
|
||||||
|
|
||||||
|
if not meta:
|
||||||
|
logger.debug(
|
||||||
|
ugettext(
|
||||||
|
'Object "%s" is not a model and cannot be checked for '
|
||||||
|
'access.'
|
||||||
|
) % force_text(obj)
|
||||||
|
)
|
||||||
|
return True
|
||||||
else:
|
else:
|
||||||
|
source_queryset = obj._meta.default_manager.all()
|
||||||
|
|
||||||
|
restricted_queryset = obj._meta.default_manager.none()
|
||||||
|
for permission in permissions:
|
||||||
|
# Default relationship betweens permissions is OR
|
||||||
|
# TODO: Add support for AND relationship
|
||||||
|
restricted_queryset = restricted_queryset | self.restrict_queryset(
|
||||||
|
permission=permission, queryset=source_queryset, user=user
|
||||||
|
)
|
||||||
|
|
||||||
|
if restricted_queryset.filter(pk=obj.pk).exists():
|
||||||
|
return True
|
||||||
|
else:
|
||||||
|
raise PermissionDenied(
|
||||||
|
ugettext(message='Insufficient access for: %s') % force_text(
|
||||||
|
s=obj
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
def filter_by_access(self, permission, user, queryset):
|
||||||
|
return self.restrict_queryset(
|
||||||
|
permission=permission, queryset=queryset, user=user
|
||||||
|
)
|
||||||
|
|
||||||
|
def restrict_queryset(self, permission, queryset, user):
|
||||||
|
# Check directly granted permission via a role
|
||||||
|
try:
|
||||||
|
Permission.check_user_permissions(
|
||||||
|
permissions=(permission,), user=user
|
||||||
|
)
|
||||||
|
except PermissionDenied:
|
||||||
|
acl_filters = self._get_acl_filters(
|
||||||
|
queryset=queryset,
|
||||||
|
stored_permission=permission.stored_permission, user=user
|
||||||
|
)
|
||||||
|
|
||||||
|
final_query = None
|
||||||
|
for acl_filter in acl_filters:
|
||||||
|
if final_query is None:
|
||||||
|
final_query = acl_filter
|
||||||
|
else:
|
||||||
|
final_query = final_query | acl_filter
|
||||||
|
|
||||||
|
return queryset.filter(final_query)
|
||||||
|
else:
|
||||||
|
# User has direct permission assignment via a role, is superuser or
|
||||||
|
# is staff. Return the entire queryset.
|
||||||
return queryset
|
return queryset
|
||||||
|
|
||||||
def get_inherited_permissions(self, obj, role):
|
def get_inherited_permissions(self, obj, role):
|
||||||
|
|||||||
@@ -44,7 +44,7 @@ class ACLCreateView(SingleObjectCreateView):
|
|||||||
raise Http404
|
raise Http404
|
||||||
|
|
||||||
AccessControlList.objects.check_access(
|
AccessControlList.objects.check_access(
|
||||||
obj=self.content_object, permissions=permission_acl_edit,
|
obj=self.content_object, permissions=(permission_acl_edit,),
|
||||||
user=request.user
|
user=request.user
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -86,7 +86,7 @@ class ACLDeleteView(SingleObjectDeleteView):
|
|||||||
acl = get_object_or_404(klass=AccessControlList, pk=self.kwargs['pk'])
|
acl = get_object_or_404(klass=AccessControlList, pk=self.kwargs['pk'])
|
||||||
|
|
||||||
AccessControlList.objects.check_access(
|
AccessControlList.objects.check_access(
|
||||||
obj=acl.content_object, permissions=permission_acl_edit,
|
obj=acl.content_object, permissions=(permission_acl_edit,),
|
||||||
user=request.user
|
user=request.user
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -126,7 +126,7 @@ class ACLListView(SingleObjectListView):
|
|||||||
raise Http404
|
raise Http404
|
||||||
|
|
||||||
AccessControlList.objects.check_access(
|
AccessControlList.objects.check_access(
|
||||||
obj=self.content_object, permissions=permission_acl_view,
|
obj=self.content_object, permissions=(permission_acl_view,),
|
||||||
user=request.user
|
user=request.user
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
@@ -89,7 +89,7 @@ class GrantAccessAction(WorkflowAction):
|
|||||||
|
|
||||||
try:
|
try:
|
||||||
AccessControlList.objects.check_access(
|
AccessControlList.objects.check_access(
|
||||||
permissions=permission_acl_edit, user=request.user, obj=obj
|
obj=obj, permissions=(permission_acl_edit,), user=request.user
|
||||||
)
|
)
|
||||||
except Exception as exception:
|
except Exception as exception:
|
||||||
raise ValidationError(exception)
|
raise ValidationError(exception)
|
||||||
|
|||||||
@@ -35,8 +35,8 @@ class APIDocumentCabinetListView(generics.ListAPIView):
|
|||||||
def get_queryset(self):
|
def get_queryset(self):
|
||||||
document = get_object_or_404(klass=Document, pk=self.kwargs['pk'])
|
document = get_object_or_404(klass=Document, pk=self.kwargs['pk'])
|
||||||
AccessControlList.objects.check_access(
|
AccessControlList.objects.check_access(
|
||||||
permissions=permission_document_view, user=self.request.user,
|
obj=document, permissions=(permission_document_view,),
|
||||||
obj=document
|
user=self.request.user
|
||||||
)
|
)
|
||||||
|
|
||||||
queryset = document.get_cabinets()
|
queryset = document.get_cabinets()
|
||||||
@@ -189,8 +189,8 @@ class APICabinetDocumentView(generics.RetrieveDestroyAPIView):
|
|||||||
instance = self.get_object()
|
instance = self.get_object()
|
||||||
|
|
||||||
AccessControlList.objects.check_access(
|
AccessControlList.objects.check_access(
|
||||||
permissions=permission_document_view, user=self.request.user,
|
obj=instance, permissions=(permission_document_view,),
|
||||||
obj=instance
|
user=self.request.user
|
||||||
)
|
)
|
||||||
|
|
||||||
serializer = self.get_serializer(instance)
|
serializer = self.get_serializer(instance)
|
||||||
|
|||||||
@@ -73,8 +73,16 @@ class CabinetsApp(MayanAppConfig):
|
|||||||
permission_cabinet_remove_document
|
permission_cabinet_remove_document
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
ModelPermission.register_inheritance(
|
|
||||||
model=Cabinet, related='get_root',
|
def get_root_filter():
|
||||||
|
return {
|
||||||
|
'acl_filter': {'level': 0},
|
||||||
|
'acl_values': ('tree_id',),
|
||||||
|
'field_lookup': 'tree_id__in'
|
||||||
|
}
|
||||||
|
|
||||||
|
ModelPermission.register_function(
|
||||||
|
model=Cabinet, function=get_root_filter
|
||||||
)
|
)
|
||||||
|
|
||||||
SourceColumn(
|
SourceColumn(
|
||||||
|
|||||||
@@ -63,7 +63,7 @@ class CabinetChildAddView(SingleObjectCreateView):
|
|||||||
cabinet = super(CabinetChildAddView, self).get_object(*args, **kwargs)
|
cabinet = super(CabinetChildAddView, self).get_object(*args, **kwargs)
|
||||||
|
|
||||||
AccessControlList.objects.check_access(
|
AccessControlList.objects.check_access(
|
||||||
obj=cabinet.get_root(), permissions=permission_cabinet_edit,
|
obj=cabinet.get_root(), permissions=(permission_cabinet_edit,),
|
||||||
user=self.request.user
|
user=self.request.user
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -142,7 +142,7 @@ class CabinetDetailView(DocumentListView):
|
|||||||
permission_object = cabinet.get_root()
|
permission_object = cabinet.get_root()
|
||||||
|
|
||||||
AccessControlList.objects.check_access(
|
AccessControlList.objects.check_access(
|
||||||
obj=permission_object, permissions=permission_cabinet_view,
|
obj=permission_object, permissions=(permission_cabinet_view,),
|
||||||
user=self.request.user
|
user=self.request.user
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -193,7 +193,7 @@ class DocumentCabinetListView(CabinetListView):
|
|||||||
self.document = get_object_or_404(klass=Document, pk=self.kwargs['pk'])
|
self.document = get_object_or_404(klass=Document, pk=self.kwargs['pk'])
|
||||||
|
|
||||||
AccessControlList.objects.check_access(
|
AccessControlList.objects.check_access(
|
||||||
obj=self.document, permissions=permission_document_view,
|
obj=self.document, permissions=(permission_document_view,),
|
||||||
user=request.user
|
user=request.user
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -288,7 +288,7 @@ class DocumentAddToCabinetView(MultipleObjectFormActionView):
|
|||||||
|
|
||||||
for cabinet in form.cleaned_data['cabinets']:
|
for cabinet in form.cleaned_data['cabinets']:
|
||||||
AccessControlList.objects.check_access(
|
AccessControlList.objects.check_access(
|
||||||
obj=cabinet, permissions=permission_cabinet_add_document,
|
obj=cabinet, permissions=(permission_cabinet_add_document,),
|
||||||
user=self.request.user
|
user=self.request.user
|
||||||
)
|
)
|
||||||
if cabinet in cabinet_membership:
|
if cabinet in cabinet_membership:
|
||||||
@@ -376,7 +376,7 @@ class DocumentRemoveFromCabinetView(MultipleObjectFormActionView):
|
|||||||
|
|
||||||
for cabinet in form.cleaned_data['cabinets']:
|
for cabinet in form.cleaned_data['cabinets']:
|
||||||
AccessControlList.objects.check_access(
|
AccessControlList.objects.check_access(
|
||||||
obj=cabinet, permissions=permission_cabinet_remove_document,
|
obj=cabinet, permissions=(permission_cabinet_remove_document,),
|
||||||
user=self.request.user
|
user=self.request.user
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
@@ -79,12 +79,13 @@ class APICheckedoutDocumentView(generics.RetrieveDestroyAPIView):
|
|||||||
|
|
||||||
if document.checkout_info().user == request.user:
|
if document.checkout_info().user == request.user:
|
||||||
AccessControlList.objects.check_access(
|
AccessControlList.objects.check_access(
|
||||||
obj=document, permissions=permission_document_check_in,
|
obj=document, permissions=(permission_document_check_in,),
|
||||||
user=request.user
|
user=request.user
|
||||||
)
|
)
|
||||||
else:
|
else:
|
||||||
AccessControlList.objects.check_access(
|
AccessControlList.objects.check_access(
|
||||||
obj=document, permissions=permission_document_check_in_override,
|
obj=document,
|
||||||
|
permissions=(permission_document_check_in_override,),
|
||||||
user=request.user
|
user=request.user
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
@@ -42,7 +42,7 @@ class NewDocumentCheckoutSerializer(serializers.ModelSerializer):
|
|||||||
document = Document.objects.get(pk=validated_data.pop('document_pk'))
|
document = Document.objects.get(pk=validated_data.pop('document_pk'))
|
||||||
|
|
||||||
AccessControlList.objects.check_access(
|
AccessControlList.objects.check_access(
|
||||||
obj=document, permissions=permission_document_check_out,
|
obj=document, permissions=(permission_document_check_out,),
|
||||||
user=self.context['request'].user
|
user=self.context['request'].user
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
@@ -31,7 +31,7 @@ class CheckoutDocumentView(SingleObjectCreateView):
|
|||||||
self.document = get_object_or_404(klass=Document, pk=self.kwargs['pk'])
|
self.document = get_object_or_404(klass=Document, pk=self.kwargs['pk'])
|
||||||
|
|
||||||
AccessControlList.objects.check_access(
|
AccessControlList.objects.check_access(
|
||||||
obj=self.document, permissions=permission_document_check_out,
|
obj=self.document, permissions=(permission_document_check_out,),
|
||||||
user=request.user
|
user=request.user
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -168,13 +168,13 @@ class DocumentCheckinView(ConfirmView):
|
|||||||
|
|
||||||
if document.get_check_out_info().user == self.request.user:
|
if document.get_check_out_info().user == self.request.user:
|
||||||
AccessControlList.objects.check_access(
|
AccessControlList.objects.check_access(
|
||||||
obj=document, permissions=permission_document_check_in,
|
obj=document, permissions=(permission_document_check_in,),
|
||||||
user=self.request.user
|
user=self.request.user
|
||||||
)
|
)
|
||||||
else:
|
else:
|
||||||
AccessControlList.objects.check_access(
|
AccessControlList.objects.check_access(
|
||||||
obj=document,
|
obj=document,
|
||||||
permissions=permission_document_check_in_override,
|
permissions=(permission_document_check_in_override,),
|
||||||
user=self.request.user
|
user=self.request.user
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
@@ -286,8 +286,8 @@ class ObjectListPermissionFilterMixin(object):
|
|||||||
def dispatch(self, request, *args, **kwargs):
|
def dispatch(self, request, *args, **kwargs):
|
||||||
if self.access_object_retrieve_method and self.object_permission:
|
if self.access_object_retrieve_method and self.object_permission:
|
||||||
AccessControlList.objects.check_access(
|
AccessControlList.objects.check_access(
|
||||||
permissions=(self.object_permission,), user=request.user,
|
obj=getattr(self, self.access_object_retrieve_method)(),
|
||||||
obj=getattr(self, self.access_object_retrieve_method)()
|
permissions=(self.object_permission,), user=request.user
|
||||||
)
|
)
|
||||||
return super(ObjectListPermissionFilterMixin, self).dispatch(request, *args, **kwargs)
|
return super(ObjectListPermissionFilterMixin, self).dispatch(request, *args, **kwargs)
|
||||||
|
|
||||||
@@ -296,7 +296,8 @@ class ObjectListPermissionFilterMixin(object):
|
|||||||
|
|
||||||
if not self.access_object_retrieve_method and self.object_permission:
|
if not self.access_object_retrieve_method and self.object_permission:
|
||||||
return AccessControlList.objects.filter_by_access(
|
return AccessControlList.objects.filter_by_access(
|
||||||
self.object_permission, self.request.user, queryset=queryset
|
queryset=queryset, permission=self.object_permission,
|
||||||
|
user=self.request.user
|
||||||
)
|
)
|
||||||
else:
|
else:
|
||||||
return queryset
|
return queryset
|
||||||
@@ -327,9 +328,10 @@ class ObjectPermissionCheckMixin(object):
|
|||||||
def dispatch(self, request, *args, **kwargs):
|
def dispatch(self, request, *args, **kwargs):
|
||||||
if self.object_permission:
|
if self.object_permission:
|
||||||
AccessControlList.objects.check_access(
|
AccessControlList.objects.check_access(
|
||||||
permissions=self.object_permission, user=request.user,
|
|
||||||
obj=self.get_permission_object(),
|
obj=self.get_permission_object(),
|
||||||
related=getattr(self, 'object_permission_related', None)
|
permissions=(self.object_permission,),
|
||||||
|
related=getattr(self, 'object_permission_related', None),
|
||||||
|
user=request.user
|
||||||
)
|
)
|
||||||
|
|
||||||
return super(
|
return super(
|
||||||
@@ -427,7 +429,7 @@ class ViewPermissionCheckMixin(object):
|
|||||||
|
|
||||||
def dispatch(self, request, *args, **kwargs):
|
def dispatch(self, request, *args, **kwargs):
|
||||||
if self.view_permission:
|
if self.view_permission:
|
||||||
Permission.check_permissions(
|
Permission.check_user_permissions(
|
||||||
permissions=(self.view_permission,), user=self.request.user
|
permissions=(self.view_permission,), user=self.request.user
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
@@ -33,6 +33,26 @@ def encapsulate(function):
|
|||||||
return lambda: function
|
return lambda: function
|
||||||
|
|
||||||
|
|
||||||
|
def get_related_field(model, related_field_name):
|
||||||
|
try:
|
||||||
|
local_field_name, remaining_field_path = related_field_name.split(
|
||||||
|
LOOKUP_SEP, 1
|
||||||
|
)
|
||||||
|
except ValueError:
|
||||||
|
local_field_name = related_field_name
|
||||||
|
remaining_field_path = None
|
||||||
|
|
||||||
|
related_field = model._meta.get_field(local_field_name)
|
||||||
|
|
||||||
|
if remaining_field_path:
|
||||||
|
return get_related_field(
|
||||||
|
model=related_field.related_model,
|
||||||
|
related_field_name=remaining_field_path
|
||||||
|
)
|
||||||
|
|
||||||
|
return related_field
|
||||||
|
|
||||||
|
|
||||||
def introspect_attribute(attribute_name, obj):
|
def introspect_attribute(attribute_name, obj):
|
||||||
"""
|
"""
|
||||||
Resolve the attribute of model. Supports nested reference using dotted
|
Resolve the attribute of model. Supports nested reference using dotted
|
||||||
|
|||||||
@@ -145,7 +145,7 @@ class ObjectErrorLogEntryListClearView(ConfirmView):
|
|||||||
class ObjectErrorLogEntryListView(SingleObjectListView):
|
class ObjectErrorLogEntryListView(SingleObjectListView):
|
||||||
def dispatch(self, request, *args, **kwargs):
|
def dispatch(self, request, *args, **kwargs):
|
||||||
AccessControlList.objects.check_access(
|
AccessControlList.objects.check_access(
|
||||||
obj=self.get_object(), permissions=permission_error_log_view,
|
obj=self.get_object(), permissions=(permission_error_log_view,),
|
||||||
user=request.user
|
user=request.user
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
@@ -5,3 +5,9 @@ class DatabaseWarning(UserWarning):
|
|||||||
"""
|
"""
|
||||||
Warning when using unsupported database backends
|
Warning when using unsupported database backends
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
||||||
|
class InterfaceWarning(UserWarning):
|
||||||
|
"""
|
||||||
|
Warning when using obsolete internal interfaces
|
||||||
|
"""
|
||||||
|
|||||||
@@ -45,7 +45,7 @@ class TransformationCreateView(SingleObjectCreateView):
|
|||||||
|
|
||||||
AccessControlList.objects.check_access(
|
AccessControlList.objects.check_access(
|
||||||
obj=self.content_object,
|
obj=self.content_object,
|
||||||
permissions=permission_transformation_create, user=request.user
|
permissions=(permission_transformation_create,), user=request.user
|
||||||
)
|
)
|
||||||
|
|
||||||
return super(TransformationCreateView, self).dispatch(
|
return super(TransformationCreateView, self).dispatch(
|
||||||
@@ -96,7 +96,7 @@ class TransformationDeleteView(SingleObjectDeleteView):
|
|||||||
|
|
||||||
AccessControlList.objects.check_access(
|
AccessControlList.objects.check_access(
|
||||||
obj=self.transformation.content_object,
|
obj=self.transformation.content_object,
|
||||||
permissions=permission_transformation_delete, user=request.user
|
permissions=(permission_transformation_delete,), user=request.user
|
||||||
)
|
)
|
||||||
|
|
||||||
return super(TransformationDeleteView, self).dispatch(
|
return super(TransformationDeleteView, self).dispatch(
|
||||||
@@ -145,7 +145,7 @@ class TransformationEditView(SingleObjectEditView):
|
|||||||
|
|
||||||
AccessControlList.objects.check_access(
|
AccessControlList.objects.check_access(
|
||||||
obj=self.transformation.content_object,
|
obj=self.transformation.content_object,
|
||||||
permissions=permission_transformation_edit, user=request.user
|
permissions=(permission_transformation_edit,), user=request.user
|
||||||
)
|
)
|
||||||
|
|
||||||
return super(TransformationEditView, self).dispatch(
|
return super(TransformationEditView, self).dispatch(
|
||||||
@@ -202,7 +202,7 @@ class TransformationListView(SingleObjectListView):
|
|||||||
|
|
||||||
AccessControlList.objects.check_access(
|
AccessControlList.objects.check_access(
|
||||||
obj=self.content_object,
|
obj=self.content_object,
|
||||||
permissions=permission_transformation_view, user=request.user
|
permissions=(permission_transformation_view,), user=request.user
|
||||||
)
|
)
|
||||||
|
|
||||||
return super(TransformationListView, self).dispatch(
|
return super(TransformationListView, self).dispatch(
|
||||||
|
|||||||
@@ -30,7 +30,7 @@ class APICommentListView(generics.ListCreateAPIView):
|
|||||||
)
|
)
|
||||||
|
|
||||||
AccessControlList.objects.check_access(
|
AccessControlList.objects.check_access(
|
||||||
obj=document, permissions=permission_required,
|
obj=document, permissions=(permission_required,),
|
||||||
user=self.request.user
|
user=self.request.user
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -85,7 +85,7 @@ class APICommentView(generics.RetrieveDestroyAPIView):
|
|||||||
)
|
)
|
||||||
|
|
||||||
AccessControlList.objects.check_access(
|
AccessControlList.objects.check_access(
|
||||||
obj=document, permissions=permission_required,
|
obj=document, permissions=(permission_required,),
|
||||||
user=self.request.user
|
user=self.request.user
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
@@ -26,7 +26,7 @@ class DocumentCommentCreateView(SingleObjectCreateView):
|
|||||||
|
|
||||||
def dispatch(self, request, *args, **kwargs):
|
def dispatch(self, request, *args, **kwargs):
|
||||||
AccessControlList.objects.check_access(
|
AccessControlList.objects.check_access(
|
||||||
obj=self.get_document(), permissions=permission_comment_create,
|
obj=self.get_document(), permissions=(permission_comment_create,),
|
||||||
user=request.user
|
user=request.user
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -67,7 +67,7 @@ class DocumentCommentDeleteView(SingleObjectDeleteView):
|
|||||||
def dispatch(self, request, *args, **kwargs):
|
def dispatch(self, request, *args, **kwargs):
|
||||||
AccessControlList.objects.check_access(
|
AccessControlList.objects.check_access(
|
||||||
obj=self.get_object().document,
|
obj=self.get_object().document,
|
||||||
permissions=permission_comment_delete, user=request.user
|
permissions=(permission_comment_delete,), user=request.user
|
||||||
)
|
)
|
||||||
|
|
||||||
return super(
|
return super(
|
||||||
@@ -120,7 +120,7 @@ class DocumentCommentListView(SingleObjectListView):
|
|||||||
|
|
||||||
def get_object_list(self):
|
def get_object_list(self):
|
||||||
AccessControlList.objects.check_access(
|
AccessControlList.objects.check_access(
|
||||||
obj=self.get_document(), permissions=permission_comment_view,
|
obj=self.get_document(), permissions=(permission_comment_view,),
|
||||||
user=self.request.user
|
user=self.request.user
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
@@ -67,7 +67,7 @@ class APIIndexNodeInstanceDocumentListView(generics.ListAPIView):
|
|||||||
)
|
)
|
||||||
AccessControlList.objects.check_access(
|
AccessControlList.objects.check_access(
|
||||||
obj=index_node_instance.index,
|
obj=index_node_instance.index,
|
||||||
permissions=permission_document_indexing_view,
|
permissions=(permission_document_indexing_view,),
|
||||||
user=self.request.user
|
user=self.request.user
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -113,7 +113,7 @@ class APIDocumentIndexListView(generics.ListAPIView):
|
|||||||
def get_queryset(self):
|
def get_queryset(self):
|
||||||
document = get_object_or_404(klass=Document, pk=self.kwargs['pk'])
|
document = get_object_or_404(klass=Document, pk=self.kwargs['pk'])
|
||||||
AccessControlList.objects.check_access(
|
AccessControlList.objects.check_access(
|
||||||
obj=document, permissions=permission_document_view,
|
obj=document, permissions=(permission_document_view,),
|
||||||
user=self.request.user
|
user=self.request.user
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
@@ -204,7 +204,7 @@ class TemplateNodeCreateView(SingleObjectCreateView):
|
|||||||
def dispatch(self, request, *args, **kwargs):
|
def dispatch(self, request, *args, **kwargs):
|
||||||
AccessControlList.objects.check_access(
|
AccessControlList.objects.check_access(
|
||||||
obj=self.get_parent_node().index,
|
obj=self.get_parent_node().index,
|
||||||
permissions=permission_document_indexing_edit, user=request.user
|
permissions=(permission_document_indexing_edit,), user=request.user
|
||||||
)
|
)
|
||||||
|
|
||||||
return super(
|
return super(
|
||||||
@@ -311,7 +311,7 @@ class IndexInstanceNodeView(DocumentListView):
|
|||||||
|
|
||||||
AccessControlList.objects.check_access(
|
AccessControlList.objects.check_access(
|
||||||
obj=self.index_instance_node.index(),
|
obj=self.index_instance_node.index(),
|
||||||
permissions=permission_document_indexing_instance_view,
|
permissions=(permission_document_indexing_instance_view,),
|
||||||
user=request.user
|
user=request.user
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -378,7 +378,7 @@ class DocumentIndexNodeListView(SingleObjectListView):
|
|||||||
|
|
||||||
def dispatch(self, request, *args, **kwargs):
|
def dispatch(self, request, *args, **kwargs):
|
||||||
AccessControlList.objects.check_access(
|
AccessControlList.objects.check_access(
|
||||||
obj=self.get_document(), permissions=permission_document_view,
|
obj=self.get_document(), permissions=(permission_document_view,),
|
||||||
user=request.user
|
user=request.user
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
@@ -65,6 +65,7 @@ class DocumentSignaturesApp(MayanAppConfig):
|
|||||||
app_label='django_gpg', model_name='Key'
|
app_label='django_gpg', model_name='Key'
|
||||||
)
|
)
|
||||||
|
|
||||||
|
DetachedSignature = self.get_model(model_name='DetachedSignature')
|
||||||
EmbeddedSignature = self.get_model(model_name='EmbeddedSignature')
|
EmbeddedSignature = self.get_model(model_name='EmbeddedSignature')
|
||||||
|
|
||||||
SignatureBaseModel = self.get_model(model_name='SignatureBaseModel')
|
SignatureBaseModel = self.get_model(model_name='SignatureBaseModel')
|
||||||
@@ -86,6 +87,12 @@ class DocumentSignaturesApp(MayanAppConfig):
|
|||||||
permission_document_version_signature_upload,
|
permission_document_version_signature_upload,
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
ModelPermission.register_inheritance(
|
||||||
|
model=SignatureBaseModel, related='document_version'
|
||||||
|
)
|
||||||
|
ModelPermission.register_inheritance(
|
||||||
|
model=DetachedSignature, related='document_version'
|
||||||
|
)
|
||||||
|
|
||||||
SourceColumn(
|
SourceColumn(
|
||||||
source=SignatureBaseModel, label=_('Date'), attribute='date'
|
source=SignatureBaseModel, label=_('Date'), attribute='date'
|
||||||
|
|||||||
@@ -42,47 +42,44 @@ link_document_version_signature_delete = Link(
|
|||||||
args='resolved_object.pk', condition=is_detached_signature,
|
args='resolved_object.pk', condition=is_detached_signature,
|
||||||
icon_class_path='mayan.apps.document_signatures.icons.icon_document_version_signature_delete',
|
icon_class_path='mayan.apps.document_signatures.icons.icon_document_version_signature_delete',
|
||||||
permissions=(permission_document_version_signature_delete,),
|
permissions=(permission_document_version_signature_delete,),
|
||||||
permissions_related='document_version.document', tags='dangerous',
|
tags='dangerous', text=_('Delete'),
|
||||||
text=_('Delete'), view='signatures:document_version_signature_delete',
|
view='signatures:document_version_signature_delete',
|
||||||
)
|
)
|
||||||
link_document_version_signature_details = Link(
|
link_document_version_signature_details = Link(
|
||||||
args='resolved_object.pk',
|
args='resolved_object.pk',
|
||||||
icon_class_path='mayan.apps.document_signatures.icons.icon_document_version_signature_details',
|
icon_class_path='mayan.apps.document_signatures.icons.icon_document_version_signature_details',
|
||||||
permissions=(permission_document_version_signature_view,),
|
permissions=(permission_document_version_signature_view,),
|
||||||
permissions_related='document_version.document', text=_('Details'),
|
text=_('Details'), view='signatures:document_version_signature_details',
|
||||||
view='signatures:document_version_signature_details',
|
|
||||||
)
|
)
|
||||||
link_document_version_signature_list = Link(
|
link_document_version_signature_list = Link(
|
||||||
args='resolved_object.pk',
|
args='resolved_object.pk',
|
||||||
icon_class_path='mayan.apps.document_signatures.icons.icon_document_version_signature_list',
|
icon_class_path='mayan.apps.document_signatures.icons.icon_document_version_signature_list',
|
||||||
permissions=(permission_document_version_signature_view,),
|
permissions=(permission_document_version_signature_view,),
|
||||||
permissions_related='document', text=_('Signatures'),
|
text=_('Signatures'), view='signatures:document_version_signature_list'
|
||||||
view='signatures:document_version_signature_list',
|
|
||||||
)
|
)
|
||||||
link_document_version_signature_download = Link(
|
link_document_version_signature_download = Link(
|
||||||
args='resolved_object.pk', condition=is_detached_signature,
|
args='resolved_object.pk', condition=is_detached_signature,
|
||||||
permissions=(permission_document_version_signature_download,),
|
permissions=(permission_document_version_signature_download,),
|
||||||
permissions_related='document_version.document', text=_('Download'),
|
text=_('Download'), view='signatures:document_version_signature_download'
|
||||||
view='signatures:document_version_signature_download',
|
|
||||||
)
|
)
|
||||||
link_document_version_signature_upload = Link(
|
link_document_version_signature_upload = Link(
|
||||||
args='resolved_object.pk',
|
args='resolved_object.pk',
|
||||||
icon_class_path='mayan.apps.document_signatures.icons.icon_document_version_signature_upload',
|
icon_class_path='mayan.apps.document_signatures.icons.icon_document_version_signature_upload',
|
||||||
permissions=(permission_document_version_signature_upload,),
|
permissions=(permission_document_version_signature_upload,),
|
||||||
permissions_related='document', text=_('Upload signature'),
|
text=_('Upload signature'),
|
||||||
view='signatures:document_version_signature_upload',
|
view='signatures:document_version_signature_upload'
|
||||||
)
|
)
|
||||||
link_document_version_signature_detached_create = Link(
|
link_document_version_signature_detached_create = Link(
|
||||||
args='resolved_object.pk',
|
args='resolved_object.pk',
|
||||||
icon_class_path='mayan.apps.document_signatures.icons.icon_document_version_signature_detached_create',
|
icon_class_path='mayan.apps.document_signatures.icons.icon_document_version_signature_detached_create',
|
||||||
permissions=(permission_document_version_sign_detached,),
|
permissions=(permission_document_version_sign_detached,),
|
||||||
permissions_related='document', text=_('Sign detached'),
|
text=_('Sign detached'),
|
||||||
view='signatures:document_version_signature_detached_create',
|
view='signatures:document_version_signature_detached_create'
|
||||||
)
|
)
|
||||||
link_document_version_signature_embedded_create = Link(
|
link_document_version_signature_embedded_create = Link(
|
||||||
args='resolved_object.pk',
|
args='resolved_object.pk',
|
||||||
icon_class_path='mayan.apps.document_signatures.icons.icon_document_version_signature_embedded_create',
|
icon_class_path='mayan.apps.document_signatures.icons.icon_document_version_signature_embedded_create',
|
||||||
permissions=(permission_document_version_sign_embedded,),
|
permissions=(permission_document_version_sign_embedded,),
|
||||||
permissions_related='document', text=_('Sign embedded'),
|
text=_('Sign embedded'),
|
||||||
view='signatures:document_version_signature_embedded_create',
|
view='signatures:document_version_signature_embedded_create'
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -54,7 +54,7 @@ class DocumentVersionDetachedSignatureCreateView(FormView):
|
|||||||
passphrase = form.cleaned_data['passphrase'] or None
|
passphrase = form.cleaned_data['passphrase'] or None
|
||||||
|
|
||||||
AccessControlList.objects.check_access(
|
AccessControlList.objects.check_access(
|
||||||
obj=key, permissions=permission_key_sign, user=self.request.user
|
obj=key, permissions=(permission_key_sign,), user=self.request.user
|
||||||
)
|
)
|
||||||
|
|
||||||
try:
|
try:
|
||||||
@@ -109,7 +109,7 @@ class DocumentVersionDetachedSignatureCreateView(FormView):
|
|||||||
def dispatch(self, request, *args, **kwargs):
|
def dispatch(self, request, *args, **kwargs):
|
||||||
AccessControlList.objects.check_access(
|
AccessControlList.objects.check_access(
|
||||||
obj=self.get_document_version().document,
|
obj=self.get_document_version().document,
|
||||||
permissions=permission_document_version_sign_detached,
|
permissions=(permission_document_version_sign_detached,),
|
||||||
user=request.user
|
user=request.user
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -146,7 +146,7 @@ class DocumentVersionEmbeddedSignatureCreateView(FormView):
|
|||||||
passphrase = form.cleaned_data['passphrase'] or None
|
passphrase = form.cleaned_data['passphrase'] or None
|
||||||
|
|
||||||
AccessControlList.objects.check_access(
|
AccessControlList.objects.check_access(
|
||||||
obj=key, permissions=permission_key_sign, user=self.request.user
|
obj=key, permissions=(permission_key_sign,), user=self.request.user
|
||||||
)
|
)
|
||||||
|
|
||||||
try:
|
try:
|
||||||
@@ -206,7 +206,7 @@ class DocumentVersionEmbeddedSignatureCreateView(FormView):
|
|||||||
def dispatch(self, request, *args, **kwargs):
|
def dispatch(self, request, *args, **kwargs):
|
||||||
AccessControlList.objects.check_access(
|
AccessControlList.objects.check_access(
|
||||||
obj=self.get_document_version().document,
|
obj=self.get_document_version().document,
|
||||||
permissions=permission_document_version_sign_embedded,
|
permissions=(permission_document_version_sign_embedded,),
|
||||||
user=request.user
|
user=request.user
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -283,8 +283,9 @@ class DocumentVersionSignatureDownloadView(SingleObjectDownloadView):
|
|||||||
class DocumentVersionSignatureListView(SingleObjectListView):
|
class DocumentVersionSignatureListView(SingleObjectListView):
|
||||||
def dispatch(self, request, *args, **kwargs):
|
def dispatch(self, request, *args, **kwargs):
|
||||||
AccessControlList.objects.check_access(
|
AccessControlList.objects.check_access(
|
||||||
permissions=permission_document_version_signature_view,
|
obj=self.get_document_version(),
|
||||||
user=request.user, obj=self.get_document_version()
|
permissions=(permission_document_version_signature_view,),
|
||||||
|
user=request.user
|
||||||
)
|
)
|
||||||
|
|
||||||
return super(
|
return super(
|
||||||
@@ -345,7 +346,7 @@ class DocumentVersionSignatureUploadView(SingleObjectCreateView):
|
|||||||
def dispatch(self, request, *args, **kwargs):
|
def dispatch(self, request, *args, **kwargs):
|
||||||
AccessControlList.objects.check_access(
|
AccessControlList.objects.check_access(
|
||||||
obj=self.get_document_version(),
|
obj=self.get_document_version(),
|
||||||
permissions=permission_document_version_signature_upload,
|
permissions=(permission_document_version_signature_upload,),
|
||||||
user=request.user
|
user=request.user
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
@@ -40,8 +40,8 @@ class APIDocumentTypeWorkflowListView(generics.ListAPIView):
|
|||||||
)
|
)
|
||||||
|
|
||||||
AccessControlList.objects.check_access(
|
AccessControlList.objects.check_access(
|
||||||
permissions=permission_document_type_view, user=self.request.user,
|
obj=document_type, permissions=(permission_document_type_view,),
|
||||||
obj=document_type
|
user=self.request.user
|
||||||
)
|
)
|
||||||
|
|
||||||
return document_type
|
return document_type
|
||||||
@@ -105,8 +105,8 @@ class APIWorkflowDocumentTypeList(generics.ListCreateAPIView):
|
|||||||
workflow = get_object_or_404(klass=Workflow, pk=self.kwargs['pk'])
|
workflow = get_object_or_404(klass=Workflow, pk=self.kwargs['pk'])
|
||||||
|
|
||||||
AccessControlList.objects.check_access(
|
AccessControlList.objects.check_access(
|
||||||
permissions=permission_required, user=self.request.user,
|
obj=workflow, permissions=(permission_required,),
|
||||||
obj=workflow
|
user=self.request.user
|
||||||
)
|
)
|
||||||
|
|
||||||
return workflow
|
return workflow
|
||||||
@@ -158,8 +158,8 @@ class APIWorkflowDocumentTypeView(generics.RetrieveDestroyAPIView):
|
|||||||
workflow = get_object_or_404(klass=Workflow, pk=self.kwargs['pk'])
|
workflow = get_object_or_404(klass=Workflow, pk=self.kwargs['pk'])
|
||||||
|
|
||||||
AccessControlList.objects.check_access(
|
AccessControlList.objects.check_access(
|
||||||
permissions=permission_required, user=self.request.user,
|
obj=workflow, permissions=(permission_required,),
|
||||||
obj=workflow
|
user=self.request.user
|
||||||
)
|
)
|
||||||
|
|
||||||
return workflow
|
return workflow
|
||||||
@@ -261,8 +261,8 @@ class APIWorkflowStateListView(generics.ListCreateAPIView):
|
|||||||
workflow = get_object_or_404(klass=Workflow, pk=self.kwargs['pk'])
|
workflow = get_object_or_404(klass=Workflow, pk=self.kwargs['pk'])
|
||||||
|
|
||||||
AccessControlList.objects.check_access(
|
AccessControlList.objects.check_access(
|
||||||
permissions=permission_required, user=self.request.user,
|
obj=workflow, permissions=(permission_required,),
|
||||||
obj=workflow
|
user=self.request.user
|
||||||
)
|
)
|
||||||
|
|
||||||
return workflow
|
return workflow
|
||||||
@@ -304,8 +304,8 @@ class APIWorkflowStateView(generics.RetrieveUpdateDestroyAPIView):
|
|||||||
workflow = get_object_or_404(klass=Workflow, pk=self.kwargs['pk'])
|
workflow = get_object_or_404(klass=Workflow, pk=self.kwargs['pk'])
|
||||||
|
|
||||||
AccessControlList.objects.check_access(
|
AccessControlList.objects.check_access(
|
||||||
permissions=permission_required, user=self.request.user,
|
obj=workflow, permissions=(permission_required,),
|
||||||
obj=workflow
|
user=self.request.user
|
||||||
)
|
)
|
||||||
|
|
||||||
return workflow
|
return workflow
|
||||||
@@ -357,8 +357,8 @@ class APIWorkflowTransitionListView(generics.ListCreateAPIView):
|
|||||||
workflow = get_object_or_404(klass=Workflow, pk=self.kwargs['pk'])
|
workflow = get_object_or_404(klass=Workflow, pk=self.kwargs['pk'])
|
||||||
|
|
||||||
AccessControlList.objects.check_access(
|
AccessControlList.objects.check_access(
|
||||||
permissions=permission_required, user=self.request.user,
|
obj=workflow, permissions=(permission_required,),
|
||||||
obj=workflow
|
user=self.request.user
|
||||||
)
|
)
|
||||||
|
|
||||||
return workflow
|
return workflow
|
||||||
@@ -411,8 +411,8 @@ class APIWorkflowTransitionView(generics.RetrieveUpdateDestroyAPIView):
|
|||||||
workflow = get_object_or_404(klass=Workflow, pk=self.kwargs['pk'])
|
workflow = get_object_or_404(klass=Workflow, pk=self.kwargs['pk'])
|
||||||
|
|
||||||
AccessControlList.objects.check_access(
|
AccessControlList.objects.check_access(
|
||||||
permissions=permission_required, user=self.request.user,
|
obj=workflow, permissions=(permission_required,),
|
||||||
obj=workflow
|
user=self.request.user
|
||||||
)
|
)
|
||||||
|
|
||||||
return workflow
|
return workflow
|
||||||
@@ -435,8 +435,8 @@ class APIWorkflowInstanceListView(generics.ListAPIView):
|
|||||||
document = get_object_or_404(klass=Document, pk=self.kwargs['pk'])
|
document = get_object_or_404(klass=Document, pk=self.kwargs['pk'])
|
||||||
|
|
||||||
AccessControlList.objects.check_access(
|
AccessControlList.objects.check_access(
|
||||||
permissions=permission_workflow_view, user=self.request.user,
|
obj=document, permissions=(permission_workflow_view,),
|
||||||
obj=document
|
user=self.request.user
|
||||||
)
|
)
|
||||||
|
|
||||||
return document
|
return document
|
||||||
@@ -460,8 +460,8 @@ class APIWorkflowInstanceView(generics.RetrieveAPIView):
|
|||||||
document = get_object_or_404(klass=Document, pk=self.kwargs['pk'])
|
document = get_object_or_404(klass=Document, pk=self.kwargs['pk'])
|
||||||
|
|
||||||
AccessControlList.objects.check_access(
|
AccessControlList.objects.check_access(
|
||||||
permissions=permission_workflow_view, user=self.request.user,
|
obj=document, permissions=(permission_workflow_view,),
|
||||||
obj=document
|
user=self.request.user
|
||||||
)
|
)
|
||||||
|
|
||||||
return document
|
return document
|
||||||
@@ -488,9 +488,10 @@ class APIWorkflowInstanceLogEntryListView(generics.ListCreateAPIView):
|
|||||||
Failing that, check for ACLs for any of the workflow's transitions.
|
Failing that, check for ACLs for any of the workflow's transitions.
|
||||||
Failing that, then raise PermissionDenied
|
Failing that, then raise PermissionDenied
|
||||||
"""
|
"""
|
||||||
|
# TODO: Improvement above
|
||||||
AccessControlList.objects.check_access(
|
AccessControlList.objects.check_access(
|
||||||
permissions=permission_workflow_view, user=self.request.user,
|
obj=document, permissions=(permission_workflow_view,),
|
||||||
obj=document
|
user=self.request.user
|
||||||
)
|
)
|
||||||
|
|
||||||
return document
|
return document
|
||||||
|
|||||||
@@ -417,8 +417,9 @@ class WorkflowInstance(models.Model):
|
|||||||
all transition options.
|
all transition options.
|
||||||
"""
|
"""
|
||||||
AccessControlList.objects.check_access(
|
AccessControlList.objects.check_access(
|
||||||
permissions=permission_workflow_transition,
|
obj=self.workflow,
|
||||||
user=_user, obj=self.workflow
|
permissions=(permission_workflow_transition,),
|
||||||
|
user=_user
|
||||||
)
|
)
|
||||||
except PermissionDenied:
|
except PermissionDenied:
|
||||||
"""
|
"""
|
||||||
@@ -427,7 +428,8 @@ class WorkflowInstance(models.Model):
|
|||||||
"""
|
"""
|
||||||
queryset = AccessControlList.objects.filter_by_access(
|
queryset = AccessControlList.objects.filter_by_access(
|
||||||
permission=permission_workflow_transition,
|
permission=permission_workflow_transition,
|
||||||
user=_user, queryset=queryset
|
queryset=queryset,
|
||||||
|
user=_user
|
||||||
)
|
)
|
||||||
return queryset
|
return queryset
|
||||||
else:
|
else:
|
||||||
|
|||||||
@@ -23,8 +23,8 @@ __all__ = (
|
|||||||
class DocumentWorkflowInstanceListView(SingleObjectListView):
|
class DocumentWorkflowInstanceListView(SingleObjectListView):
|
||||||
def dispatch(self, request, *args, **kwargs):
|
def dispatch(self, request, *args, **kwargs):
|
||||||
AccessControlList.objects.check_access(
|
AccessControlList.objects.check_access(
|
||||||
permissions=permission_workflow_view, user=request.user,
|
obj=self.get_document(), permissions=(permission_workflow_view,),
|
||||||
obj=self.get_document()
|
user=request.user
|
||||||
)
|
)
|
||||||
|
|
||||||
return super(
|
return super(
|
||||||
@@ -58,8 +58,8 @@ class DocumentWorkflowInstanceListView(SingleObjectListView):
|
|||||||
class WorkflowInstanceDetailView(SingleObjectListView):
|
class WorkflowInstanceDetailView(SingleObjectListView):
|
||||||
def dispatch(self, request, *args, **kwargs):
|
def dispatch(self, request, *args, **kwargs):
|
||||||
AccessControlList.objects.check_access(
|
AccessControlList.objects.check_access(
|
||||||
permissions=permission_workflow_view, user=request.user,
|
obj=self.get_workflow_instance().document,
|
||||||
obj=self.get_workflow_instance().document
|
permissions=(permission_workflow_view,), user=request.user
|
||||||
)
|
)
|
||||||
|
|
||||||
return super(
|
return super(
|
||||||
|
|||||||
@@ -27,8 +27,8 @@ class WorkflowDocumentListView(DocumentListView):
|
|||||||
)
|
)
|
||||||
|
|
||||||
AccessControlList.objects.check_access(
|
AccessControlList.objects.check_access(
|
||||||
permissions=permission_workflow_view, user=request.user,
|
obj=self.workflow, permissions=(permission_workflow_view,),
|
||||||
obj=self.workflow
|
user=request.user
|
||||||
)
|
)
|
||||||
|
|
||||||
return super(
|
return super(
|
||||||
@@ -111,8 +111,8 @@ class WorkflowStateDocumentListView(DocumentListView):
|
|||||||
)
|
)
|
||||||
|
|
||||||
AccessControlList.objects.check_access(
|
AccessControlList.objects.check_access(
|
||||||
permissions=permission_workflow_view, user=self.request.user,
|
obj=workflow_state.workflow,
|
||||||
obj=workflow_state.workflow
|
permissions=(permission_workflow_view,), user=self.request.user
|
||||||
)
|
)
|
||||||
|
|
||||||
return workflow_state
|
return workflow_state
|
||||||
@@ -121,8 +121,8 @@ class WorkflowStateDocumentListView(DocumentListView):
|
|||||||
class WorkflowStateListView(SingleObjectListView):
|
class WorkflowStateListView(SingleObjectListView):
|
||||||
def dispatch(self, request, *args, **kwargs):
|
def dispatch(self, request, *args, **kwargs):
|
||||||
AccessControlList.objects.check_access(
|
AccessControlList.objects.check_access(
|
||||||
permissions=permission_workflow_view, user=request.user,
|
obj=self.get_workflow(), permissions=(permission_workflow_view,),
|
||||||
obj=self.get_workflow()
|
user=request.user
|
||||||
)
|
)
|
||||||
|
|
||||||
return super(
|
return super(
|
||||||
|
|||||||
@@ -345,7 +345,7 @@ class SetupWorkflowStateCreateView(SingleObjectCreateView):
|
|||||||
def get_workflow(self):
|
def get_workflow(self):
|
||||||
workflow = get_object_or_404(klass=Workflow, pk=self.kwargs['pk'])
|
workflow = get_object_or_404(klass=Workflow, pk=self.kwargs['pk'])
|
||||||
AccessControlList.objects.check_access(
|
AccessControlList.objects.check_access(
|
||||||
permissions=(permission_workflow_edit,), obj=workflow,
|
obj=workflow, permissions=(permission_workflow_edit,),
|
||||||
user=self.request.user
|
user=self.request.user
|
||||||
)
|
)
|
||||||
return workflow
|
return workflow
|
||||||
@@ -380,7 +380,7 @@ class SetupWorkflowStateDeleteView(SingleObjectDeleteView):
|
|||||||
def get_workflow(self):
|
def get_workflow(self):
|
||||||
workflow = get_object_or_404(klass=Workflow, pk=self.kwargs['pk'])
|
workflow = get_object_or_404(klass=Workflow, pk=self.kwargs['pk'])
|
||||||
AccessControlList.objects.check_access(
|
AccessControlList.objects.check_access(
|
||||||
permissions=(permission_workflow_edit,), obj=workflow,
|
obj=workflow, permissions=(permission_workflow_edit,),
|
||||||
user=self.request.user
|
user=self.request.user
|
||||||
)
|
)
|
||||||
return workflow
|
return workflow
|
||||||
@@ -410,8 +410,8 @@ class SetupWorkflowStateListView(SingleObjectListView):
|
|||||||
|
|
||||||
def dispatch(self, request, *args, **kwargs):
|
def dispatch(self, request, *args, **kwargs):
|
||||||
AccessControlList.objects.check_access(
|
AccessControlList.objects.check_access(
|
||||||
permissions=permission_workflow_view, user=request.user,
|
obj=self.get_workflow(), permissions=(permission_workflow_view,),
|
||||||
obj=self.get_workflow()
|
user=request.user
|
||||||
)
|
)
|
||||||
|
|
||||||
return super(
|
return super(
|
||||||
@@ -492,7 +492,7 @@ class SetupWorkflowTransitionCreateView(SingleObjectCreateView):
|
|||||||
def get_workflow(self):
|
def get_workflow(self):
|
||||||
workflow = get_object_or_404(klass=Workflow, pk=self.kwargs['pk'])
|
workflow = get_object_or_404(klass=Workflow, pk=self.kwargs['pk'])
|
||||||
AccessControlList.objects.check_access(
|
AccessControlList.objects.check_access(
|
||||||
permissions=(permission_workflow_edit,), obj=workflow,
|
obj=workflow, permissions=(permission_workflow_edit,),
|
||||||
user=self.request.user
|
user=self.request.user
|
||||||
)
|
)
|
||||||
return workflow
|
return workflow
|
||||||
@@ -580,8 +580,9 @@ class SetupWorkflowTransitionTriggerEventListView(FormView):
|
|||||||
|
|
||||||
def dispatch(self, *args, **kwargs):
|
def dispatch(self, *args, **kwargs):
|
||||||
AccessControlList.objects.check_access(
|
AccessControlList.objects.check_access(
|
||||||
permissions=permission_workflow_edit,
|
obj=self.get_object().workflow,
|
||||||
user=self.request.user, obj=self.get_object().workflow
|
permissions=(permission_workflow_edit,),
|
||||||
|
user=self.request.user
|
||||||
)
|
)
|
||||||
|
|
||||||
EventType.refresh()
|
EventType.refresh()
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ from mayan.apps.rest_api.permissions import MayanPermission
|
|||||||
|
|
||||||
from .literals import DOCUMENT_IMAGE_TASK_TIMEOUT
|
from .literals import DOCUMENT_IMAGE_TASK_TIMEOUT
|
||||||
from .models import (
|
from .models import (
|
||||||
Document, DocumentType, RecentDocument
|
DeletedDocument, Document, DocumentType, RecentDocument
|
||||||
)
|
)
|
||||||
from .permissions import (
|
from .permissions import (
|
||||||
permission_document_create, permission_document_delete,
|
permission_document_create, permission_document_delete,
|
||||||
@@ -42,14 +42,14 @@ from .tasks import task_generate_document_page_image
|
|||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
class APIDeletedDocumentListView(generics.ListAPIView):
|
class APITrashedDocumentListView(generics.ListAPIView):
|
||||||
"""
|
"""
|
||||||
Returns a list of all the trashed documents.
|
Returns a list of all the trashed documents.
|
||||||
"""
|
"""
|
||||||
filter_backends = (MayanObjectPermissionsFilter,)
|
filter_backends = (MayanObjectPermissionsFilter,)
|
||||||
mayan_object_permissions = {'GET': (permission_document_view,)}
|
mayan_object_permissions = {'GET': (permission_document_view,)}
|
||||||
permission_classes = (MayanPermission,)
|
permission_classes = (MayanPermission,)
|
||||||
queryset = Document.trash.all()
|
queryset = DeletedDocument.objects.all()
|
||||||
serializer_class = DeletedDocumentSerializer
|
serializer_class = DeletedDocumentSerializer
|
||||||
|
|
||||||
|
|
||||||
@@ -64,7 +64,7 @@ class APIDeletedDocumentView(generics.RetrieveDestroyAPIView):
|
|||||||
'GET': (permission_document_view,)
|
'GET': (permission_document_view,)
|
||||||
}
|
}
|
||||||
permission_classes = (MayanPermission,)
|
permission_classes = (MayanPermission,)
|
||||||
queryset = Document.trash.all()
|
queryset = DeletedDocument.objects.all()
|
||||||
serializer_class = DeletedDocumentSerializer
|
serializer_class = DeletedDocumentSerializer
|
||||||
|
|
||||||
|
|
||||||
@@ -76,7 +76,7 @@ class APIDeletedDocumentRestoreView(generics.GenericAPIView):
|
|||||||
'POST': (permission_document_restore,)
|
'POST': (permission_document_restore,)
|
||||||
}
|
}
|
||||||
permission_classes = (MayanPermission,)
|
permission_classes = (MayanPermission,)
|
||||||
queryset = Document.trash.all()
|
queryset = DeletedDocument.objects.all()
|
||||||
|
|
||||||
def get_serializer(self, *args, **kwargs):
|
def get_serializer(self, *args, **kwargs):
|
||||||
return None
|
return None
|
||||||
@@ -143,8 +143,8 @@ class APIDocumentListView(generics.ListCreateAPIView):
|
|||||||
|
|
||||||
def perform_create(self, serializer):
|
def perform_create(self, serializer):
|
||||||
AccessControlList.objects.check_access(
|
AccessControlList.objects.check_access(
|
||||||
permissions=(permission_document_create,), user=self.request.user,
|
obj=serializer.validated_data['document_type'],
|
||||||
obj=serializer.validated_data['document_type']
|
permissions=(permission_document_create,), user=self.request.user
|
||||||
)
|
)
|
||||||
serializer.save(_user=self.request.user)
|
serializer.save(_user=self.request.user)
|
||||||
|
|
||||||
@@ -164,7 +164,8 @@ class APIDocumentPageImageView(generics.RetrieveAPIView):
|
|||||||
document = get_object_or_404(Document.passthrough, pk=self.kwargs['pk'])
|
document = get_object_or_404(Document.passthrough, pk=self.kwargs['pk'])
|
||||||
|
|
||||||
AccessControlList.objects.check_access(
|
AccessControlList.objects.check_access(
|
||||||
permission_required, self.request.user, document
|
obj=document, permissions=(permission_required,),
|
||||||
|
user=self.request.user
|
||||||
)
|
)
|
||||||
return document
|
return document
|
||||||
|
|
||||||
@@ -231,7 +232,8 @@ class APIDocumentPageView(generics.RetrieveUpdateAPIView):
|
|||||||
document = get_object_or_404(Document, pk=self.kwargs['pk'])
|
document = get_object_or_404(Document, pk=self.kwargs['pk'])
|
||||||
|
|
||||||
AccessControlList.objects.check_access(
|
AccessControlList.objects.check_access(
|
||||||
permission_required, self.request.user, document
|
obj=document, permissions=(permission_required,),
|
||||||
|
user=self.request.user
|
||||||
)
|
)
|
||||||
return document
|
return document
|
||||||
|
|
||||||
@@ -309,8 +311,8 @@ class APIDocumentTypeDocumentListView(generics.ListAPIView):
|
|||||||
def get_queryset(self):
|
def get_queryset(self):
|
||||||
document_type = get_object_or_404(DocumentType, pk=self.kwargs['pk'])
|
document_type = get_object_or_404(DocumentType, pk=self.kwargs['pk'])
|
||||||
AccessControlList.objects.check_access(
|
AccessControlList.objects.check_access(
|
||||||
permissions=permission_document_type_view, user=self.request.user,
|
obj=document_type, permissions=(permission_document_type_view,),
|
||||||
obj=document_type
|
user=self.request.user
|
||||||
)
|
)
|
||||||
|
|
||||||
return document_type.documents.all()
|
return document_type.documents.all()
|
||||||
@@ -326,8 +328,8 @@ class APIDocumentVersionDownloadView(DownloadMixin, generics.RetrieveAPIView):
|
|||||||
document = get_object_or_404(Document, pk=self.kwargs['pk'])
|
document = get_object_or_404(Document, pk=self.kwargs['pk'])
|
||||||
|
|
||||||
AccessControlList.objects.check_access(
|
AccessControlList.objects.check_access(
|
||||||
permissions=(permission_document_download,), user=self.request.user,
|
obj=document, permissions=(permission_document_download,),
|
||||||
obj=document
|
user=self.request.user
|
||||||
)
|
)
|
||||||
return document
|
return document
|
||||||
|
|
||||||
@@ -420,7 +422,8 @@ class APIDocumentVersionPageListView(generics.ListAPIView):
|
|||||||
document = get_object_or_404(Document, pk=self.kwargs['pk'])
|
document = get_object_or_404(Document, pk=self.kwargs['pk'])
|
||||||
|
|
||||||
AccessControlList.objects.check_access(
|
AccessControlList.objects.check_access(
|
||||||
permission_document_view, self.request.user, document
|
obj=document, permissions=(permission_document_view,),
|
||||||
|
user=self.request.user
|
||||||
)
|
)
|
||||||
return document
|
return document
|
||||||
|
|
||||||
@@ -442,7 +445,6 @@ class APIDocumentVersionsListView(generics.ListCreateAPIView):
|
|||||||
mayan_object_permissions = {
|
mayan_object_permissions = {
|
||||||
'GET': (permission_document_version_view,),
|
'GET': (permission_document_version_view,),
|
||||||
}
|
}
|
||||||
mayan_permission_attribute_check = 'document'
|
|
||||||
permission_classes = (MayanPermission,)
|
permission_classes = (MayanPermission,)
|
||||||
|
|
||||||
def create(self, request, *args, **kwargs):
|
def create(self, request, *args, **kwargs):
|
||||||
@@ -471,8 +473,8 @@ class APIDocumentVersionsListView(generics.ListCreateAPIView):
|
|||||||
document = get_object_or_404(Document, pk=self.kwargs['pk'])
|
document = get_object_or_404(Document, pk=self.kwargs['pk'])
|
||||||
|
|
||||||
AccessControlList.objects.check_access(
|
AccessControlList.objects.check_access(
|
||||||
permissions=(permission_document_new_version,),
|
obj=document, permissions=(permission_document_new_version,),
|
||||||
user=self.request.user, obj=document
|
user=self.request.user,
|
||||||
)
|
)
|
||||||
serializer.save(document=document, _user=self.request.user)
|
serializer.save(document=document, _user=self.request.user)
|
||||||
|
|
||||||
@@ -497,7 +499,8 @@ class APIDocumentVersionView(generics.RetrieveUpdateDestroyAPIView):
|
|||||||
document = get_object_or_404(Document, pk=self.kwargs['pk'])
|
document = get_object_or_404(Document, pk=self.kwargs['pk'])
|
||||||
|
|
||||||
AccessControlList.objects.check_access(
|
AccessControlList.objects.check_access(
|
||||||
permission_required, self.request.user, document
|
obj=document, permissions=(permission_required,),
|
||||||
|
user=self.request.user
|
||||||
)
|
)
|
||||||
return document
|
return document
|
||||||
|
|
||||||
|
|||||||
@@ -220,10 +220,6 @@ class DocumentsApp(MayanAppConfig):
|
|||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
ModelPermission.register_proxy(
|
|
||||||
source=Document, model=DocumentType,
|
|
||||||
)
|
|
||||||
|
|
||||||
ModelPermission.register_inheritance(
|
ModelPermission.register_inheritance(
|
||||||
model=Document, related='document_type',
|
model=Document, related='document_type',
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -53,13 +53,13 @@ def task_clear_image_cache():
|
|||||||
|
|
||||||
|
|
||||||
@app.task(ignore_result=True)
|
@app.task(ignore_result=True)
|
||||||
def task_delete_document(deleted_document_id):
|
def task_delete_document(trashed_document_id):
|
||||||
DeletedDocument = apps.get_model(
|
DeletedDocument = apps.get_model(
|
||||||
app_label='documents', model_name='DeletedDocument'
|
app_label='documents', model_name='DeletedDocument'
|
||||||
)
|
)
|
||||||
|
|
||||||
logger.debug(msg='Executing')
|
logger.debug(msg='Executing')
|
||||||
deleted_document = DeletedDocument.objects.get(pk=deleted_document_id)
|
deleted_document = DeletedDocument.objects.get(pk=trashed_document_id)
|
||||||
deleted_document.delete()
|
deleted_document.delete()
|
||||||
logger.debug(msg='Finshed')
|
logger.debug(msg='Finshed')
|
||||||
|
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ from ..permissions import (
|
|||||||
from .base import GenericDocumentViewTestCase
|
from .base import GenericDocumentViewTestCase
|
||||||
|
|
||||||
|
|
||||||
class DeletedDocumentTestCase(GenericDocumentViewTestCase):
|
class TrashedDocumentTestCase(GenericDocumentViewTestCase):
|
||||||
def _request_document_restore_view(self):
|
def _request_document_restore_view(self):
|
||||||
return self.post(
|
return self.post(
|
||||||
viewname='documents:document_restore', kwargs={
|
viewname='documents:document_restore', kwargs={
|
||||||
@@ -22,7 +22,7 @@ class DeletedDocumentTestCase(GenericDocumentViewTestCase):
|
|||||||
self.assertEqual(Document.objects.count(), 0)
|
self.assertEqual(Document.objects.count(), 0)
|
||||||
|
|
||||||
response = self._request_document_restore_view()
|
response = self._request_document_restore_view()
|
||||||
self.assertEqual(response.status_code, 403)
|
self.assertEqual(response.status_code, 302)
|
||||||
|
|
||||||
self.assertEqual(DeletedDocument.objects.count(), 1)
|
self.assertEqual(DeletedDocument.objects.count(), 1)
|
||||||
self.assertEqual(Document.objects.count(), 0)
|
self.assertEqual(Document.objects.count(), 0)
|
||||||
@@ -50,7 +50,7 @@ class DeletedDocumentTestCase(GenericDocumentViewTestCase):
|
|||||||
|
|
||||||
def test_document_trash_no_permissions(self):
|
def test_document_trash_no_permissions(self):
|
||||||
response = self._request_document_trash_view()
|
response = self._request_document_trash_view()
|
||||||
self.assertEqual(response.status_code, 403)
|
self.assertEqual(response.status_code, 302)
|
||||||
|
|
||||||
self.assertEqual(DeletedDocument.objects.count(), 0)
|
self.assertEqual(DeletedDocument.objects.count(), 0)
|
||||||
self.assertEqual(Document.objects.count(), 1)
|
self.assertEqual(Document.objects.count(), 1)
|
||||||
@@ -79,7 +79,7 @@ class DeletedDocumentTestCase(GenericDocumentViewTestCase):
|
|||||||
self.assertEqual(DeletedDocument.objects.count(), 1)
|
self.assertEqual(DeletedDocument.objects.count(), 1)
|
||||||
|
|
||||||
response = self._request_document_delete_view()
|
response = self._request_document_delete_view()
|
||||||
self.assertEqual(response.status_code, 403)
|
self.assertEqual(response.status_code, 302)
|
||||||
|
|
||||||
self.assertEqual(Document.objects.count(), 0)
|
self.assertEqual(Document.objects.count(), 0)
|
||||||
self.assertEqual(DeletedDocument.objects.count(), 1)
|
self.assertEqual(DeletedDocument.objects.count(), 1)
|
||||||
@@ -3,7 +3,7 @@ from __future__ import unicode_literals
|
|||||||
from django.conf.urls import url
|
from django.conf.urls import url
|
||||||
|
|
||||||
from .api_views import (
|
from .api_views import (
|
||||||
APIDeletedDocumentListView, APIDeletedDocumentRestoreView,
|
APITrashedDocumentListView, APIDeletedDocumentRestoreView,
|
||||||
APIDeletedDocumentView, APIDocumentDownloadView, APIDocumentView,
|
APIDeletedDocumentView, APIDocumentDownloadView, APIDocumentView,
|
||||||
APIDocumentListView, APIDocumentVersionDownloadView,
|
APIDocumentListView, APIDocumentVersionDownloadView,
|
||||||
APIDocumentPageImageView, APIDocumentPageView,
|
APIDocumentPageImageView, APIDocumentPageView,
|
||||||
@@ -13,31 +13,33 @@ from .api_views import (
|
|||||||
APIRecentDocumentListView
|
APIRecentDocumentListView
|
||||||
)
|
)
|
||||||
from .views import (
|
from .views import (
|
||||||
ClearImageCacheView, DeletedDocumentDeleteView,
|
ClearImageCacheView, DocumentDocumentTypeEditView, DocumentDownloadFormView,
|
||||||
DeletedDocumentDeleteManyView, DeletedDocumentListView,
|
|
||||||
DocumentDocumentTypeEditView, DocumentDownloadFormView,
|
|
||||||
DocumentDownloadView, DocumentDuplicatesListView, DocumentEditView,
|
DocumentDownloadView, DocumentDuplicatesListView, DocumentEditView,
|
||||||
DocumentListView, DocumentPageListView, DocumentPageNavigationFirst,
|
DocumentListView, DocumentPageListView, DocumentPageNavigationFirst,
|
||||||
DocumentPageNavigationLast, DocumentPageNavigationNext,
|
DocumentPageNavigationLast, DocumentPageNavigationNext,
|
||||||
DocumentPageNavigationPrevious, DocumentPageRotateLeftView,
|
DocumentPageNavigationPrevious, DocumentPageRotateLeftView,
|
||||||
DocumentPageRotateRightView, DocumentPageView, DocumentPageViewResetView,
|
DocumentPageRotateRightView, DocumentPageView, DocumentPageViewResetView,
|
||||||
DocumentPageZoomInView, DocumentPageZoomOutView, DocumentPreviewView,
|
DocumentPageZoomInView, DocumentPageZoomOutView, DocumentPreviewView,
|
||||||
DocumentPrint, DocumentRestoreView, DocumentRestoreManyView,
|
DocumentPrint, DocumentTransformationsClearView,
|
||||||
DocumentTransformationsClearView, DocumentTransformationsCloneView,
|
DocumentTransformationsCloneView, DocumentTypeCreateView,
|
||||||
DocumentTrashView, DocumentTrashManyView, DocumentTypeCreateView,
|
|
||||||
DocumentTypeDeleteView, DocumentTypeDocumentListView,
|
DocumentTypeDeleteView, DocumentTypeDocumentListView,
|
||||||
DocumentTypeFilenameCreateView, DocumentTypeFilenameDeleteView,
|
DocumentTypeFilenameCreateView, DocumentTypeFilenameDeleteView,
|
||||||
DocumentTypeFilenameEditView, DocumentTypeFilenameListView,
|
DocumentTypeFilenameEditView, DocumentTypeFilenameListView,
|
||||||
DocumentTypeListView, DocumentTypeEditView, DocumentUpdatePageCountView,
|
DocumentTypeListView, DocumentTypeEditView, DocumentUpdatePageCountView,
|
||||||
DocumentVersionDownloadFormView, DocumentVersionDownloadView,
|
DocumentVersionDownloadFormView, DocumentVersionDownloadView,
|
||||||
DocumentVersionListView, DocumentVersionRevertView, DocumentVersionView,
|
DocumentVersionListView, DocumentVersionRevertView, DocumentVersionView,
|
||||||
DocumentView, DuplicatedDocumentListView, EmptyTrashCanView,
|
DocumentView, DuplicatedDocumentListView,
|
||||||
RecentAccessDocumentListView, RecentAddedDocumentListView,
|
RecentAccessDocumentListView, RecentAddedDocumentListView,
|
||||||
ScanDuplicatedDocuments
|
ScanDuplicatedDocuments
|
||||||
)
|
)
|
||||||
from .views.favorite_document_views import (
|
from .views.favorite_document_views import (
|
||||||
FavoriteAddView, FavoriteDocumentListView, FavoriteRemoveView
|
FavoriteAddView, FavoriteDocumentListView, FavoriteRemoveView
|
||||||
)
|
)
|
||||||
|
from .views.trashed_document_views import (
|
||||||
|
DocumentTrashView, EmptyTrashCanView, TrashedDocumentDeleteView,
|
||||||
|
TrashedDocumentListView, TrashedDocumentRestoreView
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
urlpatterns_favorite_documents = [
|
urlpatterns_favorite_documents = [
|
||||||
url(
|
url(
|
||||||
@@ -62,6 +64,42 @@ urlpatterns_favorite_documents = [
|
|||||||
view=FavoriteRemoveView.as_view(),
|
view=FavoriteRemoveView.as_view(),
|
||||||
name='document_multiple_remove_from_favorites'
|
name='document_multiple_remove_from_favorites'
|
||||||
),
|
),
|
||||||
|
url(
|
||||||
|
regex=r'^trash_can/empty/$', view=EmptyTrashCanView.as_view(),
|
||||||
|
name='trash_can_empty'
|
||||||
|
),
|
||||||
|
]
|
||||||
|
|
||||||
|
urlpatterns_trashed_documents = [
|
||||||
|
url(
|
||||||
|
regex=r'^(?P<pk>\d+)/trash/$', view=DocumentTrashView.as_view(),
|
||||||
|
name='document_trash'
|
||||||
|
),
|
||||||
|
url(
|
||||||
|
regex=r'^multiple/trash/$', view=DocumentTrashView.as_view(),
|
||||||
|
name='document_multiple_trash'
|
||||||
|
),
|
||||||
|
url(
|
||||||
|
regex=r'^list/deleted/$', view=TrashedDocumentListView.as_view(),
|
||||||
|
name='document_list_deleted'
|
||||||
|
),
|
||||||
|
url(
|
||||||
|
regex=r'^(?P<pk>\d+)/restore/$',
|
||||||
|
view=TrashedDocumentRestoreView.as_view(), name='document_restore'
|
||||||
|
),
|
||||||
|
url(
|
||||||
|
regex=r'^multiple/restore/$', view=TrashedDocumentRestoreView.as_view(),
|
||||||
|
name='document_multiple_restore'
|
||||||
|
),
|
||||||
|
url(
|
||||||
|
regex=r'^(?P<pk>\d+)/delete/$',
|
||||||
|
view=TrashedDocumentDeleteView.as_view(), name='document_delete'
|
||||||
|
),
|
||||||
|
url(
|
||||||
|
regex=r'^multiple/delete/$',
|
||||||
|
view=TrashedDocumentDeleteView.as_view(),
|
||||||
|
name='document_multiple_delete'
|
||||||
|
),
|
||||||
]
|
]
|
||||||
|
|
||||||
urlpatterns = [
|
urlpatterns = [
|
||||||
@@ -78,10 +116,6 @@ urlpatterns = [
|
|||||||
view=RecentAddedDocumentListView.as_view(),
|
view=RecentAddedDocumentListView.as_view(),
|
||||||
name='document_list_recent_added'
|
name='document_list_recent_added'
|
||||||
),
|
),
|
||||||
url(
|
|
||||||
regex=r'^list/deleted/$', view=DeletedDocumentListView.as_view(),
|
|
||||||
name='document_list_deleted'
|
|
||||||
),
|
|
||||||
url(
|
url(
|
||||||
regex=r'^list/duplicated/$',
|
regex=r'^list/duplicated/$',
|
||||||
view=DuplicatedDocumentListView.as_view(),
|
view=DuplicatedDocumentListView.as_view(),
|
||||||
@@ -100,23 +134,6 @@ urlpatterns = [
|
|||||||
view=DocumentDuplicatesListView.as_view(),
|
view=DocumentDuplicatesListView.as_view(),
|
||||||
name='document_duplicates_list'
|
name='document_duplicates_list'
|
||||||
),
|
),
|
||||||
url(
|
|
||||||
regex=r'^(?P<pk>\d+)/restore/$', view=DocumentRestoreView.as_view(),
|
|
||||||
name='document_restore'
|
|
||||||
),
|
|
||||||
url(
|
|
||||||
regex=r'^multiple/restore/$', view=DocumentRestoreManyView.as_view(),
|
|
||||||
name='document_multiple_restore'
|
|
||||||
),
|
|
||||||
url(
|
|
||||||
regex=r'^(?P<pk>\d+)/delete/$',
|
|
||||||
view=DeletedDocumentDeleteView.as_view(), name='document_delete'
|
|
||||||
),
|
|
||||||
url(
|
|
||||||
regex=r'^multiple/delete/$',
|
|
||||||
view=DeletedDocumentDeleteManyView.as_view(),
|
|
||||||
name='document_multiple_delete'
|
|
||||||
),
|
|
||||||
url(
|
url(
|
||||||
regex=r'^(?P<pk>\d+)/type/$',
|
regex=r'^(?P<pk>\d+)/type/$',
|
||||||
view=DocumentDocumentTypeEditView.as_view(),
|
view=DocumentDocumentTypeEditView.as_view(),
|
||||||
@@ -126,14 +143,6 @@ urlpatterns = [
|
|||||||
regex=r'^multiple/type/$', view=DocumentDocumentTypeEditView.as_view(),
|
regex=r'^multiple/type/$', view=DocumentDocumentTypeEditView.as_view(),
|
||||||
name='document_multiple_document_type_edit'
|
name='document_multiple_document_type_edit'
|
||||||
),
|
),
|
||||||
url(
|
|
||||||
regex=r'^(?P<pk>\d+)/trash/$', view=DocumentTrashView.as_view(),
|
|
||||||
name='document_trash'
|
|
||||||
),
|
|
||||||
url(
|
|
||||||
regex=r'^multiple/trash/$', view=DocumentTrashManyView.as_view(),
|
|
||||||
name='document_multiple_trash'
|
|
||||||
),
|
|
||||||
url(
|
url(
|
||||||
regex=r'^(?P<pk>\d+)/edit/$', view=DocumentEditView.as_view(),
|
regex=r'^(?P<pk>\d+)/edit/$', view=DocumentEditView.as_view(),
|
||||||
name='document_edit'
|
name='document_edit'
|
||||||
@@ -218,11 +227,6 @@ urlpatterns = [
|
|||||||
regex=r'^cache/clear/$', view=ClearImageCacheView.as_view(),
|
regex=r'^cache/clear/$', view=ClearImageCacheView.as_view(),
|
||||||
name='document_clear_image_cache'
|
name='document_clear_image_cache'
|
||||||
),
|
),
|
||||||
url(
|
|
||||||
regex=r'^trash_can/empty/$', view=EmptyTrashCanView.as_view(),
|
|
||||||
name='trash_can_empty'
|
|
||||||
),
|
|
||||||
|
|
||||||
url(
|
url(
|
||||||
regex=r'^page/(?P<pk>\d+)/$', view=DocumentPageView.as_view(),
|
regex=r'^page/(?P<pk>\d+)/$', view=DocumentPageView.as_view(),
|
||||||
name='document_page_view'
|
name='document_page_view'
|
||||||
@@ -323,7 +327,7 @@ urlpatterns = [
|
|||||||
),
|
),
|
||||||
]
|
]
|
||||||
urlpatterns.extend(urlpatterns_favorite_documents)
|
urlpatterns.extend(urlpatterns_favorite_documents)
|
||||||
|
urlpatterns.extend(urlpatterns_trashed_documents)
|
||||||
|
|
||||||
api_urls = [
|
api_urls = [
|
||||||
url(
|
url(
|
||||||
@@ -384,7 +388,7 @@ api_urls = [
|
|||||||
),
|
),
|
||||||
url(
|
url(
|
||||||
regex=r'^trashed_documents/$',
|
regex=r'^trashed_documents/$',
|
||||||
view=APIDeletedDocumentListView.as_view(), name='trasheddocument-list'
|
view=APITrashedDocumentListView.as_view(), name='trasheddocument-list'
|
||||||
),
|
),
|
||||||
url(
|
url(
|
||||||
regex=r'^trashed_documents/(?P<pk>[0-9]+)/$',
|
regex=r'^trashed_documents/(?P<pk>[0-9]+)/$',
|
||||||
|
|||||||
@@ -38,8 +38,8 @@ logger = logging.getLogger(__name__)
|
|||||||
class DocumentPageListView(SingleObjectListView):
|
class DocumentPageListView(SingleObjectListView):
|
||||||
def dispatch(self, request, *args, **kwargs):
|
def dispatch(self, request, *args, **kwargs):
|
||||||
AccessControlList.objects.check_access(
|
AccessControlList.objects.check_access(
|
||||||
permissions=permission_document_view, user=self.request.user,
|
obj=self.get_document(), permissions=(permission_document_view,),
|
||||||
obj=self.get_document()
|
user=self.request.user
|
||||||
)
|
)
|
||||||
|
|
||||||
return super(
|
return super(
|
||||||
@@ -66,8 +66,8 @@ class DocumentPageNavigationBase(RedirectView):
|
|||||||
document_page = self.get_object()
|
document_page = self.get_object()
|
||||||
|
|
||||||
AccessControlList.objects.check_access(
|
AccessControlList.objects.check_access(
|
||||||
permissions=permission_document_view, user=request.user,
|
obj=document_page.document,
|
||||||
obj=document_page.document
|
permissions=(permission_document_view,), user=request.user
|
||||||
)
|
)
|
||||||
|
|
||||||
return super(DocumentPageNavigationBase, self).dispatch(
|
return super(DocumentPageNavigationBase, self).dispatch(
|
||||||
@@ -170,8 +170,8 @@ class DocumentPageView(SimpleView):
|
|||||||
|
|
||||||
def dispatch(self, request, *args, **kwargs):
|
def dispatch(self, request, *args, **kwargs):
|
||||||
AccessControlList.objects.check_access(
|
AccessControlList.objects.check_access(
|
||||||
permissions=permission_document_view, user=request.user,
|
obj=self.get_object().document,
|
||||||
obj=self.get_object().document
|
permissions=(permission_document_view,), user=request.user
|
||||||
)
|
)
|
||||||
|
|
||||||
return super(
|
return super(
|
||||||
@@ -214,11 +214,11 @@ class DocumentPageViewResetView(RedirectView):
|
|||||||
|
|
||||||
class DocumentPageInteractiveTransformation(RedirectView):
|
class DocumentPageInteractiveTransformation(RedirectView):
|
||||||
def dispatch(self, request, *args, **kwargs):
|
def dispatch(self, request, *args, **kwargs):
|
||||||
object = self.get_object()
|
obj = self.get_object()
|
||||||
|
|
||||||
AccessControlList.objects.check_access(
|
AccessControlList.objects.check_access(
|
||||||
permissions=permission_document_view, user=request.user,
|
obj=obj, permissions=(permission_document_view,),
|
||||||
obj=object
|
user=request.user
|
||||||
)
|
)
|
||||||
|
|
||||||
return super(DocumentPageInteractiveTransformation, self).dispatch(
|
return super(DocumentPageInteractiveTransformation, self).dispatch(
|
||||||
|
|||||||
@@ -138,8 +138,9 @@ class DocumentTypeFilenameCreateView(SingleObjectCreateView):
|
|||||||
|
|
||||||
def dispatch(self, request, *args, **kwargs):
|
def dispatch(self, request, *args, **kwargs):
|
||||||
AccessControlList.objects.check_access(
|
AccessControlList.objects.check_access(
|
||||||
permissions=permission_document_type_edit, user=request.user,
|
obj=self.get_document_type(),
|
||||||
obj=self.get_document_type()
|
permissions=(permission_document_type_edit,),
|
||||||
|
user=request.user
|
||||||
)
|
)
|
||||||
|
|
||||||
return super(DocumentTypeFilenameCreateView, self).dispatch(
|
return super(DocumentTypeFilenameCreateView, self).dispatch(
|
||||||
|
|||||||
@@ -32,8 +32,9 @@ logger = logging.getLogger(__name__)
|
|||||||
class DocumentVersionListView(SingleObjectListView):
|
class DocumentVersionListView(SingleObjectListView):
|
||||||
def dispatch(self, request, *args, **kwargs):
|
def dispatch(self, request, *args, **kwargs):
|
||||||
AccessControlList.objects.check_access(
|
AccessControlList.objects.check_access(
|
||||||
permissions=permission_document_version_view, user=request.user,
|
obj=self.get_document(),
|
||||||
obj=self.get_document()
|
permissions=(permission_document_version_view,),
|
||||||
|
user=request.user
|
||||||
)
|
)
|
||||||
|
|
||||||
self.get_document().add_as_recent_document_for_user(request.user)
|
self.get_document().add_as_recent_document_for_user(request.user)
|
||||||
|
|||||||
@@ -318,8 +318,8 @@ class DocumentDownloadView(SingleObjectDownloadView):
|
|||||||
class DocumentDuplicatesListView(DocumentListView):
|
class DocumentDuplicatesListView(DocumentListView):
|
||||||
def dispatch(self, request, *args, **kwargs):
|
def dispatch(self, request, *args, **kwargs):
|
||||||
AccessControlList.objects.check_access(
|
AccessControlList.objects.check_access(
|
||||||
permissions=permission_document_view, user=self.request.user,
|
obj=self.get_document(), permissions=(permission_document_view,),
|
||||||
obj=self.get_document()
|
user=self.request.user
|
||||||
)
|
)
|
||||||
|
|
||||||
return super(
|
return super(
|
||||||
@@ -582,8 +582,8 @@ class DocumentTransformationsCloneView(FormView):
|
|||||||
instance = get_object_or_404(klass=Document, pk=self.kwargs['pk'])
|
instance = get_object_or_404(klass=Document, pk=self.kwargs['pk'])
|
||||||
|
|
||||||
AccessControlList.objects.check_access(
|
AccessControlList.objects.check_access(
|
||||||
permissions=permission_transformation_edit,
|
obj=instance, permissions=(permission_transformation_edit,),
|
||||||
user=self.request.user, obj=instance
|
user=self.request.user
|
||||||
)
|
)
|
||||||
|
|
||||||
instance.add_as_recent_document_for_user(self.request.user)
|
instance.add_as_recent_document_for_user(self.request.user)
|
||||||
@@ -597,8 +597,8 @@ class DocumentPrint(FormView):
|
|||||||
def dispatch(self, request, *args, **kwargs):
|
def dispatch(self, request, *args, **kwargs):
|
||||||
instance = self.get_object()
|
instance = self.get_object()
|
||||||
AccessControlList.objects.check_access(
|
AccessControlList.objects.check_access(
|
||||||
permissions=permission_document_print, user=self.request.user,
|
obj=instance, permissions=(permission_document_print,),
|
||||||
obj=instance
|
user=self.request.user
|
||||||
)
|
)
|
||||||
|
|
||||||
instance.add_as_recent_document_for_user(self.request.user)
|
instance.add_as_recent_document_for_user(self.request.user)
|
||||||
|
|||||||
@@ -3,13 +3,13 @@ from __future__ import absolute_import, unicode_literals
|
|||||||
import logging
|
import logging
|
||||||
|
|
||||||
from django.contrib import messages
|
from django.contrib import messages
|
||||||
from django.shortcuts import get_object_or_404
|
from django.urls import reverse_lazy
|
||||||
from django.urls import reverse, reverse_lazy
|
from django.utils.translation import ugettext_lazy as _, ungettext
|
||||||
from django.utils.translation import ugettext_lazy as _
|
|
||||||
|
|
||||||
from mayan.apps.acls.models import AccessControlList
|
from mayan.apps.acls.models import AccessControlList
|
||||||
from mayan.apps.common.generics import ConfirmView
|
from mayan.apps.common.generics import (
|
||||||
from mayan.apps.common.mixins import MultipleInstanceActionMixin
|
ConfirmView, MultipleObjectConfirmActionView
|
||||||
|
)
|
||||||
|
|
||||||
from ..icons import icon_document_list_deleted
|
from ..icons import icon_document_list_deleted
|
||||||
from ..models import DeletedDocument, Document
|
from ..models import DeletedDocument, Document
|
||||||
@@ -23,64 +23,100 @@ from ..tasks import task_delete_document
|
|||||||
from .document_views import DocumentListView
|
from .document_views import DocumentListView
|
||||||
|
|
||||||
__all__ = (
|
__all__ = (
|
||||||
'DeletedDocumentDeleteView', 'DeletedDocumentDeleteManyView',
|
'DocumentTrashView', 'EmptyTrashCanView', 'TrashedDocumentDeleteView',
|
||||||
'DeletedDocumentListView', 'DocumentRestoreView', 'DocumentRestoreManyView',
|
'TrashedDocumentListView', 'TrashedDocumentRestoreView'
|
||||||
'DocumentTrashView', 'DocumentTrashManyView', 'EmptyTrashCanView'
|
|
||||||
)
|
)
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
class DeletedDocumentDeleteView(ConfirmView):
|
class DocumentTrashView(MultipleObjectConfirmActionView):
|
||||||
extra_context = {
|
model = Document
|
||||||
'title': _('Delete the selected document?')
|
object_permission = permission_document_trash
|
||||||
|
pk_url_kwarg = 'pk'
|
||||||
|
success_message_singular = _(
|
||||||
|
'%(count)d document moved to the trash.'
|
||||||
|
)
|
||||||
|
success_message_plural = _(
|
||||||
|
'%(count)d documents moved to the trash.'
|
||||||
|
)
|
||||||
|
|
||||||
|
def get_extra_context(self):
|
||||||
|
queryset = self.get_object_list()
|
||||||
|
|
||||||
|
result = {
|
||||||
|
'title': ungettext(
|
||||||
|
single='Move the selected document to the trash?',
|
||||||
|
plural='Move the selected documents to the trash?',
|
||||||
|
number=queryset.count()
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
def object_action(self, instance):
|
return result
|
||||||
source_document = get_object_or_404(
|
|
||||||
klass=Document.passthrough, pk=instance.pk
|
|
||||||
)
|
|
||||||
|
|
||||||
AccessControlList.objects.check_access(
|
def object_action(self, form, instance):
|
||||||
permissions=permission_document_delete, user=self.request.user,
|
instance.delete()
|
||||||
obj=source_document
|
|
||||||
)
|
|
||||||
|
|
||||||
task_delete_document.apply_async(
|
|
||||||
kwargs={'deleted_document_id': instance.pk}
|
class EmptyTrashCanView(ConfirmView):
|
||||||
|
extra_context = {
|
||||||
|
'title': _('Empty trash?')
|
||||||
|
}
|
||||||
|
view_permission = permission_empty_trash
|
||||||
|
action_cancel_redirect = post_action_redirect = reverse_lazy(
|
||||||
|
'documents:document_list_deleted'
|
||||||
)
|
)
|
||||||
|
|
||||||
def view_action(self):
|
def view_action(self):
|
||||||
instance = get_object_or_404(
|
for deleted_document in DeletedDocument.objects.all():
|
||||||
klass=DeletedDocument, pk=self.kwargs['pk']
|
task_delete_document.apply_async(
|
||||||
)
|
kwargs={'trashed_document_id': deleted_document.pk}
|
||||||
self.object_action(instance=instance)
|
|
||||||
messages.success(
|
|
||||||
self.request, _('Document: %(document)s deleted.') % {
|
|
||||||
'document': instance
|
|
||||||
}
|
|
||||||
)
|
)
|
||||||
|
|
||||||
|
messages.success(self.request, _('Trash emptied successfully'))
|
||||||
|
|
||||||
class DeletedDocumentDeleteManyView(MultipleInstanceActionMixin, DeletedDocumentDeleteView):
|
|
||||||
extra_context = {
|
class TrashedDocumentDeleteView(MultipleObjectConfirmActionView):
|
||||||
'title': _('Delete the selected documents?')
|
|
||||||
}
|
|
||||||
model = DeletedDocument
|
model = DeletedDocument
|
||||||
success_message = '%(count)d document deleted.'
|
object_permission = permission_document_delete
|
||||||
success_message_plural = '%(count)d documents deleted.'
|
pk_url_kwarg = 'pk'
|
||||||
|
success_message_singular = _(
|
||||||
|
'%(count)d trashed document deleted.'
|
||||||
|
)
|
||||||
|
success_message_plural = _(
|
||||||
|
'%(count)d trashed documents deleted.'
|
||||||
|
)
|
||||||
|
|
||||||
|
def get_extra_context(self):
|
||||||
|
queryset = self.get_object_list()
|
||||||
|
|
||||||
|
result = {
|
||||||
|
'title': ungettext(
|
||||||
|
single='Delete the selected trashed document?',
|
||||||
|
plural='Delete the selected trashed documents?',
|
||||||
|
number=queryset.count()
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
return result
|
||||||
|
|
||||||
|
def object_action(self, form, instance):
|
||||||
|
task_delete_document.apply_async(
|
||||||
|
kwargs={'trashed_document_id': instance.pk}
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
class DeletedDocumentListView(DocumentListView):
|
class TrashedDocumentListView(DocumentListView):
|
||||||
object_permission = None
|
object_permission = None
|
||||||
|
|
||||||
def get_document_queryset(self):
|
def get_document_queryset(self):
|
||||||
return AccessControlList.objects.filter_by_access(
|
return AccessControlList.objects.filter_by_access(
|
||||||
permission_document_view, self.request.user,
|
permission=permission_document_view,
|
||||||
queryset=DeletedDocument.trash.all()
|
queryset=DeletedDocument.trash.all(),
|
||||||
|
user=self.request.user
|
||||||
)
|
)
|
||||||
|
|
||||||
def get_extra_context(self):
|
def get_extra_context(self):
|
||||||
context = super(DeletedDocumentListView, self).get_extra_context()
|
context = super(TrashedDocumentListView, self).get_extra_context()
|
||||||
context.update(
|
context.update(
|
||||||
{
|
{
|
||||||
'hide_link': True,
|
'hide_link': True,
|
||||||
@@ -99,103 +135,29 @@ class DeletedDocumentListView(DocumentListView):
|
|||||||
return context
|
return context
|
||||||
|
|
||||||
|
|
||||||
class DocumentRestoreView(ConfirmView):
|
class TrashedDocumentRestoreView(MultipleObjectConfirmActionView):
|
||||||
extra_context = {
|
|
||||||
'title': _('Restore the selected document?')
|
|
||||||
}
|
|
||||||
|
|
||||||
def object_action(self, instance):
|
|
||||||
source_document = get_object_or_404(
|
|
||||||
klass=Document.passthrough, pk=instance.pk
|
|
||||||
)
|
|
||||||
|
|
||||||
AccessControlList.objects.check_access(
|
|
||||||
permissions=permission_document_restore, user=self.request.user,
|
|
||||||
obj=source_document
|
|
||||||
)
|
|
||||||
|
|
||||||
instance.restore()
|
|
||||||
|
|
||||||
def view_action(self):
|
|
||||||
instance = get_object_or_404(
|
|
||||||
klass=DeletedDocument, pk=self.kwargs['pk']
|
|
||||||
)
|
|
||||||
|
|
||||||
self.object_action(instance=instance)
|
|
||||||
|
|
||||||
messages.success(
|
|
||||||
self.request, _('Document: %(document)s restored.') % {
|
|
||||||
'document': instance
|
|
||||||
}
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
class DocumentRestoreManyView(MultipleInstanceActionMixin, DocumentRestoreView):
|
|
||||||
extra_context = {
|
|
||||||
'title': _('Restore the selected documents?')
|
|
||||||
}
|
|
||||||
model = DeletedDocument
|
model = DeletedDocument
|
||||||
success_message = '%(count)d document restored.'
|
object_permission = permission_document_restore
|
||||||
success_message_plural = '%(count)d documents restored.'
|
pk_url_kwarg = 'pk'
|
||||||
|
success_message_singular = _(
|
||||||
|
'%(count)d trashed document restored.'
|
||||||
class DocumentTrashView(ConfirmView):
|
|
||||||
def get_extra_context(self):
|
|
||||||
return {
|
|
||||||
'object': self.get_object(),
|
|
||||||
'title': _('Move "%s" to the trash?') % self.get_object()
|
|
||||||
}
|
|
||||||
|
|
||||||
def get_object(self):
|
|
||||||
return get_object_or_404(klass=Document, pk=self.kwargs['pk'])
|
|
||||||
|
|
||||||
def get_post_action_redirect(self):
|
|
||||||
return reverse('documents:document_list_recent_access')
|
|
||||||
|
|
||||||
def object_action(self, instance):
|
|
||||||
AccessControlList.objects.check_access(
|
|
||||||
permissions=permission_document_trash, user=self.request.user,
|
|
||||||
obj=instance
|
|
||||||
)
|
)
|
||||||
|
success_message_plural = _(
|
||||||
instance.delete()
|
'%(count)d trashed documents restored.'
|
||||||
|
|
||||||
def view_action(self):
|
|
||||||
instance = self.get_object()
|
|
||||||
|
|
||||||
self.object_action(instance=instance)
|
|
||||||
|
|
||||||
messages.success(
|
|
||||||
self.request, _('Document: %(document)s moved to trash successfully.') % {
|
|
||||||
'document': instance
|
|
||||||
}
|
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
class DocumentTrashManyView(MultipleInstanceActionMixin, DocumentTrashView):
|
|
||||||
model = Document
|
|
||||||
success_message = '%(count)d document moved to the trash.'
|
|
||||||
success_message_plural = '%(count)d documents moved to the trash.'
|
|
||||||
|
|
||||||
def get_extra_context(self):
|
def get_extra_context(self):
|
||||||
return {
|
queryset = self.get_object_list()
|
||||||
'title': _('Move the selected documents to the trash?')
|
|
||||||
|
result = {
|
||||||
|
'title': ungettext(
|
||||||
|
single='Restore the selected trashed document?',
|
||||||
|
plural='Restore the selected trashed documents?',
|
||||||
|
number=queryset.count()
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return result
|
||||||
|
|
||||||
class EmptyTrashCanView(ConfirmView):
|
def object_action(self, form, instance):
|
||||||
extra_context = {
|
instance.restore()
|
||||||
'title': _('Empty trash?')
|
|
||||||
}
|
|
||||||
view_permission = permission_empty_trash
|
|
||||||
action_cancel_redirect = post_action_redirect = reverse_lazy(
|
|
||||||
'documents:document_list_deleted'
|
|
||||||
)
|
|
||||||
|
|
||||||
def view_action(self):
|
|
||||||
for deleted_document in DeletedDocument.objects.all():
|
|
||||||
task_delete_document.apply_async(
|
|
||||||
kwargs={'deleted_document_id': deleted_document.pk}
|
|
||||||
)
|
|
||||||
|
|
||||||
messages.success(self.request, _('Trash emptied successfully'))
|
|
||||||
|
|||||||
@@ -42,8 +42,8 @@ class APIObjectEventListView(generics.ListAPIView):
|
|||||||
obj = self.get_object()
|
obj = self.get_object()
|
||||||
|
|
||||||
AccessControlList.objects.check_access(
|
AccessControlList.objects.check_access(
|
||||||
permissions=permission_events_view, user=self.request.user,
|
obj=obj, permissions=(permission_events_view,),
|
||||||
obj=obj
|
user=self.request.user
|
||||||
)
|
)
|
||||||
|
|
||||||
return any_stream(obj)
|
return any_stream(obj)
|
||||||
|
|||||||
@@ -113,8 +113,9 @@ class EventType(object):
|
|||||||
if result.target:
|
if result.target:
|
||||||
try:
|
try:
|
||||||
AccessControlList.objects.check_access(
|
AccessControlList.objects.check_access(
|
||||||
permissions=permission_events_view,
|
obj=result.target,
|
||||||
user=user, obj=result.target
|
permissions=(permission_events_view,),
|
||||||
|
user=user
|
||||||
)
|
)
|
||||||
except PermissionDenied:
|
except PermissionDenied:
|
||||||
pass
|
pass
|
||||||
@@ -139,8 +140,9 @@ class EventType(object):
|
|||||||
if relationship.exists():
|
if relationship.exists():
|
||||||
try:
|
try:
|
||||||
AccessControlList.objects.check_access(
|
AccessControlList.objects.check_access(
|
||||||
permissions=permission_events_view,
|
obj=result.target,
|
||||||
user=user, obj=result.target
|
permissions=(permission_events_view,),
|
||||||
|
user=user
|
||||||
)
|
)
|
||||||
except PermissionDenied:
|
except PermissionDenied:
|
||||||
pass
|
pass
|
||||||
@@ -161,8 +163,9 @@ class EventType(object):
|
|||||||
if relationship.exists():
|
if relationship.exists():
|
||||||
try:
|
try:
|
||||||
AccessControlList.objects.check_access(
|
AccessControlList.objects.check_access(
|
||||||
permissions=permission_events_view,
|
obj=result.action_object,
|
||||||
user=user, obj=result.action_object
|
permissions=(permission_events_view,),
|
||||||
|
user=user
|
||||||
)
|
)
|
||||||
except PermissionDenied:
|
except PermissionDenied:
|
||||||
pass
|
pass
|
||||||
@@ -191,7 +194,6 @@ class ModelEventType(object):
|
|||||||
Class to allow matching a model to a specific set of events.
|
Class to allow matching a model to a specific set of events.
|
||||||
"""
|
"""
|
||||||
_inheritances = {}
|
_inheritances = {}
|
||||||
_proxies = {}
|
|
||||||
_registry = {}
|
_registry = {}
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
@@ -211,11 +213,6 @@ class ModelEventType(object):
|
|||||||
if class_events:
|
if class_events:
|
||||||
events.extend(class_events)
|
events.extend(class_events)
|
||||||
|
|
||||||
proxy = cls._proxies.get(type(instance))
|
|
||||||
|
|
||||||
if proxy:
|
|
||||||
events.extend(cls._registry.get(proxy))
|
|
||||||
|
|
||||||
pks = [
|
pks = [
|
||||||
event.id for event in set(events)
|
event.id for event in set(events)
|
||||||
]
|
]
|
||||||
@@ -237,7 +234,3 @@ class ModelEventType(object):
|
|||||||
@classmethod
|
@classmethod
|
||||||
def register_inheritance(cls, model, related):
|
def register_inheritance(cls, model, related):
|
||||||
cls._inheritances[model] = related
|
cls._inheritances[model] = related
|
||||||
|
|
||||||
@classmethod
|
|
||||||
def register_proxy(cls, source, model):
|
|
||||||
cls._proxies[model] = source
|
|
||||||
|
|||||||
@@ -234,7 +234,7 @@ class ObjectEventTypeSubscriptionListView(FormView):
|
|||||||
raise Http404
|
raise Http404
|
||||||
|
|
||||||
AccessControlList.objects.check_access(
|
AccessControlList.objects.check_access(
|
||||||
obj=content_object, permissions=permission_events_view,
|
obj=content_object, permissions=(permission_events_view,),
|
||||||
user=self.request.user
|
user=self.request.user
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
@@ -35,7 +35,7 @@ class APIResolvedSmartLinkDocumentListView(generics.ListAPIView):
|
|||||||
document = get_object_or_404(klass=Document, pk=self.kwargs['pk'])
|
document = get_object_or_404(klass=Document, pk=self.kwargs['pk'])
|
||||||
|
|
||||||
AccessControlList.objects.check_access(
|
AccessControlList.objects.check_access(
|
||||||
obj=document, permissions=permission_document_view,
|
obj=document, permissions=(permission_document_view,),
|
||||||
user=self.request.user
|
user=self.request.user
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -48,7 +48,7 @@ class APIResolvedSmartLinkDocumentListView(generics.ListAPIView):
|
|||||||
)
|
)
|
||||||
|
|
||||||
AccessControlList.objects.check_access(
|
AccessControlList.objects.check_access(
|
||||||
obj=smart_link, permissions=permission_smart_link_view,
|
obj=smart_link, permissions=(permission_smart_link_view,),
|
||||||
user=self.request.user
|
user=self.request.user
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -91,7 +91,7 @@ class APIResolvedSmartLinkView(generics.RetrieveAPIView):
|
|||||||
document = get_object_or_404(klass=Document, pk=self.kwargs['pk'])
|
document = get_object_or_404(klass=Document, pk=self.kwargs['pk'])
|
||||||
|
|
||||||
AccessControlList.objects.check_access(
|
AccessControlList.objects.check_access(
|
||||||
obj=document, permissions=permission_document_view,
|
obj=document, permissions=(permission_document_view,),
|
||||||
user=self.request.user
|
user=self.request.user
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -128,7 +128,7 @@ class APIResolvedSmartLinkListView(generics.ListAPIView):
|
|||||||
document = get_object_or_404(klass=Document, pk=self.kwargs['pk'])
|
document = get_object_or_404(klass=Document, pk=self.kwargs['pk'])
|
||||||
|
|
||||||
AccessControlList.objects.check_access(
|
AccessControlList.objects.check_access(
|
||||||
obj=document, permissions=permission_document_view,
|
obj=document, permissions=(permission_document_view,),
|
||||||
user=self.request.user
|
user=self.request.user
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -187,7 +187,7 @@ class APISmartLinkConditionListView(generics.ListCreateAPIView):
|
|||||||
smart_link = get_object_or_404(klass=SmartLink, pk=self.kwargs['pk'])
|
smart_link = get_object_or_404(klass=SmartLink, pk=self.kwargs['pk'])
|
||||||
|
|
||||||
AccessControlList.objects.check_access(
|
AccessControlList.objects.check_access(
|
||||||
obj=smart_link, permissions=permission_required,
|
obj=smart_link, permissions=(permission_required,),
|
||||||
user=self.request.user
|
user=self.request.user
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -230,7 +230,7 @@ class APISmartLinkConditionView(generics.RetrieveUpdateDestroyAPIView):
|
|||||||
smart_link = get_object_or_404(klass=SmartLink, pk=self.kwargs['pk'])
|
smart_link = get_object_or_404(klass=SmartLink, pk=self.kwargs['pk'])
|
||||||
|
|
||||||
AccessControlList.objects.check_access(
|
AccessControlList.objects.check_access(
|
||||||
obj=smart_link, permissions=permission_required,
|
obj=smart_link, permissions=(permission_required,),
|
||||||
user=self.request.user
|
user=self.request.user
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
@@ -88,12 +88,12 @@ class ResolvedSmartLinkView(DocumentListView):
|
|||||||
)
|
)
|
||||||
|
|
||||||
AccessControlList.objects.check_access(
|
AccessControlList.objects.check_access(
|
||||||
obj=self.document, permissions=permission_document_view,
|
obj=self.document, permissions=(permission_document_view,),
|
||||||
user=request.user
|
user=request.user
|
||||||
)
|
)
|
||||||
|
|
||||||
AccessControlList.objects.check_access(
|
AccessControlList.objects.check_access(
|
||||||
obj=self.smart_link, permissions=permission_smart_link_view,
|
obj=self.smart_link, permissions=(permission_smart_link_view,),
|
||||||
user=request.user
|
user=request.user
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -109,8 +109,9 @@ class ResolvedSmartLinkView(DocumentListView):
|
|||||||
|
|
||||||
try:
|
try:
|
||||||
AccessControlList.objects.check_access(
|
AccessControlList.objects.check_access(
|
||||||
obj=self.smart_link, permissions=permission_smart_link_edit,
|
obj=self.smart_link,
|
||||||
user=self.request.user,
|
permissions=(permission_smart_link_edit,),
|
||||||
|
user=self.request.user
|
||||||
)
|
)
|
||||||
except PermissionDenied:
|
except PermissionDenied:
|
||||||
pass
|
pass
|
||||||
@@ -205,7 +206,7 @@ class DocumentSmartLinkListView(SmartLinkListView):
|
|||||||
self.document = get_object_or_404(klass=Document, pk=self.kwargs['pk'])
|
self.document = get_object_or_404(klass=Document, pk=self.kwargs['pk'])
|
||||||
|
|
||||||
AccessControlList.objects.check_access(
|
AccessControlList.objects.check_access(
|
||||||
obj=self.document, permissions=permission_document_view,
|
obj=self.document, permissions=(permission_document_view,),
|
||||||
user=request.user
|
user=request.user
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -319,7 +320,8 @@ class SmartLinkConditionCreateView(SingleObjectCreateView):
|
|||||||
|
|
||||||
def dispatch(self, request, *args, **kwargs):
|
def dispatch(self, request, *args, **kwargs):
|
||||||
AccessControlList.objects.check_access(
|
AccessControlList.objects.check_access(
|
||||||
obj=self.get_smart_link(), permissions=permission_smart_link_edit,
|
obj=self.get_smart_link(),
|
||||||
|
permissions=(permission_smart_link_edit,),
|
||||||
user=request.user
|
user=request.user
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -359,7 +361,7 @@ class SmartLinkConditionEditView(SingleObjectEditView):
|
|||||||
def dispatch(self, request, *args, **kwargs):
|
def dispatch(self, request, *args, **kwargs):
|
||||||
AccessControlList.objects.check_access(
|
AccessControlList.objects.check_access(
|
||||||
obj=self.get_object().smart_link,
|
obj=self.get_object().smart_link,
|
||||||
permissions=permission_smart_link_edit, user=request.user
|
permissions=(permission_smart_link_edit,), user=request.user
|
||||||
)
|
)
|
||||||
|
|
||||||
return super(
|
return super(
|
||||||
@@ -388,7 +390,7 @@ class SmartLinkConditionDeleteView(SingleObjectDeleteView):
|
|||||||
def dispatch(self, request, *args, **kwargs):
|
def dispatch(self, request, *args, **kwargs):
|
||||||
AccessControlList.objects.check_access(
|
AccessControlList.objects.check_access(
|
||||||
obj=self.get_object().smart_link,
|
obj=self.get_object().smart_link,
|
||||||
permissions=permission_smart_link_edit, user=request.user
|
permissions=(permission_smart_link_edit,), user=request.user
|
||||||
)
|
)
|
||||||
|
|
||||||
return super(
|
return super(
|
||||||
|
|||||||
@@ -85,8 +85,8 @@ class MailDocumentView(MultipleObjectFormActionView):
|
|||||||
|
|
||||||
def object_action(self, form, instance):
|
def object_action(self, form, instance):
|
||||||
AccessControlList.objects.check_access(
|
AccessControlList.objects.check_access(
|
||||||
permissions=permission_user_mailer_use, user=self.request.user,
|
obj=form.cleaned_data['user_mailer'],
|
||||||
obj=form.cleaned_data['user_mailer']
|
permissions=(permission_user_mailer_use,), user=self.request.user
|
||||||
)
|
)
|
||||||
|
|
||||||
task_send_document.apply_async(
|
task_send_document.apply_async(
|
||||||
@@ -261,8 +261,8 @@ class UserMailerTestView(FormView):
|
|||||||
def get_object(self):
|
def get_object(self):
|
||||||
user_mailer = get_object_or_404(klass=UserMailer, pk=self.kwargs['pk'])
|
user_mailer = get_object_or_404(klass=UserMailer, pk=self.kwargs['pk'])
|
||||||
AccessControlList.objects.check_access(
|
AccessControlList.objects.check_access(
|
||||||
permissions=permission_user_mailer_use, user=self.request.user,
|
obj=user_mailer, permissions=(permission_user_mailer_use,),
|
||||||
obj=user_mailer
|
user=self.request.user
|
||||||
)
|
)
|
||||||
|
|
||||||
return user_mailer
|
return user_mailer
|
||||||
|
|||||||
@@ -43,8 +43,8 @@ class APIDocumentMetadataListView(generics.ListCreateAPIView):
|
|||||||
)
|
)
|
||||||
|
|
||||||
AccessControlList.objects.check_access(
|
AccessControlList.objects.check_access(
|
||||||
permissions=permission_required, user=self.request.user,
|
obj=document, permissions=(permission_required,),
|
||||||
obj=document
|
user=self.request.user
|
||||||
)
|
)
|
||||||
|
|
||||||
return document
|
return document
|
||||||
@@ -103,8 +103,8 @@ class APIDocumentMetadataView(generics.RetrieveUpdateDestroyAPIView):
|
|||||||
)
|
)
|
||||||
|
|
||||||
AccessControlList.objects.check_access(
|
AccessControlList.objects.check_access(
|
||||||
permissions=permission_required, user=self.request.user,
|
obj=document, permissions=(permission_required,),
|
||||||
obj=document
|
user=self.request.user
|
||||||
)
|
)
|
||||||
|
|
||||||
return document
|
return document
|
||||||
@@ -175,8 +175,8 @@ class APIDocumentTypeMetadataTypeListView(generics.ListCreateAPIView):
|
|||||||
)
|
)
|
||||||
|
|
||||||
AccessControlList.objects.check_access(
|
AccessControlList.objects.check_access(
|
||||||
permissions=permission_required, user=self.request.user,
|
obj=document_type, permissions=(permission_required,),
|
||||||
obj=document_type
|
user=self.request.user
|
||||||
)
|
)
|
||||||
|
|
||||||
return document_type
|
return document_type
|
||||||
@@ -232,8 +232,8 @@ class APIDocumentTypeMetadataTypeView(generics.RetrieveUpdateDestroyAPIView):
|
|||||||
)
|
)
|
||||||
|
|
||||||
AccessControlList.objects.check_access(
|
AccessControlList.objects.check_access(
|
||||||
permissions=permission_required, user=self.request.user,
|
obj=document_type, permissions=(permission_required,),
|
||||||
obj=document_type
|
user=self.request.user
|
||||||
)
|
)
|
||||||
|
|
||||||
return document_type
|
return document_type
|
||||||
|
|||||||
@@ -397,8 +397,9 @@ class DocumentMetadataEditView(MultipleObjectFormActionView):
|
|||||||
class DocumentMetadataListView(SingleObjectListView):
|
class DocumentMetadataListView(SingleObjectListView):
|
||||||
def dispatch(self, request, *args, **kwargs):
|
def dispatch(self, request, *args, **kwargs):
|
||||||
AccessControlList.objects.check_access(
|
AccessControlList.objects.check_access(
|
||||||
permissions=permission_metadata_document_view,
|
obj=self.get_document(),
|
||||||
user=self.request.user, obj=self.get_document()
|
permissions=(permission_metadata_document_view,),
|
||||||
|
user=self.request.user
|
||||||
)
|
)
|
||||||
|
|
||||||
return super(DocumentMetadataListView, self).dispatch(
|
return super(DocumentMetadataListView, self).dispatch(
|
||||||
@@ -725,8 +726,8 @@ class SetupDocumentTypeMetadataTypes(FormView):
|
|||||||
obj = get_object_or_404(klass=self.model, pk=self.kwargs['pk'])
|
obj = get_object_or_404(klass=self.model, pk=self.kwargs['pk'])
|
||||||
|
|
||||||
AccessControlList.objects.check_access(
|
AccessControlList.objects.check_access(
|
||||||
permissions=(permission_metadata_type_edit,),
|
obj=obj, permissions=(permission_metadata_type_edit,),
|
||||||
user=self.request.user, obj=obj
|
user=self.request.user
|
||||||
)
|
)
|
||||||
return obj
|
return obj
|
||||||
|
|
||||||
|
|||||||
@@ -48,7 +48,7 @@ class Link(object):
|
|||||||
conditional_disable=None, description=None, html_data=None,
|
conditional_disable=None, description=None, html_data=None,
|
||||||
html_extra_classes=None, icon_class=None, icon_class_path=None,
|
html_extra_classes=None, icon_class=None, icon_class_path=None,
|
||||||
keep_query=False, kwargs=None, name=None, permissions=None,
|
keep_query=False, kwargs=None, name=None, permissions=None,
|
||||||
permissions_related=None, remove_from_query=None, tags=None, url=None
|
remove_from_query=None, tags=None, url=None
|
||||||
):
|
):
|
||||||
self.args = args or []
|
self.args = args or []
|
||||||
self.badge_text = badge_text
|
self.badge_text = badge_text
|
||||||
@@ -62,7 +62,6 @@ class Link(object):
|
|||||||
self.kwargs = kwargs or {}
|
self.kwargs = kwargs or {}
|
||||||
self.name = name
|
self.name = name
|
||||||
self.permissions = permissions or []
|
self.permissions = permissions or []
|
||||||
self.permissions_related = permissions_related
|
|
||||||
self.remove_from_query = remove_from_query or []
|
self.remove_from_query = remove_from_query or []
|
||||||
self.tags = tags
|
self.tags = tags
|
||||||
self.text = text
|
self.text = text
|
||||||
@@ -117,13 +116,13 @@ class Link(object):
|
|||||||
try:
|
try:
|
||||||
AccessControlList.objects.check_access(
|
AccessControlList.objects.check_access(
|
||||||
obj=resolved_object, permissions=self.permissions,
|
obj=resolved_object, permissions=self.permissions,
|
||||||
related=self.permissions_related, user=request.user
|
user=request.user
|
||||||
)
|
)
|
||||||
except PermissionDenied:
|
except PermissionDenied:
|
||||||
return None
|
return None
|
||||||
else:
|
else:
|
||||||
try:
|
try:
|
||||||
Permission.check_permissions(
|
Permission.check_user_permissions(
|
||||||
permissions=self.permissions, user=request.user
|
permissions=self.permissions, user=request.user
|
||||||
)
|
)
|
||||||
except PermissionDenied:
|
except PermissionDenied:
|
||||||
@@ -567,7 +566,7 @@ class SourceColumn(object):
|
|||||||
except KeyError:
|
except KeyError:
|
||||||
try:
|
try:
|
||||||
# Might be a subclass, try its root class
|
# Might be a subclass, try its root class
|
||||||
result.extend(cls._registry[source.__class__.__mro__[-2]])
|
result = cls._registry[source.__class__.__mro__[-2]]
|
||||||
except KeyError:
|
except KeyError:
|
||||||
try:
|
try:
|
||||||
# Might be an inherited class insance, try its source class
|
# Might be an inherited class insance, try its source class
|
||||||
|
|||||||
@@ -27,7 +27,7 @@ def get_cascade_condition(app_label, model_name, object_permission, view_permiss
|
|||||||
|
|
||||||
if view_permission:
|
if view_permission:
|
||||||
try:
|
try:
|
||||||
Permission.check_permissions(
|
Permission.check_user_permissions(
|
||||||
permissions=(view_permission,), user=context.request.user
|
permissions=(view_permission,), user=context.request.user
|
||||||
)
|
)
|
||||||
except PermissionDenied:
|
except PermissionDenied:
|
||||||
|
|||||||
@@ -73,7 +73,8 @@ class Permission(object):
|
|||||||
)
|
)
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def check_permissions(cls, permissions, user):
|
def check_user_permissions(cls, permissions, user):
|
||||||
|
# TODO: Remove list check. Add permissions arguments will be lists.
|
||||||
try:
|
try:
|
||||||
for permission in permissions:
|
for permission in permissions:
|
||||||
if permission.stored_permission.user_has_this(user=user):
|
if permission.stored_permission.user_has_this(user=user):
|
||||||
|
|||||||
@@ -26,7 +26,7 @@ class PermissionTestCase(GroupTestMixin, PermissionTestMixin, RoleTestMixin, Use
|
|||||||
|
|
||||||
def test_no_permissions(self):
|
def test_no_permissions(self):
|
||||||
with self.assertRaises(PermissionDenied):
|
with self.assertRaises(PermissionDenied):
|
||||||
Permission.check_permissions(
|
Permission.check_user_permissions(
|
||||||
permissions=(self.test_permission,), user=self.test_user
|
permissions=(self.test_permission,), user=self.test_user
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -36,7 +36,7 @@ class PermissionTestCase(GroupTestMixin, PermissionTestMixin, RoleTestMixin, Use
|
|||||||
self.test_role.groups.add(self.test_group)
|
self.test_role.groups.add(self.test_group)
|
||||||
|
|
||||||
try:
|
try:
|
||||||
Permission.check_permissions(
|
Permission.check_user_permissions(
|
||||||
permissions=(self.test_permission,), user=self.test_user
|
permissions=(self.test_permission,), user=self.test_user
|
||||||
)
|
)
|
||||||
except PermissionDenied:
|
except PermissionDenied:
|
||||||
|
|||||||
@@ -12,14 +12,14 @@ from mayan.apps.permissions import Permission
|
|||||||
|
|
||||||
class MayanPermission(BasePermission):
|
class MayanPermission(BasePermission):
|
||||||
def has_permission(self, request, view):
|
def has_permission(self, request, view):
|
||||||
required_permission = getattr(
|
required_permissions = getattr(
|
||||||
view, 'mayan_view_permissions', {}
|
view, 'mayan_view_permissions', {}
|
||||||
).get(request.method, None)
|
).get(request.method, None)
|
||||||
|
|
||||||
if required_permission:
|
if required_permissions:
|
||||||
try:
|
try:
|
||||||
Permission.check_permissions(
|
Permission.check_user_permissions(
|
||||||
permissions=required_permission, user=request.user
|
permissions=required_permissions, user=request.user
|
||||||
)
|
)
|
||||||
except PermissionDenied:
|
except PermissionDenied:
|
||||||
return False
|
return False
|
||||||
@@ -29,22 +29,15 @@ class MayanPermission(BasePermission):
|
|||||||
return True
|
return True
|
||||||
|
|
||||||
def has_object_permission(self, request, view, obj):
|
def has_object_permission(self, request, view, obj):
|
||||||
required_permission = getattr(
|
required_permissions = getattr(
|
||||||
view, 'mayan_object_permissions', {}
|
view, 'mayan_object_permissions', {}
|
||||||
).get(request.method, None)
|
).get(request.method, None)
|
||||||
|
|
||||||
if required_permission:
|
if required_permissions:
|
||||||
try:
|
try:
|
||||||
if hasattr(view, 'mayan_permission_attribute_check'):
|
|
||||||
AccessControlList.objects.check_access(
|
AccessControlList.objects.check_access(
|
||||||
permissions=required_permission,
|
obj=obj, permissions=required_permissions,
|
||||||
user=request.user, obj=obj,
|
user=request.user
|
||||||
related=view.mayan_permission_attribute_check
|
|
||||||
)
|
|
||||||
else:
|
|
||||||
AccessControlList.objects.check_access(
|
|
||||||
permissions=required_permission, user=request.user,
|
|
||||||
obj=obj
|
|
||||||
)
|
)
|
||||||
except PermissionDenied:
|
except PermissionDenied:
|
||||||
return False
|
return False
|
||||||
|
|||||||
@@ -248,7 +248,7 @@ class StagingFolderViewTestCase(GenericViewTestCase):
|
|||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
def test_staging_folder_delete_no_permission(self):
|
def test_staging_file_delete_no_permission(self):
|
||||||
staging_folder = StagingFolderSource.objects.create(
|
staging_folder = StagingFolderSource.objects.create(
|
||||||
label=TEST_SOURCE_LABEL,
|
label=TEST_SOURCE_LABEL,
|
||||||
folder_path=self.temporary_directory,
|
folder_path=self.temporary_directory,
|
||||||
@@ -263,11 +263,11 @@ class StagingFolderViewTestCase(GenericViewTestCase):
|
|||||||
response = self._request_staging_file_delete_view(
|
response = self._request_staging_file_delete_view(
|
||||||
staging_folder=staging_folder, staging_file=staging_file
|
staging_folder=staging_folder, staging_file=staging_file
|
||||||
)
|
)
|
||||||
self.assertEqual(response.status_code, 403)
|
self.assertEqual(response.status_code, 404)
|
||||||
|
|
||||||
self.assertEqual(len(list(staging_folder.get_files())), 1)
|
self.assertEqual(len(list(staging_folder.get_files())), 1)
|
||||||
|
|
||||||
def test_staging_folder_delete_with_permission(self):
|
def test_staging_file_delete_with_permission(self):
|
||||||
self.grant_permission(permission=permission_staging_file_delete)
|
self.grant_permission(permission=permission_staging_file_delete)
|
||||||
|
|
||||||
staging_folder = StagingFolderSource.objects.create(
|
staging_folder = StagingFolderSource.objects.create(
|
||||||
|
|||||||
@@ -14,12 +14,13 @@ from django.utils.translation import ugettext_lazy as _
|
|||||||
|
|
||||||
from mayan.apps.acls.models import AccessControlList
|
from mayan.apps.acls.models import AccessControlList
|
||||||
from mayan.apps.checkouts.models import NewVersionBlock
|
from mayan.apps.checkouts.models import NewVersionBlock
|
||||||
from mayan.apps.common.menus import menu_facet
|
|
||||||
from mayan.apps.common.models import SharedUploadedFile
|
|
||||||
from mayan.apps.common.generics import (
|
from mayan.apps.common.generics import (
|
||||||
ConfirmView, MultiFormView, SingleObjectCreateView,
|
ConfirmView, MultiFormView, SingleObjectCreateView,
|
||||||
SingleObjectDeleteView, SingleObjectEditView, SingleObjectListView
|
SingleObjectDeleteView, SingleObjectEditView, SingleObjectListView
|
||||||
)
|
)
|
||||||
|
from mayan.apps.common.menus import menu_facet
|
||||||
|
from mayan.apps.common.mixins import ExternalObjectMixin
|
||||||
|
from mayan.apps.common.models import SharedUploadedFile
|
||||||
from mayan.apps.documents.models import DocumentType, Document
|
from mayan.apps.documents.models import DocumentType, Document
|
||||||
from mayan.apps.documents.permissions import (
|
from mayan.apps.documents.permissions import (
|
||||||
permission_document_create, permission_document_new_version
|
permission_document_create, permission_document_new_version
|
||||||
@@ -205,7 +206,7 @@ class UploadInteractiveView(UploadBaseView):
|
|||||||
)
|
)
|
||||||
|
|
||||||
AccessControlList.objects.check_access(
|
AccessControlList.objects.check_access(
|
||||||
obj=self.document_type, permissions=permission_document_create,
|
obj=self.document_type, permissions=(permission_document_create,),
|
||||||
user=request.user
|
user=request.user
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -386,7 +387,7 @@ class UploadInteractiveVersionView(UploadBaseView):
|
|||||||
)
|
)
|
||||||
|
|
||||||
AccessControlList.objects.check_access(
|
AccessControlList.objects.check_access(
|
||||||
obj=self.document, permissions=permission_document_new_version,
|
obj=self.document, permissions=(permission_document_new_version,),
|
||||||
user=self.request.user
|
user=self.request.user
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -474,28 +475,22 @@ class UploadInteractiveVersionView(UploadBaseView):
|
|||||||
return context
|
return context
|
||||||
|
|
||||||
|
|
||||||
class StagingFileDeleteView(SingleObjectDeleteView):
|
class StagingFileDeleteView(ExternalObjectMixin, SingleObjectDeleteView):
|
||||||
object_permission = permission_staging_file_delete
|
external_object_class = StagingFolderSource
|
||||||
object_permission_related = 'staging_folder'
|
external_object_permission = permission_staging_file_delete
|
||||||
|
|
||||||
def get_extra_context(self):
|
def get_extra_context(self):
|
||||||
return {
|
return {
|
||||||
'object': self.get_object(),
|
'object': self.object,
|
||||||
'object_name': _('Staging file'),
|
'object_name': _('Staging file'),
|
||||||
'source': self.get_source(),
|
'title': _('Delete staging file "%s"?') % self.object,
|
||||||
}
|
}
|
||||||
|
|
||||||
def get_object(self):
|
def get_object(self):
|
||||||
source = self.get_source()
|
return self.external_object.get_file(
|
||||||
return source.get_file(
|
|
||||||
encoded_filename=self.kwargs['encoded_filename']
|
encoded_filename=self.kwargs['encoded_filename']
|
||||||
)
|
)
|
||||||
|
|
||||||
def get_source(self):
|
|
||||||
return get_object_or_404(
|
|
||||||
klass=StagingFolderSource, pk=self.kwargs['pk']
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
# Setup views
|
# Setup views
|
||||||
class SetupSourceCheckView(ConfirmView):
|
class SetupSourceCheckView(ConfirmView):
|
||||||
|
|||||||
@@ -89,7 +89,7 @@ class APITagDocumentListView(generics.ListAPIView):
|
|||||||
tag = get_object_or_404(klass=Tag, pk=self.kwargs['pk'])
|
tag = get_object_or_404(klass=Tag, pk=self.kwargs['pk'])
|
||||||
|
|
||||||
AccessControlList.objects.check_access(
|
AccessControlList.objects.check_access(
|
||||||
permissions=permission_tag_view, user=self.request.user, obj=tag
|
obj=tag, permissions=(permission_tag_view,), user=self.request.user
|
||||||
)
|
)
|
||||||
|
|
||||||
return tag.documents.all()
|
return tag.documents.all()
|
||||||
@@ -113,8 +113,8 @@ class APIDocumentTagListView(generics.ListCreateAPIView):
|
|||||||
document = self.get_document()
|
document = self.get_document()
|
||||||
|
|
||||||
AccessControlList.objects.check_access(
|
AccessControlList.objects.check_access(
|
||||||
permissions=permission_document_view, user=self.request.user,
|
obj=document, permissions=(permission_document_view,),
|
||||||
obj=document
|
user=self.request.user
|
||||||
)
|
)
|
||||||
|
|
||||||
return document.attached_tags().all()
|
return document.attached_tags().all()
|
||||||
@@ -165,8 +165,8 @@ class APIDocumentTagView(generics.RetrieveDestroyAPIView):
|
|||||||
document = get_object_or_404(klass=Document, pk=self.kwargs['document_pk'])
|
document = get_object_or_404(klass=Document, pk=self.kwargs['document_pk'])
|
||||||
|
|
||||||
AccessControlList.objects.check_access(
|
AccessControlList.objects.check_access(
|
||||||
permissions=permission_document_view, user=self.request.user,
|
obj=document, permissions=(permission_document_view,),
|
||||||
obj=document
|
user=self.request.user
|
||||||
)
|
)
|
||||||
return document
|
return document
|
||||||
|
|
||||||
|
|||||||
@@ -112,7 +112,7 @@ class NewDocumentTagSerializer(serializers.Serializer):
|
|||||||
|
|
||||||
try:
|
try:
|
||||||
AccessControlList.objects.check_access(
|
AccessControlList.objects.check_access(
|
||||||
obj=tag, permissions=permission_tag_attach,
|
obj=tag, permissions=(permission_tag_attach,),
|
||||||
user=self.context['request'].user
|
user=self.context['request'].user
|
||||||
)
|
)
|
||||||
except PermissionDenied:
|
except PermissionDenied:
|
||||||
|
|||||||
@@ -100,7 +100,7 @@ class TagAttachActionView(MultipleObjectFormActionView):
|
|||||||
|
|
||||||
for tag in form.cleaned_data['tags']:
|
for tag in form.cleaned_data['tags']:
|
||||||
AccessControlList.objects.check_access(
|
AccessControlList.objects.check_access(
|
||||||
obj=tag, permissions=permission_tag_attach,
|
obj=tag, permissions=(permission_tag_attach,),
|
||||||
user=self.request.user
|
user=self.request.user
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -251,7 +251,7 @@ class DocumentTagListView(TagListView):
|
|||||||
self.document = get_object_or_404(klass=Document, pk=self.kwargs['pk'])
|
self.document = get_object_or_404(klass=Document, pk=self.kwargs['pk'])
|
||||||
|
|
||||||
AccessControlList.objects.check_access(
|
AccessControlList.objects.check_access(
|
||||||
obj=self.document, permissions=permission_document_view,
|
obj=self.document, permissions=(permission_document_view,),
|
||||||
user=request.user,
|
user=request.user,
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -348,7 +348,7 @@ class TagRemoveActionView(MultipleObjectFormActionView):
|
|||||||
|
|
||||||
for tag in form.cleaned_data['tags']:
|
for tag in form.cleaned_data['tags']:
|
||||||
AccessControlList.objects.check_access(
|
AccessControlList.objects.check_access(
|
||||||
obj=tag, permissions=permission_tag_remove,
|
obj=tag, permissions=(permission_tag_remove,),
|
||||||
user=self.request.user
|
user=self.request.user
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
@@ -149,8 +149,7 @@ class APIUserGroupList(generics.ListCreateAPIView):
|
|||||||
user = get_object_or_404(klass=get_user_model(), pk=self.kwargs['pk'])
|
user = get_object_or_404(klass=get_user_model(), pk=self.kwargs['pk'])
|
||||||
|
|
||||||
AccessControlList.objects.check_access(
|
AccessControlList.objects.check_access(
|
||||||
permissions=(permission,), user=self.request.user,
|
obj=user, permissions=(permission,), user=self.request.user
|
||||||
obj=user
|
|
||||||
)
|
)
|
||||||
return user
|
return user
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user