Improve logging and enable ACL determination to use an Object obtained from an internal method of the located processDomainObjectClass.

This commit is contained in:
Ben Alex 2004-11-20 04:09:14 +00:00
parent 61580d1973
commit f251436a99
1 changed files with 74 additions and 0 deletions

View File

@ -25,8 +25,14 @@ import net.sf.acegisecurity.acl.basic.AbstractBasicAclEntry;
import org.aopalliance.intercept.MethodInvocation;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.factory.InitializingBean;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Iterator;
@ -120,10 +126,15 @@ import java.util.Iterator;
*/
public class BasicAclEntryVoter implements AccessDecisionVoter,
InitializingBean {
//~ Static fields/initializers =============================================
private static final Log logger = LogFactory.getLog(BasicAclEntryVoter.class);
//~ Instance fields ========================================================
private AclManager aclManager;
private Class processDomainObjectClass;
private String internalMethod;
private String processConfigAttribute;
private int[] requirePermission;
@ -137,6 +148,27 @@ public class BasicAclEntryVoter implements AccessDecisionVoter,
return aclManager;
}
public void setInternalMethod(String internalMethod) {
this.internalMethod = internalMethod;
}
/**
* Optionally specifies a method of the domain object that will be used to
* obtain a contained domain object. That contained domain object will be
* used for the ACL evaluation. This is useful if a domain object contains
* a parent that an ACL evaluation should be targeted for, instead of the
* child domain object (which perhaps is being created and as such does
* not yet have any ACL permissions)
*
* @return <code>null</code> to use the domain object, or the name of a
* method (that requires no arguments) that should be invoked to
* obtain an <code>Object</code> which will be the domain object
* used for ACL evaluation
*/
public String getInternalMethod() {
return internalMethod;
}
public void setProcessConfigAttribute(String processConfigAttribute) {
this.processConfigAttribute = processConfigAttribute;
}
@ -222,6 +254,48 @@ public class BasicAclEntryVoter implements AccessDecisionVoter,
return AccessDecisionVoter.ACCESS_ABSTAIN;
}
// Evaluate if we are required to use an inner domain object
if ((internalMethod != null) && !"".equals(internalMethod)) {
try {
Class clazz = domainObject.getClass();
Method method = clazz.getMethod(internalMethod, null);
domainObject = method.invoke(domainObject, null);
} catch (NoSuchMethodException nsme) {
throw new AuthorizationServiceException(
"Object of class '" + domainObject.getClass()
+ "' does not provide the requested internalMethod: "
+ internalMethod);
} catch (IllegalAccessException iae) {
if (logger.isDebugEnabled()) {
logger.debug("IllegalAccessException", iae);
if (iae.getCause() != null) {
logger.debug("Cause: "
+ iae.getCause().getMessage(),
iae.getCause());
}
}
throw new AuthorizationServiceException(
"Problem invoking internalMethod: "
+ internalMethod + " for object: " + domainObject);
} catch (InvocationTargetException ite) {
if (logger.isDebugEnabled()) {
logger.debug("InvocationTargetException", ite);
if (ite.getCause() != null) {
logger.debug("Cause: "
+ ite.getCause().getMessage(),
ite.getCause());
}
}
throw new AuthorizationServiceException(
"Problem invoking internalMethod: "
+ internalMethod + " for object: " + domainObject);
}
}
// Obtain the ACLs applicable to the domain object
AclEntry[] acls = aclManager.getAcls(domainObject,
authentication);