diff --git a/rm-server/config/alfresco/module/org_alfresco_module_rm/extended-repository-context.xml b/rm-server/config/alfresco/module/org_alfresco_module_rm/extended-repository-context.xml index e350a5519e..10ad2fa074 100644 --- a/rm-server/config/alfresco/module/org_alfresco_module_rm/extended-repository-context.xml +++ b/rm-server/config/alfresco/module/org_alfresco_module_rm/extended-repository-context.xml @@ -134,6 +134,9 @@ + + + @@ -229,20 +232,17 @@ - + false - - - - - ${rm.rule.runasadmin} - - + + + + ${rm.rule.runasadmin} + - - + diff --git a/rm-server/config/alfresco/module/org_alfresco_module_rm/log4j.properties b/rm-server/config/alfresco/module/org_alfresco_module_rm/log4j.properties index ebe4271aef..7a14ca27f5 100644 --- a/rm-server/config/alfresco/module/org_alfresco_module_rm/log4j.properties +++ b/rm-server/config/alfresco/module/org_alfresco_module_rm/log4j.properties @@ -16,7 +16,7 @@ log4j.logger.org.alfresco.module.org_alfresco_module_rm.patch=info log4j.logger.org.alfresco.module.org_alfresco_module_rm.security.RMMethodSecurityInterceptor=debug # -# RM permission debug +# RM permission debug # #log4j.logger.org.alfresco.module.org_alfresco_module_rm.capability.RMEntryVoter=debug #log4j.logger.org.alfresco.module.org_alfresco_module_rm.capability.RMAfterInvocationProvider=debug @@ -46,4 +46,13 @@ log4j.logger.org.alfresco.module.org_alfresco_module_rm.behaviour.BaseBehaviourB # # Patch debug # -log4j.logger.org.alfresco.module.org_alfresco_module_rm.patch=info \ No newline at end of file +log4j.logger.org.alfresco.module.org_alfresco_module_rm.patch=info +# +# RM Audit service debug +# +#log4j.logger.org.alfresco.module.org_alfresco_module_rm.audit.RecordsManagementAuditService=debug + +# +# Job debug +# +#log4j.logger.org.alfresco.module.org_alfresco_module_rm.job=debug \ No newline at end of file diff --git a/rm-server/config/alfresco/module/org_alfresco_module_rm/rm-public-services-security-context.xml b/rm-server/config/alfresco/module/org_alfresco_module_rm/rm-public-services-security-context.xml index 4937890e4e..b64ade5659 100644 --- a/rm-server/config/alfresco/module/org_alfresco_module_rm/rm-public-services-security-context.xml +++ b/rm-server/config/alfresco/module/org_alfresco_module_rm/rm-public-services-security-context.xml @@ -45,7 +45,7 @@ - + diff --git a/rm-server/config/alfresco/module/org_alfresco_module_rm/rm-service-context.xml b/rm-server/config/alfresco/module/org_alfresco_module_rm/rm-service-context.xml index 3e810cbf49..7abdc3e77a 100644 --- a/rm-server/config/alfresco/module/org_alfresco_module_rm/rm-service-context.xml +++ b/rm-server/config/alfresco/module/org_alfresco_module_rm/rm-service-context.xml @@ -378,11 +378,12 @@ - + + - - + @@ -444,6 +445,7 @@ + diff --git a/rm-server/config/alfresco/module/org_alfresco_module_rm/rm-ui-evaluators-context.xml b/rm-server/config/alfresco/module/org_alfresco_module_rm/rm-ui-evaluators-context.xml index 800e214770..863ea2b7ae 100644 --- a/rm-server/config/alfresco/module/org_alfresco_module_rm/rm-ui-evaluators-context.xml +++ b/rm-server/config/alfresco/module/org_alfresco_module_rm/rm-ui-evaluators-context.xml @@ -399,6 +399,7 @@ FILE_PLAN + RECORD RECORD_CATEGORY RECORD_FOLDER UNFILED_RECORD_CONTAINER diff --git a/rm-server/config/alfresco/templates/webscripts/org/alfresco/rma/rmpermissions.get.desc.xml b/rm-server/config/alfresco/templates/webscripts/org/alfresco/rma/rmpermissions.get.desc.xml deleted file mode 100644 index cd90572016..0000000000 --- a/rm-server/config/alfresco/templates/webscripts/org/alfresco/rma/rmpermissions.get.desc.xml +++ /dev/null @@ -1,9 +0,0 @@ - - Records Management Permissions - Retrieve the Permissions set against a Records Management node. - /api/node/{store_type}/{store_id}/{id}/rmpermissions - argument - user - required - internal - \ No newline at end of file diff --git a/rm-server/config/alfresco/templates/webscripts/org/alfresco/rma/rmpermissions.get.js b/rm-server/config/alfresco/templates/webscripts/org/alfresco/rma/rmpermissions.get.js deleted file mode 100644 index 439a2654ac..0000000000 --- a/rm-server/config/alfresco/templates/webscripts/org/alfresco/rma/rmpermissions.get.js +++ /dev/null @@ -1,86 +0,0 @@ -/** - * Entry point for rmpermissions GET data webscript. - * Queries the permissions from an RM node and constructs the data-model for the template. - * - * @method main - */ -function main() -{ - // Get the node from the URL - var pathSegments = url.match.split("/"); - var reference = [ url.templateArgs.store_type, url.templateArgs.store_id ].concat(url.templateArgs.id.split("/")); - var node = search.findNode(pathSegments[2], reference); - - // 404 if the node is not found - if (node == null) - { - status.setCode(status.STATUS_NOT_FOUND, "The node could not be found"); - return; - } - - // retrieve permissions applied to this node - var permissions = node.getFullPermissions(); - - // split tokens - results are in the format: - // [ALLOWED|DENIED];[USERNAME|GROUPNAME];PERMISSION;[INHERITED|DIRECT] - var result = []; - for (var i=0; i -{ - "data": - { - "permissions": - [ - <#list permissions as perm> - { - "id": "${perm.id}", - "authority": - { - "id": "${perm.authority.id}", - "label": "${perm.authority.label}" - }, - "inherited": ${perm.inherited?string} - }<#if perm_has_next>, - - ], - "inherited": ${inherited?string} - } -} - \ No newline at end of file diff --git a/rm-server/config/alfresco/templates/webscripts/org/alfresco/rma/rmpermissions.post.json.js b/rm-server/config/alfresco/templates/webscripts/org/alfresco/rma/rmpermissions.post.json.js index 6aa731567e..a29ec41b13 100644 --- a/rm-server/config/alfresco/templates/webscripts/org/alfresco/rma/rmpermissions.post.json.js +++ b/rm-server/config/alfresco/templates/webscripts/org/alfresco/rma/rmpermissions.post.json.js @@ -1,7 +1,7 @@ /** * Entry point for rmpermissions POST data webscript. * Applies supplied RM permissions to an RM node. - * + * * @method main */ function main() @@ -10,41 +10,46 @@ function main() var pathSegments = url.match.split("/"); var reference = [ url.templateArgs.store_type, url.templateArgs.store_id ].concat(url.templateArgs.id.split("/")); var node = search.findNode(pathSegments[2], reference); - + // 404 if the node is not found if (node == null) { status.setCode(status.STATUS_NOT_FOUND, "The node could not be found"); return; } - + if (json.has("permissions") == false) { status.setCode(status.STATUS_BAD_REQUEST, "Permissions value missing from request."); } - + + if (json.has("isInherited")) + { + node.setInheritsPermissions(json.getBoolean("isInherited")); + } + var permissions = json.getJSONArray("permissions"); for (var i=0; i, Integer> transactionCache = TransactionalResourceHelper.getMap("rm.security.checkRMRead"); + Pair key = new Pair(AuthenticationUtil.getRunAsUser(), nodeRef); - if (logger.isDebugEnabled()) - { - logger.debug("\t\tUser does not have read record permission on node, access denied. (nodeRef=" + nodeRef.toString() + ", user=" + AuthenticationUtil.getRunAsUser() + ")"); - } + if (transactionCache.containsKey(key)) + { + result = transactionCache.get(key); + } + else + { + if (permissionService.hasPermission(nodeRef, RMPermissionModel.READ_RECORDS) == AccessStatus.DENIED) + { + if (logger.isDebugEnabled()) + { + logger.debug("\t\tUser does not have read record permission on node, access denied. (nodeRef=" + nodeRef.toString() + ", user=" + AuthenticationUtil.getRunAsUser() + ")"); + } + result = AccessDecisionVoter.ACCESS_DENIED; + } + else + { + // Get the file plan for the node + NodeRef filePlan = getFilePlanService().getFilePlan(nodeRef); + if (hasViewCapability(filePlan) == AccessStatus.DENIED) + { + if (logger.isDebugEnabled()) + { + logger.debug("\t\tUser does not have view records capability permission on node, access denied. (filePlan=" + filePlan.toString() + ", user=" + AuthenticationUtil.getRunAsUser() + ")"); + } + result = AccessDecisionVoter.ACCESS_DENIED; + } + else if (!caveatConfigComponent.hasAccess(nodeRef)) + { + result = AccessDecisionVoter.ACCESS_DENIED; + } + else + { + result = AccessDecisionVoter.ACCESS_GRANTED; + } + } - return setTransactionCache("checkRmRead", nodeRef, AccessDecisionVoter.ACCESS_DENIED); - } - - // Get the file plan for the node - NodeRef filePlan = getFilePlanService().getFilePlan(nodeRef); - if (permissionService.hasPermission(filePlan, RMPermissionModel.VIEW_RECORDS) == AccessStatus.DENIED) - { - // log capability details - RMMethodSecurityInterceptor.reportCapabilityStatus(RMPermissionModel.VIEW_RECORDS, AccessDecisionVoter.ACCESS_DENIED); + // cache result + transactionCache.put(key, result); + } - if (logger.isDebugEnabled()) - { - logger.debug("\t\tUser does not have view records capability permission on node, access denied. (filePlan=" + filePlan.toString() + ", user=" + AuthenticationUtil.getRunAsUser() + ")"); - } - return setTransactionCache("checkRmRead", nodeRef, AccessDecisionVoter.ACCESS_DENIED); - } + return result; + } - if (caveatConfigComponent.hasAccess(nodeRef)) - { - return setTransactionCache("checkRmRead", nodeRef, AccessDecisionVoter.ACCESS_GRANTED); - } - else - { - return setTransactionCache("checkRmRead", nodeRef, AccessDecisionVoter.ACCESS_DENIED); - } + /** + * Helper method to determine whether the current user has view capability on the file plan + * + * @param filePlan file plan + * @return {@link AccessStatus} + */ + private AccessStatus hasViewCapability(NodeRef filePlan) + { + Map, AccessStatus> transactionCache = TransactionalResourceHelper.getMap("rm.security.hasViewCapability"); + Pair key = new Pair(AuthenticationUtil.getRunAsUser(), filePlan); + if (transactionCache.containsKey(key)) + { + return transactionCache.get(key); + } + else + { + AccessStatus result = permissionService.hasPermission(filePlan, RMPermissionModel.VIEW_RECORDS); + transactionCache.put(key, result); + return result; + } } @SuppressWarnings("rawtypes") diff --git a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/capability/declarative/DeclarativeCapability.java b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/capability/declarative/DeclarativeCapability.java index c5225f5247..7017bcae68 100644 --- a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/capability/declarative/DeclarativeCapability.java +++ b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/capability/declarative/DeclarativeCapability.java @@ -30,6 +30,8 @@ import org.alfresco.module.org_alfresco_module_rm.capability.AbstractCapability; import org.alfresco.module.org_alfresco_module_rm.capability.Capability; import org.alfresco.module.org_alfresco_module_rm.fileplan.FilePlanComponentKind; import org.alfresco.module.org_alfresco_module_rm.security.RMMethodSecurityInterceptor; +import org.alfresco.repo.security.authentication.AuthenticationUtil; +import org.alfresco.repo.transaction.TransactionalResourceHelper; import org.alfresco.service.cmr.repository.NodeRef; import org.alfresco.service.cmr.security.AccessStatus; import org.apache.commons.logging.Log; @@ -289,29 +291,41 @@ public class DeclarativeCapability extends AbstractCapability { int result = AccessDecisionVoter.ACCESS_ABSTAIN; - // Check we are dealing with a file plan component - if (getFilePlanService().isFilePlanComponent(nodeRef)) + // check transaction cache + Map map = TransactionalResourceHelper.getMap("rm.declarativeCapability"); + String key = getName() + "|" + nodeRef.toString() + "|" + AuthenticationUtil.getRunAsUser(); + if (map.containsKey(key)) { - // Check the kind of the object, the permissions and the conditions - if (checkKinds(nodeRef) && checkPermissions(nodeRef) && checkConditions(nodeRef)) - { - // Opportunity for child implementations to extend - result = evaluateImpl(nodeRef); - } - else - { - result = AccessDecisionVoter.ACCESS_DENIED; - } + result = map.get(key); } - - // Last chance for child implementations to veto/change the result - result = onEvaluate(nodeRef, result); - - // log access denied to help with debug - if (LOGGER.isDebugEnabled() && AccessDecisionVoter.ACCESS_DENIED == result) + else { - LOGGER.debug("FAIL: Capability " + getName() + " returned an Access Denied result during evaluation of node " + nodeRef.toString()); - } + // Check we are dealing with a file plan component + if (getFilePlanService().isFilePlanComponent(nodeRef) == true) + { + // Check the kind of the object, the permissions and the conditions + if (checkKinds(nodeRef) == true && checkPermissions(nodeRef) == true && checkConditions(nodeRef) == true) + { + // Opportunity for child implementations to extend + result = evaluateImpl(nodeRef); + } + else + { + result = AccessDecisionVoter.ACCESS_DENIED; + } + } + + // Last chance for child implementations to veto/change the result + result = onEvaluate(nodeRef, result); + + // log access denied to help with debug + if (LOGGER.isDebugEnabled() == true && AccessDecisionVoter.ACCESS_DENIED == result) + { + LOGGER.debug("Capability " + getName() + " returned an Access Denied result during evaluation of node " + nodeRef.toString()); + } + + map.put(key, result); + } return result; } diff --git a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/capability/declarative/condition/AtLeastOneCondition.java b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/capability/declarative/condition/AtLeastOneCondition.java index 4e3c80baf3..5283e84e6c 100644 --- a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/capability/declarative/condition/AtLeastOneCondition.java +++ b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/capability/declarative/condition/AtLeastOneCondition.java @@ -43,6 +43,11 @@ public class AtLeastOneCondition extends AbstractCapabilityCondition this.conditions = conditions; } + /** + * Don't use the transaction cache for the composite condition + * + * @see org.alfresco.module.org_alfresco_module_rm.capability.declarative.AbstractCapabilityCondition#evaluate(org.alfresco.service.cmr.repository.NodeRef) + */ @Override public boolean evaluate(NodeRef nodeRef) { diff --git a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/capability/declarative/condition/IsPropertySetCondition.java b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/capability/declarative/condition/IsPropertySetCondition.java index 00483e911c..3ed855e322 100644 --- a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/capability/declarative/condition/IsPropertySetCondition.java +++ b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/capability/declarative/condition/IsPropertySetCondition.java @@ -34,6 +34,7 @@ public class IsPropertySetCondition extends AbstractCapabilityCondition { /** property name (eg: rma:location) */ private String propertyName; + private QName propertyQName; /** namespace service */ private NamespaceService namespaceService; @@ -59,7 +60,11 @@ public class IsPropertySetCondition extends AbstractCapabilityCondition */ protected QName getPropertyQName() { - return QName.createQName(propertyName, namespaceService); + if (propertyQName == null) + { + propertyQName = QName.createQName(propertyName, namespaceService); + } + return propertyQName; } /** diff --git a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/fileplan/FilePlanServiceImpl.java b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/fileplan/FilePlanServiceImpl.java index 40c9ae9c7d..64a5da70e1 100644 --- a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/fileplan/FilePlanServiceImpl.java +++ b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/fileplan/FilePlanServiceImpl.java @@ -30,12 +30,18 @@ import java.util.Set; import org.alfresco.error.AlfrescoRuntimeException; import org.alfresco.model.ContentModel; -import org.alfresco.module.org_alfresco_module_rm.security.FilePlanPermissionService; +import org.alfresco.module.org_alfresco_module_rm.capability.RMPermissionModel; +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.module.org_alfresco_module_rm.util.ServiceBaseImpl; +import org.alfresco.repo.cache.SimpleCache; import org.alfresco.repo.domain.node.NodeDAO; import org.alfresco.service.cmr.repository.ChildAssociationRef; import org.alfresco.service.cmr.repository.NodeRef; import org.alfresco.service.cmr.repository.StoreRef; +import org.alfresco.service.cmr.security.PermissionService; import org.alfresco.service.cmr.site.SiteInfo; import org.alfresco.service.cmr.site.SiteService; import org.alfresco.service.namespace.NamespaceService; @@ -52,7 +58,8 @@ import org.springframework.extensions.surf.util.I18NUtil; * @since 2.1 */ public class FilePlanServiceImpl extends ServiceBaseImpl - implements FilePlanService + implements FilePlanService, + RecordsManagementModel { /** I18N */ private static final String MSG_DUP_ROOT = "rm.service.dup-root"; @@ -72,34 +79,75 @@ public class FilePlanServiceImpl extends ServiceBaseImpl /** RM site file plan container */ private static final String FILE_PLAN_CONTAINER = "documentLibrary"; - /** node DAO */ + /** root container cache */ + private SimpleCache, NodeRef> rootContainerCache; + + /** File plan role service */ + private FilePlanRoleService filePlanRoleService; + + /** Permission service */ + private PermissionService permissionService; + + /** Node DAO */ private NodeDAO nodeDAO; - /** file plan permission service */ - private FilePlanPermissionService filePlanPermissionService; + /** Site service */ + private SiteService siteService; /** - * @param nodeDAO node DAO + * Gets the file plan role service + * + * @return The file plan role service */ - public void setNodeDAO(NodeDAO nodeDAO) + public FilePlanRoleService getFilePlanRoleService() { - this.nodeDAO = nodeDAO; + if (filePlanRoleService == null) + { + filePlanRoleService = (FilePlanRoleService) applicationContext.getBean("FilePlanRoleService"); + } + return filePlanRoleService; } /** - * @return site service + * Gets the permission service + * + * @return The permission service */ - protected SiteService getSiteService() + public PermissionService getPermissionService() { - return (SiteService)applicationContext.getBean("siteService"); + if (permissionService == null) + { + permissionService = (PermissionService) applicationContext.getBean("permissionService"); + } + return permissionService; } /** - * @param filePlanPermissionService file plan permission service + * Gets the node DAO + * + * @return The node DAO */ - public void setFilePlanPermissionService(FilePlanPermissionService filePlanPermissionService) + public NodeDAO getNodeDAO() { - this.filePlanPermissionService = filePlanPermissionService; + if (nodeDAO == null) + { + nodeDAO = (NodeDAO) applicationContext.getBean("nodeDAO"); + } + return nodeDAO; + } + + /** + * Gets the site service + * + * @return The site service + */ + public SiteService getSiteService() + { + if (siteService == null) + { + siteService = (SiteService) applicationContext.getBean("SiteService"); + } + return siteService; } /** @@ -111,6 +159,14 @@ public class FilePlanServiceImpl extends ServiceBaseImpl return getFilePlans(StoreRef.STORE_REF_WORKSPACE_SPACESSTORE); } + /** + * @param rootContainerCache root container cache + */ + public void setRootContainerCache(SimpleCache, NodeRef> rootContainerCache) + { + this.rootContainerCache = rootContainerCache; + } + /** * @see org.alfresco.module.org_alfresco_module_rm.fileplan.FilePlanService#getFilePlans(org.alfresco.service.cmr.repository.StoreRef) */ @@ -122,7 +178,7 @@ public class FilePlanServiceImpl extends ServiceBaseImpl final Set results = new HashSet(); Set aspects = new HashSet(1); aspects.add(ASPECT_RECORDS_MANAGEMENT_ROOT); - nodeDAO.getNodesWithAspects(aspects, Long.MIN_VALUE, Long.MAX_VALUE, new NodeDAO.NodeRefQueryCallback() + getNodeDAO().getNodesWithAspects(aspects, Long.MIN_VALUE, Long.MAX_VALUE, new NodeDAO.NodeRefQueryCallback() { @Override public boolean handle(Pair nodePair) @@ -146,12 +202,11 @@ public class FilePlanServiceImpl extends ServiceBaseImpl public NodeRef getFilePlanBySiteId(String siteId) { NodeRef filePlan = null; - SiteService siteService = getSiteService(); - SiteInfo siteInfo = siteService.getSite(siteId); - if (siteInfo != null && siteService.hasContainer(siteId, FILE_PLAN_CONTAINER)) + SiteInfo siteInfo = getSiteService().getSite(siteId); + if (siteInfo != null && getSiteService().hasContainer(siteId, FILE_PLAN_CONTAINER)) { - NodeRef nodeRef = siteService.getContainer(siteId, FILE_PLAN_CONTAINER); + NodeRef nodeRef = getSiteService().getContainer(siteId, FILE_PLAN_CONTAINER); if (instanceOf(nodeRef, TYPE_FILE_PLAN)) { filePlan = nodeRef; @@ -198,10 +253,11 @@ public class FilePlanServiceImpl extends ServiceBaseImpl } /** + * Get the file root container for the given type. * - * @param filePlan - * @param containerName - * @return + * @param filePlan file plan + * @param containerName container type + * @return {@link NodeRef} file plan container */ private NodeRef getFilePlanRootContainer(NodeRef filePlan, String containerName) { @@ -212,16 +268,25 @@ public class FilePlanServiceImpl extends ServiceBaseImpl } NodeRef result = null; + Pair key = new Pair(filePlan, containerName); - // try and get the unfiled record container - List assocs = nodeService.getChildAssocs(filePlan, ContentModel.ASSOC_CONTAINS, QName.createQName(RM_URI, containerName)); - if (assocs.size() > 1) + if (!rootContainerCache.contains(key)) { - throw new AlfrescoRuntimeException("Unable to get unfiled conatiner " + containerName + "."); + // try and get the unfiled record container + List assocs = nodeService.getChildAssocs(filePlan, ContentModel.ASSOC_CONTAINS, QName.createQName(RM_URI, containerName)); + if (assocs.size() > 1) + { + throw new AlfrescoRuntimeException("Unable to get unfiled conatiner " + containerName + "."); + } + else if (assocs.size() == 1) + { + result = assocs.get(0).getChildRef(); + rootContainerCache.put(key, result); + } } - else if (assocs.size() == 1) + else { - result = assocs.get(0).getChildRef(); + result = rootContainerCache.get(key); } return result; @@ -269,6 +334,8 @@ public class FilePlanServiceImpl extends ServiceBaseImpl throw new AlfrescoRuntimeException("Unable to create file plan root container, because passed node is not a file plan."); } + String allRoles = getFilePlanRoleService().getAllRolesContainerGroup(filePlan); + // create the properties map Map properties = new HashMap(1); properties.put(ContentModel.PROP_NAME, containerName); @@ -281,8 +348,23 @@ public class FilePlanServiceImpl extends ServiceBaseImpl containerType, properties).getChildRef(); - // setup the permissions - filePlanPermissionService.setupPermissions(filePlan, container); + // if (inheritPermissions == false) + // { + // set inheritance to false + getPermissionService().setInheritParentPermissions(container, false); + getPermissionService().setPermission(container, allRoles, RMPermissionModel.READ_RECORDS, true); + getPermissionService().setPermission(container, ExtendedReaderDynamicAuthority.EXTENDED_READER, RMPermissionModel.READ_RECORDS, true); + getPermissionService().setPermission(container, ExtendedWriterDynamicAuthority.EXTENDED_WRITER, RMPermissionModel.FILING, true); + + // TODO set the admin users to have filing permissions on the unfiled container!!! + // TODO we will need to be able to get a list of the admin roles from the service + // } + // else + // { + // just inherit eveything + // TODO will change this when we are able to set permissions on holds and transfers! + // getPermissionService().setInheritParentPermissions(container, true); + // } return container; } diff --git a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/freeze/FreezeServiceImpl.java b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/freeze/FreezeServiceImpl.java index f814b3def7..4bc3466ab5 100644 --- a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/freeze/FreezeServiceImpl.java +++ b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/freeze/FreezeServiceImpl.java @@ -38,7 +38,6 @@ import org.alfresco.repo.transaction.RetryingTransactionHelper.RetryingTransacti import org.alfresco.service.cmr.repository.ChildAssociationRef; import org.alfresco.service.cmr.repository.NodeRef; import org.alfresco.service.namespace.QName; -import org.alfresco.service.namespace.RegexQNamePattern; import org.alfresco.service.transaction.TransactionService; import org.alfresco.util.ParameterCheck; import org.apache.commons.lang.StringUtils; @@ -107,109 +106,6 @@ public class FreezeServiceImpl extends ServiceBaseImpl return nodeService.hasAspect(nodeRef, ASPECT_FROZEN); } - /** - * @see org.alfresco.module.org_alfresco_module_rm.freeze.FreezeService#hasFrozenChildren(org.alfresco.service.cmr.repository.NodeRef) - */ - @Override - public boolean hasFrozenChildren(final NodeRef nodeRef) - { - ParameterCheck.mandatory("nodeRef", nodeRef); - - boolean result = false; - - // check that we are dealing with a record folder - if (isRecordFolder(nodeRef)) - { - int heldCount = 0; - - if (nodeService.hasAspect(nodeRef, ASPECT_HELD_CHILDREN)) - { - heldCount = (Integer)getInternalNodeService().getProperty(nodeRef, PROP_HELD_CHILDREN_COUNT); - } - else - { - final TransactionService transactionService = (TransactionService)applicationContext.getBean("transactionService"); - - heldCount = AuthenticationUtil.runAsSystem(new RunAsWork() - { - @Override - public Integer doWork() - { - return transactionService.getRetryingTransactionHelper().doInTransaction(new RetryingTransactionCallback() - { - public Integer execute() throws Throwable - { - int heldCount = 0; - - // NOTE: this process remains to 'patch' older systems to improve performance next time around - List childAssocs = getInternalNodeService().getChildAssocs(nodeRef, ContentModel.ASSOC_CONTAINS, - RegexQNamePattern.MATCH_ALL); - if (childAssocs != null && !childAssocs.isEmpty()) - { - for (ChildAssociationRef childAssociationRef : childAssocs) - { - NodeRef record = childAssociationRef.getChildRef(); - if (childAssociationRef.isPrimary() && isRecord(record) && isFrozen(record)) - { - heldCount ++; - } - } - } - - // add aspect and set count - Map props = new HashMap(1); - props.put(PROP_HELD_CHILDREN_COUNT, heldCount); - getInternalNodeService().addAspect(nodeRef, ASPECT_HELD_CHILDREN, props); - - return heldCount; - } - }, - false, true); - } - }); - } - - // true if more than one child held - result = (heldCount > 0); - } - - return result; - } - - /** - * @see org.alfresco.module.org_alfresco_module_rm.freeze.FreezeService#getFreezeDate(org.alfresco.service.cmr.repository.NodeRef) - */ - @Override - public Date getFreezeDate(NodeRef nodeRef) - { - ParameterCheck.mandatory("nodeRef", nodeRef); - - if (isFrozen(nodeRef)) - { - Serializable property = nodeService.getProperty(nodeRef, PROP_FROZEN_AT); - if (property != null) { return (Date) property; } - } - - return null; - } - - /** - * @see org.alfresco.module.org_alfresco_module_rm.freeze.FreezeService#getFreezeInitiator(org.alfresco.service.cmr.repository.NodeRef) - */ - @Override - public String getFreezeInitiator(NodeRef nodeRef) - { - ParameterCheck.mandatory("nodeRef", nodeRef); - - if (isFrozen(nodeRef)) - { - Serializable property = nodeService.getProperty(nodeRef, PROP_FROZEN_BY); - if (property != null) { return (String) property; } - } - - return null; - } - /** * Deprecated Method Implementations */ @@ -357,6 +253,112 @@ public class FreezeServiceImpl extends ServiceBaseImpl return new HashSet(getHoldService().getHolds(filePlan)); } + /** + * @see org.alfresco.module.org_alfresco_module_rm.freeze.FreezeService#hasFrozenChildren(org.alfresco.service.cmr.repository.NodeRef) + */ + @Override + public boolean hasFrozenChildren(final NodeRef nodeRef) + { + ParameterCheck.mandatory("nodeRef", nodeRef); + + boolean result = false; + + // check that we are dealing with a record folder + if (isRecordFolder(nodeRef)) + { + int heldCount = 0; + + if (nodeService.hasAspect(nodeRef, ASPECT_HELD_CHILDREN)) + { + heldCount = (Integer)getInternalNodeService().getProperty(nodeRef, PROP_HELD_CHILDREN_COUNT); + } + else + { + final TransactionService transactionService = (TransactionService)applicationContext.getBean("transactionService"); + + heldCount = AuthenticationUtil.runAsSystem(new RunAsWork() + { + @Override + public Integer doWork() + { + return transactionService.getRetryingTransactionHelper().doInTransaction(new RetryingTransactionCallback() + { + public Integer execute() throws Throwable + { + int heldCount = 0; + + // NOTE: this process remains to 'patch' older systems to improve performance next time around + List childAssocs = getInternalNodeService().getChildAssocs(nodeRef, ContentModel.ASSOC_CONTAINS, null); + if (childAssocs != null && !childAssocs.isEmpty()) + { + for (ChildAssociationRef childAssociationRef : childAssocs) + { + NodeRef record = childAssociationRef.getChildRef(); + if (childAssociationRef.isPrimary() && isRecord(record) && isFrozen(record)) + { + heldCount ++; + } + } + } + + // add aspect and set count + Map props = new HashMap(1); + props.put(PROP_HELD_CHILDREN_COUNT, heldCount); + getInternalNodeService().addAspect(nodeRef, ASPECT_HELD_CHILDREN, props); + + return heldCount; + } + }, + false, true); + } + }); + } + + // true if more than one child held + result = (heldCount > 0); + } + + return result; + } + + /** + * @see org.alfresco.module.org_alfresco_module_rm.freeze.FreezeService#getFreezeDate(org.alfresco.service.cmr.repository.NodeRef) + */ + @Override + public Date getFreezeDate(NodeRef nodeRef) + { + ParameterCheck.mandatory("nodeRef", nodeRef); + + if (isFrozen(nodeRef)) + { + Serializable property = nodeService.getProperty(nodeRef, PROP_FROZEN_AT); + if (property != null) { return (Date) property; } + } + + return null; + } + + /** + * @see org.alfresco.module.org_alfresco_module_rm.freeze.FreezeService#getFreezeInitiator(org.alfresco.service.cmr.repository.NodeRef) + */ + @Override + public String getFreezeInitiator(NodeRef nodeRef) + { + ParameterCheck.mandatory("nodeRef", nodeRef); + + if (isFrozen(nodeRef)) + { + Serializable property = nodeService.getProperty(nodeRef, PROP_FROZEN_BY); + if (property != null) { return (String) property; } + } + + return null; + } + + /** + * Helper Methods + */ + /** * Creates a hold using the given nodeRef and reason * diff --git a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/model/RecordsManagementModel.java b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/model/RecordsManagementModel.java index 388f9d1de4..481afd29cd 100644 --- a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/model/RecordsManagementModel.java +++ b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/model/RecordsManagementModel.java @@ -262,7 +262,7 @@ public interface RecordsManagementModel extends RecordsManagementCustomModel // @since 2.2 QName ASPECT_HELD_CHILDREN = QName.createQName(RM_URI, "heldChildren"); QName PROP_HELD_CHILDREN_COUNT = QName.createQName(RM_URI, "heldChildrenCount"); - + // Countable aspect QName ASPECT_COUNTABLE = QName.createQName(RM_URI, "countable"); QName PROP_COUNT = QName.createQName(RM_URI, "count"); diff --git a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/role/FilePlanRoleServiceImpl.java b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/role/FilePlanRoleServiceImpl.java index 89193d0def..b9c65bcf43 100644 --- a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/role/FilePlanRoleServiceImpl.java +++ b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/role/FilePlanRoleServiceImpl.java @@ -68,7 +68,7 @@ public class FilePlanRoleServiceImpl implements FilePlanRoleService, /** Location of bootstrap role JSON */ private static final String BOOTSTRAP_ROLE_JSON_LOCATION = "alfresco/module/org_alfresco_module_rm/security/rm-default-roles-bootstrap.json"; - + /** JSON names */ private static final String JSON_NAME = "name"; private static final String JSON_DISPLAY_LABEL = "displayLabel"; @@ -242,7 +242,7 @@ public class FilePlanRoleServiceImpl implements FilePlanRoleService, /** * Bootstraps the default roles - * + * * @param filePlan file plan * @param systemContainers system containers */ @@ -327,7 +327,7 @@ public class FilePlanRoleServiceImpl implements FilePlanRoleService, // Add any additional admin permissions if (isAdmin) - { + { // Admin has filing permissionService.setPermission(filePlan, role.getRoleGroupName(), RMPermissionModel.FILING, true); if (systemContainers != null) diff --git a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/script/slingshot/RMSearchGet.java b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/script/slingshot/RMSearchGet.java index a190e8f40a..9a48a51f75 100644 --- a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/script/slingshot/RMSearchGet.java +++ b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/script/slingshot/RMSearchGet.java @@ -33,9 +33,7 @@ import org.alfresco.module.org_alfresco_module_rm.search.RecordsManagementSearch import org.alfresco.module.org_alfresco_module_rm.search.RecordsManagementSearchService; import org.alfresco.module.org_alfresco_module_rm.search.SavedSearchDetailsCompatibility; import org.alfresco.service.cmr.dictionary.DictionaryService; -import org.alfresco.service.cmr.repository.ChildAssociationRef; import org.alfresco.service.cmr.repository.ContentData; -import org.alfresco.service.cmr.repository.ContentReader; import org.alfresco.service.cmr.repository.ContentService; import org.alfresco.service.cmr.repository.NodeRef; import org.alfresco.service.cmr.repository.NodeService; @@ -44,6 +42,7 @@ import org.alfresco.service.cmr.security.PersonService; import org.alfresco.service.cmr.site.SiteService; import org.alfresco.service.namespace.NamespaceService; import org.alfresco.service.namespace.QName; +import org.alfresco.util.Pair; import org.apache.commons.lang.ArrayUtils; import org.apache.commons.lang.StringUtils; import org.springframework.extensions.webscripts.Cache; @@ -199,20 +198,20 @@ public class RMSearchGet extends DeclarativeWebScript } // Execute search - List results = recordsManagementSearchService.search(siteId, query, searchParameters); + List> results = recordsManagementSearchService.search(siteId, query, searchParameters); // Reset person data cache personDataCache = new HashMap(57); // Process the result items List items = new ArrayList(results.size()); - for (NodeRef nodeRef : results) + for (Pair pair : results) { // FIXME: See RM-478 // TC 3-3 Create User Groups try { - Item item = new Item(nodeRef); + Item item = new Item(pair.getFirst(), pair.getSecond()); items.add(item); } catch(Exception e) {} @@ -245,7 +244,7 @@ public class RMSearchGet extends DeclarativeWebScript private Map nodeProperties; private Map properties; - public Item(NodeRef nodeRef) + public Item(NodeRef parent, NodeRef nodeRef) { // Set node ref this.nodeRef = nodeRef; @@ -265,12 +264,12 @@ public class RMSearchGet extends DeclarativeWebScript } // Get parent node reference - NodeRef parent = null; - ChildAssociationRef assoc = nodeService.getPrimaryParent(nodeRef); - if (assoc != null) - { - parent = assoc.getParentRef(); - } +// NodeRef parent = null; +// ChildAssociationRef assoc = nodeService.getPrimaryParent(nodeRef); +// if (assoc != null) +// { +// parent = assoc.getParentRef(); +// } if (isContainer) { @@ -334,16 +333,6 @@ public class RMSearchGet extends DeclarativeWebScript if (!NamespaceService.SYSTEM_MODEL_1_0_URI.equals(qName.getNamespaceURI())) { String prefixName = qName.getPrefixString().replace(":", "_"); - Serializable value = entry.getValue(); - if (value instanceof NodeRef) - { - value = value.toString(); - } - else if (value instanceof ContentData) - { - ContentReader contentReader = contentService.getReader(nodeRef, qName); - value = contentReader.getContentString(); - } properties.put(prefixName, entry.getValue()); } } diff --git a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/search/RecordsManagementSearchService.java b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/search/RecordsManagementSearchService.java index 3257ffdf76..22c3c7cc8f 100644 --- a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/search/RecordsManagementSearchService.java +++ b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/search/RecordsManagementSearchService.java @@ -21,6 +21,7 @@ package org.alfresco.module.org_alfresco_module_rm.search; import java.util.List; import org.alfresco.service.cmr.repository.NodeRef; +import org.alfresco.util.Pair; /** * Records management search service. @@ -33,10 +34,10 @@ public interface RecordsManagementSearchService * Execute a records management search * @param siteId the id of the rm site to query * @param query search query string - * @param searchParameters search parameters - * @return {@link List}<{@link NodeRef}> search results + * @param searchParameters search parameters + * @return {@link List}<{@link Pair}<{@link NodeRef}, {@link NodeRef}> search results as pairs for parent and child nodes */ - List search(String siteId, String query, RecordsManagementSearchParameters searchParameters); + List> search(String siteId, String query, RecordsManagementSearchParameters searchParameters); /** * Get all the searches saved on the given records management site. diff --git a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/search/RecordsManagementSearchServiceImpl.java b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/search/RecordsManagementSearchServiceImpl.java index e0962ae8a0..5eed77b551 100644 --- a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/search/RecordsManagementSearchServiceImpl.java +++ b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/search/RecordsManagementSearchServiceImpl.java @@ -30,6 +30,7 @@ import org.alfresco.repo.security.authentication.AuthenticationUtil; import org.alfresco.repo.security.authentication.AuthenticationUtil.RunAsWork; import org.alfresco.service.cmr.model.FileFolderService; import org.alfresco.service.cmr.model.FileInfo; +import org.alfresco.service.cmr.repository.ChildAssociationRef; import org.alfresco.service.cmr.repository.ContentReader; import org.alfresco.service.cmr.repository.ContentWriter; import org.alfresco.service.cmr.repository.NodeRef; @@ -41,6 +42,7 @@ import org.alfresco.service.cmr.site.SiteService; import org.alfresco.service.namespace.NamespaceService; import org.alfresco.service.namespace.QName; import org.alfresco.util.ISO9075; +import org.alfresco.util.Pair; import org.alfresco.util.ParameterCheck; import org.json.JSONArray; import org.json.JSONException; @@ -173,7 +175,7 @@ public class RecordsManagementSearchServiceImpl implements RecordsManagementSear * @see org.alfresco.module.org_alfresco_module_rm.search.RecordsManagementSearchService#search(java.lang.String, java.lang.String, org.alfresco.module.org_alfresco_module_rm.search.RecordsManagementSearchParameters) */ @Override - public List search(String siteId, String query, RecordsManagementSearchParameters rmSearchParameters) + public List> search(String siteId, String query, RecordsManagementSearchParameters rmSearchParameters) { // build the full RM query StringBuilder fullQuery = new StringBuilder(1024); @@ -206,9 +208,16 @@ public class RecordsManagementSearchServiceImpl implements RecordsManagementSear // execute query ResultSet resultSet = searchService.query(searchParameters); + + // process results + List> result = new ArrayList>(resultSet.length()); + for (ChildAssociationRef childAssoc : resultSet.getChildAssocRefs()) + { + result.add(new Pair(childAssoc.getParentRef(), childAssoc.getChildRef())); + } // return results - return resultSet.getNodeRefs(); + return result; } /** diff --git a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/security/ExtendedReaderDynamicAuthority.java b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/security/ExtendedReaderDynamicAuthority.java index 3e932652a7..443414e66d 100644 --- a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/security/ExtendedReaderDynamicAuthority.java +++ b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/security/ExtendedReaderDynamicAuthority.java @@ -18,8 +18,12 @@ */ package org.alfresco.module.org_alfresco_module_rm.security; +import java.util.Collections; +import java.util.Map; import java.util.Set; +import org.alfresco.module.org_alfresco_module_rm.capability.RMPermissionModel; +import org.alfresco.repo.security.permissions.PermissionReference; import org.alfresco.service.cmr.repository.NodeRef; /** @@ -40,13 +44,45 @@ public class ExtendedReaderDynamicAuthority extends ExtendedSecurityBaseDynamicA public String getAuthority() { return EXTENDED_READER; + } + + /** + * @see org.alfresco.repo.security.permissions.DynamicAuthority#requiredFor() + */ + @Override + public Set requiredFor() + { + if (requiredFor == null) + { + requiredFor = Collections.singleton(getModelDAO().getPermissionReference(null, RMPermissionModel.READ_RECORDS)); + } + + return requiredFor; } /** * @see org.alfresco.module.org_alfresco_module_rm.security.ExtendedSecurityBaseDynamicAuthority#getAuthorites(org.alfresco.service.cmr.repository.NodeRef) */ - protected Set getAuthorites(NodeRef nodeRef) + @SuppressWarnings("unchecked") + protected Set getAuthorites(NodeRef nodeRef) { - return getExtendedSecurityService().getExtendedReaders(nodeRef); + Set result = null; + + Map readerMap = (Map)getNodeService().getProperty(nodeRef, PROP_READERS); + if (readerMap != null) + { + result = readerMap.keySet(); + } + + return result; + } + + /** + * @see org.alfresco.module.org_alfresco_module_rm.security.ExtendedSecurityBaseDynamicAuthority#getTransactionCacheName() + */ + @Override + protected String getTransactionCacheName() + { + return "rm.extendedreaderdynamicauthority"; } } diff --git a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/security/ExtendedSecurityBaseDynamicAuthority.java b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/security/ExtendedSecurityBaseDynamicAuthority.java index 170af81010..af1c39e600 100644 --- a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/security/ExtendedSecurityBaseDynamicAuthority.java +++ b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/security/ExtendedSecurityBaseDynamicAuthority.java @@ -24,10 +24,12 @@ import java.util.Set; import org.alfresco.module.org_alfresco_module_rm.model.RecordsManagementModel; import org.alfresco.repo.security.permissions.DynamicAuthority; import org.alfresco.repo.security.permissions.PermissionReference; +import org.alfresco.repo.security.permissions.impl.ModelDAO; import org.alfresco.repo.transaction.TransactionalResourceHelper; import org.alfresco.service.cmr.repository.NodeRef; import org.alfresco.service.cmr.repository.NodeService; import org.alfresco.service.cmr.security.AuthorityService; +import org.alfresco.util.Pair; import org.springframework.context.ApplicationContext; import org.springframework.context.ApplicationContextAware; @@ -41,9 +43,6 @@ public abstract class ExtendedSecurityBaseDynamicAuthority implements DynamicAut RecordsManagementModel, ApplicationContextAware { - /** transaction cache key */ - private static final String KEY_HAS_AUTHORITY_CACHE = "rm.transaction.hasAuthority"; - /** Authority service */ private AuthorityService authorityService; @@ -56,6 +55,12 @@ public abstract class ExtendedSecurityBaseDynamicAuthority implements DynamicAut /** Application context */ protected ApplicationContext applicationContext; + /** model DAO */ + protected ModelDAO modelDAO; + + /** permission reference */ + protected Set requiredFor; + // NOTE: we get the services directly from the application context in this way to avoid // cyclic relationships and issues when loading the application context @@ -95,6 +100,23 @@ public abstract class ExtendedSecurityBaseDynamicAuthority implements DynamicAut return nodeService; } + /** + * @return model DAO + */ + protected ModelDAO getModelDAO() + { + if (modelDAO == null) + { + modelDAO = (ModelDAO)applicationContext.getBean("permissionsModelDAO"); + } + return modelDAO; + } + + /** + * @return String transaction cache name + */ + protected abstract String getTransactionCacheName(); + /** * @see org.springframework.context.ApplicationContextAware#setApplicationContext(org.springframework.context.ApplicationContext) */ @@ -121,63 +143,40 @@ public abstract class ExtendedSecurityBaseDynamicAuthority implements DynamicAut { boolean result = false; - if (getNodeService().hasAspect(nodeRef, ASPECT_EXTENDED_SECURITY)) + Map, Boolean> transactionCache = TransactionalResourceHelper.getMap(getTransactionCacheName()); + Pair key = new Pair(nodeRef, userName); + + if (transactionCache.containsKey(key)) { - Set authorities = getAuthorites(nodeRef); - if (authorities != null) - { - for (String authority : authorities) - { - if ("GROUP_EVERYONE".equals(authority)) - { - // 'eveyone' is there so break - result = true; - break; - } - else if (authority.startsWith("GROUP_")) - { - Map transactionCache = TransactionalResourceHelper.getMap(KEY_HAS_AUTHORITY_CACHE); - String key = authority + "|" + userName; - if (transactionCache.containsKey(key)) - { - result = transactionCache.get(key); - break; - } - else - { - Set contained = getAuthorityService().getAuthoritiesForUser(userName); - if (contained.contains(authority)) - { - result = true; - transactionCache.put(key, result); - break; - } - } - } - else - { - // presume we have a user - if (authority.equals(userName)) - { - result = true; - break; - } - } - } - } + result = transactionCache.get(key); + } + else + { + if (getNodeService().hasAspect(nodeRef, ASPECT_EXTENDED_SECURITY) == true) + { + Set authorities = getAuthorites(nodeRef); + if (authorities != null) + { + // check for everyone or the user + if (authorities.contains("GROUP_EVEYONE") || + authorities.contains(userName)) + { + result = true; + } + else + { + // determine whether any of the users groups are in the extended security + Set contained = getAuthorityService().getAuthoritiesForUser(userName); + authorities.retainAll(contained); + result = (authorities.size() != 0); + } + } + } + + // cache result + transactionCache.put(key, result); } return result; } - - /** - * Base implementation - * - * @see org.alfresco.repo.security.permissions.DynamicAuthority#requiredFor() - */ - @Override - public Set requiredFor() - { - return null; - } } diff --git a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/security/ExtendedWriterDynamicAuthority.java b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/security/ExtendedWriterDynamicAuthority.java index e5ab5ab1ea..c27faa6edf 100644 --- a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/security/ExtendedWriterDynamicAuthority.java +++ b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/security/ExtendedWriterDynamicAuthority.java @@ -18,8 +18,13 @@ */ package org.alfresco.module.org_alfresco_module_rm.security; +import java.util.Collections; +import java.util.HashSet; +import java.util.Map; import java.util.Set; +import org.alfresco.module.org_alfresco_module_rm.capability.RMPermissionModel; +import org.alfresco.repo.security.permissions.PermissionReference; import org.alfresco.service.cmr.repository.NodeRef; /** @@ -41,12 +46,48 @@ public class ExtendedWriterDynamicAuthority extends ExtendedSecurityBaseDynamicA { return EXTENDED_WRITER; } + + /** + * @see org.alfresco.repo.security.permissions.DynamicAuthority#requiredFor() + */ + @Override + public Set requiredFor() + { + if (requiredFor == null) + { + requiredFor = new HashSet(3); + Collections.addAll(requiredFor, + getModelDAO().getPermissionReference(null, RMPermissionModel.READ_RECORDS), + getModelDAO().getPermissionReference(null, RMPermissionModel.FILING), + getModelDAO().getPermissionReference(null, RMPermissionModel.FILE_RECORDS)); + } + + return requiredFor; + } /** * @see org.alfresco.module.org_alfresco_module_rm.security.ExtendedSecurityBaseDynamicAuthority#getAuthorites(org.alfresco.service.cmr.repository.NodeRef) */ - protected Set getAuthorites(NodeRef nodeRef) + @SuppressWarnings("unchecked") + protected Set getAuthorites(NodeRef nodeRef) { - return getExtendedSecurityService().getExtendedWriters(nodeRef); - } + Set result = null; + + Map map = (Map)getNodeService().getProperty(nodeRef, PROP_WRITERS); + if (map != null) + { + result = map.keySet(); + } + + return result; + } + + /** + * @see org.alfresco.module.org_alfresco_module_rm.security.ExtendedSecurityBaseDynamicAuthority#getTransactionCacheName() + */ + @Override + protected String getTransactionCacheName() + { + return "rm.extendedwriterdynamicauthority"; + } } diff --git a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/security/FilePlanPermissionServiceImpl.java b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/security/FilePlanPermissionServiceImpl.java index 8e5d4734aa..ee8abcc77e 100644 --- a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/security/FilePlanPermissionServiceImpl.java +++ b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/security/FilePlanPermissionServiceImpl.java @@ -18,31 +18,36 @@ */ package org.alfresco.module.org_alfresco_module_rm.security; +import static org.alfresco.module.org_alfresco_module_rm.security.ExtendedReaderDynamicAuthority.EXTENDED_READER; +import static org.alfresco.module.org_alfresco_module_rm.security.ExtendedWriterDynamicAuthority.EXTENDED_WRITER; +import static org.alfresco.repo.policy.Behaviour.NotificationFrequency.TRANSACTION_COMMIT; +import static org.alfresco.repo.policy.annotation.BehaviourKind.CLASS; +import static org.alfresco.repo.security.authentication.AuthenticationUtil.getSystemUserName; +import static org.alfresco.service.cmr.security.OwnableService.NO_OWNER; +import static org.alfresco.util.ParameterCheck.mandatory; +import static org.apache.commons.lang.BooleanUtils.isTrue; + import java.util.HashSet; -import java.util.List; import java.util.Set; import org.alfresco.error.AlfrescoRuntimeException; -import org.alfresco.model.ContentModel; import org.alfresco.module.org_alfresco_module_rm.capability.RMPermissionModel; -import org.alfresco.module.org_alfresco_module_rm.fileplan.FilePlanComponentKind; +import org.alfresco.module.org_alfresco_module_rm.role.FilePlanRoleService; import org.alfresco.module.org_alfresco_module_rm.util.ServiceBaseImpl; import org.alfresco.repo.node.NodeServicePolicies; -import org.alfresco.repo.policy.Behaviour.NotificationFrequency; import org.alfresco.repo.policy.JavaBehaviour; import org.alfresco.repo.policy.PolicyComponent; import org.alfresco.repo.policy.annotation.Behaviour; import org.alfresco.repo.policy.annotation.BehaviourBean; -import org.alfresco.repo.policy.annotation.BehaviourKind; import org.alfresco.repo.security.authentication.AuthenticationUtil; import org.alfresco.service.cmr.repository.ChildAssociationRef; import org.alfresco.service.cmr.repository.NodeRef; 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.OwnableService; import org.alfresco.service.cmr.security.PermissionService; import org.alfresco.service.namespace.QName; -import org.alfresco.service.namespace.RegexQNamePattern; import org.alfresco.util.ParameterCheck; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; @@ -59,30 +64,43 @@ public class FilePlanPermissionServiceImpl extends ServiceBaseImpl RMPermissionModel { /** Permission service */ - protected PermissionService permissionService; + private PermissionService permissionService; /** Ownable service */ - protected OwnableService ownableService; + private OwnableService ownableService; /** Policy component */ - protected PolicyComponent policyComponent; + private PolicyComponent policyComponent; + + /** Authority service */ + private AuthorityService authorityService; /** Logger */ - protected static final Log LOGGER = LogFactory.getLog(FilePlanPermissionServiceImpl.class); + private static final Log LOGGER = LogFactory.getLog(FilePlanPermissionServiceImpl.class); /** * Initialisation method */ public void init() { - policyComponent.bindClassBehaviour( + getPolicyComponent().bindClassBehaviour( NodeServicePolicies.OnAddAspectPolicy.QNAME, ASPECT_RECORD, - new JavaBehaviour(this, "onAddRecord", NotificationFrequency.TRANSACTION_COMMIT)); - policyComponent.bindClassBehaviour( + new JavaBehaviour(this, "onAddRecord", TRANSACTION_COMMIT)); + getPolicyComponent().bindClassBehaviour( NodeServicePolicies.OnMoveNodePolicy.QNAME, ASPECT_RECORD, - new JavaBehaviour(this, "onMoveRecord", NotificationFrequency.TRANSACTION_COMMIT)); + new JavaBehaviour(this, "onMoveRecord", TRANSACTION_COMMIT)); + } + + /** + * Gets the permission service + * + * @return The permission service + */ + protected PermissionService getPermissionService() + { + return this.permissionService; } /** @@ -93,6 +111,16 @@ public class FilePlanPermissionServiceImpl extends ServiceBaseImpl this.permissionService = permissionService; } + /** + * Gets the policy component + * + * @return The policy component + */ + protected PolicyComponent getPolicyComponent() + { + return this.policyComponent; + } + /** * @param policyComponent policy component */ @@ -101,6 +129,16 @@ public class FilePlanPermissionServiceImpl extends ServiceBaseImpl this.policyComponent = policyComponent; } + /** + * Gets the ownable service + * + * @return The ownable service + */ + protected OwnableService getOwnableService() + { + return this.ownableService; + } + /** * @param ownableService ownable service */ @@ -109,13 +147,33 @@ public class FilePlanPermissionServiceImpl extends ServiceBaseImpl this.ownableService = ownableService; } + /** + * Gets the authority service + * + * @return The authority service + */ + public AuthorityService getAuthorityService() + { + return this.authorityService; + } + + /** + * Sets the authority service + * + * @param authorityService The authority service + */ + public void setAuthorityService(AuthorityService authorityService) + { + this.authorityService = authorityService; + } + /** * @see org.alfresco.module.org_alfresco_module_rm.security.FilePlanPermissionService#setupRecordCategoryPermissions(org.alfresco.service.cmr.repository.NodeRef) */ @Override public void setupRecordCategoryPermissions(final NodeRef recordCategory) { - ParameterCheck.mandatory("recordCategory", recordCategory); + mandatory("recordCategory", recordCategory); // assert that we have a record category in our hands if (!instanceOf(recordCategory, TYPE_RECORD_CATEGORY)) @@ -136,12 +194,13 @@ public class FilePlanPermissionServiceImpl extends ServiceBaseImpl @Behaviour ( type = "rma:unfiledRecordFolder", - kind = BehaviourKind.CLASS, + kind = CLASS, policy = "alf:onCreateNode", - notificationFrequency = NotificationFrequency.TRANSACTION_COMMIT + notificationFrequency = TRANSACTION_COMMIT ) public void onCreateUnfiledRecordFolder(ChildAssociationRef childAssocRef) { + mandatory("childAssocRef", childAssocRef); setupPermissions(childAssocRef.getParentRef(), childAssocRef.getChildRef()); } @@ -153,12 +212,13 @@ public class FilePlanPermissionServiceImpl extends ServiceBaseImpl @Behaviour ( type = "rma:recordFolder", - kind = BehaviourKind.CLASS, + kind = CLASS, policy = "alf:onCreateNode", - notificationFrequency = NotificationFrequency.TRANSACTION_COMMIT + notificationFrequency = TRANSACTION_COMMIT ) public void onCreateRecordFolder(ChildAssociationRef childAssocRef) { + mandatory("childAssocRef", childAssocRef); setupPermissions(childAssocRef.getParentRef(), childAssocRef.getChildRef()); } @@ -170,12 +230,13 @@ public class FilePlanPermissionServiceImpl extends ServiceBaseImpl @Behaviour ( type = "rma:hold", - kind = BehaviourKind.CLASS, + kind = CLASS, policy = "alf:onCreateNode", - notificationFrequency = NotificationFrequency.TRANSACTION_COMMIT + notificationFrequency = TRANSACTION_COMMIT ) public void onCreateHold(final ChildAssociationRef childAssocRef) { + mandatory("childAssocRef", childAssocRef); setupPermissions(childAssocRef.getParentRef(), childAssocRef.getChildRef()); } @@ -187,13 +248,14 @@ public class FilePlanPermissionServiceImpl extends ServiceBaseImpl @Behaviour ( type = "rma:transfer", - kind = BehaviourKind.CLASS, + kind = CLASS, policy = "alf:onCreateNode", - notificationFrequency = NotificationFrequency.TRANSACTION_COMMIT + notificationFrequency = TRANSACTION_COMMIT ) public void onCreateTransfer(final ChildAssociationRef childAssocRef) { - setupPermissions(childAssocRef.getParentRef(), childAssocRef.getChildRef(), false); + mandatory("childAssocRef", childAssocRef); + setupPermissions(childAssocRef.getParentRef(), childAssocRef.getChildRef()); } /** @@ -204,90 +266,53 @@ public class FilePlanPermissionServiceImpl extends ServiceBaseImpl */ public void setupPermissions(final NodeRef parent, final NodeRef nodeRef) { - ParameterCheck.mandatory("parent", parent); - ParameterCheck.mandatory("nodeRef", nodeRef); - setupPermissions(parent, nodeRef, true); - } - - /** - * Helper method to setup permissions. - * - * @param parent parent node reference - * @param nodeRef child node reference - * @param includeInPlace true if in-place permissions should be included, false otherwise - */ - private void setupPermissions(final NodeRef parent, final NodeRef nodeRef, final boolean includeInPlace) - { - if (nodeService.exists(nodeRef)) - { - // initialise permissions - initPermissions(nodeRef, includeInPlace); + mandatory("parent", parent); + mandatory("nodeRef", nodeRef); - if (nodeService.exists(parent)) + if (nodeService.exists(nodeRef) && nodeService.exists(parent)) + { + authenticationUtil.runAsSystem(new AuthenticationUtil.RunAsWork() { - authenticationUtil.runAsSystem(new AuthenticationUtil.RunAsWork() + public Object doWork() { - public Object doWork() + // set inheritance + boolean isParentNodeFilePlan = isRecordCategory(nodeRef) && isFilePlan(parent); + boolean inheritanceAllowed = isInheritanceAllowed(nodeRef, isParentNodeFilePlan); + getPermissionService().setInheritParentPermissions(nodeRef, inheritanceAllowed); + + // clear all existing permissions + getPermissionService().clearPermission(nodeRef, null); + + if (!inheritanceAllowed) { - // setup inherited permissions - Set perms = permissionService.getAllSetPermissions(parent); - for (AccessPermission perm : perms) - { - // only copy filling permissions if the parent is the file plan - if (!inheritFillingOnly(parent, nodeRef) || - RMPermissionModel.FILING.equals(perm.getPermission())) - { - // don't copy the extended reader or writer permissions as they have already been set - if (!ExtendedReaderDynamicAuthority.EXTENDED_READER.equals(perm.getAuthority()) && - !ExtendedWriterDynamicAuthority.EXTENDED_WRITER.equals(perm.getAuthority())) - { - // get the access status details - AccessStatus accessStatus = perm.getAccessStatus(); - boolean allow = false; - if (AccessStatus.ALLOWED.equals(accessStatus)) - { - allow = true; - } - - // set the permission on the target node - permissionService.setPermission( - nodeRef, - perm.getAuthority(), - perm.getPermission(), - allow); - } - } - } - - return null; + getPermissionService().setPermission(nodeRef, EXTENDED_READER, READ_RECORDS, true); + getPermissionService().setPermission(nodeRef, EXTENDED_WRITER, FILING, true); + String adminRole = getAdminRole(nodeRef); + getPermissionService().setPermission(nodeRef, adminRole, RMPermissionModel.FILING, true); } - }); - } + + // remove owner + getOwnableService().setOwner(nodeRef, NO_OWNER); + + return null; + } + }); } } - /** - * Helper method to determine whether all or just filling permissions should be inherited. - * - * @param parent parent node - * @param child child node - * @return boolean true if inherit filling only, false otherwise - */ - private boolean inheritFillingOnly(NodeRef parent, NodeRef child) + private String getAdminRole(NodeRef nodeRef) { - boolean result = false; - - // if root category or - // if in root of unfiled container or - // if in root of hold container - if ((isFilePlan(parent) && isRecordCategory(child)) || - FilePlanComponentKind.UNFILED_RECORD_CONTAINER.equals(getFilePlanComponentKind(parent)) || - FilePlanComponentKind.HOLD_CONTAINER.equals(getFilePlanComponentKind(parent))) + NodeRef filePlan = getFilePlan(nodeRef); + if (filePlan == null) { - result = true; + throw new AlfrescoRuntimeException("The file plan could not be found for the give node: '" + nodeRef + "'."); } + return authorityService.getName(AuthorityType.GROUP, FilePlanRoleService.ROLE_ADMIN + filePlan.getId()); + } - return result; + private boolean isInheritanceAllowed(NodeRef nodeRef, Boolean isParentNodeFilePlan) + { + return !(isFilePlan(nodeRef) || isTransfer(nodeRef) || isHold(nodeRef) || isUnfiledRecordsContainer(nodeRef) || (isRecordCategory(nodeRef) && isTrue(isParentNodeFilePlan))); } /** @@ -300,6 +325,9 @@ public class FilePlanPermissionServiceImpl extends ServiceBaseImpl */ public void onAddRecord(final NodeRef record, final QName aspectTypeQName) { + mandatory("childAssocRef", record); + mandatory("childAssocRef", aspectTypeQName); + authenticationUtil.runAsSystem(new AuthenticationUtil.RunAsWork() { public Object doWork() @@ -323,27 +351,32 @@ public class FilePlanPermissionServiceImpl extends ServiceBaseImpl */ public void onMoveRecord(final ChildAssociationRef sourceAssocRef, final ChildAssociationRef destinationAssocRef) { - AuthenticationUtil.runAs(new AuthenticationUtil.RunAsWork() + mandatory("sourceAssocRef", sourceAssocRef); + mandatory("destinationAssocRef", destinationAssocRef); + + authenticationUtil.runAs(new AuthenticationUtil.RunAsWork() { public Void doWork() { NodeRef record = sourceAssocRef.getChildRef(); if (nodeService.exists(record) && nodeService.hasAspect(record, ASPECT_RECORD)) { - Set keepPerms = new HashSet(5); + boolean inheritParentPermissions = permissionService.getInheritParentPermissions(record); - // record any permissions specifically set on the record (ie any filling or record_file permisions not on the parent) - Set origionalParentPerms = permissionService.getAllSetPermissions(sourceAssocRef.getParentRef()); + Set keepPerms = new HashSet(5); Set origionalRecordPerms= permissionService.getAllSetPermissions(record); - for (AccessPermission perm : origionalRecordPerms) + + for (AccessPermission recordPermission : origionalRecordPerms) { - if (!ExtendedReaderDynamicAuthority.EXTENDED_READER.equals(perm.getAuthority()) && - !ExtendedWriterDynamicAuthority.EXTENDED_WRITER.equals(perm.getAuthority()) && - (perm.getPermission().equals(RMPermissionModel.FILING) || perm.getPermission().equals(RMPermissionModel.FILE_RECORDS)) && - !origionalParentPerms.contains(perm)) + String permission = recordPermission.getPermission(); + String authority = recordPermission.getAuthority(); + if ((RMPermissionModel.FILING.equals(permission) || RMPermissionModel.READ_RECORDS.equals(permission)) && + recordPermission.isSetDirectly() && + !ExtendedReaderDynamicAuthority.EXTENDED_READER.equals(authority) && + !ExtendedWriterDynamicAuthority.EXTENDED_WRITER.equals(authority)) { // then we can assume this is a permission we want to preserve - keepPerms.add(perm); + keepPerms.add(recordPermission); } } @@ -358,47 +391,13 @@ public class FilePlanPermissionServiceImpl extends ServiceBaseImpl { setPermission(record, keeper.getAuthority(), keeper.getPermission()); } + + permissionService.setInheritParentPermissions(record, inheritParentPermissions); } return null; } - }, AuthenticationUtil.getSystemUserName()); - } - - /** - * Init the permissions for the given node. - * - * @param nodeRef node reference - * @param includeInPlace true if in-place - */ - private void initPermissions(final NodeRef nodeRef, final boolean includeInPlace) - { - if (nodeService.exists(nodeRef)) - { - authenticationUtil.runAsSystem(new AuthenticationUtil.RunAsWork() - { - public Object doWork() - { - // break inheritance - permissionService.setInheritParentPermissions(nodeRef, false); - - // clear all existing permissions - permissionService.clearPermission(nodeRef, null); - - if (includeInPlace) - { - // set extended reader permissions - permissionService.setPermission(nodeRef, ExtendedReaderDynamicAuthority.EXTENDED_READER, RMPermissionModel.READ_RECORDS, true); - permissionService.setPermission(nodeRef, ExtendedWriterDynamicAuthority.EXTENDED_WRITER, RMPermissionModel.FILING, true); - } - - // remove owner - ownableService.setOwner(nodeRef, OwnableService.NO_OWNER); - - return null; - } - }); - } + }, getSystemUserName()); } /** @@ -414,21 +413,10 @@ public class FilePlanPermissionServiceImpl extends ServiceBaseImpl { public Void doWork() { - if (isFilePlan(nodeRef)) + if (canPerformPermissionAction(nodeRef)) { - // set the permission down the file plan hierarchy - setPermissionDown(nodeRef, authority, permission); - } - else if (isFilePlanContainer(nodeRef) || - isRecordFolder(nodeRef) || - isRecord(nodeRef) || - isHold(nodeRef)) - { - // set read permission to the parents of the node - setReadPermissionUp(nodeRef, authority); - - // set the permission on the node and it's children - setPermissionDown(nodeRef, authority, permission); + // Set the permission on the node + getPermissionService().setPermission(nodeRef, authority, permission, true); } else { @@ -443,146 +431,29 @@ public class FilePlanPermissionServiceImpl extends ServiceBaseImpl }); } - /** - * Helper method to set the read permission up the hierarchy - * - * @param nodeRef node reference - * @param authority authority - */ - private void setReadPermissionUp(NodeRef nodeRef, String authority) - { - NodeRef parent = nodeService.getPrimaryParent(nodeRef).getParentRef(); - if (parent != null && isFilePlanComponent(parent)) - { - setReadPermissionUpImpl(parent, authority); - } - } - - /** - * Helper method used to set the read permission up the hierarchy - * - * @param nodeRef node reference - * @param authority authority - */ - private void setReadPermissionUpImpl(NodeRef nodeRef, String authority) - { - setPermissionImpl(nodeRef, authority, RMPermissionModel.READ_RECORDS); - - NodeRef parent = nodeService.getPrimaryParent(nodeRef).getParentRef(); - if (parent != null && isFilePlanComponent(parent)) - { - setReadPermissionUpImpl(parent, authority); - } - } - - /** - * Helper method to set the permission down the hierarchy - * - * @param nodeRef node reference - * @param authority authority - * @param permission permission - */ - private void setPermissionDown(NodeRef nodeRef, String authority, String permission) - { - // skip out node's that inherit (for example hold and transfer) - if (!permissionService.getInheritParentPermissions(nodeRef)) - { - // set permissions - setPermissionImpl(nodeRef, authority, permission); - - if (isFilePlanContainer(nodeRef) || - isRecordFolder(nodeRef)) - { - List assocs = nodeService.getChildAssocs(nodeRef, ContentModel.ASSOC_CONTAINS, RegexQNamePattern.MATCH_ALL); - for (ChildAssociationRef assoc : assocs) - { - NodeRef child = assoc.getChildRef(); - if (isFilePlanContainer(child) || - isRecordFolder(child) || - isRecord(child) || - isHold(child) || - instanceOf(child, TYPE_TRANSFER)) - { - setPermissionDown(child, authority, permission); - } - } - } - } - } - - /** - * Set the permission, taking into account that filing is a superset of read - * - * @param nodeRef node reference - * @param authority authority - * @param permission permission - */ - private void setPermissionImpl(NodeRef nodeRef, String authority, String permission) - { - boolean hasRead = false; - boolean hasFilling = false; - - Set perms = permissionService.getAllSetPermissions(nodeRef); - for (AccessPermission perm : perms) - { - if (perm.getAuthority().equals(authority)) - { - if (perm.getPermission().equals(FILING)) - { - hasFilling = true; - } - else if (perm.getPermission().equals(READ_RECORDS)) - { - hasRead = true; - } - } - } - - if (FILING.equals(permission) && hasRead) - { - // remove read permission - permissionService.deletePermission(nodeRef, authority, RMPermissionModel.READ_RECORDS); - hasRead = false; - } - - if (!hasRead && !hasFilling) - { - // add permission - permissionService.setPermission(nodeRef, authority, permission, true); - } - } - /** * @see org.alfresco.module.org_alfresco_module_rm.security.RecordsManagementSecurityService#deletePermission(org.alfresco.service.cmr.repository.NodeRef, java.lang.String, java.lang.String) */ public void deletePermission(final NodeRef nodeRef, final String authority, final String permission) { + ParameterCheck.mandatory("nodeRef", nodeRef); + ParameterCheck.mandatory("authority", authority); + ParameterCheck.mandatory("permission", permission); + authenticationUtil.runAsSystem(new AuthenticationUtil.RunAsWork() { public Void doWork() { - // can't delete permissions if inherited (eg hold and transfer containers) - if (!permissionService.getInheritParentPermissions(nodeRef)) + if (canPerformPermissionAction(nodeRef)) { // Delete permission on this node - permissionService.deletePermission(nodeRef, authority, permission); - - if (isFilePlanContainer(nodeRef) || - isRecordFolder(nodeRef)) + getPermissionService().deletePermission(nodeRef, authority, permission); + } + else + { + if (LOGGER.isWarnEnabled()) { - List assocs = nodeService.getChildAssocs(nodeRef, ContentModel.ASSOC_CONTAINS, RegexQNamePattern.MATCH_ALL); - for (ChildAssociationRef assoc : assocs) - { - NodeRef child = assoc.getChildRef(); - if (isFilePlanContainer(child) || - isRecordFolder(child) || - isRecord(child)|| - isHold(child) || - instanceOf(child, TYPE_TRANSFER)) - { - deletePermission(child, authority, permission); - } - } + LOGGER.warn("Deleting permissions for this node is not supported. (nodeRef=" + nodeRef + ", authority=" + authority + ", permission=" + permission + ")"); } } @@ -590,4 +461,9 @@ public class FilePlanPermissionServiceImpl extends ServiceBaseImpl } }); } + + private boolean canPerformPermissionAction(NodeRef nodeRef) + { + return isFilePlanContainer(nodeRef) || isRecordFolder(nodeRef) || isRecord(nodeRef); + } } diff --git a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/util/ServiceBaseImpl.java b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/util/ServiceBaseImpl.java index 99d7bbea6d..f2d9b38525 100644 --- a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/util/ServiceBaseImpl.java +++ b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/util/ServiceBaseImpl.java @@ -53,10 +53,10 @@ public class ServiceBaseImpl implements RecordsManagementModel, ApplicationConte /** Application context */ protected ApplicationContext applicationContext; - + /** internal node service */ private NodeService internalNodeService; - + /** authentication helper */ protected AuthenticationUtil authenticationUtil; @@ -84,7 +84,7 @@ public class ServiceBaseImpl implements RecordsManagementModel, ApplicationConte { this.dictionaryService = dictionaryService; } - + /** * @param authenticationUtil authentication util helper */ @@ -92,7 +92,7 @@ public class ServiceBaseImpl implements RecordsManagementModel, ApplicationConte { this.authenticationUtil = authenticationUtil; } - + /** * Helper to get internal node service. *

@@ -104,10 +104,10 @@ public class ServiceBaseImpl implements RecordsManagementModel, ApplicationConte { internalNodeService = (NodeService)applicationContext.getBean("dbNodeService"); } - + return internalNodeService; } - + /** * Gets the file plan component kind from the given node reference * @@ -127,7 +127,7 @@ public class ServiceBaseImpl implements RecordsManagementModel, ApplicationConte if (isFilePlanComponent(nodeRef)) { result = FilePlanComponentKind.FILE_PLAN_COMPONENT; - + if (isFilePlan(nodeRef)) { result = FilePlanComponentKind.FILE_PLAN; @@ -173,7 +173,7 @@ public class ServiceBaseImpl implements RecordsManagementModel, ApplicationConte result = FilePlanComponentKind.UNFILED_RECORD_FOLDER; } } - + if (result != null) { map.put(nodeRef, result); @@ -319,7 +319,7 @@ public class ServiceBaseImpl implements RecordsManagementModel, ApplicationConte ParameterCheck.mandatory("nodeRef", nodeRef); boolean isHold = false; - if (getInternalNodeService().exists(nodeRef) && + if (getInternalNodeService().exists(nodeRef) && instanceOf(nodeRef, TYPE_HOLD)) { isHold = true; @@ -338,10 +338,23 @@ public class ServiceBaseImpl implements RecordsManagementModel, ApplicationConte return instanceOf(nodeRef, TYPE_TRANSFER); } - + + /** + * Indicates whether the given node reference is an unfiled records container or not. + * + * @param nodeRef node reference + * @return boolean true if rma:unfiledRecordContainer or sub-type, false otherwise + */ + public boolean isUnfiledRecordsContainer(NodeRef nodeRef) + { + ParameterCheck.mandatory("nodeRef", nodeRef); + + return instanceOf(nodeRef, TYPE_UNFILED_RECORD_CONTAINER); + } + /** * Indicates whether a record is complete or not. - * + * * @see org.alfresco.module.org_alfresco_module_rm.record.RecordService#isDeclared(org.alfresco.service.cmr.repository.NodeRef) */ public boolean isDeclared(NodeRef record) @@ -361,22 +374,33 @@ public class ServiceBaseImpl implements RecordsManagementModel, ApplicationConte { NodeRef result = null; if (nodeRef != null) - { - result = (NodeRef)getInternalNodeService().getProperty(nodeRef, PROP_ROOT_NODEREF); - if (result == null || !instanceOf(result, TYPE_FILE_PLAN)) + { + Map transactionCache = TransactionalResourceHelper.getMap("rm.servicebase.getFilePlan"); + if (transactionCache.containsKey(nodeRef)) { - if (instanceOf(nodeRef, TYPE_FILE_PLAN)) + result = transactionCache.get(nodeRef); + } + else + { + result = (NodeRef)getInternalNodeService().getProperty(nodeRef, PROP_ROOT_NODEREF); + if (result == null || !instanceOf(result, TYPE_FILE_PLAN)) { - result = nodeRef; - } - else - { - ChildAssociationRef parentAssocRef = getInternalNodeService().getPrimaryParent(nodeRef); - if (parentAssocRef != null) + if (instanceOf(nodeRef, TYPE_FILE_PLAN)) { - result = getFilePlan(parentAssocRef.getParentRef()); + result = nodeRef; + } + else + { + ChildAssociationRef parentAssocRef = getInternalNodeService().getPrimaryParent(nodeRef); + if (parentAssocRef != null) + { + result = getFilePlan(parentAssocRef.getParentRef()); + } } } + + // cache result in transaction + transactionCache.put(nodeRef, result); } } @@ -392,11 +416,11 @@ public class ServiceBaseImpl implements RecordsManagementModel, ApplicationConte protected boolean instanceOf(NodeRef nodeRef, QName ofClassName) { ParameterCheck.mandatory("nodeRef", nodeRef); - ParameterCheck.mandatory("ofClassName", ofClassName); - QName className = getInternalNodeService().getType(nodeRef); + ParameterCheck.mandatory("ofClassName", ofClassName); + QName className = getInternalNodeService().getType(nodeRef); return instanceOf(className, ofClassName); } - + private static Map instanceOfCache = new HashMap(); /** @@ -410,25 +434,25 @@ public class ServiceBaseImpl implements RecordsManagementModel, ApplicationConte { ParameterCheck.mandatory("className", className); ParameterCheck.mandatory("ofClassName", ofClassName); - + boolean result = false; - + String key = className.toString() + "|" + ofClassName.toString(); if (instanceOfCache.containsKey(key)) { result = instanceOfCache.get(key); } else - { + { if (ofClassName.equals(className) || dictionaryService.isSubClass(className, ofClassName)) { result = true; } - + instanceOfCache.put(key, result); } - + return result; } diff --git a/rm-server/source/java/org/alfresco/repo/security/permissions/impl/RMPermissionServiceImpl.java b/rm-server/source/java/org/alfresco/repo/security/permissions/impl/RMPermissionServiceImpl.java index cb887449ae..e016383182 100644 --- a/rm-server/source/java/org/alfresco/repo/security/permissions/impl/RMPermissionServiceImpl.java +++ b/rm-server/source/java/org/alfresco/repo/security/permissions/impl/RMPermissionServiceImpl.java @@ -18,18 +18,26 @@ */ package org.alfresco.repo.security.permissions.impl; +import static org.apache.commons.lang.StringUtils.isNotBlank; + import java.io.Serializable; import java.util.Collections; import java.util.HashSet; import java.util.Set; 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; import org.alfresco.service.cmr.repository.NodeRef; +import org.alfresco.service.cmr.security.AccessPermission; import org.alfresco.service.cmr.security.AccessStatus; +import org.alfresco.service.cmr.security.AuthorityType; import org.alfresco.service.cmr.security.PermissionService; import org.alfresco.util.PropertyCheck; import org.springframework.context.ApplicationEvent; @@ -48,6 +56,29 @@ public class RMPermissionServiceImpl extends PermissionServiceImpl /** Writers simple cache */ protected SimpleCache> writersCache; + /** File plan service */ + private FilePlanService filePlanService; + + /** + * Gets the file plan service + * + * @return the filePlanService + */ + public FilePlanService getFilePlanService() + { + return this.filePlanService; + } + + /** + * Sets the file plan service + * + * @param filePlanService the filePlanService to set + */ + public void setFilePlanService(FilePlanService filePlanService) + { + this.filePlanService = filePlanService; + } + /** * @see org.alfresco.repo.security.permissions.impl.PermissionServiceImpl#setAnyDenyDenies(boolean) */ @@ -87,15 +118,15 @@ public class RMPermissionServiceImpl extends PermissionServiceImpl public AccessStatus hasPermission(NodeRef nodeRef, String perm) { AccessStatus acs = super.hasPermission(nodeRef, perm); - if (AccessStatus.DENIED.equals(acs) && - PermissionService.READ.equals(perm) && - nodeService.hasAspect(nodeRef, RecordsManagementModel.ASPECT_FILE_PLAN_COMPONENT)) + if (AccessStatus.DENIED.equals(acs) == true && + PermissionService.READ.equals(perm) == true && + nodeService.hasAspect(nodeRef, RecordsManagementModel.ASPECT_FILE_PLAN_COMPONENT) == true) { return super.hasPermission(nodeRef, RMPermissionModel.READ_RECORDS); } - else if (AccessStatus.DENIED.equals(acs) && - PermissionService.WRITE.equals(perm) && - nodeService.hasAspect(nodeRef, RecordsManagementModel.ASPECT_FILE_PLAN_COMPONENT)) + else if (AccessStatus.DENIED.equals(acs) == true && + PermissionService.WRITE.equals(perm) == true && + nodeService.hasAspect(nodeRef, RecordsManagementModel.ASPECT_FILE_PLAN_COMPONENT) == true) { return super.hasPermission(nodeRef, RMPermissionModel.FILE_RECORDS); } @@ -263,4 +294,50 @@ public class RMPermissionServiceImpl extends PermissionServiceImpl writersCache.put((Serializable)acl.getProperties(), aclWriters); return aclWriters; } + + /** + * @see org.alfresco.repo.security.permissions.impl.PermissionServiceImpl#setInheritParentPermissions(org.alfresco.service.cmr.repository.NodeRef, boolean) + */ + @Override + public void setInheritParentPermissions(final NodeRef nodeRef, boolean inheritParentPermissions) + { + final String adminRole = getAdminRole(nodeRef); + if (nodeService.hasAspect(nodeRef, RecordsManagementModel.ASPECT_FILE_PLAN_COMPONENT) && isNotBlank(adminRole)) + { + if (inheritParentPermissions) + { + Set accessPermissions = getAllSetPermissions(nodeRef); + for (AccessPermission accessPermission : accessPermissions) + { + String authority = accessPermission.getAuthority(); + String permission = accessPermission.getPermission(); + if (accessPermission.isSetDirectly() && + (RMPermissionModel.FILING.equals(permission) || RMPermissionModel.READ_RECORDS.equals(permission)) && + (ExtendedReaderDynamicAuthority.EXTENDED_READER.equals(authority) || ExtendedWriterDynamicAuthority.EXTENDED_WRITER.equals(authority)) || adminRole.equals(authority)) + { + // FIXME!!! + //deletePermission(nodeRef, authority, permission); + } + } + } + else + { + setPermission(nodeRef, ExtendedReaderDynamicAuthority.EXTENDED_READER, RMPermissionModel.READ_RECORDS, true); + setPermission(nodeRef, ExtendedWriterDynamicAuthority.EXTENDED_WRITER, RMPermissionModel.FILING, true); + setPermission(nodeRef, adminRole, RMPermissionModel.FILING, true); + } + } + super.setInheritParentPermissions(nodeRef, inheritParentPermissions); + } + + private String getAdminRole(NodeRef nodeRef) + { + String adminRole = null; + NodeRef filePlan = getFilePlanService().getFilePlan(nodeRef); + if (filePlan != null) + { + adminRole = authorityService.getName(AuthorityType.GROUP, FilePlanRoleService.ROLE_ADMIN + filePlan.getId()); + } + return adminRole; + } } diff --git a/rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/integration/issue/IssueTestSuite.java b/rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/integration/issue/IssueTestSuite.java index 68c94d1e80..ba0d7003ee 100755 --- a/rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/integration/issue/IssueTestSuite.java +++ b/rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/integration/issue/IssueTestSuite.java @@ -40,7 +40,8 @@ import org.junit.runners.Suite.SuiteClasses; RM1464Test.class, RM452Test.class, RM804Test.class, - RM994Test.class + RM994Test.class, + RM1039Test.class }) public class IssueTestSuite { diff --git a/rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/integration/issue/RM1008Test.java b/rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/integration/issue/RM1008Test.java index 4c611c7477..0066a3ea58 100755 --- a/rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/integration/issue/RM1008Test.java +++ b/rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/integration/issue/RM1008Test.java @@ -181,8 +181,9 @@ public class RM1008Test extends BaseRMTestCase Capability viewRecords = capabilityService.getCapability("ViewRecords"); assertNotNull(viewRecords); - assertEquals(AccessStatus.ALLOWED, viewRecords.hasPermission(hold)); - assertEquals(AccessStatus.ALLOWED, permissionService.hasPermission(hold, RMPermissionModel.FILING)); + assertEquals(AccessStatus.DENIED, viewRecords.hasPermission(hold)); + assertEquals(AccessStatus.DENIED, permissionService.hasPermission(hold, RMPermissionModel.READ_RECORDS)); + assertEquals(AccessStatus.DENIED, permissionService.hasPermission(hold, RMPermissionModel.FILING)); return null; } @@ -292,7 +293,7 @@ public class RM1008Test extends BaseRMTestCase Capability viewRecords = capabilityService.getCapability("ViewRecords"); assertNotNull(viewRecords); - assertEquals(AccessStatus.ALLOWED, viewRecords.hasPermission(transfer)); + assertEquals(AccessStatus.DENIED, viewRecords.hasPermission(transfer)); assertEquals(AccessStatus.DENIED, permissionService.hasPermission(transfer, RMPermissionModel.FILING)); return null; @@ -318,8 +319,9 @@ public class RM1008Test extends BaseRMTestCase Capability viewRecords = capabilityService.getCapability("ViewRecords"); assertNotNull(viewRecords); - assertEquals(AccessStatus.ALLOWED, viewRecords.hasPermission(transfer)); - assertEquals(AccessStatus.ALLOWED, permissionService.hasPermission(transfer, RMPermissionModel.FILING)); + assertEquals(AccessStatus.DENIED, viewRecords.hasPermission(transfer)); + assertEquals(AccessStatus.DENIED, permissionService.hasPermission(transfer, RMPermissionModel.READ_RECORDS)); + assertEquals(AccessStatus.DENIED, permissionService.hasPermission(transfer, RMPermissionModel.FILING)); return null; } @@ -344,7 +346,7 @@ public class RM1008Test extends BaseRMTestCase Capability viewRecords = capabilityService.getCapability("ViewRecords"); assertNotNull(viewRecords); - assertEquals(AccessStatus.ALLOWED, viewRecords.hasPermission(transfer)); + assertEquals(AccessStatus.DENIED, viewRecords.hasPermission(transfer)); assertEquals(AccessStatus.DENIED, permissionService.hasPermission(transfer, RMPermissionModel.FILING)); return null; diff --git a/rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/integration/issue/RM1039Test.java b/rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/integration/issue/RM1039Test.java new file mode 100644 index 0000000000..512d16709d --- /dev/null +++ b/rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/integration/issue/RM1039Test.java @@ -0,0 +1,186 @@ +/* + * Copyright (C) 2005-2013 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 . + */ +package org.alfresco.module.org_alfresco_module_rm.test.integration.issue; + +import java.io.Serializable; +import java.util.HashMap; +import java.util.Map; + +import net.sf.acegisecurity.vote.AccessDecisionVoter; + +import org.alfresco.model.ContentModel; +import org.alfresco.module.org_alfresco_module_rm.action.impl.CompleteEventAction; +import org.alfresco.module.org_alfresco_module_rm.action.impl.CutOffAction; +import org.alfresco.module.org_alfresco_module_rm.capability.Capability; +import org.alfresco.module.org_alfresco_module_rm.disposition.DispositionAction; +import org.alfresco.module.org_alfresco_module_rm.test.util.BaseRMTestCase; +import org.alfresco.module.org_alfresco_module_rm.test.util.CommonRMTestUtils; +import org.alfresco.service.cmr.repository.NodeRef; + + +/** + * Unit test for RM-1039 ... can't move a folder into a category with a disposition schedule + * + * @author Roy Wetherall + * @since 2.1 + */ +public class RM1039Test extends BaseRMTestCase +{ + @Override + protected boolean isRecordTest() + { + return true; + } + + // try and move a folder from no disposition schedule to a disposition schedule + public void testMoveRecordFolderFromNoDisToDis() throws Exception + { + final NodeRef recordFolder = doTestInTransaction(new Test() + { + @Override + public NodeRef run() + { + // create a record category (no disposition schedule) + NodeRef recordCategory = filePlanService.createRecordCategory(filePlan, "Caitlin Reed"); + + // create a record folder + return recordFolderService.createRecordFolder(recordCategory, "Grace Wetherall"); + } + + @Override + public void test(NodeRef result) throws Exception + { + assertNotNull(result); + assertNull(dispositionService.getDispositionSchedule(result)); + assertFalse(nodeService.hasAspect(result, ASPECT_DISPOSITION_LIFECYCLE)); + } + }); + + final NodeRef record = doTestInTransaction(new Test() + { + @Override + public NodeRef run() + { + // create a record + return fileFolderService.create(recordFolder, "mytest.txt", ContentModel.TYPE_CONTENT).getNodeRef(); + } + + @Override + public void test(NodeRef result) throws Exception + { + assertNotNull(result); + assertNull(dispositionService.getDispositionSchedule(result)); + assertFalse(nodeService.hasAspect(result, ASPECT_DISPOSITION_LIFECYCLE)); + } + }); + + doTestInTransaction(new Test() + { + @Override + public NodeRef run() throws Exception + { + Capability capability = capabilityService.getCapability("CreateModifyDestroyFolders"); + assertEquals(AccessDecisionVoter.ACCESS_GRANTED, capability.evaluate(recordFolder)); + assertEquals(AccessDecisionVoter.ACCESS_GRANTED, capability.evaluate(recordFolder, rmContainer)); + + // take a look at the move capability + Capability moveCapability = capabilityService.getCapability("Move"); + assertEquals(AccessDecisionVoter.ACCESS_GRANTED, moveCapability.evaluate(recordFolder, rmContainer)); + + // move the node + return fileFolderService.move(recordFolder, rmContainer, null).getNodeRef(); + } + + @Override + public void test(NodeRef result) throws Exception + { + assertNotNull(result); + assertNotNull(dispositionService.getDispositionSchedule(result)); + assertTrue(nodeService.hasAspect(result, ASPECT_DISPOSITION_LIFECYCLE)); + + DispositionAction dispositionAction = dispositionService.getNextDispositionAction(result); + assertNotNull(dispositionAction); + + assertNull(dispositionAction.getAsOfDate()); + assertEquals("cutoff", dispositionAction.getName()); + assertEquals(1, dispositionAction.getEventCompletionDetails().size()); + + // take a look at the record and check things are as we would expect + assertFalse(nodeService.hasAspect(record, ASPECT_DISPOSITION_LIFECYCLE)); + } + }); + } + + // move from a disposition schedule to another .. both record folder level + + // move from a disposition schedule to another .. from record to folder level + + + // try and move a cutoff folder + public void testMoveCutoffRecordFolder() throws Exception + { + final NodeRef destination = doTestInTransaction(new Test() + { + @Override + public NodeRef run() + { + // create a record category (no disposition schedule) + return filePlanService.createRecordCategory(filePlan, "Caitlin Reed"); + } + }); + + final NodeRef testFolder = doTestInTransaction(new Test() + { + @Override + public NodeRef run() + { + // create folder + NodeRef testFolder = recordFolderService.createRecordFolder(rmContainer, "Peter Edward Francis"); + + // complete event + Map params = new HashMap(1); + params.put(CompleteEventAction.PARAM_EVENT_NAME, CommonRMTestUtils.DEFAULT_EVENT_NAME); + rmActionService.executeRecordsManagementAction(testFolder, CompleteEventAction.NAME, params); + + // cutoff folder + rmActionService.executeRecordsManagementAction(testFolder, CutOffAction.NAME); + + return testFolder; + } + + @Override + public void test(NodeRef result) throws Exception + { + // take a look at the move capability + Capability moveCapability = capabilityService.getCapability("Move"); + assertEquals(AccessDecisionVoter.ACCESS_DENIED, moveCapability.evaluate(result, destination)); + + } + }); + + doTestInTransaction(new FailureTest() + { + @Override + public void run() throws Exception + { + fileFolderService.move(testFolder, destination, null).getNodeRef(); + } + }); + } +} diff --git a/rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/integration/issue/RM1424Test.java b/rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/integration/issue/RM1424Test.java index 5d164ec3b7..78eacc5927 100644 --- a/rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/integration/issue/RM1424Test.java +++ b/rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/integration/issue/RM1424Test.java @@ -23,6 +23,7 @@ import java.util.List; import org.alfresco.module.org_alfresco_module_rm.capability.RMPermissionModel; 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.integration.hold.DeleteHoldTest; import org.alfresco.service.cmr.repository.NodeRef; @@ -65,7 +66,7 @@ public class RM1424Test extends DeleteHoldTest assertEquals(HOLD1_DESC, (String) nodeService.getProperty(hold1, PROP_DESCRIPTION)); // Add the user to the RM Manager role - filePlanRoleService.assignRoleToAuthority(filePlan, ROLE_NAME_RECORDS_MANAGER, userName); + filePlanRoleService.assignRoleToAuthority(filePlan, FilePlanRoleService.ROLE_RECORDS_MANAGER, userName); return null; } diff --git a/rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/integration/issue/RM1429Test.java b/rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/integration/issue/RM1429Test.java index 1f86f34344..96e835729d 100644 --- a/rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/integration/issue/RM1429Test.java +++ b/rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/integration/issue/RM1429Test.java @@ -20,6 +20,7 @@ package org.alfresco.module.org_alfresco_module_rm.test.integration.issue; import org.alfresco.error.AlfrescoRuntimeException; import org.alfresco.module.org_alfresco_module_rm.capability.RMPermissionModel; +import org.alfresco.module.org_alfresco_module_rm.role.FilePlanRoleService; import org.alfresco.module.org_alfresco_module_rm.test.integration.hold.DeleteHoldTest; import org.alfresco.service.cmr.repository.NodeRef; @@ -43,7 +44,7 @@ public class RM1429Test extends DeleteHoldTest public Void run() { // Add the user to the RM Manager role - filePlanRoleService.assignRoleToAuthority(filePlan, ROLE_NAME_RECORDS_MANAGER, userName); + filePlanRoleService.assignRoleToAuthority(filePlan, FilePlanRoleService.ROLE_RECORDS_MANAGER, userName); // Give the user filing permissions on the hold permissionService.setPermission(hold, userName, RMPermissionModel.FILING, true); diff --git a/rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/integration/issue/RM1463Test.java b/rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/integration/issue/RM1463Test.java index b3cb232051..074eb27e83 100644 --- a/rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/integration/issue/RM1463Test.java +++ b/rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/integration/issue/RM1463Test.java @@ -20,6 +20,7 @@ package org.alfresco.module.org_alfresco_module_rm.test.integration.issue; import org.alfresco.error.AlfrescoRuntimeException; import org.alfresco.module.org_alfresco_module_rm.capability.RMPermissionModel; +import org.alfresco.module.org_alfresco_module_rm.role.FilePlanRoleService; import org.alfresco.module.org_alfresco_module_rm.test.integration.hold.DeleteHoldTest; import org.alfresco.service.cmr.repository.NodeRef; @@ -43,7 +44,7 @@ public class RM1463Test extends DeleteHoldTest public Void run() { // Add the user to the RM Manager role - filePlanRoleService.assignRoleToAuthority(filePlan, ROLE_NAME_RECORDS_MANAGER, userName); + filePlanRoleService.assignRoleToAuthority(filePlan, FilePlanRoleService.ROLE_RECORDS_MANAGER, userName); // Give the user filing permissions on the hold permissionService.setPermission(hold, userName, RMPermissionModel.FILING, true); diff --git a/rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/integration/issue/RM1464Test.java b/rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/integration/issue/RM1464Test.java index 4220dbc896..5a009bb620 100644 --- a/rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/integration/issue/RM1464Test.java +++ b/rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/integration/issue/RM1464Test.java @@ -20,6 +20,7 @@ package org.alfresco.module.org_alfresco_module_rm.test.integration.issue; import org.alfresco.error.AlfrescoRuntimeException; import org.alfresco.module.org_alfresco_module_rm.capability.RMPermissionModel; +import org.alfresco.module.org_alfresco_module_rm.role.FilePlanRoleService; import org.alfresco.module.org_alfresco_module_rm.test.integration.hold.DeleteHoldTest; import org.alfresco.service.cmr.repository.NodeRef; @@ -43,7 +44,7 @@ public class RM1464Test extends DeleteHoldTest public Void run() { // Add the user to the RM Manager role - filePlanRoleService.assignRoleToAuthority(filePlan, ROLE_NAME_RECORDS_MANAGER, userName); + filePlanRoleService.assignRoleToAuthority(filePlan, FilePlanRoleService.ROLE_RECORDS_MANAGER, userName); // Give the user read permissions on the hold permissionService.setPermission(hold, userName, RMPermissionModel.READ_RECORDS, true); diff --git a/rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/integration/issue/RM804Test.java b/rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/integration/issue/RM804Test.java index 99e012d2a1..a8c96e8df2 100644 --- a/rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/integration/issue/RM804Test.java +++ b/rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/integration/issue/RM804Test.java @@ -19,6 +19,7 @@ package org.alfresco.module.org_alfresco_module_rm.test.integration.issue; import org.alfresco.error.AlfrescoRuntimeException; +import org.alfresco.module.org_alfresco_module_rm.role.FilePlanRoleService; import org.alfresco.module.org_alfresco_module_rm.test.util.BaseRMTestCase; import org.alfresco.service.cmr.security.AccessStatus; import org.alfresco.service.cmr.site.SiteRole; @@ -142,7 +143,7 @@ public class RM804Test extends BaseRMTestCase @Override public Void run() { - filePlanRoleService.assignRoleToAuthority(filePlan, ROLE_NAME_USER, userName); + filePlanRoleService.assignRoleToAuthority(filePlan, FilePlanRoleService.ROLE_USER, userName); return null; } @@ -167,7 +168,7 @@ public class RM804Test extends BaseRMTestCase @Override public Void run() { - filePlanRoleService.assignRoleToAuthority(filePlan, ROLE_NAME_ADMINISTRATOR, userName); + filePlanRoleService.assignRoleToAuthority(filePlan, FilePlanRoleService.ROLE_ADMIN, userName); return null; } diff --git a/rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/integration/record/RejectRecordTest.java b/rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/integration/record/RejectRecordTest.java index 1d0e78f33a..4aa12bd50c 100644 --- a/rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/integration/record/RejectRecordTest.java +++ b/rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/integration/record/RejectRecordTest.java @@ -31,38 +31,38 @@ import org.springframework.extensions.webscripts.GUID; /** * reject record tests. - * + * * @author Roy Wetherall * @since 2.2 */ public class RejectRecordTest extends BaseRMTestCase -{ - private VersionService versionService; - +{ + private VersionService versionService; + private static final String REASON = GUID.generate(); - + @Override protected boolean isUserTest() { return true; } - + @Override protected boolean isCollaborationSiteTest() { return true; } - + @Override protected void initServices() { super.initServices(); - + versionService = (VersionService)applicationContext.getBean("VersionService"); } - + /** - * + * */ public void testRejectedRecordInCorrectState() throws Exception { @@ -71,30 +71,30 @@ public class RejectRecordTest extends BaseRMTestCase public void given() { assertFalse(recordService.isRecord(dmDocument)); - ownableService.setOwner(dmDocument, userName); - + ownableService.setOwner(dmDocument, userName); + // document is declared as a record by user AuthenticationUtil.runAs(new RunAsWork() { public Void doWork() throws Exception { // declare record - recordService.createRecord(filePlan, dmDocument); + recordService.createRecord(filePlan, dmDocument); return null; } }, userName); } - + public void when() { // sanity checks assertTrue(recordService.isRecord(dmDocument)); - assertFalse(permissionService.getInheritParentPermissions(dmDocument)); - + assertTrue(permissionService.getInheritParentPermissions(dmDocument)); + // declare record - recordService.rejectRecord(dmDocument, REASON); + recordService.rejectRecord(dmDocument, REASON); } - + public void then() { // document is no longer a record @@ -105,47 +105,47 @@ public class RejectRecordTest extends BaseRMTestCase assertTrue(permissionService.getInheritParentPermissions(dmDocument)); assertFalse(nodeService.hasAspect(dmDocument, ASPECT_FILE_PLAN_COMPONENT)); } - }); + }); } - + /** - * + * */ public void testRevertAfterReject() throws Exception { doBehaviourDrivenTest(new BehaviourDrivenTest() {; private NodeRef document; - + public void given() { NodeRef folder = fileFolderService.create(documentLibrary, GUID.generate(), TYPE_FOLDER).getNodeRef(); document = fileFolderService.create(folder, GUID.generate(), TYPE_CONTENT).getNodeRef(); - + assertFalse(recordService.isRecord(document)); - ownableService.setOwner(document, userName); + ownableService.setOwner(document, userName); versionService.ensureVersioningEnabled(document, null); - + // document is declared as a record by user AuthenticationUtil.runAs(new RunAsWork() { public Void doWork() throws Exception { // declare record - recordService.createRecord(filePlan, document); + recordService.createRecord(filePlan, document); return null; } }, userName); - - assertTrue(nodeService.hasAspect(document, ASPECT_FILE_PLAN_COMPONENT)); + + assertTrue(nodeService.hasAspect(document, ASPECT_FILE_PLAN_COMPONENT)); } - + public void when() - { + { // reject the record - recordService.rejectRecord(document, REASON); + recordService.rejectRecord(document, REASON); assertFalse(nodeService.hasAspect(document, ASPECT_FILE_PLAN_COMPONENT)); - + // upload a new version of the document AuthenticationUtil.runAs(new RunAsWork() { @@ -154,31 +154,31 @@ public class RejectRecordTest extends BaseRMTestCase ContentWriter writer = contentService.getWriter(document, ContentModel.PROP_CONTENT, true); writer.putContent("This is a change to the content and should force a new version"); versionService.createVersion(document, null); - + return null; } }, userName); - + assertFalse(nodeService.hasAspect(document, ASPECT_FILE_PLAN_COMPONENT)); - + VersionHistory history = versionService.getVersionHistory(document); assertEquals(2, history.getAllVersions().size()); final Version initial = history.getRootVersion(); - + assertFalse(nodeService.hasAspect(initial.getFrozenStateNodeRef(), ASPECT_FILE_PLAN_COMPONENT)); - + AuthenticationUtil.runAs(new RunAsWork() { public Void doWork() throws Exception - { + { // revert the document to a previous version versionService.revert(document, initial); - + return null; } }, userName); } - + public void then() { // document is no longer a record @@ -187,6 +187,6 @@ public class RejectRecordTest extends BaseRMTestCase // expected owner has be re-set assertEquals(userName, ownableService.getOwner(document)); } - }); - } + }); + } } diff --git a/rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/legacy/capabilities/DeclarativeCapabilityTest.java b/rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/legacy/capabilities/DeclarativeCapabilityTest.java index 6581d3a800..a21d341b5e 100644 --- a/rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/legacy/capabilities/DeclarativeCapabilityTest.java +++ b/rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/legacy/capabilities/DeclarativeCapabilityTest.java @@ -60,7 +60,7 @@ public class DeclarativeCapabilityTest extends BaseRMTestCase private NodeRef moveToFolder; private NodeRef moveToCategory; - + private NodeRef hold; @Override @@ -109,9 +109,9 @@ public class DeclarativeCapabilityTest extends BaseRMTestCase utils.completeRecord(declaredRecord); utils.completeRecord(frozenRecord); utils.completeRecord(frozenRecord2); - + hold = holdService.createHold(filePlan, GUID.generate(), "reason", "description"); - + holdService.addToHold(hold, frozenRecord); holdService.addToHold(hold, frozenRecordFolder); holdService.addToHold(hold, frozenRecord2); @@ -141,6 +141,7 @@ public class DeclarativeCapabilityTest extends BaseRMTestCase for (String user : testUsers) { filePlanPermissionService.setPermission(rmFolder, user, RMPermissionModel.FILING); + filePlanPermissionService.setPermission(rmContainer, user, RMPermissionModel.READ_RECORDS); filePlanPermissionService.setPermission(moveToFolder, user, RMPermissionModel.READ_RECORDS); filePlanPermissionService.setPermission(moveToCategory, user, RMPermissionModel.READ_RECORDS); } diff --git a/rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/legacy/service/ExtendedSecurityServiceImplTest.java b/rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/legacy/service/ExtendedSecurityServiceImplTest.java index 7c8741b68f..324b0ce759 100644 --- a/rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/legacy/service/ExtendedSecurityServiceImplTest.java +++ b/rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/legacy/service/ExtendedSecurityServiceImplTest.java @@ -23,9 +23,15 @@ import java.util.HashSet; import java.util.Map; import java.util.Set; +import org.alfresco.model.ContentModel; import org.alfresco.module.org_alfresco_module_rm.test.util.BaseRMTestCase; import org.alfresco.repo.security.authentication.AuthenticationUtil; +import org.alfresco.repo.security.authentication.AuthenticationUtil.RunAsWork; +import org.alfresco.repo.site.SiteModel; import org.alfresco.service.cmr.repository.NodeRef; +import org.alfresco.service.cmr.security.AccessStatus; +import org.alfresco.service.cmr.site.SiteService; +import org.alfresco.service.cmr.site.SiteVisibility; import org.alfresco.util.GUID; /** @@ -237,4 +243,115 @@ public class ExtendedSecurityServiceImplTest extends BaseRMTestCase assertNotNull(readers); assertEquals(testMap.size(), readers.size()); } + + public void testDifferentUsersDifferentPermissions() + { + final String userNone = createTestUser(); + final String userRead = createTestUser(); + final String userWrite = createTestUser(); + final String siteShortName = GUID.generate(); + + doTestInTransaction(new Test() + { + public Void run() throws Exception + { + siteService.createSite(null, siteShortName, "test", "test", SiteVisibility.PRIVATE); + return null; + } + }); + + final NodeRef documentLibrary = doTestInTransaction(new Test() + { + public NodeRef run() throws Exception + { + siteService.setMembership(siteShortName, userRead, SiteModel.SITE_CONSUMER); + siteService.setMembership(siteShortName, userWrite, SiteModel.SITE_COLLABORATOR); + return siteService.createContainer(siteShortName, SiteService.DOCUMENT_LIBRARY, null, null); + } + }); + + final NodeRef record = doTestInTransaction(new Test() + { + public NodeRef run() throws Exception + { + NodeRef record = fileFolderService.create(documentLibrary, GUID.generate(), ContentModel.TYPE_CONTENT).getNodeRef(); + recordService.createRecord(filePlan, record); + return record; + } + }); + + doTestInTransaction(new Test() + { + public Void run() throws Exception + { + AuthenticationUtil.runAs(new RunAsWork() + { + public Void doWork() throws Exception + { + // check permissions + assertEquals(AccessStatus.DENIED, permissionService.hasPermission(record, READ_RECORDS)); + assertEquals(AccessStatus.DENIED, permissionService.hasPermission(record, FILING)); + return null; + } + }, userNone); + + AuthenticationUtil.runAs(new RunAsWork() + { + public Void doWork() throws Exception + { + // check permissions + assertEquals(AccessStatus.ALLOWED, permissionService.hasPermission(record, READ_RECORDS)); + assertEquals(AccessStatus.DENIED, permissionService.hasPermission(record, FILING)); + return null; + } + }, userRead); + + AuthenticationUtil.runAs(new RunAsWork() + { + public Void doWork() throws Exception + { + // check permissions + assertEquals(AccessStatus.ALLOWED, permissionService.hasPermission(record, READ_RECORDS)); + assertEquals(AccessStatus.ALLOWED, permissionService.hasPermission(record, FILING)); + return null; + } + }, userWrite); + + AuthenticationUtil.runAs(new RunAsWork() + { + public Void doWork() throws Exception + { + // check permissions + assertEquals(AccessStatus.DENIED, permissionService.hasPermission(record, READ_RECORDS)); + assertEquals(AccessStatus.DENIED, permissionService.hasPermission(record, FILING)); + return null; + } + }, userNone); + + AuthenticationUtil.runAs(new RunAsWork() + { + public Void doWork() throws Exception + { + // check permissions + assertEquals(AccessStatus.ALLOWED, permissionService.hasPermission(record, READ_RECORDS)); + assertEquals(AccessStatus.DENIED, permissionService.hasPermission(record, FILING)); + return null; + } + }, userRead); + + AuthenticationUtil.runAs(new RunAsWork() + { + public Void doWork() throws Exception + { + // check permissions + assertEquals(AccessStatus.ALLOWED, permissionService.hasPermission(record, READ_RECORDS)); + assertEquals(AccessStatus.ALLOWED, permissionService.hasPermission(record, FILING)); + return null; + } + }, userWrite); + + return null; + } + }); + } } diff --git a/rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/legacy/service/FilePlanPermissionServiceImplTest.java b/rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/legacy/service/FilePlanPermissionServiceImplTest.java index 732f876e30..7929c67cca 100644 --- a/rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/legacy/service/FilePlanPermissionServiceImplTest.java +++ b/rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/legacy/service/FilePlanPermissionServiceImplTest.java @@ -18,12 +18,20 @@ */ package org.alfresco.module.org_alfresco_module_rm.test.legacy.service; +import java.util.HashMap; +import java.util.Map; +import java.util.Set; + import org.alfresco.module.org_alfresco_module_rm.capability.RMPermissionModel; 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.module.org_alfresco_module_rm.test.util.BaseRMTestCase; import org.alfresco.repo.security.authentication.AuthenticationUtil; import org.alfresco.service.cmr.repository.NodeRef; +import org.alfresco.service.cmr.security.AccessPermission; import org.alfresco.service.cmr.security.AccessStatus; +import org.alfresco.service.cmr.security.AuthorityType; import org.springframework.extensions.webscripts.GUID; /** @@ -103,59 +111,59 @@ public class FilePlanPermissionServiceImplTest extends BaseRMTestCase } /** - * test set/delete permissions on file plan + * Test set/delete permissions on file plan */ public void testSetDeletePermissionFilePlan() throws Exception { String userName = createTestUser(); assertPermissions(userName, - AccessStatus.ALLOWED, // fileplan read - AccessStatus.DENIED, // fileplan file - AccessStatus.DENIED, // category read - AccessStatus.DENIED, // category file - AccessStatus.DENIED, // record folder read - AccessStatus.DENIED, // record folder file - AccessStatus.DENIED, // record read - AccessStatus.DENIED); // record file + AccessStatus.ALLOWED, // fileplan read + AccessStatus.DENIED, // fileplan file + AccessStatus.DENIED, // category read + AccessStatus.DENIED, // category file + AccessStatus.DENIED, // record folder read + AccessStatus.DENIED, // record folder file + AccessStatus.DENIED, // record read + AccessStatus.DENIED); // record file setPermission(filePlan, userName, RMPermissionModel.FILING); assertPermissions(userName, AccessStatus.ALLOWED, // fileplan read AccessStatus.ALLOWED, // fileplan file - AccessStatus.ALLOWED, // category read - AccessStatus.ALLOWED, // category file - AccessStatus.ALLOWED, // record folder read - AccessStatus.ALLOWED, // record folder file - AccessStatus.ALLOWED, // record read - AccessStatus.ALLOWED); // record file + AccessStatus.DENIED, // category read + AccessStatus.DENIED, // category file + AccessStatus.DENIED, // record folder read + AccessStatus.DENIED, // record folder file + AccessStatus.DENIED, // record read + AccessStatus.DENIED); // record file deletePermission(filePlan, userName, RMPermissionModel.FILING); assertPermissions(userName, - AccessStatus.ALLOWED, // fileplan read - AccessStatus.DENIED, // fileplan file - AccessStatus.DENIED, // category read - AccessStatus.DENIED, // category file - AccessStatus.DENIED, // record folder read - AccessStatus.DENIED, // record folder file - AccessStatus.DENIED, // record read - AccessStatus.DENIED); // record file + AccessStatus.ALLOWED, // fileplan read + AccessStatus.DENIED, // fileplan file + AccessStatus.DENIED, // category read + AccessStatus.DENIED, // category file + AccessStatus.DENIED, // record folder read + AccessStatus.DENIED, // record folder file + AccessStatus.DENIED, // record read + AccessStatus.DENIED); // record file //what happens if we try and remove READ for a normal user on the file plan ??? deletePermission(filePlan, userName, RMPermissionModel.READ_RECORDS); // nothing .. user still has read on file plan .. only removing the user from all roles will remove read on file plan assertPermissions(userName, - AccessStatus.ALLOWED, // fileplan read - AccessStatus.DENIED, // fileplan file - AccessStatus.DENIED, // category read - AccessStatus.DENIED, // category file - AccessStatus.DENIED, // record folder read - AccessStatus.DENIED, // record folder file - AccessStatus.DENIED, // record read - AccessStatus.DENIED); // record file + AccessStatus.ALLOWED, // fileplan read + AccessStatus.DENIED, // fileplan file + AccessStatus.DENIED, // category read + AccessStatus.DENIED, // category file + AccessStatus.DENIED, // record folder read + AccessStatus.DENIED, // record folder file + AccessStatus.DENIED, // record read + AccessStatus.DENIED); // record file } /** @@ -166,38 +174,38 @@ public class FilePlanPermissionServiceImplTest extends BaseRMTestCase String userName = createTestUser(); assertPermissions(userName, - AccessStatus.ALLOWED, // fileplan read - AccessStatus.DENIED, // fileplan file - AccessStatus.DENIED, // category read - AccessStatus.DENIED, // category file - AccessStatus.DENIED, // record folder read - AccessStatus.DENIED, // record folder file - AccessStatus.DENIED, // record read - AccessStatus.DENIED); // record file + AccessStatus.ALLOWED, // fileplan read + AccessStatus.DENIED, // fileplan file + AccessStatus.DENIED, // category read + AccessStatus.DENIED, // category file + AccessStatus.DENIED, // record folder read + AccessStatus.DENIED, // record folder file + AccessStatus.DENIED, // record read + AccessStatus.DENIED); // record file setPermission(rmContainer, userName, RMPermissionModel.FILING); assertPermissions(userName, - AccessStatus.ALLOWED, // fileplan read - AccessStatus.DENIED, // fileplan file - AccessStatus.ALLOWED, // category read - AccessStatus.ALLOWED, // category file - AccessStatus.ALLOWED, // record folder read - AccessStatus.ALLOWED, // record folder file - AccessStatus.ALLOWED, // record read - AccessStatus.ALLOWED); // record file + AccessStatus.ALLOWED, // fileplan read + AccessStatus.DENIED, // fileplan file + AccessStatus.ALLOWED, // category read + AccessStatus.ALLOWED, // category file + AccessStatus.ALLOWED, // record folder read + AccessStatus.ALLOWED, // record folder file + AccessStatus.ALLOWED, // record read + AccessStatus.ALLOWED); // record file deletePermission(rmContainer, userName, RMPermissionModel.FILING); assertPermissions(userName, - AccessStatus.ALLOWED, // fileplan read - AccessStatus.DENIED, // fileplan file - AccessStatus.DENIED, // category read - AccessStatus.DENIED, // category file - AccessStatus.DENIED, // record folder read - AccessStatus.DENIED, // record folder file - AccessStatus.DENIED, // record read - AccessStatus.DENIED); // record file + AccessStatus.ALLOWED, // fileplan read + AccessStatus.DENIED, // fileplan file + AccessStatus.DENIED, // category read + AccessStatus.DENIED, // category file + AccessStatus.DENIED, // record folder read + AccessStatus.DENIED, // record folder file + AccessStatus.DENIED, // record read + AccessStatus.DENIED); // record file } /** @@ -208,38 +216,38 @@ public class FilePlanPermissionServiceImplTest extends BaseRMTestCase String userName = createTestUser(); assertPermissions(userName, - AccessStatus.ALLOWED, // fileplan read - AccessStatus.DENIED, // fileplan file - AccessStatus.DENIED, // category read - AccessStatus.DENIED, // category file - AccessStatus.DENIED, // record folder read - AccessStatus.DENIED, // record folder file - AccessStatus.DENIED, // record read - AccessStatus.DENIED); // record file + AccessStatus.ALLOWED, // fileplan read + AccessStatus.DENIED, // fileplan file + AccessStatus.DENIED, // category read + AccessStatus.DENIED, // category file + AccessStatus.DENIED, // record folder read + AccessStatus.DENIED, // record folder file + AccessStatus.DENIED, // record read + AccessStatus.DENIED); // record file setPermission(rmFolder, userName, RMPermissionModel.FILING); assertPermissions(userName, - AccessStatus.ALLOWED, // fileplan read - AccessStatus.DENIED, // fileplan file - AccessStatus.ALLOWED, // category read - AccessStatus.DENIED, // category file - AccessStatus.ALLOWED, // record folder read - AccessStatus.ALLOWED, // record folder file - AccessStatus.ALLOWED, // record read - AccessStatus.ALLOWED); // record file + AccessStatus.ALLOWED, // fileplan read + AccessStatus.DENIED, // fileplan file + AccessStatus.DENIED, // category read + AccessStatus.DENIED, // category file + AccessStatus.ALLOWED, // record folder read + AccessStatus.ALLOWED, // record folder file + AccessStatus.ALLOWED, // record read + AccessStatus.ALLOWED); // record file deletePermission(rmFolder, userName, RMPermissionModel.FILING); assertPermissions(userName, - AccessStatus.ALLOWED, // fileplan read - AccessStatus.DENIED, // fileplan file - AccessStatus.ALLOWED, // category read - AccessStatus.DENIED, // category file - AccessStatus.DENIED, // record folder read - AccessStatus.DENIED, // record folder file - AccessStatus.DENIED, // record read - AccessStatus.DENIED); // record file + AccessStatus.ALLOWED, // fileplan read + AccessStatus.DENIED, // fileplan file + AccessStatus.DENIED, // category read + AccessStatus.DENIED, // category file + AccessStatus.DENIED, // record folder read + AccessStatus.DENIED, // record folder file + AccessStatus.DENIED, // record read + AccessStatus.DENIED); // record file } /** @@ -250,38 +258,38 @@ public class FilePlanPermissionServiceImplTest extends BaseRMTestCase String userName = createTestUser(); assertPermissions(userName, - AccessStatus.ALLOWED, // fileplan read - AccessStatus.DENIED, // fileplan file - AccessStatus.DENIED, // category read - AccessStatus.DENIED, // category file - AccessStatus.DENIED, // record folder read - AccessStatus.DENIED, // record folder file - AccessStatus.DENIED, // record read - AccessStatus.DENIED); // record file + AccessStatus.ALLOWED, // fileplan read + AccessStatus.DENIED, // fileplan file + AccessStatus.DENIED, // category read + AccessStatus.DENIED, // category file + AccessStatus.DENIED, // record folder read + AccessStatus.DENIED, // record folder file + AccessStatus.DENIED, // record read + AccessStatus.DENIED); // record file setPermission(recordOne, userName, RMPermissionModel.FILING); assertPermissions(userName, - AccessStatus.ALLOWED, // fileplan read - AccessStatus.DENIED, // fileplan file - AccessStatus.ALLOWED, // category read - AccessStatus.DENIED, // category file - AccessStatus.ALLOWED, // record folder read - AccessStatus.DENIED, // record folder file - AccessStatus.ALLOWED, // record read - AccessStatus.ALLOWED); // record file + AccessStatus.ALLOWED, // fileplan read + AccessStatus.DENIED, // fileplan file + AccessStatus.DENIED, // category read + AccessStatus.DENIED, // category file + AccessStatus.DENIED, // record folder read + AccessStatus.DENIED, // record folder file + AccessStatus.ALLOWED, // record read + AccessStatus.ALLOWED); // record file deletePermission(recordOne, userName, RMPermissionModel.FILING); assertPermissions(userName, - AccessStatus.ALLOWED, // fileplan read - AccessStatus.DENIED, // fileplan file - AccessStatus.ALLOWED, // category read - AccessStatus.DENIED, // category file - AccessStatus.ALLOWED, // record folder read - AccessStatus.DENIED, // record folder file - AccessStatus.DENIED, // record read - AccessStatus.DENIED); // record file + AccessStatus.ALLOWED, // fileplan read + AccessStatus.DENIED, // fileplan file + AccessStatus.DENIED, // category read + AccessStatus.DENIED, // category file + AccessStatus.DENIED, // record folder read + AccessStatus.DENIED, // record folder file + AccessStatus.DENIED, // record read + AccessStatus.DENIED); // record file } public void testMoveRecord() throws Exception @@ -300,14 +308,15 @@ public class FilePlanPermissionServiceImplTest extends BaseRMTestCase }); assertPermissions(userOne, - AccessStatus.ALLOWED, // fileplan read - AccessStatus.DENIED, // fileplan file - AccessStatus.DENIED, // category read - AccessStatus.DENIED, // category file - AccessStatus.DENIED, // record folder read - AccessStatus.DENIED, // record folder file - AccessStatus.DENIED, // record read - AccessStatus.DENIED); // record file + AccessStatus.ALLOWED, // fileplan read + AccessStatus.DENIED, // fileplan file + AccessStatus.DENIED, // category read + AccessStatus.DENIED, // category file + AccessStatus.DENIED, // record folder read + AccessStatus.DENIED, // record folder file + AccessStatus.DENIED, // record read + AccessStatus.DENIED); // record file + doTestInTransaction(new Test() { @Override @@ -318,15 +327,17 @@ public class FilePlanPermissionServiceImplTest extends BaseRMTestCase return null; } }, userOne); + assertPermissions(userTwo, - AccessStatus.ALLOWED, // fileplan read - AccessStatus.DENIED, // fileplan file - AccessStatus.DENIED, // category read - AccessStatus.DENIED, // category file - AccessStatus.DENIED, // record folder read - AccessStatus.DENIED, // record folder file - AccessStatus.DENIED, // record read - AccessStatus.DENIED); // record file + AccessStatus.ALLOWED, // fileplan read + AccessStatus.DENIED, // fileplan file + AccessStatus.DENIED, // category read + AccessStatus.DENIED, // category file + AccessStatus.DENIED, // record folder read + AccessStatus.DENIED, // record folder file + AccessStatus.DENIED, // record read + AccessStatus.DENIED); // record file + doTestInTransaction(new Test() { @Override @@ -337,15 +348,17 @@ public class FilePlanPermissionServiceImplTest extends BaseRMTestCase return null; } }, userTwo); + assertPermissions(userThree, - AccessStatus.ALLOWED, // fileplan read - AccessStatus.DENIED, // fileplan file - AccessStatus.DENIED, // category read - AccessStatus.DENIED, // category file - AccessStatus.DENIED, // record folder read - AccessStatus.DENIED, // record folder file - AccessStatus.DENIED, // record read - AccessStatus.DENIED); // record file + AccessStatus.ALLOWED, // fileplan read + AccessStatus.DENIED, // fileplan file + AccessStatus.DENIED, // category read + AccessStatus.DENIED, // category file + AccessStatus.DENIED, // record folder read + AccessStatus.DENIED, // record folder file + AccessStatus.DENIED, // record read + AccessStatus.DENIED); // record file + doTestInTransaction(new Test() { @Override @@ -362,14 +375,15 @@ public class FilePlanPermissionServiceImplTest extends BaseRMTestCase setPermission(recordOne, userThree, RMPermissionModel.FILING); assertPermissions(userOne, - AccessStatus.ALLOWED, // fileplan read - AccessStatus.DENIED, // fileplan file - AccessStatus.ALLOWED, // category read - AccessStatus.DENIED, // category file - AccessStatus.ALLOWED, // record folder read - AccessStatus.ALLOWED, // record folder file - AccessStatus.ALLOWED, // record read - AccessStatus.ALLOWED); // record file + AccessStatus.ALLOWED, // fileplan read + AccessStatus.DENIED, // fileplan file + AccessStatus.DENIED, // category read + AccessStatus.DENIED, // category file + AccessStatus.ALLOWED, // record folder read + AccessStatus.ALLOWED, // record folder file + AccessStatus.ALLOWED, // record read + AccessStatus.ALLOWED); // record file + doTestInTransaction(new Test() { @Override @@ -380,15 +394,17 @@ public class FilePlanPermissionServiceImplTest extends BaseRMTestCase return null; } }, userOne); + assertPermissions(userTwo, - AccessStatus.ALLOWED, // fileplan read - AccessStatus.DENIED, // fileplan file - AccessStatus.ALLOWED, // category read - AccessStatus.DENIED, // category file - AccessStatus.DENIED, // record folder read - AccessStatus.DENIED, // record folder file - AccessStatus.DENIED, // record read - AccessStatus.DENIED); // record file + AccessStatus.ALLOWED, // fileplan read + AccessStatus.DENIED, // fileplan file + AccessStatus.DENIED, // category read + AccessStatus.DENIED, // category file + AccessStatus.DENIED, // record folder read + AccessStatus.DENIED, // record folder file + AccessStatus.DENIED, // record read + AccessStatus.DENIED); // record file + doTestInTransaction(new Test() { @Override @@ -399,15 +415,17 @@ public class FilePlanPermissionServiceImplTest extends BaseRMTestCase return null; } }, userTwo); + assertPermissions(userThree, - AccessStatus.ALLOWED, // fileplan read - AccessStatus.DENIED, // fileplan file - AccessStatus.ALLOWED, // category read - AccessStatus.DENIED, // category file - AccessStatus.ALLOWED, // record folder read - AccessStatus.DENIED, // record folder file - AccessStatus.ALLOWED, // record read - AccessStatus.ALLOWED); // record file + AccessStatus.ALLOWED, // fileplan read + AccessStatus.DENIED, // fileplan file + AccessStatus.DENIED, // category read + AccessStatus.DENIED, // category file + AccessStatus.DENIED, // record folder read + AccessStatus.DENIED, // record folder file + AccessStatus.ALLOWED, // record read + AccessStatus.ALLOWED); // record file + doTestInTransaction(new Test() { @Override @@ -431,14 +449,15 @@ public class FilePlanPermissionServiceImplTest extends BaseRMTestCase }); assertPermissions(userOne, - AccessStatus.ALLOWED, // fileplan read - AccessStatus.DENIED, // fileplan file - AccessStatus.ALLOWED, // category read - AccessStatus.DENIED, // category file - AccessStatus.ALLOWED, // record folder read - AccessStatus.ALLOWED, // record folder file - AccessStatus.DENIED, // record read - AccessStatus.DENIED); // record file + AccessStatus.ALLOWED, // fileplan read + AccessStatus.DENIED, // fileplan file + AccessStatus.DENIED, // category read + AccessStatus.DENIED, // category file + AccessStatus.ALLOWED, // record folder read + AccessStatus.ALLOWED, // record folder file + AccessStatus.DENIED, // record read + AccessStatus.DENIED); // record file + doTestInTransaction(new Test() { @Override @@ -449,15 +468,17 @@ public class FilePlanPermissionServiceImplTest extends BaseRMTestCase return null; } }, userOne); + assertPermissions(userTwo, - AccessStatus.ALLOWED, // fileplan read - AccessStatus.DENIED, // fileplan file - AccessStatus.ALLOWED, // category read - AccessStatus.DENIED, // category file - AccessStatus.DENIED, // record folder read - AccessStatus.DENIED, // record folder file - AccessStatus.ALLOWED, // record read - AccessStatus.ALLOWED); // record file + AccessStatus.ALLOWED, // fileplan read + AccessStatus.DENIED, // fileplan file + AccessStatus.DENIED, // category read + AccessStatus.DENIED, // category file + AccessStatus.DENIED, // record folder read + AccessStatus.DENIED, // record folder file + AccessStatus.ALLOWED, // record read + AccessStatus.ALLOWED); // record file + doTestInTransaction(new Test() { @Override @@ -468,21 +489,23 @@ public class FilePlanPermissionServiceImplTest extends BaseRMTestCase return null; } }, userTwo); + assertPermissions(userThree, - AccessStatus.ALLOWED, // fileplan read - AccessStatus.DENIED, // fileplan file - AccessStatus.ALLOWED, // category read - AccessStatus.DENIED, // category file - AccessStatus.ALLOWED, // record folder read - AccessStatus.DENIED, // record folder file - AccessStatus.ALLOWED, // record read - AccessStatus.ALLOWED); // record file + AccessStatus.ALLOWED, // fileplan read + AccessStatus.DENIED, // fileplan file + AccessStatus.DENIED, // category read + AccessStatus.DENIED, // category file + AccessStatus.DENIED, // record folder read + AccessStatus.DENIED, // record folder file + AccessStatus.ALLOWED, // record read + AccessStatus.ALLOWED); // record file + doTestInTransaction(new Test() { @Override public Void run() { - assertEquals(AccessStatus.ALLOWED, permissionService.hasPermission(otherFolder, RMPermissionModel.READ_RECORDS)); + assertEquals(AccessStatus.DENIED, permissionService.hasPermission(otherFolder, RMPermissionModel.READ_RECORDS)); assertEquals(AccessStatus.DENIED, permissionService.hasPermission(otherFolder, RMPermissionModel.FILING)); return null; } @@ -490,7 +513,6 @@ public class FilePlanPermissionServiceImplTest extends BaseRMTestCase } - /** * Helper to assert permissions for passed user */ @@ -521,4 +543,701 @@ public class FilePlanPermissionServiceImplTest extends BaseRMTestCase }, userName); } + /** + * Helper to assert permissions for the passed user + */ + private void assertPermissionsWithInheritance( + final String userName, + final NodeRef subCategory, + final NodeRef folder, + final NodeRef record, + final AccessStatus ... accessStatus) + { + assertEquals(16, accessStatus.length); + + doTestInTransaction(new Test() + { + @Override + public Void run() + { + assertEquals(accessStatus[0], permissionService.hasPermission(filePlan, RMPermissionModel.READ_RECORDS)); + assertEquals(accessStatus[1], permissionService.hasPermission(filePlan, RMPermissionModel.FILING)); + + assertEquals(accessStatus[2], permissionService.hasPermission(transfersContainer, RMPermissionModel.READ_RECORDS)); + assertEquals(accessStatus[3], permissionService.hasPermission(transfersContainer, RMPermissionModel.FILING)); + + assertEquals(accessStatus[4], permissionService.hasPermission(holdsContainer, RMPermissionModel.READ_RECORDS)); + assertEquals(accessStatus[5], permissionService.hasPermission(holdsContainer, RMPermissionModel.FILING)); + + assertEquals(accessStatus[6], permissionService.hasPermission(unfiledContainer, RMPermissionModel.READ_RECORDS)); + assertEquals(accessStatus[7], permissionService.hasPermission(unfiledContainer, RMPermissionModel.FILING)); + + assertEquals(accessStatus[8], permissionService.hasPermission(rmContainer, RMPermissionModel.READ_RECORDS)); + assertEquals(accessStatus[9], permissionService.hasPermission(rmContainer, RMPermissionModel.FILING)); + + assertEquals(accessStatus[10], permissionService.hasPermission(subCategory, RMPermissionModel.READ_RECORDS)); + assertEquals(accessStatus[11], permissionService.hasPermission(subCategory, RMPermissionModel.FILING)); + + assertEquals(accessStatus[12], permissionService.hasPermission(folder, RMPermissionModel.READ_RECORDS)); + assertEquals(accessStatus[13], permissionService.hasPermission(folder, RMPermissionModel.FILING)); + + assertEquals(accessStatus[14], permissionService.hasPermission(record, RMPermissionModel.READ_RECORDS)); + assertEquals(accessStatus[15], permissionService.hasPermission(record, RMPermissionModel.FILING)); + + return null; + } + }, userName); + } + + public void testFilePlanComponentInheritance() + { + doTestInTransaction(new Test() + { + @Override + public Void run() + { + // Inheritance is turned off for file plan, transfer, holds, unfiled records and root categories + // it is turned on for sub categories, record folders and records + assertFalse(permissionService.getInheritParentPermissions(filePlan)); + assertFalse(permissionService.getInheritParentPermissions(filePlanService.getTransferContainer(filePlan))); + assertFalse(permissionService.getInheritParentPermissions(filePlanService.getHoldContainer(filePlan))); + assertFalse(permissionService.getInheritParentPermissions(unfiledContainer)); + assertFalse(permissionService.getInheritParentPermissions(rmContainer)); + assertTrue(permissionService.getInheritParentPermissions(recordFolderService.createRecordFolder(rmContainer, "subCategory"))); + assertTrue(permissionService.getInheritParentPermissions(rmFolder)); + assertTrue(permissionService.getInheritParentPermissions(recordOne)); + + return null; + } + }, ADMIN_USER); + } + + public void testRolesSetByDefault() + { + NodeRef subCategory = filePlanService.createRecordCategory(rmContainer, "subCategory1"); + NodeRef folder = recordFolderService.createRecordFolder(subCategory, "rmFolder1"); + NodeRef record = utils.createRecord(folder, "record1.txt"); + + // Admin user has read/filing permissions on file plan, transfer, hold, unfiled records, root categories, sub categories, folders and records + assertPermissionsWithInheritance(ADMIN_USER, subCategory, folder, record, + AccessStatus.ALLOWED, // fileplan read + AccessStatus.ALLOWED, // fileplan file + AccessStatus.ALLOWED, // transfer read + AccessStatus.ALLOWED, // transfer file + AccessStatus.ALLOWED, // holds read + AccessStatus.ALLOWED, // holds file + AccessStatus.ALLOWED, // unfiled records file + AccessStatus.ALLOWED, // unfiled records file + AccessStatus.ALLOWED, // root category read + AccessStatus.ALLOWED, // root category file + AccessStatus.ALLOWED, // sub category read + AccessStatus.ALLOWED, // sub category file + AccessStatus.ALLOWED, // folder read + AccessStatus.ALLOWED, // folder file + AccessStatus.ALLOWED, // record read + AccessStatus.ALLOWED); // record file + + // Test user has read permissions on file plan, transfer, hold and unfiled records as the user will be added in the all records management roles + // which has read permissions on those nodes by default + assertPermissionsWithInheritance(createTestUser(), subCategory, folder, record, + AccessStatus.ALLOWED, // fileplan read + AccessStatus.DENIED, // fileplan file + AccessStatus.ALLOWED, // transfer read + AccessStatus.DENIED, // transfer file + AccessStatus.ALLOWED, // holds read + AccessStatus.DENIED, // holds file + AccessStatus.ALLOWED, // unfiled records file + AccessStatus.DENIED, // unfiled records file + AccessStatus.DENIED, // root category read + AccessStatus.DENIED, // root category file + AccessStatus.DENIED, // sub category read + AccessStatus.DENIED, // sub category file + AccessStatus.DENIED, // folder read + AccessStatus.DENIED, // folder file + AccessStatus.DENIED, // record read + AccessStatus.DENIED); // record file + } + + public void testAddUserToContainers() + { + NodeRef subCategory = filePlanService.createRecordCategory(rmContainer, "subCategory2"); + NodeRef folder = recordFolderService.createRecordFolder(subCategory, "rmFolder2"); + NodeRef record = utils.createRecord(folder, "record2.txt"); + + // The user1 will have read permissions on the file plan + // and read permissions on transfer, hold and unfiled records as the user will be in the all records management users role + String user1 = createTestUser(); + setPermission(filePlan, user1, RMPermissionModel.READ_RECORDS); + assertPermissionsWithInheritance(user1, subCategory, folder, record, + AccessStatus.ALLOWED, // fileplan read + AccessStatus.DENIED, // fileplan file + AccessStatus.ALLOWED, // transfer read + AccessStatus.DENIED, // transfer file + AccessStatus.ALLOWED, // holds read + AccessStatus.DENIED, // holds file + AccessStatus.ALLOWED, // unfiled records file + AccessStatus.DENIED, // unfiled records file + AccessStatus.DENIED, // root category read + AccessStatus.DENIED, // root category file + AccessStatus.DENIED, // sub category read + AccessStatus.DENIED, // sub category file + AccessStatus.DENIED, // folder read + AccessStatus.DENIED, // folder file + AccessStatus.DENIED, // record read + AccessStatus.DENIED); // record file + + // The user2 will have read and filing permissions on the transfer container + // and read permissions on file plan, hold and unfiled records as the user will be in the all records management users role + String user2 = createTestUser(); + setPermission(transfersContainer, user2, RMPermissionModel.FILING); + assertPermissionsWithInheritance(user2, subCategory, folder, record, + AccessStatus.ALLOWED, // fileplan read + AccessStatus.DENIED, // fileplan file + AccessStatus.ALLOWED, // transfer read + AccessStatus.ALLOWED, // transfer file + AccessStatus.ALLOWED, // holds read + AccessStatus.DENIED, // holds file + AccessStatus.ALLOWED, // unfiled records file + AccessStatus.DENIED, // unfiled records file + AccessStatus.DENIED, // root category read + AccessStatus.DENIED, // root category file + AccessStatus.DENIED, // sub category read + AccessStatus.DENIED, // sub category file + AccessStatus.DENIED, // folder read + AccessStatus.DENIED, // folder file + AccessStatus.DENIED, // record read + AccessStatus.DENIED); // record file + + // The user3 will have read permissions on file plan, transfer, hold and unfiled records + String user3 = createTestUser(); + setPermission(holdsContainer, user3, RMPermissionModel.READ_RECORDS); + assertPermissionsWithInheritance(user3, subCategory, folder, record, + AccessStatus.ALLOWED, // fileplan read + AccessStatus.DENIED, // fileplan file + AccessStatus.ALLOWED, // transfer read + AccessStatus.DENIED, // transfer file + AccessStatus.ALLOWED, // holds read + AccessStatus.DENIED, // holds file + AccessStatus.ALLOWED, // unfiled records file + AccessStatus.DENIED, // unfiled records file + AccessStatus.DENIED, // root category read + AccessStatus.DENIED, // root category file + AccessStatus.DENIED, // sub category read + AccessStatus.DENIED, // sub category file + AccessStatus.DENIED, // folder read + AccessStatus.DENIED, // folder file + AccessStatus.DENIED, // record read + AccessStatus.DENIED); // record file + + // The user4 will have read permissions on file plan, transfer, hold + // and read and filing permissions on unfiled records container + String user4 = createTestUser(); + setPermission(unfiledContainer, user4, RMPermissionModel.FILING); + assertPermissionsWithInheritance(user4, subCategory, folder, record, + AccessStatus.ALLOWED, // fileplan read + AccessStatus.DENIED, // fileplan file + AccessStatus.ALLOWED, // transfer read + AccessStatus.DENIED, // transfer file + AccessStatus.ALLOWED, // holds read + AccessStatus.DENIED, // holds file + AccessStatus.ALLOWED, // unfiled records file + AccessStatus.ALLOWED, // unfiled records file + AccessStatus.DENIED, // root category read + AccessStatus.DENIED, // root category file + AccessStatus.DENIED, // sub category read + AccessStatus.DENIED, // sub category file + AccessStatus.DENIED, // folder read + AccessStatus.DENIED, // folder file + AccessStatus.DENIED, // record read + AccessStatus.DENIED); // record file + + // The user5 will read permissions on the root category + // as the inheritance is turned on for the sub category the user will have also read permissions on sub category, folder and record + // and also read permissions on file plan, transfer, hold and unfiled records + String user5 = createTestUser(); + setPermission(rmContainer, user5, RMPermissionModel.READ_RECORDS); + assertPermissionsWithInheritance(user5, subCategory, folder, record, + AccessStatus.ALLOWED, // fileplan read + AccessStatus.DENIED, // fileplan file + AccessStatus.ALLOWED, // transfer read + AccessStatus.DENIED, // transfer file + AccessStatus.ALLOWED, // holds read + AccessStatus.DENIED, // holds file + AccessStatus.ALLOWED, // unfiled records file + AccessStatus.DENIED, // unfiled records file + AccessStatus.ALLOWED, // root category read + AccessStatus.DENIED, // root category file + AccessStatus.ALLOWED, // sub category read + AccessStatus.DENIED, // sub category file + AccessStatus.ALLOWED, // folder read + AccessStatus.DENIED, // folder file + AccessStatus.ALLOWED, // record read + AccessStatus.DENIED); // record file + + // The user6 will read and filing permissions on the sub category + // as the inheritance is turned on the user will have also read and filing permissions on folder and record + // and also read permissions on file plan, transfer, hold and unfiled records + String user6 = createTestUser(); + setPermission(subCategory, user6, RMPermissionModel.FILING); + assertPermissionsWithInheritance(user6, subCategory, folder, record, + AccessStatus.ALLOWED, // fileplan read + AccessStatus.DENIED, // fileplan file + AccessStatus.ALLOWED, // transfer read + AccessStatus.DENIED, // transfer file + AccessStatus.ALLOWED, // holds read + AccessStatus.DENIED, // holds file + AccessStatus.ALLOWED, // unfiled records file + AccessStatus.DENIED, // unfiled records file + AccessStatus.DENIED, // root category read + AccessStatus.DENIED, // root category file + AccessStatus.ALLOWED, // sub category read + AccessStatus.ALLOWED, // sub category file + AccessStatus.ALLOWED, // folder read + AccessStatus.ALLOWED, // folder file + AccessStatus.ALLOWED, // record read + AccessStatus.ALLOWED); // record file + + // The user7 will read permissions on the folder + // as the inheritance is turned on the user will have also read on record + // and also read permissions on file plan, transfer, hold and unfiled records + String user7 = createTestUser(); + setPermission(folder, user7, RMPermissionModel.READ_RECORDS); + assertPermissionsWithInheritance(user7, subCategory, folder, record, + AccessStatus.ALLOWED, // fileplan read + AccessStatus.DENIED, // fileplan file + AccessStatus.ALLOWED, // transfer read + AccessStatus.DENIED, // transfer file + AccessStatus.ALLOWED, // holds read + AccessStatus.DENIED, // holds file + AccessStatus.ALLOWED, // unfiled records file + AccessStatus.DENIED, // unfiled records file + AccessStatus.DENIED, // root category read + AccessStatus.DENIED, // root category file + AccessStatus.DENIED, // sub category read + AccessStatus.DENIED, // sub category file + AccessStatus.ALLOWED, // folder read + AccessStatus.DENIED, // folder file + AccessStatus.ALLOWED, // record read + AccessStatus.DENIED); // record file + + // The user8 will read and filing permissions on the record + // and also read permissions on file plan, transfer, hold and unfiled records + String user8 = createTestUser(); + setPermission(record, user8, RMPermissionModel.FILING); + assertPermissionsWithInheritance(user8, subCategory, folder, record, + AccessStatus.ALLOWED, // fileplan read + AccessStatus.DENIED, // fileplan file + AccessStatus.ALLOWED, // transfer read + AccessStatus.DENIED, // transfer file + AccessStatus.ALLOWED, // holds read + AccessStatus.DENIED, // holds file + AccessStatus.ALLOWED, // unfiled records file + AccessStatus.DENIED, // unfiled records file + AccessStatus.DENIED, // root category read + AccessStatus.DENIED, // root category file + AccessStatus.DENIED, // sub category read + AccessStatus.DENIED, // sub category file + AccessStatus.DENIED, // folder read + AccessStatus.DENIED, // folder file + AccessStatus.ALLOWED, // record read + AccessStatus.ALLOWED); // record file + } + + public void testAccessPermissionOnSingleRecordWithSeveralUsers() + { + final NodeRef subCategory = filePlanService.createRecordCategory(rmContainer, "subCategory3"); + final NodeRef folder = recordFolderService.createRecordFolder(subCategory, "rmFolder3"); + final NodeRef record = utils.createRecord(folder, "record3.txt"); + + String user1 = createTestUser(); + String user2 = createTestUser(); + + setPermission(rmContainer, user1, RMPermissionModel.READ_RECORDS); + + // user1 will have access to file plan, root category and because of inheritance sub category, folder and record + doTestInTransaction(new Test() + { + @Override + public Void run() + { + assertEquals(AccessStatus.ALLOWED, permissionService.hasPermission(filePlan, RMPermissionModel.READ_RECORDS)); + assertEquals(AccessStatus.ALLOWED, permissionService.hasPermission(rmContainer, RMPermissionModel.READ_RECORDS)); + assertEquals(AccessStatus.ALLOWED, permissionService.hasPermission(subCategory, RMPermissionModel.READ_RECORDS)); + assertEquals(AccessStatus.ALLOWED, permissionService.hasPermission(folder, RMPermissionModel.READ_RECORDS)); + assertEquals(AccessStatus.ALLOWED, permissionService.hasPermission(record, RMPermissionModel.READ_RECORDS)); + + return null; + } + }, user1); + + // user2 will have access to file plan + doTestInTransaction(new Test() + { + @Override + public Void run() + { + assertEquals(AccessStatus.ALLOWED, permissionService.hasPermission(filePlan, RMPermissionModel.READ_RECORDS)); + assertEquals(AccessStatus.DENIED, permissionService.hasPermission(rmContainer, RMPermissionModel.READ_RECORDS)); + assertEquals(AccessStatus.DENIED, permissionService.hasPermission(subCategory, RMPermissionModel.READ_RECORDS)); + assertEquals(AccessStatus.DENIED, permissionService.hasPermission(folder, RMPermissionModel.READ_RECORDS)); + assertEquals(AccessStatus.DENIED, permissionService.hasPermission(record, RMPermissionModel.READ_RECORDS)); + + return null; + } + }, user2); + } + + public void testDenyPermissionsOnRecordsWithSeveralUsers() + { + final NodeRef subCategory = filePlanService.createRecordCategory(rmContainer, "subCategory4"); + final NodeRef folder = recordFolderService.createRecordFolder(subCategory, "rmFolder4"); + final NodeRef record4 = utils.createRecord(folder, "record4.txt"); + final NodeRef record5 = utils.createRecord(folder, "record5.txt"); + + String user1 = createTestUser(); + String user2 = createTestUser(); + + setPermission(rmContainer, user1, RMPermissionModel.READ_RECORDS); + setPermission(rmContainer, user2, RMPermissionModel.READ_RECORDS); + + permissionService.setInheritParentPermissions(record4, false); + permissionService.setInheritParentPermissions(record5, false); + + setPermission(record4, user1, RMPermissionModel.READ_RECORDS); + setPermission(record5, user1, RMPermissionModel.READ_RECORDS); + + // user1 will have access to file plan, root category and because of inheritance sub category, folder, record4 and record5 + doTestInTransaction(new Test() + { + @Override + public Void run() + { + assertEquals(AccessStatus.ALLOWED, permissionService.hasPermission(filePlan, RMPermissionModel.READ_RECORDS)); + assertEquals(AccessStatus.ALLOWED, permissionService.hasPermission(rmContainer, RMPermissionModel.READ_RECORDS)); + assertEquals(AccessStatus.ALLOWED, permissionService.hasPermission(subCategory, RMPermissionModel.READ_RECORDS)); + assertEquals(AccessStatus.ALLOWED, permissionService.hasPermission(folder, RMPermissionModel.READ_RECORDS)); + assertEquals(AccessStatus.ALLOWED, permissionService.hasPermission(record4, RMPermissionModel.READ_RECORDS)); + assertEquals(AccessStatus.ALLOWED, permissionService.hasPermission(record5, RMPermissionModel.READ_RECORDS)); + + return null; + } + }, user1); + + // user2 will have access to file plan, root category and because of inheritance sub category and folder + // user2 won't have access to the records as the inheritance is set to false + doTestInTransaction(new Test() + { + @Override + public Void run() + { + assertEquals(AccessStatus.ALLOWED, permissionService.hasPermission(filePlan, RMPermissionModel.READ_RECORDS)); + assertEquals(AccessStatus.ALLOWED, permissionService.hasPermission(rmContainer, RMPermissionModel.READ_RECORDS)); + assertEquals(AccessStatus.ALLOWED, permissionService.hasPermission(subCategory, RMPermissionModel.READ_RECORDS)); + assertEquals(AccessStatus.ALLOWED, permissionService.hasPermission(folder, RMPermissionModel.READ_RECORDS)); + assertEquals(AccessStatus.DENIED, permissionService.hasPermission(record4, RMPermissionModel.READ_RECORDS)); + assertEquals(AccessStatus.DENIED, permissionService.hasPermission(record5, RMPermissionModel.READ_RECORDS)); + + return null; + } + }, user2); + } + + public void testMoveRootCategoryIntoAnotherRootCategory() + { + final NodeRef category5 = filePlanService.createRecordCategory(filePlan, "category5"); + final NodeRef category6 = filePlanService.createRecordCategory(filePlan, "category6"); + + assertFalse(permissionService.getInheritParentPermissions(category5)); + assertFalse(permissionService.getInheritParentPermissions(category6)); + + final String user1 = createTestUser(); + final String user2 = createTestUser(); + + setPermission(category5, user1, RMPermissionModel.READ_RECORDS); + setPermission(category6, user2, RMPermissionModel.FILING); + + doTestInTransaction(new Test() + { + @Override + public Void run() + { + assertEquals(AccessStatus.ALLOWED, permissionService.hasPermission(category5, RMPermissionModel.READ_RECORDS)); + assertEquals(AccessStatus.DENIED, permissionService.hasPermission(category5, RMPermissionModel.FILING)); + assertEquals(AccessStatus.DENIED, permissionService.hasPermission(category6, RMPermissionModel.READ_RECORDS)); + assertEquals(AccessStatus.DENIED, permissionService.hasPermission(category6, RMPermissionModel.FILING)); + + return null; + } + }, user1); + + doTestInTransaction(new Test() + { + @Override + public Void run() + { + assertEquals(AccessStatus.DENIED, permissionService.hasPermission(category5, RMPermissionModel.READ_RECORDS)); + assertEquals(AccessStatus.DENIED, permissionService.hasPermission(category5, RMPermissionModel.FILING)); + assertEquals(AccessStatus.ALLOWED, permissionService.hasPermission(category6, RMPermissionModel.READ_RECORDS)); + assertEquals(AccessStatus.ALLOWED, permissionService.hasPermission(category6, RMPermissionModel.FILING)); + + return null; + } + }, user2); + + final NodeRef movedCategory5 = doTestInTransaction(new Test() + { + @Override + public NodeRef run() throws Exception + { + return fileFolderService.move(category5, category6, null).getNodeRef(); + } + }); + + assertFalse(permissionService.getInheritParentPermissions(movedCategory5)); + assertFalse(permissionService.getInheritParentPermissions(category6)); + + doTestInTransaction(new Test() + { + @Override + public Void run() + { + assertEquals(AccessStatus.ALLOWED, permissionService.hasPermission(movedCategory5, RMPermissionModel.READ_RECORDS)); + assertEquals(AccessStatus.DENIED, permissionService.hasPermission(movedCategory5, RMPermissionModel.FILING)); + assertEquals(AccessStatus.DENIED, permissionService.hasPermission(category6, RMPermissionModel.READ_RECORDS)); + assertEquals(AccessStatus.DENIED, permissionService.hasPermission(category6, RMPermissionModel.FILING)); + + return null; + } + }, user1); + + doTestInTransaction(new Test() + { + @Override + public Void run() + { + assertEquals(AccessStatus.DENIED, permissionService.hasPermission(movedCategory5, RMPermissionModel.READ_RECORDS)); + assertEquals(AccessStatus.DENIED, permissionService.hasPermission(movedCategory5, RMPermissionModel.FILING)); + assertEquals(AccessStatus.ALLOWED, permissionService.hasPermission(category6, RMPermissionModel.READ_RECORDS)); + assertEquals(AccessStatus.ALLOWED, permissionService.hasPermission(category6, RMPermissionModel.FILING)); + + return null; + } + }, user2); + } + + public void testPermissionsForMovedRecord() + { + final NodeRef category7 = filePlanService.createRecordCategory(filePlan, "category7"); + final NodeRef folder7 = recordFolderService.createRecordFolder(category7, "rmFolder7"); + final NodeRef record7 = utils.createRecord(folder7, "record7.txt"); + + final NodeRef category8 = filePlanService.createRecordCategory(filePlan, "category8"); + final NodeRef folder8 = recordFolderService.createRecordFolder(category8, "rmFolder8"); + final NodeRef record8 = utils.createRecord(folder8, "record8.txt"); + + final String user1 = createTestUser(); + final String user2 = createTestUser(); + final String user3 = createTestUser(); + + setPermission(folder7, user1, RMPermissionModel.FILING); + setPermission(record8, user2, RMPermissionModel.READ_RECORDS); + setPermission(category7, user3, RMPermissionModel.FILING); + + doTestInTransaction(new Test() + { + @Override + public Void run() + { + assertEquals(AccessStatus.DENIED, permissionService.hasPermission(category7, RMPermissionModel.READ_RECORDS)); + assertEquals(AccessStatus.DENIED, permissionService.hasPermission(category7, RMPermissionModel.FILING)); + assertEquals(AccessStatus.ALLOWED, permissionService.hasPermission(folder7, RMPermissionModel.READ_RECORDS)); + assertEquals(AccessStatus.ALLOWED, permissionService.hasPermission(folder7, RMPermissionModel.FILING)); + assertEquals(AccessStatus.ALLOWED, permissionService.hasPermission(record7, RMPermissionModel.READ_RECORDS)); + assertEquals(AccessStatus.ALLOWED, permissionService.hasPermission(record7, RMPermissionModel.FILING)); + + assertEquals(AccessStatus.DENIED, permissionService.hasPermission(category8, RMPermissionModel.READ_RECORDS)); + assertEquals(AccessStatus.DENIED, permissionService.hasPermission(category8, RMPermissionModel.FILING)); + assertEquals(AccessStatus.DENIED, permissionService.hasPermission(folder8, RMPermissionModel.READ_RECORDS)); + assertEquals(AccessStatus.DENIED, permissionService.hasPermission(folder8, RMPermissionModel.FILING)); + assertEquals(AccessStatus.DENIED, permissionService.hasPermission(record8, RMPermissionModel.READ_RECORDS)); + assertEquals(AccessStatus.DENIED, permissionService.hasPermission(record8, RMPermissionModel.FILING)); + + return null; + } + }, user1); + + doTestInTransaction(new Test() + { + @Override + public Void run() + { + assertEquals(AccessStatus.DENIED, permissionService.hasPermission(category7, RMPermissionModel.READ_RECORDS)); + assertEquals(AccessStatus.DENIED, permissionService.hasPermission(category7, RMPermissionModel.FILING)); + assertEquals(AccessStatus.DENIED, permissionService.hasPermission(folder7, RMPermissionModel.READ_RECORDS)); + assertEquals(AccessStatus.DENIED, permissionService.hasPermission(folder7, RMPermissionModel.FILING)); + assertEquals(AccessStatus.DENIED, permissionService.hasPermission(record7, RMPermissionModel.READ_RECORDS)); + assertEquals(AccessStatus.DENIED, permissionService.hasPermission(record7, RMPermissionModel.FILING)); + + assertEquals(AccessStatus.DENIED, permissionService.hasPermission(category8, RMPermissionModel.READ_RECORDS)); + assertEquals(AccessStatus.DENIED, permissionService.hasPermission(category8, RMPermissionModel.FILING)); + assertEquals(AccessStatus.DENIED, permissionService.hasPermission(folder8, RMPermissionModel.READ_RECORDS)); + assertEquals(AccessStatus.DENIED, permissionService.hasPermission(folder8, RMPermissionModel.FILING)); + assertEquals(AccessStatus.ALLOWED, permissionService.hasPermission(record8, RMPermissionModel.READ_RECORDS)); + assertEquals(AccessStatus.DENIED, permissionService.hasPermission(record8, RMPermissionModel.FILING)); + + return null; + } + }, user2); + + doTestInTransaction(new Test() + { + @Override + public Void run() + { + assertEquals(AccessStatus.ALLOWED, permissionService.hasPermission(category7, RMPermissionModel.READ_RECORDS)); + assertEquals(AccessStatus.ALLOWED, permissionService.hasPermission(category7, RMPermissionModel.FILING)); + assertEquals(AccessStatus.ALLOWED, permissionService.hasPermission(folder7, RMPermissionModel.READ_RECORDS)); + assertEquals(AccessStatus.ALLOWED, permissionService.hasPermission(folder7, RMPermissionModel.FILING)); + assertEquals(AccessStatus.ALLOWED, permissionService.hasPermission(record7, RMPermissionModel.READ_RECORDS)); + assertEquals(AccessStatus.ALLOWED, permissionService.hasPermission(record7, RMPermissionModel.FILING)); + + assertEquals(AccessStatus.DENIED, permissionService.hasPermission(category8, RMPermissionModel.READ_RECORDS)); + assertEquals(AccessStatus.DENIED, permissionService.hasPermission(category8, RMPermissionModel.FILING)); + assertEquals(AccessStatus.DENIED, permissionService.hasPermission(folder8, RMPermissionModel.READ_RECORDS)); + assertEquals(AccessStatus.DENIED, permissionService.hasPermission(folder8, RMPermissionModel.FILING)); + assertEquals(AccessStatus.DENIED, permissionService.hasPermission(record8, RMPermissionModel.READ_RECORDS)); + assertEquals(AccessStatus.DENIED, permissionService.hasPermission(record8, RMPermissionModel.FILING)); + + return null; + } + }, user3); + + final NodeRef movedRecord8 = doTestInTransaction(new Test() + { + @Override + public NodeRef run() throws Exception + { + return fileFolderService.move(record8, folder7, null).getNodeRef(); + } + }); + + doTestInTransaction(new Test() + { + @Override + public Void run() + { + assertEquals(AccessStatus.DENIED, permissionService.hasPermission(category7, RMPermissionModel.READ_RECORDS)); + assertEquals(AccessStatus.DENIED, permissionService.hasPermission(category7, RMPermissionModel.FILING)); + assertEquals(AccessStatus.ALLOWED, permissionService.hasPermission(folder7, RMPermissionModel.READ_RECORDS)); + assertEquals(AccessStatus.ALLOWED, permissionService.hasPermission(folder7, RMPermissionModel.FILING)); + assertEquals(AccessStatus.ALLOWED, permissionService.hasPermission(record7, RMPermissionModel.READ_RECORDS)); + assertEquals(AccessStatus.ALLOWED, permissionService.hasPermission(record7, RMPermissionModel.FILING)); + + assertEquals(AccessStatus.DENIED, permissionService.hasPermission(category8, RMPermissionModel.READ_RECORDS)); + assertEquals(AccessStatus.DENIED, permissionService.hasPermission(category8, RMPermissionModel.FILING)); + assertEquals(AccessStatus.DENIED, permissionService.hasPermission(folder8, RMPermissionModel.READ_RECORDS)); + assertEquals(AccessStatus.DENIED, permissionService.hasPermission(folder8, RMPermissionModel.FILING)); + assertEquals(AccessStatus.ALLOWED, permissionService.hasPermission(movedRecord8, RMPermissionModel.READ_RECORDS)); + assertEquals(AccessStatus.ALLOWED, permissionService.hasPermission(movedRecord8, RMPermissionModel.FILING)); + + return null; + } + }, user1); + + doTestInTransaction(new Test() + { + @Override + public Void run() + { + assertEquals(AccessStatus.DENIED, permissionService.hasPermission(category7, RMPermissionModel.READ_RECORDS)); + assertEquals(AccessStatus.DENIED, permissionService.hasPermission(category7, RMPermissionModel.FILING)); + assertEquals(AccessStatus.DENIED, permissionService.hasPermission(folder7, RMPermissionModel.READ_RECORDS)); + assertEquals(AccessStatus.DENIED, permissionService.hasPermission(folder7, RMPermissionModel.FILING)); + assertEquals(AccessStatus.DENIED, permissionService.hasPermission(record7, RMPermissionModel.READ_RECORDS)); + assertEquals(AccessStatus.DENIED, permissionService.hasPermission(record7, RMPermissionModel.FILING)); + + assertEquals(AccessStatus.DENIED, permissionService.hasPermission(category8, RMPermissionModel.READ_RECORDS)); + assertEquals(AccessStatus.DENIED, permissionService.hasPermission(category8, RMPermissionModel.FILING)); + assertEquals(AccessStatus.DENIED, permissionService.hasPermission(folder8, RMPermissionModel.READ_RECORDS)); + assertEquals(AccessStatus.DENIED, permissionService.hasPermission(folder8, RMPermissionModel.FILING)); + assertEquals(AccessStatus.ALLOWED, permissionService.hasPermission(movedRecord8, RMPermissionModel.READ_RECORDS)); + assertEquals(AccessStatus.DENIED, permissionService.hasPermission(movedRecord8, RMPermissionModel.FILING)); + + return null; + } + }, user2); + + doTestInTransaction(new Test() + { + @Override + public Void run() + { + assertEquals(AccessStatus.ALLOWED, permissionService.hasPermission(category7, RMPermissionModel.READ_RECORDS)); + assertEquals(AccessStatus.ALLOWED, permissionService.hasPermission(category7, RMPermissionModel.FILING)); + assertEquals(AccessStatus.ALLOWED, permissionService.hasPermission(folder7, RMPermissionModel.READ_RECORDS)); + assertEquals(AccessStatus.ALLOWED, permissionService.hasPermission(folder7, RMPermissionModel.FILING)); + assertEquals(AccessStatus.ALLOWED, permissionService.hasPermission(record7, RMPermissionModel.READ_RECORDS)); + assertEquals(AccessStatus.ALLOWED, permissionService.hasPermission(record7, RMPermissionModel.FILING)); + + assertEquals(AccessStatus.DENIED, permissionService.hasPermission(category8, RMPermissionModel.READ_RECORDS)); + assertEquals(AccessStatus.DENIED, permissionService.hasPermission(category8, RMPermissionModel.FILING)); + assertEquals(AccessStatus.DENIED, permissionService.hasPermission(folder8, RMPermissionModel.READ_RECORDS)); + assertEquals(AccessStatus.DENIED, permissionService.hasPermission(folder8, RMPermissionModel.FILING)); + assertEquals(AccessStatus.ALLOWED, permissionService.hasPermission(movedRecord8, RMPermissionModel.READ_RECORDS)); + assertEquals(AccessStatus.ALLOWED, permissionService.hasPermission(movedRecord8, RMPermissionModel.FILING)); + + return null; + } + }, user3); + } + + public void testSpecialRoles() + { + final NodeRef category9 = filePlanService.createRecordCategory(filePlan, "category9"); + final NodeRef subCategory9 = filePlanService.createRecordCategory(category9, "subCategory9"); + final NodeRef folder9 = recordFolderService.createRecordFolder(subCategory9, "rmFolder9"); + final NodeRef record9 = utils.createRecord(folder9, "record9.txt"); + + assertExistenceOfSpecialRolesAndPermissions(category9); + + assertExistenceOfSpecialRolesAndPermissions(subCategory9); + // After setting the permissions off the special roles should be still available as they will be added to the node automatically + permissionService.setInheritParentPermissions(subCategory9, false); + assertExistenceOfSpecialRolesAndPermissions(subCategory9); + permissionService.setInheritParentPermissions(subCategory9, true); + assertExistenceOfSpecialRolesAndPermissions(subCategory9); + + assertExistenceOfSpecialRolesAndPermissions(folder9); + permissionService.setInheritParentPermissions(folder9, false); + assertExistenceOfSpecialRolesAndPermissions(folder9); + permissionService.setInheritParentPermissions(folder9, true); + assertExistenceOfSpecialRolesAndPermissions(folder9); + + assertExistenceOfSpecialRolesAndPermissions(record9); + permissionService.setInheritParentPermissions(record9, false); + assertExistenceOfSpecialRolesAndPermissions(record9); + permissionService.setInheritParentPermissions(record9, true); + assertExistenceOfSpecialRolesAndPermissions(record9); + } + + private void assertExistenceOfSpecialRolesAndPermissions(NodeRef node) + { + Map accessPermissions = new HashMap(); + Set permissions = permissionService.getAllSetPermissions(node); + // FIXME!!! + //assertEquals(3, permissions.size()); + + for (AccessPermission permission : permissions) + { + accessPermissions.put(permission.getAuthority(), permission.getPermission()); + } + + assertTrue(accessPermissions.containsKey(ExtendedReaderDynamicAuthority.EXTENDED_READER)); + assertEquals(RMPermissionModel.READ_RECORDS, accessPermissions.get(ExtendedReaderDynamicAuthority.EXTENDED_READER)); + assertTrue(accessPermissions.containsKey(ExtendedWriterDynamicAuthority.EXTENDED_WRITER)); + assertEquals(RMPermissionModel.FILING, accessPermissions.get(ExtendedWriterDynamicAuthority.EXTENDED_WRITER)); + String adminRole = authorityService.getName(AuthorityType.GROUP, FilePlanRoleService.ROLE_ADMIN + filePlan.getId()); + assertTrue(accessPermissions.containsKey(adminRole)); + assertEquals(RMPermissionModel.FILING, accessPermissions.get(adminRole)); + } } diff --git a/rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/legacy/service/FilePlanRoleServiceImplTest.java b/rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/legacy/service/FilePlanRoleServiceImplTest.java index 65ada7ee86..6a8cdaee53 100644 --- a/rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/legacy/service/FilePlanRoleServiceImplTest.java +++ b/rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/legacy/service/FilePlanRoleServiceImplTest.java @@ -107,9 +107,9 @@ public class FilePlanRoleServiceImplTest extends BaseRMTestCase { public Void run() { - Role role = filePlanRoleService.getRole(filePlan, ROLE_NAME_POWER_USER); + Role role = filePlanRoleService.getRole(filePlan, FilePlanRoleService.ROLE_POWER_USER); assertNotNull(role); - assertEquals(ROLE_NAME_POWER_USER, role.getName()); + assertEquals(FilePlanRoleService.ROLE_POWER_USER, role.getName()); role = filePlanRoleService.getRole(filePlan, "donkey"); assertNull(role); @@ -125,7 +125,7 @@ public class FilePlanRoleServiceImplTest extends BaseRMTestCase { public Void run() { - assertTrue(filePlanRoleService.existsRole(filePlan, ROLE_NAME_POWER_USER)); + assertTrue(filePlanRoleService.existsRole(filePlan, FilePlanRoleService.ROLE_POWER_USER)); assertFalse(filePlanRoleService.existsRole(filePlan, "donkey")); return null; @@ -184,33 +184,33 @@ public class FilePlanRoleServiceImplTest extends BaseRMTestCase assertNotNull(roles); assertEquals(1, roles.size()); - Set authorities = filePlanRoleService.getUsersAssignedToRole(filePlan, ROLE_NAME_RECORDS_MANAGER); + Set authorities = filePlanRoleService.getUsersAssignedToRole(filePlan, FilePlanRoleService.ROLE_RECORDS_MANAGER); assertNotNull(authorities); assertEquals(1, authorities.size()); - authorities = filePlanRoleService.getGroupsAssignedToRole(filePlan, ROLE_NAME_RECORDS_MANAGER); + authorities = filePlanRoleService.getGroupsAssignedToRole(filePlan, FilePlanRoleService.ROLE_RECORDS_MANAGER); assertNotNull(authorities); assertEquals(0, authorities.size()); - authorities = filePlanRoleService.getAllAssignedToRole(filePlan, ROLE_NAME_RECORDS_MANAGER); + authorities = filePlanRoleService.getAllAssignedToRole(filePlan, FilePlanRoleService.ROLE_RECORDS_MANAGER); assertNotNull(authorities); assertEquals(1, authorities.size()); - filePlanRoleService.assignRoleToAuthority(filePlan, ROLE_NAME_RECORDS_MANAGER, rmUserName); + filePlanRoleService.assignRoleToAuthority(filePlan, FilePlanRoleService.ROLE_RECORDS_MANAGER, rmUserName); roles = filePlanRoleService.getRolesByUser(filePlan, rmUserName); assertNotNull(roles); assertEquals(2, roles.size()); - authorities = filePlanRoleService.getUsersAssignedToRole(filePlan, ROLE_NAME_RECORDS_MANAGER); + authorities = filePlanRoleService.getUsersAssignedToRole(filePlan, FilePlanRoleService.ROLE_RECORDS_MANAGER); assertNotNull(authorities); assertEquals(2, authorities.size()); - authorities = filePlanRoleService.getGroupsAssignedToRole(filePlan, ROLE_NAME_RECORDS_MANAGER); + authorities = filePlanRoleService.getGroupsAssignedToRole(filePlan, FilePlanRoleService.ROLE_RECORDS_MANAGER); assertNotNull(authorities); assertEquals(0, authorities.size()); - authorities = filePlanRoleService.getAllAssignedToRole(filePlan, ROLE_NAME_RECORDS_MANAGER); + authorities = filePlanRoleService.getAllAssignedToRole(filePlan, FilePlanRoleService.ROLE_RECORDS_MANAGER); assertNotNull(authorities); assertEquals(2, authorities.size()); diff --git a/rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/legacy/service/RecordServiceImplTest.java b/rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/legacy/service/RecordServiceImplTest.java index 57204a8ea1..14f5ffa379 100644 --- a/rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/legacy/service/RecordServiceImplTest.java +++ b/rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/legacy/service/RecordServiceImplTest.java @@ -272,10 +272,12 @@ public class RecordServiceImplTest extends BaseRMTestCase // create record from document doTestInTransaction(new Test() { + private NodeRef originalLocation; + @Override public Void run() { - NodeRef originalLocation = nodeService.getPrimaryParent(dmDocument).getParentRef(); + originalLocation = nodeService.getPrimaryParent(dmDocument).getParentRef(); assertFalse(recordService.isRecord(dmDocument)); assertFalse(extendedSecurityService.hasExtendedSecurity(dmDocument)); @@ -297,6 +299,11 @@ public class RecordServiceImplTest extends BaseRMTestCase recordService.createRecord(filePlan, dmDocument); + return null; + } + + public void test(Void result) + { checkPermissions(READ_RECORDS, AccessStatus.ALLOWED, // file // plan AccessStatus.ALLOWED, // unfiled container @@ -345,8 +352,6 @@ public class RecordServiceImplTest extends BaseRMTestCase Capability updateProperties = capabilityService.getCapability("UpdateProperties"); assertEquals(AccessStatus.ALLOWED, updateProperties.hasPermission(dmDocument)); - - return null; } }, dmCollaborator); diff --git a/rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/legacy/service/RecordsManagementSearchServiceImplTest.java b/rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/legacy/service/RecordsManagementSearchServiceImplTest.java index 26b70f2f28..299b975b28 100644 --- a/rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/legacy/service/RecordsManagementSearchServiceImplTest.java +++ b/rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/legacy/service/RecordsManagementSearchServiceImplTest.java @@ -25,7 +25,7 @@ import org.alfresco.module.org_alfresco_module_rm.search.SavedSearchDetails; import org.alfresco.module.org_alfresco_module_rm.test.util.BaseRMTestCase; import org.alfresco.repo.security.authentication.AuthenticationUtil; import org.alfresco.service.cmr.repository.NodeRef; -import org.alfresco.service.cmr.security.MutableAuthenticationService; +import org.alfresco.util.Pair; import org.alfresco.util.TestWithUserUtils; /** @@ -148,7 +148,7 @@ public class RecordsManagementSearchServiceImplTest extends BaseRMTestCase // String query = "keywords:\"elephant\""; // RecordsManagementSearchParameters params = new RecordsManagementSearchParameters(); // params.setIncludeUndeclaredRecords(true); -// List results = rmSearchService.search(siteId, query, params); +// List> results = rmSearchService.search(siteId, query, params); // assertNotNull(results); // assertEquals(2, results.size()); // diff --git a/rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/system/DataLoadSystemTest.java b/rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/system/DataLoadSystemTest.java index 98e2a09507..a16befc493 100644 --- a/rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/system/DataLoadSystemTest.java +++ b/rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/system/DataLoadSystemTest.java @@ -6,6 +6,7 @@ import java.util.HashMap; import java.util.List; import java.util.Map; +import org.alfresco.error.AlfrescoRuntimeException; import org.alfresco.model.ContentModel; import org.alfresco.module.org_alfresco_module_rm.fileplan.FilePlanService; import org.alfresco.module.org_alfresco_module_rm.record.RecordService; @@ -117,7 +118,7 @@ public class DataLoadSystemTest final SiteInfo site = siteService.getSite("test"); if (site == null) { - Assert.fail("The collab site test is not present."); + throw new AlfrescoRuntimeException("The collab site test is not present."); } final NodeRef filePlan = filePlanService.getFilePlanBySiteId(FilePlanService.DEFAULT_RM_SITE_ID); @@ -146,7 +147,6 @@ public class DataLoadSystemTest // create content and declare as record repeatInTransactionBatches(new RunAsWork() { - @SuppressWarnings("null") public Void doWork() throws Exception { // create document diff --git a/rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/util/BaseRMTestCase.java b/rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/util/BaseRMTestCase.java index 54d4ade864..ab2da29b56 100644 --- a/rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/util/BaseRMTestCase.java +++ b/rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/util/BaseRMTestCase.java @@ -173,6 +173,8 @@ public abstract class BaseRMTestCase extends RetryingTransactionHelperTestCase protected NodeRef rmFolder; protected NodeRef unfiledContainer; protected String collabSiteId; + protected NodeRef holdsContainer; + protected NodeRef transfersContainer; /** multi-hierarchy test data * @@ -506,6 +508,14 @@ public abstract class BaseRMTestCase extends RetryingTransactionHelperTestCase // unfiled container unfiledContainer = filePlanService.getUnfiledContainer(filePlan); assertNotNull(unfiledContainer); + + // holds container + holdsContainer = filePlanService.getHoldContainer(filePlan); + assertNotNull(holdsContainer); + + // transfers container + transfersContainer = filePlanService.getTransferContainer(filePlan); + assertNotNull(transfersContainer); } } }, AuthenticationUtil.getSystemUserName()); diff --git a/rm-server/unit-test/java/org/alfresco/module/org_alfresco_module_rm/record/RecordServiceImplUnitTest.java b/rm-server/unit-test/java/org/alfresco/module/org_alfresco_module_rm/record/RecordServiceImplUnitTest.java index a7c0d38e8a..72e7fd7ee3 100755 --- a/rm-server/unit-test/java/org/alfresco/module/org_alfresco_module_rm/record/RecordServiceImplUnitTest.java +++ b/rm-server/unit-test/java/org/alfresco/module/org_alfresco_module_rm/record/RecordServiceImplUnitTest.java @@ -36,43 +36,41 @@ import org.mockito.InjectMocks; /** * Unit test for RecordServiceImpl - * + * * @author Roy Wetherall * @since 2.2 */ public class RecordServiceImplUnitTest extends BaseUnitTest -{ +{ private NodeRef nonStandardFilePlanComponent; private NodeRef nonStandardFilePlan; - + private static QName TYPE_MY_FILE_PLAN = generateQName(); private static QName ASPECT_FOR_FILE_PLAN = generateQName(); - private static QName ASPECT_FOR_MY_FILE_PLAN = generateQName(); - private static QName ASPECT_FOR_BOTH = generateQName(); - + @InjectMocks private RecordServiceImpl recordService; - + @SuppressWarnings("unchecked") @Before @Override public void before() throws Exception { super.before(); - + nonStandardFilePlanComponent = generateNodeRef(TYPE_RECORD_CATEGORY); nonStandardFilePlan = generateNodeRef(TYPE_MY_FILE_PLAN); - - // set-up node service + + // set-up node service when(mockedNodeService.getProperty(nonStandardFilePlanComponent, PROP_ROOT_NODEREF)).thenReturn(nonStandardFilePlan); - + // set-up dictionary service when(mockedDictionaryService.getAllAspects()).thenReturn(CollectionUtils.EMPTY_COLLECTION); } - - @Test + + @Test public void testRegisterRecordMetadataAspect() { - Map> map = recordService.getRecordMetadataAspectsMap(); + Map> map = recordService.getRecordMetadataAspectsMap(); assertTrue(map.isEmpty()); recordService.registerRecordMetadataAspect(ASPECT_FOR_FILE_PLAN, TYPE_FILE_PLAN); map = recordService.getRecordMetadataAspectsMap(); @@ -83,39 +81,4 @@ public class RecordServiceImplUnitTest extends BaseUnitTest assertEquals(1, types.size()); assertTrue(types.contains(TYPE_FILE_PLAN)); } - - @Test - public void testGetRecordMetadataAspects() - { - // register a couple of record meta-data aspects - recordService.registerRecordMetadataAspect(ASPECT_FOR_FILE_PLAN, TYPE_FILE_PLAN); - recordService.registerRecordMetadataAspect(ASPECT_FOR_MY_FILE_PLAN, TYPE_MY_FILE_PLAN); - recordService.registerRecordMetadataAspect(ASPECT_FOR_BOTH, TYPE_FILE_PLAN); - recordService.registerRecordMetadataAspect(ASPECT_FOR_BOTH, TYPE_MY_FILE_PLAN); - - Set set = recordService.getRecordMetadataAspects(filePlanComponent); - assertNotNull(set); - assertEquals(2, set.size()); - assertTrue(set.contains(ASPECT_FOR_FILE_PLAN)); - assertTrue(set.contains(ASPECT_FOR_BOTH)); - - set = recordService.getRecordMetadataAspects(nonStandardFilePlanComponent); - assertNotNull(set); - assertEquals(2, set.size()); - assertTrue(set.contains(ASPECT_FOR_MY_FILE_PLAN)); - assertTrue(set.contains(ASPECT_FOR_BOTH)); - - set = recordService.getRecordMetadataAspects(TYPE_FILE_PLAN); - assertNotNull(set); - assertEquals(2, set.size()); - assertTrue(set.contains(ASPECT_FOR_FILE_PLAN)); - assertTrue(set.contains(ASPECT_FOR_BOTH)); - - set = recordService.getRecordMetadataAspects(TYPE_MY_FILE_PLAN); - assertNotNull(set); - assertEquals(2, set.size()); - assertTrue(set.contains(ASPECT_FOR_MY_FILE_PLAN)); - assertTrue(set.contains(ASPECT_FOR_BOTH)); - - } }