From 3908805a7fc00db82914479750761ec893997f81 Mon Sep 17 00:00:00 2001 From: Reinhard Date: Tue, 12 Mar 2024 17:51:31 +0100 Subject: [PATCH] user api and permissions --- .../pigeonhole/apps/courses/permissions.py | 2 +- backend/pigeonhole/apps/users/permissions.py | 18 ++++++++++ backend/pigeonhole/apps/users/views.py | 35 ++++++++++++++++++- 3 files changed, 53 insertions(+), 2 deletions(-) create mode 100644 backend/pigeonhole/apps/users/permissions.py diff --git a/backend/pigeonhole/apps/courses/permissions.py b/backend/pigeonhole/apps/courses/permissions.py index f7939197..2bcebaaf 100644 --- a/backend/pigeonhole/apps/courses/permissions.py +++ b/backend/pigeonhole/apps/courses/permissions.py @@ -17,7 +17,7 @@ def has_permission(self, request, view): return True return - if request.user.is_student or request.user.is_teacher: + if request.user.is_student: return view.action in ['list', 'retrieve'] return False diff --git a/backend/pigeonhole/apps/users/permissions.py b/backend/pigeonhole/apps/users/permissions.py new file mode 100644 index 00000000..bc2d912d --- /dev/null +++ b/backend/pigeonhole/apps/users/permissions.py @@ -0,0 +1,18 @@ +from rest_framework import permissions + +from backend.pigeonhole.apps.users.models import User + + +class UserPermissions(permissions.BasePermission): + def has_permission(self, request, view): + if request.user.is_admin or request.user.is_superuser: + return True # TODO can admins destroy each other? + + if request.user.is_teacher or request.user.is_student: + if view.action in ['list', 'retrieve']: # TODO: can teachers create and destroy users? + return True + elif view.action in ['update', 'partial_update', 'destroy'] and User.objects.filter( + id=request.user.id).exists(): + return True + + return False diff --git a/backend/pigeonhole/apps/users/views.py b/backend/pigeonhole/apps/users/views.py index 5fec4879..81dc7938 100644 --- a/backend/pigeonhole/apps/users/views.py +++ b/backend/pigeonhole/apps/users/views.py @@ -3,12 +3,13 @@ from rest_framework.response import Response from backend.pigeonhole.apps.users.models import User, UserSerializer +from .permissions import UserPermissions class UserViewSet(viewsets.ModelViewSet): queryset = User.objects.all() serializer_class = UserSerializer - permission_classes = [IsAuthenticated] + permission_classes = [IsAuthenticated, UserPermissions] def list(self, request, *args, **kwargs): serializer = UserSerializer(self.queryset, many=True) @@ -24,3 +25,35 @@ def create(self, request, *args, **kwargs): return Response(serializer.data, status=status.HTTP_201_CREATED) else: return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST) + + def update(self, request, *args, **kwargs): + user_id = kwargs.get('pk') + user = User.objects.get(pk=user_id) + serializer = UserSerializer(user, data=request.data) + if serializer.is_valid(): + serializer.save() + return Response(serializer.data, status=status.HTTP_200_OK) + else: + return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST) + + def partial_update(self, request, *args, **kwargs): + user_id = kwargs.get('pk') + user = User.objects.get(pk=user_id) + serializer = UserSerializer(user, data=request.data, partial=True) + if serializer.is_valid(): + serializer.save() + return Response(serializer.data, status=status.HTTP_200_OK) + else: + return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST) + + def destroy(self, request, *args, **kwargs): + user_id = kwargs.get('pk') + user = User.objects.get(pk=user_id) + user.delete() + return Response(status=status.HTTP_204_NO_CONTENT) + + def retrieve(self, request, *args, **kwargs): + user_id = kwargs.get('pk') + user = User.objects.get(pk=user_id) + serializer = UserSerializer(user, many=False) + return Response(serializer.data, status=status.HTTP_200_OK)