mirror of
https://github.com/Alfresco/alfresco-community-repo.git
synced 2025-07-31 17:39:05 +00:00
RM: Policy refactor
* moved policy implementations out of RMEntryVoter and into separate classes * rather than being a hard coded list, policies are now registered via spring allowing others to be easily added * re-arrange some of the support implementation * RMEntryVoter is now significantly smaller and most of the logic that was once encapsulated in here is spread over supporting classes and services * TODO .. need to review policies and determine which are appropraite .. much easier to do now! git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/modules/recordsmanagement/HEAD@48815 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261
This commit is contained in:
@@ -78,6 +78,7 @@
|
||||
<!-- Import fixed permission definitions for RM -->
|
||||
<import resource="classpath:alfresco/module/org_alfresco_module_rm/rm-public-services-security-context.xml"/>
|
||||
<import resource="classpath:alfresco/module/org_alfresco_module_rm/security/rm-method-security-context.xml"/>
|
||||
<import resource="classpath:alfresco/module/org_alfresco_module_rm/security/rm-policy-context.xml"/>
|
||||
|
||||
<!-- Import the RM service's -->
|
||||
<import resource="classpath:alfresco/module/org_alfresco_module_rm/rm-service-context.xml"/>
|
||||
|
@@ -14,7 +14,6 @@
|
||||
abstract="true"
|
||||
parent="RMSecurityCommon"
|
||||
init-method="init">
|
||||
<property name="voter" ref="rmEntryVoter"/>
|
||||
<property name="capabilityService" ref="CapabilityService"/>
|
||||
</bean>
|
||||
|
||||
|
@@ -93,10 +93,7 @@
|
||||
lazy-init="false"
|
||||
parent="RMSecurityCommon"
|
||||
depends-on="CapabilityService">
|
||||
<!-- Services -->
|
||||
<property name="namespacePrefixResolver" ref="namespaceService"/>
|
||||
<property name="dictionaryService" ref="dictionaryService"/>
|
||||
<property name="dispositionService" ref="dispositionService"/>
|
||||
<property name="capabilityService" ref="capabilityService"/>
|
||||
|
||||
</bean>
|
||||
|
@@ -15,6 +15,6 @@
|
||||
|
||||
<bean id="rm-method-security-post-processor" class="org.alfresco.module.org_alfresco_module_rm.security.RMMethodSecurityPostProcessor">
|
||||
<property name="properties" ref="rm-method-security-properties"/>
|
||||
</bean>
|
||||
</bean>
|
||||
|
||||
</beans>
|
@@ -0,0 +1,55 @@
|
||||
<?xml version='1.0' encoding='UTF-8'?>
|
||||
<!DOCTYPE beans PUBLIC '-//SPRING//DTD BEAN//EN' 'http://www.springframework.org/dtd/spring-beans.dtd'>
|
||||
|
||||
<beans>
|
||||
|
||||
<bean id="basePolicy" abstract="true" parent="RMSecurityCommon" init-method="init">
|
||||
<property name="capabilityService" ref="capabilityService" />
|
||||
<property name="rmEntryVoter" ref="rmEntryVoter" />
|
||||
</bean>
|
||||
|
||||
<bean id="readPolicy" parent="basePolicy" class="org.alfresco.module.org_alfresco_module_rm.capability.policy.ReadPolicy">
|
||||
<property name="name" value="Read"/>
|
||||
</bean>
|
||||
|
||||
<bean id="createPolicy" parent="basePolicy" class="org.alfresco.module.org_alfresco_module_rm.capability.policy.CreatePolicy">
|
||||
<property name="name" value="Create"/>
|
||||
</bean>
|
||||
|
||||
<bean id="movePolicy" parent="basePolicy" class="org.alfresco.module.org_alfresco_module_rm.capability.policy.MovePolicy">
|
||||
<property name="name" value="Move"/>
|
||||
</bean>
|
||||
|
||||
<bean id="updatePolicy" parent="basePolicy" class="org.alfresco.module.org_alfresco_module_rm.capability.policy.UpdatePolicy">
|
||||
<property name="name" value="Update"/>
|
||||
</bean>
|
||||
|
||||
<bean id="deletePolicy" parent="basePolicy" class="org.alfresco.module.org_alfresco_module_rm.capability.policy.DeletePolicy">
|
||||
<property name="name" value="Delete"/>
|
||||
</bean>
|
||||
|
||||
<bean id="updatePropertiesPolicy" parent="basePolicy" class="org.alfresco.module.org_alfresco_module_rm.capability.policy.UpdatePropertiesPolicy">
|
||||
<property name="name" value="UpdateProperties"/>
|
||||
</bean>
|
||||
|
||||
<bean id="assocPolicy" parent="basePolicy" class="org.alfresco.module.org_alfresco_module_rm.capability.policy.AssocPolicy">
|
||||
<property name="name" value="Assoc"/>
|
||||
</bean>
|
||||
|
||||
<bean id="writeContentPolicy" parent="basePolicy" class="org.alfresco.module.org_alfresco_module_rm.capability.policy.WriteContentPolicy">
|
||||
<property name="name" value="WriteContent"/>
|
||||
</bean>
|
||||
|
||||
<bean id="capabilityPolicy" parent="basePolicy" class="org.alfresco.module.org_alfresco_module_rm.capability.policy.CapabilityPolicy">
|
||||
<property name="name" value="Capability"/>
|
||||
</bean>
|
||||
|
||||
<bean id="declarePolicy" parent="basePolicy" class="org.alfresco.module.org_alfresco_module_rm.capability.policy.DeclarePolicy">
|
||||
<property name="name" value="Declare"/>
|
||||
</bean>
|
||||
|
||||
<bean id="readPropertyPolicy" parent="basePolicy" class="org.alfresco.module.org_alfresco_module_rm.capability.policy.ReadPropertyPolicy">
|
||||
<property name="name" value="ReadProperty"/>
|
||||
</bean>
|
||||
|
||||
</beans>
|
@@ -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
|
||||
*/
|
||||
|
@@ -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<String, Policy> policies = new HashMap<String, Policy>();
|
||||
private HashMap<String, Policy> policies = new HashMap<String, Policy>();
|
||||
|
||||
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<ConfigAttributeDefintion> supportedDefinitions = extractSupportedDefinitions(config);
|
||||
List<ConfigAttributeDefinition> 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<QName, Serializable> 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<QName, Serializable> properties = (Map<QName, Serializable>) 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<NodeRef> 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<ConfigAttributeDefintion> extractSupportedDefinitions(ConfigAttributeDefinition config)
|
||||
private List<ConfigAttributeDefinition> extractSupportedDefinitions(net.sf.acegisecurity.ConfigAttributeDefinition config)
|
||||
{
|
||||
List<ConfigAttributeDefintion> definitions = new ArrayList<ConfigAttributeDefintion>(2);
|
||||
List<ConfigAttributeDefinition> definitions = new ArrayList<ConfigAttributeDefinition>(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<Integer, Integer> parameters = new HashMap<Integer, Integer>(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<QName, Serializable> 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<QName, Serializable> 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<QName, Serializable>(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;
|
||||
}
|
||||
|
||||
}
|
||||
|
@@ -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<NodeRef> 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;
|
||||
}
|
||||
}
|
||||
|
@@ -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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
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<QName, Serializable> 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<QName, Serializable> properties = (Map<QName, Serializable>) invocation.getArguments()[position];
|
||||
return properties;
|
||||
}
|
||||
}
|
||||
throw new ACLEntryVoterException("Unknown type");
|
||||
}
|
||||
}
|
@@ -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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
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);
|
||||
}
|
||||
|
||||
}
|
@@ -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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
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);
|
||||
}
|
||||
|
||||
}
|
@@ -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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
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<Integer, Integer> parameters = new HashMap<Integer, Integer>(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<Integer, Integer> getParameters()
|
||||
{
|
||||
return parameters;
|
||||
}
|
||||
|
||||
public boolean isParent()
|
||||
{
|
||||
return parent;
|
||||
}
|
||||
}
|
@@ -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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
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);
|
||||
}
|
||||
|
||||
}
|
@@ -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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
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);
|
||||
}
|
||||
|
||||
}
|
@@ -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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@@ -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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
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;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
@@ -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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
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);
|
||||
}
|
@@ -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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
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);
|
||||
}
|
||||
}
|
@@ -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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@@ -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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
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<QName, Serializable> 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);
|
||||
}
|
||||
|
||||
}
|
@@ -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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
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<QName, Serializable> 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<QName, Serializable>(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);
|
||||
}
|
||||
|
||||
}
|
@@ -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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
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);
|
||||
}
|
||||
|
||||
}
|
@@ -178,7 +178,7 @@ public class CapabilityServiceImplTest extends BaseRMTestCase
|
||||
assertNotNull(vitalRecordCapabilities);
|
||||
|
||||
vitalRecordCapabilitiesSize = vitalRecordCapabilities.size();
|
||||
assertEquals(1, vitalRecordCapabilitiesSize);
|
||||
assertTrue(vitalRecordCapabilitiesSize > 0);
|
||||
|
||||
return null;
|
||||
}
|
||||
|
Reference in New Issue
Block a user