Implement extra permission checks and mutations on restriction mixin

This commit is contained in:
Mark Veidemanis 2023-02-10 14:32:51 +00:00
parent 72055181bc
commit 7938bffc8d
Signed by: m
GPG Key ID: 5ACFCEED46C0904F
1 changed files with 36 additions and 3 deletions

View File

@ -15,6 +15,10 @@ from core.util import logs
log = logs.get_logger(__name__) log = logs.get_logger(__name__)
class AbortSave(Exception):
pass
class RestrictedViewMixin: class RestrictedViewMixin:
""" """
This mixin overrides two helpers in order to pass the user object to the filters. This mixin overrides two helpers in order to pass the user object to the filters.
@ -33,17 +37,28 @@ class RestrictedViewMixin:
page_kwarg = "page" page_kwarg = "page"
ordering = None ordering = None
def set_extra_args(self, user):
"""
This function is overriden to filter the objects by the requesting user.
"""
self.extra_permission_args = {}
def get_queryset(self, **kwargs): def get_queryset(self, **kwargs):
""" """
This function is overriden to filter the objects by the requesting user. This function is overriden to filter the objects by the requesting user.
""" """
self.set_extra_args(self.request.user)
if self.queryset is not None: if self.queryset is not None:
queryset = self.queryset queryset = self.queryset
if isinstance(queryset, QuerySet): if isinstance(queryset, QuerySet):
# queryset = queryset.all() # queryset = queryset.all()
queryset = queryset.filter(user=self.request.user) queryset = queryset.filter(
user=self.request.user, **self.extra_permission_args
)
elif self.model is not None: elif self.model is not None:
queryset = self.model._default_manager.filter(user=self.request.user) queryset = self.model._default_manager.filter(
user=self.request.user, **self.extra_permission_args
)
else: else:
raise ImproperlyConfigured( raise ImproperlyConfigured(
"%(cls)s is missing a QuerySet. Define " "%(cls)s is missing a QuerySet. Define "
@ -99,6 +114,7 @@ class ObjectList(RestrictedViewMixin, ObjectNameMixin, ListView):
list_url_args = ["type"] list_url_args = ["type"]
submit_url_name = None submit_url_name = None
submit_url_args = ["type"]
delete_all_url_name = None delete_all_url_name = None
widget_options = None widget_options = None
@ -146,6 +162,13 @@ class ObjectList(RestrictedViewMixin, ObjectNameMixin, ListView):
if is_empty: if is_empty:
raise Http404("Empty list") raise Http404("Empty list")
submit_url_args = {}
for arg in self.submit_url_args:
if arg in locals():
submit_url_args[arg] = locals()[arg]
elif arg in kwargs:
submit_url_args[arg] = kwargs[arg]
context = self.get_context_data() context = self.get_context_data()
context["title"] = self.title + f" ({type})" context["title"] = self.title + f" ({type})"
context["title_singular"] = self.title_singular context["title_singular"] = self.title_singular
@ -159,7 +182,9 @@ class ObjectList(RestrictedViewMixin, ObjectNameMixin, ListView):
context["context_object_name_singular"] = self.context_object_name_singular context["context_object_name_singular"] = self.context_object_name_singular
if self.submit_url_name is not None: if self.submit_url_name is not None:
context["submit_url"] = reverse(self.submit_url_name, kwargs={"type": type}) context["submit_url"] = reverse(
self.submit_url_name, kwargs=submit_url_args
)
if self.list_url_name is not None: if self.list_url_name is not None:
context["list_url"] = reverse(self.list_url_name, kwargs=list_url_args) context["list_url"] = reverse(self.list_url_name, kwargs=list_url_args)
@ -204,11 +229,19 @@ class ObjectCreate(RestrictedViewMixin, ObjectNameMixin, CreateView):
def post_save(self, obj): def post_save(self, obj):
pass pass
def pre_save_mutate(self, user, obj):
pass
def form_valid(self, form): def form_valid(self, form):
obj = form.save(commit=False) obj = form.save(commit=False)
if self.request is None: if self.request is None:
raise Exception("Request is None") raise Exception("Request is None")
obj.user = self.request.user obj.user = self.request.user
try:
self.pre_save_mutate(self.request.user, obj)
except AbortSave as e:
context = {"message": f"Failed to save: {e}", "class": "danger"}
return self.render_to_response(context)
obj.save() obj.save()
form.save_m2m() form.save_m2m()
self.post_save(obj) self.post_save(obj)