diff --git a/changelog.txt b/changelog.txt index dcf9bad970..ea620f6055 100644 --- a/changelog.txt +++ b/changelog.txt @@ -8,6 +8,7 @@ Changes in version 0.7 (2004-xx-xx) * Added AuthenticationProcessingFilter.setDetails for use by subclasses * Added 403-causing exception to HttpSession via SecurityEnforcementFilter * Added net.sf.acegisecurity.intercept.event package +* Improved BasicAclProvider to only respond to specified ACL object requests * Refactored MethodDefinitionSource to work with Method, not MethodInvocation * Refactored AbstractSecurityInterceptor to better support other AOP libraries * Fixed AbstractProcessingFitler to use removeAttribute (JRun compatibility) diff --git a/core/src/main/java/org/acegisecurity/acl/basic/BasicAclProvider.java b/core/src/main/java/org/acegisecurity/acl/basic/BasicAclProvider.java index da8a310908..4833436dd1 100644 --- a/core/src/main/java/org/acegisecurity/acl/basic/BasicAclProvider.java +++ b/core/src/main/java/org/acegisecurity/acl/basic/BasicAclProvider.java @@ -93,6 +93,7 @@ public class BasicAclProvider implements AclProvider, InitializingBean { private BasicAclDao basicAclDao; private BasicAclEntryCache basicAclEntryCache = new NullAclEntryCache(); private Class defaultAclObjectIdentityClass = NamedEntityObjectIdentity.class; + private Class restrictSupportToClass = null; private EffectiveAclsResolver effectiveAclsResolver = new GrantedAuthorityEffectiveAclsResolver(); //~ Methods ================================================================ @@ -230,6 +231,28 @@ public class BasicAclProvider implements AclProvider, InitializingBean { return effectiveAclsResolver; } + /** + * If set to a value other than null, the {@link + * #supports(Object)} method will only support the indicates class. + * This is useful if you wish to wire multiple + * BasicAclProviders in a list of + * AclProviderManager.providers but only have particular + * instances respond to particular domain object types. + * + * @param restrictSupportToClass the class to restrict this + * BasicAclProvider to service request for, or + * null (the default) if the + * BasicAclProvider should respond to every class + * presented + */ + public void setRestrictSupportToClass(Class restrictSupportToClass) { + this.restrictSupportToClass = restrictSupportToClass; + } + + public Class getRestrictSupportToClass() { + return restrictSupportToClass; + } + public void afterPropertiesSet() { if (basicAclDao == null) { throw new IllegalArgumentException("basicAclDao required"); @@ -260,9 +283,14 @@ public class BasicAclProvider implements AclProvider, InitializingBean { } /** - * Indicates support for the passed object if it an - * AclObjectIdentity is returned by {@link - * #obtainIdentity(Object)}. + * Indicates support for the passed object. + * + *

+ * An object will only be supported if it (i) is allowed to be supported as + * defined by the {@link #setRestrictSupportToClass(Class)} method, + * and (ii) if an AclObjectIdentity is returned by + * {@link #obtainIdentity(Object)} for that object. + *

* * @param domainInstance the instance to check * @@ -270,6 +298,16 @@ public class BasicAclProvider implements AclProvider, InitializingBean { * false otherwise */ public boolean supports(Object domainInstance) { + if (domainInstance == null) { + return false; + } + + if ((restrictSupportToClass != null) + && !restrictSupportToClass.isAssignableFrom( + domainInstance.getClass())) { + return false; + } + if (obtainIdentity(domainInstance) == null) { return false; } else { diff --git a/core/src/test/java/org/acegisecurity/acl/basic/BasicAclProviderTests.java b/core/src/test/java/org/acegisecurity/acl/basic/BasicAclProviderTests.java index 4c4022dd4b..6cf46d6c82 100644 --- a/core/src/test/java/org/acegisecurity/acl/basic/BasicAclProviderTests.java +++ b/core/src/test/java/org/acegisecurity/acl/basic/BasicAclProviderTests.java @@ -184,6 +184,10 @@ public class BasicAclProviderTests extends TestCase { provider.setBasicAclDao(new MockDao()); assertNotNull(provider.getBasicAclDao()); + + assertNull(provider.getRestrictSupportToClass()); + provider.setRestrictSupportToClass(SomeDomain.class); + assertEquals(SomeDomain.class, provider.getRestrictSupportToClass()); } public void testStartupFailsIfNullAclDao() throws Exception { @@ -276,6 +280,16 @@ public class BasicAclProviderTests extends TestCase { // this one SHOULD be supported, as it implements AclObjectIdentityAware assertTrue(provider.supports(new MockDomain(4))); + + // now restrict the provider to only respond to SomeDomain.class requests + provider.setRestrictSupportToClass(SomeDomain.class); + assertEquals(SomeDomain.class, provider.getRestrictSupportToClass()); + + // this one SHOULD be supported, as it has a getId() method AND it meets the restrictSupportToClass criteria + assertTrue(provider.supports(new SomeDomain())); + + // this one should NOT be suported, as whilst it implement AclObjectIdentityAware (as proven earlier in the test), it does NOT meet the restrictSupportToClass criteria + assertFalse(provider.supports(new MockDomain(4))); } private JdbcDaoImpl makePopulatedJdbcDao() throws Exception {