Commit 00129cb0 authored by Hamza Dely's avatar Hamza Dely

[consos/views] Remplace certains tests de droits par un décorateur

parent a42e081f
......@@ -316,6 +316,7 @@ class NoteViewSet(viewsets.GenericViewSet):
filter_backends = (filters.SearchFilter,)
search_fields = ('$alias',)
@requires("comptes.adherent_chercher", Acl.BASIQUE)
def list(self, request):
"""
Renvoie la liste de toutes les notes actives
......@@ -324,9 +325,6 @@ class NoteViewSet(viewsets.GenericViewSet):
- contenir un paramètre 'search' contenant une expression régulière
à rechercher
"""
if not request.user.has_perm("comptes.adherent_chercher", Acl.BASIQUE):
return Response({}, status=status.HTTP_403_FORBIDDEN)
lookup_args = {}
if not request.user.has_perm("comptes.adherent_chercher", Acl.TOTAL):
lookup_args.update(**{'adherent__supprime' : False})
......@@ -355,15 +353,13 @@ class NoteViewSet(viewsets.GenericViewSet):
serializer = self.get_serializer(data, fields=fields, many=True)
return Response(serializer.data, status=status.HTTP_200_OK)
@requires("comptes.adherent_detail")
def retrieve(self, request, pk=None):
"""
Renvoie les informations sur la note demandée
Les données doivent :
- être envoyées via une requête GET
"""
if not request.user.has_perm("comptes.adherent_detail", Acl.LIMITE):
return Response({}, status=status.HTTP_403_FORBIDDEN)
note = self.get_object()
if (request.user != note.adherent
and not request.user.has_perm("comptes.adherent_detail", Acl.BASIQUE)):
......@@ -378,6 +374,7 @@ class NoteViewSet(viewsets.GenericViewSet):
serializer = self.get_serializer(note, fields=fields)
return Response(serializer.data, status=status.HTTP_200_OK)
@requires("consos.note_ouvrir", Acl.BASIQUE)
def create(self, request):
"""
Ouvre la note d'un adhérent donné
......@@ -386,15 +383,13 @@ class NoteViewSet(viewsets.GenericViewSet):
- contenir un paramètre 'adherent' contenant l'identifiant de l'adhérent
dont il faut ouvrir la note
"""
if not request.user.has_perm("consos.note_ouvrir", Acl.BASIQUE):
return Response({}, status=status.HTTP_403_FORBIDDEN)
serializer = self.get_serializer(data=request.data, fields=['adherent'])
serializer.is_valid(raise_exception=True)
serializer.save()
return Response({}, status=status.HTTP_201_CREATED)
@detail_route(methods=['patch'])
@requires("consos.note_soft_lock")
def protect(self, request, pk=None):
"""
Protège une note, i.e. empêche qu'une transaction ne puisse être effectuée dessus
......@@ -430,6 +425,7 @@ class NoteViewSet(viewsets.GenericViewSet):
return Response({}, status=status.HTTP_200_OK)
@detail_route(methods=['patch'])
@requires("consos.note_hard_lock", Acl.BASIQUE)
def block(self, request, pk=None):
"""
Bloque une note, i.e. empêche que la note ne puisse être utilisée.
......@@ -506,15 +502,13 @@ class BoutonViewSet(viewsets.GenericViewSet):
serializer = self.get_serializer(qs, many=True)
return Response(serializer.data, status=status.HTTP_200_OK)
@requires("consos.bouton_ajouter")
def create(self, request):
"""
Ajoute un nouveau bouton dans la base de données
Les données doivent :
- être envoyées via une requête POST
"""
if not request.user.has_perm("consos.bouton_ajouter"):
return Response({}, status=status.HTTP_403_FORBIDDEN)
serializer = self.get_serializer(data=request.data)
serializer.is_valid(raise_exception=True)
note_id = serializer.validated_data['credite']
......@@ -543,13 +537,11 @@ class BoutonViewSet(viewsets.GenericViewSet):
serializer.save()
return Response({}, status=status.HTTP_201_CREATED)
@requires("consos.bouton_modifer")
def partial_update(self, request, pk=None):
"""
Modifie un bouton existant
"""
if not request.user.has_perm("consos.bouton_modifier"):
return Response({}, status=status.HTTP_403_FORBIDDEN)
bouton = self.get_object()
serializer = self.get_serializer(bouton, data=request.data, partial=True)
serializer.is_valid(raise_exception=True)
......@@ -560,13 +552,11 @@ class BoutonViewSet(viewsets.GenericViewSet):
serializer.save()
@detail_route(methods=['patch'])
@requires("consos.bouton_activer")
def activate(self, request, pk=None):
"""
Active ou désactive un bouton
"""
if not request.user.has_perm("consos.bouton_activer"):
return Response({},status=status.HTTP_403_FORBIDDEN)
activate = to_bool(request.query_params.get('activate', None))
if activate is None:
return Response({"detail" : "Paramètre 'activate' incorrect"}, status=status.HTTP_400_BAD_REQUEST)
......@@ -576,13 +566,11 @@ class BoutonViewSet(viewsets.GenericViewSet):
bouton.save()
return Response({}, status=status.HTTP_200_OK)
@requires("consos.bouton_supprimer")
def destroy(self, request, pk=None):
"""
Supprime un bouton existant
"""
if not request.user.has_perm("consos.bouton_supprimer"):
return Response({}, status=status.HTTP_403_FORBIDDEN)
bouton = self.get_object()
if bouton.credite != request.user and not request.user.has_perm("consos.bouton_supprimer", Acl.BASIQUE):
return Response({"detail" : "Vous ne pouvez supprimer que des boutons liés à vôtre note"}, status=status.HTTP_403_FORBIDDEN)
......@@ -598,13 +586,11 @@ class TransactionViewSet(viewsets.GenericViewSet):
filter_backends = (DjangoFilterBackend,)
filter_fields = ('id', 'valide',)
@requires("consos.transaction_effectuer")
def list(self, request):
"""
Renvoie la liste des transactions existantes
"""
if not request.user.has_perm("consos.transaction_effectuer"):
return Response({}, status=status.HTTP_403_FORBIDDEN)
qs = self.get_queryset()
if not request.user.has_perm("consos.transaction_effectuer", Acl.TOTAL):
qs = qs.filter(Q(emetteur=request.user) | Q(destinataire=request.user))
......@@ -612,6 +598,7 @@ class TransactionViewSet(viewsets.GenericViewSet):
serializer = self.get_serializer(qs, many=True)
return Response(serializer.data, status=status.HTTP_200_OK)
@requires("consos.transaction_effectuer")
def create(self, request):
"""
Effectue une ou plusieurs nouvelles transactions.
......@@ -623,9 +610,6 @@ class TransactionViewSet(viewsets.GenericViewSet):
contenir une liste d'identifiants de note dans le paramètre 'emetteur', ainsi qu'une quantité
dans le paramètre 'quantite'
"""
if not request.user.has_perm("consos.transaction_effectuer"):
return Response({}, status=status.HTTP_403_FORBIDDEN)
serializer = self.get_serializer(data=request.data)
serializer.is_valid(raise_exception=True)
if (any(emetteur != request.user for emetteur in serializer.validated_data.get('emetteurs', []))
......@@ -635,13 +619,11 @@ class TransactionViewSet(viewsets.GenericViewSet):
return Response({}, status=status.HTTP_201_CREATED)
@detail_route(methods=['patch'])
@requires("consos.transaction_devalider")
def valide(self, request, pk=None):
"""
Valide/dévalide une transaction
"""
if not request.user.has_perm("consos.transaction_devalider"):
return Response({}, status=status.HTTP_403_FORBIDDEN)
transaction = self.get_object()
fields = ['valide']
serializer = self.get_serializer(transaction, data=request.data, partial=True, fields=fields)
......
"""
Décorateurs utilisés par les vues de la Note Kfet 2018
"""
from functools import wraps
from rest_framework import status
from rest_framework.response import Response
from note_kfet.droits import D, Acl
def requires(perm, acl=Acl.LIMITE, detail=None):
"""
Vérifie que l'utilisateur a bien le droit et l'accréditation
demandée pour exécuter l'appel à l'API, et renvoie un code
HTTP 403 dans le cas contraire.
"""
def method_decorator(method):
@wraps(method)
def method_wrapper(self, request, *args, **kwargs):
response = {} if detail is None else {"detail" : detail}
if callable(perm) and not perm(request.user):
return Response(response, status=status.HTTP_403_FORBIDDEN)
if isinstance(perm, D):
perm_args = (perm,)
else:
perm_args = (perm, acl,)
if not request.user.has_perm(*perm_args):
return Response(response, status=status.HTTP_403_FORBIDDEN)
return method(self, request, *args, **kwargs)
return method_wrapper
return method_decorator
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment