From ed37696a67a0e1dc90fa5fdcd0c566e223a7b6c0 Mon Sep 17 00:00:00 2001 From: youichiro Date: Tue, 27 Jul 2021 18:17:33 +0900 Subject: [PATCH] manage permissions with permission_classes --- backend/api/exceptions.py | 4 ---- backend/api/permissions.py | 7 +++++++ backend/api/tests/api/test_project.py | 6 +++--- backend/api/views/project.py | 16 +++++++++------- 4 files changed, 19 insertions(+), 14 deletions(-) diff --git a/backend/api/exceptions.py b/backend/api/exceptions.py index ed14bf4d..cac3c279 100644 --- a/backend/api/exceptions.py +++ b/backend/api/exceptions.py @@ -63,7 +63,3 @@ class RoleConstraintException(APIException): class RoleAlreadyAssignedException(APIException): status_code = status.HTTP_400_BAD_REQUEST default_detail = 'This user is already assigned to a role in this project.' - - -class ProjectCreationPermissionDenied(PermissionDenied): - default_detail = 'You do not have permission to create a new project.' diff --git a/backend/api/permissions.py b/backend/api/permissions.py index 99b8cd56..ee03e973 100644 --- a/backend/api/permissions.py +++ b/backend/api/permissions.py @@ -98,6 +98,13 @@ class IsAnnotationApprover(RolePermission): role_name = settings.ROLE_ANNOTATION_APPROVER +class IsStaff(BasePermission): + def has_permission(self, request, view): + if request.user.is_superuser or request.user.is_staff: + return True + return False + + def is_in_role(role_name, user_id, project_id): return RoleMapping.objects.filter( user_id=user_id, diff --git a/backend/api/tests/api/test_project.py b/backend/api/tests/api/test_project.py index 9b596222..c3ea022c 100644 --- a/backend/api/tests/api/test_project.py +++ b/backend/api/tests/api/test_project.py @@ -39,16 +39,16 @@ class TestProjectCreate(CRUDMixin): 'resourcetype': 'TextClassificationProject' } - def test_allow_authenticated_and_staff_user_to_create_project(self): + def test_allows_staff_user_to_create_project(self): self.user.is_staff = True self.user.save() response = self.assert_create(self.user, status.HTTP_201_CREATED) self.assertEqual(response.data['name'], self.data['name']) - def test_disallow_authenticated_user_to_create_project(self): + def test_disallows_non_staff_user_to_create_project(self): self.assert_create(self.user, status.HTTP_403_FORBIDDEN) - def test_disallow_unauthenticated_user_to_create_project(self): + def test_disallows_unauthenticated_user_to_create_project(self): self.assert_create(expected=status.HTTP_403_FORBIDDEN) diff --git a/backend/api/views/project.py b/backend/api/views/project.py index 663171b0..2e5e0451 100644 --- a/backend/api/views/project.py +++ b/backend/api/views/project.py @@ -3,25 +3,27 @@ from rest_framework import generics, status from rest_framework.permissions import IsAuthenticated from rest_framework.response import Response -from ..exceptions import ProjectCreationPermissionDenied from ..models import Project -from ..permissions import IsInProjectReadOnlyOrAdmin +from ..permissions import IsInProjectReadOnlyOrAdmin, IsStaff from ..serializers import ProjectPolymorphicSerializer, ProjectSerializer class ProjectList(generics.ListCreateAPIView): serializer_class = ProjectPolymorphicSerializer pagination_class = None - permission_classes = [IsAuthenticated, ] + + def get_permissions(self): + if self.request.method == 'GET': + self.permission_classes = [IsAuthenticated, ] + else: + self.permission_classes = [IsAuthenticated & IsStaff] + return super().get_permissions() def get_queryset(self): return self.request.user.projects def perform_create(self, serializer): - if self.request.user.is_staff: - serializer.save(users=[self.request.user]) - else: - raise ProjectCreationPermissionDenied() + serializer.save(users=[self.request.user]) def delete(self, request, *args, **kwargs): delete_ids = request.data['ids']