mirror of
https://github.com/Alfresco/alfresco-community-repo.git
synced 2025-07-31 17:39:05 +00:00
Merge release/V2.3.0.x into release/V2.3
This commit is contained in:
@@ -0,0 +1,928 @@
|
||||
/*
|
||||
* #%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);
|
||||
|
||||
}
|
||||
}
|
@@ -18,13 +18,10 @@
|
||||
*/
|
||||
package org.alfresco.module.org_alfresco_module_rm.security;
|
||||
|
||||
import static org.mockito.Matchers.anyString;
|
||||
import static org.mockito.Matchers.eq;
|
||||
import static org.mockito.Mockito.doReturn;
|
||||
import static org.mockito.Mockito.never;
|
||||
import static org.mockito.Mockito.times;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.verifyNoMoreInteractions;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
@@ -163,16 +160,7 @@ public class FilePlanPermissionServiceImplUnitTest extends BaseUnitTest
|
||||
filePlanPermissionService.setPermission(unfiledRecordFolder, AUTHORITY, RMPermissionModel.READ_RECORDS);
|
||||
|
||||
// verify permission set on target node
|
||||
verify(mockedPermissionService, times(1)).setPermission(unfiledRecordFolder, AUTHORITY, RMPermissionModel.READ_RECORDS, true);
|
||||
|
||||
// verify READ permission set up hierarchy
|
||||
verify(mockedPermissionService, times(1)).setPermission(unfiledRecordContainer, AUTHORITY, RMPermissionModel.READ_RECORDS, true);
|
||||
verify(mockedPermissionService, times(1)).setPermission(filePlan, AUTHORITY, RMPermissionModel.READ_RECORDS, true);
|
||||
|
||||
// verify READ permission set down hierarchy
|
||||
verify(mockedPermissionService, times(1)).setPermission(unfiledRecordFolderChild, AUTHORITY, RMPermissionModel.READ_RECORDS, true);
|
||||
verify(mockedPermissionService, times(1)).setPermission(unfiledRecord, AUTHORITY, RMPermissionModel.READ_RECORDS, true);
|
||||
|
||||
verify(mockedPermissionService, times(1)).setPermission(unfiledRecordFolder, AUTHORITY, RMPermissionModel.READ_RECORDS, true);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -185,15 +173,7 @@ public class FilePlanPermissionServiceImplUnitTest extends BaseUnitTest
|
||||
filePlanPermissionService.setPermission(unfiledRecordFolder, AUTHORITY, RMPermissionModel.FILING);
|
||||
|
||||
// verify permission set on target node
|
||||
verify(mockedPermissionService, times(1)).setPermission(unfiledRecordFolder, AUTHORITY, RMPermissionModel.FILING, true);
|
||||
|
||||
// verify READ permission set up hierarchy
|
||||
verify(mockedPermissionService, times(1)).setPermission(unfiledRecordContainer, AUTHORITY, RMPermissionModel.READ_RECORDS, true);
|
||||
verify(mockedPermissionService, times(1)).setPermission(filePlan, AUTHORITY, RMPermissionModel.READ_RECORDS, true);
|
||||
|
||||
// verify FILING permission set down hierarchy
|
||||
verify(mockedPermissionService, times(1)).setPermission(unfiledRecordFolderChild, AUTHORITY, RMPermissionModel.FILING, true);
|
||||
verify(mockedPermissionService, times(1)).setPermission(unfiledRecord, AUTHORITY, RMPermissionModel.FILING, true);
|
||||
verify(mockedPermissionService, times(1)).setPermission(unfiledRecordFolder, AUTHORITY, RMPermissionModel.FILING, true);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -207,14 +187,6 @@ public class FilePlanPermissionServiceImplUnitTest extends BaseUnitTest
|
||||
|
||||
// verify permission deleted on target node
|
||||
verify(mockedPermissionService, times(1)).deletePermission(unfiledRecordFolder, AUTHORITY, RMPermissionModel.READ_RECORDS);
|
||||
|
||||
// verify no permissions deleted up the hierarchy
|
||||
verify(mockedPermissionService, never()).deletePermission(eq(unfiledRecordContainer), eq(AUTHORITY), anyString());
|
||||
verify(mockedPermissionService, never()).deletePermission(eq(filePlan), eq(AUTHORITY), anyString());
|
||||
|
||||
// verify READ permission removed down hierarchy
|
||||
verify(mockedPermissionService, times(1)).deletePermission(unfiledRecordFolderChild, AUTHORITY, RMPermissionModel.READ_RECORDS);
|
||||
verify(mockedPermissionService, times(1)).deletePermission(unfiledRecord, AUTHORITY, RMPermissionModel.READ_RECORDS);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -228,16 +200,6 @@ public class FilePlanPermissionServiceImplUnitTest extends BaseUnitTest
|
||||
|
||||
// verify permission set on target node
|
||||
verify(mockedPermissionService, times(1)).setPermission(holdContainer, AUTHORITY, RMPermissionModel.READ_RECORDS, true);
|
||||
|
||||
// verify READ permission set up hierarchy
|
||||
verify(mockedPermissionService, times(1)).setPermission(filePlan, AUTHORITY, RMPermissionModel.READ_RECORDS, true);
|
||||
|
||||
// verify READ permission set on hold
|
||||
verify(mockedPermissionService, times(1)).setPermission(hold, AUTHORITY, RMPermissionModel.READ_RECORDS, true);
|
||||
|
||||
// verify permission not set on child of hold
|
||||
verify(mockedPermissionService, never()).setPermission(eq(heldRecord), eq(AUTHORITY), anyString(), eq(true));
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -250,17 +212,7 @@ public class FilePlanPermissionServiceImplUnitTest extends BaseUnitTest
|
||||
filePlanPermissionService.setPermission(holdContainer, AUTHORITY, RMPermissionModel.FILING);
|
||||
|
||||
// verify permission set on target node
|
||||
verify(mockedPermissionService, times(1)).setPermission(holdContainer, AUTHORITY, RMPermissionModel.FILING, true);
|
||||
|
||||
// verify READ permission set up hierarchy
|
||||
verify(mockedPermissionService, times(1)).setPermission(filePlan, AUTHORITY, RMPermissionModel.READ_RECORDS, true);
|
||||
|
||||
// verify FILING permission set on hold
|
||||
verify(mockedPermissionService, times(1)).setPermission(hold, AUTHORITY, RMPermissionModel.FILING, true);
|
||||
|
||||
// verify permission not set on child of hold
|
||||
verify(mockedPermissionService, never()).setPermission(eq(heldRecord), eq(AUTHORITY), anyString(), eq(true));
|
||||
|
||||
verify(mockedPermissionService, times(1)).setPermission(holdContainer, AUTHORITY, RMPermissionModel.FILING, true);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -274,13 +226,6 @@ public class FilePlanPermissionServiceImplUnitTest extends BaseUnitTest
|
||||
|
||||
// verify permission set on target node
|
||||
verify(mockedPermissionService, times(1)).setPermission(hold, AUTHORITY, RMPermissionModel.READ_RECORDS, true);
|
||||
|
||||
// verify READ permission set up hierarchy
|
||||
verify(mockedPermissionService, times(1)).setPermission(holdContainer, AUTHORITY, RMPermissionModel.READ_RECORDS, true);
|
||||
verify(mockedPermissionService, times(1)).setPermission(filePlan, AUTHORITY, RMPermissionModel.READ_RECORDS, true);
|
||||
|
||||
// verify permission not set on child of hold
|
||||
verify(mockedPermissionService, never()).setPermission(eq(heldRecord), eq(AUTHORITY), anyString(), eq(true));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -293,14 +238,7 @@ public class FilePlanPermissionServiceImplUnitTest extends BaseUnitTest
|
||||
filePlanPermissionService.setPermission(hold, AUTHORITY, RMPermissionModel.FILING);
|
||||
|
||||
// verify permission set on target node
|
||||
verify(mockedPermissionService, times(1)).setPermission(hold, AUTHORITY, RMPermissionModel.FILING, true);
|
||||
|
||||
// verify READ permission set up hierarchy
|
||||
verify(mockedPermissionService, times(1)).setPermission(holdContainer, AUTHORITY, RMPermissionModel.READ_RECORDS, true);
|
||||
verify(mockedPermissionService, times(1)).setPermission(filePlan, AUTHORITY, RMPermissionModel.READ_RECORDS, true);
|
||||
|
||||
// verify permission not set on child of hold
|
||||
verify(mockedPermissionService, never()).setPermission(eq(heldRecord), eq(AUTHORITY), anyString(), eq(true));
|
||||
verify(mockedPermissionService, times(1)).setPermission(hold, AUTHORITY, RMPermissionModel.FILING, true);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -313,10 +251,6 @@ public class FilePlanPermissionServiceImplUnitTest extends BaseUnitTest
|
||||
// setup basic file and read for authorities
|
||||
perms.add(new AccessPermissionImpl(RMPermissionModel.READ_RECORDS, AccessStatus.ALLOWED, AUTHORITY, 0));
|
||||
perms.add(new AccessPermissionImpl(RMPermissionModel.FILING, AccessStatus.ALLOWED, AUTHORITY2, 1));
|
||||
|
||||
// setup in-place readers and writers
|
||||
perms.add(new AccessPermissionImpl(RMPermissionModel.READ_RECORDS, AccessStatus.ALLOWED, ExtendedReaderDynamicAuthority.EXTENDED_READER, 2));
|
||||
perms.add(new AccessPermissionImpl(RMPermissionModel.FILING, AccessStatus.ALLOWED, ExtendedWriterDynamicAuthority.EXTENDED_WRITER, 3));
|
||||
|
||||
doReturn(perms).when(mockedPermissionService).getAllSetPermissions(nodeRef);
|
||||
}
|
||||
@@ -324,13 +258,12 @@ public class FilePlanPermissionServiceImplUnitTest extends BaseUnitTest
|
||||
/**
|
||||
* Helper to verify the core permissions have been initialized correctly
|
||||
*/
|
||||
private void verifyInitPermissions(NodeRef nodeRef)
|
||||
private void verifyInitPermissions(NodeRef nodeRef, boolean isInherited)
|
||||
{
|
||||
verify(mockedPermissionService, times(1)).setInheritParentPermissions(nodeRef, false);
|
||||
verify(mockedPermissionService, times(1)).clearPermission(nodeRef, null);
|
||||
verify(mockedPermissionService, times(1)).setPermission(nodeRef, ExtendedReaderDynamicAuthority.EXTENDED_READER, RMPermissionModel.READ_RECORDS, true);
|
||||
verify(mockedPermissionService, times(1)).setPermission(nodeRef, ExtendedWriterDynamicAuthority.EXTENDED_WRITER, RMPermissionModel.FILING, true);
|
||||
verify(mockedOwnableService, times(1)).setOwner(nodeRef, OwnableService.NO_OWNER);
|
||||
verify(mockedPermissionService).getAllSetPermissions(nodeRef);
|
||||
verify(mockedPermissionService).setInheritParentPermissions(nodeRef, isInherited);
|
||||
verify(mockedPermissionService).clearPermission(nodeRef, null);
|
||||
verify(mockedOwnableService).setOwner(nodeRef, OwnableService.NO_OWNER);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -341,21 +274,20 @@ public class FilePlanPermissionServiceImplUnitTest extends BaseUnitTest
|
||||
* @param read verification mode relating to setting read on the child
|
||||
* @param filling verification mode relating to setting filling on the child
|
||||
*/
|
||||
private void verifyInitPermissions(NodeRef parent, NodeRef child, VerificationMode read, VerificationMode filling)
|
||||
private void verifyInitPermissions(NodeRef parent, NodeRef child, VerificationMode read, VerificationMode filling, boolean isParentFilePlan, boolean isInherited)
|
||||
{
|
||||
// verify the core permissions are set-up correctly
|
||||
verifyInitPermissions(child);
|
||||
|
||||
// verify the permissions came from the correct parent
|
||||
verify(mockedPermissionService).getAllSetPermissions(parent);
|
||||
|
||||
// verify all the inherited permissions are set correctly (note read are not inherited from fileplan)
|
||||
verify(mockedPermissionService, filling).setPermission(child, AUTHORITY2, RMPermissionModel.FILING, true);
|
||||
verify(mockedPermissionService, read).setPermission(child, AUTHORITY, RMPermissionModel.READ_RECORDS, true);
|
||||
|
||||
// verify that there are no unaccounted for interactions with the permission service
|
||||
verifyNoMoreInteractions(mockedPermissionService);
|
||||
verifyInitPermissions(child, isInherited);
|
||||
|
||||
if (isParentFilePlan)
|
||||
{
|
||||
// verify the permissions came from the correct parent
|
||||
verify(mockedPermissionService).getAllSetPermissions(parent);
|
||||
|
||||
// verify all the inherited permissions are set correctly (note read are not inherited from fileplan)
|
||||
verify(mockedPermissionService, filling).setPermission(child, AUTHORITY2, RMPermissionModel.FILING, true);
|
||||
verify(mockedPermissionService, read).setPermission(child, AUTHORITY, RMPermissionModel.READ_RECORDS, true);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -371,7 +303,7 @@ public class FilePlanPermissionServiceImplUnitTest extends BaseUnitTest
|
||||
filePlanPermissionService.setupRecordCategoryPermissions(rootRecordCategory);
|
||||
|
||||
// verify permission init
|
||||
verifyInitPermissions(filePlan, rootRecordCategory, never(), times(1));
|
||||
verifyInitPermissions(filePlan, rootRecordCategory, never(), times(1), true, false);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -387,7 +319,7 @@ public class FilePlanPermissionServiceImplUnitTest extends BaseUnitTest
|
||||
filePlanPermissionService.setupRecordCategoryPermissions(recordCategory);
|
||||
|
||||
// verify permission init
|
||||
verifyInitPermissions(rootRecordCategory, recordCategory, times(1), times(1));
|
||||
verifyInitPermissions(rootRecordCategory, recordCategory, times(1), times(1), false, true);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -403,7 +335,7 @@ public class FilePlanPermissionServiceImplUnitTest extends BaseUnitTest
|
||||
filePlanPermissionService.setupPermissions(recordCategory, newRecordFolder);
|
||||
|
||||
// verify permission init
|
||||
verifyInitPermissions(recordCategory, newRecordFolder, times(1), times(1));
|
||||
verifyInitPermissions(recordCategory, newRecordFolder, times(1), times(1), false, true);
|
||||
|
||||
}
|
||||
|
||||
@@ -420,7 +352,7 @@ public class FilePlanPermissionServiceImplUnitTest extends BaseUnitTest
|
||||
filePlanPermissionService.setupPermissions(newRecordFolder, newRecord);
|
||||
|
||||
// verify permission init
|
||||
verifyInitPermissions(newRecordFolder, newRecord, times(1), times(1));
|
||||
verifyInitPermissions(newRecordFolder, newRecord, times(1), times(1), false, true);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -436,7 +368,7 @@ public class FilePlanPermissionServiceImplUnitTest extends BaseUnitTest
|
||||
filePlanPermissionService.setupPermissions(filePlan, holdContainer);
|
||||
|
||||
// verify permissions are set-up correctly
|
||||
verifyInitPermissions(filePlan, holdContainer, times(1), times(1));
|
||||
verifyInitPermissions(filePlan, holdContainer, times(1), times(1), false, true);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -452,7 +384,7 @@ public class FilePlanPermissionServiceImplUnitTest extends BaseUnitTest
|
||||
filePlanPermissionService.setupPermissions(holdContainer, hold);
|
||||
|
||||
// verify permissions are set-up correctly
|
||||
verifyInitPermissions(holdContainer, hold, never(), times(1));
|
||||
verifyInitPermissions(holdContainer, hold, never(), times(1), false, false);
|
||||
|
||||
}
|
||||
|
||||
@@ -469,7 +401,7 @@ public class FilePlanPermissionServiceImplUnitTest extends BaseUnitTest
|
||||
filePlanPermissionService.setupPermissions(filePlan, unfiledRecordContainer);
|
||||
|
||||
// verify permissions are set-up correctly
|
||||
verifyInitPermissions(filePlan, unfiledRecordContainer, times(1), times(1));
|
||||
verifyInitPermissions(filePlan, unfiledRecordContainer, times(1), times(1), false, false);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -485,7 +417,7 @@ public class FilePlanPermissionServiceImplUnitTest extends BaseUnitTest
|
||||
filePlanPermissionService.setupPermissions(unfiledRecordContainer, unfiledRecordFolder);
|
||||
|
||||
// verify permissions are set-up correctly
|
||||
verifyInitPermissions(unfiledRecordContainer, unfiledRecordFolder, never(), times(1));
|
||||
verifyInitPermissions(unfiledRecordContainer, unfiledRecordFolder, never(), times(1), false, true);
|
||||
|
||||
}
|
||||
|
||||
@@ -502,7 +434,7 @@ public class FilePlanPermissionServiceImplUnitTest extends BaseUnitTest
|
||||
filePlanPermissionService.setupPermissions(unfiledRecordFolder, unfiledRecord);
|
||||
|
||||
// verify permission init
|
||||
verifyInitPermissions(unfiledRecordFolder, unfiledRecord, times(1), times(1));
|
||||
verifyInitPermissions(unfiledRecordFolder, unfiledRecord, times(1), times(1), false, true);
|
||||
|
||||
}
|
||||
}
|
||||
|
@@ -0,0 +1,130 @@
|
||||
/*
|
||||
* #%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.test.util;
|
||||
|
||||
import static org.mockito.Matchers.eq;
|
||||
import static org.mockito.Mockito.doReturn;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
import org.alfresco.model.ContentModel;
|
||||
import org.alfresco.service.cmr.repository.NodeRef;
|
||||
import org.alfresco.service.cmr.repository.NodeService;
|
||||
import org.alfresco.service.cmr.repository.StoreRef;
|
||||
import org.alfresco.service.namespace.QName;
|
||||
import org.alfresco.util.GUID;
|
||||
|
||||
/**
|
||||
* Utilities helpful when mocking Alfresco constructs.
|
||||
*
|
||||
* @author Roy Wetherall
|
||||
* @since 2.4.a
|
||||
*/
|
||||
public class AlfMock
|
||||
{
|
||||
/**
|
||||
* Helper to generate random text value suitable for a property
|
||||
* value or node name
|
||||
*/
|
||||
public static String generateText()
|
||||
{
|
||||
return UUID.randomUUID().toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper method to generate a qname.
|
||||
*/
|
||||
public static QName generateQName()
|
||||
{
|
||||
return generateQName(GUID.generate());
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper method to generate a qname.
|
||||
*/
|
||||
public static QName generateQName(String uri)
|
||||
{
|
||||
return QName.createQName(uri, GUID.generate());
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper method to generate a node reference.
|
||||
*
|
||||
* @return {@link NodeRef} node reference that behaves like a node that exists in the spaces store
|
||||
*/
|
||||
public static NodeRef generateNodeRef(NodeService mockedNodeService)
|
||||
{
|
||||
return generateNodeRef(mockedNodeService, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper method to generate a node reference of a particular type.
|
||||
*
|
||||
* @param type content type qualified name
|
||||
* @return {@link NodeRef} node reference that behaves like a node that exists in the spaces store with
|
||||
* the content type provided
|
||||
*/
|
||||
public static NodeRef generateNodeRef(NodeService mockedNodeService, QName type)
|
||||
{
|
||||
return generateNodeRef(mockedNodeService, type, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper method to generate a cm:content node reference with a given name.
|
||||
*
|
||||
* @param name content name
|
||||
* @return NodeRef node reference
|
||||
*/
|
||||
public static NodeRef generateCmContent(NodeService mockedNodeService, String name)
|
||||
{
|
||||
NodeRef nodeRef = generateNodeRef(mockedNodeService, ContentModel.TYPE_CONTENT, true);
|
||||
doReturn(name).when(mockedNodeService).getProperty(nodeRef, ContentModel.PROP_NAME);
|
||||
return nodeRef;
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper method to generate a node reference of a particular type with a given existence characteristic.
|
||||
*
|
||||
* @param type content type qualified name
|
||||
* @param exists indicates whether this node should behave like a node that exists or not
|
||||
* @return {@link NodeRef} node reference that behaves like a node that exists (or not) in the spaces store with
|
||||
* the content type provided
|
||||
*/
|
||||
public static NodeRef generateNodeRef(NodeService mockedNodeService, QName type, boolean exists)
|
||||
{
|
||||
NodeRef nodeRef = new NodeRef(StoreRef.STORE_REF_WORKSPACE_SPACESSTORE, GUID.generate());
|
||||
when(mockedNodeService.exists(eq(nodeRef))).thenReturn(exists);
|
||||
if (type != null)
|
||||
{
|
||||
when(mockedNodeService.getType(eq(nodeRef))).thenReturn(type);
|
||||
}
|
||||
return nodeRef;
|
||||
}
|
||||
|
||||
}
|
@@ -0,0 +1,392 @@
|
||||
/*
|
||||
* Copyright (C) 2005-2014 Alfresco Software Limited.
|
||||
*
|
||||
* This file is part of Alfresco
|
||||
*
|
||||
* 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/>.
|
||||
*/
|
||||
|
||||
package org.alfresco.repo.web.scripts.roles;
|
||||
|
||||
import static java.util.Collections.emptyMap;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
import static org.mockito.Matchers.any;
|
||||
import static org.mockito.Matchers.anyBoolean;
|
||||
import static org.mockito.Matchers.anyLong;
|
||||
import static org.mockito.Matchers.eq;
|
||||
import static org.mockito.Mockito.doAnswer;
|
||||
import static org.mockito.Mockito.never;
|
||||
import static org.mockito.Mockito.times;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
|
||||
import org.alfresco.module.org_alfresco_module_rm.model.RecordsManagementModel;
|
||||
import org.alfresco.module.org_alfresco_module_rm.security.ExtendedReaderDynamicAuthority;
|
||||
import org.alfresco.module.org_alfresco_module_rm.security.ExtendedSecurityService;
|
||||
import org.alfresco.module.org_alfresco_module_rm.security.ExtendedWriterDynamicAuthority;
|
||||
import org.alfresco.module.org_alfresco_module_rm.test.util.AlfMock;
|
||||
import org.alfresco.module.org_alfresco_module_rm.test.util.BaseWebScriptUnitTest;
|
||||
import org.alfresco.repo.domain.node.NodeDAO;
|
||||
import org.alfresco.repo.domain.patch.PatchDAO;
|
||||
import org.alfresco.repo.domain.qname.QNameDAO;
|
||||
import org.alfresco.repo.transaction.RetryingTransactionHelper;
|
||||
import org.alfresco.repo.transaction.RetryingTransactionHelper.RetryingTransactionCallback;
|
||||
import org.alfresco.service.cmr.repository.NodeRef;
|
||||
import org.alfresco.service.cmr.repository.NodeService;
|
||||
import org.alfresco.service.cmr.security.PermissionService;
|
||||
import org.alfresco.service.namespace.QName;
|
||||
import org.alfresco.service.transaction.TransactionService;
|
||||
import org.alfresco.util.Pair;
|
||||
import org.json.JSONObject;
|
||||
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.extensions.webscripts.DeclarativeWebScript;
|
||||
|
||||
/**
|
||||
* DynamicAuthoritiesGet Unit Test
|
||||
*
|
||||
* @author Silviu Dinuta
|
||||
*/
|
||||
@SuppressWarnings("deprecation")
|
||||
public class DynamicAuthoritiesGetUnitTest extends BaseWebScriptUnitTest implements RecordsManagementModel
|
||||
{
|
||||
/** test data */
|
||||
private static final Long ASPECT_ID = 123l;
|
||||
private static final QName ASPECT = AlfMock.generateQName();
|
||||
|
||||
/** mocks */
|
||||
@Mock
|
||||
private PatchDAO mockedPatchDAO;
|
||||
@Mock
|
||||
private NodeDAO mockedNodeDAO;
|
||||
@Mock
|
||||
private QNameDAO mockedQnameDAO;
|
||||
@Mock
|
||||
private NodeService mockedNodeService;
|
||||
@Mock
|
||||
private PermissionService mockedPermissionService;
|
||||
@Mock
|
||||
private ExtendedSecurityService mockedExtendedSecurityService;
|
||||
@Mock
|
||||
private TransactionService mockedTransactionService;
|
||||
@Mock
|
||||
private RetryingTransactionHelper mockedRetryingTransactionHelper;
|
||||
|
||||
/** test component */
|
||||
@InjectMocks
|
||||
private DynamicAuthoritiesGet webScript;
|
||||
|
||||
@Override
|
||||
protected DeclarativeWebScript getWebScript()
|
||||
{
|
||||
return webScript;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getWebScriptTemplate()
|
||||
{
|
||||
return "alfresco/templates/webscripts/org/alfresco/repository/roles/rm-dynamicauthorities.get.json.ftl";
|
||||
}
|
||||
|
||||
/**
|
||||
* Before test
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
@Before
|
||||
public void before()
|
||||
{
|
||||
MockitoAnnotations.initMocks(this);
|
||||
webScript.setNodeService(mockedNodeService);
|
||||
webScript.setPermissionService(mockedPermissionService);
|
||||
webScript.setExtendedSecurityService(mockedExtendedSecurityService);
|
||||
// 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), anyBoolean(), anyBoolean());
|
||||
|
||||
when(mockedTransactionService.getRetryingTransactionHelper()).thenReturn(mockedRetryingTransactionHelper);
|
||||
|
||||
// max node id
|
||||
when(mockedPatchDAO.getMaxAdmNodeID()).thenReturn(500000L);
|
||||
|
||||
// aspect
|
||||
when(mockedQnameDAO.getQName(ASPECT_EXTENDED_SECURITY)).thenReturn(new Pair<Long, QName>(ASPECT_ID, ASPECT));
|
||||
}
|
||||
|
||||
/**
|
||||
* Given that there are no nodes with the extended security aspect When the action is executed Nothing happens
|
||||
* @throws Exception
|
||||
*/
|
||||
@SuppressWarnings({ "unchecked" })
|
||||
@Test
|
||||
public void noNodesWithExtendedSecurity() throws Exception
|
||||
{
|
||||
when(mockedPatchDAO.getNodesByAspectQNameId(eq(ASPECT_ID), anyLong(), anyLong()))
|
||||
.thenReturn(Collections.emptyList());
|
||||
|
||||
// Set up parameters.
|
||||
Map<String, String> parameters = ImmutableMap.of("batchsize", "10", "maxProcessedRecords", "3");
|
||||
JSONObject json = executeJSONWebScript(parameters);
|
||||
assertNotNull(json);
|
||||
String actualJSONString = json.toString();
|
||||
|
||||
// Check the JSON result using Jackson to allow easy equality testing.
|
||||
ObjectMapper mapper = new ObjectMapper();
|
||||
String expectedJSONString = "{\"responsestatus\":\"success\",\"message\":\"Processed 0 records.\"}";
|
||||
assertEquals(mapper.readTree(expectedJSONString), mapper.readTree(actualJSONString));
|
||||
|
||||
|
||||
verify(mockedNodeService, never()).getProperty(any(NodeRef.class), eq(PROP_READERS));
|
||||
verify(mockedNodeService, never()).getProperty(any(NodeRef.class), eq(PROP_WRITERS));
|
||||
verify(mockedNodeService, never()).removeAspect(any(NodeRef.class), eq(ASPECT_EXTENDED_SECURITY));
|
||||
verify(mockedPermissionService, never()).clearPermission(any(NodeRef.class),
|
||||
eq(ExtendedReaderDynamicAuthority.EXTENDED_READER));
|
||||
verify(mockedPermissionService, never()).clearPermission(any(NodeRef.class),
|
||||
eq(ExtendedWriterDynamicAuthority.EXTENDED_WRITER));
|
||||
verify(mockedExtendedSecurityService, never()).set(any(NodeRef.class), any(Set.class), any(Set.class));
|
||||
}
|
||||
|
||||
/**
|
||||
* Given that there are records with the extended security aspect When the action is executed Then the aspect is
|
||||
* removed And the dynamic authorities permissions are cleared And extended security is set via the updated API
|
||||
* @throws Exception
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
@Test
|
||||
public void recordsWithExtendedSecurityAspect() throws Exception
|
||||
{
|
||||
List<Long> ids = Stream.of(1l, 2l, 3l).collect(Collectors.toList());
|
||||
|
||||
when(mockedPatchDAO.getNodesByAspectQNameId(eq(ASPECT_ID), anyLong(), anyLong()))
|
||||
.thenReturn(ids)
|
||||
.thenReturn(Collections.emptyList());
|
||||
|
||||
ids.stream().forEach((i) -> {
|
||||
NodeRef nodeRef = AlfMock.generateNodeRef(mockedNodeService);
|
||||
when(mockedNodeDAO.getNodePair(i)).thenReturn(new Pair<Long, NodeRef>(i, nodeRef));
|
||||
when(mockedNodeService.hasAspect(nodeRef, ASPECT_RECORD)).thenReturn(true);
|
||||
when(mockedNodeService.getProperty(nodeRef, PROP_READERS))
|
||||
.thenReturn((Serializable) Collections.emptyMap());
|
||||
when(mockedNodeService.getProperty(nodeRef, PROP_WRITERS))
|
||||
.thenReturn((Serializable) Collections.emptyMap());
|
||||
|
||||
});
|
||||
|
||||
// Set up parameters.
|
||||
Map<String, String> parameters = ImmutableMap.of("batchsize", "10", "maxProcessedRecords", "4");
|
||||
JSONObject json = executeJSONWebScript(parameters);
|
||||
assertNotNull(json);
|
||||
String actualJSONString = json.toString();
|
||||
ObjectMapper mapper = new ObjectMapper();
|
||||
String expectedJSONString = "{\"responsestatus\":\"success\",\"message\":\"Processed 3 records.\"}";
|
||||
assertEquals(mapper.readTree(expectedJSONString), mapper.readTree(actualJSONString));
|
||||
|
||||
|
||||
verify(mockedNodeService, times(3)).getProperty(any(NodeRef.class), eq(PROP_READERS));
|
||||
verify(mockedNodeService, times(3)).getProperty(any(NodeRef.class), eq(PROP_WRITERS));
|
||||
verify(mockedNodeService, times(3)).removeAspect(any(NodeRef.class), eq(ASPECT_EXTENDED_SECURITY));
|
||||
verify(mockedPermissionService, times(3)).clearPermission(any(NodeRef.class),
|
||||
eq(ExtendedReaderDynamicAuthority.EXTENDED_READER));
|
||||
verify(mockedPermissionService, times(3)).clearPermission(any(NodeRef.class),
|
||||
eq(ExtendedWriterDynamicAuthority.EXTENDED_WRITER));
|
||||
verify(mockedExtendedSecurityService, times(3)).set(any(NodeRef.class), any(Set.class), any(Set.class));
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Given that there are non-records with the extended security aspect When the web script is executed Then the aspect is
|
||||
* removed And the dynamic authorities permissions are cleared
|
||||
* @throws Exception
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
@Test
|
||||
public void nonRecordsWithExtendedSecurityAspect() throws Exception
|
||||
{
|
||||
List<Long> ids = Stream.of(1l, 2l, 3l).collect(Collectors.toList());
|
||||
|
||||
when(mockedPatchDAO.getNodesByAspectQNameId(eq(ASPECT_ID), anyLong(), anyLong()))
|
||||
.thenReturn(ids)
|
||||
.thenReturn(Collections.emptyList());
|
||||
|
||||
ids.stream().forEach((i) -> {
|
||||
NodeRef nodeRef = AlfMock.generateNodeRef(mockedNodeService);
|
||||
when(mockedNodeDAO.getNodePair(i)).thenReturn(new Pair<Long, NodeRef>(i, nodeRef));
|
||||
when(mockedNodeService.hasAspect(nodeRef, ASPECT_RECORD)).thenReturn(false);
|
||||
when(mockedNodeService.getProperty(nodeRef, PROP_READERS))
|
||||
.thenReturn((Serializable) Collections.emptyMap());
|
||||
when(mockedNodeService.getProperty(nodeRef, PROP_WRITERS))
|
||||
.thenReturn((Serializable) Collections.emptyMap());
|
||||
|
||||
});
|
||||
|
||||
// Set up parameters.
|
||||
Map<String, String> parameters = ImmutableMap.of("batchsize", "10", "maxProcessedRecords", "4");
|
||||
JSONObject json = executeJSONWebScript(parameters);
|
||||
assertNotNull(json);
|
||||
String actualJSONString = json.toString();
|
||||
ObjectMapper mapper = new ObjectMapper();
|
||||
String expectedJSONString = "{\"responsestatus\":\"success\",\"message\":\"Processed 3 records.\"}";
|
||||
assertEquals(mapper.readTree(expectedJSONString), mapper.readTree(actualJSONString));
|
||||
|
||||
|
||||
verify(mockedNodeService, times(3)).getProperty(any(NodeRef.class), eq(PROP_READERS));
|
||||
verify(mockedNodeService, times(3)).getProperty(any(NodeRef.class), eq(PROP_WRITERS));
|
||||
verify(mockedNodeService, times(3)).removeAspect(any(NodeRef.class), eq(ASPECT_EXTENDED_SECURITY));
|
||||
verify(mockedPermissionService, times(3)).clearPermission(any(NodeRef.class),
|
||||
eq(ExtendedReaderDynamicAuthority.EXTENDED_READER));
|
||||
verify(mockedPermissionService, times(3)).clearPermission(any(NodeRef.class),
|
||||
eq(ExtendedWriterDynamicAuthority.EXTENDED_WRITER));
|
||||
verify(mockedExtendedSecurityService, never()).set(any(NodeRef.class), any(Set.class), any(Set.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void missingBatchSizeParameter() throws Exception
|
||||
{
|
||||
JSONObject json = executeJSONWebScript(emptyMap());
|
||||
assertNotNull(json);
|
||||
String actualJSONString = json.toString();
|
||||
ObjectMapper mapper = new ObjectMapper();
|
||||
String expectedJSONString = "{\"responsestatus\":\"failed\",\"message\":\"Parameter batchsize is mandatory\"}";
|
||||
assertEquals(mapper.readTree(expectedJSONString), mapper.readTree(actualJSONString));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void invalidBatchSizeParameter() throws Exception
|
||||
{
|
||||
// Set up parameters.
|
||||
Map<String, String> parameters = ImmutableMap.of("batchsize", "dd");
|
||||
JSONObject json = executeJSONWebScript(parameters);
|
||||
assertNotNull(json);
|
||||
String actualJSONString = json.toString();
|
||||
ObjectMapper mapper = new ObjectMapper();
|
||||
String expectedJSONString = "{\"responsestatus\":\"failed\",\"message\":\"Parameter batchsize is invalid.\"}";
|
||||
assertEquals(mapper.readTree(expectedJSONString), mapper.readTree(actualJSONString));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void batchSizeShouldBeGraterThanZero() throws Exception
|
||||
{
|
||||
when(mockedQnameDAO.getQName(ASPECT_EXTENDED_SECURITY)).thenReturn(null);
|
||||
// Set up parameters.
|
||||
Map<String, String> parameters = ImmutableMap.of("batchsize", "0");
|
||||
JSONObject json = executeJSONWebScript(parameters);
|
||||
assertNotNull(json);
|
||||
String actualJSONString = json.toString();
|
||||
ObjectMapper mapper = new ObjectMapper();
|
||||
String expectedJSONString = "{\"responsestatus\":\"failed\",\"message\":\"Parameter batchsize should be a number greater than 0.\"}";
|
||||
assertEquals(mapper.readTree(expectedJSONString), mapper.readTree(actualJSONString));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void extendedSecurityAspectNotCreated() throws Exception
|
||||
{
|
||||
when(mockedQnameDAO.getQName(ASPECT_EXTENDED_SECURITY)).thenReturn(null);
|
||||
// Set up parameters.
|
||||
Map<String, String> parameters = ImmutableMap.of("batchsize", "3");
|
||||
JSONObject json = executeJSONWebScript(parameters);
|
||||
assertNotNull(json);
|
||||
String actualJSONString = json.toString();
|
||||
ObjectMapper mapper = new ObjectMapper();
|
||||
String expectedJSONString = "{\"responsestatus\":\"success\",\"message\":\"There where no records to be processed.\"}";
|
||||
assertEquals(mapper.readTree(expectedJSONString), mapper.readTree(actualJSONString));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void processAllRecordsWhenMaxProcessedRecordsIsZero() throws Exception
|
||||
{
|
||||
List<Long> ids = Stream.of(1l, 2l, 3l,4l).collect(Collectors.toList());
|
||||
|
||||
when(mockedPatchDAO.getNodesByAspectQNameId(eq(ASPECT_ID), anyLong(), anyLong()))
|
||||
.thenReturn(ids)
|
||||
.thenReturn(Collections.emptyList());
|
||||
|
||||
ids.stream().forEach((i) -> {
|
||||
NodeRef nodeRef = AlfMock.generateNodeRef(mockedNodeService);
|
||||
when(mockedNodeDAO.getNodePair(i)).thenReturn(new Pair<Long, NodeRef>(i, nodeRef));
|
||||
when(mockedNodeService.hasAspect(nodeRef, ASPECT_RECORD)).thenReturn(false);
|
||||
when(mockedNodeService.getProperty(nodeRef, PROP_READERS))
|
||||
.thenReturn((Serializable) Collections.emptyMap());
|
||||
when(mockedNodeService.getProperty(nodeRef, PROP_WRITERS))
|
||||
.thenReturn((Serializable) Collections.emptyMap());
|
||||
|
||||
});
|
||||
|
||||
// Set up parameters.
|
||||
Map<String, String> parameters = ImmutableMap.of("batchsize", "10", "maxProcessedRecords", "0");
|
||||
JSONObject json = executeJSONWebScript(parameters);
|
||||
assertNotNull(json);
|
||||
String actualJSONString = json.toString();
|
||||
ObjectMapper mapper = new ObjectMapper();
|
||||
String expectedJSONString = "{\"responsestatus\":\"success\",\"message\":\"Processed 4 records.\"}";
|
||||
assertEquals(mapper.readTree(expectedJSONString), mapper.readTree(actualJSONString));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void whenMaxProcessedRecordsIsMissingItDefaultsToBatchSize() throws Exception
|
||||
{
|
||||
List<Long> ids = Stream.of(1l, 2l, 3l, 4l, 5l).collect(Collectors.toList());
|
||||
|
||||
when(mockedPatchDAO.getNodesByAspectQNameId(eq(ASPECT_ID), anyLong(), anyLong()))
|
||||
.thenReturn(ids)
|
||||
.thenReturn(Collections.emptyList());
|
||||
|
||||
ids.stream().forEach((i) -> {
|
||||
NodeRef nodeRef = AlfMock.generateNodeRef(mockedNodeService);
|
||||
when(mockedNodeDAO.getNodePair(i)).thenReturn(new Pair<Long, NodeRef>(i, nodeRef));
|
||||
when(mockedNodeService.hasAspect(nodeRef, ASPECT_RECORD)).thenReturn(false);
|
||||
when(mockedNodeService.getProperty(nodeRef, PROP_READERS))
|
||||
.thenReturn((Serializable) Collections.emptyMap());
|
||||
when(mockedNodeService.getProperty(nodeRef, PROP_WRITERS))
|
||||
.thenReturn((Serializable) Collections.emptyMap());
|
||||
|
||||
});
|
||||
|
||||
// Set up parameters.
|
||||
Map<String, String> parameters = ImmutableMap.of("batchsize", "4");
|
||||
JSONObject json = executeJSONWebScript(parameters);
|
||||
assertNotNull(json);
|
||||
String actualJSONString = json.toString();
|
||||
ObjectMapper mapper = new ObjectMapper();
|
||||
String expectedJSONString = "{\"responsestatus\":\"success\",\"message\":\"Processed first 4 records.\"}";
|
||||
assertEquals(mapper.readTree(expectedJSONString), mapper.readTree(actualJSONString));
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user