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 41d6b9855e..7c300ec6e7 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 @@ -78,6 +78,7 @@ + diff --git a/rm-server/config/alfresco/module/org_alfresco_module_rm/rm-capabilities-context.xml b/rm-server/config/alfresco/module/org_alfresco_module_rm/rm-capabilities-context.xml index 8392047960..349e7f3eb9 100644 --- a/rm-server/config/alfresco/module/org_alfresco_module_rm/rm-capabilities-context.xml +++ b/rm-server/config/alfresco/module/org_alfresco_module_rm/rm-capabilities-context.xml @@ -14,7 +14,6 @@ abstract="true" parent="RMSecurityCommon" init-method="init"> - 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 0ebbdee4ed..fab4dee8f1 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 @@ -93,10 +93,7 @@ lazy-init="false" parent="RMSecurityCommon" depends-on="CapabilityService"> - - - diff --git a/rm-server/config/alfresco/module/org_alfresco_module_rm/security/rm-method-security-context.xml b/rm-server/config/alfresco/module/org_alfresco_module_rm/security/rm-method-security-context.xml index b98e93a395..6931347171 100644 --- a/rm-server/config/alfresco/module/org_alfresco_module_rm/security/rm-method-security-context.xml +++ b/rm-server/config/alfresco/module/org_alfresco_module_rm/security/rm-method-security-context.xml @@ -15,6 +15,6 @@ - + \ No newline at end of file diff --git a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/capability/AbstractCapability.java b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/capability/AbstractCapability.java index 01a251f7ec..685ad74f41 100644 --- a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/capability/AbstractCapability.java +++ b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/capability/AbstractCapability.java @@ -41,9 +41,6 @@ public abstract class AbstractCapability extends RMSecurityCommon @SuppressWarnings("unused") private static Log logger = LogFactory.getLog(AbstractCapability.class); - /** RM entry voter */ - protected RMEntryVoter voter; - /** Capability service */ protected CapabilityService capabilityService; @@ -63,14 +60,6 @@ public abstract class AbstractCapability extends RMSecurityCommon /** Indicates whether this is a private capability or not */ protected boolean isPrivate = false; - /** - * @param voter RM entry voter - */ - public void setVoter(RMEntryVoter voter) - { - this.voter = voter; - } - /** * @param capabilityService capability service */ 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 7294721c7c..9d21ead256 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 @@ -18,41 +18,23 @@ */ package org.alfresco.module.org_alfresco_module_rm.capability; -import java.io.Serializable; import java.lang.reflect.Method; import java.util.ArrayList; import java.util.HashMap; import java.util.Iterator; import java.util.List; -import java.util.Map; -import java.util.StringTokenizer; import net.sf.acegisecurity.Authentication; import net.sf.acegisecurity.ConfigAttribute; -import net.sf.acegisecurity.ConfigAttributeDefinition; import net.sf.acegisecurity.vote.AccessDecisionVoter; -import org.alfresco.module.org_alfresco_module_rm.RecordsManagementService; -import org.alfresco.module.org_alfresco_module_rm.capability.impl.CreateCapability; -import org.alfresco.module.org_alfresco_module_rm.capability.impl.UpdateCapability; -import org.alfresco.module.org_alfresco_module_rm.capability.impl.UpdatePropertiesCapability; -import org.alfresco.module.org_alfresco_module_rm.caveat.RMCaveatConfigComponent; -import org.alfresco.module.org_alfresco_module_rm.disposition.DispositionService; -import org.alfresco.module.org_alfresco_module_rm.model.RecordsManagementModel; +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.repo.security.authentication.AuthenticationUtil; -import org.alfresco.repo.security.permissions.impl.SimplePermissionReference; -import org.alfresco.repo.security.permissions.impl.acegi.ACLEntryVoterException; -import org.alfresco.service.cmr.dictionary.DictionaryService; -import org.alfresco.service.cmr.repository.AssociationRef; -import org.alfresco.service.cmr.repository.ChildAssociationRef; import org.alfresco.service.cmr.repository.NodeRef; -import org.alfresco.service.cmr.repository.NodeService; -import org.alfresco.service.cmr.repository.StoreRef; import org.alfresco.service.cmr.search.SearchService; import org.alfresco.service.cmr.security.OwnableService; -import org.alfresco.service.cmr.security.PermissionService; import org.alfresco.service.namespace.NamespacePrefixResolver; -import org.alfresco.service.namespace.QName; import org.aopalliance.intercept.MethodInvocation; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; @@ -66,60 +48,34 @@ public class RMEntryVoter extends RMSecurityCommon { private static Log logger = LogFactory.getLog(RMEntryVoter.class); - private static final String RM = "RM"; - private static final String RM_ALLOW = "RM_ALLOW"; - private static final String RM_DENY = "RM_DENY"; - private static final String RM_CAP = "RM_CAP"; - private static final String RM_ABSTAIN = "RM_ABSTAIN"; - private static final String RM_QUERY = "RM_QUERY"; - - private NamespacePrefixResolver nspr; - private NodeService nodeService; - private PermissionService permissionService; - private RMCaveatConfigComponent caveatConfigComponent; - private DictionaryService dictionaryService; - private RecordsManagementService recordsManagementService; - private DispositionService dispositionService; + private NamespacePrefixResolver nspr; private SearchService searchService; private OwnableService ownableService; - private CapabilityService capabilityService; - private static HashMap policies = new HashMap(); + private HashMap policies = new HashMap(); - static +// static +// { +// policies.put("Read", new ReadPolicy()); +// policies.put("Create", new CreatePolicy()); +// policies.put("Move", new MovePolicy()); +// policies.put("Update", new UpdatePolicy()); +// policies.put("Delete", new DeletePolicy()); +// policies.put("UpdateProperties", new UpdatePropertiesPolicy()); +// policies.put("Assoc", new AssocPolicy()); +// policies.put("WriteContent", new WriteContentPolicy()); +// policies.put("Capability", new CapabilityPolicy()); +// policies.put("Declare", new DeclarePolicy()); +// policies.put("ReadProperty", new ReadPropertyPolicy()); +// } + + private ApplicationContext applicationContext; + + @Override + public void setApplicationContext(ApplicationContext applicationContext) throws BeansException { - policies.put("Read", new ReadPolicy()); - policies.put("Create", new CreatePolicy()); - policies.put("Move", new MovePolicy()); - policies.put("Update", new UpdatePolicy()); - policies.put("Delete", new DeletePolicy()); - policies.put("UpdateProperties", new UpdatePropertiesPolicy()); - policies.put("Assoc", new AssocPolicy()); - policies.put("WriteContent", new WriteContentPolicy()); - policies.put("Capability", new CapabilityPolicy()); - policies.put("Declare", new DeclarePolicy()); - policies.put("ReadProperty", new ReadPropertyPolicy()); - } - - /** - * Set the permission service - * - * @param permissionService - */ - public void setPermissionService(PermissionService permissionService) - { - this.permissionService = permissionService; - } - - /** - * Set the node service - * - * @param nodeService - */ - public void setNodeService(NodeService nodeService) - { - this.nodeService = nodeService; + this.applicationContext = applicationContext; } /** @@ -144,6 +100,7 @@ public class RMEntryVoter extends RMSecurityCommon } /** + * * @return */ public OwnableService getOwnableService() @@ -164,23 +121,27 @@ public class RMEntryVoter extends RMSecurityCommon { this.nspr = nspr; } - - public void setCaveatConfigComponent(RMCaveatConfigComponent caveatConfigComponent) + + /** + * Register a policy the voter + * + * @param policy policy + */ + public void registerPolicy(Policy policy) { - this.caveatConfigComponent = caveatConfigComponent; - } - - public void setDictionaryService(DictionaryService dictionaryService) - { - this.dictionaryService = dictionaryService; + policies.put(policy.getName(), policy); } + /** + * @see net.sf.acegisecurity.vote.AccessDecisionVoter#supports(net.sf.acegisecurity.ConfigAttribute) + */ + @Override public boolean supports(ConfigAttribute attribute) { if ((attribute.getAttribute() != null) - && (attribute.getAttribute().equals(RM_ABSTAIN) - || attribute.getAttribute().equals(RM_QUERY) || attribute.getAttribute().equals(RM_ALLOW) || attribute.getAttribute().equals(RM_DENY) - || attribute.getAttribute().startsWith(RM_CAP) || attribute.getAttribute().startsWith(RM))) + && (attribute.getAttribute().equals(ConfigAttributeDefinition.RM_ABSTAIN) + || attribute.getAttribute().equals(ConfigAttributeDefinition.RM_QUERY) || attribute.getAttribute().equals(ConfigAttributeDefinition.RM_ALLOW) || attribute.getAttribute().equals(ConfigAttributeDefinition.RM_DENY) + || attribute.getAttribute().startsWith(ConfigAttributeDefinition.RM_CAP) || attribute.getAttribute().startsWith(ConfigAttributeDefinition.RM))) { return true; } @@ -197,7 +158,7 @@ public class RMEntryVoter extends RMSecurityCommon } @SuppressWarnings("unchecked") - public int vote(Authentication authentication, Object object, ConfigAttributeDefinition config) + public int vote(Authentication authentication, Object object, net.sf.acegisecurity.ConfigAttributeDefinition config) { if (logger.isDebugEnabled()) { @@ -214,7 +175,7 @@ public class RMEntryVoter extends RMSecurityCommon return AccessDecisionVoter.ACCESS_GRANTED; } - List supportedDefinitions = extractSupportedDefinitions(config); + List supportedDefinitions = extractSupportedDefinitions(config); // No RM definitions so we do not vote if (supportedDefinitions.size() == 0) @@ -231,36 +192,36 @@ public class RMEntryVoter extends RMSecurityCommon // If any abstain we deny // All present must vote to allow unless an explicit direction comes first (e.g. RM_ALLOW) - for (ConfigAttributeDefintion cad : supportedDefinitions) + for (ConfigAttributeDefinition cad : supportedDefinitions) { // Whatever is found first takes precedence - if (cad.typeString.equals(RM_DENY)) + if (cad.getTypeString().equals(ConfigAttributeDefinition.RM_DENY)) { return AccessDecisionVoter.ACCESS_DENIED; } - else if (cad.typeString.equals(RM_ABSTAIN)) + else if (cad.getTypeString().equals(ConfigAttributeDefinition.RM_ABSTAIN)) { return AccessDecisionVoter.ACCESS_ABSTAIN; } - else if (cad.typeString.equals(RM_ALLOW)) + else if (cad.getTypeString().equals(ConfigAttributeDefinition.RM_ALLOW)) { return AccessDecisionVoter.ACCESS_GRANTED; } // RM_QUERY is a special case - the entry is allowed and filtering sorts out the results // It is distinguished from RM_ALLOW so query may have additional behaviour in the future - else if (cad.typeString.equals(RM_QUERY)) + else if (cad.getTypeString().equals(ConfigAttributeDefinition.RM_QUERY)) { return AccessDecisionVoter.ACCESS_GRANTED; } // Ignore config that references method arguments that do not exist // Arguably we should deny here but that requires a full impact analysis // These entries effectively abstain - else if (((cad.parameters.get(0) != null) && (cad.parameters.get(0) >= invocation.getArguments().length)) - || ((cad.parameters.get(1) != null) && (cad.parameters.get(1) >= invocation.getArguments().length))) + else if (((cad.getParameters().get(0) != null) && (cad.getParameters().get(0) >= invocation.getArguments().length)) || + ((cad.getParameters().get(1) != null) && (cad.getParameters().get(1) >= invocation.getArguments().length))) { continue; } - else if (cad.typeString.equals(RM_CAP)) + else if (cad.getTypeString().equals(ConfigAttributeDefinition.RM_CAP)) { switch(checkCapability(invocation, params, cad)) { @@ -271,11 +232,11 @@ public class RMEntryVoter extends RMSecurityCommon { if(logger.isTraceEnabled()) { - logger.trace("Capability " + cad.required + " abstained for " + invocation.getMethod(), new IllegalStateException()); + logger.trace("Capability " + cad.getRequired() + " abstained for " + invocation.getMethod(), new IllegalStateException()); } else { - logger.debug("Capability " + cad.required + " abstained for " + invocation.getMethod()); + logger.debug("Capability " + cad.getRequired() + " abstained for " + invocation.getMethod()); } } // abstain denies @@ -284,7 +245,7 @@ public class RMEntryVoter extends RMSecurityCommon break; } } - else if (cad.typeString.equals(RM)) + else if (cad.getTypeString().equals(ConfigAttributeDefinition.RM)) { switch(checkPolicy(invocation, params, cad)) { @@ -295,11 +256,11 @@ public class RMEntryVoter extends RMSecurityCommon { if(logger.isTraceEnabled()) { - logger.trace("Policy " + cad.policyName + " abstained for " + invocation.getMethod(), new IllegalStateException()); + logger.trace("Policy " + cad.getPolicyName() + " abstained for " + invocation.getMethod(), new IllegalStateException()); } else { - logger.debug("Policy " + cad.policyName + " abstained for " + invocation.getMethod()); + logger.debug("Policy " + cad.getPolicyName() + " abstained for " + invocation.getMethod()); } } // abstain denies @@ -317,14 +278,14 @@ public class RMEntryVoter extends RMSecurityCommon } @SuppressWarnings("unchecked") - private int checkCapability(MethodInvocation invocation, Class[] params, ConfigAttributeDefintion cad) + private int checkCapability(MethodInvocation invocation, Class[] params, ConfigAttributeDefinition cad) { - NodeRef testNodeRef = getTestNode(getNodeService(), getRecordsManagementService(), invocation, params, cad.parameters.get(0), cad.parent); + NodeRef testNodeRef = getTestNode(invocation, params, cad.getParameters().get(0), cad.isParent()); if (testNodeRef == null) { return AccessDecisionVoter.ACCESS_ABSTAIN; } - Capability capability = capabilityService.getCapability(cad.required.getName()); + Capability capability = capabilityService.getCapability(cad.getRequired().getName()); if (capability == null) { return AccessDecisionVoter.ACCESS_DENIED; @@ -334,210 +295,16 @@ public class RMEntryVoter extends RMSecurityCommon } @SuppressWarnings("unchecked") - private static QName getType(NodeService nodeService, MethodInvocation invocation, Class[] params, int position, boolean parent) + private int checkPolicy(MethodInvocation invocation, Class[] params, ConfigAttributeDefinition cad) { - if (QName.class.isAssignableFrom(params[position])) - { - if (invocation.getArguments()[position] != null) - { - QName qname = (QName) invocation.getArguments()[position]; - return qname; - } - } - else if (NodeRef.class.isAssignableFrom(params[position])) - { - if (invocation.getArguments()[position] != null) - { - NodeRef nodeRef = (NodeRef) invocation.getArguments()[position]; - return nodeService.getType(nodeRef); - } - } - - return null; - } - - @SuppressWarnings("unchecked") - private static QName getQName(MethodInvocation invocation, Class[] params, int position) - { - if (QName.class.isAssignableFrom(params[position])) - { - if (invocation.getArguments()[position] != null) - { - QName qname = (QName) invocation.getArguments()[position]; - return qname; - } - } - throw new ACLEntryVoterException("Unknown type"); - } - - @SuppressWarnings("unchecked") - private static Serializable getProperty(MethodInvocation invocation, Class[] params, int position) - { - if (invocation.getArguments()[position] == null) - { - return null; - } - if (Serializable.class.isAssignableFrom(params[position])) - { - if (invocation.getArguments()[position] != null) - { - Serializable property = (Serializable) invocation.getArguments()[position]; - return property; - } - } - throw new ACLEntryVoterException("Unknown type"); - } - - @SuppressWarnings("unchecked") - private static Map getProperties(MethodInvocation invocation, Class[] params, int position) - { - if (invocation.getArguments()[position] == null) - { - return null; - } - if (Map.class.isAssignableFrom(params[position])) - { - if (invocation.getArguments()[position] != null) - { - Map properties = (Map) invocation.getArguments()[position]; - return properties; - } - } - throw new ACLEntryVoterException("Unknown type"); - } - - @SuppressWarnings("unchecked") - private static NodeRef getTestNode(NodeService nodeService, RecordsManagementService rmService, MethodInvocation invocation, Class[] params, int position, boolean parent) - { - NodeRef testNodeRef = null; - if (position < 0) - { - // Test against the fileplan root node - List rmRoots = rmService.getFilePlans(); - if (rmRoots.size() != 0) - { - // TODO for now we can take the first one as we only support a single rm site - testNodeRef = rmRoots.get(0); - - if (logger.isDebugEnabled()) - { - logger.debug("\tPermission test against the rm root node " + nodeService.getPath(testNodeRef)); - } - } - } - else if (StoreRef.class.isAssignableFrom(params[position])) - { - if (invocation.getArguments()[position] != null) - { - if (logger.isDebugEnabled()) - { - logger.debug("\tPermission test against the store - using permissions on the root node"); - } - StoreRef storeRef = (StoreRef) invocation.getArguments()[position]; - if (nodeService.exists(storeRef)) - { - testNodeRef = nodeService.getRootNode(storeRef); - } - } - } - else if (NodeRef.class.isAssignableFrom(params[position])) - { - testNodeRef = (NodeRef) invocation.getArguments()[position]; - if (parent) - { - testNodeRef = nodeService.getPrimaryParent(testNodeRef).getParentRef(); - if (logger.isDebugEnabled()) - { - if (nodeService.exists(testNodeRef)) - { - logger.debug("\tPermission test for parent on node " + nodeService.getPath(testNodeRef)); - } - else - { - logger.debug("\tPermission test for parent on non-existing node " + testNodeRef); - } - logger.debug("\tPermission test for parent on node " + nodeService.getPath(testNodeRef)); - } - } - else - { - if (logger.isDebugEnabled()) - { - if (nodeService.exists(testNodeRef)) - { - logger.debug("\tPermission test on node " + nodeService.getPath(testNodeRef)); - } - else - { - logger.debug("\tPermission test on non-existing node " + testNodeRef); - } - } - } - } - else if (ChildAssociationRef.class.isAssignableFrom(params[position])) - { - if (invocation.getArguments()[position] != null) - { - if (parent) - { - testNodeRef = ((ChildAssociationRef) invocation.getArguments()[position]).getParentRef(); - } - else - { - testNodeRef = ((ChildAssociationRef) invocation.getArguments()[position]).getChildRef(); - } - if (logger.isDebugEnabled()) - { - if (nodeService.exists(testNodeRef)) - { - logger.debug("\tPermission test on node " + nodeService.getPath(testNodeRef)); - } - else - { - logger.debug("\tPermission test on non-existing node " + testNodeRef); - } - } - } - } - else if (AssociationRef.class.isAssignableFrom(params[position])) - { - if (invocation.getArguments()[position] != null) - { - if (parent) - { - testNodeRef = ((AssociationRef) invocation.getArguments()[position]).getSourceRef(); - } - else - { - testNodeRef = ((AssociationRef) invocation.getArguments()[position]).getTargetRef(); - } - if (logger.isDebugEnabled()) - { - if (nodeService.exists(testNodeRef)) - { - logger.debug("\tPermission test on node " + nodeService.getPath(testNodeRef)); - } - else - { - logger.debug("\tPermission test on non-existing node " + testNodeRef); - } - } - } - } - return testNodeRef; - } - - @SuppressWarnings("unchecked") - private int checkPolicy(MethodInvocation invocation, Class[] params, ConfigAttributeDefintion cad) - { - Policy policy = policies.get(cad.policyName); + Policy policy = policies.get(cad.getPolicyName()); if (policy == null) { return AccessDecisionVoter.ACCESS_GRANTED; } else { - return policy.evaluate(this.nodeService, this.recordsManagementService, this.capabilityService, invocation, params, cad); + return policy.evaluate(invocation, params, cad); } } @@ -548,9 +315,9 @@ public class RMEntryVoter extends RMSecurityCommon } @SuppressWarnings("unchecked") - private List extractSupportedDefinitions(ConfigAttributeDefinition config) + private List extractSupportedDefinitions(net.sf.acegisecurity.ConfigAttributeDefinition config) { - List definitions = new ArrayList(2); + List definitions = new ArrayList(2); Iterator iter = config.getConfigAttributes(); while (iter.hasNext()) @@ -559,454 +326,11 @@ public class RMEntryVoter extends RMSecurityCommon if (this.supports(attr)) { - definitions.add(new ConfigAttributeDefintion(attr)); + definitions.add(new ConfigAttributeDefinition(attr, nspr)); } } return definitions; } - - /** - * @return the nodeService - */ - public NodeService getNodeService() - { - return nodeService; - } - - /** - * @return the permissionService - */ - public PermissionService getPermissionService() - { - return permissionService; - } - - /** - * @return the caveatConfigService - */ - public RMCaveatConfigComponent getCaveatConfigComponent() - { - return caveatConfigComponent; - } - - /** - * @param recordsManagementService - * the recordsManagementService to set - */ - public void setRecordsManagementService(RecordsManagementService recordsManagementService) - { - this.recordsManagementService = recordsManagementService; - } - - /** - * @return the recordsManagementService - */ - public RecordsManagementService getRecordsManagementService() - { - return recordsManagementService; - } - - public void setDispositionService(DispositionService dispositionService) - { - this.dispositionService = dispositionService; - } - - public DispositionService getDispositionService() - { - return dispositionService; - } - - /** - * @return the dictionaryService - */ - public DictionaryService getDictionaryService() - { - return dictionaryService; - } - - private class ConfigAttributeDefintion - { - String typeString; - - String policyName; - - SimplePermissionReference required; - - HashMap parameters = new HashMap(2, 1.0f); - - boolean parent = false; - - ConfigAttributeDefintion(ConfigAttribute attr) - { - StringTokenizer st = new StringTokenizer(attr.getAttribute(), ".", false); - if (st.countTokens() < 1) - { - throw new ACLEntryVoterException("There must be at least one token in a config attribute"); - } - typeString = st.nextToken(); - - if (!(typeString.equals(RM) || typeString.equals(RM_ALLOW) || typeString.equals(RM_CAP) || typeString.equals(RM_DENY) || typeString.equals(RM_QUERY) || typeString - .equals(RM_ABSTAIN))) - { - throw new ACLEntryVoterException("Invalid type: must be ACL_NODE, ACL_PARENT or ACL_ALLOW"); - } - - if (typeString.equals(RM)) - { - policyName = st.nextToken(); - int position = 0; - while (st.hasMoreElements()) - { - String numberString = st.nextToken(); - Integer value = Integer.parseInt(numberString); - parameters.put(position, value); - position++; - } - } - else if (typeString.equals(RM_CAP)) - { - String numberString = st.nextToken(); - String qNameString = st.nextToken(); - String permissionString = st.nextToken(); - - Integer value = Integer.parseInt(numberString); - parameters.put(0, value); - - QName qName = QName.createQName(qNameString, nspr); - - required = SimplePermissionReference.getPermissionReference(qName, permissionString); - - if (st.hasMoreElements()) - { - parent = true; - } - } - } - } - - interface Policy - { - /** - * - * @param nodeService - * @param rmService - * @param capabilitiesService - * @param invocation - * @param params - * @param cad - * @return - */ - @SuppressWarnings("unchecked") - int evaluate( - NodeService nodeService, - RecordsManagementService rmService, - CapabilityService capabilitiesService, - MethodInvocation invocation, - Class[] params, - ConfigAttributeDefintion cad); - } - - private static class ReadPolicy implements Policy - { - - @SuppressWarnings("unchecked") - public int evaluate( - NodeService nodeService, - RecordsManagementService rmService, - CapabilityService capabilityService, - MethodInvocation invocation, - Class[] params, - ConfigAttributeDefintion cad) - { - NodeRef testNodeRef = getTestNode(nodeService, rmService, invocation, params, cad.parameters.get(0), cad.parent); - return capabilityService.getCapability(RMPermissionModel.VIEW_RECORDS).evaluate(testNodeRef); - } - - } - - private static class CreatePolicy implements Policy - { - - @SuppressWarnings("unchecked") - public int evaluate( - NodeService nodeService, - RecordsManagementService rmService, - CapabilityService capabilityService, - MethodInvocation invocation, - Class[] params, - ConfigAttributeDefintion cad) - { - - NodeRef destination = getTestNode(nodeService, rmService, invocation, params, cad.parameters.get(0), cad.parent); - QName type = getType(nodeService, invocation, params, cad.parameters.get(1), cad.parent); - // linkee is not null for creating secondary child assocs - NodeRef linkee = getTestNode(nodeService, rmService, invocation, params, cad.parameters.get(1), cad.parent); - QName assocType = null; - if(cad.parameters.size() > 2) - { - assocType = getType(nodeService, invocation, params, cad.parameters.get(2), cad.parent); - } - - return ((CreateCapability)capabilityService.getCapability("Create")).evaluate(destination, linkee, type, assocType); - } - - } - - private static class MovePolicy implements Policy - { - - @SuppressWarnings("unchecked") - public int evaluate( - NodeService nodeService, - RecordsManagementService rmService, - CapabilityService capabilityService, - MethodInvocation invocation, - Class[] params, - ConfigAttributeDefintion cad) - { - - NodeRef movee = null; - if (cad.parameters.get(0) > -1) - { - movee = getTestNode(nodeService, rmService, invocation, params, cad.parameters.get(0), cad.parent); - } - - NodeRef destination = null; - if (cad.parameters.get(1) > -1) - { - destination = getTestNode(nodeService, rmService, invocation, params, cad.parameters.get(1), cad.parent); - } - - if ((movee != null) && (destination != null)) - { - return capabilityService.getCapability("Move").evaluate(movee, destination); - } - else - { - return AccessDecisionVoter.ACCESS_DENIED; - } - - } - } - - private static class UpdatePolicy implements Policy - { - - @SuppressWarnings("unchecked") - public int evaluate( - NodeService nodeService, - RecordsManagementService rmService, - CapabilityService capabilityService, - MethodInvocation invocation, - Class[] params, - ConfigAttributeDefintion cad) - { - NodeRef updatee = getTestNode(nodeService, rmService, invocation, params, cad.parameters.get(0), cad.parent); - QName aspectQName = null; - if (cad.parameters.size() > 1) - { - if (cad.parameters.get(1) > -1) - { - aspectQName = getQName(invocation, params, cad.parameters.get(1)); - } - } - Map properties = null; - if (cad.parameters.size() > 2) - { - if (cad.parameters.get(2) > -1) - { - properties = getProperties(invocation, params, cad.parameters.get(2)); - } - } - - UpdateCapability updateCapability = (UpdateCapability)capabilityService.getCapability("Update"); - return updateCapability.evaluate(updatee, aspectQName, properties); - } - - } - - private static class DeletePolicy implements Policy - { - - @SuppressWarnings("unchecked") - public int evaluate( - NodeService nodeService, - RecordsManagementService rmService, - CapabilityService capabilityService, - MethodInvocation invocation, - Class[] params, - ConfigAttributeDefintion cad) - { - NodeRef deletee = null; - if (cad.parameters.get(0) > -1) - { - deletee = getTestNode(nodeService, rmService, invocation, params, cad.parameters.get(0), cad.parent); - } - if (deletee != null) - { - - return capabilityService.getCapability("Delete").evaluate(deletee); - - } - else - { - return AccessDecisionVoter.ACCESS_DENIED; - } - } - - } - - private static class UpdatePropertiesPolicy implements Policy - { - @SuppressWarnings("unchecked") - public int evaluate( - NodeService nodeService, - RecordsManagementService rmService, - CapabilityService capabilityService, - MethodInvocation invocation, - Class[] params, - ConfigAttributeDefintion cad) - { - NodeRef updatee = getTestNode(nodeService, rmService, invocation, params, cad.parameters.get(0), cad.parent); - Map properties; - if (QName.class.isAssignableFrom(params[cad.parameters.get(1)])) - { - // single update/delete - // We have a specific property - QName propertyQName = getQName(invocation, params, cad.parameters.get(1)); - properties = new HashMap(1, 1.0f); - if (cad.parameters.size() > 2) - { - properties.put(propertyQName, getProperty(invocation, params, cad.parameters.get(2))); - } - else - { - properties.put(propertyQName, null); - } - } - else - { - properties = getProperties(invocation, params, cad.parameters.get(1)); - } - - return ((UpdatePropertiesCapability)capabilityService.getCapability("UpdateProperties")).evaluate(updatee, properties); - } - - } - - private static class AssocPolicy implements Policy - { - - @SuppressWarnings("unchecked") - public int evaluate( - NodeService nodeService, - RecordsManagementService rmService, - CapabilityService capabilityService, - MethodInvocation invocation, - Class[] params, - ConfigAttributeDefintion cad) - { - Policy policy = policies.get("Read"); - if (policy == null) - { - return AccessDecisionVoter.ACCESS_DENIED; - } - else - { - return policy.evaluate(nodeService, rmService, capabilityService, invocation, params, cad); - } - } - - } - - private static class WriteContentPolicy implements Policy - { - - @SuppressWarnings("unchecked") - public int evaluate( - NodeService nodeService, - RecordsManagementService rmService, - CapabilityService capabilityService, - MethodInvocation invocation, - Class[] params, - ConfigAttributeDefintion cad) - { - NodeRef updatee = getTestNode(nodeService, rmService, invocation, params, cad.parameters.get(0), cad.parent); - return capabilityService.getCapability("WriteContent").evaluate(updatee); - } - - } - - private static class CapabilityPolicy implements Policy - { - - @SuppressWarnings("unchecked") - public int evaluate( - NodeService nodeService, - RecordsManagementService rmService, - CapabilityService capabilityService, - MethodInvocation invocation, - Class[] params, - ConfigAttributeDefintion cad) - { - NodeRef assignee = getTestNode(nodeService, rmService, invocation, params, cad.parameters.get(0), cad.parent); - return capabilityService.getCapability(RMPermissionModel.MANAGE_ACCESS_CONTROLS).evaluate(assignee); - } - - } - - private static class DeclarePolicy implements Policy - { - - @SuppressWarnings("unchecked") - public int evaluate( - NodeService nodeService, - RecordsManagementService rmService, - CapabilityService capabilityService, - MethodInvocation invocation, - Class[] params, - ConfigAttributeDefintion cad) - { - NodeRef declaree = getTestNode(nodeService, rmService, invocation, params, cad.parameters.get(0), cad.parent); - return capabilityService.getCapability("Declare").evaluate(declaree); - } - - } - - private static class ReadPropertyPolicy implements Policy - { - - @SuppressWarnings("unchecked") - public int evaluate( - NodeService nodeService, - RecordsManagementService rmService, - CapabilityService capabilityService, - MethodInvocation invocation, - Class[] params, - ConfigAttributeDefintion cad) - { - NodeRef nodeRef = getTestNode(nodeService, rmService, invocation, params, cad.parameters.get(0), cad.parent); - QName propertyQName = getQName(invocation, params, cad.parameters.get(1)); - if(propertyQName.equals(RecordsManagementModel.PROP_HOLD_REASON)) - { - return capabilityService.getCapability(RMPermissionModel.VIEW_UPDATE_REASONS_FOR_FREEZE).evaluate(nodeRef); - } - else - { - return AccessDecisionVoter.ACCESS_GRANTED; - } - } - - } - - private ApplicationContext applicationContext; - - @Override - public void setApplicationContext(ApplicationContext applicationContext) - throws BeansException - { - this.applicationContext = applicationContext; - } } diff --git a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/capability/RMSecurityCommon.java b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/capability/RMSecurityCommon.java index 9ebada37c5..3679b25708 100644 --- a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/capability/RMSecurityCommon.java +++ b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/capability/RMSecurityCommon.java @@ -18,6 +18,8 @@ */ package org.alfresco.module.org_alfresco_module_rm.capability; +import java.util.List; + import net.sf.acegisecurity.vote.AccessDecisionVoter; import org.alfresco.module.org_alfresco_module_rm.RecordsManagementService; @@ -25,10 +27,14 @@ import org.alfresco.module.org_alfresco_module_rm.caveat.RMCaveatConfigComponent import org.alfresco.module.org_alfresco_module_rm.fileplan.FilePlanService; import org.alfresco.repo.security.authentication.AuthenticationUtil; import org.alfresco.repo.transaction.AlfrescoTransactionSupport; +import org.alfresco.service.cmr.repository.AssociationRef; +import org.alfresco.service.cmr.repository.ChildAssociationRef; import org.alfresco.service.cmr.repository.NodeRef; import org.alfresco.service.cmr.repository.NodeService; +import org.alfresco.service.cmr.repository.StoreRef; import org.alfresco.service.cmr.security.AccessStatus; import org.alfresco.service.cmr.security.PermissionService; +import org.aopalliance.intercept.MethodInvocation; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; @@ -220,4 +226,125 @@ public class RMSecurityCommon } } + + @SuppressWarnings("unchecked") + protected NodeRef getTestNode(MethodInvocation invocation, Class[] params, int position, boolean parent) + { + NodeRef testNodeRef = null; + if (position < 0) + { + // Test against the fileplan root node + List rmRoots = rmService.getFilePlans(); + if (rmRoots.size() != 0) + { + // TODO for now we can take the first one as we only support a single rm site + testNodeRef = rmRoots.get(0); + + if (logger.isDebugEnabled()) + { + logger.debug("\tPermission test against the rm root node " + nodeService.getPath(testNodeRef)); + } + } + } + else if (StoreRef.class.isAssignableFrom(params[position])) + { + if (invocation.getArguments()[position] != null) + { + if (logger.isDebugEnabled()) + { + logger.debug("\tPermission test against the store - using permissions on the root node"); + } + StoreRef storeRef = (StoreRef) invocation.getArguments()[position]; + if (nodeService.exists(storeRef)) + { + testNodeRef = nodeService.getRootNode(storeRef); + } + } + } + else if (NodeRef.class.isAssignableFrom(params[position])) + { + testNodeRef = (NodeRef) invocation.getArguments()[position]; + if (parent) + { + testNodeRef = nodeService.getPrimaryParent(testNodeRef).getParentRef(); + if (logger.isDebugEnabled()) + { + if (nodeService.exists(testNodeRef)) + { + logger.debug("\tPermission test for parent on node " + nodeService.getPath(testNodeRef)); + } + else + { + logger.debug("\tPermission test for parent on non-existing node " + testNodeRef); + } + logger.debug("\tPermission test for parent on node " + nodeService.getPath(testNodeRef)); + } + } + else + { + if (logger.isDebugEnabled()) + { + if (nodeService.exists(testNodeRef)) + { + logger.debug("\tPermission test on node " + nodeService.getPath(testNodeRef)); + } + else + { + logger.debug("\tPermission test on non-existing node " + testNodeRef); + } + } + } + } + else if (ChildAssociationRef.class.isAssignableFrom(params[position])) + { + if (invocation.getArguments()[position] != null) + { + if (parent) + { + testNodeRef = ((ChildAssociationRef) invocation.getArguments()[position]).getParentRef(); + } + else + { + testNodeRef = ((ChildAssociationRef) invocation.getArguments()[position]).getChildRef(); + } + if (logger.isDebugEnabled()) + { + if (nodeService.exists(testNodeRef)) + { + logger.debug("\tPermission test on node " + nodeService.getPath(testNodeRef)); + } + else + { + logger.debug("\tPermission test on non-existing node " + testNodeRef); + } + } + } + } + else if (AssociationRef.class.isAssignableFrom(params[position])) + { + if (invocation.getArguments()[position] != null) + { + if (parent) + { + testNodeRef = ((AssociationRef) invocation.getArguments()[position]).getSourceRef(); + } + else + { + testNodeRef = ((AssociationRef) invocation.getArguments()[position]).getTargetRef(); + } + if (logger.isDebugEnabled()) + { + if (nodeService.exists(testNodeRef)) + { + logger.debug("\tPermission test on node " + nodeService.getPath(testNodeRef)); + } + else + { + logger.debug("\tPermission test on non-existing node " + testNodeRef); + } + } + } + } + return testNodeRef; + } } diff --git a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/capability/policy/AbstractBasePolicy.java b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/capability/policy/AbstractBasePolicy.java new file mode 100644 index 0000000000..3504cc6b56 --- /dev/null +++ b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/capability/policy/AbstractBasePolicy.java @@ -0,0 +1,197 @@ +/* + * 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.capability.policy; + +import java.io.Serializable; +import java.util.Map; + +import org.alfresco.module.org_alfresco_module_rm.capability.CapabilityService; +import org.alfresco.module.org_alfresco_module_rm.capability.RMEntryVoter; +import org.alfresco.module.org_alfresco_module_rm.capability.RMSecurityCommon; +import org.alfresco.repo.security.permissions.impl.acegi.ACLEntryVoterException; +import org.alfresco.service.cmr.repository.NodeRef; +import org.alfresco.service.namespace.QName; +import org.aopalliance.intercept.MethodInvocation; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +/** + * Abstract base policy implementation + * + * @author Roy Wetherall + * @since 2.1 + */ +public abstract class AbstractBasePolicy extends RMSecurityCommon + implements Policy +{ + /** Logger */ + protected static Log logger = LogFactory.getLog(AbstractBasePolicy.class); + + /** Capability service */ + protected CapabilityService capabilityService; + + /** RM entry */ + protected RMEntryVoter rmEntryVoter; + + /** Policy name */ + protected String name; + + /** + * @param name policy name + */ + public void setName(String name) + { + this.name = name; + } + + /** + * @see org.alfresco.module.org_alfresco_module_rm.capability.policy.Policy#getName() + */ + @Override + public String getName() + { + return name; + } + + /** + * @param capabilityService capability service + */ + public void setCapabilityService(CapabilityService capabilityService) + { + this.capabilityService = capabilityService; + } + + /** + * @param rmEntryVoter rm entry voter + */ + public void setRmEntryVoter(RMEntryVoter rmEntryVoter) + { + this.rmEntryVoter = rmEntryVoter; + } + + /** + * Init method + */ + public void init() + { + rmEntryVoter.registerPolicy(this); + } + + /** + * + * @param invocation + * @param params + * @param position + * @param parent + * @return + */ + @SuppressWarnings("unchecked") + protected QName getType(MethodInvocation invocation, Class[] params, int position, boolean parent) + { + if (QName.class.isAssignableFrom(params[position])) + { + if (invocation.getArguments()[position] != null) + { + QName qname = (QName) invocation.getArguments()[position]; + return qname; + } + } + else if (NodeRef.class.isAssignableFrom(params[position])) + { + if (invocation.getArguments()[position] != null) + { + NodeRef nodeRef = (NodeRef) invocation.getArguments()[position]; + return nodeService.getType(nodeRef); + } + } + + return null; + } + + /** + * + * @param invocation + * @param params + * @param position + * @return + */ + @SuppressWarnings("unchecked") + protected QName getQName(MethodInvocation invocation, Class[] params, int position) + { + if (QName.class.isAssignableFrom(params[position])) + { + if (invocation.getArguments()[position] != null) + { + QName qname = (QName) invocation.getArguments()[position]; + return qname; + } + } + throw new ACLEntryVoterException("Unknown type"); + } + + /** + * + * @param invocation + * @param params + * @param position + * @return + */ + @SuppressWarnings("unchecked") + protected Serializable getProperty(MethodInvocation invocation, Class[] params, int position) + { + if (invocation.getArguments()[position] == null) + { + return null; + } + if (Serializable.class.isAssignableFrom(params[position])) + { + if (invocation.getArguments()[position] != null) + { + Serializable property = (Serializable) invocation.getArguments()[position]; + return property; + } + } + throw new ACLEntryVoterException("Unknown type"); + } + + /** + * + * @param invocation + * @param params + * @param position + * @return + */ + @SuppressWarnings("unchecked") + protected Map getProperties(MethodInvocation invocation, Class[] params, int position) + { + if (invocation.getArguments()[position] == null) + { + return null; + } + if (Map.class.isAssignableFrom(params[position])) + { + if (invocation.getArguments()[position] != null) + { + Map properties = (Map) invocation.getArguments()[position]; + return properties; + } + } + throw new ACLEntryVoterException("Unknown type"); + } +} diff --git a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/capability/policy/AssocPolicy.java b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/capability/policy/AssocPolicy.java new file mode 100644 index 0000000000..32f349bb95 --- /dev/null +++ b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/capability/policy/AssocPolicy.java @@ -0,0 +1,38 @@ +/* + * 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.capability.policy; + +import org.alfresco.module.org_alfresco_module_rm.capability.RMPermissionModel; +import org.alfresco.service.cmr.repository.NodeRef; +import org.aopalliance.intercept.MethodInvocation; + +public class AssocPolicy extends AbstractBasePolicy +{ + + @SuppressWarnings("unchecked") + public int evaluate( + MethodInvocation invocation, + Class[] params, + ConfigAttributeDefinition cad) + { + NodeRef testNodeRef = getTestNode(invocation, params, cad.getParameters().get(0), cad.isParent()); + return capabilityService.getCapability(RMPermissionModel.VIEW_RECORDS).evaluate(testNodeRef); + } + +} \ No newline at end of file diff --git a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/capability/policy/CapabilityPolicy.java b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/capability/policy/CapabilityPolicy.java new file mode 100644 index 0000000000..84f368aa4c --- /dev/null +++ b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/capability/policy/CapabilityPolicy.java @@ -0,0 +1,46 @@ +/* + * 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.capability.policy; + +import org.alfresco.module.org_alfresco_module_rm.capability.RMPermissionModel; +import org.alfresco.service.cmr.repository.NodeRef; +import org.aopalliance.intercept.MethodInvocation; + +/** + * + * @author Roy Wetherall + * @since 2.1 + */ +public class CapabilityPolicy extends AbstractBasePolicy +{ + /** + * @see org.alfresco.module.org_alfresco_module_rm.capability.policy.Policy#evaluate(org.aopalliance.intercept.MethodInvocation, java.lang.Class[], org.alfresco.module.org_alfresco_module_rm.capability.policy.ConfigAttributeDefinition) + */ + @Override + @SuppressWarnings("unchecked") + public int evaluate( + MethodInvocation invocation, + Class[] params, + ConfigAttributeDefinition cad) + { + NodeRef assignee = getTestNode(invocation, params, cad.getParameters().get(0), cad.isParent()); + return capabilityService.getCapability(RMPermissionModel.MANAGE_ACCESS_CONTROLS).evaluate(assignee); + } + +} \ No newline at end of file diff --git a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/capability/policy/ConfigAttributeDefinition.java b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/capability/policy/ConfigAttributeDefinition.java new file mode 100644 index 0000000000..fed2793d2a --- /dev/null +++ b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/capability/policy/ConfigAttributeDefinition.java @@ -0,0 +1,125 @@ +/* + * 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.capability.policy; + +import java.util.HashMap; +import java.util.StringTokenizer; + +import net.sf.acegisecurity.ConfigAttribute; + +import org.alfresco.repo.security.permissions.impl.SimplePermissionReference; +import org.alfresco.repo.security.permissions.impl.acegi.ACLEntryVoterException; +import org.alfresco.service.namespace.NamespacePrefixResolver; +import org.alfresco.service.namespace.QName; + +/** + * @author Roy Wetherall + * @since 2.1 + */ +public class ConfigAttributeDefinition +{ + public static final String RM = "RM"; + public static final String RM_ALLOW = "RM_ALLOW"; + public static final String RM_DENY = "RM_DENY"; + public static final String RM_CAP = "RM_CAP"; + public static final String RM_ABSTAIN = "RM_ABSTAIN"; + public static final String RM_QUERY = "RM_QUERY"; + + private String typeString; + + private String policyName; + + private SimplePermissionReference required; + + private HashMap parameters = new HashMap(2, 1.0f); + + private boolean parent = false; + + public ConfigAttributeDefinition(ConfigAttribute attr, NamespacePrefixResolver namespacePrefixResolver) + { + StringTokenizer st = new StringTokenizer(attr.getAttribute(), ".", false); + if (st.countTokens() < 1) + { + throw new ACLEntryVoterException("There must be at least one token in a config attribute"); + } + typeString = st.nextToken(); + + if (!(typeString.equals(RM) || typeString.equals(RM_ALLOW) || typeString.equals(RM_CAP) || typeString.equals(RM_DENY) || typeString.equals(RM_QUERY) || typeString + .equals(RM_ABSTAIN))) + { + throw new ACLEntryVoterException("Invalid type: must be ACL_NODE, ACL_PARENT or ACL_ALLOW"); + } + + if (typeString.equals(RM)) + { + policyName = st.nextToken(); + int position = 0; + while (st.hasMoreElements()) + { + String numberString = st.nextToken(); + Integer value = Integer.parseInt(numberString); + parameters.put(position, value); + position++; + } + } + else if (typeString.equals(RM_CAP)) + { + String numberString = st.nextToken(); + String qNameString = st.nextToken(); + String permissionString = st.nextToken(); + + Integer value = Integer.parseInt(numberString); + parameters.put(0, value); + + QName qName = QName.createQName(qNameString, namespacePrefixResolver); + + required = SimplePermissionReference.getPermissionReference(qName, permissionString); + + if (st.hasMoreElements()) + { + parent = true; + } + } + } + + public String getTypeString() + { + return typeString; + } + + public String getPolicyName() + { + return policyName; + } + + public SimplePermissionReference getRequired() + { + return required; + } + + public HashMap getParameters() + { + return parameters; + } + + public boolean isParent() + { + return parent; + } +} diff --git a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/capability/policy/CreatePolicy.java b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/capability/policy/CreatePolicy.java new file mode 100644 index 0000000000..4e2b3e6383 --- /dev/null +++ b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/capability/policy/CreatePolicy.java @@ -0,0 +1,48 @@ +/* + * 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.capability.policy; + +import org.alfresco.module.org_alfresco_module_rm.capability.impl.CreateCapability; +import org.alfresco.service.cmr.repository.NodeRef; +import org.alfresco.service.namespace.QName; +import org.aopalliance.intercept.MethodInvocation; + +public class CreatePolicy extends AbstractBasePolicy +{ + @SuppressWarnings("unchecked") + public int evaluate( + MethodInvocation invocation, + Class[] params, + ConfigAttributeDefinition cad) + { + + NodeRef destination = getTestNode(invocation, params, cad.getParameters().get(0), cad.isParent()); + QName type = getType(invocation, params, cad.getParameters().get(1), cad.isParent()); + // linkee is not null for creating secondary child assocs + NodeRef linkee = getTestNode(invocation, params, cad.getParameters().get(1), cad.isParent()); + QName assocType = null; + if(cad.getParameters().size() > 2) + { + assocType = getType(invocation, params, cad.getParameters().get(2), cad.isParent()); + } + + return ((CreateCapability)capabilityService.getCapability("Create")).evaluate(destination, linkee, type, assocType); + } + +} \ No newline at end of file diff --git a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/capability/policy/DeclarePolicy.java b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/capability/policy/DeclarePolicy.java new file mode 100644 index 0000000000..8a545d1b42 --- /dev/null +++ b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/capability/policy/DeclarePolicy.java @@ -0,0 +1,37 @@ +/* + * 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.capability.policy; + +import org.alfresco.service.cmr.repository.NodeRef; +import org.aopalliance.intercept.MethodInvocation; + +public class DeclarePolicy extends AbstractBasePolicy +{ + + @SuppressWarnings("unchecked") + public int evaluate( + MethodInvocation invocation, + Class[] params, + ConfigAttributeDefinition cad) + { + NodeRef declaree = getTestNode(invocation, params, cad.getParameters().get(0), cad.isParent()); + return capabilityService.getCapability("Declare").evaluate(declaree); + } + +} \ No newline at end of file diff --git a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/capability/policy/DeletePolicy.java b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/capability/policy/DeletePolicy.java new file mode 100644 index 0000000000..ecbdc0f658 --- /dev/null +++ b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/capability/policy/DeletePolicy.java @@ -0,0 +1,52 @@ +/* + * 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.capability.policy; + +import net.sf.acegisecurity.vote.AccessDecisionVoter; + +import org.alfresco.service.cmr.repository.NodeRef; +import org.aopalliance.intercept.MethodInvocation; + +public class DeletePolicy extends AbstractBasePolicy +{ + + @SuppressWarnings("unchecked") + public int evaluate( + MethodInvocation invocation, + Class[] params, + ConfigAttributeDefinition cad) + { + NodeRef deletee = null; + if (cad.getParameters().get(0) > -1) + { + deletee = getTestNode(invocation, params, cad.getParameters().get(0), cad.isParent()); + } + if (deletee != null) + { + + return capabilityService.getCapability("Delete").evaluate(deletee); + + } + else + { + return AccessDecisionVoter.ACCESS_DENIED; + } + } + +} \ No newline at end of file diff --git a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/capability/policy/MovePolicy.java b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/capability/policy/MovePolicy.java new file mode 100644 index 0000000000..f37defbd5f --- /dev/null +++ b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/capability/policy/MovePolicy.java @@ -0,0 +1,58 @@ +/* + * 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.capability.policy; + +import net.sf.acegisecurity.vote.AccessDecisionVoter; + +import org.alfresco.service.cmr.repository.NodeRef; +import org.aopalliance.intercept.MethodInvocation; + +public class MovePolicy extends AbstractBasePolicy +{ + + @SuppressWarnings("unchecked") + public int evaluate( + MethodInvocation invocation, + Class[] params, + ConfigAttributeDefinition cad) + { + + NodeRef movee = null; + if (cad.getParameters().get(0) > -1) + { + movee = getTestNode(invocation, params, cad.getParameters().get(0), cad.isParent()); + } + + NodeRef destination = null; + if (cad.getParameters().get(1) > -1) + { + destination = getTestNode(invocation, params, cad.getParameters().get(1), cad.isParent()); + } + + if ((movee != null) && (destination != null)) + { + return capabilityService.getCapability("Move").evaluate(movee, destination); + } + else + { + return AccessDecisionVoter.ACCESS_DENIED; + } + + } +} \ No newline at end of file diff --git a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/capability/policy/Policy.java b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/capability/policy/Policy.java new file mode 100644 index 0000000000..54083ed9a7 --- /dev/null +++ b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/capability/policy/Policy.java @@ -0,0 +1,49 @@ +/* + * 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.capability.policy; + +import org.aopalliance.intercept.MethodInvocation; + +/** + * Policy interface + * + * @author Roy Wetherall + * @since 2.1 + */ +public interface Policy +{ + /** + * @return policy name + */ + String getName(); + + /** + * Evaluate the policy + * + * @param invocation + * @param params + * @param cad + * @return + */ + @SuppressWarnings("unchecked") + int evaluate( + MethodInvocation invocation, + Class[] params, + ConfigAttributeDefinition cad); +} \ No newline at end of file diff --git a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/capability/policy/ReadPolicy.java b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/capability/policy/ReadPolicy.java new file mode 100644 index 0000000000..6423886b63 --- /dev/null +++ b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/capability/policy/ReadPolicy.java @@ -0,0 +1,37 @@ +/* + * 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.capability.policy; + +import org.alfresco.module.org_alfresco_module_rm.capability.RMPermissionModel; +import org.alfresco.service.cmr.repository.NodeRef; +import org.aopalliance.intercept.MethodInvocation; + +public class ReadPolicy extends AbstractBasePolicy +{ + + @SuppressWarnings("unchecked") + public int evaluate( + MethodInvocation invocation, + Class[] params, + ConfigAttributeDefinition cad) + { + NodeRef testNodeRef = getTestNode(invocation, params, cad.getParameters().get(0), cad.isParent()); + return capabilityService.getCapability(RMPermissionModel.VIEW_RECORDS).evaluate(testNodeRef); + } +} \ No newline at end of file diff --git a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/capability/policy/ReadPropertyPolicy.java b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/capability/policy/ReadPropertyPolicy.java new file mode 100644 index 0000000000..f64827f308 --- /dev/null +++ b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/capability/policy/ReadPropertyPolicy.java @@ -0,0 +1,50 @@ +/* + * 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.capability.policy; + +import net.sf.acegisecurity.vote.AccessDecisionVoter; + +import org.alfresco.module.org_alfresco_module_rm.capability.RMPermissionModel; +import org.alfresco.module.org_alfresco_module_rm.model.RecordsManagementModel; +import org.alfresco.service.cmr.repository.NodeRef; +import org.alfresco.service.namespace.QName; +import org.aopalliance.intercept.MethodInvocation; + +public class ReadPropertyPolicy extends AbstractBasePolicy +{ + + @SuppressWarnings("unchecked") + public int evaluate( + MethodInvocation invocation, + Class[] params, + ConfigAttributeDefinition cad) + { + NodeRef nodeRef = getTestNode(invocation, params, cad.getParameters().get(0), cad.isParent()); + QName propertyQName = getQName(invocation, params, cad.getParameters().get(1)); + if(propertyQName.equals(RecordsManagementModel.PROP_HOLD_REASON)) + { + return capabilityService.getCapability(RMPermissionModel.VIEW_UPDATE_REASONS_FOR_FREEZE).evaluate(nodeRef); + } + else + { + return AccessDecisionVoter.ACCESS_GRANTED; + } + } + +} \ No newline at end of file diff --git a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/capability/policy/UpdatePolicy.java b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/capability/policy/UpdatePolicy.java new file mode 100644 index 0000000000..3508b2fe38 --- /dev/null +++ b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/capability/policy/UpdatePolicy.java @@ -0,0 +1,60 @@ +/* + * 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.capability.policy; + +import java.io.Serializable; +import java.util.Map; + +import org.alfresco.module.org_alfresco_module_rm.capability.impl.UpdateCapability; +import org.alfresco.service.cmr.repository.NodeRef; +import org.alfresco.service.namespace.QName; +import org.aopalliance.intercept.MethodInvocation; + +public class UpdatePolicy extends AbstractBasePolicy +{ + + @SuppressWarnings("unchecked") + public int evaluate( + MethodInvocation invocation, + Class[] params, + ConfigAttributeDefinition cad) + { + NodeRef updatee = getTestNode(invocation, params, cad.getParameters().get(0), cad.isParent()); + QName aspectQName = null; + if (cad.getParameters().size() > 1) + { + if (cad.getParameters().get(1) > -1) + { + aspectQName = getQName(invocation, params, cad.getParameters().get(1)); + } + } + Map properties = null; + if (cad.getParameters().size() > 2) + { + if (cad.getParameters().get(2) > -1) + { + properties = getProperties(invocation, params, cad.getParameters().get(2)); + } + } + + UpdateCapability updateCapability = (UpdateCapability)capabilityService.getCapability("Update"); + return updateCapability.evaluate(updatee, aspectQName, properties); + } + +} \ No newline at end of file diff --git a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/capability/policy/UpdatePropertiesPolicy.java b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/capability/policy/UpdatePropertiesPolicy.java new file mode 100644 index 0000000000..c8bb219884 --- /dev/null +++ b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/capability/policy/UpdatePropertiesPolicy.java @@ -0,0 +1,63 @@ +/* + * 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.capability.policy; + +import java.io.Serializable; +import java.util.HashMap; +import java.util.Map; + +import org.alfresco.module.org_alfresco_module_rm.capability.impl.UpdatePropertiesCapability; +import org.alfresco.service.cmr.repository.NodeRef; +import org.alfresco.service.namespace.QName; +import org.aopalliance.intercept.MethodInvocation; + +public class UpdatePropertiesPolicy extends AbstractBasePolicy +{ + @SuppressWarnings("unchecked") + public int evaluate( + MethodInvocation invocation, + Class[] params, + ConfigAttributeDefinition cad) + { + NodeRef updatee = getTestNode(invocation, params, cad.getParameters().get(0), cad.isParent()); + Map properties; + if (QName.class.isAssignableFrom(params[cad.getParameters().get(1)])) + { + // single update/delete + // We have a specific property + QName propertyQName = getQName(invocation, params, cad.getParameters().get(1)); + properties = new HashMap(1, 1.0f); + if (cad.getParameters().size() > 2) + { + properties.put(propertyQName, getProperty(invocation, params, cad.getParameters().get(2))); + } + else + { + properties.put(propertyQName, null); + } + } + else + { + properties = getProperties(invocation, params, cad.getParameters().get(1)); + } + + return ((UpdatePropertiesCapability)capabilityService.getCapability("UpdateProperties")).evaluate(updatee, properties); + } + +} \ No newline at end of file diff --git a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/capability/policy/WriteContentPolicy.java b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/capability/policy/WriteContentPolicy.java new file mode 100644 index 0000000000..dd3ebb3f29 --- /dev/null +++ b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/capability/policy/WriteContentPolicy.java @@ -0,0 +1,37 @@ +/* + * 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.capability.policy; + +import org.alfresco.service.cmr.repository.NodeRef; +import org.aopalliance.intercept.MethodInvocation; + +public class WriteContentPolicy extends AbstractBasePolicy +{ + + @SuppressWarnings("unchecked") + public int evaluate( + MethodInvocation invocation, + Class[] params, + ConfigAttributeDefinition cad) + { + NodeRef updatee = getTestNode(invocation, params, cad.getParameters().get(0), cad.isParent()); + return capabilityService.getCapability("WriteContent").evaluate(updatee); + } + +} \ No newline at end of file diff --git a/rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/service/CapabilityServiceImplTest.java b/rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/service/CapabilityServiceImplTest.java index 021ede32a6..8c4a187119 100644 --- a/rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/service/CapabilityServiceImplTest.java +++ b/rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/service/CapabilityServiceImplTest.java @@ -178,7 +178,7 @@ public class CapabilityServiceImplTest extends BaseRMTestCase assertNotNull(vitalRecordCapabilities); vitalRecordCapabilitiesSize = vitalRecordCapabilities.size(); - assertEquals(1, vitalRecordCapabilitiesSize); + assertTrue(vitalRecordCapabilitiesSize > 0); return null; }