From 4266a1f14834ad2d0fcee90bd9ac78dc7cd8b592 Mon Sep 17 00:00:00 2001 From: Stefano Pigozzi Date: Fri, 16 Apr 2021 17:01:58 +0200 Subject: [PATCH] =?UTF-8?q?=E2=9C=A8=20Complete=20permissions?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- sophon/core/models.py | 3 ++ sophon/core/serializers.py | 29 +++++++++++++++-- sophon/core/urls.py | 7 +--- sophon/core/views.py | 66 ++++++++++++++++---------------------- 4 files changed, 58 insertions(+), 47 deletions(-) diff --git a/sophon/core/models.py b/sophon/core/models.py index 28dc9fb..04c961e 100644 --- a/sophon/core/models.py +++ b/sophon/core/models.py @@ -356,6 +356,9 @@ class Project(models.Model): blank=True, ) + def get_project(self): + return self + def get_contributors(self): """ :return: All the contributors (:attr:`.owner` + :attr:`.collaborators`) of the project. diff --git a/sophon/core/serializers.py b/sophon/core/serializers.py index 5afac33..e9181c8 100644 --- a/sophon/core/serializers.py +++ b/sophon/core/serializers.py @@ -54,7 +54,7 @@ class DataFlowSerializer(serializers.ModelSerializer): ] -class ProjectListSerializer(serializers.ModelSerializer): +class ProjectPrivateSerializer(serializers.ModelSerializer): class Meta: model = models.Project fields = [ @@ -71,7 +71,30 @@ class ProjectListSerializer(serializers.ModelSerializer): ] -class ProjectCollaboratorSerializer(serializers.ModelSerializer): +class ProjectViewableSerializer(serializers.ModelSerializer): + class Meta: + model = models.Project + fields = [ + "slug", + "name", + "description", + "visibility", + "owner", + "collaborators", + "flows", + ] + read_only_fields = [ + "slug", + "name", + "description", + "visibility", + "owner", + "collaborators", + "flows", + ] + + +class ProjectEditableSerializer(serializers.ModelSerializer): class Meta: model = models.Project fields = [ @@ -91,7 +114,7 @@ class ProjectCollaboratorSerializer(serializers.ModelSerializer): ] -class ProjectOwnerSerializer(serializers.ModelSerializer): +class ProjectAdministrableSerializer(serializers.ModelSerializer): """ Serializer for :class:`.models.Project` when accessed as the project owner. """ diff --git a/sophon/core/urls.py b/sophon/core/urls.py index b6da8b0..00d9fb1 100644 --- a/sophon/core/urls.py +++ b/sophon/core/urls.py @@ -6,14 +6,9 @@ from . import views router = DefaultRouter() router.register("datasources", views.DataSourceViewSet) router.register("dataflows", views.DataFlowViewSet) +router.register("projects", views.ProjectViewSet) urlpatterns = [ - path("projects/", views.ProjectListView), - path("projects/", views.ProjectCreateView), - path("projects/", views.ProjectRetrieveView), - path("projects/", views.ProjectUpdateCollaboratorView), - path("projects/", views.ProjectUpdateOwnerView), - path("projects/", views.ProjectDestroyView), path("", include(router.urls)), ] diff --git a/sophon/core/views.py b/sophon/core/views.py index 615d7cb..ece35b4 100644 --- a/sophon/core/views.py +++ b/sophon/core/views.py @@ -6,47 +6,37 @@ from logging import getLogger log = getLogger(__name__) -class ProjectViewSet(viewsets.GenericViewSet): +class ProjectViewSet(viewsets.ModelViewSet): queryset = models.Project.objects.all() + @property + def permission_classes(self): + return { + "list": [], + "create": [permissions.IsAuthenticated], + "retrieve": [custom_permissions.CanViewProject], + "update": [custom_permissions.CanEditProject], + "partial_update": [custom_permissions.CanEditProject], + "destroy": [custom_permissions.CanAdministrateProject], + None: [], + }[self.action] + def get_serializer_class(self): - if self.action == "" - - -class ProjectListView(generics.ListAPIView): - queryset = models.Project.objects.all() - serializer_class = serializers.ProjectListSerializer - permission_classes = [] - - -class ProjectCreateView(generics.CreateAPIView): - queryset = models.Project.objects.all() - serializer_class = serializers.ProjectOwnerSerializer - permission_classes = [permissions.IsAuthenticated] - - -class ProjectRetrieveView(generics.RetrieveAPIView): - queryset = models.Project.objects.all() - serializer_class = serializers.ProjectCollaboratorSerializer - permission_classes = [custom_permissions.CanViewProject] - - -class ProjectUpdateCollaboratorView(generics.UpdateAPIView): - queryset = models.Project.objects.all() - serializer_class = serializers.ProjectCollaboratorSerializer - permission_classes = [custom_permissions.CanEditProject] - - -class ProjectUpdateOwnerView(generics.DestroyAPIView): - queryset = models.Project.objects.all() - serializer_class = serializers.ProjectOwnerSerializer - permission_classes = [custom_permissions.CanAdministrateProject] - - -class ProjectDestroyView(generics.DestroyAPIView): - queryset = models.Project.objects.all() - serializer_class = serializers.ProjectCollaboratorSerializer - permission_classes = [custom_permissions.CanAdministrateProject] + if self.action == "list": + return serializers.ProjectPrivateSerializer + elif self.action == "create": + return serializers.ProjectAdministrableSerializer + else: + project = self.get_object() + user = self.request.user + if project.can_be_administrated_by(user): + return serializers.ProjectAdministrableSerializer + elif project.can_be_edited_by(user): + return serializers.ProjectEditableSerializer + elif project.can_be_viewed_by(user): + return serializers.ProjectViewableSerializer + else: + return serializers.ProjectPrivateSerializer class DataFlowViewSet(viewsets.ModelViewSet):