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

Merge branch 'create-transcription-error' into 'master'

trigger a 403 not a 404 when trying to create a transcription without write access

Closes #952

See merge request !1638
parents 0d156fc2 e852f5eb
No related branches found
No related tags found
1 merge request!1638trigger a 403 not a 404 when trying to create a transcription without write access
......@@ -43,7 +43,7 @@ from arkindex.users.models import Role
tags=['transcriptions'],
)
)
class TranscriptionCreate(CreateAPIView):
class TranscriptionCreate(ACLMixin, CreateAPIView):
"""
Create a single transcription attached to an element
"""
......@@ -60,9 +60,12 @@ class TranscriptionCreate(CreateAPIView):
return Element.objects.none()
# We need to use the default database to avoid stale read
# when creating a transcription on a newly created element
# when creating a transcription on a newly created element.
# We retrieve the readable objects then check permissions
# instead of retrieving writable objects directly so as not to
# get 404_NOT_FOUND errors on elements the user has access to.
return Element.objects.using('default').filter(
corpus__in=Corpus.objects.writable(self.request.user)
corpus__in=Corpus.objects.readable(self.request.user)
)
def get_serializer_context(self):
......@@ -71,6 +74,13 @@ class TranscriptionCreate(CreateAPIView):
context['element'] = self.get_object()
return context
def check_object_permissions(self, request, context):
super().check_object_permissions(request, context)
role = Role.Contributor
detail = "A write access to the element's corpus is required."
if not self.has_access(context.corpus, role.value):
raise PermissionDenied(detail=detail)
def perform_create(self, serializer):
return Transcription.objects.create(
element=self.element,
......
......@@ -26,7 +26,7 @@ class TestTranscriptionCreate(FixtureAPITestCase):
cls.private_read_user = User.objects.create_user('a@bc.de', 'a')
cls.private_read_user.verified_email = True
cls.private_read_user.save()
cls.private_corpus.memberships.create(user=cls.user, level=Role.Guest.value)
cls.private_corpus.memberships.create(user=cls.private_read_user, level=Role.Guest.value)
cls.worker_version = WorkerVersion.objects.get(worker__slug='reco')
......@@ -44,6 +44,18 @@ class TestTranscriptionCreate(FixtureAPITestCase):
format='json',
data={'text': 'NEKUDOTAYIM'}
)
self.assertEqual(response.status_code, status.HTTP_403_FORBIDDEN)
self.assertDictEqual(response.json(), {
'detail': "A write access to the element's corpus is required."
})
def test_create_transcription_no_read_right(self):
self.client.force_login(self.user)
response = self.client.post(
reverse('api:transcription-create', kwargs={'pk': self.private_page.id}),
format='json',
data={'text': 'NEKUDOTAYIM'}
)
self.assertEqual(response.status_code, status.HTTP_404_NOT_FOUND)
def test_create_transcription_no_element(self):
......@@ -60,7 +72,7 @@ class TestTranscriptionCreate(FixtureAPITestCase):
Checks the view creates a manual transcription and runs ES indexing
"""
self.client.force_login(self.user)
with self.assertNumQueries(6):
with self.assertNumQueries(8):
response = self.client.post(
reverse('api:transcription-create', kwargs={'pk': self.line.id}),
format='json',
......@@ -88,7 +100,7 @@ class TestTranscriptionCreate(FixtureAPITestCase):
"""
self.client.force_login(self.user)
ts = self.line.transcriptions.create(text='GLOUBIBOULGA')
with self.assertNumQueries(5):
with self.assertNumQueries(7):
response = self.client.post(
reverse('api:transcription-create', kwargs={'pk': self.line.id}),
format='json',
......
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