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 <roberto.rosario@mayan-edms.com>
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
Reference in New Issue
Block a user