/* * #%L * Alfresco Records Management Module * %% * Copyright (C) 2005 - 2016 Alfresco Software Limited * %% * This file is part of the Alfresco software. * - * If the software was purchased under a paid Alfresco license, the terms of * the paid license agreement will prevail. Otherwise, the software is * provided under the following open source license terms: * - * Alfresco is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * - * Alfresco is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * - * You should have received a copy of the GNU Lesser General Public License * along with Alfresco. If not, see <http://www.gnu.org/licenses/>. * #L% */ package org.alfresco.module.org_alfresco_module_rm.security; import static org.alfresco.module.org_alfresco_module_rm.security.ExtendedSecurityServiceImpl.READER_GROUP_PREFIX; import static org.alfresco.module.org_alfresco_module_rm.security.ExtendedSecurityServiceImpl.ROOT_IPR_GROUP; import static org.alfresco.module.org_alfresco_module_rm.security.ExtendedSecurityServiceImpl.WRITER_GROUP_PREFIX; import static org.alfresco.module.org_alfresco_module_rm.test.util.AlfMock.generateText; import static org.alfresco.service.cmr.security.PermissionService.GROUP_PREFIX; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; import static org.mockito.Matchers.any; import static org.mockito.Matchers.anySet; import static org.mockito.Matchers.anyString; import static org.mockito.Matchers.eq; import static org.mockito.Mockito.doAnswer; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.never; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; import java.util.ArrayList; import java.util.Collections; import java.util.List; import java.util.Set; import java.util.stream.Collectors; import java.util.stream.Stream; import org.alfresco.model.RenditionModel; import org.alfresco.module.org_alfresco_module_rm.capability.RMPermissionModel; import org.alfresco.module.org_alfresco_module_rm.fileplan.FilePlanService; import org.alfresco.module.org_alfresco_module_rm.model.RecordsManagementModel; import org.alfresco.module.org_alfresco_module_rm.role.FilePlanRoleService; import org.alfresco.module.org_alfresco_module_rm.test.util.AlfMock; import org.alfresco.query.PagingRequest; import org.alfresco.query.PagingResults; import org.alfresco.repo.security.authority.RMAuthority; import org.alfresco.repo.security.permissions.impl.AccessPermissionImpl; import org.alfresco.repo.transaction.RetryingTransactionHelper; import org.alfresco.repo.transaction.RetryingTransactionHelper.RetryingTransactionCallback; import org.alfresco.service.cmr.repository.ChildAssociationRef; import org.alfresco.service.cmr.repository.NodeRef; import org.alfresco.service.cmr.repository.NodeService; import org.alfresco.service.cmr.security.AccessPermission; import org.alfresco.service.cmr.security.AccessStatus; import org.alfresco.service.cmr.security.AuthorityService; import org.alfresco.service.cmr.security.AuthorityType; import org.alfresco.service.cmr.security.PermissionService; import org.alfresco.service.namespace.RegexQNamePattern; import org.alfresco.service.transaction.TransactionService; import org.junit.Before; import org.junit.Test; import org.mockito.InjectMocks; import org.mockito.Mock; import org.mockito.MockitoAnnotations; import org.mockito.invocation.InvocationOnMock; import org.mockito.stubbing.Answer; import org.springframework.context.ApplicationContext; import org.springframework.context.event.ContextRefreshedEvent; /** * Extended security service implementation unit test. * * @author Roy Wetherall * @since 2.5 */ public class ExtendedSecurityServiceImplUnitTest { /** service mocks*/ @Mock private FilePlanService mockedFilePlanService; @Mock private FilePlanRoleService mockedFilePlanRoleService; @Mock private AuthorityService mockedAuthorityService; @Mock private PermissionService mockedPermissionService; @Mock private TransactionService mockedTransactionService; @Mock private RetryingTransactionHelper mockedRetryingTransactionHelper; @Mock private NodeService mockedNodeService; @Mock private PagingResults<String> mockedReadPagingResults; @Mock private PagingResults<String> mockedWritePagingResults; @Mock private ApplicationContext mockedApplicationContext; @Mock private ChildAssociationRef mockedChildAssociationRef; /** test component */ @InjectMocks private ExtendedSecurityServiceImpl extendedSecurityService; /** read/write group full names */ private static final String READER_GROUP_FULL_PREFIX = GROUP_PREFIX + READER_GROUP_PREFIX; private static final String WRITER_GROUP_FULL_PREFIX = GROUP_PREFIX + WRITER_GROUP_PREFIX; /** test authorities */ private static final String USER = "USER"; private static final String GROUP = GROUP_PREFIX + "GROUP"; private static final String USER_W = "USER_W"; private static final String GROUP_W = GROUP_PREFIX + "GROUP_W"; private static final Set<String> READERS = Stream.of(USER, GROUP).collect(Collectors.toSet()); private static final Set<String> WRITERS = Stream.of(USER_W, GROUP_W).collect(Collectors.toSet()); /** has extended security permission set */ private static final Set<AccessPermission> HAS_EXTENDED_SECURITY = Stream .of(new AccessPermissionImpl(AlfMock.generateText(), AccessStatus.ALLOWED, READER_GROUP_FULL_PREFIX, 0), new AccessPermissionImpl(AlfMock.generateText(), AccessStatus.ALLOWED, AlfMock.generateText(), 1), new AccessPermissionImpl(AlfMock.generateText(), AccessStatus.ALLOWED, WRITER_GROUP_FULL_PREFIX, 2)) .collect(Collectors.toSet()); /** has no extended security permission set */ private static final Set<AccessPermission> HAS_NO_EXTENDED_SECURITY = Stream .of(new AccessPermissionImpl(AlfMock.generateText(), AccessStatus.ALLOWED, AlfMock.generateText(), 0), new AccessPermissionImpl(AlfMock.generateText(), AccessStatus.ALLOWED, AlfMock.generateText(), 1), new AccessPermissionImpl(AlfMock.generateText(), AccessStatus.ALLOWED, AlfMock.generateText(), 2)) .collect(Collectors.toSet()); /** test data */ private NodeRef nodeRef; private NodeRef filePlan; private String readGroupPrefix; private String writeGroupPrefix; /** * Before tests */ @SuppressWarnings("unchecked") @Before public void before() { // initialise mocks MockitoAnnotations.initMocks(this); // setup node nodeRef = AlfMock.generateNodeRef(mockedNodeService); // setup file plan filePlan = AlfMock.generateNodeRef(mockedNodeService); when(mockedFilePlanService.getFilePlan(any(NodeRef.class))) .thenReturn(filePlan); // set-up application context when(mockedApplicationContext.getBean("dbNodeService")) .thenReturn(mockedNodeService); // setup retrying transaction helper Answer<Object> doInTransactionAnswer = new Answer<Object>() { @SuppressWarnings("rawtypes") @Override public Object answer(InvocationOnMock invocation) throws Throwable { RetryingTransactionCallback callback = (RetryingTransactionCallback)invocation.getArguments()[0]; return callback.execute(); } }; doAnswer(doInTransactionAnswer) .when(mockedRetryingTransactionHelper) .<Object>doInTransaction(any(RetryingTransactionCallback.class)); when(mockedTransactionService.getRetryingTransactionHelper()) .thenReturn(mockedRetryingTransactionHelper); // setup create authority Answer<String> createAuthorityAnswer = new Answer<String>() { public String answer(InvocationOnMock invocation) throws Throwable { return PermissionService.GROUP_PREFIX + (String)invocation.getArguments()[1]; } }; when(mockedAuthorityService.createAuthority(any(AuthorityType.class), anyString(), anyString(), anySet())) .thenAnswer(createAuthorityAnswer); // setup group prefixes readGroupPrefix = extendedSecurityService.getIPRGroupPrefixShortName(READER_GROUP_PREFIX, READERS); writeGroupPrefix = extendedSecurityService.getIPRGroupPrefixShortName(WRITER_GROUP_PREFIX, WRITERS); // make sure the users and groups exist Stream .of(USER, USER_W, GROUP, GROUP_W) .forEach((a) -> when(mockedAuthorityService.authorityExists(a)) .thenReturn(true)); } /** * Given that the root authority does not exist * When the application context is refreshed * Then the root authority is created */ @Test public void rootAuthorityDoesNotExist() { // group doesn't exist when(mockedAuthorityService.authorityExists(GROUP_PREFIX + ExtendedSecurityServiceImpl.ROOT_IPR_GROUP)) .thenReturn(false); // refresh context extendedSecurityService.onApplicationEvent(mock(ContextRefreshedEvent.class)); // verify group is created verify(mockedAuthorityService).createAuthority(AuthorityType.GROUP, ROOT_IPR_GROUP, ROOT_IPR_GROUP, Collections.singleton(RMAuthority.ZONE_APP_RM)); } /** * Given that the root authority exists * When the application context is refreshed * Then nothing happens */ @Test public void rootAuthorityDoesExist() { // group doesn't exist when(mockedAuthorityService.authorityExists(GROUP_PREFIX + ROOT_IPR_GROUP)) .thenReturn(true); // refresh context extendedSecurityService.onApplicationEvent(mock(ContextRefreshedEvent.class)); // verify group is created verify(mockedAuthorityService, never()).createAuthority(AuthorityType.GROUP, ROOT_IPR_GROUP, ROOT_IPR_GROUP, Collections.singleton(RMAuthority.ZONE_APP_RM)); } /** * Given that an IPR read group has read on a node * And that an IPR write group has filling on a node * When checking for the existence of extended permissions on that node * Then it will be confirmed */ @Test public void hasExtendedSecurityWithReadAndWriteGroups() { // setup permissions when(mockedPermissionService.getAllSetPermissions(nodeRef)) .thenReturn(HAS_EXTENDED_SECURITY); // has extended security assertTrue(extendedSecurityService.hasExtendedSecurity(nodeRef)); } /** * Given that there is no IPR read group has read on a node * When checking for the existence of extended permissions on that node * Then it will be denied */ @Test public void hasExtendedSecurityWithNoReadGroup() { // setup permissions Set<AccessPermission> permissions = Stream .of(new AccessPermissionImpl(AlfMock.generateText(), AccessStatus.ALLOWED, AlfMock.generateText(), 0), new AccessPermissionImpl(AlfMock.generateText(), AccessStatus.ALLOWED, AlfMock.generateText(), 1), new AccessPermissionImpl(AlfMock.generateText(), AccessStatus.ALLOWED, GROUP_PREFIX + WRITER_GROUP_PREFIX, 2)) .collect(Collectors.toSet()); when(mockedPermissionService.getAllSetPermissions(nodeRef)) .thenReturn(permissions); // has extended security assertFalse(extendedSecurityService.hasExtendedSecurity(nodeRef)); } /** * Given that there is no IPR write group has read on a node * When checking for the existence of extended permissions on that node * Then it will be denied */ @Test public void hasExtendedSecurityWithNoWriteGroup() { // setup permissions Set<AccessPermission> permissions = Stream .of(new AccessPermissionImpl(AlfMock.generateText(), AccessStatus.ALLOWED, GROUP_PREFIX + READER_GROUP_PREFIX, 0), new AccessPermissionImpl(AlfMock.generateText(), AccessStatus.ALLOWED, AlfMock.generateText(), 1), new AccessPermissionImpl(AlfMock.generateText(), AccessStatus.ALLOWED, AlfMock.generateText(), 2)) .collect(Collectors.toSet()); when(mockedPermissionService.getAllSetPermissions(nodeRef)) .thenReturn(permissions); // has extended security assertFalse(extendedSecurityService.hasExtendedSecurity(nodeRef)); } /** * Given that an IPR read group has no groups assigned permission * When checking for the existence of extended permissions on that node * Then it will be denied */ @Test public void hasExtendedSecurityWithNoAssignedGroups() { // setup permissions when(mockedPermissionService.getAllSetPermissions(nodeRef)) .thenReturn(HAS_NO_EXTENDED_SECURITY); // has extended security assertFalse(extendedSecurityService.hasExtendedSecurity(nodeRef)); } /** * Given that there are no IPR groups assigned * When I try and get the extended readers * The I will get an empty set */ @Test public void getExtendedReadersNoIPRGroupsAssigned() { // setup permissions when(mockedPermissionService.getAllSetPermissions(nodeRef)) .thenReturn(HAS_NO_EXTENDED_SECURITY); // get extended readers assertTrue(extendedSecurityService.getReaders(nodeRef).isEmpty()); } /** * Given that there are IPR groups assigned * When I try and get the extended readers * The I will get the set of readers */ @Test public void getExtendedReaders() { // setup permissions when(mockedPermissionService.getAllSetPermissions(nodeRef)) .thenReturn(HAS_EXTENDED_SECURITY); when(mockedAuthorityService.getContainedAuthorities(null, READER_GROUP_FULL_PREFIX, true)) .thenReturn(Stream .of(USER, GROUP) .collect(Collectors.toSet())); // get extended readers Set<String> extendedReaders = extendedSecurityService.getReaders(nodeRef); assertEquals(Stream .of(USER, GROUP) .collect(Collectors.toSet()), extendedReaders); } /** * Given that there are no IPR groups assigned * When I try and get the extended writers * The I will get an empty set */ @Test public void getExtendedWritersNoIPRGroupsAssigned() { // setup permissions when(mockedPermissionService.getAllSetPermissions(nodeRef)) .thenReturn(HAS_NO_EXTENDED_SECURITY); // get extended writers assertTrue(extendedSecurityService.getWriters(nodeRef).isEmpty()); } /** * Given that there are IPR groups assigned * When I try and get the extended writers * The I will get the set of writers */ @Test public void getExtendedWriters() { // setup permissions when(mockedPermissionService.getAllSetPermissions(nodeRef)) .thenReturn(HAS_EXTENDED_SECURITY); when(mockedAuthorityService.getContainedAuthorities(null, WRITER_GROUP_FULL_PREFIX, true)) .thenReturn(Stream .of(USER, GROUP) .collect(Collectors.toSet())); // get extended writers Set<String> extendedWriters = extendedSecurityService.getWriters(nodeRef); assertEquals(Stream .of(USER, GROUP) .collect(Collectors.toSet()), extendedWriters); } /** * Given a node with no previous IPR groups assigned * And no IPR group matching authorities * When I add some read and write authorities * Then new IPR groups are created * And they are assigned to the node * And they are added to the RM roles */ @Test public void addExtendedSecurityForTheFirstTimeAndCreateGroups() { // group names String readGroup = extendedSecurityService.getIPRGroupShortName(READER_GROUP_PREFIX, READERS, 0); String writeGroup = extendedSecurityService.getIPRGroupShortName(WRITER_GROUP_PREFIX, WRITERS, 0); // setup query results when(mockedReadPagingResults.getPage()) .thenReturn(Collections.emptyList()); when(mockedAuthorityService.getAuthorities( eq(AuthorityType.GROUP), eq(RMAuthority.ZONE_APP_RM), any(String.class), eq(false), eq(false), any(PagingRequest.class))) .thenReturn(mockedReadPagingResults); // add extended security extendedSecurityService.set(nodeRef, READERS, WRITERS); // verify no old permissions needing to be cleared verify(mockedPermissionService, never()).clearPermission(eq(nodeRef), anyString()); // verify read group created correctly verify(mockedAuthorityService).createAuthority(AuthorityType.GROUP, readGroup, readGroup, Collections.singleton(RMAuthority.ZONE_APP_RM)); readGroup = GROUP_PREFIX + readGroup; verify(mockedAuthorityService).addAuthority(GROUP_PREFIX + ROOT_IPR_GROUP, readGroup); verify(mockedAuthorityService).addAuthority(readGroup, USER); verify(mockedAuthorityService).addAuthority(readGroup, GROUP); // verify write group created correctly verify(mockedAuthorityService).createAuthority(AuthorityType.GROUP, writeGroup, writeGroup, Collections.singleton(RMAuthority.ZONE_APP_RM)); writeGroup = GROUP_PREFIX + writeGroup; verify(mockedAuthorityService).addAuthority(GROUP_PREFIX + ROOT_IPR_GROUP, writeGroup); verify(mockedAuthorityService).addAuthority(writeGroup, USER_W); verify(mockedAuthorityService).addAuthority(writeGroup, GROUP_W); // verify groups assigned to RM roles verify(mockedFilePlanRoleService).assignRoleToAuthority(filePlan, FilePlanRoleService.ROLE_EXTENDED_READERS, readGroup); verify(mockedFilePlanRoleService).assignRoleToAuthority(filePlan, FilePlanRoleService.ROLE_EXTENDED_WRITERS, writeGroup); // verify permissions are assigned to node verify(mockedPermissionService).setPermission(nodeRef, readGroup, RMPermissionModel.READ_RECORDS, true); verify(mockedPermissionService).setPermission(nodeRef, writeGroup, RMPermissionModel.FILING, true); } /** * Given a node with no previous IPR groups assigned * And existing IPR groups matching * When I add some read and write authorities * Then the existing IPR groups are used * And they are assigned to the node * And do not not need to be re-added to the RM roles */ @Test public void addExtendedSecurityForTheFirstTimeAndReuseGroups() { // group names String readGroup = readGroupPrefix + "0"; String writeGroup = writeGroupPrefix + "0"; // setup query results when(mockedReadPagingResults.getPage()) .thenReturn(Stream.of(GROUP_PREFIX + readGroup).collect(Collectors.toList())); when(mockedAuthorityService.getAuthorities( eq(AuthorityType.GROUP), eq(RMAuthority.ZONE_APP_RM), eq(readGroupPrefix), eq(false), eq(false), any(PagingRequest.class))) .thenReturn(mockedReadPagingResults); when(mockedWritePagingResults.getPage()) .thenReturn(Stream.of(GROUP_PREFIX + writeGroup).collect(Collectors.toList())); when(mockedAuthorityService.getAuthorities( eq(AuthorityType.GROUP), eq(RMAuthority.ZONE_APP_RM), eq(writeGroupPrefix), eq(false), eq(false), any(PagingRequest.class))) .thenReturn(mockedWritePagingResults); // setup exact match when(mockedAuthorityService.authorityExists(GROUP_PREFIX + writeGroup)) .thenReturn(true); when(mockedAuthorityService.getContainedAuthorities(null, GROUP_PREFIX + readGroup, true)) .thenReturn(Stream .of(USER, GROUP) .collect(Collectors.toSet())); when(mockedAuthorityService.getContainedAuthorities(null, GROUP_PREFIX + writeGroup, true)) .thenReturn(Stream .of(USER_W, GROUP_W) .collect(Collectors.toSet())); // add extended security extendedSecurityService.set(nodeRef, READERS, WRITERS); // verify no old permissions needing to be cleared verify(mockedPermissionService, never()).clearPermission(eq(nodeRef), anyString()); // verify read group is not recreated verify(mockedAuthorityService, never()).createAuthority(AuthorityType.GROUP, readGroup, readGroup, Collections.singleton(RMAuthority.ZONE_APP_RM)); readGroup = GROUP_PREFIX + readGroup; verify(mockedAuthorityService, never()).addAuthority(GROUP_PREFIX + ROOT_IPR_GROUP, readGroup); verify(mockedAuthorityService, never()).addAuthority(readGroup, USER); verify(mockedAuthorityService, never()).addAuthority(readGroup, GROUP); // verify write group is not recreated verify(mockedAuthorityService, never()).createAuthority(AuthorityType.GROUP, writeGroup, writeGroup, Collections.singleton(RMAuthority.ZONE_APP_RM)); writeGroup = GROUP_PREFIX + writeGroup; verify(mockedAuthorityService, never()).addAuthority(readGroup, writeGroup); verify(mockedAuthorityService, never()).addAuthority(writeGroup, USER_W); verify(mockedAuthorityService, never()).addAuthority(writeGroup, GROUP_W); // verify groups assigned to RM roles verify(mockedFilePlanRoleService).assignRoleToAuthority(filePlan, FilePlanRoleService.ROLE_EXTENDED_READERS, readGroup); verify(mockedFilePlanRoleService).assignRoleToAuthority(filePlan, FilePlanRoleService.ROLE_EXTENDED_WRITERS, writeGroup); // verify permissions are assigned to node verify(mockedPermissionService).setPermission(nodeRef, readGroup, RMPermissionModel.READ_RECORDS, true); verify(mockedPermissionService).setPermission(nodeRef, writeGroup, RMPermissionModel.FILING, true); } /** * Given a node with no previous IPR groups assigned * And existing IPR groups matches existing has, but not exact match * When I add some read and write authorities * Then new groups are created * And they are assigned to the node * And added to the RM roles */ @Test public void addExtendedSecurityForTheFirstTimeAndCreateGroupsAfterClash() { // group names String readGroup = readGroupPrefix + "0"; String writeGroup = writeGroupPrefix + "0"; // setup query results when(mockedReadPagingResults.getPage()) .thenReturn(Stream.of(GROUP_PREFIX + readGroup).collect(Collectors.toList())); when(mockedAuthorityService.getAuthorities( eq(AuthorityType.GROUP), eq(RMAuthority.ZONE_APP_RM), eq(readGroupPrefix), eq(false), eq(false), any(PagingRequest.class))) .thenReturn(mockedReadPagingResults); when(mockedWritePagingResults.getPage()) .thenReturn(Stream.of(GROUP_PREFIX + writeGroup).collect(Collectors.toList())); when(mockedAuthorityService.getAuthorities( eq(AuthorityType.GROUP), eq(RMAuthority.ZONE_APP_RM), eq(writeGroupPrefix), eq(false), eq(false), any(PagingRequest.class))) .thenReturn(mockedWritePagingResults); // setup exact match when(mockedAuthorityService.authorityExists(GROUP_PREFIX + writeGroup)) .thenReturn(true); when(mockedAuthorityService.getContainedAuthorities(null, GROUP_PREFIX + readGroup, true)) .thenReturn(Stream .of(USER, GROUP, AlfMock.generateText()) .collect(Collectors.toSet())); when(mockedAuthorityService.getContainedAuthorities(null, GROUP_PREFIX + writeGroup, true)) .thenReturn(Stream .of(USER_W, AlfMock.generateText()) .collect(Collectors.toSet())); // add extended security extendedSecurityService.set(nodeRef, READERS, WRITERS); // verify no old permissions needing to be cleared verify(mockedPermissionService, never()).clearPermission(eq(nodeRef), anyString()); // new group names readGroup = extendedSecurityService.getIPRGroupShortName(READER_GROUP_PREFIX, READERS, 1); writeGroup = extendedSecurityService.getIPRGroupShortName(WRITER_GROUP_PREFIX, WRITERS, 1); // verify read group created correctly verify(mockedAuthorityService).createAuthority(AuthorityType.GROUP, readGroup, readGroup, Collections.singleton(RMAuthority.ZONE_APP_RM)); readGroup = GROUP_PREFIX + readGroup; verify(mockedAuthorityService).addAuthority(GROUP_PREFIX + ROOT_IPR_GROUP, readGroup); verify(mockedAuthorityService).addAuthority(readGroup, USER); verify(mockedAuthorityService).addAuthority(readGroup, GROUP); // verify write group created correctly verify(mockedAuthorityService).createAuthority(AuthorityType.GROUP, writeGroup, writeGroup, Collections.singleton(RMAuthority.ZONE_APP_RM)); writeGroup = GROUP_PREFIX + writeGroup; verify(mockedAuthorityService).addAuthority(GROUP_PREFIX + ROOT_IPR_GROUP, writeGroup); verify(mockedAuthorityService).addAuthority(writeGroup, USER_W); verify(mockedAuthorityService).addAuthority(writeGroup, GROUP_W); // verify groups assigned to RM roles verify(mockedFilePlanRoleService).assignRoleToAuthority(filePlan, FilePlanRoleService.ROLE_EXTENDED_READERS, readGroup); verify(mockedFilePlanRoleService).assignRoleToAuthority(filePlan, FilePlanRoleService.ROLE_EXTENDED_WRITERS, writeGroup); // verify permissions are assigned to node verify(mockedPermissionService).setPermission(nodeRef, readGroup, RMPermissionModel.READ_RECORDS, true); verify(mockedPermissionService).setPermission(nodeRef, writeGroup, RMPermissionModel.FILING, true); } /** * Given a node with no previous IPR groups assigned * And existing IPR groups matching, but found on second page of find results * When I add some read and write authorities * Then the existing IPR groups are used * And they are assigned to the node * And do not not need to be re-added to the RM roles */ @Test public void addExtendedSecurityWithResultPaging() { // group names String readGroup = readGroupPrefix + "0"; String writeGroup = writeGroupPrefix + "0"; // create fity results List<String> fiftyResults = new ArrayList<String>(50); for (int i = 0; i < 50; i++) { fiftyResults.add(AlfMock.generateText()); } // setup query results when(mockedReadPagingResults.getPage()) .thenReturn(fiftyResults) .thenReturn(Stream.of(GROUP_PREFIX + readGroup).collect(Collectors.toList())); when(mockedAuthorityService.getAuthorities( eq(AuthorityType.GROUP), eq(RMAuthority.ZONE_APP_RM), eq(readGroupPrefix), eq(false), eq(false), any(PagingRequest.class))) .thenReturn(mockedReadPagingResults); when(mockedWritePagingResults.getPage()) .thenReturn(fiftyResults) .thenReturn(Stream.of(GROUP_PREFIX + writeGroup).collect(Collectors.toList())); when(mockedAuthorityService.getAuthorities( eq(AuthorityType.GROUP), eq(RMAuthority.ZONE_APP_RM), eq(writeGroupPrefix), eq(false), eq(false), any(PagingRequest.class))) .thenReturn(mockedWritePagingResults); // setup exact match when(mockedAuthorityService.authorityExists(GROUP_PREFIX + writeGroup)) .thenReturn(true); when(mockedAuthorityService.getContainedAuthorities(null, GROUP_PREFIX + readGroup, true)) .thenReturn(Stream .of(USER, GROUP) .collect(Collectors.toSet())); when(mockedAuthorityService.getContainedAuthorities(null, GROUP_PREFIX + writeGroup, true)) .thenReturn(Stream .of(USER_W, GROUP_W) .collect(Collectors.toSet())); // add extended security extendedSecurityService.set(nodeRef, READERS, WRITERS); // verify no old permissions needing to be cleared verify(mockedPermissionService, never()).clearPermission(eq(nodeRef), anyString()); // verify read group is not recreated verify(mockedAuthorityService, never()).createAuthority(AuthorityType.GROUP, readGroup, readGroup, Collections.singleton(RMAuthority.ZONE_APP_RM)); readGroup = GROUP_PREFIX + readGroup; verify(mockedAuthorityService, never()).addAuthority(GROUP_PREFIX + ROOT_IPR_GROUP, readGroup); verify(mockedAuthorityService, never()).addAuthority(readGroup, USER); verify(mockedAuthorityService, never()).addAuthority(readGroup, GROUP); // verify write group is not recreated verify(mockedAuthorityService, never()).createAuthority(AuthorityType.GROUP, writeGroup, writeGroup, Collections.singleton(RMAuthority.ZONE_APP_RM)); writeGroup = GROUP_PREFIX + writeGroup; verify(mockedAuthorityService, never()).addAuthority(readGroup, writeGroup); verify(mockedAuthorityService, never()).addAuthority(writeGroup, USER_W); verify(mockedAuthorityService, never()).addAuthority(writeGroup, GROUP_W); // verify groups assigned to RM roles verify(mockedFilePlanRoleService).assignRoleToAuthority(filePlan, FilePlanRoleService.ROLE_EXTENDED_READERS, readGroup); verify(mockedFilePlanRoleService).assignRoleToAuthority(filePlan, FilePlanRoleService.ROLE_EXTENDED_WRITERS, writeGroup); // verify permissions are assigned to node verify(mockedPermissionService).setPermission(nodeRef, readGroup, RMPermissionModel.READ_RECORDS, true); verify(mockedPermissionService).setPermission(nodeRef, writeGroup, RMPermissionModel.FILING, true); } /** * Given that a node already has extended security * When I add extended security * Then the existing extended security is replaced with the new extended security */ @Test public void addExtendedSecurityToNodeWithExtendedSecurity() { // group names String readGroup = extendedSecurityService.getIPRGroupShortName(READER_GROUP_FULL_PREFIX, READERS, 0); String writeGroup = extendedSecurityService.getIPRGroupShortName(WRITER_GROUP_FULL_PREFIX, WRITERS, 0); // setup permissions Set<AccessPermission> permissions = Stream .of(new AccessPermissionImpl(AlfMock.generateText(), AccessStatus.ALLOWED, readGroup, 0), new AccessPermissionImpl(AlfMock.generateText(), AccessStatus.ALLOWED, AlfMock.generateText(), 1), new AccessPermissionImpl(AlfMock.generateText(), AccessStatus.ALLOWED, writeGroup, 2)) .collect(Collectors.toSet()); when(mockedPermissionService.getAllSetPermissions(nodeRef)) .thenReturn(permissions); // set revised reader and writers String user = generateText(); String group = generateText(); String userW = generateText(); String groupW = generateText(); Set<String> newReaders = Stream.of(user, group).collect(Collectors.toSet()); Set<String> newWriters = Stream.of(userW, groupW).collect(Collectors.toSet()); // new group names String newReadGroup = extendedSecurityService.getIPRGroupShortName(READER_GROUP_PREFIX, newReaders, 0); String newWriteGroup = extendedSecurityService.getIPRGroupShortName(WRITER_GROUP_PREFIX, newWriters, 0); // make sure users and groups exist Stream .of(user, group, userW, groupW) .forEach((a) -> when(mockedAuthorityService.authorityExists(a)) .thenReturn(true)); // setup query results for no group matches when(mockedReadPagingResults.getPage()) .thenReturn(Collections.emptyList()); when(mockedAuthorityService.getAuthorities( eq(AuthorityType.GROUP), eq(RMAuthority.ZONE_APP_RM), any(String.class), eq(false), eq(false), any(PagingRequest.class))) .thenReturn(mockedReadPagingResults); // set extended security extendedSecurityService.set(nodeRef, newReaders, newWriters); // verify that the old permissions are cleared verify(mockedPermissionService).clearPermission(nodeRef, readGroup); verify(mockedPermissionService).clearPermission(nodeRef, writeGroup); // verify read group created correctly verify(mockedAuthorityService).createAuthority(AuthorityType.GROUP, newReadGroup, newReadGroup, Collections.singleton(RMAuthority.ZONE_APP_RM)); newReadGroup = GROUP_PREFIX + newReadGroup; verify(mockedAuthorityService).addAuthority(GROUP_PREFIX + ROOT_IPR_GROUP, newReadGroup); verify(mockedAuthorityService).addAuthority(newReadGroup, user); verify(mockedAuthorityService).addAuthority(newReadGroup, group); // verify write group created correctly verify(mockedAuthorityService).createAuthority(AuthorityType.GROUP, newWriteGroup, newWriteGroup, Collections.singleton(RMAuthority.ZONE_APP_RM)); newWriteGroup = GROUP_PREFIX + newWriteGroup; verify(mockedAuthorityService).addAuthority(GROUP_PREFIX + ROOT_IPR_GROUP, newWriteGroup); verify(mockedAuthorityService).addAuthority(newWriteGroup, userW); verify(mockedAuthorityService).addAuthority(newWriteGroup, groupW); // verify groups assigned to RM roles verify(mockedFilePlanRoleService).assignRoleToAuthority(filePlan, FilePlanRoleService.ROLE_EXTENDED_READERS, newReadGroup); verify(mockedFilePlanRoleService).assignRoleToAuthority(filePlan, FilePlanRoleService.ROLE_EXTENDED_WRITERS, newWriteGroup); // verify permissions are assigned to node verify(mockedPermissionService).setPermission(nodeRef, newReadGroup, RMPermissionModel.READ_RECORDS, true); verify(mockedPermissionService).setPermission(nodeRef, newWriteGroup, RMPermissionModel.FILING, true); } /** * Given that a node has renditions * When I add extended security * Then they are applied to the renditions */ @Test public void extendedSecurityAddedToRenditions() { // group names String readGroup = extendedSecurityService.getIPRGroupShortName(READER_GROUP_PREFIX, READERS, 0); String writeGroup = extendedSecurityService.getIPRGroupShortName(WRITER_GROUP_PREFIX, WRITERS, 0); // setup query results when(mockedReadPagingResults.getPage()) .thenReturn(Collections.emptyList()); when(mockedAuthorityService.getAuthorities( eq(AuthorityType.GROUP), eq(RMAuthority.ZONE_APP_RM), any(String.class), eq(false), eq(false), any(PagingRequest.class))) .thenReturn(mockedReadPagingResults); // setup renditions NodeRef renditionNodeRef = AlfMock.generateNodeRef(mockedNodeService); when(mockedNodeService.hasAspect(nodeRef, RecordsManagementModel.ASPECT_RECORD)) .thenReturn(true); when(mockedChildAssociationRef.getChildRef()) .thenReturn(renditionNodeRef); when(mockedNodeService.getChildAssocs(nodeRef, RenditionModel.ASSOC_RENDITION, RegexQNamePattern.MATCH_ALL)) .thenReturn(Collections.singletonList(mockedChildAssociationRef)); // add extended security extendedSecurityService.set(nodeRef, READERS, WRITERS); // verify no old permissions needing to be cleared verify(mockedPermissionService, never()).clearPermission(eq(nodeRef), anyString()); // verify read group created correctly verify(mockedAuthorityService).createAuthority(AuthorityType.GROUP, readGroup, readGroup, Collections.singleton(RMAuthority.ZONE_APP_RM)); readGroup = GROUP_PREFIX + readGroup; verify(mockedAuthorityService).addAuthority(GROUP_PREFIX + ROOT_IPR_GROUP, readGroup); verify(mockedAuthorityService).addAuthority(readGroup, USER); verify(mockedAuthorityService).addAuthority(readGroup, GROUP); // verify write group created correctly verify(mockedAuthorityService).createAuthority(AuthorityType.GROUP, writeGroup, writeGroup, Collections.singleton(RMAuthority.ZONE_APP_RM)); writeGroup = GROUP_PREFIX + writeGroup; verify(mockedAuthorityService).addAuthority(GROUP_PREFIX + ROOT_IPR_GROUP, writeGroup); verify(mockedAuthorityService).addAuthority(writeGroup, USER_W); verify(mockedAuthorityService).addAuthority(writeGroup, GROUP_W); // verify groups assigned to RM roles verify(mockedFilePlanRoleService).assignRoleToAuthority(filePlan, FilePlanRoleService.ROLE_EXTENDED_READERS, readGroup); verify(mockedFilePlanRoleService).assignRoleToAuthority(filePlan, FilePlanRoleService.ROLE_EXTENDED_WRITERS, writeGroup); // verify permissions are assigned to node verify(mockedPermissionService).setPermission(nodeRef, readGroup, RMPermissionModel.READ_RECORDS, true); verify(mockedPermissionService).setPermission(nodeRef, writeGroup, RMPermissionModel.FILING, true); // verify permissions are assigned to the rendition verify(mockedPermissionService).setPermission(renditionNodeRef, readGroup, RMPermissionModel.READ_RECORDS, true); verify(mockedPermissionService).setPermission(renditionNodeRef, writeGroup, RMPermissionModel.FILING, true); } /** * Given that a node has extended security * When I remove the extended security * Then the inplace groups permissions are removed */ @Test public void removeAllExtendedSecurity() { // group names String readGroup = extendedSecurityService.getIPRGroupShortName(READER_GROUP_FULL_PREFIX, READERS, 0); String writeGroup = extendedSecurityService.getIPRGroupShortName(WRITER_GROUP_FULL_PREFIX, WRITERS, 0); // setup permissions Set<AccessPermission> permissions = Stream .of(new AccessPermissionImpl(AlfMock.generateText(), AccessStatus.ALLOWED, readGroup, 0), new AccessPermissionImpl(AlfMock.generateText(), AccessStatus.ALLOWED, AlfMock.generateText(), 1), new AccessPermissionImpl(AlfMock.generateText(), AccessStatus.ALLOWED, writeGroup, 2)) .collect(Collectors.toSet()); when(mockedPermissionService.getAllSetPermissions(nodeRef)) .thenReturn(permissions); // remove extended security extendedSecurityService.remove(nodeRef); // verify that the groups permissions have been removed verify(mockedPermissionService).clearPermission(nodeRef, readGroup); verify(mockedPermissionService).clearPermission(nodeRef, writeGroup); } /** * Given that a node has no extended security * When I remove the extended security * Then nothing happens */ @Test public void noExtendedSecurityToRemove() { when(mockedPermissionService.getAllSetPermissions(nodeRef)) .thenReturn(HAS_NO_EXTENDED_SECURITY); // remove extended security extendedSecurityService.remove(nodeRef); // verify that the groups permissions have been removed verify(mockedPermissionService, never()).clearPermission(eq(nodeRef), anyString()); } /** * Given that node has renditions * When I remove the extended security for a node * Then the extended security is also removed from the renditions */ @Test public void removeExtendedSecurityFromRenditions() { // group names String readGroup = extendedSecurityService.getIPRGroupShortName(READER_GROUP_FULL_PREFIX, READERS, 0); String writeGroup = extendedSecurityService.getIPRGroupShortName(WRITER_GROUP_FULL_PREFIX, WRITERS, 0); // setup renditions NodeRef renditionNodeRef = AlfMock.generateNodeRef(mockedNodeService); when(mockedNodeService.hasAspect(nodeRef, RecordsManagementModel.ASPECT_RECORD)) .thenReturn(true); when(mockedChildAssociationRef.getChildRef()) .thenReturn(renditionNodeRef); when(mockedNodeService.getChildAssocs(nodeRef, RenditionModel.ASSOC_RENDITION, RegexQNamePattern.MATCH_ALL)) .thenReturn(Collections.singletonList(mockedChildAssociationRef)); // setup permissions Set<AccessPermission> permissions = Stream .of(new AccessPermissionImpl(AlfMock.generateText(), AccessStatus.ALLOWED, readGroup, 0), new AccessPermissionImpl(AlfMock.generateText(), AccessStatus.ALLOWED, AlfMock.generateText(), 1), new AccessPermissionImpl(AlfMock.generateText(), AccessStatus.ALLOWED, writeGroup, 2)) .collect(Collectors.toSet()); when(mockedPermissionService.getAllSetPermissions(nodeRef)) .thenReturn(permissions); // remove extended security extendedSecurityService.remove(nodeRef); // verify that the groups permissions have been removed verify(mockedPermissionService).clearPermission(nodeRef, readGroup); verify(mockedPermissionService).clearPermission(nodeRef, writeGroup); // verify that the groups permissions have been removed from the rendition verify(mockedPermissionService).clearPermission(renditionNodeRef, readGroup); verify(mockedPermissionService).clearPermission(renditionNodeRef, writeGroup); } }