diff --git a/arkindex/documents/serializers/elements.py b/arkindex/documents/serializers/elements.py index e44ffc75b468d6754cf6f84c10f79145df347879..e4c08bae036d124322bc4556fc727ff68d16123d 100644 --- a/arkindex/documents/serializers/elements.py +++ b/arkindex/documents/serializers/elements.py @@ -83,6 +83,16 @@ class CorpusSerializer(serializers.ModelSerializer): count = corpus.corpus_right.count() return count + def validate_public(self, public): + """ + Only an admin can toggle a corpus public property + Normal users may create private corpus only + """ + toggled = self.instance and self.instance.public != public + if (toggled or public) and not self.context['request'].user.is_admin: + raise ValidationError(['Only admin users are allowed to edit the public attribute on a corpus.']) + return public + def create(self, validated_data): corpus = Corpus.objects.create(**validated_data) corpus.corpus_right.create( diff --git a/arkindex/documents/tests/test_corpus.py b/arkindex/documents/tests/test_corpus.py index 9c1f03a7669f07c6f1b2f3ae59c78a507d0b0c3e..f33d2c65cc239ce97bf32634916dc268d386a2a8 100644 --- a/arkindex/documents/tests/test_corpus.py +++ b/arkindex/documents/tests/test_corpus.py @@ -262,7 +262,46 @@ class TestCorpus(FixtureAPITestCase): [str(vol1.id), str(vol2.id)], ) + def test_create_requires_login(self): + response = self.client.post(reverse('api:corpus'), { + 'name': 'New Corpus', + 'description': 'Some description', + 'public': False, + }) + self.assertEqual(response.status_code, status.HTTP_403_FORBIDDEN) + + def test_create_public_admin(self): + """ + Administrators can create a public corpus + """ + self.client.force_login(self.superuser) + response = self.client.post(reverse('api:corpus'), { + 'name': 'New Corpus', + 'description': 'Some description', + 'public': True, + }) + self.assertEqual(response.status_code, status.HTTP_201_CREATED) + self.assertTrue(Corpus.objects.get(name='New Corpus').public) + + def test_create_public_normal_user(self): + """ + Normal users cannot create a public corpus + """ + self.client.force_login(self.user) + response = self.client.post(reverse('api:corpus'), { + 'name': 'New Corpus', + 'description': 'Some description', + 'public': True, + }) + self.assertEqual(response.status_code, status.HTTP_400_BAD_REQUEST) + self.assertDictEqual(response.json(), { + 'public': ['Only admin users are allowed to edit the public attribute on a corpus.'] + }) + def test_create(self): + """ + Any user is able to create a corpus defining its name and description + """ self.client.force_login(self.user) response = self.client.post(reverse('api:corpus'), { 'name': 'New Corpus', @@ -290,14 +329,6 @@ class TestCorpus(FixtureAPITestCase): } for values in DEFAULT_CORPUS_TYPES] ) - def test_create_requires_login(self): - response = self.client.post(reverse('api:corpus'), { - 'name': 'New Corpus', - 'description': 'Some description', - 'public': False, - }) - self.assertEqual(response.status_code, status.HTTP_403_FORBIDDEN) - def test_retrieve_public(self): response = self.client.get(reverse('api:corpus-retrieve', kwargs={'pk': self.corpus_public.id})) self.assertEqual(response.status_code, status.HTTP_200_OK) @@ -377,6 +408,51 @@ class TestCorpus(FixtureAPITestCase): self.assertEqual(self.corpus_private.name, 'new name') self.assertEqual(self.corpus_private.description, 'new description') + def test_update_private_to_public_normal_user(self): + """ + A normal user should not be able to make a private corpus public + """ + self.client.force_login(self.user) + response = self.client.patch(reverse('api:corpus-retrieve', kwargs={'pk': self.corpus_private.id}), { + 'public': True + }) + self.assertEqual(response.status_code, status.HTTP_400_BAD_REQUEST) + self.assertDictEqual(response.json(), { + 'public': ['Only admin users are allowed to edit the public attribute on a corpus.'] + }) + + def test_update_public_to_private_normal_user(self): + """ + A normal user should not be able to make a public corpus private + even if he has a write access to this corpus + """ + self.client.force_login(self.user) + self.assertTrue(self.corpus_public.corpus_right.get(user=self.user).can_write) + response = self.client.patch(reverse('api:corpus-retrieve', kwargs={'pk': self.corpus_public.id}), { + 'public': False + }) + self.assertEqual(response.status_code, status.HTTP_400_BAD_REQUEST) + self.assertDictEqual(response.json(), { + 'public': ['Only admin users are allowed to edit the public attribute on a corpus.'] + }) + + def test_normal_user_update_public_corpus(self): + """ + An user with no write right should not be able to edit a public corpus + """ + self.client.force_login(self.user) + right = self.corpus_public.corpus_right.get(user=self.user) + right.can_write = False + right.can_admin = False + right.save() + response = self.client.patch(reverse('api:corpus-retrieve', kwargs={'pk': self.corpus_public.id}), { + 'name': 'Gloubiboulga', + 'description': 'Bla bla bla', + 'public': False + }) + self.assertEqual(response.status_code, status.HTTP_403_FORBIDDEN) + self.assertDictEqual(response.json(), {'detail': 'You do not have write access to this corpus.'}) + def test_update_requires_login(self): response = self.client.patch(reverse('api:corpus-retrieve', kwargs={'pk': self.corpus_private.id}), { 'name': 'new name',