From 6aad76866fc6e4d10cf6ee8ca6faee74b66221f6 Mon Sep 17 00:00:00 2001 From: mpeltriaux Date: Mon, 15 Dec 2025 09:40:30 +0100 Subject: [PATCH] # Fixes Permission check order * fixes bug where permissions would be checked on non-logged in users which caused errors --- compensation/views/compensation/remove.py | 6 +++--- compensation/views/eco_account/remove.py | 6 +++--- ema/views/ema.py | 4 ++-- ema/views/remove.py | 5 +++-- intervention/views/remove.py | 5 +++-- konova/views/detail.py | 9 ++++----- konova/views/identifier.py | 10 +++------- konova/views/index.py | 10 +++------- konova/views/remove.py | 21 ++++++++++----------- 9 files changed, 34 insertions(+), 42 deletions(-) diff --git a/compensation/views/compensation/remove.py b/compensation/views/compensation/remove.py index bced8af8..a073d089 100644 --- a/compensation/views/compensation/remove.py +++ b/compensation/views/compensation/remove.py @@ -3,7 +3,7 @@ Author: Michel Peltriaux Created on: 14.12.25 """ -from django.http import HttpRequest +from django.http import HttpRequest, HttpResponse from django.utils.decorators import method_decorator from compensation.models import Compensation @@ -16,5 +16,5 @@ class RemoveCompensationView(AbstractRemoveView): _REDIRECT_URL = "compensation:index" @method_decorator(shared_access_required(Compensation, "id")) - def dispatch(self, request: HttpRequest, id: str, *args, **kwargs): - return super().dispatch(request, id, *args, **kwargs) + def get(self, request: HttpRequest, *args, **kwargs) -> HttpResponse: + return super().get(request, *args, **kwargs) diff --git a/compensation/views/eco_account/remove.py b/compensation/views/eco_account/remove.py index 834a076d..b1ab0334 100644 --- a/compensation/views/eco_account/remove.py +++ b/compensation/views/eco_account/remove.py @@ -3,7 +3,7 @@ Author: Michel Peltriaux Created on: 14.12.25 """ -from django.http import HttpRequest +from django.http import HttpRequest, HttpResponse from django.utils.decorators import method_decorator from compensation.forms.eco_account import RemoveEcoAccountModalForm @@ -18,5 +18,5 @@ class RemoveEcoAccountView(AbstractRemoveView): _FORM = RemoveEcoAccountModalForm @method_decorator(shared_access_required(EcoAccount, "id")) - def dispatch(self, request: HttpRequest, id: str, *args, **kwargs): - return super().dispatch(request, id, *args, **kwargs) + def get(self, request: HttpRequest, *args, **kwargs) -> HttpResponse: + return super().get(request, *args, **kwargs) diff --git a/ema/views/ema.py b/ema/views/ema.py index 8fed05ea..0d949727 100644 --- a/ema/views/ema.py +++ b/ema/views/ema.py @@ -114,8 +114,8 @@ class EmaIdentifierGeneratorView(AbstractIdentifierGeneratorView): _MODEL = Ema @method_decorator(conservation_office_group_required) - def dispatch(self, request, *args, **kwargs): - return super().dispatch(request, *args, **kwargs) + def get(self, request: HttpRequest, *args, **kwargs) -> HttpResponse: + return super().get(request, *args, **kwargs) @login_required @conservation_office_group_required diff --git a/ema/views/remove.py b/ema/views/remove.py index 9e3b3507..07abfae8 100644 --- a/ema/views/remove.py +++ b/ema/views/remove.py @@ -3,6 +3,7 @@ Author: Michel Peltriaux Created on: 14.12.25 """ +from django.http import HttpRequest, HttpResponse from django.utils.decorators import method_decorator from ema.models import Ema @@ -16,5 +17,5 @@ class RemoveEmaView(AbstractRemoveView): @method_decorator(conservation_office_group_required) @method_decorator(shared_access_required(Ema, "id")) - def dispatch(self, request, *args, **kwargs): - return super().dispatch(request, *args, **kwargs) + def get(self, request: HttpRequest, *args, **kwargs) -> HttpResponse: + return super().get(request, *args, **kwargs) diff --git a/intervention/views/remove.py b/intervention/views/remove.py index 10b6ae7f..defe8730 100644 --- a/intervention/views/remove.py +++ b/intervention/views/remove.py @@ -3,6 +3,7 @@ Author: Michel Peltriaux Created on: 14.12.25 """ +from django.http import HttpRequest, HttpResponse from django.utils.decorators import method_decorator from intervention.models import Intervention @@ -15,5 +16,5 @@ class RemoveInterventionView(AbstractRemoveView): _REDIRECT_URL = "intervention:index" @method_decorator(shared_access_required(Intervention, "id")) - def dispatch(self, request, *args, **kwargs): - return super().dispatch(request, *args, **kwargs) + def get(self, request: HttpRequest, *args, **kwargs) -> HttpResponse: + return super().get(request, *args, **kwargs) diff --git a/konova/views/detail.py b/konova/views/detail.py index 8b36296f..49e0156c 100644 --- a/konova/views/detail.py +++ b/konova/views/detail.py @@ -3,6 +3,8 @@ Author: Michel Peltriaux Created on: 14.12.25 """ +from abc import ABC + from django.contrib.auth.mixins import LoginRequiredMixin from django.http import HttpRequest, HttpResponse from django.utils.decorators import method_decorator @@ -11,16 +13,13 @@ from django.views import View from konova.decorators import uuid_required, any_group_check -class AbstractDetailView(LoginRequiredMixin, View): +class AbstractDetailView(LoginRequiredMixin, View, ABC): _TEMPLATE = None - class Meta: - abstract = True - @method_decorator(uuid_required) - @method_decorator(any_group_check) def dispatch(self, request, *args, **kwargs): return super().dispatch(request, *args, **kwargs) + @method_decorator(any_group_check) def get(self, request: HttpRequest, id: str, *args, **kwargs) -> HttpResponse: raise NotImplementedError() diff --git a/konova/views/identifier.py b/konova/views/identifier.py index b5fdd4be..ddacbd3f 100644 --- a/konova/views/identifier.py +++ b/konova/views/identifier.py @@ -3,6 +3,8 @@ Author: Michel Peltriaux Created on: 14.12.25 """ +from abc import ABC + from django.contrib.auth.mixins import LoginRequiredMixin from django.http import HttpRequest, JsonResponse from django.utils.decorators import method_decorator @@ -12,16 +14,10 @@ from konova.decorators import default_group_required from konova.utils.generators import IdentifierGenerator -class AbstractIdentifierGeneratorView(LoginRequiredMixin, View): +class AbstractIdentifierGeneratorView(LoginRequiredMixin, View, ABC): _MODEL = None - class Meta: - abstract = True - @method_decorator(default_group_required) - def dispatch(self, request, *args, **kwargs): - return super().dispatch(request, *args, **kwargs) - def get(self, request: HttpRequest, *args, **kwargs): generator = IdentifierGenerator(model=self._MODEL) identifier = generator.generate_id() diff --git a/konova/views/index.py b/konova/views/index.py index 65a28656..228c019a 100644 --- a/konova/views/index.py +++ b/konova/views/index.py @@ -3,6 +3,8 @@ Author: Michel Peltriaux Created on: 14.12.25 """ +from abc import ABC + from django.contrib.auth.mixins import LoginRequiredMixin from django.http import HttpRequest, HttpResponse from django.utils.decorators import method_decorator @@ -11,15 +13,9 @@ from django.views import View from konova.decorators import any_group_check -class AbstractIndexView(LoginRequiredMixin, View): +class AbstractIndexView(LoginRequiredMixin, View, ABC): _TEMPLATE = "generic_index.html" - class Meta: - abstract = True - @method_decorator(any_group_check) - def dispatch(self, request, *args, **kwargs): - return super().dispatch(request, *args, **kwargs) - def get(self, request: HttpRequest, *args, **kwargs) -> HttpResponse: raise NotImplementedError() diff --git a/konova/views/remove.py b/konova/views/remove.py index 7117d9cd..24093677 100644 --- a/konova/views/remove.py +++ b/konova/views/remove.py @@ -3,8 +3,10 @@ Author: Michel Peltriaux Created on: 14.12.25 """ +from abc import ABC + from django.contrib.auth.mixins import LoginRequiredMixin -from django.http import HttpRequest +from django.http import HttpRequest, HttpResponse from django.urls import reverse from django.utils.decorators import method_decorator from django.views import View @@ -14,19 +16,16 @@ from konova.decorators import default_group_required from konova.forms.modals import RemoveModalForm -class AbstractRemoveView(LoginRequiredMixin, View): +class AbstractRemoveView(LoginRequiredMixin, View, ABC): _MODEL = None _REDIRECT_URL = None _FORM = RemoveModalForm - class Meta: - abstract = True - - @method_decorator(default_group_required) def dispatch(self, request, *args, **kwargs): return super().dispatch(request, *args, **kwargs) - def __process_request(self, request: HttpRequest, id: str): + @method_decorator(default_group_required) + def __process_request(self, request: HttpRequest, id: str, *args, **kwargs) -> HttpResponse: obj = self._MODEL.objects.get(id=id) identifier = obj.identifier form = self._FORM(request.POST or None, instance=obj, request=request) @@ -36,7 +35,7 @@ class AbstractRemoveView(LoginRequiredMixin, View): redirect_url=reverse(self._REDIRECT_URL) ) - def get(self, request: HttpRequest, id: str): + def get(self, request: HttpRequest, id: str, *args, **kwargs) -> HttpResponse: """ GET endpoint for removing via modal form Due to the legacy logic of the form (which processes get and post requests directly), we simply need to pipe @@ -48,9 +47,9 @@ class AbstractRemoveView(LoginRequiredMixin, View): Returns: """ - return self.__process_request(request, id) + return self.__process_request(request, id, *args, **kwargs) - def post(self, request: HttpRequest, id: str): + def post(self, request: HttpRequest, id: str, *args, **kwargs) -> HttpResponse: """ POST endpoint for removing via modal form Due to the legacy logic of the form (which processes get and post requests directly), we simply need to pipe @@ -62,4 +61,4 @@ class AbstractRemoveView(LoginRequiredMixin, View): Returns: """ - return self.__process_request(request, id) + return self.__process_request(request, id, *args, **kwargs)