diff --git a/core/src/main/java/org/acegisecurity/vote/AbstractAclVoter.java b/core/src/main/java/org/acegisecurity/vote/AbstractAclVoter.java index 078929a49d..8ffa9ac6ef 100644 --- a/core/src/main/java/org/acegisecurity/vote/AbstractAclVoter.java +++ b/core/src/main/java/org/acegisecurity/vote/AbstractAclVoter.java @@ -1,4 +1,4 @@ -/* Copyright 2004, 2005 Acegi Technology Pty Limited +/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -17,11 +17,15 @@ package org.acegisecurity.vote; import org.acegisecurity.AuthorizationServiceException; import org.acegisecurity.ConfigAttribute; + import org.acegisecurity.acl.AclEntry; import org.acegisecurity.acl.AclManager; import org.aopalliance.intercept.MethodInvocation; +import org.aspectj.lang.JoinPoint; +import org.aspectj.lang.reflect.CodeSignature; + import org.springframework.util.Assert; import java.lang.reflect.Method; @@ -39,8 +43,7 @@ import java.lang.reflect.Method; * Authentication object. This class is designed to process * {@link AclEntry}s that are subclasses of {@link * org.acegisecurity.acl.basic.BasicAclEntry} only. Generally these are - * obtained by using the {@link - * org.acegisecurity.acl.basic.BasicAclProvider}. + * obtained by using the {@link org.acegisecurity.acl.basic.BasicAclProvider}. *

* *

@@ -122,16 +125,42 @@ public abstract class AbstractAclVoter implements AccessDecisionVoter { //~ Methods ================================================================ - public void setProcessDomainObjectClass(Class processDomainObjectClass) { - Assert.notNull(processDomainObjectClass, - "processDomainObjectClass cannot be set to null"); - this.processDomainObjectClass = processDomainObjectClass; + protected Object getDomainObjectInstance(Object secureObject) { + Object[] args; + Class[] params; + + if (secureObject instanceof MethodInvocation) { + MethodInvocation invocation = (MethodInvocation) secureObject; + params = invocation.getMethod().getParameterTypes(); + args = invocation.getArguments(); + } else { + JoinPoint jp = (JoinPoint) secureObject; + params = ((CodeSignature) jp.getStaticPart().getSignature()) + .getParameterTypes(); + args = jp.getArgs(); + } + + for (int i = 0; i < params.length; i++) { + if (processDomainObjectClass.isAssignableFrom(params[i])) { + return args[i]; + } + } + + throw new AuthorizationServiceException("Secure object: " + + secureObject + " did not provide any argument of type: " + + processDomainObjectClass); } public Class getProcessDomainObjectClass() { return processDomainObjectClass; } + public void setProcessDomainObjectClass(Class processDomainObjectClass) { + Assert.notNull(processDomainObjectClass, + "processDomainObjectClass cannot be set to null"); + this.processDomainObjectClass = processDomainObjectClass; + } + /** * This implementation supports only * MethodSecurityInterceptor, because it queries the @@ -143,24 +172,12 @@ public abstract class AbstractAclVoter implements AccessDecisionVoter { * MethodInvocation, false otherwise */ public boolean supports(Class clazz) { - return (MethodInvocation.class.isAssignableFrom(clazz)); - } - - protected Object getDomainObjectInstance(Object secureObject) { - MethodInvocation invocation = (MethodInvocation) secureObject; - - // Check if this MethodInvocation provides the required argument - Method method = invocation.getMethod(); - Class[] params = method.getParameterTypes(); - - for (int i = 0; i < params.length; i++) { - if (processDomainObjectClass.isAssignableFrom(params[i])) { - return invocation.getArguments()[i]; - } + if (MethodInvocation.class.isAssignableFrom(clazz)) { + return true; + } else if (JoinPoint.class.isAssignableFrom(clazz)) { + return true; + } else { + return false; } - - throw new AuthorizationServiceException("MethodInvocation: " - + invocation + " did not provide any argument of type: " - + processDomainObjectClass); } } diff --git a/core/src/test/java/org/acegisecurity/vote/BasicAclEntryVoterTests.java b/core/src/test/java/org/acegisecurity/vote/BasicAclEntryVoterTests.java index 9fe2a8d870..aa40a4449f 100644 --- a/core/src/test/java/org/acegisecurity/vote/BasicAclEntryVoterTests.java +++ b/core/src/test/java/org/acegisecurity/vote/BasicAclEntryVoterTests.java @@ -1,4 +1,4 @@ -/* Copyright 2004, 2005 Acegi Technology Pty Limited +/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -21,11 +21,14 @@ import org.acegisecurity.AuthorizationServiceException; import org.acegisecurity.ConfigAttributeDefinition; import org.acegisecurity.MockAclManager; import org.acegisecurity.SecurityConfig; + import org.acegisecurity.acl.AclEntry; import org.acegisecurity.acl.AclManager; import org.acegisecurity.acl.basic.MockAclObjectIdentity; import org.acegisecurity.acl.basic.SimpleAclEntry; + import org.acegisecurity.providers.UsernamePasswordAuthenticationToken; + import org.acegisecurity.util.SimpleMethodInvocation; import org.aopalliance.intercept.MethodInvocation; @@ -54,14 +57,23 @@ public class BasicAclEntryVoterTests extends TestCase { //~ Methods ================================================================ - public final void setUp() throws Exception { - super.setUp(); + private MethodInvocation getMethodInvocation(SomeDomainObject domainObject) + throws Exception { + Class clazz = SomeDomainObjectManager.class; + Method method = clazz.getMethod("someServiceMethod", + new Class[] {SomeDomainObject.class}); + + return new SimpleMethodInvocation(method, new Object[] {domainObject}); } public static void main(String[] args) { junit.textui.TestRunner.run(BasicAclEntryVoterTests.class); } + public final void setUp() throws Exception { + super.setUp(); + } + public void testNormalOperation() throws Exception { // Setup a domain object subject of this test SomeDomainObject domainObject = new SomeDomainObject("foo"); @@ -101,10 +113,11 @@ public class BasicAclEntryVoterTests extends TestCase { attr)); } - public void testOnlySupportsMethodInvocation() { + public void testOnlySupportsMethodInvocationAndJoinPoint() { BasicAclEntryVoter voter = new BasicAclEntryVoter(); assertTrue(voter.supports(MethodInvocation.class)); - assertFalse(voter.supports(JoinPoint.class)); + assertTrue(voter.supports(JoinPoint.class)); + assertFalse(voter.supports(String.class)); } public void testStartupRejectsMissingAclManager() throws Exception { @@ -456,15 +469,6 @@ public class BasicAclEntryVoterTests extends TestCase { } } - private MethodInvocation getMethodInvocation(SomeDomainObject domainObject) - throws Exception { - Class clazz = SomeDomainObjectManager.class; - Method method = clazz.getMethod("someServiceMethod", - new Class[] {SomeDomainObject.class}); - - return new SimpleMethodInvocation(method, new Object[] {domainObject}); - } - //~ Inner Classes ========================================================== private class MockAclEntry implements AclEntry {