Skip to content
Snippets Groups Projects
Commit f10d42b2 authored by Erwan Rouchet's avatar Erwan Rouchet
Browse files

Add and use mixin methods for right checking

parent d2f0800a
No related branches found
No related tags found
No related merge requests found
from django.db.models import Sum
from django.http.response import Http404
from django.shortcuts import get_object_or_404
from django.core.exceptions import PermissionDenied
from django.conf import settings
......@@ -41,14 +42,13 @@ class DataImportsList(CorpusACLMixin, ListCreateAPIView):
if serializer.validated_data['mode'] not in (DataImportMode.Images, ):
raise ValidationError('Unsupported mode for now, sorry.')
if not self.request.user.is_admin and \
Right.Write not in serializer.validated_data['corpus'].get_acl_rights(self.request.user):
if not self.has_write_access(serializer.validated_data['corpus']):
raise PermissionDenied
return super().perform_create(serializer)
class DataImportDetails(RetrieveUpdateDestroyAPIView):
class DataImportDetails(CorpusACLMixin, RetrieveUpdateDestroyAPIView):
"""
Retrieve and edit a data import
"""
......@@ -61,8 +61,7 @@ class DataImportDetails(RetrieveUpdateDestroyAPIView):
def perform_update(self, serializer):
dataimport = serializer.instance
if not self.request.user.is_admin and \
Right.Write not in dataimport.corpus.get_acl_rights(self.request.user):
if not self.has_write_access(dataimport.corpus):
raise PermissionDenied
if dataimport.state not in (DataImportState.Created, DataImportState.Configured):
......@@ -86,8 +85,7 @@ class DataImportDetails(RetrieveUpdateDestroyAPIView):
dataimport.save()
def perform_destroy(self, instance):
if not self.request.user.is_admin and \
Right.Write not in instance.corpus.get_acl_rights(self.request.user):
if not self.has_write_access(instance.corpus):
raise PermissionDenied
if instance.state == DataImportState.Running:
raise ValidationError("Cannot delete a workflow while it is running")
......@@ -109,7 +107,7 @@ class DataImportFailures(ListAPIView):
).prefetch_related('dataimport__revision__repo', 'element').order_by('path', 'line')
class DataImportDemo(CreateAPIView):
class DataImportDemo(CorpusACLMixin, CreateAPIView):
"""
Create, configure and start an Images workflow from a single DataFile
"""
......@@ -136,7 +134,7 @@ class DataImportDemo(CreateAPIView):
volume = get_object_or_404(Element, **filters)
assert self.request.user.is_admin or Right.Write in volume.corpus.get_acl_rights(self.request.user), \
assert self.has_write_access(volume.corpus), \
'Corpus is not writable'
# Start the import
......@@ -167,7 +165,7 @@ class DataFileList(CorpusACLMixin, ListAPIView):
return DataFile.objects.filter(corpus=self.get_corpus(self.kwargs['pk']))
class DataFileRetrieve(RetrieveUpdateDestroyAPIView):
class DataFileRetrieve(CorpusACLMixin, RetrieveUpdateDestroyAPIView):
"""
Get one file
"""
......@@ -178,19 +176,17 @@ class DataFileRetrieve(RetrieveUpdateDestroyAPIView):
return DataFile.objects.filter(corpus__in=Corpus.objects.readable(self.request.user))
def perform_update(self, serializer):
if not self.request.user.is_admin and \
Right.Write not in serializer.instance.corpus.get_acl_rights(self.request.user):
if not self.has_write_access(serializer.instance.corpus):
raise PermissionDenied
return super().perform_update(serializer)
def perform_destroy(self, instance):
if not self.request.user.is_admin and \
Right.Write not in instance.corpus.get_acl_rights(self.request.user):
if not self.has_write_access(instance.corpus):
raise PermissionDenied
return super().perform_destroy(instance)
class DataFileUpload(APIView):
class DataFileUpload(CorpusACLMixin, APIView):
"""
Upload a new file to a corpus
"""
......@@ -200,15 +196,10 @@ class DataFileUpload(APIView):
def post(self, request, pk=None, format=None):
if 'file' not in request.FILES:
raise ValidationError({'file': ['No file was sent in the request']})
corpus_qs = Corpus.objects.filter(id=pk)
if not corpus_qs.exists():
try:
corpus = self.get_corpus(pk, right=Right.Write)
except Http404:
raise ValidationError({'corpus': ['Corpus not found']})
corpus = corpus_qs.get()
# Check corpus is writable for current user
if not self.request.user.is_admin and \
Right.Write not in corpus.get_acl_rights(self.request.user):
raise PermissionDenied
file_obj = request.FILES['file']
......@@ -293,7 +284,7 @@ class AvailableRepositoriesList(ListCreateAPIView):
return Response(data={'import_id': str(dataimport.id)}, status=status.HTTP_201_CREATED)
class RepositoryRetrieve(RetrieveUpdateDestroyAPIView):
class RepositoryRetrieve(CorpusACLMixin, RetrieveUpdateDestroyAPIView):
permission_classes = (IsAuthenticated, )
serializer_class = RepositorySerializer
......@@ -304,14 +295,12 @@ class RepositoryRetrieve(RetrieveUpdateDestroyAPIView):
)
def perform_update(self, serializer):
if not self.request.user.is_admin and \
Right.Write not in serializer.instance.corpus.get_acl_rights(self.request.user):
if not self.has_write_access(serializer.instance.corpus):
raise PermissionDenied
return super().perform_update(self, serializer)
def perform_destroy(self, instance):
if not self.request.user.is_admin and \
Right.Write not in instance.corpus.get_acl_rights(self.request.user):
if not self.has_write_access(instance.corpus):
raise PermissionDenied
return super().perform_destroy(self, instance)
......
......@@ -10,3 +10,17 @@ class CorpusACLMixin(object):
if right not in corpus.get_acl_rights(self.request.user):
raise PermissionDenied()
return corpus
def has_read_access(self, corpus):
assert isinstance(corpus, Corpus)
return corpus.public or self.request.user.is_admin or Right.Read in corpus.get_acl_rights(self.request.user)
def has_write_access(self, corpus):
assert isinstance(corpus, Corpus)
return self.request.user.is_admin or self.request.user.is_anonymous and \
Right.Write in corpus.get_acl_rights(self.request.user)
def has_admin_access(self, corpus):
assert isinstance(corpus, Corpus)
return self.request.user.is_admin or self.request.user.is_anonymous and \
Right.Admin in corpus.get_acl_rights(self.request.user)
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment