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 AclEntry
s 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
+
+
+
+
+
+
+
+
+
+
+