core: refactor permissions mixins

This commit is contained in:
Antoine Bartuccio 2019-10-17 11:24:51 +02:00
parent 241650c171
commit a6088c0e4a
Signed by: klmp200
GPG Key ID: E7245548C53F904B
1 changed files with 50 additions and 62 deletions

View File

@ -140,6 +140,50 @@ def can_view(obj, user):
return can_edit(obj, user) return can_edit(obj, user)
class GenericContentPermission(View):
"""
Used to build permission mixins
This view protect any child view that would be showing an object that is restricted based
on two properties
:prop permission_function: function to test permission with, takes an object and an user an return a bool
:prop raised_error: permission to be raised
:raises: raised_error
"""
permission_function = lambda obj, user: False
raised_error = PermissionDenied
@classmethod
def get_permission_function(cls, obj, user):
return cls.permission_function(obj, user)
def dispatch(self, request, *arg, **kwargs):
if hasattr(self, "get_object") and callable(self.get_object):
self.object = self.get_object()
if not self.get_permission_function(self.object, request.user):
raise self.raised_error
return super(GenericContentPermission, self).dispatch(
request, *arg, **kwargs
)
# If we get here, it's a ListView
queryset = self.get_queryset()
l_id = [o.id for o in queryset if self.get_permission_function(o, request.user)]
if not l_id and queryset.count() != 0:
raise self.raised_error
self._get_queryset = self.get_queryset
def get_qs(self2):
return self2._get_queryset().filter(id__in=l_id)
self.get_queryset = types.MethodType(get_qs, self)
return super(GenericContentPermission, self).dispatch(request, *arg, **kwargs)
class CanCreateMixin(View): class CanCreateMixin(View):
""" """
This view is made to protect any child view that would create an object, and thus, that can not be protected by any This view is made to protect any child view that would create an object, and thus, that can not be protected by any
@ -161,7 +205,7 @@ class CanCreateMixin(View):
raise PermissionDenied raise PermissionDenied
class CanEditPropMixin(View): class CanEditPropMixin(GenericContentPermission):
""" """
This view is made to protect any child view that would be showing some properties of an object that are restricted This view is made to protect any child view that would be showing some properties of an object that are restricted
to only the owner group of the given object. to only the owner group of the given object.
@ -171,28 +215,10 @@ class CanEditPropMixin(View):
:raises: PermissionDenied :raises: PermissionDenied
""" """
def dispatch(self, request, *arg, **kwargs): permission_function = can_edit_prop
if hasattr(self, "get_object"):
self.object = self.get_object()
if not can_edit_prop(self.object, request.user):
raise PermissionDenied
return super(CanEditPropMixin, self).dispatch(request, *arg, **kwargs)
# If we get here, it's a ListView
l_id = [o.id for o in self.get_queryset() if can_edit_prop(o, request.user)]
if not l_id and self.get_queryset().count() != 0:
raise PermissionDenied
self._get_queryset = self.get_queryset
def get_qs(self2):
return self2._get_queryset().filter(id__in=l_id)
self.get_queryset = types.MethodType(get_qs, self)
return super(CanEditPropMixin, self).dispatch(request, *arg, **kwargs)
class CanEditMixin(View): class CanEditMixin(GenericContentPermission):
""" """
This view makes exactly the same thing as its direct parent, but checks the group on the edit_groups field of the This view makes exactly the same thing as its direct parent, but checks the group on the edit_groups field of the
object object
@ -200,28 +226,10 @@ class CanEditMixin(View):
:raises: PermissionDenied :raises: PermissionDenied
""" """
def dispatch(self, request, *arg, **kwargs): permission_function = can_edit
if hasattr(self, "get_object"):
self.object = self.get_object()
if not can_edit(self.object, request.user):
raise PermissionDenied
return super(CanEditMixin, self).dispatch(request, *arg, **kwargs)
# If we get here, it's a ListView
l_id = [o.id for o in self.get_queryset() if can_edit(o, request.user)]
if not l_id and self.get_queryset().count() != 0:
raise PermissionDenied
self._get_queryset = self.get_queryset
def get_qs(self2):
return self2._get_queryset().filter(id__in=l_id)
self.get_queryset = types.MethodType(get_qs, self)
return super(CanEditMixin, self).dispatch(request, *arg, **kwargs)
class CanViewMixin(View): class CanViewMixin(GenericContentPermission):
""" """
This view still makes exactly the same thing as its direct parent, but checks the group on the view_groups field of This view still makes exactly the same thing as its direct parent, but checks the group on the view_groups field of
the object the object
@ -229,27 +237,7 @@ class CanViewMixin(View):
:raises: PermissionDenied :raises: PermissionDenied
""" """
def dispatch(self, request, *arg, **kwargs): permission_function = can_view
if hasattr(self, "get_object"):
self.object = self.get_object()
if not can_view(self.object, request.user):
raise PermissionDenied
return super(CanViewMixin, self).dispatch(request, *arg, **kwargs)
# If we get here, it's a ListView
queryset = self.get_queryset()
l_id = [o.id for o in queryset if can_view(o, request.user)]
if not l_id and queryset.count() != 0:
raise PermissionDenied
self._get_queryset = self.get_queryset
def get_qs(self2):
return self2._get_queryset().filter(id__in=l_id)
self.get_queryset = types.MethodType(get_qs, self)
return super(CanViewMixin, self).dispatch(request, *arg, **kwargs)
class FormerSubscriberMixin(View): class FormerSubscriberMixin(View):