From 3c9454160f6641961a2bedc8486544300b0aaca5 Mon Sep 17 00:00:00 2001 From: Roberto Rosario Date: Tue, 30 Jul 2019 03:07:17 -0400 Subject: [PATCH] Support custom model managers for check_access() Allow app to specify which model manager will be used when creating the queryset that is passed to check_access. Signed-off-by: Roberto Rosario --- mayan/apps/acls/classes.py | 9 +++++++ mayan/apps/acls/managers.py | 39 +++++++++++++++++++------------ mayan/apps/documents/api_views.py | 2 +- 3 files changed, 34 insertions(+), 16 deletions(-) diff --git a/mayan/apps/acls/classes.py b/mayan/apps/acls/classes.py index 1c06e0d05e..5ba83b893f 100644 --- a/mayan/apps/acls/classes.py +++ b/mayan/apps/acls/classes.py @@ -12,6 +12,7 @@ logger = logging.getLogger(__name__) class ModelPermission(object): _functions = {} _inheritances = {} + _manager_names = {} _registry = {} @classmethod @@ -97,6 +98,10 @@ class ModelPermission(object): def get_inheritance(cls, model): return cls._inheritances[model] + @classmethod + def get_manager_name(cls, model): + return cls._manager_names[model] + @classmethod def register_function(cls, model, function): cls._functions[model] = function @@ -104,3 +109,7 @@ class ModelPermission(object): @classmethod def register_inheritance(cls, model, related): cls._inheritances[model] = related + + @classmethod + def register_manager(cls, model, manager_name): + cls._manager_names[model] = manager_name diff --git a/mayan/apps/acls/managers.py b/mayan/apps/acls/managers.py index 2bc9f457ff..1ff252f0ff 100644 --- a/mayan/apps/acls/managers.py +++ b/mayan/apps/acls/managers.py @@ -200,28 +200,37 @@ class AccessControlListManager(models.Manager): return result - def check_access(self, obj, permissions, user, manager=None): + def check_access(self, obj, permissions, user): # Allow specific managers for models that have more than one # for example the Document model when checking for access for a trashed # document. - if manager: - source_queryset = manager.all() + 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: - 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) + try: + manager_name = ModelPermission.get_manager_name( + model=meta.model ) - return True - else: - source_queryset = obj._meta.default_manager.all() + except KeyError: + manager_name = None - restricted_queryset = obj._meta.default_manager.none() + if manager_name: + manager = getattr(obj._meta.model, manager_name) + else: + manager = obj._meta.default_manager + + source_queryset = manager.all() + + restricted_queryset = manager.none() for permission in permissions: # Default relationship betweens permissions is OR # TODO: Add support for AND relationship diff --git a/mayan/apps/documents/api_views.py b/mayan/apps/documents/api_views.py index f80f5ec67d..443a1a38b6 100644 --- a/mayan/apps/documents/api_views.py +++ b/mayan/apps/documents/api_views.py @@ -164,7 +164,7 @@ class APIDocumentPageImageView(generics.RetrieveAPIView): AccessControlList.objects.check_access( obj=document, permissions=(permission_required,), - user=self.request.user, manager=Document.passthrough + user=self.request.user ) return document