RM-3074: Added root group and zones

* added root inplace group, created on start-up if not already there
* all groups created in RM zone
* fixed up file plan permission unit test and removed ignore from test
suite
* removed delimeters from groups names to keep length to a min
This commit is contained in:
Roy Wetherall
2016-08-01 11:18:51 +10:00
parent f76b7df53c
commit 18bf4594ff
7 changed files with 106 additions and 118 deletions

View File

@@ -576,6 +576,7 @@
<property name="filePlanRoleService" ref="filePlanRoleService" />
<property name="authorityService" ref="authorityService"/>
<property name="permissionService" ref="permissionService"/>
<property name="transactionService" ref="transactionService"/>
</bean>
<bean id="ExtendedSecurityService" class="org.springframework.aop.framework.ProxyFactoryBean">

View File

@@ -41,7 +41,7 @@ import org.alfresco.service.cmr.repository.NodeRef;
@AlfrescoPublicApi
public interface ExtendedSecurityService
{
static final String IPR_GROUP_PREFIX = "IPR_";
static final String IPR_GROUP_PREFIX = "IPR";
/**
* Indicates whether a node has extended security.

View File

@@ -27,6 +27,8 @@
package org.alfresco.module.org_alfresco_module_rm.security;
import static org.alfresco.service.cmr.security.PermissionService.GROUP_PREFIX;
import java.util.Collections;
import java.util.List;
import java.util.Set;
@@ -38,6 +40,8 @@ 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.util.ServiceBaseImpl;
import org.alfresco.repo.security.authority.RMAuthority;
import org.alfresco.repo.transaction.RetryingTransactionHelper;
import org.alfresco.service.cmr.repository.ChildAssociationRef;
import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.cmr.security.AccessPermission;
@@ -45,7 +49,10 @@ 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.alfresco.util.ParameterCheck;
import org.springframework.context.ApplicationListener;
import org.springframework.context.event.ContextRefreshedEvent;
import org.springframework.extensions.webscripts.ui.common.StringUtils;
import com.google.gdata.util.common.base.Pair;
@@ -58,10 +65,13 @@ import com.google.gdata.util.common.base.Pair;
*/
public class ExtendedSecurityServiceImpl extends ServiceBaseImpl
implements ExtendedSecurityService,
RecordsManagementModel
RecordsManagementModel,
ApplicationListener<ContextRefreshedEvent>
{
private static final String READER_GROUP_PREFIX = ExtendedSecurityService.IPR_GROUP_PREFIX + "R_";
private static final String WRITER_GROUP_PREFIX = ExtendedSecurityService.IPR_GROUP_PREFIX + "W_";
/** ipr group names */
private static final String ROOT_IPR_GROUP = "INPLACE_RECORD_MANAGEMENT";
private static final String READER_GROUP_PREFIX = ExtendedSecurityService.IPR_GROUP_PREFIX + "R";
private static final String WRITER_GROUP_PREFIX = ExtendedSecurityService.IPR_GROUP_PREFIX + "W";
/** File plan service */
private FilePlanService filePlanService;
@@ -75,6 +85,9 @@ public class ExtendedSecurityServiceImpl extends ServiceBaseImpl
/** permission service */
private PermissionService permissionService;
/** transaction service */
private TransactionService transactionService;
/**
* @param filePlanService file plan service
*/
@@ -107,9 +120,47 @@ public class ExtendedSecurityServiceImpl extends ServiceBaseImpl
this.permissionService = permissionService;
}
/**
* @param transactionService transaction service
*/
public void setTransactionService(TransactionService transactionService)
{
this.transactionService = transactionService;
}
/**
* Application context refresh event handler
*/
@Override
public void onApplicationEvent(ContextRefreshedEvent contextRefreshedEvent)
{
transactionService.getRetryingTransactionHelper().doInTransaction(new RetryingTransactionHelper.RetryingTransactionCallback<Void>()
{
public Void execute() throws Throwable
{
// if the root group doesn't exist then create it
if (!authorityService.authorityExists(getRootIRPGroup()))
{
authorityService.createAuthority(AuthorityType.GROUP, ROOT_IPR_GROUP, ROOT_IPR_GROUP, Collections.singleton(RMAuthority.ZONE_APP_RM));
}
return null;
}
});
}
/**
* Get root IPR group name
*/
private String getRootIRPGroup()
{
return GROUP_PREFIX + ROOT_IPR_GROUP;
}
/**
* @see org.alfresco.module.org_alfresco_module_rm.security.ExtendedSecurityService#hasExtendedSecurity(org.alfresco.service.cmr.repository.NodeRef)
*/
@Override
public boolean hasExtendedSecurity(NodeRef nodeRef)
{
return (getIPRGroups(nodeRef) != null);
@@ -222,11 +273,11 @@ public class ExtendedSecurityServiceImpl extends ServiceBaseImpl
Set<AccessPermission> permissions = permissionService.getAllSetPermissions(nodeRef);
for (AccessPermission permission : permissions)
{
if (permission.getAuthority().startsWith(PermissionService.GROUP_PREFIX + READER_GROUP_PREFIX))
if (permission.getAuthority().startsWith(GROUP_PREFIX + READER_GROUP_PREFIX))
{
iprReaderGroup = permission.getAuthority();
}
else if (permission.getAuthority().startsWith(PermissionService.GROUP_PREFIX + WRITER_GROUP_PREFIX))
else if (permission.getAuthority().startsWith(GROUP_PREFIX + WRITER_GROUP_PREFIX))
{
iprWriterGroup = permission.getAuthority();
}
@@ -253,6 +304,7 @@ public class ExtendedSecurityServiceImpl extends ServiceBaseImpl
// see if the groups already exists or not
String readerGroupName = getIPRGroupName(READER_GROUP_PREFIX, readers, writers, false);
String writerGroupName = getIPRGroupName(WRITER_GROUP_PREFIX, readers, writers, false);
if (authorityService.authorityExists(readerGroupName) &&
authorityService.authorityExists(writerGroupName))
{
@@ -304,12 +356,11 @@ public class ExtendedSecurityServiceImpl extends ServiceBaseImpl
if (!shortName)
{
builder.append(PermissionService.GROUP_PREFIX);
builder.append(GROUP_PREFIX);
}
builder.append(prefix)
.append(getAuthoritySetHashCode(readers))
.append("-")
.append(getAuthoritySetHashCode(writers));
return builder.toString();
@@ -338,7 +389,7 @@ public class ExtendedSecurityServiceImpl extends ServiceBaseImpl
*/
private Pair<String, String> createIPRGroups(Set<String> readers, Set<String> writers)
{
String iprReaderGroup = createIPRGroup(getIPRGroupName(READER_GROUP_PREFIX, readers, writers, true), null, readers);
String iprReaderGroup = createIPRGroup(getIPRGroupName(READER_GROUP_PREFIX, readers, writers, true), getRootIRPGroup(), readers);
String iprWriterGroup = createIPRGroup(getIPRGroupName(WRITER_GROUP_PREFIX, readers, writers, true), iprReaderGroup, writers);
return new Pair<String, String>(iprReaderGroup, iprWriterGroup);
}
@@ -354,7 +405,7 @@ public class ExtendedSecurityServiceImpl extends ServiceBaseImpl
{
ParameterCheck.mandatory("groupShortName", groupShortName);
String group = authorityService.createAuthority(AuthorityType.GROUP, groupShortName); // TODO set appropriate zone
String group = authorityService.createAuthority(AuthorityType.GROUP, groupShortName, groupShortName, Collections.singleton(RMAuthority.ZONE_APP_RM));
if (parent != null)
{

View File

@@ -449,9 +449,20 @@ public class FilePlanPermissionServiceImpl extends ServiceBaseImpl
return authorityService.getName(AuthorityType.GROUP, FilePlanRoleService.ROLE_ADMIN + filePlan.getId());
}
/**
* Indicates whether the default behaviour is to inherit permissions or not.
*
* @param nodeRef node reference
* @param isParentNodeFilePlan true if parent node is a file plan, false otherwise
* @return boolean true if inheritance true, false otherwise
*/
private boolean isInheritanceAllowed(NodeRef nodeRef, Boolean isParentNodeFilePlan)
{
return !(isFilePlan(nodeRef) || isTransfer(nodeRef) || isHold(nodeRef) || isUnfiledRecordsContainer(nodeRef) || (isRecordCategory(nodeRef) && isTrue(isParentNodeFilePlan)));
return !(isFilePlan(nodeRef) ||
isTransfer(nodeRef) ||
isHold(nodeRef) ||
isUnfiledRecordsContainer(nodeRef) ||
(isRecordCategory(nodeRef) && isTrue(isParentNodeFilePlan)));
}
/**
@@ -516,9 +527,6 @@ public class FilePlanPermissionServiceImpl extends ServiceBaseImpl
}
}
// clear all existing permissions and start again
// permissionService.deletePermissions(record);
// re-setup the records permissions
setupPermissions(destinationAssocRef.getParentRef(), record);
@@ -600,7 +608,7 @@ public class FilePlanPermissionServiceImpl extends ServiceBaseImpl
private boolean canPerformPermissionAction(NodeRef nodeRef)
{
return isFilePlanContainer(nodeRef) || isRecordFolder(nodeRef) || isRecord(nodeRef) || isTransfer(nodeRef);
return isFilePlanContainer(nodeRef) || isRecordFolder(nodeRef) || isRecord(nodeRef) || isTransfer(nodeRef) || isHold(nodeRef);
}
/**

View File

@@ -39,8 +39,6 @@ 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.security.ExtendedReaderDynamicAuthority;
import org.alfresco.module.org_alfresco_module_rm.security.ExtendedWriterDynamicAuthority;
import org.alfresco.repo.cache.SimpleCache;
import org.alfresco.repo.security.permissions.AccessControlEntry;
import org.alfresco.repo.security.permissions.AccessControlList;

View File

@@ -27,13 +27,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;
@@ -173,15 +170,6 @@ public class FilePlanPermissionServiceImplUnitTest extends BaseUnitTest
// 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);
}
/**
@@ -195,14 +183,6 @@ public class FilePlanPermissionServiceImplUnitTest extends BaseUnitTest
// 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);
}
/**
@@ -216,14 +196,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);
}
/**
@@ -237,16 +209,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));
}
/**
@@ -260,16 +222,6 @@ public class FilePlanPermissionServiceImplUnitTest extends BaseUnitTest
// 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));
}
/**
@@ -283,13 +235,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));
}
/**
@@ -303,13 +248,6 @@ public class FilePlanPermissionServiceImplUnitTest extends BaseUnitTest
// 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));
}
/**
@@ -323,23 +261,18 @@ public class FilePlanPermissionServiceImplUnitTest extends BaseUnitTest
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);
}
/**
* 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);
}
/**
@@ -350,21 +283,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);
verifyInitPermissions(child, isInherited);
// 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);
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);
}
}
/**
@@ -380,7 +312,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);
}
/**
@@ -396,7 +328,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);
}
/**
@@ -412,7 +344,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);
}
@@ -429,7 +361,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);
}
/**
@@ -445,7 +377,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);
}
/**
@@ -461,7 +393,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);
}
@@ -478,7 +410,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);
}
/**
@@ -494,7 +426,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);
}
@@ -511,7 +443,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);
}
}

View File

@@ -40,9 +40,7 @@ import org.junit.runner.RunWith;
@RunWith(ClasspathSuite.class)
@ClassnameFilters({
// Execute all test classes ending with "UnitTest"
".*UnitTest",
// Put the test classes you want to exclude here
"!.*FilePlanPermissionServiceImplUnitTest"
".*UnitTest"
})
public class AllUnitTestSuite
{