diff --git a/core/src/main/java/org/fao/geonet/kernel/datamanager/IMetadataOperations.java b/core/src/main/java/org/fao/geonet/kernel/datamanager/IMetadataOperations.java index b2411bb2ca8..46dc7677973 100644 --- a/core/src/main/java/org/fao/geonet/kernel/datamanager/IMetadataOperations.java +++ b/core/src/main/java/org/fao/geonet/kernel/datamanager/IMetadataOperations.java @@ -24,6 +24,7 @@ package org.fao.geonet.kernel.datamanager; import java.util.Collection; +import java.util.List; import org.fao.geonet.domain.OperationAllowed; import org.fao.geonet.domain.ReservedOperation; @@ -52,6 +53,15 @@ public interface IMetadataOperations { */ void deleteMetadataOper(String metadataId, boolean skipAllReservedGroup) throws Exception; + /** + * Removes all operations stored for a metadata except for the operations of the groups in the exclude list. + * Used for preventing deletion of operations for reserved and restricted groups. + * + * @param metadataId Metadata identifier + * @param groupIdsToExclude List of group ids to exclude from deletion + */ + void deleteMetadataOper(String metadataId, List groupIdsToExclude); + /** * Adds a permission to a group. Metadata is not reindexed. */ diff --git a/core/src/main/java/org/fao/geonet/kernel/datamanager/base/BaseMetadataOperations.java b/core/src/main/java/org/fao/geonet/kernel/datamanager/base/BaseMetadataOperations.java index 47cfe3b5342..526c1d65c38 100644 --- a/core/src/main/java/org/fao/geonet/kernel/datamanager/base/BaseMetadataOperations.java +++ b/core/src/main/java/org/fao/geonet/kernel/datamanager/base/BaseMetadataOperations.java @@ -116,6 +116,18 @@ public void deleteMetadataOper(String metadataId, boolean skipAllReservedGroup) } } + /** + * Removes all operations stored for a metadata except for the operations of the groups in the exclude list. + * Used for preventing deletion of operations for reserved and restricted groups. + * + * @param metadataId Metadata identifier + * @param groupIdsToExclude List of group ids to exclude from deletion + */ + @Override + public void deleteMetadataOper(String metadataId, List groupIdsToExclude) { + opAllowedRepo.deleteAllByMetadataIdExceptGroupId(Integer.parseInt(metadataId), groupIdsToExclude); + } + /** * Adds a permission to a group. Metadata is not reindexed. */ diff --git a/domain/src/main/java/org/fao/geonet/repository/GroupRepository.java b/domain/src/main/java/org/fao/geonet/repository/GroupRepository.java index 617de58a3dc..5faa3f84f12 100644 --- a/domain/src/main/java/org/fao/geonet/repository/GroupRepository.java +++ b/domain/src/main/java/org/fao/geonet/repository/GroupRepository.java @@ -52,6 +52,14 @@ public interface GroupRepository extends GeonetRepository, Group @Nullable Group findByEmail(@Nonnull String email); + /** + * Find all groups with a minimumProfileForPrivileges not equal to null. + * These groups are "restricted". + * + * @return a list of groups with a minimumProfileForPrivileges not equal to null + */ + @Nullable + List findByMinimumProfileForPrivilegesNotNull(); public @Nullable diff --git a/domain/src/test/java/org/fao/geonet/repository/GroupRepositoryTest.java b/domain/src/test/java/org/fao/geonet/repository/GroupRepositoryTest.java index a7be16cc822..f45f0b4c1bc 100644 --- a/domain/src/test/java/org/fao/geonet/repository/GroupRepositoryTest.java +++ b/domain/src/test/java/org/fao/geonet/repository/GroupRepositoryTest.java @@ -25,6 +25,7 @@ import org.fao.geonet.domain.Group; +import org.fao.geonet.domain.Profile; import org.fao.geonet.domain.ReservedGroup; import org.junit.Test; import org.springframework.beans.factory.annotation.Autowired; @@ -131,6 +132,20 @@ public void testFindByEmail() throws Exception { assertNull(_repo.findByEmail("some wrong email")); } + @Test + public void testFindByMinimumProfileForPrivilegesNotNull() throws Exception { + Group savedGroup = _repo.save(newGroup().setMinimumProfileForPrivileges(Profile.Reviewer)); + Group savedGroup2 = _repo.save(newGroup()); + + _repo.flush(); + _entityManager.flush(); + _entityManager.clear(); + + List groups = _repo.findByMinimumProfileForPrivilegesNotNull(); + assertEquals(1, groups.size()); + assertSameContents(savedGroup, groups.get(0)); + } + @Test public void testFindReservedGroup() throws Exception { Group savedGroup = _repo.save(ReservedGroup.all.getGroupEntityTemplate()); diff --git a/services/src/main/java/org/fao/geonet/api/records/MetadataSharingApi.java b/services/src/main/java/org/fao/geonet/api/records/MetadataSharingApi.java index 40eaabdedf6..0f4054f00c1 100644 --- a/services/src/main/java/org/fao/geonet/api/records/MetadataSharingApi.java +++ b/services/src/main/java/org/fao/geonet/api/records/MetadataSharingApi.java @@ -565,8 +565,24 @@ private void setOperations( // Check if the user profile can change the privileges for publication/un-publication of the reserved groups checkChangesAllowedToUserProfileForReservedGroups(context.getUserSession(), sharingBefore, privileges, !sharing.isClear()); + List excludeFromDelete = new ArrayList(); + + // Exclude deleting privileges for groups in which the user does not have the minimum profile for privileges + for (Group group: groupRepository.findByMinimumProfileForPrivilegesNotNull()) { + if (!canUserChangePrivilegesForGroup(context, groupOwnerId, group)) { + excludeFromDelete.add(group.getId()); + } + } + + // Exclude deleting privileges for reserved groups if the skipAllReservedGroup flag is set + if (skipAllReservedGroup) { + excludeFromDelete.add(ReservedGroup.all.getId()); + excludeFromDelete.add(ReservedGroup.intranet.getId()); + excludeFromDelete.add(ReservedGroup.guest.getId()); + } + if (sharing.isClear()) { - dataManager.deleteMetadataOper(context, String.valueOf(metadata.getId()), skipAllReservedGroup); + metadataOperations.deleteMetadataOper(String.valueOf(metadata.getId()), excludeFromDelete); } for (GroupOperations p : privileges) { diff --git a/web-ui/src/main/resources/catalog/components/common/share/ShareService.js b/web-ui/src/main/resources/catalog/components/common/share/ShareService.js index 4ecd86461ff..71e04f161f2 100644 --- a/web-ui/src/main/resources/catalog/components/common/share/ShareService.js +++ b/web-ui/src/main/resources/catalog/components/common/share/ShareService.js @@ -245,9 +245,10 @@ // Do not submit internal groups info // If user is not allowed. var allowed = - ($.inArray(g.group, gnShareConstants.internalGroups) !== -1 && - user.isReviewerOrMore()) || - $.inArray(g.group, gnShareConstants.internalGroups) === -1; + !g.restricted && + (($.inArray(g.group, gnShareConstants.internalGroups) !== -1 && + user.isReviewerOrMore()) || + $.inArray(g.group, gnShareConstants.internalGroups) === -1); if (allowed) { ops.push({