# Fixes Permission check order

* fixes bug where permissions would be checked on non-logged in users which caused errors
This commit is contained in:
mpeltriaux 2025-12-15 09:40:30 +01:00
parent 1af807deae
commit 6aad76866f
9 changed files with 34 additions and 42 deletions

View File

@ -3,7 +3,7 @@ Author: Michel Peltriaux
Created on: 14.12.25 Created on: 14.12.25
""" """
from django.http import HttpRequest from django.http import HttpRequest, HttpResponse
from django.utils.decorators import method_decorator from django.utils.decorators import method_decorator
from compensation.models import Compensation from compensation.models import Compensation
@ -16,5 +16,5 @@ class RemoveCompensationView(AbstractRemoveView):
_REDIRECT_URL = "compensation:index" _REDIRECT_URL = "compensation:index"
@method_decorator(shared_access_required(Compensation, "id")) @method_decorator(shared_access_required(Compensation, "id"))
def dispatch(self, request: HttpRequest, id: str, *args, **kwargs): def get(self, request: HttpRequest, *args, **kwargs) -> HttpResponse:
return super().dispatch(request, id, *args, **kwargs) return super().get(request, *args, **kwargs)

View File

@ -3,7 +3,7 @@ Author: Michel Peltriaux
Created on: 14.12.25 Created on: 14.12.25
""" """
from django.http import HttpRequest from django.http import HttpRequest, HttpResponse
from django.utils.decorators import method_decorator from django.utils.decorators import method_decorator
from compensation.forms.eco_account import RemoveEcoAccountModalForm from compensation.forms.eco_account import RemoveEcoAccountModalForm
@ -18,5 +18,5 @@ class RemoveEcoAccountView(AbstractRemoveView):
_FORM = RemoveEcoAccountModalForm _FORM = RemoveEcoAccountModalForm
@method_decorator(shared_access_required(EcoAccount, "id")) @method_decorator(shared_access_required(EcoAccount, "id"))
def dispatch(self, request: HttpRequest, id: str, *args, **kwargs): def get(self, request: HttpRequest, *args, **kwargs) -> HttpResponse:
return super().dispatch(request, id, *args, **kwargs) return super().get(request, *args, **kwargs)

View File

@ -114,8 +114,8 @@ class EmaIdentifierGeneratorView(AbstractIdentifierGeneratorView):
_MODEL = Ema _MODEL = Ema
@method_decorator(conservation_office_group_required) @method_decorator(conservation_office_group_required)
def dispatch(self, request, *args, **kwargs): def get(self, request: HttpRequest, *args, **kwargs) -> HttpResponse:
return super().dispatch(request, *args, **kwargs) return super().get(request, *args, **kwargs)
@login_required @login_required
@conservation_office_group_required @conservation_office_group_required

View File

@ -3,6 +3,7 @@ Author: Michel Peltriaux
Created on: 14.12.25 Created on: 14.12.25
""" """
from django.http import HttpRequest, HttpResponse
from django.utils.decorators import method_decorator from django.utils.decorators import method_decorator
from ema.models import Ema from ema.models import Ema
@ -16,5 +17,5 @@ class RemoveEmaView(AbstractRemoveView):
@method_decorator(conservation_office_group_required) @method_decorator(conservation_office_group_required)
@method_decorator(shared_access_required(Ema, "id")) @method_decorator(shared_access_required(Ema, "id"))
def dispatch(self, request, *args, **kwargs): def get(self, request: HttpRequest, *args, **kwargs) -> HttpResponse:
return super().dispatch(request, *args, **kwargs) return super().get(request, *args, **kwargs)

View File

@ -3,6 +3,7 @@ Author: Michel Peltriaux
Created on: 14.12.25 Created on: 14.12.25
""" """
from django.http import HttpRequest, HttpResponse
from django.utils.decorators import method_decorator from django.utils.decorators import method_decorator
from intervention.models import Intervention from intervention.models import Intervention
@ -15,5 +16,5 @@ class RemoveInterventionView(AbstractRemoveView):
_REDIRECT_URL = "intervention:index" _REDIRECT_URL = "intervention:index"
@method_decorator(shared_access_required(Intervention, "id")) @method_decorator(shared_access_required(Intervention, "id"))
def dispatch(self, request, *args, **kwargs): def get(self, request: HttpRequest, *args, **kwargs) -> HttpResponse:
return super().dispatch(request, *args, **kwargs) return super().get(request, *args, **kwargs)

View File

@ -3,6 +3,8 @@ Author: Michel Peltriaux
Created on: 14.12.25 Created on: 14.12.25
""" """
from abc import ABC
from django.contrib.auth.mixins import LoginRequiredMixin from django.contrib.auth.mixins import LoginRequiredMixin
from django.http import HttpRequest, HttpResponse from django.http import HttpRequest, HttpResponse
from django.utils.decorators import method_decorator 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 from konova.decorators import uuid_required, any_group_check
class AbstractDetailView(LoginRequiredMixin, View): class AbstractDetailView(LoginRequiredMixin, View, ABC):
_TEMPLATE = None _TEMPLATE = None
class Meta:
abstract = True
@method_decorator(uuid_required) @method_decorator(uuid_required)
@method_decorator(any_group_check)
def dispatch(self, request, *args, **kwargs): def dispatch(self, request, *args, **kwargs):
return super().dispatch(request, *args, **kwargs) return super().dispatch(request, *args, **kwargs)
@method_decorator(any_group_check)
def get(self, request: HttpRequest, id: str, *args, **kwargs) -> HttpResponse: def get(self, request: HttpRequest, id: str, *args, **kwargs) -> HttpResponse:
raise NotImplementedError() raise NotImplementedError()

View File

@ -3,6 +3,8 @@ Author: Michel Peltriaux
Created on: 14.12.25 Created on: 14.12.25
""" """
from abc import ABC
from django.contrib.auth.mixins import LoginRequiredMixin from django.contrib.auth.mixins import LoginRequiredMixin
from django.http import HttpRequest, JsonResponse from django.http import HttpRequest, JsonResponse
from django.utils.decorators import method_decorator from django.utils.decorators import method_decorator
@ -12,16 +14,10 @@ from konova.decorators import default_group_required
from konova.utils.generators import IdentifierGenerator from konova.utils.generators import IdentifierGenerator
class AbstractIdentifierGeneratorView(LoginRequiredMixin, View): class AbstractIdentifierGeneratorView(LoginRequiredMixin, View, ABC):
_MODEL = None _MODEL = None
class Meta:
abstract = True
@method_decorator(default_group_required) @method_decorator(default_group_required)
def dispatch(self, request, *args, **kwargs):
return super().dispatch(request, *args, **kwargs)
def get(self, request: HttpRequest, *args, **kwargs): def get(self, request: HttpRequest, *args, **kwargs):
generator = IdentifierGenerator(model=self._MODEL) generator = IdentifierGenerator(model=self._MODEL)
identifier = generator.generate_id() identifier = generator.generate_id()

View File

@ -3,6 +3,8 @@ Author: Michel Peltriaux
Created on: 14.12.25 Created on: 14.12.25
""" """
from abc import ABC
from django.contrib.auth.mixins import LoginRequiredMixin from django.contrib.auth.mixins import LoginRequiredMixin
from django.http import HttpRequest, HttpResponse from django.http import HttpRequest, HttpResponse
from django.utils.decorators import method_decorator from django.utils.decorators import method_decorator
@ -11,15 +13,9 @@ from django.views import View
from konova.decorators import any_group_check from konova.decorators import any_group_check
class AbstractIndexView(LoginRequiredMixin, View): class AbstractIndexView(LoginRequiredMixin, View, ABC):
_TEMPLATE = "generic_index.html" _TEMPLATE = "generic_index.html"
class Meta:
abstract = True
@method_decorator(any_group_check) @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: def get(self, request: HttpRequest, *args, **kwargs) -> HttpResponse:
raise NotImplementedError() raise NotImplementedError()

View File

@ -3,8 +3,10 @@ Author: Michel Peltriaux
Created on: 14.12.25 Created on: 14.12.25
""" """
from abc import ABC
from django.contrib.auth.mixins import LoginRequiredMixin 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.urls import reverse
from django.utils.decorators import method_decorator from django.utils.decorators import method_decorator
from django.views import View from django.views import View
@ -14,19 +16,16 @@ from konova.decorators import default_group_required
from konova.forms.modals import RemoveModalForm from konova.forms.modals import RemoveModalForm
class AbstractRemoveView(LoginRequiredMixin, View): class AbstractRemoveView(LoginRequiredMixin, View, ABC):
_MODEL = None _MODEL = None
_REDIRECT_URL = None _REDIRECT_URL = None
_FORM = RemoveModalForm _FORM = RemoveModalForm
class Meta:
abstract = True
@method_decorator(default_group_required)
def dispatch(self, request, *args, **kwargs): def dispatch(self, request, *args, **kwargs):
return super().dispatch(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) obj = self._MODEL.objects.get(id=id)
identifier = obj.identifier identifier = obj.identifier
form = self._FORM(request.POST or None, instance=obj, request=request) 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) 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 """ 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 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: 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 """ 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 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: Returns:
""" """
return self.__process_request(request, id) return self.__process_request(request, id, *args, **kwargs)