diff --git a/rm-server/config/alfresco/module/org_alfresco_module_rm/capability/rm-capabilities-condition-context.xml b/rm-server/config/alfresco/module/org_alfresco_module_rm/capability/rm-capabilities-condition-context.xml index 4ff50f11c4..408cbbf617 100644 --- a/rm-server/config/alfresco/module/org_alfresco_module_rm/capability/rm-capabilities-condition-context.xml +++ b/rm-server/config/alfresco/module/org_alfresco_module_rm/capability/rm-capabilities-condition-context.xml @@ -14,17 +14,20 @@ + + + + + + \ No newline at end of file diff --git a/rm-server/config/alfresco/module/org_alfresco_module_rm/capability/rm-capabilities-freeze-context.xml b/rm-server/config/alfresco/module/org_alfresco_module_rm/capability/rm-capabilities-freeze-context.xml index 1492b420ba..8db7ba051b 100644 --- a/rm-server/config/alfresco/module/org_alfresco_module_rm/capability/rm-capabilities-freeze-context.xml +++ b/rm-server/config/alfresco/module/org_alfresco_module_rm/capability/rm-capabilities-freeze-context.xml @@ -11,12 +11,13 @@ + FILE_PLAN HOLD_CONTAINER - + diff --git a/rm-server/config/alfresco/module/org_alfresco_module_rm/capability/rm-capabilities-security-context.xml b/rm-server/config/alfresco/module/org_alfresco_module_rm/capability/rm-capabilities-security-context.xml index 60ca183ea8..c8a93a897b 100644 --- a/rm-server/config/alfresco/module/org_alfresco_module_rm/capability/rm-capabilities-security-context.xml +++ b/rm-server/config/alfresco/module/org_alfresco_module_rm/capability/rm-capabilities-security-context.xml @@ -22,7 +22,7 @@ - + @@ -31,13 +31,13 @@ + - diff --git a/rm-server/config/alfresco/module/org_alfresco_module_rm/module-context.xml b/rm-server/config/alfresco/module/org_alfresco_module_rm/module-context.xml index aa17145c97..0a656298a5 100644 --- a/rm-server/config/alfresco/module/org_alfresco_module_rm/module-context.xml +++ b/rm-server/config/alfresco/module/org_alfresco_module_rm/module-context.xml @@ -5,6 +5,12 @@ + + + + + + diff --git a/rm-server/config/alfresco/module/org_alfresco_module_rm/rm-deprecated-context.xml b/rm-server/config/alfresco/module/org_alfresco_module_rm/rm-deprecated-context.xml index d472ccb460..7a855c5149 100644 --- a/rm-server/config/alfresco/module/org_alfresco_module_rm/rm-deprecated-context.xml +++ b/rm-server/config/alfresco/module/org_alfresco_module_rm/rm-deprecated-context.xml @@ -115,14 +115,14 @@ org.alfresco.module.org_alfresco_module_rm.RecordsManagementService.getNodeRefPath=RM.Read.0 org.alfresco.module.org_alfresco_module_rm.RecordsManagementService.getFilePlan=RM.Read.0,AFTER_RM.FilterNode org.alfresco.module.org_alfresco_module_rm.RecordsManagementService.getFilePlans=RM_ALLOW - org.alfresco.module.org_alfresco_module_rm.RecordsManagementService.createFilePlan=RM.WRITE.0 + org.alfresco.module.org_alfresco_module_rm.RecordsManagementService.createFilePlan=RM.Create.0 org.alfresco.module.org_alfresco_module_rm.RecordsManagementService.getAllContained=RM.Read.0,AFTER_RM.FilterNode org.alfresco.module.org_alfresco_module_rm.RecordsManagementService.getContainedRecordCategories=RM.Read.0,AFTER_RM.FilterNode org.alfresco.module.org_alfresco_module_rm.RecordsManagementService.getContainedRecordFolders=RM.Read.0,AFTER_RM.FilterNode - org.alfresco.module.org_alfresco_module_rm.RecordsManagementService.createRecordCategory=RM.Write.0 + org.alfresco.module.org_alfresco_module_rm.RecordsManagementService.createRecordCategory=RM.Create.0 org.alfresco.module.org_alfresco_module_rm.RecordsManagementService.isRecordFolderDeclared=RM.Read.0 org.alfresco.module.org_alfresco_module_rm.RecordsManagementService.isRecordFolderClosed=RM.Read.0 - org.alfresco.module.org_alfresco_module_rm.RecordsManagementService.createRecordFolder=RM.Write.0 + org.alfresco.module.org_alfresco_module_rm.RecordsManagementService.createRecordFolder=RM.Create.0 org.alfresco.module.org_alfresco_module_rm.RecordsManagementService.getRecords=RM.Read.0,AFTER_RM.FilterNode org.alfresco.module.org_alfresco_module_rm.RecordsManagementService.getRecordFolders=RM.Read.0,AFTER_RM.FilterNode org.alfresco.module.org_alfresco_module_rm.RecordsManagementService.getRecordMetaDataAspects=RM_ALLOW 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 b64ade5659..4ec6af98ed 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 @@ -96,7 +96,8 @@ depends-on="CapabilityService"> - + + 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 75b0792b6f..a0f6289c24 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 @@ -418,11 +418,11 @@ org.alfresco.module.org_alfresco_module_rm.fileplan.FilePlanService.getFilePlanBySiteId=RM_ALLOW,AFTER_RM.FilterNode org.alfresco.module.org_alfresco_module_rm.fileplan.FilePlanService.existsUnfiledContainer=RM.Read.0 org.alfresco.module.org_alfresco_module_rm.fileplan.FilePlanService.getUnfiledContainer=RM.Read.0,AFTER_RM.FilterNode - org.alfresco.module.org_alfresco_module_rm.fileplan.FilePlanService.createUnfiledContainer=RM.Write.0 + org.alfresco.module.org_alfresco_module_rm.fileplan.FilePlanService.createUnfiledContainer=RM.Create.0 org.alfresco.module.org_alfresco_module_rm.fileplan.FilePlanService.getHoldContainer=RM.Read.0,AFTER_RM.FilterNode - org.alfresco.module.org_alfresco_module_rm.fileplan.FilePlanService.createHoldContainer=RM.Write.0 + org.alfresco.module.org_alfresco_module_rm.fileplan.FilePlanService.createHoldContainer=RM.Create.0 org.alfresco.module.org_alfresco_module_rm.fileplan.FilePlanService.getTransferContainer=RM.Read.0,AFTER_RM.FilterNode - org.alfresco.module.org_alfresco_module_rm.fileplan.FilePlanService.createTransferContainer=RM.Write.0 + org.alfresco.module.org_alfresco_module_rm.fileplan.FilePlanService.createTransferContainer=RM.Create.0 org.alfresco.module.org_alfresco_module_rm.fileplan.FilePlanService.createFilePlan=RM_ALLOW org.alfresco.module.org_alfresco_module_rm.fileplan.FilePlanService.getNodeRefPath=RM.Read.0 org.alfresco.module.org_alfresco_module_rm.fileplan.FilePlanService.isFilePlanContainer=RM_ALLOW @@ -430,7 +430,7 @@ org.alfresco.module.org_alfresco_module_rm.fileplan.FilePlanService.getAllContained=RM.Read.0,AFTER_RM.FilterNode org.alfresco.module.org_alfresco_module_rm.fileplan.FilePlanService.getContainedRecordCategories=RM.Read.0,AFTER_RM.FilterNode org.alfresco.module.org_alfresco_module_rm.fileplan.FilePlanService.getContainedRecordFolders=RM.Read.0,AFTER_RM.FilterNode - org.alfresco.module.org_alfresco_module_rm.fileplan.FilePlanService.createRecordCategory=RM.Write.0 + org.alfresco.module.org_alfresco_module_rm.fileplan.FilePlanService.createRecordCategory=RM.Create.0 org.alfresco.module.org_alfresco_module_rm.fileplan.FilePlanService.*=RM_DENY ]]> @@ -538,8 +538,8 @@ @@ -1167,7 +1167,7 @@ @@ -1523,15 +1523,15 @@ org.alfresco.module.org_alfresco_module_rm.hold.HoldService.getHold=RM.Read.0,AFTER_RM.FilterNode org.alfresco.module.org_alfresco_module_rm.hold.HoldService.heldBy=RM.Read.0,AFTER_RM.FilterNode org.alfresco.module.org_alfresco_module_rm.hold.HoldService.getHeld=RM.Read.0,AFTER_RM.FilterNode - org.alfresco.module.org_alfresco_module_rm.hold.HoldService.createHold=RM.Read.0 + org.alfresco.module.org_alfresco_module_rm.hold.HoldService.createHold=RM_CAP.0.rma:filePlanComponent.CreateHold org.alfresco.module.org_alfresco_module_rm.hold.HoldService.getHoldReason=RM.Read.0 - org.alfresco.module.org_alfresco_module_rm.hold.HoldService.setHoldReason=RM.Write.0 - org.alfresco.module.org_alfresco_module_rm.hold.HoldService.deleteHold=RM.Write.0 - org.alfresco.module.org_alfresco_module_rm.hold.HoldService.addToHold=RM.Write.0 - org.alfresco.module.org_alfresco_module_rm.hold.HoldService.addToHolds=RM.Write.0 - org.alfresco.module.org_alfresco_module_rm.hold.HoldService.removeFromHold=RM.Write.0 - org.alfresco.module.org_alfresco_module_rm.hold.HoldService.removeFromHolds=RM.Write.0 - org.alfresco.module.org_alfresco_module_rm.hold.HoldService.removeFromAllHolds=RM.Write.0 + org.alfresco.module.org_alfresco_module_rm.hold.HoldService.setHoldReason=RM_CAP.0.rma:filePlanComponent.EditHold + org.alfresco.module.org_alfresco_module_rm.hold.HoldService.deleteHold=RM_CAP.0.rma:filePlanComponent.DeleteHold + org.alfresco.module.org_alfresco_module_rm.hold.HoldService.addToHold=RM_CAP.0.rma:filePlanComponent.AddToHold + org.alfresco.module.org_alfresco_module_rm.hold.HoldService.addToHolds=RM_CAP.0.rma:filePlanComponent.AddToHold + org.alfresco.module.org_alfresco_module_rm.hold.HoldService.removeFromHold=RM_CAP.0.rma:filePlanComponent.RemoveFromHold + org.alfresco.module.org_alfresco_module_rm.hold.HoldService.removeFromHolds=RM_CAP.0.rma:filePlanComponent.RemoveFromHold + org.alfresco.module.org_alfresco_module_rm.hold.HoldService.removeFromAllHolds=RM_ALLOW org.alfresco.module.org_alfresco_module_rm.hold.HoldService.*=RM_DENY ]]> diff --git a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/capability/RMEntryVoter.java b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/capability/RMEntryVoter.java index 8d0e0597e5..05f579daf6 100644 --- a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/capability/RMEntryVoter.java +++ b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/capability/RMEntryVoter.java @@ -29,12 +29,13 @@ import net.sf.acegisecurity.Authentication; import net.sf.acegisecurity.ConfigAttribute; import net.sf.acegisecurity.vote.AccessDecisionVoter; +import org.alfresco.error.AlfrescoRuntimeException; import org.alfresco.module.org_alfresco_module_rm.capability.policy.ConfigAttributeDefinition; import org.alfresco.module.org_alfresco_module_rm.capability.policy.Policy; import org.alfresco.module.org_alfresco_module_rm.security.RMMethodSecurityInterceptor; +import org.alfresco.module.org_alfresco_module_rm.util.AlfrescoTransactionSupport; +import org.alfresco.module.org_alfresco_module_rm.util.TransactionalResourceHelper; import org.alfresco.repo.security.authentication.AuthenticationUtil; -import org.alfresco.repo.transaction.AlfrescoTransactionSupport; -import org.alfresco.repo.transaction.TransactionalResourceHelper; import org.alfresco.service.cmr.repository.NodeRef; import org.alfresco.service.namespace.NamespacePrefixResolver; import org.aopalliance.intercept.MethodInvocation; @@ -59,6 +60,12 @@ public class RMEntryVoter extends RMSecurityCommon /** Capability Service */ private CapabilityService capabilityService; + + /** Transactional Resource Helper */ + private TransactionalResourceHelper transactionalResourceHelper; + + /** Alfresco transaction support */ + private AlfrescoTransactionSupport alfrescoTransactionSupport; /** Policy map */ private Map policies = new HashMap(); @@ -78,6 +85,22 @@ public class RMEntryVoter extends RMSecurityCommon { this.nspr = nspr; } + + /** + * @param transactionalResourceHelper transactional resource helper + */ + public void setTransactionalResourceHelper(TransactionalResourceHelper transactionalResourceHelper) + { + this.transactionalResourceHelper = transactionalResourceHelper; + } + + /** + * @param alfrescoTransactionSupport alfresco transaction support helper + */ + public void setAlfrescoTransactionSupport(AlfrescoTransactionSupport alfrescoTransactionSupport) + { + this.alfrescoTransactionSupport = alfrescoTransactionSupport; + } /** * Register a policy the voter @@ -130,7 +153,7 @@ public class RMEntryVoter extends RMSecurityCommon MethodInvocation mi = (MethodInvocation)object; - if (TransactionalResourceHelper.isResourcePresent("voting")) + if (transactionalResourceHelper.isResourcePresent("voting")) { if (logger.isDebugEnabled()) { @@ -144,7 +167,7 @@ public class RMEntryVoter extends RMSecurityCommon logger.debug("Method: " + mi.getMethod().getDeclaringClass().getName() + "." + mi.getMethod().getName()); } - AlfrescoTransactionSupport.bindResource("voting", true); + alfrescoTransactionSupport.bindResource("voting", true); try { // The system user can do anything @@ -165,8 +188,15 @@ public class RMEntryVoter extends RMSecurityCommon return AccessDecisionVoter.ACCESS_ABSTAIN; } + // check we have an instance of a method invocation + if (!(object instanceof MethodInvocation)) + { + // we expect a method invocation + throw new AlfrescoRuntimeException("Passed object is not an instance of MethodInvocation as expected."); + } + + // get information about the method MethodInvocation invocation = (MethodInvocation) object; - Method method = invocation.getMethod(); Class[] params = method.getParameterTypes(); @@ -273,7 +303,7 @@ public class RMEntryVoter extends RMSecurityCommon } finally { - AlfrescoTransactionSupport.unbindResource("voting"); + alfrescoTransactionSupport.unbindResource("voting"); } // all voted to allow @@ -281,11 +311,12 @@ public class RMEntryVoter extends RMSecurityCommon } /** + * Check the capability * - * @param invocation - * @param params - * @param cad - * @return + * @param invocation method invocation + * @param params parameters + * @param cad config definition + * @return int evaluation result */ @SuppressWarnings("rawtypes") private int checkCapability(MethodInvocation invocation, Class[] params, ConfigAttributeDefinition cad) @@ -298,29 +329,33 @@ public class RMEntryVoter extends RMSecurityCommon Capability capability = capabilityService.getCapability(cad.getRequired().getName()); if (capability == null) { - return AccessDecisionVoter.ACCESS_DENIED; + throw new AlfrescoRuntimeException("The capability '" + cad.getRequired().getName() + "' set on method '" + invocation.getMethod().getName() + "' does not exist."); } return capability.hasPermissionRaw(testNodeRef); } /** + * Evaluate policy to determine access * - * @param invocation - * @param params - * @param cad - * @return + * @param invocation invocation information + * @param params parameters + * @param cad configuration attribute definition + * @return int policy evaluation */ @SuppressWarnings("rawtypes") private int checkPolicy(MethodInvocation invocation, Class[] params, ConfigAttributeDefinition cad) { + // try to get the policy Policy policy = policies.get(cad.getPolicyName()); if (policy == null) { - return AccessDecisionVoter.ACCESS_GRANTED; + // throw an exception if the policy is invalid + throw new AlfrescoRuntimeException("The policy '" + cad.getPolicyName() + "' set on the method '" + invocation.getMethod().getName() + "' does not exist."); } else { + // evaluate the policy return policy.evaluate(invocation, params, cad); } } diff --git a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/capability/declarative/AbstractCapabilityCondition.java b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/capability/declarative/AbstractCapabilityCondition.java index b7d400a4e7..09d1bec413 100644 --- a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/capability/declarative/AbstractCapabilityCondition.java +++ b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/capability/declarative/AbstractCapabilityCondition.java @@ -26,8 +26,8 @@ import org.alfresco.module.org_alfresco_module_rm.freeze.FreezeService; import org.alfresco.module.org_alfresco_module_rm.model.RecordsManagementModel; import org.alfresco.module.org_alfresco_module_rm.record.RecordService; import org.alfresco.module.org_alfresco_module_rm.recordfolder.RecordFolderService; +import org.alfresco.module.org_alfresco_module_rm.util.TransactionalResourceHelper; 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.repository.NodeService; import org.alfresco.service.cmr.security.PermissionService; @@ -56,6 +56,9 @@ public abstract class AbstractCapabilityCondition implements CapabilityCondition protected FilePlanService filePlanService; protected DispositionService dispositionService; protected RecordFolderService recordFolderService; + + /** transaction resource helper */ + private TransactionalResourceHelper transactionalResourceHelper; /** * @param recordService record service @@ -112,6 +115,14 @@ public abstract class AbstractCapabilityCondition implements CapabilityCondition { this.recordFolderService = recordFolderService; } + + /** + * @param transactionalResourceHelper transactional resource helper + */ + public void setTransactionalResourceHelper(TransactionalResourceHelper transactionalResourceHelper) + { + this.transactionalResourceHelper = transactionalResourceHelper; + } /** * @see org.alfresco.module.org_alfresco_module_rm.capability.declarative.CapabilityCondition#getName() @@ -131,7 +142,7 @@ public abstract class AbstractCapabilityCondition implements CapabilityCondition boolean result = false; // check transaction cache - Map map = TransactionalResourceHelper.getMap(KEY_EVALUATE); + Map map = transactionalResourceHelper.getMap(KEY_EVALUATE); String key = getName() + "|" + nodeRef.toString() + "|" + AuthenticationUtil.getRunAsUser(); if (map.containsKey(key)) { diff --git a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/capability/declarative/condition/FillingOnHoldContainerCapabilityCondition.java b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/capability/declarative/condition/FillingOnHoldContainerCapabilityCondition.java new file mode 100644 index 0000000000..391f81d74f --- /dev/null +++ b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/capability/declarative/condition/FillingOnHoldContainerCapabilityCondition.java @@ -0,0 +1,60 @@ +/* + * Copyright (C) 2005-2014 Alfresco Software Limited. + * + * This file is part of Alfresco + * + * Alfresco is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Alfresco is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with Alfresco. If not, see . + */ +package org.alfresco.module.org_alfresco_module_rm.capability.declarative.condition; + +import org.alfresco.module.org_alfresco_module_rm.capability.RMPermissionModel; +import org.alfresco.module.org_alfresco_module_rm.capability.declarative.AbstractCapabilityCondition; +import org.alfresco.service.cmr.repository.NodeRef; +import org.alfresco.service.cmr.security.AccessStatus; + +/** + * Filling capability for hold condition. + * + * @author Roy Wetherall + * @since 2.3 + */ +public class FillingOnHoldContainerCapabilityCondition extends AbstractCapabilityCondition +{ + /** + * @see org.alfresco.module.org_alfresco_module_rm.capability.declarative.CapabilityCondition#evaluate(org.alfresco.service.cmr.repository.NodeRef) + */ + @Override + public boolean evaluateImpl(NodeRef nodeRef) + { + boolean result = false; + NodeRef holdContainer = nodeRef; + + // if we have a file plan, go get the hold container + if (filePlanService.isFilePlan(nodeRef) == true) + { + holdContainer = filePlanService.getHoldContainer(nodeRef); + } + + // ensure we are dealing with a hold container + if (TYPE_HOLD_CONTAINER.equals(nodeService.getType(holdContainer))) + { + if (permissionService.hasPermission(holdContainer, RMPermissionModel.FILE_RECORDS) != AccessStatus.DENIED) + { + result = true; + } + } + + return result; + } +} diff --git a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/capability/declarative/condition/FrozenCapabilityCondition.java b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/capability/declarative/condition/FrozenCapabilityCondition.java index dd271ed432..a7b4e5132a 100644 --- a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/capability/declarative/condition/FrozenCapabilityCondition.java +++ b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/capability/declarative/condition/FrozenCapabilityCondition.java @@ -19,27 +19,57 @@ package org.alfresco.module.org_alfresco_module_rm.capability.declarative.condition; import org.alfresco.module.org_alfresco_module_rm.capability.declarative.AbstractCapabilityCondition; +import org.alfresco.module.org_alfresco_module_rm.hold.HoldService; import org.alfresco.service.cmr.repository.NodeRef; /** + * Indicates whether an item is held or not. + *

+ * A hold object is by definition considered to be held. + * * @author Roy Wetherall */ public class FrozenCapabilityCondition extends AbstractCapabilityCondition { -private boolean checkChildren = false; + /** indicates whether children should be checked */ + private boolean checkChildren = false; + + /** hold service */ + private HoldService holdService; + /** + * @param checkChildren true to check children, false otherwise + */ public void setCheckChildren(boolean checkChildren) { this.checkChildren = checkChildren; } + + /** + * @param holdService hold service + */ + public void setHoldService(HoldService holdService) + { + this.holdService = holdService; + } @Override public boolean evaluateImpl(NodeRef nodeRef) { - boolean result = freezeService.isFrozen(nodeRef); - if (!result && checkChildren) + boolean result = false; + + // check whether we are working with a hold or not + if (holdService.isHold(nodeRef)) { - result = freezeService.hasFrozenChildren(nodeRef); + result = true; + } + else + { + result = freezeService.isFrozen(nodeRef); + if (!result && checkChildren) + { + result = freezeService.hasFrozenChildren(nodeRef); + } } return result; } diff --git a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/capability/declarative/condition/HoldCapabilityCondition.java b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/capability/declarative/condition/HoldCapabilityCondition.java index 9666de3539..1f860ae8d0 100644 --- a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/capability/declarative/condition/HoldCapabilityCondition.java +++ b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/capability/declarative/condition/HoldCapabilityCondition.java @@ -62,16 +62,23 @@ public class HoldCapabilityCondition extends AbstractCapabilityCondition { boolean result = false; - List holds = holdService.heldBy(nodeRef, includedInHold); - for (NodeRef hold : holds) + if (holdService.isHold(nodeRef)) { - // return true as soon as we find one hold we have filling permission on - if (AccessStatus.ALLOWED.equals(permissionService.hasPermission(hold, RMPermissionModel.FILING))) + result = AccessStatus.ALLOWED.equals(permissionService.hasPermission(nodeRef, RMPermissionModel.FILING)); + } + else + { + List holds = holdService.heldBy(nodeRef, includedInHold); + for (NodeRef hold : holds) { - result = true; - break; + // return true as soon as we find one hold we have filling permission on + if (AccessStatus.ALLOWED.equals(permissionService.hasPermission(hold, RMPermissionModel.FILING))) + { + result = true; + break; + } } - } + } return result; } diff --git a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/disposition/DispositionServiceImpl.java b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/disposition/DispositionServiceImpl.java index c302937ae1..05b994a87b 100644 --- a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/disposition/DispositionServiceImpl.java +++ b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/disposition/DispositionServiceImpl.java @@ -969,7 +969,7 @@ public class DispositionServiceImpl extends ServiceBaseImpl * @see org.alfresco.module.org_alfresco_module_rm.disposition.DispositionService#cutoffDisposableItem(NodeRef) */ @Override - public void cutoffDisposableItem(NodeRef nodeRef) + public void cutoffDisposableItem(final NodeRef nodeRef) { ParameterCheck.mandatory("nodeRef", nodeRef); @@ -1001,7 +1001,15 @@ public class DispositionServiceImpl extends ServiceBaseImpl if (recordFolderService.isRecordFolder(nodeRef) && !recordFolderService.isRecordFolderClosed(nodeRef)) { - recordFolderService.closeRecordFolder(nodeRef); + // runAs system so that we can close a record that has already been cutoff + authenticationUtil.runAsSystem(new RunAsWork() + { + public Void doWork() throws Exception + { + recordFolderService.closeRecordFolder(nodeRef); + return null; + } + }); } } else diff --git a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/security/RMMethodSecurityInterceptor.java b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/security/RMMethodSecurityInterceptor.java index 40ec0eae61..1d4e1e5f3d 100644 --- a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/security/RMMethodSecurityInterceptor.java +++ b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/security/RMMethodSecurityInterceptor.java @@ -39,7 +39,7 @@ public class RMMethodSecurityInterceptor extends MethodSecurityInterceptor { public String name; public AccessStatus status; - public Map conditions = new HashMap(); + public Map conditions = new HashMap(); } /** diff --git a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/util/AlfrescoTransactionSupport.java b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/util/AlfrescoTransactionSupport.java new file mode 100644 index 0000000000..d2f9796300 --- /dev/null +++ b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/util/AlfrescoTransactionSupport.java @@ -0,0 +1,45 @@ +/* + * Copyright (C) 2005-2014 Alfresco Software Limited. + * + * This file is part of Alfresco + * + * Alfresco is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Alfresco is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with Alfresco. If not, see . + */ +package org.alfresco.module.org_alfresco_module_rm.util; + +/** + * Alfresco Transaction Support delegation bean. + * + * @author Roy Wetherall + * @since 2.3 + * @see org.alfresco.repo.transaction.AlfrescoTransactionSupport + */ +public class AlfrescoTransactionSupport +{ + /** + * @see org.alfresco.repo.transaction.AlfrescoTransactionSupport#bindResource(Object, Object) + */ + public void bindResource(Object key, Object resource) + { + org.alfresco.repo.transaction.AlfrescoTransactionSupport.bindResource(key, resource); + } + + /** + * @see org.alfresco.repo.transaction.AlfrescoTransactionSupport#unbindResource(Object) + */ + public void unbindResource(Object key) + { + org.alfresco.repo.transaction.AlfrescoTransactionSupport.unbindResource(key); + } +} diff --git a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/util/TransactionalResourceHelper.java b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/util/TransactionalResourceHelper.java new file mode 100644 index 0000000000..9f62a1512d --- /dev/null +++ b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/util/TransactionalResourceHelper.java @@ -0,0 +1,106 @@ +/* + * Copyright (C) 2005-2014 Alfresco Software Limited. + * + * This file is part of Alfresco + * + * Alfresco is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Alfresco is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with Alfresco. If not, see . + */ +package org.alfresco.module.org_alfresco_module_rm.util; + +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.TreeSet; + +/** + * Delegate spring bean for TransactionResourceHelper + * + * @author Roy Wetherall + * @since 2.3 + * @see org.alfresco.repo.transaction.TransactionalResourceHelper + */ +public class TransactionalResourceHelper +{ + /** + * @see org.alfresco.repo.transaction.TransactionalResourceHelper#getCount(Object) + */ + public int getCount(Object resourceKey) + { + return org.alfresco.repo.transaction.TransactionalResourceHelper.getCount(resourceKey); + } + + /** + * @see org.alfresco.repo.transaction.TransactionalResourceHelper#getCount(Object) + */ + public void resetCount(Object resourceKey) + { + org.alfresco.repo.transaction.TransactionalResourceHelper.resetCount(resourceKey); + } + + /** + * @see org.alfresco.repo.transaction.TransactionalResourceHelper#incrementCount(Object) + */ + public int incrementCount(Object resourceKey) + { + return org.alfresco.repo.transaction.TransactionalResourceHelper.incrementCount(resourceKey); + } + + /** + * @see org.alfresco.repo.transaction.TransactionalResourceHelper#decrementCount(Object, boolean) + */ + public int decrementCount(Object resourceKey, boolean allowNegative) + { + return org.alfresco.repo.transaction.TransactionalResourceHelper.decrementCount(resourceKey, allowNegative); + } + + /** + * @see org.alfresco.repo.transaction.TransactionalResourceHelper#getCount(Object) + */ + public boolean isResourcePresent(Object resourceKey) + { + return org.alfresco.repo.transaction.TransactionalResourceHelper.isResourcePresent(resourceKey); + } + + /** + * @see org.alfresco.repo.transaction.TransactionalResourceHelper#getMap(Object) + */ + public Map getMap(Object resourceKey) + { + return org.alfresco.repo.transaction.TransactionalResourceHelper.getMap(resourceKey); + } + + /** + * @see org.alfresco.repo.transaction.TransactionalResourceHelper#getSet(Object) + */ + public Set getSet(Object resourceKey) + { + return org.alfresco.repo.transaction.TransactionalResourceHelper.getSet(resourceKey); + } + + /** + * @see org.alfresco.repo.transaction.TransactionalResourceHelper#getTreeSet(Object) + */ + public TreeSet getTreeSet(Object resourceKey) + { + return org.alfresco.repo.transaction.TransactionalResourceHelper.getTreeSet(resourceKey); + } + + /** + * @see org.alfresco.repo.transaction.TransactionalResourceHelper#getList(Object) + */ + public List getList(Object resourceKey) + { + return org.alfresco.repo.transaction.TransactionalResourceHelper.getList(resourceKey); + } +} diff --git a/rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/integration/hold/CreateHoldTest.java b/rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/integration/hold/CreateHoldTest.java index f5a7b93ec9..08f6af286f 100644 --- a/rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/integration/hold/CreateHoldTest.java +++ b/rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/integration/hold/CreateHoldTest.java @@ -96,7 +96,9 @@ public class CreateHoldTest extends BaseRMTestCase { public Void doWork() throws Exception { + // ensure the user has the correct permission to create the hold filePlanPermissionService.setPermission(holdsContainer, testUser, FILING); + return null; } }, getAdminUserName()); diff --git a/rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/integration/issue/RM1030Test.java b/rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/integration/issue/RM1030Test.java index e3e63b8727..3f692b4adb 100755 --- a/rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/integration/issue/RM1030Test.java +++ b/rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/integration/issue/RM1030Test.java @@ -19,7 +19,9 @@ package org.alfresco.module.org_alfresco_module_rm.test.integration.issue; import java.util.List; +import java.util.Set; +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.repository.NodeRef; @@ -45,6 +47,12 @@ public class RM1030Test extends BaseRMTestCase @Override public NodeRef run() { + Set auths = filePlanRoleService.getAllAssignedToRole(filePlan, FilePlanRoleService.ROLE_ADMIN); + for (String auth : auths) + { + System.out.println(auth); + } + // show there are no holds when we start List holds = holdService.getHolds(filePlan); assertNotNull(holds); diff --git a/rm-server/unit-test/java/org/alfresco/module/org_alfresco_module_rm/capability/RMEntryVoterUnitTest.java b/rm-server/unit-test/java/org/alfresco/module/org_alfresco_module_rm/capability/RMEntryVoterUnitTest.java new file mode 100644 index 0000000000..b52ec4b82d --- /dev/null +++ b/rm-server/unit-test/java/org/alfresco/module/org_alfresco_module_rm/capability/RMEntryVoterUnitTest.java @@ -0,0 +1,153 @@ +/* + * Copyright (C) 2005-2014 Alfresco Software Limited. + * + * This file is part of Alfresco + * + * Alfresco is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Alfresco is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with Alfresco. If not, see . + */ +package org.alfresco.module.org_alfresco_module_rm.capability; + +import static org.mockito.Matchers.any; +import static org.mockito.Matchers.eq; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + +import java.lang.reflect.Method; +import java.util.Iterator; + +import net.sf.acegisecurity.Authentication; +import net.sf.acegisecurity.ConfigAttribute; + +import org.alfresco.error.AlfrescoRuntimeException; +import org.alfresco.module.org_alfresco_module_rm.capability.policy.ConfigAttributeDefinition; +import org.alfresco.module.org_alfresco_module_rm.capability.policy.Policy; +import org.alfresco.module.org_alfresco_module_rm.test.util.BaseUnitTest; +import org.alfresco.service.cmr.repository.NodeRef; +import org.aopalliance.intercept.MethodInvocation; +import org.junit.Test; +import org.mockito.InjectMocks; +import org.mockito.Mock; + +/** + * RM entry voter unit test + * + * @author Roy Wetherall + * @since 2.3 + */ +public class RMEntryVoterUnitTest extends BaseUnitTest +{ + private static final String POLICY_NAME = "myPolicy"; + + /** RM Entry */ + private @InjectMocks RMEntryVoter entryVoter; + + /** Mocked policy */ + private @Mock Policy mockedPolicy; + + /** + * Given that we have provided an invalid policy + * When I evaluate the voter + * Then an AlfrescoRuntimeException is thrown + */ + @Test + public void invalidPolicy() throws Exception + { + // given I am providing an invalid policy for a method + Authentication mockedAuthentication = mock(Authentication.class); + MethodInvocation mockedMethodInvocation = createMethodInvoation("myTestMethod", NodeRef.class); + net.sf.acegisecurity.ConfigAttributeDefinition mockedConfigDef = createConfigDefinition("RM.invalid"); + + // I expect an Alfresco Runtime Exception + exception.expect(AlfrescoRuntimeException.class); + + // call vote + entryVoter.vote(mockedAuthentication, mockedMethodInvocation, mockedConfigDef); + } + + /** + * Given that I have provided a valid policy + * When I evaluate the voter + * Then the corresponding policy will be evaluated + */ + @Test + public void validPolicy() throws Exception + { + when(mockedPolicy.getName()) + .thenReturn(POLICY_NAME); + entryVoter.registerPolicy(mockedPolicy); + + // mock calling details + Authentication mockedAuthentication = mock(Authentication.class); + MethodInvocation mockedMethodInvocation = createMethodInvoation("myTestMethod", NodeRef.class); + net.sf.acegisecurity.ConfigAttributeDefinition mockedConfigDef = createConfigDefinition("RM." + POLICY_NAME); + + // call vote + entryVoter.vote(mockedAuthentication, mockedMethodInvocation, mockedConfigDef); + + // verify that the policy was executed + verify(mockedPolicy, times(1)).evaluate(eq(mockedMethodInvocation), any(Class[].class), any(ConfigAttributeDefinition.class)); + } + + /** + * Helper method to create configuration object + */ + @SuppressWarnings("rawtypes") + private net.sf.acegisecurity.ConfigAttributeDefinition createConfigDefinition(String value) + { + net.sf.acegisecurity.ConfigAttributeDefinition mockedConfig = mock(net.sf.acegisecurity.ConfigAttributeDefinition.class); + + ConfigAttribute mockedConfigAttr = mock(ConfigAttribute.class); + when(mockedConfigAttr.getAttribute()) + .thenReturn(value); + + Iterator mockedIter = mock(Iterator.class); + when(mockedIter.hasNext()) + .thenReturn(true) + .thenReturn(false); + when(mockedIter.next()) + .thenReturn(mockedConfigAttr); + + when(mockedConfig.getConfigAttributes()) + .thenReturn(mockedIter); + + return mockedConfig; + } + + /** + * Helper method to create method invocation mock + */ + private MethodInvocation createMethodInvoation(String methodName, Class ... parameterTypes) + throws Exception + { + // mock method invocation + MethodInvocation mockedMethodInvocation = mock(MethodInvocation.class); + + // get method object .. assumed to be a method on this object + Method method = RMEntryVoterUnitTest.class.getMethod(methodName, parameterTypes); + when(mockedMethodInvocation.getMethod()) + .thenReturn(method); + + return mockedMethodInvocation; + } + + /** ========= Test methods ======== */ + + public void myTestMethod(NodeRef nodeRef) + { + // does nothing + } + +} diff --git a/rm-server/unit-test/java/org/alfresco/module/org_alfresco_module_rm/capability/declarative/condition/CapabilityDeclarativeConditionSuite.java b/rm-server/unit-test/java/org/alfresco/module/org_alfresco_module_rm/capability/declarative/condition/CapabilityDeclarativeConditionSuite.java new file mode 100644 index 0000000000..b27a9ba6b3 --- /dev/null +++ b/rm-server/unit-test/java/org/alfresco/module/org_alfresco_module_rm/capability/declarative/condition/CapabilityDeclarativeConditionSuite.java @@ -0,0 +1,40 @@ +/* + * Copyright (C) 2005-2014 Alfresco Software Limited. + * + * This file is part of Alfresco + * + * Alfresco is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Alfresco is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with Alfresco. If not, see . + */ +package org.alfresco.module.org_alfresco_module_rm.capability.declarative.condition; + +import org.junit.runner.RunWith; +import org.junit.runners.Suite; +import org.junit.runners.Suite.SuiteClasses; + +/** + * capability.declarative.condition unit test suite + * + * @author Roy Wetherall + * @since 2.3 + */ +@RunWith(Suite.class) +@SuiteClasses( +{ + HoldCapabilityConditionUnitTest.class, + FillingOnHoldContainerCapabilityConditionUnitTest.class, + FrozenCapabilityConditionUnitTest.class +}) +public class CapabilityDeclarativeConditionSuite +{ +} diff --git a/rm-server/unit-test/java/org/alfresco/module/org_alfresco_module_rm/capability/declarative/condition/FillingOnHoldContainerCapabilityConditionUnitTest.java b/rm-server/unit-test/java/org/alfresco/module/org_alfresco_module_rm/capability/declarative/condition/FillingOnHoldContainerCapabilityConditionUnitTest.java new file mode 100644 index 0000000000..6fb7262306 --- /dev/null +++ b/rm-server/unit-test/java/org/alfresco/module/org_alfresco_module_rm/capability/declarative/condition/FillingOnHoldContainerCapabilityConditionUnitTest.java @@ -0,0 +1,141 @@ +/* + * Copyright (C) 2005-2014 Alfresco Software Limited. + * + * This file is part of Alfresco + * + * Alfresco is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Alfresco is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with Alfresco. If not, see . + */ +package org.alfresco.module.org_alfresco_module_rm.capability.declarative.condition; + +import static org.mockito.Mockito.*; +import static org.junit.Assert.*; + +import org.alfresco.module.org_alfresco_module_rm.capability.RMPermissionModel; +import org.alfresco.module.org_alfresco_module_rm.test.util.BaseUnitTest; +import org.alfresco.service.cmr.repository.NodeRef; +import org.alfresco.service.cmr.security.AccessStatus; +import org.junit.Before; +import org.junit.Test; +import org.mockito.InjectMocks; + +/** + * Filling on hold container capability condition unit test + * + * @author Roy Wetherall + * @since 2.3 + */ +public class FillingOnHoldContainerCapabilityConditionUnitTest extends BaseUnitTest +{ + /** evaluator */ + private @InjectMocks FillingOnHoldContainerCapabilityCondition condition; + + /** + * @see org.alfresco.module.org_alfresco_module_rm.test.util.BaseUnitTest#before() + */ + @Before + @Override + public void before() throws Exception + { + super.before(); + } + + /** + * Given hold container node + * And no filling permission + * When evaluate + * Then false + */ + @Test + public void noFillingOnHoldContainer() + { + NodeRef holdContainer = generateNodeRef(TYPE_HOLD_CONTAINER); + when(mockedFilePlanService.isFilePlan(holdContainer)) + .thenReturn(false); + when(mockedPermissionService.hasPermission(holdContainer, RMPermissionModel.FILE_RECORDS)) + .thenReturn(AccessStatus.DENIED); + + assertFalse(condition.evaluateImpl(holdContainer)); + } + + /** + * Given hold container node + * And filling permission + * When evaluate + * Then true + */ + @Test + public void fillingOnHoldContainer() + { + NodeRef holdContainer = generateNodeRef(TYPE_HOLD_CONTAINER); + when(mockedFilePlanService.isFilePlan(holdContainer)) + .thenReturn(false); + when(mockedPermissionService.hasPermission(holdContainer, RMPermissionModel.FILE_RECORDS)) + .thenReturn(AccessStatus.ALLOWED); + + assertTrue(condition.evaluateImpl(holdContainer)); + } + + /** + * Given file-plan node + * And no filling permission on hold container + * When evaluate + * Then false + */ + @Test + public void filePlanNoFilling() + { + NodeRef holdContainer = generateNodeRef(TYPE_HOLD_CONTAINER); + when(mockedFilePlanService.getHoldContainer(filePlan)) + .thenReturn(holdContainer); + when(mockedPermissionService.hasPermission(holdContainer, RMPermissionModel.FILE_RECORDS)) + .thenReturn(AccessStatus.DENIED); + + assertFalse(condition.evaluateImpl(holdContainer)); + } + + /** + * Given file-plan node + * And filling permission on hold container + * When evaluate + * Then true + */ + @Test + public void filePlanFilling() + { + NodeRef holdContainer = generateNodeRef(TYPE_HOLD_CONTAINER); + when(mockedFilePlanService.getHoldContainer(filePlan)) + .thenReturn(holdContainer); + when(mockedPermissionService.hasPermission(holdContainer, RMPermissionModel.FILE_RECORDS)) + .thenReturn(AccessStatus.ALLOWED); + + assertTrue(condition.evaluateImpl(holdContainer)); + } + + /** + * Given unexpected node type + * When evaluate + * Then false + */ + @Test + public void unexpectedNode() + { + NodeRef unexpectedNode = generateNodeRef(); + when(mockedFilePlanService.isFilePlan(unexpectedNode)) + .thenReturn(false); + when(mockedPermissionService.hasPermission(unexpectedNode, RMPermissionModel.FILE_RECORDS)) + .thenReturn(AccessStatus.ALLOWED); + + assertFalse(condition.evaluateImpl(unexpectedNode)); + } +} diff --git a/rm-server/unit-test/java/org/alfresco/module/org_alfresco_module_rm/capability/declarative/condition/FrozenCapabilityConditionUnitTest.java b/rm-server/unit-test/java/org/alfresco/module/org_alfresco_module_rm/capability/declarative/condition/FrozenCapabilityConditionUnitTest.java new file mode 100644 index 0000000000..55f10e24c5 --- /dev/null +++ b/rm-server/unit-test/java/org/alfresco/module/org_alfresco_module_rm/capability/declarative/condition/FrozenCapabilityConditionUnitTest.java @@ -0,0 +1,232 @@ +/* + * Copyright (C) 2005-2014 Alfresco Software Limited. + * + * This file is part of Alfresco + * + * Alfresco is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Alfresco is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with Alfresco. If not, see . + */ +package org.alfresco.module.org_alfresco_module_rm.capability.declarative.condition; + +import static org.junit.Assert.*; +import static org.mockito.Mockito.*; + +import org.alfresco.module.org_alfresco_module_rm.test.util.BaseUnitTest; +import org.alfresco.service.cmr.repository.NodeRef; +import org.junit.Before; +import org.junit.Test; +import org.mockito.InjectMocks; + +/** + * Frozen capability condition unit test + * + * @author Roy Wetherall + * @since 2.3 + */ +public class FrozenCapabilityConditionUnitTest extends BaseUnitTest +{ + /** evaluator */ + private @InjectMocks FrozenCapabilityCondition condition; + + /** + * @see org.alfresco.module.org_alfresco_module_rm.test.util.BaseUnitTest#before() + */ + @Before + @Override + public void before() throws Exception + { + super.before(); + } + + /** + * Given hold + * When evaluate + * Then true + */ + @Test + public void evaluateHold() + { + // is a hold + NodeRef nodeRef = generateNodeRef(); + when(mockedHoldService.isHold(nodeRef)) + .thenReturn(true); + + // evaluate + assertTrue(condition.evaluate(nodeRef)); + + // verify + verify(mockedHoldService, times(1)).isHold(nodeRef); + verify(mockedFreezeService, never()).isFrozen(nodeRef); + verify(mockedFreezeService, never()).hasFrozenChildren(nodeRef); + } + + /** + * Given is frozen + * And no check children + * When evaluate + * Then true + */ + @Test + public void frozenDontCheckChildren() + { + // is not a hold + NodeRef nodeRef = generateNodeRef(); + when(mockedHoldService.isHold(nodeRef)) + .thenReturn(false); + + // dont check children + condition.setCheckChildren(false); + + // is frozen + when(mockedFreezeService.isFrozen(nodeRef)) + .thenReturn(true); + + // evaluate + assertTrue(condition.evaluate(nodeRef)); + + // verify + verify(mockedHoldService, times(1)).isHold(nodeRef); + verify(mockedFreezeService, times(1)).isFrozen(nodeRef); + verify(mockedFreezeService, never()).hasFrozenChildren(nodeRef); + } + + /** + * Given is not frozen + * And no check children + * When evaluate + * Then false + */ + @Test + public void notFrozenDontCheckChildren() + { + // is not a hold + NodeRef nodeRef = generateNodeRef(); + when(mockedHoldService.isHold(nodeRef)) + .thenReturn(false); + + // dont check children + condition.setCheckChildren(false); + + // is not frozen + when(mockedFreezeService.isFrozen(nodeRef)) + .thenReturn(false); + + // evaluate + assertFalse(condition.evaluate(nodeRef)); + + // verify + verify(mockedHoldService, times(1)).isHold(nodeRef); + verify(mockedFreezeService, times(1)).isFrozen(nodeRef); + verify(mockedFreezeService, never()).hasFrozenChildren(nodeRef); + } + + /** + * Given is frozen + * And check children + * When evaluate + * Then true + */ + @Test + public void frozenCheckChildren() + { + // is not a hold + NodeRef nodeRef = generateNodeRef(); + when(mockedHoldService.isHold(nodeRef)) + .thenReturn(false); + + // check children + condition.setCheckChildren(true); + + // is frozen + when(mockedFreezeService.isFrozen(nodeRef)) + .thenReturn(true); + + // evaluate + assertTrue(condition.evaluate(nodeRef)); + + // verify + verify(mockedHoldService, times(1)).isHold(nodeRef); + verify(mockedFreezeService, times(1)).isFrozen(nodeRef); + verify(mockedFreezeService, never()).hasFrozenChildren(nodeRef); + } + + /** + * Given is not frozen + * And check children + * And children no frozen + * When evaluate + * Then false + */ + @Test + public void notFrozenCheckChildrenNotFrozen() + { + // is not a hold + NodeRef nodeRef = generateNodeRef(); + when(mockedHoldService.isHold(nodeRef)) + .thenReturn(false); + + // check children + condition.setCheckChildren(true); + + // is not frozen + when(mockedFreezeService.isFrozen(nodeRef)) + .thenReturn(false); + + // children not frozen + when(mockedFreezeService.hasFrozenChildren(nodeRef)) + .thenReturn(false); + + // evaluate + assertFalse(condition.evaluate(nodeRef)); + + // verify + verify(mockedHoldService, times(1)).isHold(nodeRef); + verify(mockedFreezeService, times(1)).isFrozen(nodeRef); + verify(mockedFreezeService, times(1)).hasFrozenChildren(nodeRef); + } + + /** + * Given is not frozen + * And check children + * And children frozen + * When evaluate + * Then true + */ + @Test + public void notFrozenCheckChildrenFrozen() + { + // is not a hold + NodeRef nodeRef = generateNodeRef(); + when(mockedHoldService.isHold(nodeRef)) + .thenReturn(false); + + // check children + condition.setCheckChildren(true); + + // is not frozen + when(mockedFreezeService.isFrozen(nodeRef)) + .thenReturn(false); + + // children frozen + when(mockedFreezeService.hasFrozenChildren(nodeRef)) + .thenReturn(true); + + // evaluate + assertTrue(condition.evaluate(nodeRef)); + + // verify + verify(mockedHoldService, times(1)).isHold(nodeRef); + verify(mockedFreezeService, times(1)).isFrozen(nodeRef); + verify(mockedFreezeService, times(1)).hasFrozenChildren(nodeRef); + } +} diff --git a/rm-server/unit-test/java/org/alfresco/module/org_alfresco_module_rm/capability/declarative/condition/HoldCapabilityConditionUnitTest.java b/rm-server/unit-test/java/org/alfresco/module/org_alfresco_module_rm/capability/declarative/condition/HoldCapabilityConditionUnitTest.java index 0f0eb1bf68..ad4b3484bf 100644 --- a/rm-server/unit-test/java/org/alfresco/module/org_alfresco_module_rm/capability/declarative/condition/HoldCapabilityConditionUnitTest.java +++ b/rm-server/unit-test/java/org/alfresco/module/org_alfresco_module_rm/capability/declarative/condition/HoldCapabilityConditionUnitTest.java @@ -57,10 +57,10 @@ public class HoldCapabilityConditionUnitTest extends BaseUnitTest private List holds; /** mocked objects */ - @Mock(name="kinds") Set mockedKinds; + private @Mock(name="kinds") Set mockedKinds; /** evaluator */ - @Spy @InjectMocks HoldCapabilityCondition evaluator; + private @Spy @InjectMocks HoldCapabilityCondition evaluator; /** * @see org.alfresco.module.org_alfresco_module_rm.test.util.BaseUnitTest#before() diff --git a/rm-server/unit-test/java/org/alfresco/module/org_alfresco_module_rm/test/AllUnitTestSuite.java b/rm-server/unit-test/java/org/alfresco/module/org_alfresco_module_rm/test/AllUnitTestSuite.java index 0882c65579..02090856a2 100644 --- a/rm-server/unit-test/java/org/alfresco/module/org_alfresco_module_rm/test/AllUnitTestSuite.java +++ b/rm-server/unit-test/java/org/alfresco/module/org_alfresco_module_rm/test/AllUnitTestSuite.java @@ -23,7 +23,8 @@ import org.alfresco.module.org_alfresco_module_rm.action.impl.FileReportActionUn import org.alfresco.module.org_alfresco_module_rm.action.impl.UnlinkFromActionUnitTest; import org.alfresco.module.org_alfresco_module_rm.bootstrap.BootstrapImporterModuleComponentUnitTest; import org.alfresco.module.org_alfresco_module_rm.bootstrap.RecordContributorsGroupBootstrapComponentUnitTest; -import org.alfresco.module.org_alfresco_module_rm.capability.declarative.condition.HoldCapabilityConditionUnitTest; +import org.alfresco.module.org_alfresco_module_rm.capability.RMEntryVoterUnitTest; +import org.alfresco.module.org_alfresco_module_rm.capability.declarative.condition.CapabilityDeclarativeConditionSuite; import org.alfresco.module.org_alfresco_module_rm.forms.RecordsManagementTypeFormFilterUnitTest; import org.alfresco.module.org_alfresco_module_rm.hold.HoldServiceImplUnitTest; import org.alfresco.module.org_alfresco_module_rm.job.DispositionLifecycleJobExecuterUnitTest; @@ -58,6 +59,7 @@ import org.junit.runners.Suite.SuiteClasses; DispositionLifecycleJobExecuterUnitTest.class, DictionaryBootstrapPostProcessorUnitTest.class, DateParameterProcessorUnitTest.class, + RMEntryVoterUnitTest.class, // services RecordServiceImplUnitTest.class, @@ -74,9 +76,6 @@ import org.junit.runners.Suite.SuiteClasses; HoldPostUnitTest.class, HoldPutUnitTest.class, - // capability conditions - HoldCapabilityConditionUnitTest.class, - // action implementations FileReportActionUnitTest.class, UnlinkFromActionUnitTest.class, @@ -91,7 +90,10 @@ import org.junit.runners.Suite.SuiteClasses; // bootstrap BootstrapImporterModuleComponentUnitTest.class, - RecordContributorsGroupBootstrapComponentUnitTest.class + RecordContributorsGroupBootstrapComponentUnitTest.class, + + // suites by package + CapabilityDeclarativeConditionSuite.class }) public class AllUnitTestSuite { diff --git a/rm-server/unit-test/java/org/alfresco/module/org_alfresco_module_rm/test/util/BaseUnitTest.java b/rm-server/unit-test/java/org/alfresco/module/org_alfresco_module_rm/test/util/BaseUnitTest.java index 3cce7a93a1..01394d66de 100644 --- a/rm-server/unit-test/java/org/alfresco/module/org_alfresco_module_rm/test/util/BaseUnitTest.java +++ b/rm-server/unit-test/java/org/alfresco/module/org_alfresco_module_rm/test/util/BaseUnitTest.java @@ -35,6 +35,7 @@ import org.alfresco.model.ContentModel; import org.alfresco.module.org_alfresco_module_rm.action.RecordsManagementActionService; import org.alfresco.module.org_alfresco_module_rm.audit.RecordsManagementAuditService; import org.alfresco.module.org_alfresco_module_rm.fileplan.FilePlanService; +import org.alfresco.module.org_alfresco_module_rm.freeze.FreezeService; import org.alfresco.module.org_alfresco_module_rm.hold.HoldService; import org.alfresco.module.org_alfresco_module_rm.identifier.IdentifierService; import org.alfresco.module.org_alfresco_module_rm.model.RecordsManagementModel; @@ -46,7 +47,9 @@ import org.alfresco.module.org_alfresco_module_rm.recordfolder.RecordFolderServi import org.alfresco.module.org_alfresco_module_rm.report.ReportService; import org.alfresco.module.org_alfresco_module_rm.role.FilePlanRoleService; import org.alfresco.module.org_alfresco_module_rm.security.ExtendedSecurityService; +import org.alfresco.module.org_alfresco_module_rm.util.AlfrescoTransactionSupport; import org.alfresco.module.org_alfresco_module_rm.util.AuthenticationUtil; +import org.alfresco.module.org_alfresco_module_rm.util.TransactionalResourceHelper; import org.alfresco.module.org_alfresco_module_rm.version.RecordableVersionService; import org.alfresco.repo.policy.BehaviourFilter; import org.alfresco.repo.policy.PolicyComponent; @@ -128,6 +131,9 @@ public class BaseUnitTest implements RecordsManagementModel, ContentModel @Mock(name="recordableVersionConfigService") protected RecordableVersionConfigService mockedRecordableVersionConfigService; @Mock(name="cmObjectType") protected CmObjectType mockedCmObjectType; @Mock(name="recordableVersionService") protected RecordableVersionService mockedRecordableVersionService; + @Mock(name="transactionalResourceHelper") protected TransactionalResourceHelper mockedTransactionalResourceHelper; + @Mock(name="alfrescoTransactionSupport") protected AlfrescoTransactionSupport mockedAlfrescoTransactionSupport; + @Mock(name="freezeService") protected FreezeService mockedFreezeService; /** application context mock */ @Mock(name="applicationContext") protected ApplicationContext mockedApplicationContext;