From 9baf7fc6bf0dd8b6dafe24a3f958f84c95ba7b52 Mon Sep 17 00:00:00 2001 From: Hironsan Date: Tue, 31 Jul 2018 18:58:17 +0900 Subject: [PATCH] Add permissions --- app/db.sqlite3 | Bin 258048 -> 258048 bytes app/server/models.py | 9 +++++++ app/server/views.py | 60 ++++++++++++++++++++++++++++--------------- 3 files changed, 48 insertions(+), 21 deletions(-) diff --git a/app/db.sqlite3 b/app/db.sqlite3 index 3f2a393a8b31af6059b17d386a77c4f9225918ec..359340ddf38f95c1b451af72f6d3280db95cf8cf 100644 GIT binary patch delta 496 zcmZp8z~AtIe}XjQhKVxHtQ#2gBu;Eh3DRS%-@IL~xq#2o%Glh>z*x`J*wnzxWU|Nn z4v>(gm8rR&k%6V5g-P?h`P=W!XWX-aiAQF$p+Xk7m?R?yBO?KX;uLfUjR_;YFjP6C8~<;<$^5^8O26{5b5*l2b28R% zpYe|=9cbnjW=@Cc+z!mWZ2TX&YxzF{6Jd_NL3@r?stXaUCrx*4!D}Yp7Vc}!t_h8_k#J`>2 zgFl!5&St>`Gk#SSW?x1^7O+mw?Ps12)Skw`|A_xE{}TRI{xqQW5dP_{^O*&NQEg_G TV|HYmu2aJ-wSDn?=GXuLdl-!C delta 329 zcmYMsze@sP90u_B*VXC$_~z7*gF{eD$DN_(1z`kHL?q1y4pEa}h09qasnDdE&>Jlm z)ShAVE=~0>G|Q2D6fOOr=xyp5pXb9<37`_d(Fpci(K*FO6W`m{>#G*_y27d!&6FEY zx(UacOxy9a-Cpny|EiR0C#<-ga2&hZ^F`0ccb%>iD`|#4h(lP0u;Fn}M02E1G2G_K zSyApCV?d#D^F+2st}up^fTZvzPX=U^=K?bGZ@QzEVMzc0 diff --git a/app/server/models.py b/app/server/models.py index 10ae8c68..c246173a 100644 --- a/app/server/models.py +++ b/app/server/models.py @@ -170,3 +170,12 @@ class Factory(object): return document.seq_annotations.all() elif document.project.is_type_of(Project.Seq2seq): return document.seq2seq_annotations.all() + + @classmethod + def get_annotation_class(cls, project): + if project.is_type_of(Project.DOCUMENT_CLASSIFICATION): + return DocumentAnnotation + elif project.is_type_of(Project.SEQUENCE_LABELING): + return SequenceAnnotation + elif project.is_type_of(Project.Seq2seq): + return Seq2seqAnnotation diff --git a/app/server/views.py b/app/server/views.py index ec2c2b63..d54d2569 100644 --- a/app/server/views.py +++ b/app/server/views.py @@ -11,7 +11,7 @@ from django.contrib.auth.mixins import LoginRequiredMixin from rest_framework import viewsets, filters, generics from rest_framework.decorators import action from rest_framework.response import Response -from rest_framework.permissions import IsAdminUser, IsAuthenticated +from rest_framework.permissions import SAFE_METHODS, BasePermission, IsAdminUser, IsAuthenticated from .models import Label, Document, Project, Factory from .models import DocumentAnnotation, SequenceAnnotation, Seq2seqAnnotation @@ -69,11 +69,43 @@ class DataDownloadAPI(View): return response +class IsProjectUser(BasePermission): + + def has_permission(self, request, view): + user = request.user + project_id = view.kwargs.get('project_id') + project = get_object_or_404(Project, pk=project_id) + + return user in project.users.all() + + +class IsAdminUserAndWriteOnly(BasePermission): + + def has_permission(self, request, view): + if request.method in SAFE_METHODS: + return True + + return IsAdminUser().has_permission(request, view) + + +class IsOwnAnnotation(BasePermission): + + def has_permission(self, request, view): + user = request.user + project_id = view.kwargs.get('project_id') + annotation_id = view.kwargs.get('annotation_id') + project = get_object_or_404(Project, pk=project_id) + Annotation = Factory.get_annotation_class(project) + annotation = Annotation.objects.get(id=annotation_id) + + return annotation.user == user + + class ProjectViewSet(viewsets.ModelViewSet): queryset = Project.objects.all() serializer_class = ProjectSerializer pagination_class = None - permission_classes = (IsAuthenticated,) + permission_classes = (IsAuthenticated, IsAdminUserAndWriteOnly) @action(methods=['get'], detail=True) def progress(self, request, pk=None): @@ -85,24 +117,11 @@ class ProjectViewSet(viewsets.ModelViewSet): return Response({'total': total, 'remaining': remaining}) -from rest_framework import permissions - - -class ProjectPermission(permissions.BasePermission): - - def has_permission(self, request, view): - user = request.user - project_id = view.kwargs.get('project_id') - project = get_object_or_404(Project, pk=project_id) - - return user in project.users.all() - - class ProjectLabelsAPI(generics.ListCreateAPIView): queryset = Label.objects.all() serializer_class = LabelSerializer pagination_class = None - permission_classes = (IsAuthenticated, ProjectPermission) + permission_classes = (IsAuthenticated, IsProjectUser, IsAdminUserAndWriteOnly) def get_queryset(self): project_id = self.kwargs['project_id'] @@ -119,7 +138,7 @@ class ProjectLabelsAPI(generics.ListCreateAPIView): class ProjectLabelAPI(generics.RetrieveUpdateDestroyAPIView): queryset = Label.objects.all() serializer_class = LabelSerializer - permission_classes = (IsAuthenticated,) + permission_classes = (IsAuthenticated, IsProjectUser, IsAdminUser) def get_queryset(self): project_id = self.kwargs['project_id'] @@ -140,7 +159,7 @@ class ProjectDocsAPI(generics.ListCreateAPIView): queryset = Document.objects.all() filter_backends = (DjangoFilterBackend, filters.SearchFilter, filters.OrderingFilter) search_fields = ('text', ) - permission_classes = (IsAuthenticated,) + permission_classes = (IsAuthenticated, IsProjectUser, IsAdminUserAndWriteOnly) def get_serializer_class(self): project_id = self.kwargs['project_id'] @@ -164,7 +183,7 @@ class ProjectDocsAPI(generics.ListCreateAPIView): class AnnotationsAPI(generics.ListCreateAPIView): pagination_class = None - permission_classes = (IsAuthenticated,) + permission_classes = (IsAuthenticated, IsProjectUser) def get_serializer_class(self): project_id = self.kwargs['project_id'] @@ -207,7 +226,7 @@ class AnnotationsAPI(generics.ListCreateAPIView): class AnnotationAPI(generics.RetrieveUpdateDestroyAPIView): - permission_classes = (IsAuthenticated,) + permission_classes = (IsAuthenticated, IsProjectUser, IsOwnAnnotation) def get_queryset(self): doc_id = self.kwargs['doc_id'] @@ -232,7 +251,6 @@ class AnnotationAPI(generics.RetrieveUpdateDestroyAPIView): text = request.data['text'] annotation = get_object_or_404(Seq2seqAnnotation, pk=request.data['id']) annotation.text = text - print(text) annotation.save() serializer = self.serializer_class(annotation)