diff --git a/core/src/test/java/org/acegisecurity/ITargetObject.java b/core/src/test/java/org/acegisecurity/ITargetObject.java index a58ff0b71c..37f0f889c4 100644 --- a/core/src/test/java/org/acegisecurity/ITargetObject.java +++ b/core/src/test/java/org/acegisecurity/ITargetObject.java @@ -24,6 +24,8 @@ package net.sf.acegisecurity; public interface ITargetObject { //~ Methods ================================================================ + public Integer computeHashCode(String input); + public int countLength(String input); public String makeLowerCase(String input); diff --git a/core/src/test/java/org/acegisecurity/MockAclManager.java b/core/src/test/java/org/acegisecurity/MockAclManager.java new file mode 100644 index 0000000000..3264a5dae5 --- /dev/null +++ b/core/src/test/java/org/acegisecurity/MockAclManager.java @@ -0,0 +1,66 @@ +/* Copyright 2004 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. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package net.sf.acegisecurity; + +import net.sf.acegisecurity.acl.AclEntry; +import net.sf.acegisecurity.acl.AclManager; + + +/** + * Returns the indicated collection of AclEntrys when the given + * Authentication principal is presented for the indicated domain + * Object instance. + * + * @author Ben Alex + * @version $Id$ + */ +public class MockAclManager implements AclManager { + //~ Instance fields ======================================================== + + private Object object; + private Object principal; + private AclEntry[] acls; + + //~ Constructors =========================================================== + + public MockAclManager(Object domainObject, Object principal, AclEntry[] acls) { + this.object = domainObject; + this.principal = principal; + this.acls = acls; + } + + private MockAclManager() {} + + //~ Methods ================================================================ + + public AclEntry[] getAcls(Object domainInstance, + Authentication authentication) { + if (domainInstance.equals(object) + && authentication.getPrincipal().equals(principal)) { + return acls; + } else { + return null; + } + } + + public AclEntry[] getAcls(Object domainInstance) { + if (domainInstance.equals(object)) { + return acls; + } else { + return null; + } + } +} diff --git a/core/src/test/java/org/acegisecurity/MockAfterInvocationManager.java b/core/src/test/java/org/acegisecurity/MockAfterInvocationManager.java new file mode 100644 index 0000000000..104fa92212 --- /dev/null +++ b/core/src/test/java/org/acegisecurity/MockAfterInvocationManager.java @@ -0,0 +1,60 @@ +/* Copyright 2004 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. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package net.sf.acegisecurity; + +import java.util.Iterator; + + +/** + * If there is a configuration attribute of "AFTER_INVOCATION_MOCK", modifies + * the return value to null. + * + * @author Ben Alex + * @version $Id$ + */ +public class MockAfterInvocationManager implements AfterInvocationManager { + //~ Methods ================================================================ + + public Object decide(Authentication authentication, Object object, + ConfigAttributeDefinition config, Object returnedObject) + throws AccessDeniedException { + Iterator iter = config.getConfigAttributes(); + + while (iter.hasNext()) { + ConfigAttribute attr = (ConfigAttribute) iter.next(); + + if (this.supports(attr)) { + return null; + } + } + + // this "after invocation" hasn't got a config attribute asking + // for this mock to modify the returned object + return returnedObject; + } + + public boolean supports(ConfigAttribute attribute) { + if (attribute.getAttribute().equals("AFTER_INVOCATION_MOCK")) { + return true; + } else { + return false; + } + } + + public boolean supports(Class clazz) { + return true; + } +} diff --git a/core/src/test/java/org/acegisecurity/MockApplicationContext.java b/core/src/test/java/org/acegisecurity/MockApplicationContext.java new file mode 100644 index 0000000000..cb3200d5b3 --- /dev/null +++ b/core/src/test/java/org/acegisecurity/MockApplicationContext.java @@ -0,0 +1,36 @@ +/* Copyright 2004 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. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package net.sf.acegisecurity; + +import org.springframework.context.ConfigurableApplicationContext; +import org.springframework.context.support.ClassPathXmlApplicationContext; + + +/** + * Simply returns an ApplicationContext which has a couple of + * ApplicationEvent listeners. + * + * @author Ben Alex + * @version $Id$ + */ +public class MockApplicationContext { + //~ Methods ================================================================ + + public static ConfigurableApplicationContext getContext() { + return new ClassPathXmlApplicationContext( + "net/sf/acegisecurity/applicationContext.xml"); + } +} diff --git a/core/src/test/java/org/acegisecurity/MockJoinPoint.java b/core/src/test/java/org/acegisecurity/MockJoinPoint.java new file mode 100644 index 0000000000..a5c56a6a39 --- /dev/null +++ b/core/src/test/java/org/acegisecurity/MockJoinPoint.java @@ -0,0 +1,162 @@ +/* Copyright 2004 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. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package net.sf.acegisecurity; + +import org.aspectj.lang.JoinPoint; +import org.aspectj.lang.Signature; +import org.aspectj.lang.reflect.CodeSignature; +import org.aspectj.lang.reflect.SourceLocation; + +import java.lang.reflect.Method; + + +/** + * A mock AspectJ JoinPoint. + * + * @author Ben Alex + * @version $Id$ + */ +public class MockJoinPoint implements JoinPoint { + //~ Instance fields ======================================================== + + private Method beingInvoked; + private Object object; + + //~ Constructors =========================================================== + + public MockJoinPoint(Object object, Method beingInvoked) { + this.object = object; + this.beingInvoked = beingInvoked; + } + + private MockJoinPoint() {} + + //~ Methods ================================================================ + + public Object[] getArgs() { + throw new UnsupportedOperationException("mock not implemented"); + } + + public String getKind() { + throw new UnsupportedOperationException("mock not implemented"); + } + + public Signature getSignature() { + throw new UnsupportedOperationException("mock not implemented"); + } + + public SourceLocation getSourceLocation() { + throw new UnsupportedOperationException("mock not implemented"); + } + + public StaticPart getStaticPart() { + return new MockStaticPart(beingInvoked); + } + + public Object getTarget() { + return object; + } + + public Object getThis() { + throw new UnsupportedOperationException("mock not implemented"); + } + + public String toLongString() { + throw new UnsupportedOperationException("mock not implemented"); + } + + public String toShortString() { + throw new UnsupportedOperationException("mock not implemented"); + } + + //~ Inner Classes ========================================================== + + private class MockCodeSignature implements CodeSignature { + private Method beingInvoked; + + public MockCodeSignature(Method beingInvoked) { + this.beingInvoked = beingInvoked; + } + + private MockCodeSignature() {} + + public Class getDeclaringType() { + throw new UnsupportedOperationException("mock not implemented"); + } + + public String getDeclaringTypeName() { + throw new UnsupportedOperationException("mock not implemented"); + } + + public Class[] getExceptionTypes() { + throw new UnsupportedOperationException("mock not implemented"); + } + + public int getModifiers() { + throw new UnsupportedOperationException("mock not implemented"); + } + + public String getName() { + return beingInvoked.getName(); + } + + public String[] getParameterNames() { + throw new UnsupportedOperationException("mock not implemented"); + } + + public Class[] getParameterTypes() { + return beingInvoked.getParameterTypes(); + } + + public String toLongString() { + throw new UnsupportedOperationException("mock not implemented"); + } + + public String toShortString() { + throw new UnsupportedOperationException("mock not implemented"); + } + } + + private class MockStaticPart implements StaticPart { + private Method beingInvoked; + + public MockStaticPart(Method beingInvoked) { + this.beingInvoked = beingInvoked; + } + + private MockStaticPart() {} + + public String getKind() { + throw new UnsupportedOperationException("mock not implemented"); + } + + public Signature getSignature() { + return new MockCodeSignature(beingInvoked); + } + + public SourceLocation getSourceLocation() { + throw new UnsupportedOperationException("mock not implemented"); + } + + public String toLongString() { + throw new UnsupportedOperationException("mock not implemented"); + } + + public String toShortString() { + throw new UnsupportedOperationException("mock not implemented"); + } + } +} diff --git a/core/src/test/java/org/acegisecurity/MockMethodInvocation.java b/core/src/test/java/org/acegisecurity/MockMethodInvocation.java index 0c74e72898..8f9676c032 100644 --- a/core/src/test/java/org/acegisecurity/MockMethodInvocation.java +++ b/core/src/test/java/org/acegisecurity/MockMethodInvocation.java @@ -22,20 +22,34 @@ import java.lang.reflect.Method; /** - * DOCUMENT ME! + * Represents the AOP Alliance MethodInvocation secure object. * * @author Ben Alex * @version $Id$ */ public class MockMethodInvocation implements MethodInvocation { + //~ Instance fields ======================================================== + + private Method method; + private Object[] arguments; + + //~ Constructors =========================================================== + + public MockMethodInvocation(Method method, Object[] arguments) { + this.method = method; + this.arguments = arguments; + } + + public MockMethodInvocation() {} + //~ Methods ================================================================ public Object[] getArguments() { - throw new UnsupportedOperationException("mock method not implemented"); + return arguments; } public Method getMethod() { - throw new UnsupportedOperationException("mock method not implemented"); + return method; } public AccessibleObject getStaticPart() { diff --git a/core/src/test/java/org/acegisecurity/MockRunAsManager.java b/core/src/test/java/org/acegisecurity/MockRunAsManager.java index 43b9523e01..9926e8df61 100644 --- a/core/src/test/java/org/acegisecurity/MockRunAsManager.java +++ b/core/src/test/java/org/acegisecurity/MockRunAsManager.java @@ -47,7 +47,7 @@ public class MockRunAsManager implements RunAsManager { } public boolean supports(ConfigAttribute attribute) { - if ("RUN_AS".equals(attribute.getAttribute())) { + if (attribute.getAttribute().startsWith("RUN_AS")) { return true; } else { return false; diff --git a/core/src/test/java/org/acegisecurity/TargetObject.java b/core/src/test/java/org/acegisecurity/TargetObject.java index 4bd977553e..be5daa7de8 100644 --- a/core/src/test/java/org/acegisecurity/TargetObject.java +++ b/core/src/test/java/org/acegisecurity/TargetObject.java @@ -29,6 +29,10 @@ import net.sf.acegisecurity.context.SecureContext; public class TargetObject implements ITargetObject { //~ Methods ================================================================ + public Integer computeHashCode(String input) { + return new Integer(input.hashCode()); + } + public int countLength(String input) { return input.length(); } 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 6cf46d6c82..3181ad349b 100644 --- a/core/src/test/java/org/acegisecurity/acl/basic/BasicAclProviderTests.java +++ b/core/src/test/java/org/acegisecurity/acl/basic/BasicAclProviderTests.java @@ -292,6 +292,11 @@ public class BasicAclProviderTests extends TestCase { assertFalse(provider.supports(new MockDomain(4))); } + public void testSupportsReturnsNullIfObjectNull() { + BasicAclProvider provider = new BasicAclProvider(); + assertFalse(provider.supports(new Integer(34))); + } + private JdbcDaoImpl makePopulatedJdbcDao() throws Exception { JdbcDaoImpl dao = new JdbcDaoImpl(); dao.setDataSource(PopulatedDatabase.getDataSource()); diff --git a/core/src/test/java/org/acegisecurity/acl/basic/SimpleAclEntryTests.java b/core/src/test/java/org/acegisecurity/acl/basic/SimpleAclEntryTests.java index 3e9b01e8e6..a7e2d26565 100644 --- a/core/src/test/java/org/acegisecurity/acl/basic/SimpleAclEntryTests.java +++ b/core/src/test/java/org/acegisecurity/acl/basic/SimpleAclEntryTests.java @@ -82,6 +82,10 @@ public class SimpleAclEntryTests extends TestCase { assertFalse(acl.isPermitted(SimpleAclEntry.ADMINISTRATION)); acl.togglePermission(SimpleAclEntry.CREATE); assertFalse(acl.isPermitted(SimpleAclEntry.CREATE)); + + acl.togglePermission(SimpleAclEntry.DELETE); + assertTrue(acl.isPermitted(SimpleAclEntry.DELETE)); + assertEquals("----D", acl.printPermissionsBlock()); } public void testDetectsNullOnMainConstructor() { diff --git a/core/src/test/java/org/acegisecurity/acl/basic/jdbc/JdbcExtendedDaoImplTests.java b/core/src/test/java/org/acegisecurity/acl/basic/jdbc/JdbcExtendedDaoImplTests.java new file mode 100644 index 0000000000..11676098c4 --- /dev/null +++ b/core/src/test/java/org/acegisecurity/acl/basic/jdbc/JdbcExtendedDaoImplTests.java @@ -0,0 +1,336 @@ +/* Copyright 2004 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. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package net.sf.acegisecurity.acl.basic.jdbc; + +import junit.framework.TestCase; + +import net.sf.acegisecurity.PopulatedDatabase; +import net.sf.acegisecurity.acl.basic.AclObjectIdentity; +import net.sf.acegisecurity.acl.basic.BasicAclEntry; +import net.sf.acegisecurity.acl.basic.NamedEntityObjectIdentity; +import net.sf.acegisecurity.acl.basic.SimpleAclEntry; + +import org.springframework.dao.DataIntegrityViolationException; +import org.springframework.dao.DataRetrievalFailureException; + +import org.springframework.jdbc.object.MappingSqlQuery; + +import java.sql.ResultSet; +import java.sql.SQLException; + + +/** + * Tests {@link JdbcExtendedDaoImpl}. + * + * @author Ben Alex + * @version $Id$ + */ +public class JdbcExtendedDaoImplTests extends TestCase { + //~ Static fields/initializers ============================================= + + public static final String OBJECT_IDENTITY = "net.sf.acegisecurity.acl.DomainObject"; + + //~ Constructors =========================================================== + + public JdbcExtendedDaoImplTests() { + super(); + } + + public JdbcExtendedDaoImplTests(String arg0) { + super(arg0); + } + + //~ Methods ================================================================ + + public final void setUp() throws Exception { + super.setUp(); + } + + public static void main(String[] args) { + junit.textui.TestRunner.run(JdbcExtendedDaoImplTests.class); + } + + public void testChangeMask() throws Exception { + JdbcExtendedDaoImpl dao = makePopulatedJdbcDao(); + AclObjectIdentity identity = new NamedEntityObjectIdentity(OBJECT_IDENTITY, + "204"); + AclObjectIdentity parentIdentity = new NamedEntityObjectIdentity(OBJECT_IDENTITY, + "1"); + + // Create a BasicAclEntry for this AclObjectIdentity + SimpleAclEntry simpleAcl1 = new SimpleAclEntry("marissa", identity, + parentIdentity, SimpleAclEntry.CREATE); + dao.create(simpleAcl1); + + // Create another BasicAclEntry for this AclObjectIdentity + SimpleAclEntry simpleAcl2 = new SimpleAclEntry("scott", identity, + parentIdentity, SimpleAclEntry.READ); + dao.create(simpleAcl2); + + // Check creation was successful + BasicAclEntry[] acls = dao.getAcls(identity); + assertEquals(2, acls.length); + assertEquals(SimpleAclEntry.CREATE, acls[0].getMask()); + assertEquals(SimpleAclEntry.READ, acls[1].getMask()); + + // Attempt to change mask + dao.changeMask(identity, "marissa", + new Integer(SimpleAclEntry.ADMINISTRATION)); + dao.changeMask(identity, "scott", new Integer(SimpleAclEntry.NOTHING)); + acls = dao.getAcls(identity); + assertEquals(2, acls.length); + assertEquals("marissa", acls[0].getRecipient()); + assertEquals(SimpleAclEntry.ADMINISTRATION, acls[0].getMask()); + assertEquals("scott", acls[1].getRecipient()); + assertEquals(SimpleAclEntry.NOTHING, acls[1].getMask()); + } + + public void testChangeMaskThrowsExceptionWhenExistingRecordNotFound() + throws Exception { + JdbcExtendedDaoImpl dao = makePopulatedJdbcDao(); + AclObjectIdentity identity = new NamedEntityObjectIdentity(OBJECT_IDENTITY, + "205"); + AclObjectIdentity parentIdentity = new NamedEntityObjectIdentity(OBJECT_IDENTITY, + "1"); + + // Create at least one record for this AclObjectIdentity + SimpleAclEntry simpleAcl1 = new SimpleAclEntry("marissa", identity, + parentIdentity, SimpleAclEntry.CREATE); + dao.create(simpleAcl1); + + // Attempt to change mask, but for a recipient we don't have + try { + dao.changeMask(identity, "scott", + new Integer(SimpleAclEntry.ADMINISTRATION)); + fail("Should have thrown DataRetrievalFailureException"); + } catch (DataRetrievalFailureException expected) { + assertTrue(true); + } + } + + public void testConvertAclObjectIdentity() throws Exception { + JdbcExtendedDaoImpl dao = makePopulatedJdbcDao(); + + try { + dao.convertAclObjectIdentityToString(new AclObjectIdentity() { + // not a NamedEntityObjectIdentity + }); + fail("Should have thrown IllegalArgumentException"); + } catch (IllegalArgumentException expected) { + assertTrue(true); + } + } + + public void testCreationOfIdentityThenAclInSeparateInvocations() + throws Exception { + JdbcExtendedDaoImpl dao = makePopulatedJdbcDao(); + AclObjectIdentity identity = new NamedEntityObjectIdentity(OBJECT_IDENTITY, + "206"); + AclObjectIdentity parentIdentity = new NamedEntityObjectIdentity(OBJECT_IDENTITY, + "1"); + + // Create just the object identity (NB: recipient and mask is null) + SimpleAclEntry simpleAcl1 = new SimpleAclEntry(); + simpleAcl1.setAclObjectIdentity(identity); + simpleAcl1.setAclObjectParentIdentity(parentIdentity); + dao.create(simpleAcl1); + + // Delete it + dao.delete(identity); + } + + public void testDeletionOfAllRecipients() throws Exception { + JdbcExtendedDaoImpl dao = makePopulatedJdbcDao(); + AclObjectIdentity identity = new NamedEntityObjectIdentity(OBJECT_IDENTITY, + "203"); + + // Create a BasicAclEntry for this AclObjectIdentity + SimpleAclEntry simpleAcl1 = new SimpleAclEntry("marissa", identity, + null, SimpleAclEntry.CREATE); + dao.create(simpleAcl1); + + // Create another BasicAclEntry for this AclObjectIdentity + SimpleAclEntry simpleAcl2 = new SimpleAclEntry("scott", identity, null, + SimpleAclEntry.READ); + dao.create(simpleAcl2); + + // Check creation was successful + BasicAclEntry[] acls = dao.getAcls(identity); + assertEquals(2, acls.length); + + // Attempt deletion and check delete successful + dao.delete(identity); + assertNull(dao.getAcls(identity)); + } + + public void testDeletionOfSpecificRecipient() throws Exception { + JdbcExtendedDaoImpl dao = makePopulatedJdbcDao(); + AclObjectIdentity identity = new NamedEntityObjectIdentity(OBJECT_IDENTITY, + "202"); + AclObjectIdentity parentIdentity = new NamedEntityObjectIdentity(OBJECT_IDENTITY, + "1"); + + // Create a BasicAclEntry for this AclObjectIdentity + SimpleAclEntry simpleAcl1 = new SimpleAclEntry("marissa", identity, + parentIdentity, SimpleAclEntry.CREATE); + dao.create(simpleAcl1); + + // Create another BasicAclEntry for this AclObjectIdentity + SimpleAclEntry simpleAcl2 = new SimpleAclEntry("scott", identity, + parentIdentity, SimpleAclEntry.READ); + dao.create(simpleAcl2); + + // Check creation was successful + BasicAclEntry[] acls = dao.getAcls(identity); + assertEquals(2, acls.length); + + // Attempt deletion and check delete successful + dao.delete(identity, "scott"); + acls = dao.getAcls(identity); + assertEquals(1, acls.length); + assertEquals(simpleAcl1.getRecipient(), acls[0].getRecipient()); + } + + public void testGettersSetters() throws Exception { + JdbcExtendedDaoImpl dao = makePopulatedJdbcDao(); + + assertNotNull(dao.getAclObjectIdentityDelete()); + dao.setAclObjectIdentityDelete(null); + assertNull(dao.getAclObjectIdentityDelete()); + + assertNotNull(dao.getAclObjectIdentityInsert()); + dao.setAclObjectIdentityInsert(null); + assertNull(dao.getAclObjectIdentityInsert()); + + assertNotNull(dao.getAclPermissionDelete()); + dao.setAclPermissionDelete(null); + assertNull(dao.getAclPermissionDelete()); + + assertNotNull(dao.getAclPermissionInsert()); + dao.setAclPermissionInsert(null); + assertNull(dao.getAclPermissionInsert()); + + assertNotNull(dao.getAclPermissionUpdate()); + dao.setAclPermissionUpdate(null); + assertNull(dao.getAclPermissionUpdate()); + + assertNotNull(dao.getAclsByObjectIdentity()); + dao.setAclsByObjectIdentity(null); + assertNull(dao.getAclsByObjectIdentity()); + + assertNotNull(dao.getLookupPermissionIdMapping()); + dao.setLookupPermissionIdMapping(null); + assertNull(dao.getLookupPermissionIdMapping()); + + assertNotNull(dao.getAclObjectIdentityDeleteStatement()); + dao.setAclObjectIdentityDeleteStatement("SELECT ..."); + assertEquals("SELECT ...", dao.getAclObjectIdentityDeleteStatement()); + + assertNotNull(dao.getAclObjectIdentityInsertStatement()); + dao.setAclObjectIdentityInsertStatement("SELECT ..."); + assertEquals("SELECT ...", dao.getAclObjectIdentityInsertStatement()); + + assertNotNull(dao.getAclPermissionDeleteStatement()); + dao.setAclPermissionDeleteStatement("SELECT ..."); + assertEquals("SELECT ...", dao.getAclPermissionDeleteStatement()); + + assertNotNull(dao.getAclPermissionInsertStatement()); + dao.setAclPermissionInsertStatement("SELECT ..."); + assertEquals("SELECT ...", dao.getAclPermissionInsertStatement()); + + assertNotNull(dao.getAclPermissionUpdateStatement()); + dao.setAclPermissionUpdateStatement("SELECT ..."); + assertEquals("SELECT ...", dao.getAclPermissionUpdateStatement()); + + assertNotNull(dao.getAclsByObjectIdentityQuery()); + dao.setAclsByObjectIdentityQuery("SELECT ..."); + assertEquals("SELECT ...", dao.getAclsByObjectIdentityQuery()); + + assertNotNull(dao.getLookupPermissionIdQuery()); + dao.setLookupPermissionIdQuery("SELECT ..."); + assertEquals("SELECT ...", dao.getLookupPermissionIdQuery()); + } + + public void testNormalCreationAndDuplicateDetection() + throws Exception { + JdbcExtendedDaoImpl dao = makePopulatedJdbcDao(); + AclObjectIdentity identity = new NamedEntityObjectIdentity(OBJECT_IDENTITY, + "200"); + AclObjectIdentity parentIdentity = new NamedEntityObjectIdentity(OBJECT_IDENTITY, + "1"); + + // Create a BasicAclEntry for this AclObjectIdentity + SimpleAclEntry simpleAcl1 = new SimpleAclEntry("marissa", identity, + parentIdentity, SimpleAclEntry.CREATE); + dao.create(simpleAcl1); + + // Create another BasicAclEntry for this AclObjectIdentity + SimpleAclEntry simpleAcl2 = new SimpleAclEntry("scott", identity, + parentIdentity, SimpleAclEntry.READ); + dao.create(simpleAcl2); + + // Check creation was successful + BasicAclEntry[] acls = dao.getAcls(identity); + assertEquals(2, acls.length); + assertEquals(simpleAcl1.getRecipient(), acls[0].getRecipient()); + assertEquals(simpleAcl1.getMask(), acls[0].getMask()); + assertEquals(simpleAcl2.getRecipient(), acls[1].getRecipient()); + assertEquals(simpleAcl2.getMask(), acls[1].getMask()); + + // Check it rejects an attempt to create another identical entry + try { + dao.create(simpleAcl1); + fail("Should have thrown DataIntegrityViolationException"); + } catch (DataIntegrityViolationException expected) { + assertTrue(true); + } + } + + public void testRejectsInvalidParent() throws Exception { + JdbcExtendedDaoImpl dao = makePopulatedJdbcDao(); + AclObjectIdentity identity = new NamedEntityObjectIdentity(OBJECT_IDENTITY, + "201"); + AclObjectIdentity parentIdentity = new NamedEntityObjectIdentity(OBJECT_IDENTITY, + "987987987987986"); + SimpleAclEntry simpleAcl = new SimpleAclEntry("marissa", identity, + parentIdentity, SimpleAclEntry.CREATE); + + try { + dao.create(simpleAcl); + fail("Should have thrown DataRetrievalFailureException"); + } catch (DataRetrievalFailureException expected) { + assertTrue(true); + } + } + + private JdbcExtendedDaoImpl makePopulatedJdbcDao() + throws Exception { + JdbcExtendedDaoImpl dao = new JdbcExtendedDaoImpl(); + dao.setDataSource(PopulatedDatabase.getDataSource()); + dao.afterPropertiesSet(); + + return dao; + } + + //~ Inner Classes ========================================================== + + private class MockMappingSqlQuery extends MappingSqlQuery { + protected Object mapRow(ResultSet arg0, int arg1) + throws SQLException { + return null; + } + } +} diff --git a/core/src/test/java/org/acegisecurity/afterinvocation/AfterInvocationProviderManagerTests.java b/core/src/test/java/org/acegisecurity/afterinvocation/AfterInvocationProviderManagerTests.java new file mode 100644 index 0000000000..5010bf8db3 --- /dev/null +++ b/core/src/test/java/org/acegisecurity/afterinvocation/AfterInvocationProviderManagerTests.java @@ -0,0 +1,223 @@ +/* Copyright 2004 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. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package net.sf.acegisecurity.afterinvocation; + +import junit.framework.TestCase; + +import net.sf.acegisecurity.AccessDeniedException; +import net.sf.acegisecurity.Authentication; +import net.sf.acegisecurity.ConfigAttribute; +import net.sf.acegisecurity.ConfigAttributeDefinition; +import net.sf.acegisecurity.MockMethodInvocation; +import net.sf.acegisecurity.SecurityConfig; +import net.sf.acegisecurity.intercept.web.FilterInvocation; + +import org.aopalliance.intercept.MethodInvocation; + +import java.util.List; +import java.util.Vector; + + +/** + * Tests {@link AfterInvocationProviderManager}. + * + * @author Ben Alex + * @version $Id$ + */ +public class AfterInvocationProviderManagerTests extends TestCase { + //~ Constructors =========================================================== + + public AfterInvocationProviderManagerTests() { + super(); + } + + public AfterInvocationProviderManagerTests(String arg0) { + super(arg0); + } + + //~ Methods ================================================================ + + public final void setUp() throws Exception { + super.setUp(); + } + + public static void main(String[] args) { + junit.textui.TestRunner.run(AfterInvocationProviderManagerTests.class); + } + + public void testCorrectOperation() throws Exception { + AfterInvocationProviderManager manager = new AfterInvocationProviderManager(); + List list = new Vector(); + list.add(new MockAfterInvocationProvider("swap1", + MethodInvocation.class, new SecurityConfig("GIVE_ME_SWAP1"))); + list.add(new MockAfterInvocationProvider("swap2", + MethodInvocation.class, new SecurityConfig("GIVE_ME_SWAP2"))); + list.add(new MockAfterInvocationProvider("swap3", + MethodInvocation.class, new SecurityConfig("GIVE_ME_SWAP3"))); + manager.setProviders(list); + assertEquals(list, manager.getProviders()); + manager.afterPropertiesSet(); + + ConfigAttributeDefinition attr1 = new ConfigAttributeDefinition(); + attr1.addConfigAttribute(new SecurityConfig("GIVE_ME_SWAP1")); + + ConfigAttributeDefinition attr2 = new ConfigAttributeDefinition(); + attr2.addConfigAttribute(new SecurityConfig("GIVE_ME_SWAP2")); + + ConfigAttributeDefinition attr3 = new ConfigAttributeDefinition(); + attr3.addConfigAttribute(new SecurityConfig("GIVE_ME_SWAP3")); + + ConfigAttributeDefinition attr2and3 = new ConfigAttributeDefinition(); + attr2and3.addConfigAttribute(new SecurityConfig("GIVE_ME_SWAP2")); + attr2and3.addConfigAttribute(new SecurityConfig("GIVE_ME_SWAP3")); + + ConfigAttributeDefinition attr4 = new ConfigAttributeDefinition(); + attr4.addConfigAttribute(new SecurityConfig("NEVER_CAUSES_SWAP")); + + assertEquals("swap1", + manager.decide(null, new MockMethodInvocation(), attr1, + "content-before-swapping")); + + assertEquals("swap2", + manager.decide(null, new MockMethodInvocation(), attr2, + "content-before-swapping")); + + assertEquals("swap3", + manager.decide(null, new MockMethodInvocation(), attr3, + "content-before-swapping")); + + assertEquals("content-before-swapping", + manager.decide(null, new MockMethodInvocation(), attr4, + "content-before-swapping")); + + assertEquals("swap3", + manager.decide(null, new MockMethodInvocation(), attr2and3, + "content-before-swapping")); + } + + public void testRejectsEmptyProvidersList() { + AfterInvocationProviderManager manager = new AfterInvocationProviderManager(); + List list = new Vector(); + + try { + manager.setProviders(list); + fail("Should have thrown IllegalArgumentException"); + } catch (IllegalArgumentException expected) { + assertTrue(true); + } + } + + public void testRejectsNonAfterInvocationProviders() { + AfterInvocationProviderManager manager = new AfterInvocationProviderManager(); + List list = new Vector(); + list.add(new MockAfterInvocationProvider("swap1", + MethodInvocation.class, new SecurityConfig("GIVE_ME_SWAP1"))); + list.add(new Integer(45)); + list.add(new MockAfterInvocationProvider("swap3", + MethodInvocation.class, new SecurityConfig("GIVE_ME_SWAP3"))); + + try { + manager.setProviders(list); + fail("Should have thrown IllegalArgumentException"); + } catch (IllegalArgumentException expected) { + assertTrue(true); + } + } + + public void testRejectsNullProvidersList() throws Exception { + AfterInvocationProviderManager manager = new AfterInvocationProviderManager(); + + try { + manager.afterPropertiesSet(); + fail("Should have thrown IllegalArgumentException"); + } catch (IllegalArgumentException expected) { + assertTrue(true); + } + } + + public void testSupportsConfigAttributeIteration() + throws Exception { + AfterInvocationProviderManager manager = new AfterInvocationProviderManager(); + List list = new Vector(); + list.add(new MockAfterInvocationProvider("swap1", + MethodInvocation.class, new SecurityConfig("GIVE_ME_SWAP1"))); + list.add(new MockAfterInvocationProvider("swap2", + MethodInvocation.class, new SecurityConfig("GIVE_ME_SWAP2"))); + list.add(new MockAfterInvocationProvider("swap3", + MethodInvocation.class, new SecurityConfig("GIVE_ME_SWAP3"))); + manager.setProviders(list); + manager.afterPropertiesSet(); + + assertFalse(manager.supports(new SecurityConfig("UNKNOWN_ATTRIB"))); + assertTrue(manager.supports(new SecurityConfig("GIVE_ME_SWAP2"))); + } + + public void testSupportsSecureObjectIteration() throws Exception { + AfterInvocationProviderManager manager = new AfterInvocationProviderManager(); + List list = new Vector(); + list.add(new MockAfterInvocationProvider("swap1", + MethodInvocation.class, new SecurityConfig("GIVE_ME_SWAP1"))); + list.add(new MockAfterInvocationProvider("swap2", + MethodInvocation.class, new SecurityConfig("GIVE_ME_SWAP2"))); + list.add(new MockAfterInvocationProvider("swap3", + MethodInvocation.class, new SecurityConfig("GIVE_ME_SWAP3"))); + manager.setProviders(list); + manager.afterPropertiesSet(); + + assertFalse(manager.supports(FilterInvocation.class)); + assertTrue(manager.supports(MethodInvocation.class)); + } + + //~ Inner Classes ========================================================== + + /** + * Always returns the constructor-defined forceReturnObject, + * provided the same configuration attribute was provided. Also stores the + * secure object it supports. + */ + private class MockAfterInvocationProvider implements AfterInvocationProvider { + private Class secureObject; + private ConfigAttribute configAttribute; + private Object forceReturnObject; + + public MockAfterInvocationProvider(Object forceReturnObject, + Class secureObject, ConfigAttribute configAttribute) { + this.forceReturnObject = forceReturnObject; + this.secureObject = secureObject; + this.configAttribute = configAttribute; + } + + private MockAfterInvocationProvider() {} + + public Object decide(Authentication authentication, Object object, + ConfigAttributeDefinition config, Object returnedObject) + throws AccessDeniedException { + if (config.contains(configAttribute)) { + return forceReturnObject; + } + + return returnedObject; + } + + public boolean supports(Class clazz) { + return secureObject.isAssignableFrom(clazz); + } + + public boolean supports(ConfigAttribute attribute) { + return attribute.equals(configAttribute); + } + } +} diff --git a/core/src/test/java/org/acegisecurity/afterinvocation/BasicAclEntryAfterInvocationCollectionFilteringProviderTests.java b/core/src/test/java/org/acegisecurity/afterinvocation/BasicAclEntryAfterInvocationCollectionFilteringProviderTests.java new file mode 100644 index 0000000000..9d4bc3e160 --- /dev/null +++ b/core/src/test/java/org/acegisecurity/afterinvocation/BasicAclEntryAfterInvocationCollectionFilteringProviderTests.java @@ -0,0 +1,373 @@ +/* Copyright 2004 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. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package net.sf.acegisecurity.afterinvocation; + +import junit.framework.TestCase; + +import net.sf.acegisecurity.AuthorizationServiceException; +import net.sf.acegisecurity.ConfigAttributeDefinition; +import net.sf.acegisecurity.MockAclManager; +import net.sf.acegisecurity.MockMethodInvocation; +import net.sf.acegisecurity.SecurityConfig; +import net.sf.acegisecurity.acl.AclEntry; +import net.sf.acegisecurity.acl.AclManager; +import net.sf.acegisecurity.acl.basic.MockAclObjectIdentity; +import net.sf.acegisecurity.acl.basic.SimpleAclEntry; +import net.sf.acegisecurity.providers.UsernamePasswordAuthenticationToken; + +import java.util.List; +import java.util.Vector; + + +/** + * Tests {@link BasicAclEntryAfterInvocationCollectionFilteringProvider}. + * + * @author Ben Alex + * @version $Id$ + */ +public class BasicAclEntryAfterInvocationCollectionFilteringProviderTests + extends TestCase { + //~ Constructors =========================================================== + + public BasicAclEntryAfterInvocationCollectionFilteringProviderTests() { + super(); + } + + public BasicAclEntryAfterInvocationCollectionFilteringProviderTests( + String arg0) { + super(arg0); + } + + //~ Methods ================================================================ + + public final void setUp() throws Exception { + super.setUp(); + } + + public static void main(String[] args) { + junit.textui.TestRunner.run(BasicAclEntryAfterInvocationCollectionFilteringProviderTests.class); + } + + public void testCorrectOperationWhenPrincipalHasIncorrectPermissionToDomainObject() + throws Exception { + // Create an AclManager, granting scott only ADMINISTRATION rights + AclManager aclManager = new MockAclManager("belmont", "scott", + new AclEntry[] {new SimpleAclEntry("scott", + new MockAclObjectIdentity(), null, + SimpleAclEntry.ADMINISTRATION)}); + + BasicAclEntryAfterInvocationCollectionFilteringProvider provider = new BasicAclEntryAfterInvocationCollectionFilteringProvider(); + provider.setAclManager(aclManager); + provider.afterPropertiesSet(); + + // Create a Collection containing many items + List list = new Vector(); + list.add("sydney"); + list.add("melbourne"); + list.add("belmont"); + list.add("brisbane"); + + // Create the Authentication and Config Attribs we'll be presenting + UsernamePasswordAuthenticationToken auth = new UsernamePasswordAuthenticationToken("scott", + "NOT_USED"); + ConfigAttributeDefinition attr = new ConfigAttributeDefinition(); + attr.addConfigAttribute(new SecurityConfig("AFTER_ACL_COLLECTION_READ")); + + // Filter + List filteredList = (List) provider.decide(auth, + new MockMethodInvocation(), attr, list); + + assertEquals(0, filteredList.size()); + } + + public void testCorrectOperationWhenPrincipalHasNoPermissionToDomainObject() + throws Exception { + // Create an AclManager + AclManager aclManager = new MockAclManager("belmont", "marissa", + new AclEntry[] {new MockAclEntry(), new SimpleAclEntry( + "marissa", new MockAclObjectIdentity(), null, + SimpleAclEntry.ADMINISTRATION), new SimpleAclEntry( + "marissa", new MockAclObjectIdentity(), null, + SimpleAclEntry.READ), new SimpleAclEntry("marissa", + new MockAclObjectIdentity(), null, SimpleAclEntry.DELETE)}); + + BasicAclEntryAfterInvocationCollectionFilteringProvider provider = new BasicAclEntryAfterInvocationCollectionFilteringProvider(); + provider.setAclManager(aclManager); + provider.afterPropertiesSet(); + + // Create a Collection containing many items, which only "belmont" + // should remain in after filtering by provider + List list = new Vector(); + list.add("sydney"); + list.add("melbourne"); + list.add("belmont"); + list.add("brisbane"); + + // Create the Authentication and Config Attribs we'll be presenting + UsernamePasswordAuthenticationToken auth = new UsernamePasswordAuthenticationToken("scott", + "NOT_USED"); + ConfigAttributeDefinition attr = new ConfigAttributeDefinition(); + attr.addConfigAttribute(new SecurityConfig("AFTER_ACL_COLLECTION_READ")); + + // Filter + List filteredList = (List) provider.decide(auth, + new MockMethodInvocation(), attr, list); + + assertEquals(0, filteredList.size()); + } + + public void testCorrectOperationWhenPrincipalIsAuthorised() + throws Exception { + // Create an AclManager + AclManager aclManager = new MockAclManager("belmont", "marissa", + new AclEntry[] {new MockAclEntry(), new SimpleAclEntry( + "marissa", new MockAclObjectIdentity(), null, + SimpleAclEntry.ADMINISTRATION), new SimpleAclEntry( + "marissa", new MockAclObjectIdentity(), null, + SimpleAclEntry.READ), new SimpleAclEntry("marissa", + new MockAclObjectIdentity(), null, SimpleAclEntry.DELETE)}); + + BasicAclEntryAfterInvocationCollectionFilteringProvider provider = new BasicAclEntryAfterInvocationCollectionFilteringProvider(); + provider.setAclManager(aclManager); + assertEquals(aclManager, provider.getAclManager()); + provider.afterPropertiesSet(); + + // Create a Collection containing many items, which only "belmont" + // should remain in after filtering by provider + List list = new Vector(); + list.add("sydney"); + list.add("melbourne"); + list.add("belmont"); + list.add("brisbane"); + + // Create the Authentication and Config Attribs we'll be presenting + UsernamePasswordAuthenticationToken auth = new UsernamePasswordAuthenticationToken("marissa", + "NOT_USED"); + ConfigAttributeDefinition attr = new ConfigAttributeDefinition(); + attr.addConfigAttribute(new SecurityConfig("AFTER_ACL_COLLECTION_READ")); + + // Filter + List filteredList = (List) provider.decide(auth, + new MockMethodInvocation(), attr, list); + + assertEquals(1, filteredList.size()); + assertEquals("belmont", filteredList.get(0)); + } + + public void testDetectsIfReturnedObjectIsNotACollection() + throws Exception { + // Create an AclManager + AclManager aclManager = new MockAclManager("belmont", "marissa", + new AclEntry[] {new SimpleAclEntry("marissa", + new MockAclObjectIdentity(), null, + SimpleAclEntry.ADMINISTRATION), new SimpleAclEntry( + "marissa", new MockAclObjectIdentity(), null, + SimpleAclEntry.READ), new SimpleAclEntry("marissa", + new MockAclObjectIdentity(), null, SimpleAclEntry.DELETE), new MockAclEntry()}); + + BasicAclEntryAfterInvocationCollectionFilteringProvider provider = new BasicAclEntryAfterInvocationCollectionFilteringProvider(); + provider.setAclManager(aclManager); + provider.afterPropertiesSet(); + + // Create the Authentication and Config Attribs we'll be presenting + UsernamePasswordAuthenticationToken auth = new UsernamePasswordAuthenticationToken("marissa", + "NOT_USED"); + ConfigAttributeDefinition attr = new ConfigAttributeDefinition(); + attr.addConfigAttribute(new SecurityConfig("AFTER_ACL_COLLECTION_READ")); + + // Filter + try { + provider.decide(auth, new MockMethodInvocation(), attr, + new String("RETURN_OBJECT_NOT_COLLECTION")); + fail("Should have thrown AuthorizationServiceException"); + } catch (AuthorizationServiceException expected) { + assertTrue(true); + } + } + + public void testGrantsAccessIfReturnedObjectIsNull() + throws Exception { + // Create an AclManager + AclManager aclManager = new MockAclManager("belmont", "marissa", + new AclEntry[] {new SimpleAclEntry("marissa", + new MockAclObjectIdentity(), null, + SimpleAclEntry.ADMINISTRATION), new SimpleAclEntry( + "marissa", new MockAclObjectIdentity(), null, + SimpleAclEntry.READ), new SimpleAclEntry("marissa", + new MockAclObjectIdentity(), null, SimpleAclEntry.DELETE), new MockAclEntry()}); + + BasicAclEntryAfterInvocationCollectionFilteringProvider provider = new BasicAclEntryAfterInvocationCollectionFilteringProvider(); + provider.setAclManager(aclManager); + provider.afterPropertiesSet(); + + // Create the Authentication and Config Attribs we'll be presenting + UsernamePasswordAuthenticationToken auth = new UsernamePasswordAuthenticationToken("marissa", + "NOT_USED"); + ConfigAttributeDefinition attr = new ConfigAttributeDefinition(); + attr.addConfigAttribute(new SecurityConfig("AFTER_ACL_COLLECTION_READ")); + + // Filter + List filteredList = (List) provider.decide(auth, + new MockMethodInvocation(), attr, null); + + assertNull(filteredList); + } + + public void testRespectsModificationsToProcessConfigAttribute() + throws Exception { + // Create an AclManager + AclManager aclManager = new MockAclManager("sydney", "marissa", + new AclEntry[] {new SimpleAclEntry("marissa", + new MockAclObjectIdentity(), null, SimpleAclEntry.READ), new MockAclEntry()}); + + BasicAclEntryAfterInvocationCollectionFilteringProvider provider = new BasicAclEntryAfterInvocationCollectionFilteringProvider(); + provider.setAclManager(aclManager); + assertEquals("AFTER_ACL_COLLECTION_READ", + provider.getProcessConfigAttribute()); + provider.setProcessConfigAttribute("AFTER_ACL_COLLECTION_ADMIN"); + assertEquals("AFTER_ACL_COLLECTION_ADMIN", + provider.getProcessConfigAttribute()); + provider.afterPropertiesSet(); + + // Create a Collection containing many items, which only "sydney" + // should remain in after filtering by provider + List list = new Vector(); + list.add("sydney"); + list.add("melbourne"); + list.add("belmont"); + list.add("brisbane"); + + // Create the Authentication and Config Attribs we'll be presenting + UsernamePasswordAuthenticationToken auth = new UsernamePasswordAuthenticationToken("marissa", + "NOT_USED"); + ConfigAttributeDefinition attr = new ConfigAttributeDefinition(); + attr.addConfigAttribute(new SecurityConfig("AFTER_ACL_COLLECTION_READ")); + + // As no matching config attrib, ensure provider doesn't change list + assertEquals(4, + ((List) provider.decide(auth, new MockMethodInvocation(), attr, list)) + .size()); + + // Filter, this time with the conf attrib provider setup to answer + attr.addConfigAttribute(new SecurityConfig("AFTER_ACL_COLLECTION_ADMIN")); + + List filteredList = (List) provider.decide(auth, + new MockMethodInvocation(), attr, list); + + assertEquals(1, filteredList.size()); + assertEquals("sydney", filteredList.get(0)); + } + + public void testRespectsModificationsToRequirePermissions() + throws Exception { + // Create an AclManager + AclManager aclManager = new MockAclManager("sydney", "marissa", + new AclEntry[] {new SimpleAclEntry("marissa", + new MockAclObjectIdentity(), null, + SimpleAclEntry.ADMINISTRATION), new MockAclEntry()}); + + BasicAclEntryAfterInvocationCollectionFilteringProvider provider = new BasicAclEntryAfterInvocationCollectionFilteringProvider(); + provider.setAclManager(aclManager); + assertEquals(SimpleAclEntry.READ, provider.getRequirePermission()[0]); + provider.setRequirePermission(new int[] {SimpleAclEntry.ADMINISTRATION}); + assertEquals(SimpleAclEntry.ADMINISTRATION, + provider.getRequirePermission()[0]); + provider.afterPropertiesSet(); + + // Create a Collection containing many items, which only "sydney" + // should remain in after filtering by provider + List list = new Vector(); + list.add("sydney"); + list.add("melbourne"); + list.add("belmont"); + list.add("brisbane"); + + // Create the Authentication and Config Attribs we'll be presenting + UsernamePasswordAuthenticationToken auth = new UsernamePasswordAuthenticationToken("marissa", + "NOT_USED"); + ConfigAttributeDefinition attr = new ConfigAttributeDefinition(); + attr.addConfigAttribute(new SecurityConfig("AFTER_ACL_COLLECTION_READ")); + + // Filter + List filteredList = (List) provider.decide(auth, + new MockMethodInvocation(), attr, list); + + assertEquals(1, filteredList.size()); + assertEquals("sydney", filteredList.get(0)); + } + + public void testStartupDetectsMissingAclManager() throws Exception { + BasicAclEntryAfterInvocationCollectionFilteringProvider provider = new BasicAclEntryAfterInvocationCollectionFilteringProvider(); + + try { + provider.afterPropertiesSet(); + fail("Should have thrown IllegalArgumentException"); + } catch (IllegalArgumentException expected) { + assertEquals("An aclManager is mandatory", expected.getMessage()); + } + } + + public void testStartupDetectsMissingProcessConfigAttribute() + throws Exception { + BasicAclEntryAfterInvocationCollectionFilteringProvider provider = new BasicAclEntryAfterInvocationCollectionFilteringProvider(); + AclManager aclManager = new MockAclManager("sydney", "marissa", + new AclEntry[] {new SimpleAclEntry("marissa", + new MockAclObjectIdentity(), null, + SimpleAclEntry.ADMINISTRATION), new MockAclEntry()}); + provider.setAclManager(aclManager); + + provider.setProcessConfigAttribute(null); + + try { + provider.afterPropertiesSet(); + fail("Should have thrown IllegalArgumentException"); + } catch (IllegalArgumentException expected) { + assertEquals("A processConfigAttribute is mandatory", + expected.getMessage()); + } + } + + public void testStartupDetectsMissingRequirePermission() + throws Exception { + BasicAclEntryAfterInvocationCollectionFilteringProvider provider = new BasicAclEntryAfterInvocationCollectionFilteringProvider(); + AclManager aclManager = new MockAclManager("sydney", "marissa", + new AclEntry[] {new SimpleAclEntry("marissa", + new MockAclObjectIdentity(), null, + SimpleAclEntry.ADMINISTRATION), new MockAclEntry()}); + provider.setAclManager(aclManager); + + provider.setRequirePermission(null); + + try { + provider.afterPropertiesSet(); + fail("Should have thrown IllegalArgumentException"); + } catch (IllegalArgumentException expected) { + assertEquals("One or more requirePermission entries is mandatory", + expected.getMessage()); + } + } + + public void testSupportsAnything() { + assertTrue(new BasicAclEntryAfterInvocationCollectionFilteringProvider() + .supports(String.class)); + } + + //~ Inner Classes ========================================================== + + private class MockAclEntry implements AclEntry { + // just so AclTag iterates some different types of AclEntrys + } +} diff --git a/core/src/test/java/org/acegisecurity/afterinvocation/BasicAclEntryAfterInvocationProviderTests.java b/core/src/test/java/org/acegisecurity/afterinvocation/BasicAclEntryAfterInvocationProviderTests.java new file mode 100644 index 0000000000..724b77c341 --- /dev/null +++ b/core/src/test/java/org/acegisecurity/afterinvocation/BasicAclEntryAfterInvocationProviderTests.java @@ -0,0 +1,284 @@ +/* Copyright 2004 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. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package net.sf.acegisecurity.afterinvocation; + +import junit.framework.TestCase; + +import net.sf.acegisecurity.AccessDeniedException; +import net.sf.acegisecurity.ConfigAttributeDefinition; +import net.sf.acegisecurity.MockAclManager; +import net.sf.acegisecurity.MockMethodInvocation; +import net.sf.acegisecurity.SecurityConfig; +import net.sf.acegisecurity.acl.AclEntry; +import net.sf.acegisecurity.acl.AclManager; +import net.sf.acegisecurity.acl.basic.MockAclObjectIdentity; +import net.sf.acegisecurity.acl.basic.SimpleAclEntry; +import net.sf.acegisecurity.providers.UsernamePasswordAuthenticationToken; + + +/** + * Tests {@link BasicAclEntryAfterInvocationProvider}. + * + * @author Ben Alex + * @version $Id$ + */ +public class BasicAclEntryAfterInvocationProviderTests extends TestCase { + //~ Constructors =========================================================== + + public BasicAclEntryAfterInvocationProviderTests() { + super(); + } + + public BasicAclEntryAfterInvocationProviderTests(String arg0) { + super(arg0); + } + + //~ Methods ================================================================ + + public final void setUp() throws Exception { + super.setUp(); + } + + public static void main(String[] args) { + junit.textui.TestRunner.run(BasicAclEntryAfterInvocationProviderTests.class); + } + + public void testCorrectOperationWhenPrincipalHasIncorrectPermissionToDomainObject() + throws Exception { + // Create an AclManager, granting scott only ADMINISTRATION rights + AclManager aclManager = new MockAclManager("belmont", "scott", + new AclEntry[] {new SimpleAclEntry("scott", + new MockAclObjectIdentity(), null, + SimpleAclEntry.ADMINISTRATION)}); + + BasicAclEntryAfterInvocationProvider provider = new BasicAclEntryAfterInvocationProvider(); + provider.setAclManager(aclManager); + provider.afterPropertiesSet(); + + // Create the Authentication and Config Attribs we'll be presenting + UsernamePasswordAuthenticationToken auth = new UsernamePasswordAuthenticationToken("scott", + "NOT_USED"); + ConfigAttributeDefinition attr = new ConfigAttributeDefinition(); + attr.addConfigAttribute(new SecurityConfig("AFTER_ACL_READ")); + + try { + provider.decide(auth, new MockMethodInvocation(), attr, "belmont"); + fail("Should have thrown AccessDeniedException"); + } catch (AccessDeniedException expected) { + assertTrue(true); + } + } + + public void testCorrectOperationWhenPrincipalHasNoPermissionToDomainObject() + throws Exception { + // Create an AclManager + AclManager aclManager = new MockAclManager("belmont", "marissa", + new AclEntry[] {new MockAclEntry(), new SimpleAclEntry( + "marissa", new MockAclObjectIdentity(), null, + SimpleAclEntry.ADMINISTRATION), new SimpleAclEntry( + "marissa", new MockAclObjectIdentity(), null, + SimpleAclEntry.READ), new SimpleAclEntry("marissa", + new MockAclObjectIdentity(), null, SimpleAclEntry.DELETE)}); + + BasicAclEntryAfterInvocationProvider provider = new BasicAclEntryAfterInvocationProvider(); + provider.setAclManager(aclManager); + provider.afterPropertiesSet(); + + // Create the Authentication and Config Attribs we'll be presenting + UsernamePasswordAuthenticationToken auth = new UsernamePasswordAuthenticationToken("scott", + "NOT_USED"); + ConfigAttributeDefinition attr = new ConfigAttributeDefinition(); + attr.addConfigAttribute(new SecurityConfig("AFTER_ACL_READ")); + + try { + provider.decide(auth, new MockMethodInvocation(), attr, "belmont"); + fail("Should have thrown AccessDeniedException"); + } catch (AccessDeniedException expected) { + assertTrue(true); + } + } + + public void testCorrectOperationWhenPrincipalIsAuthorised() + throws Exception { + // Create an AclManager + AclManager aclManager = new MockAclManager("belmont", "marissa", + new AclEntry[] {new MockAclEntry(), new SimpleAclEntry( + "marissa", new MockAclObjectIdentity(), null, + SimpleAclEntry.ADMINISTRATION), new SimpleAclEntry( + "marissa", new MockAclObjectIdentity(), null, + SimpleAclEntry.READ), new SimpleAclEntry("marissa", + new MockAclObjectIdentity(), null, SimpleAclEntry.DELETE)}); + + BasicAclEntryAfterInvocationProvider provider = new BasicAclEntryAfterInvocationProvider(); + provider.setAclManager(aclManager); + assertEquals(aclManager, provider.getAclManager()); + provider.afterPropertiesSet(); + + // Create the Authentication and Config Attribs we'll be presenting + UsernamePasswordAuthenticationToken auth = new UsernamePasswordAuthenticationToken("marissa", + "NOT_USED"); + ConfigAttributeDefinition attr = new ConfigAttributeDefinition(); + attr.addConfigAttribute(new SecurityConfig("AFTER_ACL_READ")); + + // Filter + assertEquals("belmont", + provider.decide(auth, new MockMethodInvocation(), attr, "belmont")); + } + + public void testGrantsAccessIfReturnedObjectIsNull() + throws Exception { + // Create an AclManager + AclManager aclManager = new MockAclManager("belmont", "marissa", + new AclEntry[] {new SimpleAclEntry("marissa", + new MockAclObjectIdentity(), null, + SimpleAclEntry.ADMINISTRATION), new SimpleAclEntry( + "marissa", new MockAclObjectIdentity(), null, + SimpleAclEntry.READ), new SimpleAclEntry("marissa", + new MockAclObjectIdentity(), null, SimpleAclEntry.DELETE), new MockAclEntry()}); + + BasicAclEntryAfterInvocationProvider provider = new BasicAclEntryAfterInvocationProvider(); + provider.setAclManager(aclManager); + provider.afterPropertiesSet(); + + // Create the Authentication and Config Attribs we'll be presenting + UsernamePasswordAuthenticationToken auth = new UsernamePasswordAuthenticationToken("marissa", + "NOT_USED"); + ConfigAttributeDefinition attr = new ConfigAttributeDefinition(); + attr.addConfigAttribute(new SecurityConfig("AFTER_ACL_READ")); + + // Filter + assertNull(provider.decide(auth, new MockMethodInvocation(), attr, null)); + } + + public void testRespectsModificationsToProcessConfigAttribute() + throws Exception { + // Create an AclManager + AclManager aclManager = new MockAclManager("sydney", "marissa", + new AclEntry[] {new SimpleAclEntry("marissa", + new MockAclObjectIdentity(), null, SimpleAclEntry.READ), new MockAclEntry()}); + + BasicAclEntryAfterInvocationProvider provider = new BasicAclEntryAfterInvocationProvider(); + provider.setAclManager(aclManager); + assertEquals("AFTER_ACL_READ", provider.getProcessConfigAttribute()); + provider.setProcessConfigAttribute("AFTER_ACL_ADMIN"); + assertEquals("AFTER_ACL_ADMIN", provider.getProcessConfigAttribute()); + provider.afterPropertiesSet(); + + // Create the Authentication and Config Attribs we'll be presenting + UsernamePasswordAuthenticationToken auth = new UsernamePasswordAuthenticationToken("marissa", + "NOT_USED"); + ConfigAttributeDefinition attr = new ConfigAttributeDefinition(); + attr.addConfigAttribute(new SecurityConfig("AFTER_ACL_READ")); + + // As no matching config attrib, ensure provider returns original obj + assertEquals("sydney", + provider.decide(auth, new MockMethodInvocation(), attr, "sydney")); + + // Filter, this time with the conf attrib provider setup to answer + attr.addConfigAttribute(new SecurityConfig("AFTER_ACL_ADMIN")); + assertEquals("sydney", + provider.decide(auth, new MockMethodInvocation(), attr, "sydney")); + } + + public void testRespectsModificationsToRequirePermissions() + throws Exception { + // Create an AclManager + AclManager aclManager = new MockAclManager("sydney", "marissa", + new AclEntry[] {new SimpleAclEntry("marissa", + new MockAclObjectIdentity(), null, + SimpleAclEntry.ADMINISTRATION), new MockAclEntry()}); + + BasicAclEntryAfterInvocationProvider provider = new BasicAclEntryAfterInvocationProvider(); + provider.setAclManager(aclManager); + assertEquals(SimpleAclEntry.READ, provider.getRequirePermission()[0]); + provider.setRequirePermission(new int[] {SimpleAclEntry.ADMINISTRATION}); + assertEquals(SimpleAclEntry.ADMINISTRATION, + provider.getRequirePermission()[0]); + provider.afterPropertiesSet(); + + // Create the Authentication and Config Attribs we'll be presenting + UsernamePasswordAuthenticationToken auth = new UsernamePasswordAuthenticationToken("marissa", + "NOT_USED"); + ConfigAttributeDefinition attr = new ConfigAttributeDefinition(); + attr.addConfigAttribute(new SecurityConfig("AFTER_ACL_READ")); + + // Filter + assertEquals("sydney", + provider.decide(auth, new MockMethodInvocation(), attr, "sydney")); + } + + public void testStartupDetectsMissingAclManager() throws Exception { + BasicAclEntryAfterInvocationProvider provider = new BasicAclEntryAfterInvocationProvider(); + + try { + provider.afterPropertiesSet(); + fail("Should have thrown IllegalArgumentException"); + } catch (IllegalArgumentException expected) { + assertEquals("An aclManager is mandatory", expected.getMessage()); + } + } + + public void testStartupDetectsMissingProcessConfigAttribute() + throws Exception { + BasicAclEntryAfterInvocationProvider provider = new BasicAclEntryAfterInvocationProvider(); + AclManager aclManager = new MockAclManager("sydney", "marissa", + new AclEntry[] {new SimpleAclEntry("marissa", + new MockAclObjectIdentity(), null, + SimpleAclEntry.ADMINISTRATION), new MockAclEntry()}); + provider.setAclManager(aclManager); + + provider.setProcessConfigAttribute(null); + + try { + provider.afterPropertiesSet(); + fail("Should have thrown IllegalArgumentException"); + } catch (IllegalArgumentException expected) { + assertEquals("A processConfigAttribute is mandatory", + expected.getMessage()); + } + } + + public void testStartupDetectsMissingRequirePermission() + throws Exception { + BasicAclEntryAfterInvocationProvider provider = new BasicAclEntryAfterInvocationProvider(); + AclManager aclManager = new MockAclManager("sydney", "marissa", + new AclEntry[] {new SimpleAclEntry("marissa", + new MockAclObjectIdentity(), null, + SimpleAclEntry.ADMINISTRATION), new MockAclEntry()}); + provider.setAclManager(aclManager); + + provider.setRequirePermission(null); + + try { + provider.afterPropertiesSet(); + fail("Should have thrown IllegalArgumentException"); + } catch (IllegalArgumentException expected) { + assertEquals("One or more requirePermission entries is mandatory", + expected.getMessage()); + } + } + + public void testSupportsAnything() { + assertTrue(new BasicAclEntryAfterInvocationProvider().supports( + String.class)); + } + + //~ Inner Classes ========================================================== + + private class MockAclEntry implements AclEntry { + // just so AclTag iterates some different types of AclEntrys + } +} diff --git a/core/src/test/java/org/acegisecurity/intercept/AbstractSecurityInterceptorTests.java b/core/src/test/java/org/acegisecurity/intercept/AbstractSecurityInterceptorTests.java new file mode 100644 index 0000000000..2ca2a40dbf --- /dev/null +++ b/core/src/test/java/org/acegisecurity/intercept/AbstractSecurityInterceptorTests.java @@ -0,0 +1,125 @@ +/* Copyright 2004 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. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package net.sf.acegisecurity.intercept; + +import junit.framework.TestCase; + +import net.sf.acegisecurity.MockAccessDecisionManager; +import net.sf.acegisecurity.MockAfterInvocationManager; +import net.sf.acegisecurity.MockAuthenticationManager; +import net.sf.acegisecurity.MockMethodInvocation; +import net.sf.acegisecurity.MockRunAsManager; +import net.sf.acegisecurity.intercept.method.MockMethodDefinitionSource; + + +/** + * Tests some {@link AbstractSecurityInterceptor} methods. Most of the testing + * for this class is found in the MethodSecurityInterceptorTests + * class. + * + * @author Ben Alex + * @version $Id$ + */ +public class AbstractSecurityInterceptorTests extends TestCase { + //~ Constructors =========================================================== + + public AbstractSecurityInterceptorTests() { + super(); + } + + public AbstractSecurityInterceptorTests(String arg0) { + super(arg0); + } + + //~ Methods ================================================================ + + public static void main(String[] args) { + junit.textui.TestRunner.run(AbstractSecurityInterceptorTests.class); + } + + public void testDetectsIfInvocationPassedIncompatibleSecureObject() + throws Exception { + MockSecurityInterceptorWhichOnlySupportsStrings si = new MockSecurityInterceptorWhichOnlySupportsStrings(); + si.setRunAsManager(new MockRunAsManager()); + si.setAuthenticationManager(new MockAuthenticationManager()); + si.setAfterInvocationManager(new MockAfterInvocationManager()); + si.setAccessDecisionManager(new MockAccessDecisionManager()); + si.setObjectDefinitionSource(new MockMethodDefinitionSource(false, true)); + + try { + si.beforeInvocation(new MockMethodInvocation()); + fail("Should have thrown IllegalArgumentException"); + } catch (IllegalArgumentException expected) { + assertTrue(expected.getMessage().startsWith("Security invocation attempted for object")); + } + } + + public void testDetectsViolationOfGetSecureObjectClassMethod() + throws Exception { + MockSecurityInterceptorReturnsNull si = new MockSecurityInterceptorReturnsNull(); + si.setRunAsManager(new MockRunAsManager()); + si.setAuthenticationManager(new MockAuthenticationManager()); + si.setAfterInvocationManager(new MockAfterInvocationManager()); + si.setAccessDecisionManager(new MockAccessDecisionManager()); + si.setObjectDefinitionSource(new MockMethodDefinitionSource(false, true)); + + try { + si.afterPropertiesSet(); + fail("Should have thrown IllegalArgumentException"); + } catch (IllegalArgumentException expected) { + assertEquals("Subclass must provide a non-null response to getSecureObjectClass()", + expected.getMessage()); + } + } + + //~ Inner Classes ========================================================== + + private class MockSecurityInterceptorReturnsNull + extends AbstractSecurityInterceptor { + private ObjectDefinitionSource objectDefinitionSource; + + public void setObjectDefinitionSource( + ObjectDefinitionSource objectDefinitionSource) { + this.objectDefinitionSource = objectDefinitionSource; + } + + public Class getSecureObjectClass() { + return null; + } + + public ObjectDefinitionSource obtainObjectDefinitionSource() { + return objectDefinitionSource; + } + } + + private class MockSecurityInterceptorWhichOnlySupportsStrings + extends AbstractSecurityInterceptor { + private ObjectDefinitionSource objectDefinitionSource; + + public void setObjectDefinitionSource( + ObjectDefinitionSource objectDefinitionSource) { + this.objectDefinitionSource = objectDefinitionSource; + } + + public Class getSecureObjectClass() { + return String.class; + } + + public ObjectDefinitionSource obtainObjectDefinitionSource() { + return objectDefinitionSource; + } + } +} diff --git a/core/src/test/java/org/acegisecurity/intercept/InterceptorStatusTokenTests.java b/core/src/test/java/org/acegisecurity/intercept/InterceptorStatusTokenTests.java new file mode 100644 index 0000000000..720b73ab4e --- /dev/null +++ b/core/src/test/java/org/acegisecurity/intercept/InterceptorStatusTokenTests.java @@ -0,0 +1,74 @@ +/* Copyright 2004 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. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package net.sf.acegisecurity.intercept; + +import junit.framework.TestCase; + +import net.sf.acegisecurity.ConfigAttributeDefinition; +import net.sf.acegisecurity.MockMethodInvocation; +import net.sf.acegisecurity.SecurityConfig; +import net.sf.acegisecurity.providers.UsernamePasswordAuthenticationToken; + +import org.aopalliance.intercept.MethodInvocation; + + +/** + * Tests {@link InterceptorStatusToken}. + * + * @author Ben Alex + * @version $Id$ + */ +public class InterceptorStatusTokenTests extends TestCase { + //~ Constructors =========================================================== + + public InterceptorStatusTokenTests() { + super(); + } + + public InterceptorStatusTokenTests(String arg0) { + super(arg0); + } + + //~ Methods ================================================================ + + public static void main(String[] args) { + junit.textui.TestRunner.run(InterceptorStatusTokenTests.class); + } + + public void testDefaultConstructor() { + try { + new InterceptorStatusToken(); + fail("Should have thrown IllegalArgumentException"); + } catch (IllegalArgumentException expected) { + assertTrue(true); + } + } + + public void testOperation() { + ConfigAttributeDefinition attr = new ConfigAttributeDefinition(); + attr.addConfigAttribute(new SecurityConfig("FOO")); + + MethodInvocation mi = new MockMethodInvocation(); + + InterceptorStatusToken token = new InterceptorStatusToken(new UsernamePasswordAuthenticationToken( + "marissa", "koala"), true, attr, mi); + + assertTrue(token.isContextHolderRefreshRequired()); + assertEquals(attr, token.getAttr()); + assertEquals(mi, token.getSecureObject()); + assertEquals("marissa", token.getAuthentication().getPrincipal()); + } +} diff --git a/core/src/test/java/org/acegisecurity/intercept/event/AuthenticationCredentialsNotFoundEventTests.java b/core/src/test/java/org/acegisecurity/intercept/event/AuthenticationCredentialsNotFoundEventTests.java new file mode 100644 index 0000000000..b736d43046 --- /dev/null +++ b/core/src/test/java/org/acegisecurity/intercept/event/AuthenticationCredentialsNotFoundEventTests.java @@ -0,0 +1,74 @@ +/* Copyright 2004 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. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package net.sf.acegisecurity.intercept.event; + +import junit.framework.TestCase; + +import net.sf.acegisecurity.AuthenticationCredentialsNotFoundException; +import net.sf.acegisecurity.ConfigAttributeDefinition; +import net.sf.acegisecurity.MockMethodInvocation; + + +/** + * Tests {@link AuthenticationCredentialsNotFoundEvent}. + * + * @author Ben Alex + * @version $Id$ + */ +public class AuthenticationCredentialsNotFoundEventTests extends TestCase { + //~ Constructors =========================================================== + + public AuthenticationCredentialsNotFoundEventTests() { + super(); + } + + public AuthenticationCredentialsNotFoundEventTests(String arg0) { + super(arg0); + } + + //~ Methods ================================================================ + + public static void main(String[] args) { + junit.textui.TestRunner.run(AuthenticationCredentialsNotFoundEventTests.class); + } + + public void testRejectsNulls() { + try { + AuthenticationCredentialsNotFoundEvent event = new AuthenticationCredentialsNotFoundEvent(null, + new ConfigAttributeDefinition(), + new AuthenticationCredentialsNotFoundException("test")); + fail("Should have thrown IllegalArgumentException"); + } catch (IllegalArgumentException expected) { + assertTrue(true); + } + + try { + AuthenticationCredentialsNotFoundEvent event = new AuthenticationCredentialsNotFoundEvent(new MockMethodInvocation(), + null, new AuthenticationCredentialsNotFoundException("test")); + fail("Should have thrown IllegalArgumentException"); + } catch (IllegalArgumentException expected) { + assertTrue(true); + } + + try { + AuthenticationCredentialsNotFoundEvent event = new AuthenticationCredentialsNotFoundEvent(new MockMethodInvocation(), + new ConfigAttributeDefinition(), null); + fail("Should have thrown IllegalArgumentException"); + } catch (IllegalArgumentException expected) { + assertTrue(true); + } + } +} diff --git a/core/src/test/java/org/acegisecurity/intercept/event/AuthenticationFailureEventTests.java b/core/src/test/java/org/acegisecurity/intercept/event/AuthenticationFailureEventTests.java new file mode 100644 index 0000000000..59cd17d37c --- /dev/null +++ b/core/src/test/java/org/acegisecurity/intercept/event/AuthenticationFailureEventTests.java @@ -0,0 +1,88 @@ +/* Copyright 2004 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. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package net.sf.acegisecurity.intercept.event; + +import junit.framework.TestCase; + +import net.sf.acegisecurity.BadCredentialsException; +import net.sf.acegisecurity.ConfigAttributeDefinition; +import net.sf.acegisecurity.MockMethodInvocation; +import net.sf.acegisecurity.providers.UsernamePasswordAuthenticationToken; + + +/** + * Tests {@link AuthenticationFailureEvent}. + * + * @author Ben Alex + * @version $Id$ + */ +public class AuthenticationFailureEventTests extends TestCase { + //~ Constructors =========================================================== + + public AuthenticationFailureEventTests() { + super(); + } + + public AuthenticationFailureEventTests(String arg0) { + super(arg0); + } + + //~ Methods ================================================================ + + public static void main(String[] args) { + junit.textui.TestRunner.run(AuthenticationFailureEventTests.class); + } + + public void testRejectsNulls() { + try { + AuthenticationFailureEvent event = new AuthenticationFailureEvent(null, + new ConfigAttributeDefinition(), + new UsernamePasswordAuthenticationToken("foo", "bar"), + new BadCredentialsException("error")); + fail("Should have thrown IllegalArgumentException"); + } catch (IllegalArgumentException expected) { + assertTrue(true); + } + + try { + AuthenticationFailureEvent event = new AuthenticationFailureEvent(new MockMethodInvocation(), + null, + new UsernamePasswordAuthenticationToken("foo", "bar"), + new BadCredentialsException("error")); + fail("Should have thrown IllegalArgumentException"); + } catch (IllegalArgumentException expected) { + assertTrue(true); + } + + try { + AuthenticationFailureEvent event = new AuthenticationFailureEvent(new MockMethodInvocation(), + new ConfigAttributeDefinition(), null, + new BadCredentialsException("error")); + fail("Should have thrown IllegalArgumentException"); + } catch (IllegalArgumentException expected) { + assertTrue(true); + } + + try { + AuthenticationFailureEvent event = new AuthenticationFailureEvent(new MockMethodInvocation(), + new ConfigAttributeDefinition(), + new UsernamePasswordAuthenticationToken("foo", "bar"), null); + fail("Should have thrown IllegalArgumentException"); + } catch (IllegalArgumentException expected) { + assertTrue(true); + } + } +} diff --git a/core/src/test/java/org/acegisecurity/intercept/event/AuthorizationFailureEventTests.java b/core/src/test/java/org/acegisecurity/intercept/event/AuthorizationFailureEventTests.java new file mode 100644 index 0000000000..d60c1b80ad --- /dev/null +++ b/core/src/test/java/org/acegisecurity/intercept/event/AuthorizationFailureEventTests.java @@ -0,0 +1,88 @@ +/* Copyright 2004 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. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package net.sf.acegisecurity.intercept.event; + +import junit.framework.TestCase; + +import net.sf.acegisecurity.AccessDeniedException; +import net.sf.acegisecurity.ConfigAttributeDefinition; +import net.sf.acegisecurity.MockMethodInvocation; +import net.sf.acegisecurity.providers.UsernamePasswordAuthenticationToken; + + +/** + * Tests {@link AuthorizationFailureEvent}. + * + * @author Ben Alex + * @version $Id$ + */ +public class AuthorizationFailureEventTests extends TestCase { + //~ Constructors =========================================================== + + public AuthorizationFailureEventTests() { + super(); + } + + public AuthorizationFailureEventTests(String arg0) { + super(arg0); + } + + //~ Methods ================================================================ + + public static void main(String[] args) { + junit.textui.TestRunner.run(AuthorizationFailureEventTests.class); + } + + public void testRejectsNulls() { + try { + AuthorizationFailureEvent event = new AuthorizationFailureEvent(null, + new ConfigAttributeDefinition(), + new UsernamePasswordAuthenticationToken("foo", "bar"), + new AccessDeniedException("error")); + fail("Should have thrown IllegalArgumentException"); + } catch (IllegalArgumentException expected) { + assertTrue(true); + } + + try { + AuthorizationFailureEvent event = new AuthorizationFailureEvent(new MockMethodInvocation(), + null, + new UsernamePasswordAuthenticationToken("foo", "bar"), + new AccessDeniedException("error")); + fail("Should have thrown IllegalArgumentException"); + } catch (IllegalArgumentException expected) { + assertTrue(true); + } + + try { + AuthorizationFailureEvent event = new AuthorizationFailureEvent(new MockMethodInvocation(), + new ConfigAttributeDefinition(), null, + new AccessDeniedException("error")); + fail("Should have thrown IllegalArgumentException"); + } catch (IllegalArgumentException expected) { + assertTrue(true); + } + + try { + AuthorizationFailureEvent event = new AuthorizationFailureEvent(new MockMethodInvocation(), + new ConfigAttributeDefinition(), + new UsernamePasswordAuthenticationToken("foo", "bar"), null); + fail("Should have thrown IllegalArgumentException"); + } catch (IllegalArgumentException expected) { + assertTrue(true); + } + } +} diff --git a/core/src/test/java/org/acegisecurity/intercept/event/AuthorizedEventTests.java b/core/src/test/java/org/acegisecurity/intercept/event/AuthorizedEventTests.java new file mode 100644 index 0000000000..1444252c26 --- /dev/null +++ b/core/src/test/java/org/acegisecurity/intercept/event/AuthorizedEventTests.java @@ -0,0 +1,74 @@ +/* Copyright 2004 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. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package net.sf.acegisecurity.intercept.event; + +import junit.framework.TestCase; + +import net.sf.acegisecurity.ConfigAttributeDefinition; +import net.sf.acegisecurity.MockMethodInvocation; +import net.sf.acegisecurity.providers.UsernamePasswordAuthenticationToken; + + +/** + * Tests {@link AuthorizedEvent}. + * + * @author Ben Alex + * @version $Id$ + */ +public class AuthorizedEventTests extends TestCase { + //~ Constructors =========================================================== + + public AuthorizedEventTests() { + super(); + } + + public AuthorizedEventTests(String arg0) { + super(arg0); + } + + //~ Methods ================================================================ + + public static void main(String[] args) { + junit.textui.TestRunner.run(AuthorizedEventTests.class); + } + + public void testRejectsNulls() { + try { + AuthorizedEvent event = new AuthorizedEvent(null, + new ConfigAttributeDefinition(), + new UsernamePasswordAuthenticationToken("foo", "bar")); + fail("Should have thrown IllegalArgumentException"); + } catch (IllegalArgumentException expected) { + assertTrue(true); + } + + try { + AuthorizedEvent event = new AuthorizedEvent(new MockMethodInvocation(), + null, new UsernamePasswordAuthenticationToken("foo", "bar")); + fail("Should have thrown IllegalArgumentException"); + } catch (IllegalArgumentException expected) { + assertTrue(true); + } + + try { + AuthorizedEvent event = new AuthorizedEvent(new MockMethodInvocation(), + new ConfigAttributeDefinition(), null); + fail("Should have thrown IllegalArgumentException"); + } catch (IllegalArgumentException expected) { + assertTrue(true); + } + } +} diff --git a/core/src/test/java/org/acegisecurity/intercept/method/MethodDefinitionAttributesTests.java b/core/src/test/java/org/acegisecurity/intercept/method/MethodDefinitionAttributesTests.java index 31a0eb7a45..0204c392b2 100644 --- a/core/src/test/java/org/acegisecurity/intercept/method/MethodDefinitionAttributesTests.java +++ b/core/src/test/java/org/acegisecurity/intercept/method/MethodDefinitionAttributesTests.java @@ -32,16 +32,13 @@ import net.sf.acegisecurity.context.SecureContext; import net.sf.acegisecurity.context.SecureContextImpl; import net.sf.acegisecurity.providers.UsernamePasswordAuthenticationToken; -import org.springframework.beans.factory.support.DefaultListableBeanFactory; -import org.springframework.beans.factory.support.PropertiesBeanDefinitionReader; - +import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; import java.lang.reflect.Method; import java.util.HashSet; import java.util.Iterator; -import java.util.Properties; import java.util.Set; @@ -228,47 +225,10 @@ public class MethodDefinitionAttributesTests extends TestCase { } private ITargetObject makeInterceptedTarget() { - String PREFIX = "beans."; - DefaultListableBeanFactory lbf = new DefaultListableBeanFactory(); - Properties p = new Properties(); - p.setProperty(PREFIX + "authentication.class", - "net.sf.acegisecurity.MockAuthenticationManager"); - p.setProperty(PREFIX + "accessDecision.class", - "net.sf.acegisecurity.MockAccessDecisionManager"); - p.setProperty(PREFIX + "runAs.class", - "net.sf.acegisecurity.MockRunAsManager"); - p.setProperty(PREFIX + "attributes.class", - "net.sf.acegisecurity.intercept.method.MockAttributes"); + ApplicationContext context = new ClassPathXmlApplicationContext( + "net/sf/acegisecurity/intercept/method/applicationContext.xml"); - p.setProperty(PREFIX + "objectDefinitionSource.class", - "net.sf.acegisecurity.intercept.method.MethodDefinitionAttributes"); - p.setProperty(PREFIX + "objectDefinitionSource.attributes(ref)", - "attributes"); - - p.setProperty(PREFIX + "securityInterceptor.class", - "net.sf.acegisecurity.intercept.method.aopalliance.MethodSecurityInterceptor"); - p.setProperty(PREFIX + "securityInterceptor.authenticationManager(ref)", - "authentication"); - p.setProperty(PREFIX + "securityInterceptor.accessDecisionManager(ref)", - "accessDecision"); - p.setProperty(PREFIX + "securityInterceptor.runAsManager(ref)", "runAs"); - p.setProperty(PREFIX - + "securityInterceptor.objectDefinitionSource(ref)", - "objectDefinitionSource"); - - p.setProperty(PREFIX + "targetObject.class", - "net.sf.acegisecurity.TargetObject"); - p.setProperty(PREFIX + "target.class", - "org.springframework.aop.framework.ProxyFactoryBean"); - p.setProperty(PREFIX + "target.proxyInterfaces", - "net.sf.acegisecurity.ITargetObject"); - p.setProperty(PREFIX + "target.interceptorNames", - "securityInterceptor,targetObject"); - - (new PropertiesBeanDefinitionReader(lbf)).registerBeanDefinitions(p, - PREFIX); - - return (ITargetObject) lbf.getBean("target"); + return (ITargetObject) context.getBean("target"); } /** diff --git a/core/src/test/java/org/acegisecurity/intercept/method/MethodDefinitionSourceEditorTests.java b/core/src/test/java/org/acegisecurity/intercept/method/MethodDefinitionSourceEditorTests.java index 3da03fde5f..8607577b00 100644 --- a/core/src/test/java/org/acegisecurity/intercept/method/MethodDefinitionSourceEditorTests.java +++ b/core/src/test/java/org/acegisecurity/intercept/method/MethodDefinitionSourceEditorTests.java @@ -18,6 +18,7 @@ package net.sf.acegisecurity.intercept.method; import junit.framework.TestCase; import net.sf.acegisecurity.ConfigAttributeDefinition; +import net.sf.acegisecurity.MockJoinPoint; import net.sf.acegisecurity.SecurityConfig; import net.sf.acegisecurity.TargetObject; @@ -57,6 +58,28 @@ public class MethodDefinitionSourceEditorTests extends TestCase { junit.textui.TestRunner.run(MethodDefinitionSourceEditorTests.class); } + public void testAspectJJointPointLookup() throws Exception { + MethodDefinitionSourceEditor editor = new MethodDefinitionSourceEditor(); + editor.setAsText( + "net.sf.acegisecurity.TargetObject.countLength=ROLE_ONE,ROLE_TWO,RUN_AS_ENTRY"); + + MethodDefinitionMap map = (MethodDefinitionMap) editor.getValue(); + + Class clazz = TargetObject.class; + Method method = clazz.getMethod("countLength", + new Class[] {String.class}); + MockJoinPoint joinPoint = new MockJoinPoint(new TargetObject(), method); + + ConfigAttributeDefinition returnedCountLength = map.getAttributes(joinPoint); + + ConfigAttributeDefinition expectedCountLength = new ConfigAttributeDefinition(); + expectedCountLength.addConfigAttribute(new SecurityConfig("ROLE_ONE")); + expectedCountLength.addConfigAttribute(new SecurityConfig("ROLE_TWO")); + expectedCountLength.addConfigAttribute(new SecurityConfig( + "RUN_AS_ENTRY")); + assertEquals(expectedCountLength, returnedCountLength); + } + public void testClassNameNotFoundResultsInException() { MethodDefinitionSourceEditor editor = new MethodDefinitionSourceEditor(); @@ -160,7 +183,7 @@ public class MethodDefinitionSourceEditorTests extends TestCase { "net.sf.acegisecurity.TargetObject.*=ROLE_GENERAL\r\nnet.sf.acegisecurity.TargetObject.makeLower*=ROLE_LOWER\r\nnet.sf.acegisecurity.TargetObject.make*=ROLE_MAKE\r\nnet.sf.acegisecurity.TargetObject.makeUpper*=ROLE_UPPER"); MethodDefinitionMap map = (MethodDefinitionMap) editor.getValue(); - assertEquals(4, map.getMethodMapSize()); + assertEquals(5, map.getMethodMapSize()); ConfigAttributeDefinition returnedMakeLower = map.getAttributes(new MockMethodInvocation( TargetObject.class, "makeLowerCase", diff --git a/core/src/test/java/org/acegisecurity/intercept/method/aopalliance/MethodDefinitionSourceAdvisorTests.java b/core/src/test/java/org/acegisecurity/intercept/method/aopalliance/MethodDefinitionSourceAdvisorTests.java index ad455f128a..b433d3ef0f 100644 --- a/core/src/test/java/org/acegisecurity/intercept/method/aopalliance/MethodDefinitionSourceAdvisorTests.java +++ b/core/src/test/java/org/acegisecurity/intercept/method/aopalliance/MethodDefinitionSourceAdvisorTests.java @@ -85,6 +85,49 @@ public class MethodDefinitionSourceAdvisorTests extends TestCase { } } + public void testUnsupportedOperations() throws Throwable { + Class clazz = TargetObject.class; + Method method = clazz.getMethod("countLength", + new Class[] {String.class}); + + MethodDefinitionSourceAdvisor.InternalMethodInvocation imi = new MethodDefinitionSourceAdvisor(getInterceptor()).new InternalMethodInvocation(method); + + try { + imi.getArguments(); + fail("Should have thrown UnsupportedOperationException"); + } catch (UnsupportedOperationException expected) { + assertTrue(true); + } + + try { + imi.getStaticPart(); + fail("Should have thrown UnsupportedOperationException"); + } catch (UnsupportedOperationException expected) { + assertTrue(true); + } + + try { + imi.getThis(); + fail("Should have thrown UnsupportedOperationException"); + } catch (UnsupportedOperationException expected) { + assertTrue(true); + } + + try { + imi.proceed(); + fail("Should have thrown UnsupportedOperationException"); + } catch (UnsupportedOperationException expected) { + assertTrue(true); + } + + try { + new MethodDefinitionSourceAdvisor(getInterceptor()).new InternalMethodInvocation(); + fail("Should have thrown UnsupportedOperationException"); + } catch (UnsupportedOperationException expected) { + assertTrue(true); + } + } + private MethodSecurityInterceptor getInterceptor() { MethodDefinitionSourceEditor editor = new MethodDefinitionSourceEditor(); editor.setAsText( diff --git a/core/src/test/java/org/acegisecurity/intercept/method/aopalliance/MethodSecurityInterceptorTests.java b/core/src/test/java/org/acegisecurity/intercept/method/aopalliance/MethodSecurityInterceptorTests.java index a3f9182f50..981047e252 100644 --- a/core/src/test/java/org/acegisecurity/intercept/method/aopalliance/MethodSecurityInterceptorTests.java +++ b/core/src/test/java/org/acegisecurity/intercept/method/aopalliance/MethodSecurityInterceptorTests.java @@ -19,14 +19,17 @@ import junit.framework.TestCase; import net.sf.acegisecurity.AccessDecisionManager; import net.sf.acegisecurity.AccessDeniedException; +import net.sf.acegisecurity.AfterInvocationManager; import net.sf.acegisecurity.Authentication; import net.sf.acegisecurity.AuthenticationCredentialsNotFoundException; +import net.sf.acegisecurity.AuthenticationException; import net.sf.acegisecurity.ConfigAttribute; import net.sf.acegisecurity.ConfigAttributeDefinition; import net.sf.acegisecurity.GrantedAuthority; import net.sf.acegisecurity.GrantedAuthorityImpl; import net.sf.acegisecurity.ITargetObject; import net.sf.acegisecurity.MockAccessDecisionManager; +import net.sf.acegisecurity.MockAfterInvocationManager; import net.sf.acegisecurity.MockAuthenticationManager; import net.sf.acegisecurity.MockRunAsManager; import net.sf.acegisecurity.RunAsManager; @@ -139,17 +142,20 @@ public class MethodSecurityInterceptorTests extends TestCase { MockAuthenticationManager authManager = new MockAuthenticationManager(); MockMethodDefinitionSource methodSource = new MockMethodDefinitionSource(false, true); + MockAfterInvocationManager afterInvocation = new MockAfterInvocationManager(); MethodSecurityInterceptor si = new MethodSecurityInterceptor(); si.setAccessDecisionManager(accessDecision); si.setRunAsManager(runAs); si.setAuthenticationManager(authManager); si.setObjectDefinitionSource(methodSource); + si.setAfterInvocationManager(afterInvocation); assertEquals(accessDecision, si.getAccessDecisionManager()); assertEquals(runAs, si.getRunAsManager()); assertEquals(authManager, si.getAuthenticationManager()); assertEquals(methodSource, si.getObjectDefinitionSource()); + assertEquals(afterInvocation, si.getAfterInvocationManager()); } public void testMethodCallWithRunAsReplacement() throws Exception { @@ -178,7 +184,7 @@ public class MethodSecurityInterceptorTests extends TestCase { context.setAuthentication(token); ContextHolder.setContext(context); - ITargetObject target = makeInterceptedTarget(); + ITargetObject target = makeInterceptedTargetWithoutAnAfterInvocationManager(); String result = target.makeLowerCase("HELLO"); // Note we check the isAuthenticated becomes true in following line @@ -234,7 +240,8 @@ public class MethodSecurityInterceptorTests extends TestCase { ContextHolder.setContext(null); } - public void testRejectsAccessDecisionManagersThatDoNotSupportMethodInvocation() { + public void testRejectsAccessDecisionManagersThatDoNotSupportMethodInvocation() + throws Exception { MethodSecurityInterceptor si = new MethodSecurityInterceptor(); si.setAccessDecisionManager(new MockAccessDecisionManagerWhichOnlySupportsStrings()); si.setAuthenticationManager(new MockAuthenticationManager()); @@ -250,6 +257,28 @@ public class MethodSecurityInterceptorTests extends TestCase { } } + public void testRejectsCallsWhenAuthenticationIsIncorrect() + throws Exception { + SecureContext context = new SecureContextImpl(); + UsernamePasswordAuthenticationToken token = new UsernamePasswordAuthenticationToken("Test", + "Password", + new GrantedAuthority[] {new GrantedAuthorityImpl("MOCK_LOWER")}); + assertTrue(!token.isAuthenticated()); + context.setAuthentication(token); + ContextHolder.setContext(context); + + ITargetObject target = makeInterceptedTargetRejectsAuthentication(); + + try { + target.makeLowerCase("HELLO"); + fail("Should have thrown AuthenticationException"); + } catch (AuthenticationException expected) { + assertTrue(true); + } + + ContextHolder.setContext(null); + } + public void testRejectsCallsWhenObjectDefinitionSourceDoesNotSupportObject() throws Throwable { MethodSecurityInterceptor interceptor = new MethodSecurityInterceptor(); @@ -278,12 +307,14 @@ public class MethodSecurityInterceptorTests extends TestCase { } } - public void testRejectsRunAsManagersThatDoNotSupportMethodInvocation() { + public void testRejectsRunAsManagersThatDoNotSupportMethodInvocation() + throws Exception { MethodSecurityInterceptor si = new MethodSecurityInterceptor(); si.setAccessDecisionManager(new MockAccessDecisionManager()); si.setAuthenticationManager(new MockAuthenticationManager()); si.setObjectDefinitionSource(new MockMethodDefinitionSource(false, true)); si.setRunAsManager(new MockRunAsManagerWhichOnlySupportsStrings()); + si.setAfterInvocationManager(new MockAfterInvocationManager()); try { si.afterPropertiesSet(); @@ -294,10 +325,12 @@ public class MethodSecurityInterceptorTests extends TestCase { } } - public void testStartupCheckForAccessDecisionManager() { + public void testStartupCheckForAccessDecisionManager() + throws Exception { MethodSecurityInterceptor si = new MethodSecurityInterceptor(); si.setRunAsManager(new MockRunAsManager()); si.setAuthenticationManager(new MockAuthenticationManager()); + si.setAfterInvocationManager(new MockAfterInvocationManager()); si.setObjectDefinitionSource(new MockMethodDefinitionSource(false, true)); @@ -310,10 +343,12 @@ public class MethodSecurityInterceptorTests extends TestCase { } } - public void testStartupCheckForAuthenticationManager() { + public void testStartupCheckForAuthenticationManager() + throws Exception { MethodSecurityInterceptor si = new MethodSecurityInterceptor(); si.setAccessDecisionManager(new MockAccessDecisionManager()); si.setRunAsManager(new MockRunAsManager()); + si.setAfterInvocationManager(new MockAfterInvocationManager()); si.setObjectDefinitionSource(new MockMethodDefinitionSource(false, true)); @@ -326,7 +361,8 @@ public class MethodSecurityInterceptorTests extends TestCase { } } - public void testStartupCheckForMethodDefinitionSource() { + public void testStartupCheckForMethodDefinitionSource() + throws Exception { MethodSecurityInterceptor si = new MethodSecurityInterceptor(); si.setAccessDecisionManager(new MockAccessDecisionManager()); si.setAuthenticationManager(new MockAuthenticationManager()); @@ -340,7 +376,7 @@ public class MethodSecurityInterceptorTests extends TestCase { } } - public void testStartupCheckForRunAsManager() { + public void testStartupCheckForRunAsManager() throws Exception { MethodSecurityInterceptor si = new MethodSecurityInterceptor(); si.setAccessDecisionManager(new MockAccessDecisionManager()); si.setAuthenticationManager(new MockAuthenticationManager()); @@ -356,7 +392,25 @@ public class MethodSecurityInterceptorTests extends TestCase { } } - public void testValidationFailsIfInvalidAttributePresented() { + public void testStartupCheckForValidAfterInvocationManager() + throws Exception { + MethodSecurityInterceptor si = new MethodSecurityInterceptor(); + si.setRunAsManager(new MockRunAsManager()); + si.setAuthenticationManager(new MockAuthenticationManager()); + si.setAfterInvocationManager(new MockAfterInvocationManagerWhichOnlySupportsStrings()); + si.setAccessDecisionManager(new MockAccessDecisionManager()); + si.setObjectDefinitionSource(new MockMethodDefinitionSource(false, true)); + + try { + si.afterPropertiesSet(); + fail("Should have thrown IllegalArgumentException"); + } catch (IllegalArgumentException expected) { + assertTrue(expected.getMessage().startsWith("AfterInvocationManager does not support secure object class:")); + } + } + + public void testValidationFailsIfInvalidAttributePresented() + throws Exception { MethodSecurityInterceptor si = new MethodSecurityInterceptor(); si.setAccessDecisionManager(new MockAccessDecisionManager()); si.setAuthenticationManager(new MockAuthenticationManager()); @@ -374,7 +428,8 @@ public class MethodSecurityInterceptorTests extends TestCase { } } - public void testValidationNotAttemptedIfIsValidateConfigAttributesSetToFalse() { + public void testValidationNotAttemptedIfIsValidateConfigAttributesSetToFalse() + throws Exception { MethodSecurityInterceptor si = new MethodSecurityInterceptor(); si.setAccessDecisionManager(new MockAccessDecisionManager()); si.setAuthenticationManager(new MockAuthenticationManager()); @@ -388,7 +443,8 @@ public class MethodSecurityInterceptorTests extends TestCase { assertTrue(true); } - public void testValidationNotAttemptedIfMethodDefinitionSourceCannotReturnIterator() { + public void testValidationNotAttemptedIfMethodDefinitionSourceCannotReturnIterator() + throws Exception { MethodSecurityInterceptor si = new MethodSecurityInterceptor(); si.setAccessDecisionManager(new MockAccessDecisionManager()); si.setRunAsManager(new MockRunAsManager()); @@ -407,6 +463,29 @@ public class MethodSecurityInterceptorTests extends TestCase { return (ITargetObject) context.getBean("target"); } + private ITargetObject makeInterceptedTargetRejectsAuthentication() { + ApplicationContext context = new ClassPathXmlApplicationContext( + "net/sf/acegisecurity/intercept/method/aopalliance/applicationContext.xml"); + + MockAuthenticationManager authenticationManager = new MockAuthenticationManager(false); + MethodSecurityInterceptor si = (MethodSecurityInterceptor) context + .getBean("securityInterceptor"); + si.setAuthenticationManager(authenticationManager); + + return (ITargetObject) context.getBean("target"); + } + + private ITargetObject makeInterceptedTargetWithoutAnAfterInvocationManager() { + ApplicationContext context = new ClassPathXmlApplicationContext( + "net/sf/acegisecurity/intercept/method/aopalliance/applicationContext.xml"); + + MethodSecurityInterceptor si = (MethodSecurityInterceptor) context + .getBean("securityInterceptor"); + si.setAfterInvocationManager(null); + + return (ITargetObject) context.getBean("target"); + } + //~ Inner Classes ========================================================== private class MockAccessDecisionManagerWhichOnlySupportsStrings @@ -430,6 +509,28 @@ public class MethodSecurityInterceptorTests extends TestCase { } } + private class MockAfterInvocationManagerWhichOnlySupportsStrings + implements AfterInvocationManager { + public Object decide(Authentication authentication, Object object, + ConfigAttributeDefinition config, Object returnedObject) + throws AccessDeniedException { + throw new UnsupportedOperationException( + "mock method not implemented"); + } + + public boolean supports(Class clazz) { + if (String.class.isAssignableFrom(clazz)) { + return true; + } else { + return false; + } + } + + public boolean supports(ConfigAttribute attribute) { + return true; + } + } + private class MockObjectDefinitionSourceWhichOnlySupportsStrings extends AbstractMethodDefinitionSource { public Iterator getConfigAttributeDefinitions() { diff --git a/core/src/test/java/org/acegisecurity/intercept/method/aspectj/AspectJSecurityInterceptorTests.java b/core/src/test/java/org/acegisecurity/intercept/method/aspectj/AspectJSecurityInterceptorTests.java new file mode 100644 index 0000000000..bbc42c033d --- /dev/null +++ b/core/src/test/java/org/acegisecurity/intercept/method/aspectj/AspectJSecurityInterceptorTests.java @@ -0,0 +1,163 @@ +/* Copyright 2004 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. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package net.sf.acegisecurity.intercept.method.aspectj; + +import junit.framework.TestCase; + +import net.sf.acegisecurity.AccessDeniedException; +import net.sf.acegisecurity.GrantedAuthority; +import net.sf.acegisecurity.GrantedAuthorityImpl; +import net.sf.acegisecurity.MockAccessDecisionManager; +import net.sf.acegisecurity.MockApplicationContext; +import net.sf.acegisecurity.MockAuthenticationManager; +import net.sf.acegisecurity.MockJoinPoint; +import net.sf.acegisecurity.MockRunAsManager; +import net.sf.acegisecurity.TargetObject; +import net.sf.acegisecurity.context.ContextHolder; +import net.sf.acegisecurity.context.SecureContext; +import net.sf.acegisecurity.context.SecureContextImpl; +import net.sf.acegisecurity.intercept.method.MethodDefinitionMap; +import net.sf.acegisecurity.intercept.method.MethodDefinitionSourceEditor; +import net.sf.acegisecurity.providers.TestingAuthenticationToken; + +import java.lang.reflect.Method; + + +/** + * Tests {@link AspectJSecurityInterceptor}. + * + * @author Ben Alex + * @version $Id$ + */ +public class AspectJSecurityInterceptorTests extends TestCase { + //~ Constructors =========================================================== + + public AspectJSecurityInterceptorTests() { + super(); + } + + public AspectJSecurityInterceptorTests(String arg0) { + super(arg0); + } + + //~ Methods ================================================================ + + public final void setUp() throws Exception { + super.setUp(); + } + + public static void main(String[] args) { + junit.textui.TestRunner.run(AspectJSecurityInterceptorTests.class); + } + + public void testCallbackIsInvokedWhenPermissionGranted() + throws Exception { + AspectJSecurityInterceptor si = new AspectJSecurityInterceptor(); + si.setApplicationContext(MockApplicationContext.getContext()); + si.setAccessDecisionManager(new MockAccessDecisionManager()); + si.setAuthenticationManager(new MockAuthenticationManager()); + si.setRunAsManager(new MockRunAsManager()); + + MethodDefinitionSourceEditor editor = new MethodDefinitionSourceEditor(); + editor.setAsText( + "net.sf.acegisecurity.TargetObject.countLength=MOCK_ONE,MOCK_TWO"); + + MethodDefinitionMap map = (MethodDefinitionMap) editor.getValue(); + si.setObjectDefinitionSource(map); + assertEquals(map, si.getObjectDefinitionSource()); + + si.afterPropertiesSet(); + + Class clazz = TargetObject.class; + Method method = clazz.getMethod("countLength", + new Class[] {String.class}); + MockJoinPoint joinPoint = new MockJoinPoint(new TargetObject(), method); + + MockAspectJCallback aspectJCallback = new MockAspectJCallback(); + + SecureContext secureContext = new SecureContextImpl(); + secureContext.setAuthentication(new TestingAuthenticationToken( + "marissa", "koala", + new GrantedAuthority[] {new GrantedAuthorityImpl("MOCK_ONE")})); + ContextHolder.setContext(secureContext); + + Object result = si.invoke(joinPoint, aspectJCallback); + + assertEquals("object proceeded", result); + + ContextHolder.setContext(null); + } + + public void testCallbackIsNotInvokedWhenPermissionDenied() + throws Exception { + AspectJSecurityInterceptor si = new AspectJSecurityInterceptor(); + si.setApplicationContext(MockApplicationContext.getContext()); + si.setAccessDecisionManager(new MockAccessDecisionManager()); + si.setAuthenticationManager(new MockAuthenticationManager()); + si.setRunAsManager(new MockRunAsManager()); + + MethodDefinitionSourceEditor editor = new MethodDefinitionSourceEditor(); + editor.setAsText( + "net.sf.acegisecurity.TargetObject.countLength=MOCK_ONE,MOCK_TWO"); + + MethodDefinitionMap map = (MethodDefinitionMap) editor.getValue(); + si.setObjectDefinitionSource(map); + + si.afterPropertiesSet(); + + Class clazz = TargetObject.class; + Method method = clazz.getMethod("countLength", + new Class[] {String.class}); + MockJoinPoint joinPoint = new MockJoinPoint(new TargetObject(), method); + + MockAspectJCallback aspectJCallback = new MockAspectJCallback(); + aspectJCallback.setThrowExceptionIfInvoked(true); + + SecureContext secureContext = new SecureContextImpl(); + secureContext.setAuthentication(new TestingAuthenticationToken( + "marissa", "koala", new GrantedAuthority[] {})); + ContextHolder.setContext(secureContext); + + try { + si.invoke(joinPoint, aspectJCallback); + fail("Should have thrown AccessDeniedException"); + } catch (AccessDeniedException expected) { + assertTrue(true); + } + + ContextHolder.setContext(null); + } + + //~ Inner Classes ========================================================== + + private class MockAspectJCallback implements AspectJCallback { + private boolean throwExceptionIfInvoked = false; + + private MockAspectJCallback() {} + + public void setThrowExceptionIfInvoked(boolean throwExceptionIfInvoked) { + this.throwExceptionIfInvoked = throwExceptionIfInvoked; + } + + public Object proceedWithObject() { + if (throwExceptionIfInvoked) { + throw new IllegalStateException("AspectJCallback proceeded"); + } + + return "object proceeded"; + } + } +} diff --git a/core/src/test/java/org/acegisecurity/intercept/web/FilterSecurityInterceptorTests.java b/core/src/test/java/org/acegisecurity/intercept/web/FilterSecurityInterceptorTests.java index d977e15c6b..0a0ba80ec3 100644 --- a/core/src/test/java/org/acegisecurity/intercept/web/FilterSecurityInterceptorTests.java +++ b/core/src/test/java/org/acegisecurity/intercept/web/FilterSecurityInterceptorTests.java @@ -25,6 +25,7 @@ import net.sf.acegisecurity.ConfigAttributeDefinition; import net.sf.acegisecurity.GrantedAuthority; import net.sf.acegisecurity.GrantedAuthorityImpl; import net.sf.acegisecurity.MockAccessDecisionManager; +import net.sf.acegisecurity.MockApplicationContext; import net.sf.acegisecurity.MockAuthenticationManager; import net.sf.acegisecurity.MockHttpServletRequest; import net.sf.acegisecurity.MockHttpServletResponse; @@ -74,7 +75,8 @@ public class FilterSecurityInterceptorTests extends TestCase { junit.textui.TestRunner.run(FilterSecurityInterceptorTests.class); } - public void testEnsuresAccessDecisionManagerSupportsFilterInvocationClass() { + public void testEnsuresAccessDecisionManagerSupportsFilterInvocationClass() + throws Exception { FilterSecurityInterceptor interceptor = new FilterSecurityInterceptor(); interceptor.setAuthenticationManager(new MockAuthenticationManager()); interceptor.setObjectDefinitionSource(new RegExpBasedFilterInvocationDefinitionMap()); @@ -106,7 +108,8 @@ public class FilterSecurityInterceptorTests extends TestCase { } } - public void testEnsuresRunAsManagerSupportsFilterInvocationClass() { + public void testEnsuresRunAsManagerSupportsFilterInvocationClass() + throws Exception { FilterSecurityInterceptor interceptor = new FilterSecurityInterceptor(); interceptor.setAccessDecisionManager(new MockAccessDecisionManager()); interceptor.setAuthenticationManager(new MockAuthenticationManager()); @@ -138,7 +141,51 @@ public class FilterSecurityInterceptorTests extends TestCase { } } - public void testNormalStartupAndGetter() { + public void testHttpsInvocationReflectsPortNumber() + throws Throwable { + // Setup the FilterSecurityInterceptor + FilterSecurityInterceptor interceptor = new FilterSecurityInterceptor(); + interceptor.setAccessDecisionManager(new MockAccessDecisionManager()); + interceptor.setAuthenticationManager(new MockAuthenticationManager()); + interceptor.setRunAsManager(new MockRunAsManager()); + interceptor.setApplicationContext(MockApplicationContext.getContext()); + + // Setup a mock config attribute definition + ConfigAttributeDefinition def = new ConfigAttributeDefinition(); + def.addConfigAttribute(new SecurityConfig("MOCK_OK")); + + MockFilterInvocationDefinitionMap mockSource = new MockFilterInvocationDefinitionMap("/secure/page.html", + def); + interceptor.setObjectDefinitionSource(mockSource); + + // Setup our expectation that the filter chain will be invoked, as access is granted + MockFilterChain chain = new MockFilterChain(true); + + // Setup our HTTPS request and response + MockHttpServletResponse response = new MockHttpServletResponse(); + MockHttpServletRequest request = new MockHttpServletRequest(null, + new MockHttpSession()); + request.setServletPath("/secure/page.html"); + request.setScheme("https"); + request.setServerPort(443); + + // Setup a Context + SecureContext context = new SecureContextImpl(); + UsernamePasswordAuthenticationToken token = new UsernamePasswordAuthenticationToken("Test", + "Password", + new GrantedAuthority[] {new GrantedAuthorityImpl("MOCK_OK")}); + context.setAuthentication(token); + ContextHolder.setContext(context); + + // Create and test our secure object + FilterInvocation fi = new FilterInvocation(request, response, chain); + interceptor.invoke(fi); + + // Destroy the Context + ContextHolder.setContext(null); + } + + public void testNormalStartupAndGetter() throws Exception { FilterSecurityInterceptor interceptor = new FilterSecurityInterceptor(); interceptor.setAccessDecisionManager(new MockAccessDecisionManager()); interceptor.setAuthenticationManager(new MockAuthenticationManager()); @@ -164,6 +211,7 @@ public class FilterSecurityInterceptorTests extends TestCase { interceptor.setAccessDecisionManager(new MockAccessDecisionManager()); interceptor.setAuthenticationManager(new MockAuthenticationManager()); interceptor.setRunAsManager(new MockRunAsManager()); + interceptor.setApplicationContext(MockApplicationContext.getContext()); // Setup a mock config attribute definition ConfigAttributeDefinition def = new ConfigAttributeDefinition(); diff --git a/core/src/test/java/org/acegisecurity/providers/cas/CasAuthenticationTokenTests.java b/core/src/test/java/org/acegisecurity/providers/cas/CasAuthenticationTokenTests.java index f0e0cda195..38ac1f06df 100644 --- a/core/src/test/java/org/acegisecurity/providers/cas/CasAuthenticationTokenTests.java +++ b/core/src/test/java/org/acegisecurity/providers/cas/CasAuthenticationTokenTests.java @@ -174,6 +174,8 @@ public class CasAuthenticationTokenTests extends TestCase { assertEquals("PGTIOU-0-R0zlgrl4pdAQwBvJWO3vnNpevwqStbSGcq3vKB2SqSFFRnjPHt", token.getProxyGrantingTicketIou()); assertEquals(proxyList, token.getProxyList()); + assertEquals(makeUserDetails().getUsername(), + token.getUserDetails().getUsername()); } public void testNoArgConstructor() { diff --git a/core/src/test/java/org/acegisecurity/providers/dao/DaoAuthenticationProviderTests.java b/core/src/test/java/org/acegisecurity/providers/dao/DaoAuthenticationProviderTests.java index e57338397f..39f38e4093 100644 --- a/core/src/test/java/org/acegisecurity/providers/dao/DaoAuthenticationProviderTests.java +++ b/core/src/test/java/org/acegisecurity/providers/dao/DaoAuthenticationProviderTests.java @@ -31,6 +31,8 @@ import net.sf.acegisecurity.providers.dao.cache.NullUserCache; import net.sf.acegisecurity.providers.dao.salt.SystemWideSaltSource; import net.sf.acegisecurity.providers.encoding.ShaPasswordEncoder; +import org.springframework.context.support.ClassPathXmlApplicationContext; + import org.springframework.dao.DataAccessException; import org.springframework.dao.DataRetrievalFailureException; @@ -103,6 +105,22 @@ public class DaoAuthenticationProviderTests extends TestCase { } } + public void testAuthenticateFailsWithEmptyUsername() { + UsernamePasswordAuthenticationToken token = new UsernamePasswordAuthenticationToken(null, + "koala"); + + DaoAuthenticationProvider provider = new DaoAuthenticationProvider(); + provider.setAuthenticationDao(new MockAuthenticationDaoUserMarissa()); + provider.setUserCache(new MockUserCache()); + + try { + provider.authenticate(token); + fail("Should have thrown BadCredentialsException"); + } catch (BadCredentialsException expected) { + assertTrue(true); + } + } + public void testAuthenticateFailsWithInvalidPassword() { UsernamePasswordAuthenticationToken token = new UsernamePasswordAuthenticationToken("marissa", "INVALID_PASSWORD"); @@ -247,6 +265,27 @@ public class DaoAuthenticationProviderTests extends TestCase { assertEquals("ROLE_TWO", castResult.getAuthorities()[1].getAuthority()); } + public void testAuthenticatesWithForcePrincipalAsString() { + UsernamePasswordAuthenticationToken token = new UsernamePasswordAuthenticationToken("marissa", + "koala"); + + DaoAuthenticationProvider provider = new DaoAuthenticationProvider(); + provider.setAuthenticationDao(new MockAuthenticationDaoUserMarissa()); + provider.setUserCache(new MockUserCache()); + provider.setForcePrincipalAsString(true); + + Authentication result = provider.authenticate(token); + + if (!(result instanceof UsernamePasswordAuthenticationToken)) { + fail( + "Should have returned instance of UsernamePasswordAuthenticationToken"); + } + + UsernamePasswordAuthenticationToken castResult = (UsernamePasswordAuthenticationToken) result; + assertEquals(String.class, castResult.getPrincipal().getClass()); + assertEquals("marissa", castResult.getPrincipal()); + } + public void testGettersSetters() { DaoAuthenticationProvider provider = new DaoAuthenticationProvider(); provider.setPasswordEncoder(new ShaPasswordEncoder()); @@ -264,6 +303,41 @@ public class DaoAuthenticationProviderTests extends TestCase { assertFalse(provider.isForcePrincipalAsString()); provider.setForcePrincipalAsString(true); assertTrue(provider.isForcePrincipalAsString()); + + provider.setApplicationContext(new ClassPathXmlApplicationContext( + "net/sf/acegisecurity/util/filtertest-valid.xml")); + assertEquals(ClassPathXmlApplicationContext.class.getName(), + provider.getContext().getClass().getName()); + } + + public void testGoesBackToAuthenticationDaoToObtainLatestPasswordIfCachedPasswordSeemsIncorrect() { + UsernamePasswordAuthenticationToken token = new UsernamePasswordAuthenticationToken("marissa", + "koala"); + + MockAuthenticationDaoUserMarissa authenticationDao = new MockAuthenticationDaoUserMarissa(); + MockUserCache cache = new MockUserCache(); + DaoAuthenticationProvider provider = new DaoAuthenticationProvider(); + provider.setAuthenticationDao(authenticationDao); + provider.setUserCache(cache); + + // This will work, as password still "koala" + provider.authenticate(token); + + // Check "marissa = koala" ended up in the cache + assertEquals("koala", cache.getUserFromCache("marissa").getPassword()); + + // Now change the password the AuthenticationDao will return + authenticationDao.setPassword("easternLongNeckTurtle"); + + // Now try authentication again, with the new password + token = new UsernamePasswordAuthenticationToken("marissa", + "easternLongNeckTurtle"); + provider.authenticate(token); + + // To get this far, the new password was accepted + // Check the cache was updated + assertEquals("easternLongNeckTurtle", + cache.getUserFromCache("marissa").getPassword()); } public void testStartupFailsIfNoAuthenticationDao() @@ -320,10 +394,16 @@ public class DaoAuthenticationProviderTests extends TestCase { } private class MockAuthenticationDaoUserMarissa implements AuthenticationDao { + private String password = "koala"; + + public void setPassword(String password) { + this.password = password; + } + public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException, DataAccessException { if ("marissa".equals(username)) { - return new User("marissa", "koala", true, + return new User("marissa", password, true, new GrantedAuthority[] {new GrantedAuthorityImpl("ROLE_ONE"), new GrantedAuthorityImpl( "ROLE_TWO")}); } else { diff --git a/core/src/test/java/org/acegisecurity/providers/dao/PasswordDaoAuthenticationProviderTests.java b/core/src/test/java/org/acegisecurity/providers/dao/PasswordDaoAuthenticationProviderTests.java index e6ddb631ea..12521b00c3 100644 --- a/core/src/test/java/org/acegisecurity/providers/dao/PasswordDaoAuthenticationProviderTests.java +++ b/core/src/test/java/org/acegisecurity/providers/dao/PasswordDaoAuthenticationProviderTests.java @@ -198,6 +198,27 @@ public class PasswordDaoAuthenticationProviderTests extends TestCase { assertEquals(result.getCredentials(), result2.getCredentials()); } + public void testAuthenticatesWithForcePrincipalAsString() { + UsernamePasswordAuthenticationToken token = new UsernamePasswordAuthenticationToken("marissa", + "koala"); + + PasswordDaoAuthenticationProvider provider = new PasswordDaoAuthenticationProvider(); + provider.setPasswordAuthenticationDao(new MockAuthenticationDaoUserMarissa()); + provider.setUserCache(new MockUserCache()); + provider.setForcePrincipalAsString(true); + + Authentication result = provider.authenticate(token); + + if (!(result instanceof UsernamePasswordAuthenticationToken)) { + fail( + "Should have returned instance of UsernamePasswordAuthenticationToken"); + } + + UsernamePasswordAuthenticationToken castResult = (UsernamePasswordAuthenticationToken) result; + assertEquals(String.class, castResult.getPrincipal().getClass()); + assertEquals("marissa", castResult.getPrincipal()); + } + public void testGettersSetters() { PasswordDaoAuthenticationProvider provider = new PasswordDaoAuthenticationProvider(); provider.setUserCache(new EhCacheBasedUserCache()); diff --git a/core/src/test/java/org/acegisecurity/providers/dao/event/LoggerListenerTests.java b/core/src/test/java/org/acegisecurity/providers/dao/event/LoggerListenerTests.java index e45033caaa..434e303637 100644 --- a/core/src/test/java/org/acegisecurity/providers/dao/event/LoggerListenerTests.java +++ b/core/src/test/java/org/acegisecurity/providers/dao/event/LoggerListenerTests.java @@ -65,6 +65,22 @@ public class LoggerListenerTests extends TestCase { assertTrue(true); } + public void testLogsUsernameNotFoundEvents() { + AuthenticationFailureUsernameNotFoundEvent event = new AuthenticationFailureUsernameNotFoundEvent(getAuthentication(), + getUser()); + LoggerListener listener = new LoggerListener(); + listener.onApplicationEvent(event); + assertTrue(true); + } + + public void testLogsUsernameOfPasswordEvent() { + AuthenticationFailureUsernameOrPasswordEvent event = new AuthenticationFailureUsernameOrPasswordEvent(getAuthentication(), + getUser()); + LoggerListener listener = new LoggerListener(); + listener.onApplicationEvent(event); + assertTrue(true); + } + private Authentication getAuthentication() { UsernamePasswordAuthenticationToken authentication = new UsernamePasswordAuthenticationToken("Principal", "Credentials"); diff --git a/core/src/test/java/org/acegisecurity/taglibs/authz/AclTagTests.java b/core/src/test/java/org/acegisecurity/taglibs/authz/AclTagTests.java new file mode 100644 index 0000000000..4ee2f1446a --- /dev/null +++ b/core/src/test/java/org/acegisecurity/taglibs/authz/AclTagTests.java @@ -0,0 +1,226 @@ +/* Copyright 2004 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. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package net.sf.acegisecurity.taglibs.authz; + +import junit.framework.TestCase; + +import net.sf.acegisecurity.Authentication; +import net.sf.acegisecurity.GrantedAuthority; +import net.sf.acegisecurity.MockAclManager; +import net.sf.acegisecurity.MockApplicationContext; +import net.sf.acegisecurity.acl.AclEntry; +import net.sf.acegisecurity.acl.AclManager; +import net.sf.acegisecurity.acl.basic.MockAclObjectIdentity; +import net.sf.acegisecurity.acl.basic.SimpleAclEntry; +import net.sf.acegisecurity.context.ContextHolder; +import net.sf.acegisecurity.context.SecureContext; +import net.sf.acegisecurity.context.SecureContextImpl; +import net.sf.acegisecurity.providers.TestingAuthenticationToken; + +import org.springframework.context.ApplicationContext; +import org.springframework.context.ConfigurableApplicationContext; + +import javax.servlet.jsp.JspException; +import javax.servlet.jsp.PageContext; +import javax.servlet.jsp.tagext.Tag; + + +/** + * Tests {@link AclTag}. + * + * @author Ben Alex + * @version $Id$ + */ +public class AclTagTests extends TestCase { + //~ Instance fields ======================================================== + + private final MyAclTag aclTag = new MyAclTag(); + + //~ Methods ================================================================ + + public void testInclusionDeniedWhenAclManagerUnawareOfObject() + throws JspException { + Authentication auth = new TestingAuthenticationToken("marissa", + "koala", new GrantedAuthority[] {}); + SecureContext sc = new SecureContextImpl(); + sc.setAuthentication(auth); + ContextHolder.setContext(sc); + + aclTag.setHasPermission(new Long(SimpleAclEntry.ADMINISTRATION) + .toString()); + aclTag.setDomainObject(new Integer(54)); + assertEquals(Tag.SKIP_BODY, aclTag.doStartTag()); + + ContextHolder.setContext(null); + } + + public void testInclusionDeniedWhenAuthenticationEmpty() + throws JspException { + ContextHolder.setContext(new SecureContextImpl()); + + aclTag.setHasPermission(new Long(SimpleAclEntry.ADMINISTRATION) + .toString()); + aclTag.setDomainObject("object1"); + assertEquals(Tag.SKIP_BODY, aclTag.doStartTag()); + + ContextHolder.setContext(null); + } + + public void testInclusionDeniedWhenContextHolderEmpty() + throws JspException { + ContextHolder.setContext(null); + + aclTag.setHasPermission(new Long(SimpleAclEntry.ADMINISTRATION) + .toString()); + aclTag.setDomainObject("object1"); + assertEquals(Tag.SKIP_BODY, aclTag.doStartTag()); + + ContextHolder.setContext(null); + } + + public void testInclusionDeniedWhenNoListOfPermissionsGiven() + throws JspException { + Authentication auth = new TestingAuthenticationToken("marissa", + "koala", new GrantedAuthority[] {}); + SecureContext sc = new SecureContextImpl(); + sc.setAuthentication(auth); + ContextHolder.setContext(sc); + + aclTag.setHasPermission(null); + aclTag.setDomainObject("object1"); + assertEquals(Tag.SKIP_BODY, aclTag.doStartTag()); + + ContextHolder.setContext(null); + } + + public void testInclusionDeniedWhenPrincipalDoesNotHoldAnyPermissions() + throws JspException { + Authentication auth = new TestingAuthenticationToken("john", "crow", + new GrantedAuthority[] {}); + SecureContext sc = new SecureContextImpl(); + sc.setAuthentication(auth); + ContextHolder.setContext(sc); + + aclTag.setHasPermission(new Integer(SimpleAclEntry.ADMINISTRATION) + + "," + new Integer(SimpleAclEntry.READ)); + assertEquals(new Integer(SimpleAclEntry.ADMINISTRATION) + "," + + new Integer(SimpleAclEntry.READ), aclTag.getHasPermission()); + aclTag.setDomainObject("object1"); + assertEquals("object1", aclTag.getDomainObject()); + assertEquals(Tag.SKIP_BODY, aclTag.doStartTag()); + + ContextHolder.setContext(null); + } + + public void testInclusionDeniedWhenPrincipalDoesNotHoldRequiredPermissions() + throws JspException { + Authentication auth = new TestingAuthenticationToken("marissa", + "koala", new GrantedAuthority[] {}); + SecureContext sc = new SecureContextImpl(); + sc.setAuthentication(auth); + ContextHolder.setContext(sc); + + aclTag.setHasPermission(new Integer(SimpleAclEntry.DELETE).toString()); + aclTag.setDomainObject("object1"); + assertEquals(Tag.SKIP_BODY, aclTag.doStartTag()); + + ContextHolder.setContext(null); + } + + public void testInclusionPermittedWhenDomainObjectIsNull() + throws JspException { + aclTag.setHasPermission(new Integer(SimpleAclEntry.READ).toString()); + aclTag.setDomainObject(null); + assertEquals(Tag.EVAL_BODY_INCLUDE, aclTag.doStartTag()); + } + + public void testJspExceptionThrownIfHasPermissionNotValidFormat() + throws JspException { + Authentication auth = new TestingAuthenticationToken("john", "crow", + new GrantedAuthority[] {}); + SecureContext sc = new SecureContextImpl(); + sc.setAuthentication(auth); + ContextHolder.setContext(sc); + + aclTag.setHasPermission("0,5, 6"); // shouldn't be any space + + try { + aclTag.doStartTag(); + fail("Should have thrown JspException"); + } catch (JspException expected) { + assertTrue(true); + } + + ContextHolder.setContext(null); + } + + public void testOperationWhenPrincipalHoldsPermissionOfMultipleList() + throws JspException { + Authentication auth = new TestingAuthenticationToken("marissa", + "koala", new GrantedAuthority[] {}); + SecureContext sc = new SecureContextImpl(); + sc.setAuthentication(auth); + ContextHolder.setContext(sc); + + aclTag.setHasPermission(new Integer(SimpleAclEntry.ADMINISTRATION) + + "," + new Integer(SimpleAclEntry.READ)); + aclTag.setDomainObject("object1"); + assertEquals(Tag.EVAL_BODY_INCLUDE, aclTag.doStartTag()); + + ContextHolder.setContext(null); + } + + public void testOperationWhenPrincipalHoldsPermissionOfSingleList() + throws JspException { + Authentication auth = new TestingAuthenticationToken("marissa", + "koala", new GrantedAuthority[] {}); + SecureContext sc = new SecureContextImpl(); + sc.setAuthentication(auth); + ContextHolder.setContext(sc); + + aclTag.setHasPermission(new Integer(SimpleAclEntry.READ).toString()); + aclTag.setDomainObject("object1"); + assertEquals(Tag.EVAL_BODY_INCLUDE, aclTag.doStartTag()); + + ContextHolder.setContext(null); + } + + //~ Inner Classes ========================================================== + + private class MockAclEntry implements AclEntry { + // just so AclTag iterates some different types of AclEntrys + } + + private class MyAclTag extends AclTag { + protected ApplicationContext getContext(PageContext pageContext) { + ConfigurableApplicationContext context = MockApplicationContext + .getContext(); + + // Create an AclManager + AclManager aclManager = new MockAclManager("object1", "marissa", + new AclEntry[] {new MockAclEntry(), new SimpleAclEntry( + "marissa", new MockAclObjectIdentity(), null, + SimpleAclEntry.ADMINISTRATION), new SimpleAclEntry( + "marissa", new MockAclObjectIdentity(), null, + SimpleAclEntry.READ)}); + + // Register the AclManager into our ApplicationContext + context.getBeanFactory().registerSingleton("aclManager", aclManager); + + return context; + } + } +} diff --git a/core/src/test/java/org/acegisecurity/taglibs/authz/AuthenticationTagTests.java b/core/src/test/java/org/acegisecurity/taglibs/authz/AuthenticationTagTests.java new file mode 100644 index 0000000000..52f0efa428 --- /dev/null +++ b/core/src/test/java/org/acegisecurity/taglibs/authz/AuthenticationTagTests.java @@ -0,0 +1,133 @@ +/* Copyright 2004 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. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package net.sf.acegisecurity.taglibs.authz; + +import junit.framework.TestCase; + +import net.sf.acegisecurity.Authentication; +import net.sf.acegisecurity.GrantedAuthority; +import net.sf.acegisecurity.context.ContextHolder; +import net.sf.acegisecurity.context.SecureContext; +import net.sf.acegisecurity.context.SecureContextImpl; +import net.sf.acegisecurity.providers.TestingAuthenticationToken; +import net.sf.acegisecurity.providers.dao.User; + +import javax.servlet.jsp.JspException; +import javax.servlet.jsp.tagext.Tag; + + +/** + * Tests {@link AuthenticationTag}. + * + * @author Ben Alex + * @version $Id$ + */ +public class AuthenticationTagTests extends TestCase { + //~ Instance fields ======================================================== + + private final MyAuthenticationTag authenticationTag = new MyAuthenticationTag(); + + //~ Methods ================================================================ + + public void testOperationWhenAuthenticationIsNull() + throws JspException { + ContextHolder.setContext(new SecureContextImpl()); + + authenticationTag.setOperation("principal"); + assertEquals(Tag.SKIP_BODY, authenticationTag.doStartTag()); + assertEquals(null, authenticationTag.getLastMessage()); + + ContextHolder.setContext(null); + } + + public void testOperationWhenContextHolderIsNull() + throws JspException { + ContextHolder.setContext(null); + + authenticationTag.setOperation("principal"); + assertEquals(Tag.SKIP_BODY, authenticationTag.doStartTag()); + assertEquals(null, authenticationTag.getLastMessage()); + } + + public void testOperationWhenPrincipalIsAString() throws JspException { + Authentication auth = new TestingAuthenticationToken("marissaAsString", + "koala", new GrantedAuthority[] {}); + SecureContext sc = new SecureContextImpl(); + sc.setAuthentication(auth); + ContextHolder.setContext(sc); + + authenticationTag.setOperation("principal"); + assertEquals(Tag.SKIP_BODY, authenticationTag.doStartTag()); + assertEquals("marissaAsString", authenticationTag.getLastMessage()); + } + + public void testOperationWhenPrincipalIsAUserDetailsInstance() + throws JspException { + Authentication auth = new TestingAuthenticationToken(new User( + "marissaUserDetails", "koala", true, + new GrantedAuthority[] {}), "koala", + new GrantedAuthority[] {}); + SecureContext sc = new SecureContextImpl(); + sc.setAuthentication(auth); + ContextHolder.setContext(sc); + + authenticationTag.setOperation("principal"); + assertEquals(Tag.SKIP_BODY, authenticationTag.doStartTag()); + assertEquals("marissaUserDetails", authenticationTag.getLastMessage()); + } + + public void testOperationWhenPrincipalIsNull() throws JspException { + Authentication auth = new TestingAuthenticationToken(null, "koala", + new GrantedAuthority[] {}); + SecureContext sc = new SecureContextImpl(); + sc.setAuthentication(auth); + ContextHolder.setContext(sc); + + authenticationTag.setOperation("principal"); + assertEquals(Tag.SKIP_BODY, authenticationTag.doStartTag()); + } + + public void testSkipsBodyIfNullOrEmptyOperation() throws Exception { + authenticationTag.setOperation(""); + assertEquals("", authenticationTag.getOperation()); + assertEquals(Tag.SKIP_BODY, authenticationTag.doStartTag()); + } + + public void testThrowsExceptionForUnrecognisedOperation() { + authenticationTag.setOperation("qsq"); + + try { + authenticationTag.doStartTag(); + fail("Should have throwns JspException"); + } catch (JspException expected) { + assertTrue(true); + } + } + + //~ Inner Classes ========================================================== + + private class MyAuthenticationTag extends AuthenticationTag { + String lastMessage = null; + + public String getLastMessage() { + return lastMessage; + } + + protected void writeMessage(String msg) throws JspException { + lastMessage = msg; + } + } +} diff --git a/core/src/test/java/org/acegisecurity/ui/AbstractProcessingFilterTests.java b/core/src/test/java/org/acegisecurity/ui/AbstractProcessingFilterTests.java index 21d026391d..7f2cbf071b 100644 --- a/core/src/test/java/org/acegisecurity/ui/AbstractProcessingFilterTests.java +++ b/core/src/test/java/org/acegisecurity/ui/AbstractProcessingFilterTests.java @@ -179,6 +179,10 @@ public class AbstractProcessingFilterTests extends TestCase { filter.setAuthenticationProxyUntrustedFailureUrl("/proxy"); assertEquals("/proxy", filter.getAuthenticationProxyUntrustedFailureUrl()); + + filter.setAuthenticationServiceFailureUrl("/serviceFailure"); + assertEquals("/serviceFailure", + filter.getAuthenticationServiceFailureUrl()); } public void testIgnoresAnyServletPathOtherThanFilterProcessesUrl() @@ -365,7 +369,9 @@ public class AbstractProcessingFilterTests extends TestCase { MockAbstractProcessingFilter filter = new MockAbstractProcessingFilter(true); filter.setFilterProcessesUrl("/j_mock_post"); filter.setDefaultTargetUrl("/foobar"); + assertFalse(filter.isAlwaysUseDefaultTargetUrl()); // check default filter.setAlwaysUseDefaultTargetUrl(true); + assertTrue(filter.isAlwaysUseDefaultTargetUrl()); // check changed // Test executeFilterInContainerSimulator(config, filter, request, response, diff --git a/core/src/test/java/org/acegisecurity/ui/httpinvoker/AuthenticationSimpleHttpInvokerRequestExecutorTests.java b/core/src/test/java/org/acegisecurity/ui/httpinvoker/AuthenticationSimpleHttpInvokerRequestExecutorTests.java new file mode 100644 index 0000000000..258a18851c --- /dev/null +++ b/core/src/test/java/org/acegisecurity/ui/httpinvoker/AuthenticationSimpleHttpInvokerRequestExecutorTests.java @@ -0,0 +1,143 @@ +/* Copyright 2004 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. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package net.sf.acegisecurity.ui.httpinvoker; + +import junit.framework.TestCase; + +import net.sf.acegisecurity.Authentication; +import net.sf.acegisecurity.context.ContextHolder; +import net.sf.acegisecurity.context.SecureContext; +import net.sf.acegisecurity.context.SecureContextImpl; +import net.sf.acegisecurity.providers.UsernamePasswordAuthenticationToken; + +import java.io.IOException; + +import java.net.HttpURLConnection; +import java.net.URL; + +import java.util.HashMap; +import java.util.Map; + + +/** + * Tests {@link AuthenticationSimpleHttpInvokerRequestExecutor}. + * + * @author Ben Alex + * @version $Id$ + */ +public class AuthenticationSimpleHttpInvokerRequestExecutorTests + extends TestCase { + //~ Constructors =========================================================== + + public AuthenticationSimpleHttpInvokerRequestExecutorTests() { + super(); + } + + public AuthenticationSimpleHttpInvokerRequestExecutorTests(String arg0) { + super(arg0); + } + + //~ Methods ================================================================ + + public static void main(String[] args) { + junit.textui.TestRunner.run(AuthenticationSimpleHttpInvokerRequestExecutorTests.class); + } + + public void testNormalOperation() throws Exception { + // Setup client-side context + SecureContext clientSideContext = new SecureContextImpl(); + Authentication clientSideAuthentication = new UsernamePasswordAuthenticationToken("Aladdin", + "open sesame"); + clientSideContext.setAuthentication(clientSideAuthentication); + ContextHolder.setContext(clientSideContext); + + // Create a connection and ensure our executor sets its + // properties correctly + AuthenticationSimpleHttpInvokerRequestExecutor executor = new AuthenticationSimpleHttpInvokerRequestExecutor(); + HttpURLConnection conn = new MockHttpURLConnection(new URL( + "http://localhost/")); + executor.prepareConnection(conn, 10); + + // Check connection properties + // See http://www.faqs.org/rfcs/rfc1945.html section 11.1 for example + // we are comparing against + assertEquals("Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ==", + conn.getRequestProperty("Authorization")); + + ContextHolder.setContext(null); + } + + public void testNullAuthenticationIsNull() throws Exception { + // Setup client-side context + SecureContext clientSideContext = new SecureContextImpl(); + clientSideContext.setAuthentication(null); + ContextHolder.setContext(clientSideContext); + + // Create a connection and ensure our executor sets its + // properties correctly + AuthenticationSimpleHttpInvokerRequestExecutor executor = new AuthenticationSimpleHttpInvokerRequestExecutor(); + HttpURLConnection conn = new MockHttpURLConnection(new URL( + "http://localhost/")); + executor.prepareConnection(conn, 10); + + // Check connection properties (shouldn't be an Authorization header) + assertNull(conn.getRequestProperty("Authorization")); + } + + public void testNullContextHolderIsNull() throws Exception { + ContextHolder.setContext(null); // just to be explicit + + // Create a connection and ensure our executor sets its + // properties correctly + AuthenticationSimpleHttpInvokerRequestExecutor executor = new AuthenticationSimpleHttpInvokerRequestExecutor(); + HttpURLConnection conn = new MockHttpURLConnection(new URL( + "http://localhost/")); + executor.prepareConnection(conn, 10); + + // Check connection properties (shouldn't be an Authorization header) + assertNull(conn.getRequestProperty("Authorization")); + } + + //~ Inner Classes ========================================================== + + private class MockHttpURLConnection extends HttpURLConnection { + private Map requestProperties = new HashMap(); + + public MockHttpURLConnection(URL u) { + super(u); + } + + public void setRequestProperty(String key, String value) { + requestProperties.put(key, value); + } + + public String getRequestProperty(String key) { + return (String) requestProperties.get(key); + } + + public void connect() throws IOException { + throw new UnsupportedOperationException("mock not implemented"); + } + + public void disconnect() { + throw new UnsupportedOperationException("mock not implemented"); + } + + public boolean usingProxy() { + throw new UnsupportedOperationException("mock not implemented"); + } + } +} diff --git a/core/src/test/java/org/acegisecurity/ui/rmi/ContextPropagatingRemoteInvocationTests.java b/core/src/test/java/org/acegisecurity/ui/rmi/ContextPropagatingRemoteInvocationTests.java new file mode 100644 index 0000000000..a64045f4ba --- /dev/null +++ b/core/src/test/java/org/acegisecurity/ui/rmi/ContextPropagatingRemoteInvocationTests.java @@ -0,0 +1,102 @@ +/* Copyright 2004 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. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package net.sf.acegisecurity.ui.rmi; + +import junit.framework.TestCase; + +import net.sf.acegisecurity.Authentication; +import net.sf.acegisecurity.MockMethodInvocation; +import net.sf.acegisecurity.TargetObject; +import net.sf.acegisecurity.context.ContextHolder; +import net.sf.acegisecurity.context.SecureContext; +import net.sf.acegisecurity.context.SecureContextImpl; +import net.sf.acegisecurity.providers.UsernamePasswordAuthenticationToken; + +import org.aopalliance.intercept.MethodInvocation; + +import java.lang.reflect.Method; + + +/** + * Tests {@link ContextPropagatingRemoteInvocation} and {@link + * ContextPropagatingRemoteInvocationFactory}. + * + * @author Ben Alex + * @version $Id$ + */ +public class ContextPropagatingRemoteInvocationTests extends TestCase { + //~ Constructors =========================================================== + + public ContextPropagatingRemoteInvocationTests() { + super(); + } + + public ContextPropagatingRemoteInvocationTests(String arg0) { + super(arg0); + } + + //~ Methods ================================================================ + + public static void main(String[] args) { + junit.textui.TestRunner.run(ContextPropagatingRemoteInvocationTests.class); + } + + public void testNormalOperation() throws Exception { + // Setup client-side context + SecureContext clientSideContext = new SecureContextImpl(); + Authentication clientSideAuthentication = new UsernamePasswordAuthenticationToken("marissa", + "koala"); + clientSideContext.setAuthentication(clientSideAuthentication); + ContextHolder.setContext(clientSideContext); + + ContextPropagatingRemoteInvocation remoteInvocation = getRemoteInvocation(); + + // Set to null, as ContextPropagatingRemoteInvocation already obtained + // a copy and nulling is necessary to ensure the Context delivered by + // ContextPropagatingRemoteInvocation is used on server-side + ContextHolder.setContext(null); + + // The result from invoking the TargetObject should contain the + // Authentication class delivered via the ContextHolder + assertEquals("some_string net.sf.acegisecurity.providers.UsernamePasswordAuthenticationToken false", + remoteInvocation.invoke(new TargetObject())); + } + + public void testNullContextHolderDoesNotCauseInvocationProblems() + throws Exception { + ContextHolder.setContext(null); // just to be explicit + + ContextPropagatingRemoteInvocation remoteInvocation = getRemoteInvocation(); + ContextHolder.setContext(null); // unnecessary, but for explicitness + + assertEquals("some_string ContextHolder Not Security Aware", + remoteInvocation.invoke(new TargetObject())); + } + + private ContextPropagatingRemoteInvocation getRemoteInvocation() + throws Exception { + Class clazz = TargetObject.class; + Method method = clazz.getMethod("makeLowerCase", + new Class[] {String.class}); + MethodInvocation mi = new MockMethodInvocation(method, + new Object[] {"SOME_STRING"}); + + ContextPropagatingRemoteInvocationFactory factory = new ContextPropagatingRemoteInvocationFactory(); + + return (ContextPropagatingRemoteInvocation) factory + .createRemoteInvocation(mi); + } +} diff --git a/core/src/test/java/org/acegisecurity/ui/webapp/AuthenticationProcessingFilterEntryPointTests.java b/core/src/test/java/org/acegisecurity/ui/webapp/AuthenticationProcessingFilterEntryPointTests.java index f0374a4e4d..5b11b8f579 100644 --- a/core/src/test/java/org/acegisecurity/ui/webapp/AuthenticationProcessingFilterEntryPointTests.java +++ b/core/src/test/java/org/acegisecurity/ui/webapp/AuthenticationProcessingFilterEntryPointTests.java @@ -98,7 +98,8 @@ public class AuthenticationProcessingFilterEntryPointTests extends TestCase { assertTrue(ep.getForceHttps()); } - public void testHttpsOperation() throws Exception { + public void testHttpsOperationFromOriginalHttpUrl() + throws Exception { MockHttpServletRequest request = new MockHttpServletRequest( "/some_path"); request.setScheme("http"); @@ -150,6 +151,36 @@ public class AuthenticationProcessingFilterEntryPointTests extends TestCase { response.getRedirect()); } + public void testHttpsOperationFromOriginalHttpsUrl() + throws Exception { + MockHttpServletRequest request = new MockHttpServletRequest( + "/some_path"); + request.setScheme("https"); + request.setServerName("www.example.com"); + request.setContextPath("/bigWebApp"); + request.setServerPort(443); + + MockHttpServletResponse response = new MockHttpServletResponse(); + + AuthenticationProcessingFilterEntryPoint ep = new AuthenticationProcessingFilterEntryPoint(); + ep.setLoginFormUrl("/hello"); + ep.setPortMapper(new PortMapperImpl()); + ep.setForceHttps(true); + ep.setPortMapper(new PortMapperImpl()); + ep.setPortResolver(new MockPortResolver(80, 443)); + ep.afterPropertiesSet(); + + ep.commence(request, response); + assertEquals("https://www.example.com/bigWebApp/hello", + response.getRedirect()); + + request.setServerPort(8443); + ep.setPortResolver(new MockPortResolver(8080, 8443)); + ep.commence(request, response); + assertEquals("https://www.example.com:8443/bigWebApp/hello", + response.getRedirect()); + } + public void testNormalOperation() throws Exception { AuthenticationProcessingFilterEntryPoint ep = new AuthenticationProcessingFilterEntryPoint(); ep.setLoginFormUrl("/hello"); diff --git a/core/src/test/java/org/acegisecurity/util/FilterToBeanProxyTests.java b/core/src/test/java/org/acegisecurity/util/FilterToBeanProxyTests.java index cb209311b7..10995f941c 100644 --- a/core/src/test/java/org/acegisecurity/util/FilterToBeanProxyTests.java +++ b/core/src/test/java/org/acegisecurity/util/FilterToBeanProxyTests.java @@ -226,6 +226,26 @@ public class FilterToBeanProxyTests extends TestCase { chain); } + public void testNullDelegateDoesNotCauseNullPointerException() + throws Exception { + // Setup our filter + MockFilterConfig config = new MockFilterConfig(); + config.setInitParmeter("targetBean", "aFilterThatDoesntExist"); + config.setInitParmeter("init", "lazy"); + + // Setup our expectation that the filter chain will be invoked + MockFilterChain chain = new MockFilterChain(true); + + MockHttpServletResponse response = new MockHttpServletResponse(); + MockHttpServletRequest request = new MockHttpServletRequest("/go"); + + FilterToBeanProxy filter = new MockFilterToBeanProxy( + "net/sf/acegisecurity/util/filtertest-valid.xml"); + + // do not init (which would hapen if called .doFilter) + filter.destroy(); + } + private void executeFilterInContainerSimulator(FilterConfig filterConfig, Filter filter, ServletRequest request, ServletResponse response, FilterChain filterChain) throws ServletException, IOException { diff --git a/core/src/test/java/org/acegisecurity/util/PortResolverImplTests.java b/core/src/test/java/org/acegisecurity/util/PortResolverImplTests.java index 920ab1ef8f..d6d6ab1efc 100644 --- a/core/src/test/java/org/acegisecurity/util/PortResolverImplTests.java +++ b/core/src/test/java/org/acegisecurity/util/PortResolverImplTests.java @@ -67,6 +67,18 @@ public class PortResolverImplTests extends TestCase { assertEquals(8443, pr.getServerPort(request)); } + public void testDetectsEmptyPortMapper() throws Exception { + PortResolverImpl pr = new PortResolverImpl(); + pr.setPortMapper(null); + + try { + pr.afterPropertiesSet(); + fail("Should have thrown IllegalArgumentException"); + } catch (IllegalArgumentException expected) { + assertTrue(true); + } + } + public void testGettersSetters() throws Exception { PortResolverImpl pr = new PortResolverImpl(); assertTrue(pr.getPortMapper() != null); diff --git a/core/src/test/java/org/acegisecurity/vote/BasicAclEntryVoterTests.java b/core/src/test/java/org/acegisecurity/vote/BasicAclEntryVoterTests.java new file mode 100644 index 0000000000..4160ec0a23 --- /dev/null +++ b/core/src/test/java/org/acegisecurity/vote/BasicAclEntryVoterTests.java @@ -0,0 +1,485 @@ +/* Copyright 2004 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. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package net.sf.acegisecurity.vote; + +import junit.framework.TestCase; + +import net.sf.acegisecurity.AuthorizationServiceException; +import net.sf.acegisecurity.ConfigAttributeDefinition; +import net.sf.acegisecurity.MockAclManager; +import net.sf.acegisecurity.MockMethodInvocation; +import net.sf.acegisecurity.SecurityConfig; +import net.sf.acegisecurity.acl.AclEntry; +import net.sf.acegisecurity.acl.AclManager; +import net.sf.acegisecurity.acl.basic.MockAclObjectIdentity; +import net.sf.acegisecurity.acl.basic.SimpleAclEntry; +import net.sf.acegisecurity.providers.UsernamePasswordAuthenticationToken; + +import org.aopalliance.intercept.MethodInvocation; + +import org.aspectj.lang.JoinPoint; + +import java.lang.reflect.Method; + + +/** + * Tests {@link BasicAclEntryVoter}. + * + * @author Ben Alex + * @version $Id$ + */ +public class BasicAclEntryVoterTests extends TestCase { + //~ Constructors =========================================================== + + public BasicAclEntryVoterTests() { + super(); + } + + public BasicAclEntryVoterTests(String arg0) { + super(arg0); + } + + //~ Methods ================================================================ + + public final void setUp() throws Exception { + super.setUp(); + } + + public static void main(String[] args) { + junit.textui.TestRunner.run(BasicAclEntryVoterTests.class); + } + + public void testNormalOperation() throws Exception { + // Setup a domain object subject of this test + SomeDomainObject domainObject = new SomeDomainObject("foo"); + + // Setup an AclManager + AclManager aclManager = new MockAclManager(domainObject, "marissa", + new AclEntry[] {new MockAclEntry(), new SimpleAclEntry( + "marissa", new MockAclObjectIdentity(), null, + SimpleAclEntry.ADMINISTRATION), new SimpleAclEntry( + "marissa", new MockAclObjectIdentity(), null, + SimpleAclEntry.READ), new SimpleAclEntry("marissa", + new MockAclObjectIdentity(), null, SimpleAclEntry.DELETE)}); + + // Wire up a voter + BasicAclEntryVoter voter = new BasicAclEntryVoter(); + voter.setAclManager(aclManager); + assertEquals(aclManager, voter.getAclManager()); + voter.setProcessConfigAttribute("FOO_ADMIN_OR_WRITE_ACCESS"); + assertEquals("FOO_ADMIN_OR_WRITE_ACCESS", + voter.getProcessConfigAttribute()); + voter.setRequirePermission(new int[] {SimpleAclEntry.ADMINISTRATION, SimpleAclEntry.WRITE}); + assertEquals(2, voter.getRequirePermission().length); + voter.setProcessDomainObjectClass(SomeDomainObject.class); + assertEquals(SomeDomainObject.class, voter.getProcessDomainObjectClass()); + voter.afterPropertiesSet(); + + // Wire up an invocation to be voted on + ConfigAttributeDefinition attr = new ConfigAttributeDefinition(); + attr.addConfigAttribute(new SecurityConfig("FOO_ADMIN_OR_WRITE_ACCESS")); + + // Setup a MockMethodInvocation, so voter can retrieve domainObject + MethodInvocation mi = getMethodInvocation(domainObject); + + assertEquals(AccessDecisionVoter.ACCESS_GRANTED, + voter.vote( + new UsernamePasswordAuthenticationToken("marissa", null), mi, + attr)); + } + + public void testOnlySupportsMethodInvocation() { + BasicAclEntryVoter voter = new BasicAclEntryVoter(); + assertTrue(voter.supports(MethodInvocation.class)); + assertFalse(voter.supports(JoinPoint.class)); + } + + public void testStartupRejectsMissingAclManager() throws Exception { + AclManager aclManager = new MockAclManager("domain1", "marissa", + new AclEntry[] {new MockAclEntry(), new SimpleAclEntry( + "marissa", new MockAclObjectIdentity(), null, + SimpleAclEntry.ADMINISTRATION), new SimpleAclEntry( + "marissa", new MockAclObjectIdentity(), null, + SimpleAclEntry.READ), new SimpleAclEntry("marissa", + new MockAclObjectIdentity(), null, SimpleAclEntry.DELETE)}); + + // Wire up a voter + BasicAclEntryVoter voter = new BasicAclEntryVoter(); + voter.setProcessConfigAttribute("FOO_ADMIN_OR_WRITE_ACCESS"); + voter.setRequirePermission(new int[] {SimpleAclEntry.ADMINISTRATION, SimpleAclEntry.WRITE}); + voter.setProcessDomainObjectClass(SomeDomainObject.class); + + try { + voter.afterPropertiesSet(); + fail("Should have thrown IllegalArgumentException"); + } catch (IllegalArgumentException expected) { + assertTrue(true); + } + } + + public void testStartupRejectsMissingProcessConfigAttribute() + throws Exception { + AclManager aclManager = new MockAclManager("domain1", "marissa", + new AclEntry[] {new MockAclEntry(), new SimpleAclEntry( + "marissa", new MockAclObjectIdentity(), null, + SimpleAclEntry.ADMINISTRATION), new SimpleAclEntry( + "marissa", new MockAclObjectIdentity(), null, + SimpleAclEntry.READ), new SimpleAclEntry("marissa", + new MockAclObjectIdentity(), null, SimpleAclEntry.DELETE)}); + + // Wire up a voter + BasicAclEntryVoter voter = new BasicAclEntryVoter(); + voter.setAclManager(aclManager); + voter.setRequirePermission(new int[] {SimpleAclEntry.ADMINISTRATION, SimpleAclEntry.WRITE}); + voter.setProcessDomainObjectClass(SomeDomainObject.class); + + try { + voter.afterPropertiesSet(); + fail("Should have thrown IllegalArgumentException"); + } catch (IllegalArgumentException expected) { + assertTrue(true); + } + } + + public void testStartupRejectsMissingProcessDomainObjectClass() + throws Exception { + AclManager aclManager = new MockAclManager("domain1", "marissa", + new AclEntry[] {new MockAclEntry(), new SimpleAclEntry( + "marissa", new MockAclObjectIdentity(), null, + SimpleAclEntry.ADMINISTRATION), new SimpleAclEntry( + "marissa", new MockAclObjectIdentity(), null, + SimpleAclEntry.READ), new SimpleAclEntry("marissa", + new MockAclObjectIdentity(), null, SimpleAclEntry.DELETE)}); + + // Wire up a voter + BasicAclEntryVoter voter = new BasicAclEntryVoter(); + voter.setAclManager(aclManager); + voter.setProcessConfigAttribute("FOO_ADMIN_OR_WRITE_ACCESS"); + voter.setRequirePermission(new int[] {SimpleAclEntry.ADMINISTRATION, SimpleAclEntry.WRITE}); + + try { + voter.afterPropertiesSet(); + fail("Should have thrown IllegalArgumentException"); + } catch (IllegalArgumentException expected) { + assertTrue(true); + } + } + + public void testStartupRejectsMissingRequirePermission() + throws Exception { + AclManager aclManager = new MockAclManager("domain1", "marissa", + new AclEntry[] {new MockAclEntry(), new SimpleAclEntry( + "marissa", new MockAclObjectIdentity(), null, + SimpleAclEntry.ADMINISTRATION), new SimpleAclEntry( + "marissa", new MockAclObjectIdentity(), null, + SimpleAclEntry.READ), new SimpleAclEntry("marissa", + new MockAclObjectIdentity(), null, SimpleAclEntry.DELETE)}); + + // Wire up a voter + BasicAclEntryVoter voter = new BasicAclEntryVoter(); + voter.setAclManager(aclManager); + voter.setProcessConfigAttribute("FOO_ADMIN_OR_WRITE_ACCESS"); + voter.setProcessDomainObjectClass(SomeDomainObject.class); + + try { + voter.afterPropertiesSet(); + fail("Should have thrown IllegalArgumentException"); + } catch (IllegalArgumentException expected) { + assertTrue(true); + } + } + + public void testSupportsConfigAttribute() { + BasicAclEntryVoter voter = new BasicAclEntryVoter(); + voter.setProcessConfigAttribute("foobar"); + assertTrue(voter.supports(new SecurityConfig("foobar"))); + } + + public void testVoterAbstainsIfDomainObjectIsNull() + throws Exception { + // Setup a domain object subject of this test + SomeDomainObject domainObject = new SomeDomainObject("foo"); + + // Setup an AclManager + AclManager aclManager = new MockAclManager(domainObject, "marissa", + new AclEntry[] {new MockAclEntry(), new SimpleAclEntry( + "marissa", new MockAclObjectIdentity(), null, + SimpleAclEntry.ADMINISTRATION), new SimpleAclEntry( + "marissa", new MockAclObjectIdentity(), null, + SimpleAclEntry.READ), new SimpleAclEntry("marissa", + new MockAclObjectIdentity(), null, SimpleAclEntry.DELETE)}); + + // Wire up a voter + BasicAclEntryVoter voter = new BasicAclEntryVoter(); + voter.setAclManager(aclManager); + voter.setProcessConfigAttribute("FOO_ADMIN_OR_WRITE_ACCESS"); + voter.setRequirePermission(new int[] {SimpleAclEntry.ADMINISTRATION, SimpleAclEntry.WRITE}); + voter.setProcessDomainObjectClass(SomeDomainObject.class); + voter.afterPropertiesSet(); + + // Wire up an invocation to be voted on + ConfigAttributeDefinition attr = new ConfigAttributeDefinition(); + attr.addConfigAttribute(new SecurityConfig("A_DIFFERENT_ATTRIBUTE")); + + // Setup a MockMethodInvocation, so voter can retrieve domainObject + MethodInvocation mi = getMethodInvocation(domainObject); + + assertEquals(AccessDecisionVoter.ACCESS_ABSTAIN, + voter.vote( + new UsernamePasswordAuthenticationToken("marissa", null), mi, + attr)); + } + + public void testVoterAbstainsIfNotMatchingConfigAttribute() + throws Exception { + // Setup a domain object subject of this test + SomeDomainObject domainObject = null; + + // Setup an AclManager + AclManager aclManager = new MockAclManager(domainObject, "marissa", + new AclEntry[] {new MockAclEntry(), new SimpleAclEntry( + "marissa", new MockAclObjectIdentity(), null, + SimpleAclEntry.ADMINISTRATION), new SimpleAclEntry( + "marissa", new MockAclObjectIdentity(), null, + SimpleAclEntry.READ), new SimpleAclEntry("marissa", + new MockAclObjectIdentity(), null, SimpleAclEntry.DELETE)}); + + // Wire up a voter + BasicAclEntryVoter voter = new BasicAclEntryVoter(); + voter.setAclManager(aclManager); + voter.setProcessConfigAttribute("FOO_ADMIN_OR_WRITE_ACCESS"); + voter.setRequirePermission(new int[] {SimpleAclEntry.ADMINISTRATION, SimpleAclEntry.WRITE}); + voter.setProcessDomainObjectClass(SomeDomainObject.class); + voter.afterPropertiesSet(); + + // Wire up an invocation to be voted on + ConfigAttributeDefinition attr = new ConfigAttributeDefinition(); + attr.addConfigAttribute(new SecurityConfig("FOO_ADMIN_OR_WRITE_ACCESS")); + + // Setup a MockMethodInvocation, so voter can retrieve domainObject + MethodInvocation mi = getMethodInvocation(domainObject); + + assertEquals(AccessDecisionVoter.ACCESS_ABSTAIN, + voter.vote( + new UsernamePasswordAuthenticationToken("marissa", null), mi, + attr)); + } + + public void testVoterCanDenyAccessBasedOnInternalMethodOfDomainObject() + throws Exception { + // Setup a domain object subject of this test + SomeDomainObject domainObject = new SomeDomainObject("foo"); + + // Setup an AclManager + AclManager aclManager = new MockAclManager(domainObject.getParent(), + "marissa", + new AclEntry[] {new MockAclEntry(), new SimpleAclEntry( + "marissa", new MockAclObjectIdentity(), null, + SimpleAclEntry.DELETE)}); + + // Wire up a voter + BasicAclEntryVoter voter = new BasicAclEntryVoter(); + voter.setAclManager(aclManager); + voter.setProcessConfigAttribute("FOO_ADMIN_OR_WRITE_ACCESS"); + voter.setRequirePermission(new int[] {SimpleAclEntry.ADMINISTRATION, SimpleAclEntry.WRITE}); + voter.setProcessDomainObjectClass(SomeDomainObject.class); + voter.setInternalMethod("getParent"); + voter.afterPropertiesSet(); + + // Wire up an invocation to be voted on + ConfigAttributeDefinition attr = new ConfigAttributeDefinition(); + attr.addConfigAttribute(new SecurityConfig("FOO_ADMIN_OR_WRITE_ACCESS")); + + // Setup a MockMethodInvocation, so voter can retrieve domainObject + MethodInvocation mi = getMethodInvocation(domainObject); + + assertEquals(AccessDecisionVoter.ACCESS_DENIED, + voter.vote( + new UsernamePasswordAuthenticationToken("marissa", null), mi, + attr)); + } + + public void testVoterCanDenyAccessIfPrincipalHasNoPermissionsAtAllToDomainObject() + throws Exception { + // Setup a domain object subject of this test + SomeDomainObject domainObject = new SomeDomainObject("foo"); + + // Setup an AclManager + AclManager aclManager = new MockAclManager(domainObject, "marissa", + new AclEntry[] {new MockAclEntry(), new SimpleAclEntry( + "marissa", new MockAclObjectIdentity(), null, + SimpleAclEntry.DELETE)}); + + // Wire up a voter + BasicAclEntryVoter voter = new BasicAclEntryVoter(); + voter.setAclManager(aclManager); + voter.setProcessConfigAttribute("FOO_ADMIN_OR_WRITE_ACCESS"); + voter.setRequirePermission(new int[] {SimpleAclEntry.ADMINISTRATION, SimpleAclEntry.WRITE}); + voter.setProcessDomainObjectClass(SomeDomainObject.class); + voter.setInternalMethod("getParent"); + voter.afterPropertiesSet(); + + // Wire up an invocation to be voted on + ConfigAttributeDefinition attr = new ConfigAttributeDefinition(); + attr.addConfigAttribute(new SecurityConfig("FOO_ADMIN_OR_WRITE_ACCESS")); + + // Setup a MockMethodInvocation, so voter can retrieve domainObject + MethodInvocation mi = getMethodInvocation(domainObject); + + // NB: scott is the principal, not marissa + assertEquals(AccessDecisionVoter.ACCESS_DENIED, + voter.vote(new UsernamePasswordAuthenticationToken("scott", null), + mi, attr)); + } + + public void testVoterCanGrantAccessBasedOnInternalMethodOfDomainObject() + throws Exception { + // Setup a domain object subject of this test + SomeDomainObject domainObject = new SomeDomainObject("foo"); + + // Setup an AclManager + AclManager aclManager = new MockAclManager(domainObject.getParent(), + "marissa", + new AclEntry[] {new MockAclEntry(), new SimpleAclEntry( + "marissa", new MockAclObjectIdentity(), null, + SimpleAclEntry.ADMINISTRATION), new SimpleAclEntry( + "marissa", new MockAclObjectIdentity(), null, + SimpleAclEntry.READ), new SimpleAclEntry("marissa", + new MockAclObjectIdentity(), null, SimpleAclEntry.DELETE)}); + + // Wire up a voter + BasicAclEntryVoter voter = new BasicAclEntryVoter(); + voter.setAclManager(aclManager); + voter.setProcessConfigAttribute("FOO_ADMIN_OR_WRITE_ACCESS"); + voter.setRequirePermission(new int[] {SimpleAclEntry.ADMINISTRATION, SimpleAclEntry.WRITE}); + voter.setProcessDomainObjectClass(SomeDomainObject.class); + voter.setInternalMethod("getParent"); + assertEquals("getParent", voter.getInternalMethod()); + voter.afterPropertiesSet(); + + // Wire up an invocation to be voted on + ConfigAttributeDefinition attr = new ConfigAttributeDefinition(); + attr.addConfigAttribute(new SecurityConfig("FOO_ADMIN_OR_WRITE_ACCESS")); + + // Setup a MockMethodInvocation, so voter can retrieve domainObject + // (well actually it will access domainObject.getParent()) + MethodInvocation mi = getMethodInvocation(domainObject); + + assertEquals(AccessDecisionVoter.ACCESS_GRANTED, + voter.vote( + new UsernamePasswordAuthenticationToken("marissa", null), mi, + attr)); + } + + public void testVoterThrowsExceptionIfInvalidInternalMethodOfDomainObject() + throws Exception { + // Setup a domain object subject of this test + SomeDomainObject domainObject = new SomeDomainObject("foo"); + + // Setup an AclManager + AclManager aclManager = new MockAclManager(domainObject.getParent(), + "marissa", + new AclEntry[] {new MockAclEntry(), new SimpleAclEntry( + "marissa", new MockAclObjectIdentity(), null, + SimpleAclEntry.ADMINISTRATION), new SimpleAclEntry( + "marissa", new MockAclObjectIdentity(), null, + SimpleAclEntry.READ), new SimpleAclEntry("marissa", + new MockAclObjectIdentity(), null, SimpleAclEntry.DELETE)}); + + // Wire up a voter + BasicAclEntryVoter voter = new BasicAclEntryVoter(); + voter.setAclManager(aclManager); + voter.setProcessConfigAttribute("FOO_ADMIN_OR_WRITE_ACCESS"); + voter.setRequirePermission(new int[] {SimpleAclEntry.ADMINISTRATION, SimpleAclEntry.WRITE}); + voter.setProcessDomainObjectClass(SomeDomainObject.class); + voter.setInternalMethod("getNonExistentParentName"); + voter.afterPropertiesSet(); + + // Wire up an invocation to be voted on + ConfigAttributeDefinition attr = new ConfigAttributeDefinition(); + attr.addConfigAttribute(new SecurityConfig("FOO_ADMIN_OR_WRITE_ACCESS")); + + // Setup a MockMethodInvocation, so voter can retrieve domainObject + // (well actually it will access domainObject.getParent()) + MethodInvocation mi = getMethodInvocation(domainObject); + + try { + voter.vote(new UsernamePasswordAuthenticationToken("marissa", null), + mi, attr); + fail("Should have thrown AuthorizationServiceException"); + } catch (AuthorizationServiceException expected) { + assertTrue(true); + } + } + + public void testVoterThrowsExceptionIfProcessDomainObjectNotFound() + throws Exception { + // Setup a domain object subject of this test + SomeDomainObject domainObject = new SomeDomainObject("foo"); + + // Setup an AclManager + AclManager aclManager = new MockAclManager(domainObject.getParent(), + "marissa", + new AclEntry[] {new MockAclEntry(), new SimpleAclEntry( + "marissa", new MockAclObjectIdentity(), null, + SimpleAclEntry.ADMINISTRATION), new SimpleAclEntry( + "marissa", new MockAclObjectIdentity(), null, + SimpleAclEntry.READ), new SimpleAclEntry("marissa", + new MockAclObjectIdentity(), null, SimpleAclEntry.DELETE)}); + + // Wire up a voter + BasicAclEntryVoter voter = new BasicAclEntryVoter(); + voter.setAclManager(aclManager); + voter.setProcessConfigAttribute("FOO_ADMIN_OR_WRITE_ACCESS"); + voter.setRequirePermission(new int[] {SimpleAclEntry.ADMINISTRATION, SimpleAclEntry.WRITE}); + voter.setProcessDomainObjectClass(SomeDomainObject.class); + voter.afterPropertiesSet(); + + // Wire up an invocation to be voted on + ConfigAttributeDefinition attr = new ConfigAttributeDefinition(); + attr.addConfigAttribute(new SecurityConfig("FOO_ADMIN_OR_WRITE_ACCESS")); + + // Setup a MockMethodInvocation that doesn't provide SomeDomainObject arg + Class clazz = String.class; + Method method = clazz.getMethod("toString", new Class[] {}); + + MethodInvocation mi = new MockMethodInvocation(method, + new Object[] {domainObject}); + + try { + voter.vote(new UsernamePasswordAuthenticationToken("marissa", null), + mi, attr); + fail("Should have thrown AuthorizationServiceException"); + } catch (AuthorizationServiceException expected) { + assertTrue(true); + } + } + + private MethodInvocation getMethodInvocation(SomeDomainObject domainObject) + throws Exception { + Class clazz = SomeDomainObjectManager.class; + Method method = clazz.getMethod("someServiceMethod", + new Class[] {SomeDomainObject.class}); + + return new MockMethodInvocation(method, new Object[] {domainObject}); + } + + //~ Inner Classes ========================================================== + + private class MockAclEntry implements AclEntry { + // just so AclTag iterates some different types of AclEntrys + } +} diff --git a/core/src/test/java/org/acegisecurity/vote/SomeDomainObject.java b/core/src/test/java/org/acegisecurity/vote/SomeDomainObject.java new file mode 100644 index 0000000000..85582d90c3 --- /dev/null +++ b/core/src/test/java/org/acegisecurity/vote/SomeDomainObject.java @@ -0,0 +1,42 @@ +/* Copyright 2004 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. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package net.sf.acegisecurity.vote; + +/** + * Simple domain object, used by {@link BasicAclEntryVoterTests}. + * + * @author Ben Alex + * @version $Id$ + */ +public class SomeDomainObject { + //~ Instance fields ======================================================== + + private String identity; + + //~ Constructors =========================================================== + + public SomeDomainObject(String identity) { + this.identity = identity; + } + + private SomeDomainObject() {} + + //~ Methods ================================================================ + + public String getParent() { + return "parentOf" + identity; + } +} diff --git a/core/src/test/java/org/acegisecurity/vote/SomeDomainObjectManager.java b/core/src/test/java/org/acegisecurity/vote/SomeDomainObjectManager.java new file mode 100644 index 0000000000..127b0c6b33 --- /dev/null +++ b/core/src/test/java/org/acegisecurity/vote/SomeDomainObjectManager.java @@ -0,0 +1,29 @@ +/* Copyright 2004 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. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package net.sf.acegisecurity.vote; + +/** + * Used by {@link BasicAclEntryVoterTests} so it can create a + * MethodInvocation contining SomeDomainObject. + * + * @author Ben Alex + * @version $Id$ + */ +public class SomeDomainObjectManager { + //~ Methods ================================================================ + + public void someServiceMethod(SomeDomainObject someDomainObject) {} +} diff --git a/core/src/test/resources/org/acegisecurity/applicationContext.xml b/core/src/test/resources/org/acegisecurity/applicationContext.xml new file mode 100644 index 0000000000..86d1f55a75 --- /dev/null +++ b/core/src/test/resources/org/acegisecurity/applicationContext.xml @@ -0,0 +1,29 @@ + + + + + + + + + + + + + diff --git a/core/src/test/resources/org/acegisecurity/intercept/method/aopalliance/applicationContext.xml b/core/src/test/resources/org/acegisecurity/intercept/method/aopalliance/applicationContext.xml index b68fd32a5e..53a270d936 100644 --- a/core/src/test/resources/org/acegisecurity/intercept/method/aopalliance/applicationContext.xml +++ b/core/src/test/resources/org/acegisecurity/intercept/method/aopalliance/applicationContext.xml @@ -20,6 +20,7 @@ + @@ -29,25 +30,27 @@ + net.sf.acegisecurity.ITargetObject.makeLower*=MOCK_LOWER net.sf.acegisecurity.ITargetObject.makeUpper*=MOCK_UPPER,RUN_AS + net.sf.acegisecurity.ITargetObject.computeHashCode*=MOCK_HASH,AFTER_INVOCATION_MOCK - + - - - - - - + + net.sf.acegisecurity.ITargetObject + + + + + + + diff --git a/core/src/test/resources/org/acegisecurity/intercept/method/applicationContext.xml b/core/src/test/resources/org/acegisecurity/intercept/method/applicationContext.xml new file mode 100644 index 0000000000..09d8a3eb1f --- /dev/null +++ b/core/src/test/resources/org/acegisecurity/intercept/method/applicationContext.xml @@ -0,0 +1,55 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + net.sf.acegisecurity.ITargetObject + + + + + + + + + + +