mirror of
https://gitlab2.federez.net/re2o/re2o
synced 2024-12-23 15:33:45 +00:00
Add can_list acl, move views autocomplete mixins to re2o/views.py
This commit is contained in:
parent
db75f797c5
commit
5011694479
7 changed files with 63 additions and 13 deletions
|
@ -37,7 +37,7 @@ from .models import (
|
||||||
Banque
|
Banque
|
||||||
)
|
)
|
||||||
|
|
||||||
from re2o.mixins import AutocompleteViewMixin
|
from re2o.views import AutocompleteViewMixin
|
||||||
|
|
||||||
from re2o.acl import (
|
from re2o.acl import (
|
||||||
can_view_all,
|
can_view_all,
|
||||||
|
|
|
@ -369,6 +369,15 @@ def can_view_all(*targets):
|
||||||
return acl_base_decorator("can_view_all", *targets, on_instance=False)
|
return acl_base_decorator("can_view_all", *targets, on_instance=False)
|
||||||
|
|
||||||
|
|
||||||
|
def can_list(*targets):
|
||||||
|
"""Decorator to check if an user can list a class of model.
|
||||||
|
It runs `acl_base_decorator` with the flag `on_instance=False` and the
|
||||||
|
method 'can_list'. See `acl_base_decorator` documentation for further
|
||||||
|
details.
|
||||||
|
"""
|
||||||
|
return acl_base_decorator("can_list", *targets, on_instance=False)
|
||||||
|
|
||||||
|
|
||||||
def can_view_app(*apps_name):
|
def can_view_app(*apps_name):
|
||||||
"""Decorator to check if an user can view the applications."""
|
"""Decorator to check if an user can view the applications."""
|
||||||
for app_name in apps_name:
|
for app_name in apps_name:
|
||||||
|
|
|
@ -29,6 +29,7 @@ from django.utils.translation import ugettext as _
|
||||||
from dal import autocomplete
|
from dal import autocomplete
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class RevMixin(object):
|
class RevMixin(object):
|
||||||
"""A mixin to subclass the save and delete function of a model
|
"""A mixin to subclass the save and delete function of a model
|
||||||
to enforce the versioning of the object before those actions
|
to enforce the versioning of the object before those actions
|
||||||
|
@ -80,6 +81,8 @@ class AclMixin(object):
|
||||||
:can_view: Applied on an instance, return if the user can view the
|
:can_view: Applied on an instance, return if the user can view the
|
||||||
instance
|
instance
|
||||||
:can_view_all: Applied on a class, return if the user can view all
|
:can_view_all: Applied on a class, return if the user can view all
|
||||||
|
instances
|
||||||
|
:can_list: Applied on a class, return if the user can list all
|
||||||
instances"""
|
instances"""
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
|
@ -209,6 +212,28 @@ class AclMixin(object):
|
||||||
(permission,),
|
(permission,),
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def can_list(cls, user_request, *_args, **_kwargs):
|
||||||
|
"""Check if a user can list all instances of an object
|
||||||
|
|
||||||
|
Parameters:
|
||||||
|
user_request: User calling for this action
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
Boolean: True if user_request has the right access to do it, else
|
||||||
|
false with reason for reject authorization
|
||||||
|
"""
|
||||||
|
permission = cls.get_modulename() + ".view_" + cls.get_classname()
|
||||||
|
can = user_request.has_perm(permission)
|
||||||
|
return (
|
||||||
|
can,
|
||||||
|
_("You don't have the right to list every %s object.") % cls.get_classname()
|
||||||
|
if not can
|
||||||
|
else None,
|
||||||
|
(permission,),
|
||||||
|
cls.objects.all() if can else None,
|
||||||
|
)
|
||||||
|
|
||||||
def can_view(self, user_request, *_args, **_kwargs):
|
def can_view(self, user_request, *_args, **_kwargs):
|
||||||
"""Check if a user can view an instance of an object
|
"""Check if a user can view an instance of an object
|
||||||
|
|
||||||
|
@ -272,13 +297,3 @@ class AutocompleteMultipleModelMixin(autocomplete.ModelSelect2Multiple):
|
||||||
attrs["data-minimum-results-for-search"] = attrs.get("data-minimum-results-for-search", 10)
|
attrs["data-minimum-results-for-search"] = attrs.get("data-minimum-results-for-search", 10)
|
||||||
return attrs
|
return attrs
|
||||||
|
|
||||||
|
|
||||||
class AutocompleteViewMixin(autocomplete.Select2QuerySetView):
|
|
||||||
obj_type = None # This MUST be overridden by child class
|
|
||||||
query_filter = "name__icontains" # Override this if necessary
|
|
||||||
|
|
||||||
def get_queryset(self):
|
|
||||||
query_set = self.obj_type.objects.all()
|
|
||||||
if self.q:
|
|
||||||
query_set = query_set.filter(**{ self.query_filter: self.q})
|
|
||||||
return query_set
|
|
||||||
|
|
|
@ -141,6 +141,8 @@ def get_callback(tag_name, obj=None):
|
||||||
return acl_fct(obj.can_view_all, False)
|
return acl_fct(obj.can_view_all, False)
|
||||||
if tag_name == "cannot_view_all":
|
if tag_name == "cannot_view_all":
|
||||||
return acl_fct(obj.can_view_all, True)
|
return acl_fct(obj.can_view_all, True)
|
||||||
|
if tag_name == "can_list":
|
||||||
|
return acl_fct(obj.can_list, False)
|
||||||
if tag_name == "can_view_app":
|
if tag_name == "can_view_app":
|
||||||
return acl_fct(
|
return acl_fct(
|
||||||
lambda x: (
|
lambda x: (
|
||||||
|
@ -296,6 +298,7 @@ def acl_change_filter(parser, token):
|
||||||
@register.tag("cannot_delete_all")
|
@register.tag("cannot_delete_all")
|
||||||
@register.tag("can_view_all")
|
@register.tag("can_view_all")
|
||||||
@register.tag("cannot_view_all")
|
@register.tag("cannot_view_all")
|
||||||
|
@register.tag("can_list")
|
||||||
def acl_model_filter(parser, token):
|
def acl_model_filter(parser, token):
|
||||||
"""Generic definition of an acl templatetag for acl based on model"""
|
"""Generic definition of an acl templatetag for acl based on model"""
|
||||||
|
|
||||||
|
|
|
@ -33,6 +33,10 @@ from django.template.context_processors import csrf
|
||||||
from django.conf import settings
|
from django.conf import settings
|
||||||
from django.utils.translation import ugettext as _
|
from django.utils.translation import ugettext as _
|
||||||
from django.views.decorators.cache import cache_page
|
from django.views.decorators.cache import cache_page
|
||||||
|
from django.contrib.auth.decorators import login_required
|
||||||
|
from django.contrib.auth.mixins import LoginRequiredMixin
|
||||||
|
from django.utils.decorators import method_decorator
|
||||||
|
from dal import autocomplete
|
||||||
|
|
||||||
from preferences.models import (
|
from preferences.models import (
|
||||||
Service,
|
Service,
|
||||||
|
@ -43,6 +47,7 @@ from preferences.models import (
|
||||||
Mandate,
|
Mandate,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
from .acl import can_list
|
||||||
from .contributors import CONTRIBUTORS
|
from .contributors import CONTRIBUTORS
|
||||||
from importlib import import_module
|
from importlib import import_module
|
||||||
from re2o.settings_local import OPTIONNAL_APPS_RE2O
|
from re2o.settings_local import OPTIONNAL_APPS_RE2O
|
||||||
|
@ -169,3 +174,21 @@ def handler500(request):
|
||||||
def handler404(request):
|
def handler404(request):
|
||||||
"""The handler view for a 404 error"""
|
"""The handler view for a 404 error"""
|
||||||
return render(request, "errors/404.html", status=404)
|
return render(request, "errors/404.html", status=404)
|
||||||
|
|
||||||
|
|
||||||
|
class AutocompleteViewMixin(LoginRequiredMixin, autocomplete.Select2QuerySetView):
|
||||||
|
obj_type = None # This MUST be overridden by child class
|
||||||
|
query_set = None
|
||||||
|
query_filter = "name__icontains" # Override this if necessary
|
||||||
|
|
||||||
|
def get_queryset(self):
|
||||||
|
|
||||||
|
can, reason, _permission, query_set = self.obj_type.can_list(self.request.user)
|
||||||
|
|
||||||
|
self.query_set = query_set
|
||||||
|
if hasattr(self, "filter_results"):
|
||||||
|
self.filter_results()
|
||||||
|
else:
|
||||||
|
if self.q:
|
||||||
|
self.query_set = self.query_set.filter(**{ self.query_filter: self.q})
|
||||||
|
return self.query_set
|
||||||
|
|
|
@ -44,7 +44,7 @@ from .models import (
|
||||||
SwitchBay,
|
SwitchBay,
|
||||||
)
|
)
|
||||||
|
|
||||||
from re2o.mixins import AutocompleteViewMixin
|
from re2o.views import AutocompleteViewMixin
|
||||||
|
|
||||||
from re2o.acl import (
|
from re2o.acl import (
|
||||||
can_view_all,
|
can_view_all,
|
||||||
|
|
|
@ -45,7 +45,7 @@ from .models import (
|
||||||
EMailAddress,
|
EMailAddress,
|
||||||
)
|
)
|
||||||
|
|
||||||
from re2o.mixins import AutocompleteViewMixin
|
from re2o.views import AutocompleteViewMixin
|
||||||
|
|
||||||
from re2o.acl import (
|
from re2o.acl import (
|
||||||
can_view_all,
|
can_view_all,
|
||||||
|
|
Loading…
Reference in a new issue