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

Merge branch 'element-delete-requires-admin' into 'master'

Add permission validation on element patch/delete

See merge request !610
parents 869542ad c217079d
No related branches found
No related tags found
1 merge request!610Add permission validation on element patch/delete
......@@ -176,10 +176,7 @@ class ElementRetrieve(RetrieveUpdateDestroyAPIView):
permission_classes = (IsVerifiedOrReadOnly, )
def get_queryset(self):
if self.request.method == 'GET':
corpora = Corpus.objects.readable(self.request.user)
else:
corpora = Corpus.objects.writable(self.request.user)
corpora = Corpus.objects.readable(self.request.user)
return Element.objects \
.filter(corpus__in=corpora) \
.select_related(
......@@ -193,6 +190,14 @@ class ElementRetrieve(RetrieveUpdateDestroyAPIView):
Prefetch('classifications', queryset=classifications_queryset)
)
def check_object_permissions(self, request, obj):
super().check_object_permissions(request, obj)
rights = obj.corpus.get_acl_rights(request.user)
if request.method == 'DELETE' and Right.Admin not in rights:
self.permission_denied(request, message='You do not have admin access to this element.')
elif request.method != 'GET' and Right.Write not in rights:
self.permission_denied(request, message='You do not have write access to this element.')
def perform_destroy(self, instance):
children_count = ElementPath.objects.filter(path__contains=[instance.id]).count()
if children_count:
......
......@@ -18,7 +18,6 @@ class TestElementsAPI(FixtureAPITestCase):
cls.volume_type = cls.corpus.types.get(slug='volume')
cls.page_type = cls.corpus.types.get(slug='page')
cls.act_type = cls.corpus.types.get(slug='act')
cls.private_corpus = Corpus.objects.create(name='private')
cls.vol = cls.corpus.elements.get(name='Volume 1')
cls.element = Element.objects.get(name='Volume 1, page 2r')
cls.image = ImageServer.objects.local.images.create(
......@@ -27,6 +26,8 @@ class TestElementsAPI(FixtureAPITestCase):
width=42,
height=42,
)
cls.private_corpus = Corpus.objects.create(name='private', public=False)
cls.private_elt = cls.private_corpus.elements.create(type=cls.private_corpus.types.create(slug='type'))
def setUp(self):
self.page = self.corpus.elements.get(name='Volume 1, page 1r')
......@@ -63,14 +64,18 @@ class TestElementsAPI(FixtureAPITestCase):
self.assertEqual(response.status_code, status.HTTP_403_FORBIDDEN)
def test_element_destroy_acl(self):
self.private_corpus.corpus_right.create(user_id=self.user.id, can_write=False)
self.private_corpus.corpus_right.create(user_id=self.user.id, can_write=True, can_admin=False)
self.client.force_login(self.user)
castle_story = self.private_corpus.elements.create(
type=self.volume_type,
name='Castle story'
)
response = self.client.delete(reverse('api:element-retrieve', kwargs={'pk': str(castle_story.id)}))
self.assertEqual(response.status_code, status.HTTP_404_NOT_FOUND)
self.assertEqual(response.status_code, status.HTTP_403_FORBIDDEN)
self.assertDictEqual(
response.json(),
{'detail': 'You do not have admin access to this element.'}
)
def test_element_destroy(self):
self.client.force_login(self.user)
......@@ -142,16 +147,37 @@ class TestElementsAPI(FixtureAPITestCase):
format='json',
)
self.assertEqual(response.status_code, status.HTTP_403_FORBIDDEN)
self.assertDictEqual(
response.json(),
{'detail': 'You do not have permission to perform this action.'}
)
def test_patch_no_write_access(self):
# Create read_only corpus right
self.private_corpus.corpus_right.create(user_id=self.user.id)
self.assertTrue(self.user.verified_email)
self.client.force_login(self.user)
response = self.client.patch(
reverse('api:element-retrieve', kwargs={'pk': str(self.private_elt.id)}),
data={'name': 'Untitled (2)'},
format='json',
)
self.assertEqual(response.status_code, status.HTTP_403_FORBIDDEN)
self.assertDictEqual(
response.json(),
{'detail': 'You do not have write access to this element.'}
)
def test_patch_element_acl(self):
def test_patch_element_no_read_access(self):
"""
Check patching an element as anonymous user is not possible
"""
self.user.corpus_right.get(corpus=self.corpus).delete()
self.assertTrue(self.user.verified_email)
self.client.force_login(self.user)
ext_user = User.objects.create_user(email='ark@ark.net')
ext_user.verified_email = True
ext_user.save()
self.client.force_login(ext_user)
response = self.client.patch(
reverse('api:element-retrieve', kwargs={'pk': str(self.vol.id)}),
reverse('api:element-retrieve', kwargs={'pk': str(self.private_elt.id)}),
data={'name': 'Untitled (2)'},
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