From 4e54a93ee0c7086dcdf1a3714f630acd4d9a18a7 Mon Sep 17 00:00:00 2001 From: Yohan Boniface Date: Tue, 19 Sep 2023 08:19:20 +0200 Subject: [PATCH] Add DataLayer.INHERIT edit status option --- umap/forms.py | 5 ++- umap/models.py | 6 ++- umap/tests/test_datalayer.py | 64 ++++++++++++++++++++++++++++-- umap/tests/test_datalayer_views.py | 49 +++++++++++++++++++++++ 4 files changed, 117 insertions(+), 7 deletions(-) diff --git a/umap/forms.py b/umap/forms.py index 1b024d18..ec94e7a8 100644 --- a/umap/forms.py +++ b/umap/forms.py @@ -66,8 +66,9 @@ class DataLayerPermissionsForm(forms.ModelForm): class AnonymousDataLayerPermissionsForm(forms.ModelForm): STATUS = ( - (Map.OWNER, _("Only editable with secret edit link")), - (Map.ANONYMOUS, _("Everyone can edit")), + (DataLayer.INHERIT, _("Inherit")), + (DataLayer.OWNER, _("Only editable with secret edit link")), + (DataLayer.ANONYMOUS, _("Everyone can edit")), ) edit_status = forms.ChoiceField(choices=STATUS) diff --git a/umap/models.py b/umap/models.py index 3f8848fa..6c9c9fef 100644 --- a/umap/models.py +++ b/umap/models.py @@ -304,10 +304,12 @@ class DataLayer(NamedModel): Layer to store Features in. """ + INHERIT = 0 ANONYMOUS = 1 EDITORS = 2 OWNER = 3 EDIT_STATUS = ( + (INHERIT, _("Inherit")), (ANONYMOUS, _("Everyone")), (EDITORS, _("Editors only")), (OWNER, _("Owner only")), @@ -327,7 +329,7 @@ class DataLayer(NamedModel): ) edit_status = models.SmallIntegerField( choices=EDIT_STATUS, - default=get_default_edit_status, + default=INHERIT, verbose_name=_("edit status"), ) @@ -434,6 +436,8 @@ class DataLayer(NamedModel): Define if a user can edit or not the instance, according to his account or the request. """ + if self.edit_status == self.INHERIT: + return self.map.can_edit(user, request) can = False if not self.map.owner: if settings.UMAP_ALLOW_ANONYMOUS and self.map.is_anonymous_owner(request): diff --git a/umap/tests/test_datalayer.py b/umap/tests/test_datalayer.py index d2b70797..3464d430 100644 --- a/umap/tests/test_datalayer.py +++ b/umap/tests/test_datalayer.py @@ -4,7 +4,7 @@ import pytest from django.core.files.base import ContentFile from .base import DataLayerFactory, MapFactory -from umap.models import DataLayer +from umap.models import DataLayer, Map pytestmark = pytest.mark.django_db @@ -136,10 +136,66 @@ def test_anonymous_cannot_edit_in_anonymous_owner_mode(datalayer): assert not datalayer.can_edit() -def test_anonymous_can_edit_in_anonymous_owner_but_public_mode(datalayer): - datalayer.edit_status = DataLayer.ANONYMOUS +def test_owner_can_edit_in_inherit_mode_and_map_in_owner_mode(datalayer): + datalayer.edit_status = DataLayer.INHERIT datalayer.save() map = datalayer.map - map.owner = None + map.edit_status = Map.OWNER + map.save() + assert datalayer.can_edit(map.owner) + + +def test_editors_cannot_edit_in_inherit_mode_and_map_in_owner_mode(datalayer, user): + datalayer.edit_status = DataLayer.INHERIT + datalayer.save() + map = datalayer.map + map.editors.add(user) + map.edit_status = Map.OWNER + map.save() + assert not datalayer.can_edit(user) + + +def test_anonymous_cannot_edit_in_inherit_mode_and_map_in_owner_mode(datalayer): + datalayer.edit_status = DataLayer.INHERIT + datalayer.save() + map = datalayer.map + map.edit_status = Map.OWNER + map.save() + assert not datalayer.can_edit() + + +def test_owner_can_edit_in_inherit_mode_and_map_in_editors_mode(datalayer): + datalayer.edit_status = DataLayer.INHERIT + datalayer.save() + map = datalayer.map + map.edit_status = Map.EDITORS + map.save() + assert datalayer.can_edit(map.owner) + + +def test_editors_can_edit_in_inherit_mode_and_map_in_editors_mode(datalayer, user): + datalayer.edit_status = DataLayer.INHERIT + datalayer.save() + map = datalayer.map + map.editors.add(user) + map.edit_status = Map.EDITORS + map.save() + assert datalayer.can_edit(user) + + +def test_anonymous_cannot_edit_in_inherit_mode_and_map_in_editors_mode(datalayer): + datalayer.edit_status = DataLayer.INHERIT + datalayer.save() + map = datalayer.map + map.edit_status = Map.EDITORS + map.save() + assert not datalayer.can_edit() + + +def test_anonymous_can_edit_in_inherit_mode_and_map_in_public_mode(datalayer): + datalayer.edit_status = DataLayer.INHERIT + datalayer.save() + map = datalayer.map + map.edit_status = Map.ANONYMOUS map.save() assert datalayer.can_edit() diff --git a/umap/tests/test_datalayer_views.py b/umap/tests/test_datalayer_views.py index 01c65db7..46b94f07 100644 --- a/umap/tests/test_datalayer_views.py +++ b/umap/tests/test_datalayer_views.py @@ -336,3 +336,52 @@ def test_editor_can_edit_in_editors_mode(datalayer, client, map, post_data): assert response.status_code == 200 modified_datalayer = DataLayer.objects.get(pk=datalayer.pk) assert modified_datalayer.name == name + + +@pytest.mark.usefixtures("allow_anonymous") +def test_anonymous_owner_can_edit_if_inherit_and_map_in_owner_mode( + datalayer, cookieclient, anonymap, post_data +): + anonymap.edit_status = Map.OWNER + anonymap.save() + datalayer.edit_status = DataLayer.INHERIT + datalayer.save() + url = reverse("datalayer_update", args=(anonymap.pk, datalayer.pk)) + name = "new name" + post_data["name"] = name + response = cookieclient.post(url, post_data, follow=True) + assert response.status_code == 200 + modified_datalayer = DataLayer.objects.get(pk=datalayer.pk) + assert modified_datalayer.name == name + + +@pytest.mark.usefixtures("allow_anonymous") +def test_anonymous_user_cannot_edit_if_inherit_and_map_in_owner_mode( + datalayer, client, anonymap, post_data +): + anonymap.edit_status = Map.OWNER + anonymap.save() + datalayer.edit_status = DataLayer.INHERIT + datalayer.save() + url = reverse("datalayer_update", args=(anonymap.pk, datalayer.pk)) + name = "new name" + post_data["name"] = name + response = client.post(url, post_data, follow=True) + assert response.status_code == 403 + + +@pytest.mark.usefixtures("allow_anonymous") +def test_anonymous_user_can_edit_if_inherit_and_map_in_public_mode( + datalayer, client, anonymap, post_data +): + anonymap.edit_status = Map.ANONYMOUS + anonymap.save() + datalayer.edit_status = DataLayer.INHERIT + datalayer.save() + url = reverse("datalayer_update", args=(anonymap.pk, datalayer.pk)) + name = "new name" + post_data["name"] = name + response = client.post(url, post_data, follow=True) + assert response.status_code == 200 + modified_datalayer = DataLayer.objects.get(pk=datalayer.pk) + assert modified_datalayer.name == name