RM-3074: groups assigned to RM roles, not authorities

* IPR groups are now assigned to RM roles rather than the individual
authorities
* more unit tests
This commit is contained in:
Roy Wetherall
2016-08-02 11:20:55 +10:00
parent 6756f0f841
commit 43a961237e
3 changed files with 416 additions and 76 deletions

View File

@@ -30,22 +30,32 @@ import static org.alfresco.module.org_alfresco_module_rm.security.ExtendedSecuri
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.service.cmr.security.PermissionService.GROUP_PREFIX;
import static org.junit.Assert.*;
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.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.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;
@@ -65,6 +75,7 @@ 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;
/**
@@ -83,23 +94,29 @@ public class ExtendedSecurityServiceImplUnitTest
@Mock private TransactionService mockedTransactionService;
@Mock private RetryingTransactionHelper mockedRetryingTransactionHelper;
@Mock private NodeService mockedNodeService;
@Mock private PagingResults<String> mockedPagingResults;
@Mock private ApplicationContext mockedApplicationContext;
/** test component */
@InjectMocks private ExtendedSecurityServiceImpl extendedSecurityService;
/** read/write group full names */
private static final String READER_GROUP_FULL_NAME = GROUP_PREFIX + READER_GROUP_PREFIX;
private static final String WRITER_GROUP_FULL_NAME = GROUP_PREFIX + WRITER_GROUP_PREFIX;
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 = AlfMock.generateText();
private static final String GROUP = GROUP_PREFIX + AlfMock.generateText();
private static final String USER_W = AlfMock.generateText();
private static final String GROUP_W = GROUP_PREFIX + AlfMock.generateText();
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_NAME, 0),
.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_NAME, 2))
new AccessPermissionImpl(AlfMock.generateText(), AccessStatus.ALLOWED, WRITER_GROUP_FULL_PREFIX, 2))
.collect(Collectors.toSet());
/** has no extended security permission set */
@@ -111,25 +128,29 @@ public class ExtendedSecurityServiceImplUnitTest
/** test data */
private NodeRef nodeRef;
private NodeRef filePlan;
/**
* Before tests
*/
@SuppressWarnings("unchecked")
@Before public void before()
{
// initialise mocks
MockitoAnnotations.initMocks(this);
// setup nodeRef
// setup node
nodeRef = AlfMock.generateNodeRef(mockedNodeService);
}
/**
* Helper to setup retrying transaction helper
*/
@SuppressWarnings("unchecked")
private void setupRetryingTransactionHelper()
{
// 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>()
{
@@ -146,6 +167,18 @@ public class ExtendedSecurityServiceImplUnitTest
.<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);
}
/**
@@ -155,9 +188,6 @@ public class ExtendedSecurityServiceImplUnitTest
*/
@Test public void rootAuthorityDoesNotExist()
{
// setup retrying transaction helper
setupRetryingTransactionHelper();
// group doesn't exist
when(mockedAuthorityService.authorityExists(GROUP_PREFIX + ExtendedSecurityServiceImpl.ROOT_IPR_GROUP))
.thenReturn(false);
@@ -176,9 +206,6 @@ public class ExtendedSecurityServiceImplUnitTest
*/
@Test public void rootAuthorityDoesExist()
{
// setup retrying transaction helper
setupRetryingTransactionHelper();
// group doesn't exist
when(mockedAuthorityService.authorityExists(GROUP_PREFIX + ROOT_IPR_GROUP))
.thenReturn(true);
@@ -268,7 +295,7 @@ public class ExtendedSecurityServiceImplUnitTest
* When I try and get the extended readers
* The I will get an empty set
*/
@Test public void getExtendedReadersNoIPRGoupsAssigned()
@Test public void getExtendedReadersNoIPRGroupsAssigned()
{
// setup permissions
when(mockedPermissionService.getAllSetPermissions(nodeRef))
@@ -289,9 +316,9 @@ public class ExtendedSecurityServiceImplUnitTest
when(mockedPermissionService.getAllSetPermissions(nodeRef))
.thenReturn(HAS_EXTENDED_SECURITY);
when(mockedAuthorityService.getContainedAuthorities(null, READER_GROUP_FULL_NAME, true))
when(mockedAuthorityService.getContainedAuthorities(null, READER_GROUP_FULL_PREFIX, true))
.thenReturn(Stream
.of(USER, GROUP, WRITER_GROUP_FULL_NAME)
.of(USER, GROUP, WRITER_GROUP_FULL_PREFIX)
.collect(Collectors.toSet()));
// get extended readers
@@ -307,14 +334,360 @@ public class ExtendedSecurityServiceImplUnitTest
* 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.getExtendedWriters(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.getExtendedWriters(nodeRef);
assertEquals(Stream
.of(USER, GROUP)
.collect(Collectors.toSet()),
extendedWriters);
}
// TODO add AC for adding extended security marks
/**
* 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, WRITERS, 0);
String writeGroup = extendedSecurityService.getIPRGroupShortName(WRITER_GROUP_PREFIX, READERS, WRITERS, 0);
// setup query results
when(mockedPagingResults.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(mockedPagingResults);
// add extended security
extendedSecurityService.addExtendedSecurity(nodeRef, READERS, WRITERS);
// 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(readGroup, 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);
}
// TODO add AC for removing extended security marks
/**
* 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 = extendedSecurityService.getIPRGroupShortName(READER_GROUP_PREFIX, READERS, WRITERS, 0);
String writeGroup = extendedSecurityService.getIPRGroupShortName(WRITER_GROUP_PREFIX, READERS, WRITERS, 0);
// setup query results
when(mockedPagingResults.getPage())
.thenReturn(Stream.of(GROUP_PREFIX + readGroup).collect(Collectors.toList()));
when(mockedAuthorityService.getAuthorities(
eq(AuthorityType.GROUP),
eq(RMAuthority.ZONE_APP_RM),
any(String.class),
eq(false),
eq(false),
any(PagingRequest.class)))
.thenReturn(mockedPagingResults);
// setup exact match
when(mockedAuthorityService.authorityExists(GROUP_PREFIX + writeGroup))
.thenReturn(true);
when(mockedAuthorityService.getContainedAuthorities(null, GROUP_PREFIX + readGroup, true))
.thenReturn(Stream
.of(GROUP_PREFIX + writeGroup, 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.addExtendedSecurity(nodeRef, READERS, WRITERS);
// 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 = extendedSecurityService.getIPRGroupShortName(READER_GROUP_PREFIX, READERS, WRITERS, 0);
String writeGroup = extendedSecurityService.getIPRGroupShortName(WRITER_GROUP_PREFIX, READERS, WRITERS, 0);
// setup query results
when(mockedPagingResults.getPage())
.thenReturn(Stream.of(GROUP_PREFIX + readGroup).collect(Collectors.toList()));
when(mockedAuthorityService.getAuthorities(
eq(AuthorityType.GROUP),
eq(RMAuthority.ZONE_APP_RM),
any(String.class),
eq(false),
eq(false),
any(PagingRequest.class)))
.thenReturn(mockedPagingResults);
// setup exact match
when(mockedAuthorityService.authorityExists(GROUP_PREFIX + writeGroup))
.thenReturn(true);
when(mockedAuthorityService.getContainedAuthorities(null, GROUP_PREFIX + readGroup, true))
.thenReturn(Stream
.of(GROUP_PREFIX + writeGroup, USER, GROUP)
.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.addExtendedSecurity(nodeRef, READERS, WRITERS);
// new group names
readGroup = extendedSecurityService.getIPRGroupShortName(READER_GROUP_PREFIX, READERS, WRITERS, 1);
writeGroup = extendedSecurityService.getIPRGroupShortName(WRITER_GROUP_PREFIX, READERS, 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(readGroup, 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 = extendedSecurityService.getIPRGroupShortName(READER_GROUP_PREFIX, READERS, WRITERS, 0);
String writeGroup = extendedSecurityService.getIPRGroupShortName(WRITER_GROUP_PREFIX, READERS, WRITERS, 0);
List<String> fiftyResults = new ArrayList<String>(50);
for (int i = 0; i < 50; i++)
{
fiftyResults.add(AlfMock.generateText());
}
// setup query results
when(mockedPagingResults.getPage())
.thenReturn(fiftyResults)
.thenReturn(Stream.of(GROUP_PREFIX + readGroup).collect(Collectors.toList()));
when(mockedAuthorityService.getAuthorities(
eq(AuthorityType.GROUP),
eq(RMAuthority.ZONE_APP_RM),
any(String.class),
eq(false),
eq(false),
any(PagingRequest.class)))
.thenReturn(mockedPagingResults);
// setup exact match
when(mockedAuthorityService.authorityExists(GROUP_PREFIX + writeGroup))
.thenReturn(true);
when(mockedAuthorityService.getContainedAuthorities(null, GROUP_PREFIX + readGroup, true))
.thenReturn(Stream
.of(GROUP_PREFIX + writeGroup, 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.addExtendedSecurity(nodeRef, READERS, WRITERS);
// 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
*/
// TODO
/**
* Given that a node has renditions
* When I add extended security
* Then it applied to the renditions
*/
// TODO
/**
* 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, WRITERS, 0);
String writeGroup = extendedSecurityService.getIPRGroupShortName(WRITER_GROUP_FULL_PREFIX, READERS, 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.removeAllExtendedSecurity(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.removeAllExtendedSecurity(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 rentitions
*/
// TODO
}