diff --git a/src/backend/core/models.py b/src/backend/core/models.py index 65f2f1c9..c201b0a3 100644 --- a/src/backend/core/models.py +++ b/src/backend/core/models.py @@ -1672,6 +1672,17 @@ class Item(TreeModel, BaseModel): if redundant_ids: ItemAccess.objects.filter(id__in=redundant_ids).delete() + def _normalize_explicit_link_reach(self): + """Reset the link reach to inherit when inferior or equal to the inherited one.""" + # The cached ancestors definition predates the move, recompute it + self._ancestors_link_definition = None + inherited_reach = self.ancestors_link_definition["link_reach"] + if LinkReachChoices.get_priority(self.link_reach) <= LinkReachChoices.get_priority( + inherited_reach + ): + self.link_reach = None + self.save(update_fields=["link_reach"]) + @transaction.atomic def unrestrict(self): """Lift restriction and reattach the folder at its shortcut location.""" @@ -1706,6 +1717,7 @@ class Item(TreeModel, BaseModel): self.save(update_fields=["title"]) self.move(parent) self._normalize_explicit_accesses() + self._normalize_explicit_link_reach() self.invalidate_nb_accesses_cache() diff --git a/src/backend/core/tests/test_models_items_restricted.py b/src/backend/core/tests/test_models_items_restricted.py index 8e9f4e85..a43ac647 100644 --- a/src/backend/core/tests/test_models_items_restricted.py +++ b/src/backend/core/tests/test_models_items_restricted.py @@ -429,7 +429,48 @@ def test_models_items_restricted_unrestrict_keeps_access_without_inheritance(): assert models.ItemAccess.objects.filter(item=folder, user=user, role="owner").exists() -def test_models_items_restricted_deactivate_restriction_deduplicates_title(): +def test_models_items_restricted_unrestrict_resets_redundant_link_reach(): + """Deactivating restriction resets a link reach inferior or equal to inherited.""" + user = factories.UserFactory() + parent = factories.ItemFactory( + type=models.ItemTypeChoices.FOLDER, + link_reach=LinkReachChoices.PUBLIC, + link_role="reader", + ) + folder = factories.ItemFactory( + parent=parent, + type=models.ItemTypeChoices.FOLDER, + link_reach=None, + ) + folder = folder.restrict(user) + assert folder.link_reach == LinkReachChoices.RESTRICTED + + folder = folder.unrestrict() + + assert folder.link_reach is None + + +def test_models_items_restricted_unrestrict_keeps_superior_link_reach(): + """Deactivating restriction keeps a link reach superior to inherited.""" + user = factories.UserFactory() + parent = factories.ItemFactory( + type=models.ItemTypeChoices.FOLDER, + link_reach=LinkReachChoices.AUTHENTICATED, + link_role="reader", + ) + folder = factories.ItemFactory( + parent=parent, + type=models.ItemTypeChoices.FOLDER, + link_reach=LinkReachChoices.PUBLIC, + ) + folder = folder.restrict(user) + + folder = folder.unrestrict() + + assert folder.link_reach == LinkReachChoices.PUBLIC + + +def test_models_items_restricted_unrestrict_deduplicates_title(): """Deactivating restriction renames the folder when its title was reused.""" user = factories.UserFactory() parent = factories.ItemFactory(type=models.ItemTypeChoices.FOLDER)