From fe379d97120cf386e8bebec9ea52a4a0bb17a655 Mon Sep 17 00:00:00 2001 From: Ben Alex Date: Sun, 28 Mar 2004 11:41:20 +0000 Subject: [PATCH] Initial commit. --- .../catalina/CatalinaAcegiUserRealmTests.java | 292 ++++++++++++ .../jboss/JbossAcegiLoginModuleTests.java | 378 ++++++++++++++++ .../jetty/JettyAcegiUserRealmTests.java | 245 ++++++++++ ant.bat | 2 + core/src/main/resources/log4j.properties | 11 + .../ConfigAttributeEditorTests.java | 137 ++++++ .../java/org/acegisecurity/ITargetObject.java | 34 ++ .../MethodDefinitionAttributesTests.java | 305 +++++++++++++ .../MethodDefinitionSourceEditorTests.java | 215 +++++++++ .../MockAccessDecisionManager.java | 62 +++ .../org/acegisecurity/MockAttributes.java | 155 +++++++ .../MockAuthenticationManager.java | 31 ++ .../MockRunAsAuthenticationToken.java | 54 +++ .../org/acegisecurity/MockRunAsManager.java | 58 +++ .../org/acegisecurity/OtherTargetObject.java | 56 +++ .../acegisecurity/SecurityConfigTests.java | 108 +++++ .../SecurityInterceptorTests.java | 420 ++++++++++++++++++ .../java/org/acegisecurity/TargetObject.java | 103 +++++ ...stractAdapterAuthenticationTokenTests.java | 163 +++++++ .../adapters/adaptertest-invalid.xml | 38 ++ .../adapters/adaptertest-valid.xml | 52 +++ .../context/ContextHolderTests.java | 76 ++++ .../context/ContextImplTests.java | 53 +++ .../context/ContextInterceptorTests.java | 106 +++++ .../acegisecurity/context/ITargetObject.java | 28 ++ .../context/SecureContextImplTests.java | 82 ++++ .../acegisecurity/context/TargetObject.java | 30 ++ .../AbstractAuthenticationTokenTests.java | 165 +++++++ .../providers/ProviderManagerTests.java | 171 +++++++ .../TestingAuthenticationProviderTests.java | 76 ++++ .../TestingAuthenticationTokenTests.java | 78 ++++ ...rnamePasswordAuthenticationTokenTests.java | 91 ++++ .../dao/DaoAuthenticationProviderTests.java | 266 +++++++++++ .../providers/dao/UserTests.java | 102 +++++ .../dao/memory/UserAttributeEditorTests.java | 135 ++++++ .../dao/memory/UserMapEditorTests.java | 103 +++++ .../providers/dao/memory/UserMapTests.java | 102 +++++ .../RunAsImplAuthenticationProviderTests.java | 113 +++++ .../runas/RunAsManagerImplTests.java | 128 ++++++ .../runas/RunAsUserTokenTests.java | 90 ++++ 40 files changed, 4914 insertions(+) create mode 100644 adapters/catalina/src/test/java/org/acegisecurity/adapters/catalina/CatalinaAcegiUserRealmTests.java create mode 100644 adapters/jboss/src/test/java/org/acegisecurity/adapters/jboss/JbossAcegiLoginModuleTests.java create mode 100644 adapters/jetty/src/test/java/org/acegisecurity/adapters/jetty/JettyAcegiUserRealmTests.java create mode 100644 ant.bat create mode 100644 core/src/main/resources/log4j.properties create mode 100644 core/src/test/java/org/acegisecurity/ConfigAttributeEditorTests.java create mode 100644 core/src/test/java/org/acegisecurity/ITargetObject.java create mode 100644 core/src/test/java/org/acegisecurity/MethodDefinitionAttributesTests.java create mode 100644 core/src/test/java/org/acegisecurity/MethodDefinitionSourceEditorTests.java create mode 100644 core/src/test/java/org/acegisecurity/MockAccessDecisionManager.java create mode 100644 core/src/test/java/org/acegisecurity/MockAttributes.java create mode 100644 core/src/test/java/org/acegisecurity/MockAuthenticationManager.java create mode 100644 core/src/test/java/org/acegisecurity/MockRunAsAuthenticationToken.java create mode 100644 core/src/test/java/org/acegisecurity/MockRunAsManager.java create mode 100644 core/src/test/java/org/acegisecurity/OtherTargetObject.java create mode 100644 core/src/test/java/org/acegisecurity/SecurityConfigTests.java create mode 100644 core/src/test/java/org/acegisecurity/SecurityInterceptorTests.java create mode 100644 core/src/test/java/org/acegisecurity/TargetObject.java create mode 100644 core/src/test/java/org/acegisecurity/adapters/AbstractAdapterAuthenticationTokenTests.java create mode 100644 core/src/test/java/org/acegisecurity/adapters/adaptertest-invalid.xml create mode 100644 core/src/test/java/org/acegisecurity/adapters/adaptertest-valid.xml create mode 100644 core/src/test/java/org/acegisecurity/context/ContextHolderTests.java create mode 100644 core/src/test/java/org/acegisecurity/context/ContextImplTests.java create mode 100644 core/src/test/java/org/acegisecurity/context/ContextInterceptorTests.java create mode 100644 core/src/test/java/org/acegisecurity/context/ITargetObject.java create mode 100644 core/src/test/java/org/acegisecurity/context/SecureContextImplTests.java create mode 100644 core/src/test/java/org/acegisecurity/context/TargetObject.java create mode 100644 core/src/test/java/org/acegisecurity/providers/AbstractAuthenticationTokenTests.java create mode 100644 core/src/test/java/org/acegisecurity/providers/ProviderManagerTests.java create mode 100644 core/src/test/java/org/acegisecurity/providers/TestingAuthenticationProviderTests.java create mode 100644 core/src/test/java/org/acegisecurity/providers/TestingAuthenticationTokenTests.java create mode 100644 core/src/test/java/org/acegisecurity/providers/UsernamePasswordAuthenticationTokenTests.java create mode 100644 core/src/test/java/org/acegisecurity/providers/dao/DaoAuthenticationProviderTests.java create mode 100644 core/src/test/java/org/acegisecurity/providers/dao/UserTests.java create mode 100644 core/src/test/java/org/acegisecurity/providers/dao/memory/UserAttributeEditorTests.java create mode 100644 core/src/test/java/org/acegisecurity/providers/dao/memory/UserMapEditorTests.java create mode 100644 core/src/test/java/org/acegisecurity/providers/dao/memory/UserMapTests.java create mode 100644 core/src/test/java/org/acegisecurity/runas/RunAsImplAuthenticationProviderTests.java create mode 100644 core/src/test/java/org/acegisecurity/runas/RunAsManagerImplTests.java create mode 100644 core/src/test/java/org/acegisecurity/runas/RunAsUserTokenTests.java diff --git a/adapters/catalina/src/test/java/org/acegisecurity/adapters/catalina/CatalinaAcegiUserRealmTests.java b/adapters/catalina/src/test/java/org/acegisecurity/adapters/catalina/CatalinaAcegiUserRealmTests.java new file mode 100644 index 0000000000..0876beff96 --- /dev/null +++ b/adapters/catalina/src/test/java/org/acegisecurity/adapters/catalina/CatalinaAcegiUserRealmTests.java @@ -0,0 +1,292 @@ +/* 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.adapters.catalina; + +import junit.framework.TestCase; + +import net.sf.acegisecurity.GrantedAuthority; +import net.sf.acegisecurity.GrantedAuthorityImpl; +import net.sf.acegisecurity.adapters.PrincipalAcegiUserToken; + +import org.apache.catalina.LifecycleException; + +import java.io.File; + +import java.net.URL; + +import java.security.Principal; + + +/** + * Tests {@link CatalinaAcegiUserRealm}. + * + * @author Ben Alex + * @version $Id$ + */ +public class CatalinaAcegiUserRealmTests extends TestCase { + //~ Instance fields ======================================================== + + private final String ADAPTER_KEY = "my_key"; + + //~ Constructors =========================================================== + + public CatalinaAcegiUserRealmTests() { + super(); + } + + public CatalinaAcegiUserRealmTests(String arg0) { + super(arg0); + } + + //~ Methods ================================================================ + + public final void setUp() throws Exception { + super.setUp(); + } + + public static void main(String[] args) { + junit.textui.TestRunner.run(CatalinaAcegiUserRealmTests.class); + } + + public void testAdapterAbortsIfAppContextDoesNotContainAnAuthenticationBean() + throws Exception { + try { + CatalinaAcegiUserRealm adapter = makeAdapter( + "adaptertest-invalid.xml"); + fail("Should have thrown IllegalArgumentException"); + } catch (IllegalArgumentException expected) { + assertTrue(true); + } + } + + public void testAdapterAbortsIfNoAppContextSpecified() + throws Exception { + CatalinaAcegiUserRealm adapter = new CatalinaAcegiUserRealm(); + + adapter.setKey("KEY"); + + try { + adapter.startForTest(); + fail("Should have thrown LifecycleException"); + } catch (LifecycleException expected) { + assertEquals("appContextLocation must be defined", + expected.getMessage()); + } + + adapter.setAppContextLocation(""); + + try { + adapter.startForTest(); + fail("Should have thrown LifecycleException"); + } catch (LifecycleException expected) { + assertEquals("appContextLocation must be defined", + expected.getMessage()); + } + } + + public void testAdapterAbortsIfNoKeySpecified() throws Exception { + CatalinaAcegiUserRealm adapter = new CatalinaAcegiUserRealm(); + + adapter.setAppContextLocation("SOMETHING"); + + try { + adapter.startForTest(); + fail("Should have thrown LifecycleException"); + } catch (LifecycleException expected) { + assertEquals("key must be defined", expected.getMessage()); + } + + adapter.setKey(""); + + try { + adapter.startForTest(); + fail("Should have thrown LifecycleException"); + } catch (LifecycleException expected) { + assertEquals("key must be defined", expected.getMessage()); + } + } + + public void testAdapterAbortsWithIncorrectApplicationContextLocation() + throws Exception { + CatalinaAcegiUserRealm adapter = new CatalinaAcegiUserRealm(); + adapter.setAppContextLocation("SOME_INVALID_PATH"); + adapter.setKey("KEY"); + + try { + adapter.startForTest(); + fail("Should have thrown LifecycleException"); + } catch (LifecycleException expected) { + assertTrue(expected.getMessage().startsWith("appContextLocation does not seem to exist in")); + } + } + + public void testAdapterIdentifiesItself() throws Exception { + CatalinaAcegiUserRealm adapter = new CatalinaAcegiUserRealm(); + assertTrue(adapter.getName().lastIndexOf("CatalinaSpringUserRealm") != -1); + } + + public void testAdapterStartsUpSuccess() throws Exception { + CatalinaAcegiUserRealm adapter = makeAdapter("adaptertest-valid.xml"); + assertTrue(true); + } + + public void testAuthenticateManyParamsReturnsNull() { + CatalinaAcegiUserRealm adapter = new CatalinaAcegiUserRealm(); + assertEquals(null, + adapter.authenticate(null, null, null, null, null, null, null, null)); + } + + public void testAuthenticateX509ReturnsNull() { + CatalinaAcegiUserRealm adapter = new CatalinaAcegiUserRealm(); + assertEquals(null, adapter.authenticate(null)); + } + + public void testAuthenticationFailsForIncorrectPassword() + throws Exception { + CatalinaAcegiUserRealm adapter = makeAdapter("adaptertest-valid.xml"); + assertEquals(null, adapter.authenticate("marissa", "kangaroo")); + } + + public void testAuthenticationFailsForIncorrectUserName() + throws Exception { + CatalinaAcegiUserRealm adapter = makeAdapter("adaptertest-valid.xml"); + assertEquals(null, adapter.authenticate("melissa", "koala")); + } + + public void testAuthenticationUsingByteArrayForCredentials() + throws Exception { + CatalinaAcegiUserRealm adapter = makeAdapter("adaptertest-valid.xml"); + byte[] credentials = {'k', 'o', 'a', 'l', 'a'}; + Principal result = adapter.authenticate("marissa", credentials); + + if (!(result instanceof PrincipalAcegiUserToken)) { + fail("Should have returned PrincipalAcegiUserToken"); + } + + PrincipalAcegiUserToken castResult = (PrincipalAcegiUserToken) result; + assertEquals("marissa", castResult.getPrincipal()); + assertEquals("koala", castResult.getCredentials()); + assertEquals("ROLE_TELLER", + castResult.getAuthorities()[0].getAuthority()); + assertEquals("ROLE_SUPERVISOR", + castResult.getAuthorities()[1].getAuthority()); + assertEquals(ADAPTER_KEY.hashCode(), castResult.getKeyHash()); + } + + public void testAuthenticationUsingStringForCredentials() + throws Exception { + CatalinaAcegiUserRealm adapter = makeAdapter("adaptertest-valid.xml"); + Principal result = adapter.authenticate("marissa", "koala"); + + if (!(result instanceof PrincipalAcegiUserToken)) { + fail("Should have returned PrincipalAcegiUserToken"); + } + + PrincipalAcegiUserToken castResult = (PrincipalAcegiUserToken) result; + assertEquals("marissa", castResult.getPrincipal()); + assertEquals("koala", castResult.getCredentials()); + assertEquals("ROLE_TELLER", + castResult.getAuthorities()[0].getAuthority()); + assertEquals("ROLE_SUPERVISOR", + castResult.getAuthorities()[1].getAuthority()); + assertEquals(ADAPTER_KEY.hashCode(), castResult.getKeyHash()); + } + + public void testAuthenticationWithNullPasswordHandledGracefully() + throws Exception { + CatalinaAcegiUserRealm adapter = makeAdapter("adaptertest-valid.xml"); + assertEquals(null, adapter.authenticate("marissa", (String) null)); + } + + public void testAuthenticationWithNullUserNameHandledGracefully() + throws Exception { + CatalinaAcegiUserRealm adapter = makeAdapter("adaptertest-valid.xml"); + assertEquals(null, adapter.authenticate(null, "koala")); + } + + public void testGetPasswordReturnsNull() { + CatalinaAcegiUserRealm adapter = new CatalinaAcegiUserRealm(); + assertEquals(null, adapter.getPassword(null)); + } + + public void testGetPrincipalReturnsNull() { + CatalinaAcegiUserRealm adapter = new CatalinaAcegiUserRealm(); + assertEquals(null, adapter.getPrincipal(null)); + } + + public void testGetters() { + CatalinaAcegiUserRealm adapter = new CatalinaAcegiUserRealm(); + adapter.setKey("KEY"); + assertEquals("KEY", adapter.getKey()); + adapter.setAppContextLocation("SOME_LOCATION"); + assertEquals("SOME_LOCATION", adapter.getAppContextLocation()); + } + + public void testHasRoleWithANullPrincipalFails() { + CatalinaAcegiUserRealm adapter = new CatalinaAcegiUserRealm(); + assertTrue(!adapter.hasRole(null, "ROLE_ONE")); + } + + public void testHasRoleWithAPrincipalTheAdapterDidNotCreateFails() { + CatalinaAcegiUserRealm adapter = new CatalinaAcegiUserRealm(); + assertTrue(!adapter.hasRole(new MockPrincipal(), "ROLE_ONE")); + } + + public void testHasRoleWithPrincipalAcegiUserToken() { + PrincipalAcegiUserToken token = new PrincipalAcegiUserToken("KEY", + "Test", "Password", + new GrantedAuthority[] {new GrantedAuthorityImpl("ROLE_ONE"), new GrantedAuthorityImpl( + "ROLE_TWO")}); + CatalinaAcegiUserRealm adapter = new CatalinaAcegiUserRealm(); + assertTrue(adapter.hasRole(token, "ROLE_ONE")); + assertTrue(adapter.hasRole(token, "ROLE_TWO")); + assertTrue(!adapter.hasRole(token, "ROLE_WE_DO_NOT_HAVE")); + } + + private CatalinaAcegiUserRealm makeAdapter(String fileName) + throws Exception { + CatalinaAcegiUserRealm adapter = new CatalinaAcegiUserRealm(); + + URL url = ClassLoader.getSystemResource( + "net/sf/acegisecurity/adapters/" + fileName); + + if (url == null) { + throw new Exception("Could not find " + fileName + + " - cannot continue"); + } + + File file = new File(url.getFile()); + + System.setProperty("catalina.base", + file.getParentFile().getAbsolutePath()); + System.out.println("catalina.base set to: " + + System.getProperty("catalina.base")); + adapter.setAppContextLocation(fileName); + adapter.setKey(ADAPTER_KEY); + adapter.startForTest(); + + return adapter; + } + + //~ Inner Classes ========================================================== + + private class MockPrincipal implements Principal { + public String getName() { + throw new UnsupportedOperationException( + "mock method not implemented"); + } + } +} diff --git a/adapters/jboss/src/test/java/org/acegisecurity/adapters/jboss/JbossAcegiLoginModuleTests.java b/adapters/jboss/src/test/java/org/acegisecurity/adapters/jboss/JbossAcegiLoginModuleTests.java new file mode 100644 index 0000000000..46a3fd4d51 --- /dev/null +++ b/adapters/jboss/src/test/java/org/acegisecurity/adapters/jboss/JbossAcegiLoginModuleTests.java @@ -0,0 +1,378 @@ +/* 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.adapters.jboss; + +import junit.framework.TestCase; + +import net.sf.acegisecurity.adapters.PrincipalAcegiUserToken; + +import org.jboss.security.SimplePrincipal; + +import java.io.IOException; + +import java.security.Principal; +import java.security.acl.Group; + +import java.util.Properties; + +import javax.security.auth.Subject; +import javax.security.auth.callback.Callback; +import javax.security.auth.callback.CallbackHandler; +import javax.security.auth.callback.NameCallback; +import javax.security.auth.callback.PasswordCallback; +import javax.security.auth.callback.UnsupportedCallbackException; +import javax.security.auth.login.FailedLoginException; +import javax.security.auth.login.LoginException; + + +/** + * Tests {@link JbossAcegiLoginModule}. + * + * @author Ben Alex + * @version $Id$ + */ +public class JbossAcegiLoginModuleTests extends TestCase { + //~ Instance fields ======================================================== + + private final String ADAPTER_KEY = "my_key"; + + //~ Constructors =========================================================== + + public JbossAcegiLoginModuleTests() { + super(); + } + + public JbossAcegiLoginModuleTests(String arg0) { + super(arg0); + } + + //~ Methods ================================================================ + + public final void setUp() throws Exception { + super.setUp(); + } + + public static void main(String[] args) { + junit.textui.TestRunner.run(JbossAcegiLoginModuleTests.class); + } + + public void testAdapterAbortsIfAppContextDoesNotContainAnAuthenticationBean() + throws Exception { + JbossAcegiLoginModule adapter = new JbossAcegiLoginModule(); + Properties props = new Properties(); + props.put("key", ADAPTER_KEY); + props.put("appContextLocation", + "net/sf/acegisecurity/adapters/adaptertest-invalid.xml"); + + try { + adapter.initialize(null, null, null, props); + fail("Should have thrown IllegalArgumentException"); + } catch (IllegalArgumentException expected) { + assertTrue(true); + } + } + + public void testAdapterAbortsIfNoAppContextSpecified() + throws Exception { + JbossAcegiLoginModule adapter = new JbossAcegiLoginModule(); + + Properties props = new Properties(); + props.put("key", ADAPTER_KEY); + + try { + adapter.initialize(null, null, null, props); + fail("Should have thrown IllegalArgumentException"); + } catch (IllegalArgumentException expected) { + assertEquals("appContextLocation must be defined", + expected.getMessage()); + } + + props = new Properties(); + props.put("key", ADAPTER_KEY); + props.put("appContextLocation", ""); + + try { + adapter.initialize(null, null, null, props); + fail("Should have thrown IllegalArgumentException"); + } catch (IllegalArgumentException expected) { + assertEquals("appContextLocation must be defined", + expected.getMessage()); + } + } + + public void testAdapterAbortsIfNoKeySpecified() throws Exception { + JbossAcegiLoginModule adapter = new JbossAcegiLoginModule(); + + Properties props = new Properties(); + props.put("appContextLocation", + "net/sf/acegisecurity/adapters/adaptertest-valid.xml"); + + try { + adapter.initialize(null, null, null, props); + fail("Should have thrown IllegalArgumentException"); + } catch (IllegalArgumentException expected) { + assertEquals("key must be defined", expected.getMessage()); + } + + props = new Properties(); + props.put("key", ""); + props.put("appContextLocation", + "net/sf/acegisecurity/adapters/adaptertest-valid.xml"); + + try { + adapter.initialize(null, null, null, props); + fail("Should have thrown IllegalArgumentException"); + } catch (IllegalArgumentException expected) { + assertEquals("key must be defined", expected.getMessage()); + } + } + + public void testAdapterAbortsWithIncorrectApplicationContextLocation() + throws Exception { + JbossAcegiLoginModule adapter = new JbossAcegiLoginModule(); + + Properties props = new Properties(); + props.put("key", ADAPTER_KEY); + props.put("appContextLocation", "INVALID_PATH"); + + try { + adapter.initialize(null, null, null, props); + fail("Should have thrown IllegalArgumentException"); + } catch (IllegalArgumentException expected) { + assertTrue("Cannot locate INVALID_PATH".equals( + expected.getMessage())); + } + } + + public void testAdapterFailsToAuthenticateIfNoCallbackHandlerAvailable() + throws Exception { + JbossAcegiLoginModule adapter = new JbossAcegiLoginModule(); + Properties props = new Properties(); + props.put("key", ADAPTER_KEY); + props.put("appContextLocation", + "net/sf/acegisecurity/adapters/adaptertest-valid.xml"); + + Subject subject = new Subject(); + + adapter.initialize(subject, null, null, props); + + try { + adapter.login(); + } catch (LoginException loginException) { + assertEquals("Error: no CallbackHandler available to collect authentication information", + loginException.getMessage()); + } + } + + public void testAdapterStartsUpSuccess() throws Exception { + JbossAcegiLoginModule adapter = new JbossAcegiLoginModule(); + Properties props = new Properties(); + props.put("key", ADAPTER_KEY); + props.put("appContextLocation", + "net/sf/acegisecurity/adapters/adaptertest-valid.xml"); + adapter.initialize(null, null, null, props); + assertTrue(true); + } + + public void testAuthenticationFailsForIncorrectPassword() + throws Exception { + JbossAcegiLoginModule adapter = new JbossAcegiLoginModule(); + Properties props = new Properties(); + props.put("key", ADAPTER_KEY); + props.put("appContextLocation", + "net/sf/acegisecurity/adapters/adaptertest-valid.xml"); + + Subject subject = new Subject(); + CallbackHandler callback = new MockCallbackHandler("marissa", "kangaroo"); + + adapter.initialize(subject, callback, null, props); + + try { + adapter.login(); + fail("Should have thrown FailedLoginException"); + } catch (FailedLoginException expected) { + assertTrue(true); + } + } + + public void testAuthenticationFailsForIncorrectUserName() + throws Exception { + JbossAcegiLoginModule adapter = new JbossAcegiLoginModule(); + Properties props = new Properties(); + props.put("key", ADAPTER_KEY); + props.put("appContextLocation", + "net/sf/acegisecurity/adapters/adaptertest-valid.xml"); + + Subject subject = new Subject(); + CallbackHandler callback = new MockCallbackHandler("melissa", "koala"); + + adapter.initialize(subject, callback, null, props); + + try { + adapter.login(); + fail("Should have thrown FailedLoginException"); + } catch (FailedLoginException expected) { + assertTrue(true); + } + } + + public void testAuthenticationSuccess() throws Exception { + JbossAcegiLoginModule adapter = new JbossAcegiLoginModule(); + Properties props = new Properties(); + props.put("key", ADAPTER_KEY); + props.put("appContextLocation", + "net/sf/acegisecurity/adapters/adaptertest-valid.xml"); + + Subject subject = new Subject(); + CallbackHandler callback = new MockCallbackHandler("marissa", "koala"); + + adapter.initialize(subject, callback, null, props); + assertTrue(adapter.login()); + + Principal result = adapter.getIdentity(); + + if (!(result instanceof PrincipalAcegiUserToken)) { + fail("Should have returned PrincipalAcegiUserToken"); + } + + PrincipalAcegiUserToken castResult = (PrincipalAcegiUserToken) result; + assertEquals("marissa", castResult.getPrincipal()); + assertEquals("koala", castResult.getCredentials()); + assertEquals("ROLE_TELLER", + castResult.getAuthorities()[0].getAuthority()); + assertEquals("ROLE_SUPERVISOR", + castResult.getAuthorities()[1].getAuthority()); + assertEquals(ADAPTER_KEY.hashCode(), castResult.getKeyHash()); + } + + public void testAuthenticationWithNullPasswordHandledGracefully() + throws Exception { + JbossAcegiLoginModule adapter = new JbossAcegiLoginModule(); + Properties props = new Properties(); + props.put("key", ADAPTER_KEY); + props.put("appContextLocation", + "net/sf/acegisecurity/adapters/adaptertest-valid.xml"); + + Subject subject = new Subject(); + CallbackHandler callback = new MockCallbackHandler("marissa", null); + + adapter.initialize(subject, callback, null, props); + + try { + adapter.login(); + fail("Should have thrown FailedLoginException"); + } catch (FailedLoginException expected) { + assertTrue(true); + } + } + + public void testAuthenticationWithNullUserNameAndNullPasswordHandledGracefully() + throws Exception { + JbossAcegiLoginModule adapter = new JbossAcegiLoginModule(); + Properties props = new Properties(); + props.put("key", ADAPTER_KEY); + props.put("appContextLocation", + "net/sf/acegisecurity/adapters/adaptertest-valid.xml"); + + Subject subject = new Subject(); + CallbackHandler callback = new MockCallbackHandler(null, null); + + adapter.initialize(subject, callback, null, props); + + try { + adapter.login(); + fail("Should have thrown FailedLoginException"); + } catch (FailedLoginException expected) { + assertTrue(true); + } + } + + public void testAuthenticationWithNullUserNameHandledGracefully() + throws Exception { + JbossAcegiLoginModule adapter = new JbossAcegiLoginModule(); + Properties props = new Properties(); + props.put("key", ADAPTER_KEY); + props.put("appContextLocation", + "net/sf/acegisecurity/adapters/adaptertest-valid.xml"); + + Subject subject = new Subject(); + CallbackHandler callback = new MockCallbackHandler(null, "kangaroo"); + + adapter.initialize(subject, callback, null, props); + + try { + adapter.login(); + fail("Should have thrown FailedLoginException"); + } catch (FailedLoginException expected) { + assertTrue(true); + } + } + + public void testGetRoleSets() throws Exception { + JbossAcegiLoginModule adapter = new JbossAcegiLoginModule(); + Properties props = new Properties(); + props.put("key", ADAPTER_KEY); + props.put("appContextLocation", + "net/sf/acegisecurity/adapters/adaptertest-valid.xml"); + + Subject subject = new Subject(); + CallbackHandler callback = new MockCallbackHandler("marissa", "koala"); + + adapter.initialize(subject, callback, null, props); + assertTrue(adapter.login()); + + Group[] result = adapter.getRoleSets(); + assertEquals(1, result.length); // SimpleGroup called "Roles" + + Group roles = result[0]; + assertTrue(roles.isMember(new SimplePrincipal("ROLE_TELLER"))); + assertTrue(roles.isMember(new SimplePrincipal("ROLE_SUPERVISOR"))); + } + + //~ Inner Classes ========================================================== + + private class MockCallbackHandler implements CallbackHandler { + private String password; + private String username; + + public MockCallbackHandler(String username, String password) { + this.username = username; + this.password = password; + } + + private MockCallbackHandler() { + super(); + } + + public void handle(Callback[] callbacks) + throws IOException, UnsupportedCallbackException { + for (int i = 0; i < callbacks.length; i++) { + if (callbacks[i] instanceof NameCallback) { + ((NameCallback) callbacks[i]).setName(username); + } else if (callbacks[i] instanceof PasswordCallback) { + if (this.password == null) { + ((PasswordCallback) callbacks[i]).setPassword(null); + } else { + ((PasswordCallback) callbacks[i]).setPassword(password + .toCharArray()); + } + } else { + throw new UnsupportedCallbackException(callbacks[i]); + } + } + } + } +} diff --git a/adapters/jetty/src/test/java/org/acegisecurity/adapters/jetty/JettyAcegiUserRealmTests.java b/adapters/jetty/src/test/java/org/acegisecurity/adapters/jetty/JettyAcegiUserRealmTests.java new file mode 100644 index 0000000000..16e89b354f --- /dev/null +++ b/adapters/jetty/src/test/java/org/acegisecurity/adapters/jetty/JettyAcegiUserRealmTests.java @@ -0,0 +1,245 @@ +/* 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.adapters.jetty; + +import junit.framework.TestCase; + +import org.mortbay.http.UserPrincipal; + + +/** + * Tests {@link JettyAcegiUserRealm}. + * + * @author Ben Alex + * @version $Id$ + */ +public class JettyAcegiUserRealmTests extends TestCase { + //~ Instance fields ======================================================== + + private final String ADAPTER_KEY = "my_key"; + private final String REALM_NAME = "Acegi Powered Realm"; + + //~ Constructors =========================================================== + + public JettyAcegiUserRealmTests() { + super(); + } + + public JettyAcegiUserRealmTests(String arg0) { + super(arg0); + } + + //~ Methods ================================================================ + + public final void setUp() throws Exception { + super.setUp(); + } + + public static void main(String[] args) { + junit.textui.TestRunner.run(JettyAcegiUserRealmTests.class); + } + + public void testAdapterAbortsIfAppContextDoesNotContainAnAuthenticationBean() + throws Exception { + try { + JettyAcegiUserRealm adapter = makeAdapter("adaptertest-invalid.xml"); + fail("Should have thrown IllegalArgumentException"); + } catch (IllegalArgumentException expected) { + assertEquals("Bean context must contain at least one bean of type AuthenticationManager", + expected.getMessage()); + } + } + + public void testAdapterAbortsIfNoAppContextSpecified() + throws Exception { + try { + new JettyAcegiUserRealm(REALM_NAME, ADAPTER_KEY, null); + fail("Should have thrown IllegalArgumentException"); + } catch (IllegalArgumentException expected) { + assertEquals("appContextLocation must be specified", + expected.getMessage()); + } + + try { + new JettyAcegiUserRealm(REALM_NAME, ADAPTER_KEY, ""); + fail("Should have thrown IllegalArgumentException"); + } catch (IllegalArgumentException expected) { + assertEquals("appContextLocation must be specified", + expected.getMessage()); + } + } + + public void testAdapterAbortsIfNoKeySpecified() throws Exception { + try { + new JettyAcegiUserRealm(REALM_NAME, null, "SOME_PATH"); + fail("Should have thrown IllegalArgumentException"); + } catch (IllegalArgumentException expected) { + assertEquals("key must be specified", expected.getMessage()); + } + + try { + new JettyAcegiUserRealm(REALM_NAME, "", "SOME_PATH"); + fail("Should have thrown IllegalArgumentException"); + } catch (IllegalArgumentException expected) { + assertEquals("key must be specified", expected.getMessage()); + } + } + + public void testAdapterAbortsIfNoRealmNameSpecified() + throws Exception { + try { + new JettyAcegiUserRealm(null, ADAPTER_KEY, "SOME_PATH"); + fail("Should have thrown IllegalArgumentException"); + } catch (IllegalArgumentException expected) { + assertEquals("realm must be specified", expected.getMessage()); + } + + try { + new JettyAcegiUserRealm(null, ADAPTER_KEY, "SOME_PATH"); + fail("Should have thrown IllegalArgumentException"); + } catch (IllegalArgumentException expected) { + assertEquals("realm must be specified", expected.getMessage()); + } + } + + public void testAdapterAbortsWithIncorrectApplicationContextLocation() + throws Exception { + try { + new JettyAcegiUserRealm(REALM_NAME, ADAPTER_KEY, + "SOME_INVALID_LOCATION"); + fail("Should have thrown IllegalArgumentException"); + } catch (IllegalArgumentException expected) { + assertTrue(expected.getMessage().startsWith("Cannot locate")); + } + } + + public void testAdapterIdentifiesTheRealmItManages() + throws Exception { + JettyAcegiUserRealm adapter = makeAdapter("adaptertest-valid.xml"); + assertEquals(REALM_NAME, adapter.getName()); + } + + public void testAdapterStartsUpSuccess() throws Exception { + JettyAcegiUserRealm adapter = makeAdapter("adaptertest-valid.xml"); + assertTrue(true); + } + + public void testAuthenticationFailsForIncorrectPassword() + throws Exception { + JettyAcegiUserRealm adapter = makeAdapter("adaptertest-valid.xml"); + assertEquals(null, adapter.authenticate("marissa", "kangaroo", null)); + } + + public void testAuthenticationFailsForIncorrectUserName() + throws Exception { + JettyAcegiUserRealm adapter = makeAdapter("adaptertest-valid.xml"); + assertEquals(null, adapter.authenticate("melissa", "koala", null)); + } + + public void testAuthenticationSuccess() throws Exception { + JettyAcegiUserRealm adapter = makeAdapter("adaptertest-valid.xml"); + UserPrincipal result = adapter.authenticate("marissa", "koala", null); + + if (!(result instanceof JettyAcegiUserToken)) { + fail("Should have returned JettyAcegiUserToken"); + } + + JettyAcegiUserToken castResult = (JettyAcegiUserToken) result; + assertEquals("marissa", castResult.getPrincipal()); + assertEquals("koala", castResult.getCredentials()); + assertEquals("ROLE_TELLER", + castResult.getAuthorities()[0].getAuthority()); + assertEquals("ROLE_SUPERVISOR", + castResult.getAuthorities()[1].getAuthority()); + assertEquals(ADAPTER_KEY.hashCode(), castResult.getKeyHash()); + } + + public void testAuthenticationWithNullPasswordHandledGracefully() + throws Exception { + JettyAcegiUserRealm adapter = makeAdapter("adaptertest-valid.xml"); + assertEquals(null, adapter.authenticate("marissa", null, null)); + } + + public void testAuthenticationWithNullUserNameHandledGracefully() + throws Exception { + JettyAcegiUserRealm adapter = makeAdapter("adaptertest-valid.xml"); + assertEquals(null, adapter.authenticate(null, "koala", null)); + } + + public void testDisassociateImplemented() throws Exception { + JettyAcegiUserRealm adapter = makeAdapter("adaptertest-valid.xml"); + adapter.disassociate(new MockUserPrincipal()); + assertTrue(true); + } + + public void testGetAuthenticationManager() throws Exception { + JettyAcegiUserRealm adapter = makeAdapter("adaptertest-valid.xml"); + assertTrue(adapter.getAuthenticationManager() != null); + } + + public void testLogoutImplemented() throws Exception { + JettyAcegiUserRealm adapter = makeAdapter("adaptertest-valid.xml"); + adapter.logout(new MockUserPrincipal()); + assertTrue(true); + } + + public void testNoArgsConstructor() { + try { + new JettyAcegiUserRealm(); + fail("Should have thrown IllegalArgumentException"); + } catch (IllegalArgumentException expected) { + assertTrue(true); + } + } + + public void testPopRoleImplemented() throws Exception { + JettyAcegiUserRealm adapter = makeAdapter("adaptertest-valid.xml"); + MockUserPrincipal user = new MockUserPrincipal(); + assertEquals(user, adapter.popRole(user)); + } + + public void testPushRoleImplemented() throws Exception { + JettyAcegiUserRealm adapter = makeAdapter("adaptertest-valid.xml"); + MockUserPrincipal user = new MockUserPrincipal(); + assertEquals(user, adapter.pushRole(user, "SOME_ROLE")); + } + + private JettyAcegiUserRealm makeAdapter(String fileName) + throws Exception { + String useFile = "net/sf/acegisecurity/adapters/" + fileName; + + return new JettyAcegiUserRealm(REALM_NAME, ADAPTER_KEY, useFile); + } + + //~ Inner Classes ========================================================== + + private class MockUserPrincipal implements UserPrincipal { + public boolean isAuthenticated() { + throw new UnsupportedOperationException( + "mock method not implemented"); + } + + public String getName() { + throw new UnsupportedOperationException( + "mock method not implemented"); + } + + public boolean isUserInRole(String arg0) { + throw new UnsupportedOperationException( + "mock method not implemented"); + } + } +} diff --git a/ant.bat b/ant.bat new file mode 100644 index 0000000000..4bcbeeb144 --- /dev/null +++ b/ant.bat @@ -0,0 +1,2 @@ +%JAVA_HOME%/bin/java -cp lib/ant/ant.jar;lib/ant/ant-launcher.jar;lib/ant/ant-junit.jar;lib/junit/junit.jar;lib/clover/clover.jar;%JAVA_HOME%/lib/tools.jar org.apache.tools.ant.Main %1 %2 %3 %4 %5 %6 %7 %8 + diff --git a/core/src/main/resources/log4j.properties b/core/src/main/resources/log4j.properties new file mode 100644 index 0000000000..6f21872912 --- /dev/null +++ b/core/src/main/resources/log4j.properties @@ -0,0 +1,11 @@ +# Logging +# +# $Id$ + +log4j.rootCategory=WARN, stdout + +log4j.appender.stdout=org.apache.log4j.ConsoleAppender +log4j.appender.stdout.layout=org.apache.log4j.PatternLayout +log4j.appender.stdout.layout.ConversionPattern=%d %p %c - %m%n + +log4j.category.net.sf.acegisecurity=DEBUG diff --git a/core/src/test/java/org/acegisecurity/ConfigAttributeEditorTests.java b/core/src/test/java/org/acegisecurity/ConfigAttributeEditorTests.java new file mode 100644 index 0000000000..5f3c89a492 --- /dev/null +++ b/core/src/test/java/org/acegisecurity/ConfigAttributeEditorTests.java @@ -0,0 +1,137 @@ +/* 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 junit.framework.TestCase; + +import java.util.Iterator; + + +/** + * Tests {@link ConfigAttributeEditor} and associated {@link + * ConfigAttributeDefinition}. + * + * @author Ben Alex + * @version $Id$ + */ +public class ConfigAttributeEditorTests extends TestCase { + //~ Constructors =========================================================== + + public ConfigAttributeEditorTests() { + super(); + } + + public ConfigAttributeEditorTests(String arg0) { + super(arg0); + } + + //~ Methods ================================================================ + + public final void setUp() throws Exception { + super.setUp(); + } + + public static void main(String[] args) { + junit.textui.TestRunner.run(ConfigAttributeEditorTests.class); + } + + public void testCorrectOperation() { + ConfigAttributeEditor editor = new ConfigAttributeEditor(); + editor.setAsText("HELLO,DOCTOR,NAME,YESTERDAY,TOMORROW"); + + ConfigAttributeDefinition result = (ConfigAttributeDefinition) editor + .getValue(); + Iterator iter = result.getConfigAttributes(); + int position = 0; + + while (iter.hasNext()) { + position++; + iter.next(); + } + + assertEquals(5, position); + } + + public void testEmptyStringReturnsNull() { + ConfigAttributeEditor editor = new ConfigAttributeEditor(); + editor.setAsText(""); + + ConfigAttributeDefinition result = (ConfigAttributeDefinition) editor + .getValue(); + assertTrue(result == null); + } + + public void testEqualsHandlingWhenDifferentObjectTypes() { + ConfigAttributeDefinition def1 = new ConfigAttributeDefinition(); + def1.addConfigAttribute(new SecurityConfig("A")); + def1.addConfigAttribute(new SecurityConfig("B")); + + assertTrue(!def1.equals("A_STRING")); + } + + public void testEqualsHandlingWhenExactlyEqual() { + ConfigAttributeDefinition def1 = new ConfigAttributeDefinition(); + def1.addConfigAttribute(new SecurityConfig("A")); + def1.addConfigAttribute(new SecurityConfig("B")); + + ConfigAttributeDefinition def2 = new ConfigAttributeDefinition(); + def2.addConfigAttribute(new SecurityConfig("A")); + def2.addConfigAttribute(new SecurityConfig("B")); + + assertEquals(def1, def2); + } + + public void testEqualsHandlingWhenOrderingNotEqual() { + ConfigAttributeDefinition def1 = new ConfigAttributeDefinition(); + def1.addConfigAttribute(new SecurityConfig("A")); + def1.addConfigAttribute(new SecurityConfig("B")); + + ConfigAttributeDefinition def2 = new ConfigAttributeDefinition(); + def2.addConfigAttribute(new SecurityConfig("B")); + def2.addConfigAttribute(new SecurityConfig("A")); + + assertTrue(!def1.equals(def2)); + } + + public void testEqualsHandlingWhenTestObjectHasNoAttributes() { + ConfigAttributeDefinition def1 = new ConfigAttributeDefinition(); + def1.addConfigAttribute(new SecurityConfig("A")); + def1.addConfigAttribute(new SecurityConfig("B")); + + ConfigAttributeDefinition def2 = new ConfigAttributeDefinition(); + + assertTrue(!def1.equals(def2)); + assertTrue(!def2.equals(def1)); + } + + public void testNullReturnsNull() { + ConfigAttributeEditor editor = new ConfigAttributeEditor(); + editor.setAsText(null); + + ConfigAttributeDefinition result = (ConfigAttributeDefinition) editor + .getValue(); + assertTrue(result == null); + } + + public void testToString() { + ConfigAttributeEditor editor = new ConfigAttributeEditor(); + editor.setAsText("KOALA,KANGAROO,EMU,WOMBAT"); + + ConfigAttributeDefinition result = (ConfigAttributeDefinition) editor + .getValue(); + assertEquals("[KOALA, KANGAROO, EMU, WOMBAT]", result.toString()); + } +} diff --git a/core/src/test/java/org/acegisecurity/ITargetObject.java b/core/src/test/java/org/acegisecurity/ITargetObject.java new file mode 100644 index 0000000000..a58ff0b71c --- /dev/null +++ b/core/src/test/java/org/acegisecurity/ITargetObject.java @@ -0,0 +1,34 @@ +/* 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; + +/** + * Represents the interface of a secured object. + * + * @author Ben Alex + * @version $Id$ + */ +public interface ITargetObject { + //~ Methods ================================================================ + + public int countLength(String input); + + public String makeLowerCase(String input); + + public String makeUpperCase(String input); + + public String publicMakeLowerCase(String input); +} diff --git a/core/src/test/java/org/acegisecurity/MethodDefinitionAttributesTests.java b/core/src/test/java/org/acegisecurity/MethodDefinitionAttributesTests.java new file mode 100644 index 0000000000..0e8efdef43 --- /dev/null +++ b/core/src/test/java/org/acegisecurity/MethodDefinitionAttributesTests.java @@ -0,0 +1,305 @@ +/* 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 junit.framework.TestCase; + +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 org.springframework.beans.factory.support.DefaultListableBeanFactory; +import org.springframework.beans.factory.support.PropertiesBeanDefinitionReader; + +import org.springframework.context.support.ClassPathXmlApplicationContext; + +import java.lang.reflect.AccessibleObject; +import java.lang.reflect.Method; + +import java.util.HashSet; +import java.util.Iterator; +import java.util.Properties; +import java.util.Set; + + +/** + * Tests {@link MethodDefinitionAttributes}. + * + * @author Cameron Braid + * @author Ben Alex + */ +public class MethodDefinitionAttributesTests extends TestCase { + //~ Instance fields ======================================================== + + ClassPathXmlApplicationContext applicationContext; + + //~ Constructors =========================================================== + + public MethodDefinitionAttributesTests(String a) { + super(a); + } + + //~ Methods ================================================================ + + public final void setUp() throws Exception { + super.setUp(); + } + + public static void main(String[] args) { + junit.textui.TestRunner.run(MethodDefinitionAttributesTests.class); + } + + public void testAttributesForInterfaceTargetObject() + throws Exception { + ConfigAttributeDefinition def1 = getConfigAttributeDefinition(ITargetObject.class, + "countLength", new Class[] {String.class}); + Set set1 = toSet(def1); + assertTrue(set1.contains(new SecurityConfig("MOCK_INTERFACE"))); + assertTrue(set1.contains( + new SecurityConfig("MOCK_INTERFACE_METHOD_COUNT_LENGTH"))); + + ConfigAttributeDefinition def2 = getConfigAttributeDefinition(ITargetObject.class, + "makeLowerCase", new Class[] {String.class}); + Set set2 = toSet(def2); + assertTrue(set2.contains(new SecurityConfig("MOCK_INTERFACE"))); + assertTrue(set2.contains( + new SecurityConfig("MOCK_INTERFACE_METHOD_MAKE_LOWER_CASE"))); + + ConfigAttributeDefinition def3 = getConfigAttributeDefinition(ITargetObject.class, + "makeUpperCase", new Class[] {String.class}); + Set set3 = toSet(def3); + assertTrue(set3.contains(new SecurityConfig("MOCK_INTERFACE"))); + assertTrue(set3.contains( + new SecurityConfig("MOCK_INTERFACE_METHOD_MAKE_UPPER_CASE"))); + } + + public void testAttributesForOtherTargetObject() throws Exception { + ConfigAttributeDefinition def1 = getConfigAttributeDefinition(OtherTargetObject.class, + "countLength", new Class[] {String.class}); + Set set1 = toSet(def1); + assertTrue(set1.contains(new SecurityConfig("MOCK_INTERFACE"))); + assertTrue(set1.contains( + new SecurityConfig("MOCK_INTERFACE_METHOD_COUNT_LENGTH"))); + + // Confirm MOCK_CLASS_METHOD_COUNT_LENGTH not added, as it's a String (not a ConfigAttribute) + // Confirm also MOCK_CLASS not added, as we return null for class + assertEquals(2, set1.size()); + + ConfigAttributeDefinition def2 = getConfigAttributeDefinition(OtherTargetObject.class, + "makeLowerCase", new Class[] {String.class}); + Set set2 = toSet(def2); + assertTrue(set2.contains(new SecurityConfig("MOCK_INTERFACE"))); + assertTrue(set2.contains( + new SecurityConfig("MOCK_INTERFACE_METHOD_MAKE_LOWER_CASE"))); + assertTrue(set2.contains( + new SecurityConfig("MOCK_CLASS_METHOD_MAKE_LOWER_CASE"))); + + // Confirm MOCK_CLASS not added, as we return null for class + assertEquals(3, set2.size()); + + ConfigAttributeDefinition def3 = getConfigAttributeDefinition(OtherTargetObject.class, + "makeUpperCase", new Class[] {String.class}); + Set set3 = toSet(def3); + assertTrue(set3.contains(new SecurityConfig("MOCK_INTERFACE"))); + assertTrue(set3.contains( + new SecurityConfig("MOCK_INTERFACE_METHOD_MAKE_UPPER_CASE"))); + assertTrue(set3.contains(new SecurityConfig("RUN_AS"))); // defined against interface + + assertEquals(3, set3.size()); + } + + public void testAttributesForTargetObject() throws Exception { + ConfigAttributeDefinition def1 = getConfigAttributeDefinition(TargetObject.class, + "countLength", new Class[] {String.class}); + Set set1 = toSet(def1); + assertTrue(set1.contains(new SecurityConfig("MOCK_INTERFACE"))); + assertTrue(set1.contains( + new SecurityConfig("MOCK_INTERFACE_METHOD_COUNT_LENGTH"))); + + assertTrue(set1.contains(new SecurityConfig("MOCK_CLASS"))); + + // Confirm the MOCK_CLASS_METHOD_COUNT_LENGTH was not added, as it's not a ConfigAttribute + assertEquals(3, set1.size()); + + ConfigAttributeDefinition def2 = getConfigAttributeDefinition(TargetObject.class, + "makeLowerCase", new Class[] {String.class}); + Set set2 = toSet(def2); + assertTrue(set2.contains(new SecurityConfig("MOCK_INTERFACE"))); + assertTrue(set2.contains( + new SecurityConfig("MOCK_INTERFACE_METHOD_MAKE_LOWER_CASE"))); + assertTrue(set2.contains(new SecurityConfig("MOCK_CLASS"))); + assertTrue(set2.contains( + new SecurityConfig("MOCK_CLASS_METHOD_MAKE_LOWER_CASE"))); + assertEquals(4, set2.size()); + + ConfigAttributeDefinition def3 = getConfigAttributeDefinition(TargetObject.class, + "makeUpperCase", new Class[] {String.class}); + Set set3 = toSet(def3); + assertTrue(set3.contains(new SecurityConfig("MOCK_INTERFACE"))); + assertTrue(set3.contains( + new SecurityConfig("MOCK_INTERFACE_METHOD_MAKE_UPPER_CASE"))); + assertTrue(set3.contains(new SecurityConfig("MOCK_CLASS"))); + assertTrue(set3.contains( + new SecurityConfig("MOCK_CLASS_METHOD_MAKE_UPPER_CASE"))); + assertTrue(set3.contains(new SecurityConfig("RUN_AS"))); + assertEquals(5, set3.size()); + } + + public void testMethodCallWithRunAsReplacement() throws Exception { + SecureContext context = new SecureContextImpl(); + UsernamePasswordAuthenticationToken token = new UsernamePasswordAuthenticationToken("Test", + "Password", + new GrantedAuthority[] {new GrantedAuthorityImpl("MOCK_INTERFACE_METHOD_MAKE_UPPER_CASE")}); + context.setAuthentication(token); + ContextHolder.setContext(context); + + ITargetObject target = makeInterceptedTarget(); + String result = target.makeUpperCase("hello"); + assertEquals("HELLO net.sf.acegisecurity.MockRunAsAuthenticationToken true", + result); + + ContextHolder.setContext(null); + } + + public void testMethodCallWithoutRunAsReplacement() + throws Exception { + SecureContext context = new SecureContextImpl(); + UsernamePasswordAuthenticationToken token = new UsernamePasswordAuthenticationToken("Test", + "Password", + new GrantedAuthority[] {new GrantedAuthorityImpl("MOCK_INTERFACE_METHOD_MAKE_LOWER_CASE")}); + context.setAuthentication(token); + ContextHolder.setContext(context); + + ITargetObject target = makeInterceptedTarget(); + String result = target.makeLowerCase("HELLO"); + + assertEquals("hello net.sf.acegisecurity.providers.UsernamePasswordAuthenticationToken true", + result); + + ContextHolder.setContext(null); + } + + private ConfigAttributeDefinition getConfigAttributeDefinition( + Class clazz, String methodName, Class[] args) throws Exception { + final Method method = clazz.getMethod(methodName, args); + MethodDefinitionAttributes source = new MethodDefinitionAttributes(); + source.setAttributes(new MockAttributes()); + + ConfigAttributeDefinition config = source.getAttributes(new MockMethodInvocation() { + public Method getMethod() { + return method; + } + }); + + return config; + } + + 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.MockAttributes"); + + p.setProperty(PREFIX + "methodDefinitionSource.class", + "net.sf.acegisecurity.MethodDefinitionAttributes"); + p.setProperty(PREFIX + "methodDefinitionSource.attributes(ref)", + "attributes"); + + p.setProperty(PREFIX + "securityInterceptor.class", + "net.sf.acegisecurity.SecurityInterceptor"); + 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.methodDefinitionSource(ref)", + "methodDefinitionSource"); + + 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"); + } + + /** + * convert a ConfigAttributeDefinition into a set of + * ConfigAttribute(s) + * + * @param def the ConfigAttributeDefinition to cover + * + * @return a Set of ConfigAttributes + */ + private Set toSet(ConfigAttributeDefinition def) { + Set set = new HashSet(); + Iterator i = def.getConfigAttributes(); + + while (i.hasNext()) { + ConfigAttribute a = (ConfigAttribute) i.next(); + set.add(a); + } + + return set; + } + + //~ Inner Classes ========================================================== + + private class MockMethodInvocation implements MethodInvocation { + public Object[] getArguments() { + throw new UnsupportedOperationException( + "mock method not implemented"); + } + + public Method getMethod() { + throw new UnsupportedOperationException( + "mock method not implemented"); + } + + public AccessibleObject getStaticPart() { + throw new UnsupportedOperationException( + "mock method not implemented"); + } + + public Object getThis() { + throw new UnsupportedOperationException( + "mock method not implemented"); + } + + public Object proceed() throws Throwable { + throw new UnsupportedOperationException( + "mock method not implemented"); + } + } +} diff --git a/core/src/test/java/org/acegisecurity/MethodDefinitionSourceEditorTests.java b/core/src/test/java/org/acegisecurity/MethodDefinitionSourceEditorTests.java new file mode 100644 index 0000000000..474cf59202 --- /dev/null +++ b/core/src/test/java/org/acegisecurity/MethodDefinitionSourceEditorTests.java @@ -0,0 +1,215 @@ +/* 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 junit.framework.TestCase; + +import org.aopalliance.intercept.MethodInvocation; + +import java.lang.reflect.AccessibleObject; +import java.lang.reflect.Method; + +import java.util.Iterator; + + +/** + * Tests {@link MethodDefinitionSourceEditor}. + * + * @author Ben Alex + * @version $Id$ + */ +public class MethodDefinitionSourceEditorTests extends TestCase { + //~ Constructors =========================================================== + + public MethodDefinitionSourceEditorTests() { + super(); + } + + public MethodDefinitionSourceEditorTests(String arg0) { + super(arg0); + } + + //~ Methods ================================================================ + + public final void setUp() throws Exception { + super.setUp(); + } + + public static void main(String[] args) { + junit.textui.TestRunner.run(MethodDefinitionSourceEditorTests.class); + } + + public void testClassNameNotFoundResultsInException() { + MethodDefinitionSourceEditor editor = new MethodDefinitionSourceEditor(); + + try { + editor.setAsText("net.sf.acegisecurity.DOES_NOT_EXIST_NAME=FOO,BAR"); + fail("Should have given IllegalArgumentException"); + } catch (IllegalArgumentException expected) { + assertTrue(true); + } + } + + public void testClassNameNotInProperFormatResultsInException() { + MethodDefinitionSourceEditor editor = new MethodDefinitionSourceEditor(); + + try { + editor.setAsText("DOES_NOT_EXIST_NAME=FOO,BAR"); + fail("Should have given IllegalArgumentException"); + } catch (IllegalArgumentException expected) { + assertTrue(true); + } + } + + public void testClassNameValidButMethodNameInvalidResultsInException() { + MethodDefinitionSourceEditor editor = new MethodDefinitionSourceEditor(); + + try { + editor.setAsText( + "net.sf.acegisecurity.TargetObject.INVALID_METHOD=FOO,BAR"); + fail("Should have given IllegalArgumentException"); + } catch (IllegalArgumentException expected) { + assertTrue(true); + } + } + + public void testEmptyStringReturnsEmptyMap() { + MethodDefinitionSourceEditor editor = new MethodDefinitionSourceEditor(); + editor.setAsText(""); + + MethodDefinitionMap map = (MethodDefinitionMap) editor.getValue(); + assertEquals(0, map.getMethodMapSize()); + } + + public void testIterator() { + MethodDefinitionSourceEditor editor = new MethodDefinitionSourceEditor(); + editor.setAsText( + "net.sf.acegisecurity.TargetObject.countLength=ROLE_ONE,ROLE_TWO,RUN_AS_ENTRY\r\nnet.sf.acegisecurity.TargetObject.make*=ROLE_NINE,ROLE_SUPERVISOR"); + + MethodDefinitionMap map = (MethodDefinitionMap) editor.getValue(); + Iterator iter = map.getConfigAttributeDefinitions(); + int counter = 0; + + while (iter.hasNext()) { + iter.next(); + counter++; + } + + assertEquals(3, counter); + } + + public void testMultiMethodParsing() { + MethodDefinitionSourceEditor editor = new MethodDefinitionSourceEditor(); + editor.setAsText( + "net.sf.acegisecurity.TargetObject.countLength=ROLE_ONE,ROLE_TWO,RUN_AS_ENTRY\r\nnet.sf.acegisecurity.TargetObject.make*=ROLE_NINE,ROLE_SUPERVISOR"); + + MethodDefinitionMap map = (MethodDefinitionMap) editor.getValue(); + assertEquals(3, map.getMethodMapSize()); + } + + public void testMultiMethodParsingWhereLaterMethodsOverrideEarlierMethods() + throws Exception { + MethodDefinitionSourceEditor editor = new MethodDefinitionSourceEditor(); + editor.setAsText( + "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()); + + ConfigAttributeDefinition returnedMakeLower = map.getAttributes(new MockMethodInvocation( + TargetObject.class, "makeLowerCase", + new Class[] {String.class})); + ConfigAttributeDefinition expectedMakeLower = new ConfigAttributeDefinition(); + expectedMakeLower.addConfigAttribute(new SecurityConfig("ROLE_LOWER")); + assertEquals(expectedMakeLower, returnedMakeLower); + + ConfigAttributeDefinition returnedMakeUpper = map.getAttributes(new MockMethodInvocation( + TargetObject.class, "makeUpperCase", + new Class[] {String.class})); + ConfigAttributeDefinition expectedMakeUpper = new ConfigAttributeDefinition(); + expectedMakeUpper.addConfigAttribute(new SecurityConfig("ROLE_UPPER")); + assertEquals(expectedMakeUpper, returnedMakeUpper); + + ConfigAttributeDefinition returnedCountLength = map.getAttributes(new MockMethodInvocation( + TargetObject.class, "countLength", + new Class[] {String.class})); + ConfigAttributeDefinition expectedCountLength = new ConfigAttributeDefinition(); + expectedCountLength.addConfigAttribute(new SecurityConfig( + "ROLE_GENERAL")); + assertEquals(expectedCountLength, returnedCountLength); + } + + public void testNullReturnsEmptyMap() { + MethodDefinitionSourceEditor editor = new MethodDefinitionSourceEditor(); + editor.setAsText(null); + + MethodDefinitionMap map = (MethodDefinitionMap) editor.getValue(); + assertEquals(0, map.getMethodMapSize()); + } + + public void testSingleMethodParsing() 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(); + + ConfigAttributeDefinition returnedCountLength = map.getAttributes(new MockMethodInvocation( + TargetObject.class, "countLength", + new Class[] {String.class})); + 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); + } + + //~ Inner Classes ========================================================== + + private class MockMethodInvocation implements MethodInvocation { + Method method; + + public MockMethodInvocation(Class clazz, String methodName, + Class[] parameterTypes) throws NoSuchMethodException { + method = clazz.getMethod(methodName, parameterTypes); + } + + private MockMethodInvocation() { + super(); + } + + public Object[] getArguments() { + return null; + } + + public Method getMethod() { + return method; + } + + public AccessibleObject getStaticPart() { + return null; + } + + public Object getThis() { + return null; + } + + public Object proceed() throws Throwable { + return null; + } + } +} diff --git a/core/src/test/java/org/acegisecurity/MockAccessDecisionManager.java b/core/src/test/java/org/acegisecurity/MockAccessDecisionManager.java new file mode 100644 index 0000000000..1e082dcd20 --- /dev/null +++ b/core/src/test/java/org/acegisecurity/MockAccessDecisionManager.java @@ -0,0 +1,62 @@ +/* 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.aopalliance.intercept.MethodInvocation; + +import java.util.Iterator; + + +/** + * Grants access if the user holds any of the authorities listed in the + * configuration attributes starting with "MOCK_". + * + * @author Ben Alex + * @version $Id$ + */ +public class MockAccessDecisionManager implements AccessDecisionManager { + //~ Methods ================================================================ + + public void decide(Authentication authentication, + MethodInvocation invocation, ConfigAttributeDefinition config) + throws AccessDeniedException { + Iterator iter = config.getConfigAttributes(); + + while (iter.hasNext()) { + ConfigAttribute attr = (ConfigAttribute) iter.next(); + + if (this.supports(attr)) { + for (int i = 0; i < authentication.getAuthorities().length; + i++) { + if (attr.getAttribute().equals(authentication + .getAuthorities()[i].getAuthority())) { + return; + } + } + } + } + + throw new AccessDeniedException("Didn't hold required authority"); + } + + public boolean supports(ConfigAttribute attribute) { + if (attribute.getAttribute().startsWith("MOCK_")) { + return true; + } else { + return false; + } + } +} diff --git a/core/src/test/java/org/acegisecurity/MockAttributes.java b/core/src/test/java/org/acegisecurity/MockAttributes.java new file mode 100644 index 0000000000..5db4e10ea4 --- /dev/null +++ b/core/src/test/java/org/acegisecurity/MockAttributes.java @@ -0,0 +1,155 @@ +/* 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.metadata.Attributes; + +import java.lang.reflect.Field; +import java.lang.reflect.Method; + +import java.util.Arrays; +import java.util.Collection; +import java.util.List; + + +/** + * Used by the {@link MethodDefinitionAttributesTests}. + * + * @author Cameron Braid + * @author Ben Alex + */ +public class MockAttributes implements Attributes { + //~ Instance fields ======================================================== + + List classAttributes = Arrays.asList(new SecurityConfig[] {new SecurityConfig( + "MOCK_CLASS")}); + List classMethodAttributesCountLength = Arrays.asList(new String[] {new String( + "MOCK_CLASS_METHOD_COUNT_LENGTH")}); + List classMethodAttributesMakeLowerCase = Arrays.asList(new SecurityConfig[] {new SecurityConfig( + "MOCK_CLASS_METHOD_MAKE_LOWER_CASE")}); + List classMethodAttributesMakeUpperCase = Arrays.asList(new SecurityConfig[] {new SecurityConfig( + "MOCK_CLASS_METHOD_MAKE_UPPER_CASE")}); + List interfaceAttributes = Arrays.asList(new SecurityConfig[] {new SecurityConfig( + "MOCK_INTERFACE")}); + List interfaceMethodAttributesCountLength = Arrays.asList(new SecurityConfig[] {new SecurityConfig( + "MOCK_INTERFACE_METHOD_COUNT_LENGTH")}); + List interfaceMethodAttributesMakeLowerCase = Arrays.asList(new SecurityConfig[] {new SecurityConfig( + "MOCK_INTERFACE_METHOD_MAKE_LOWER_CASE")}); + List interfaceMethodAttributesMakeUpperCase = Arrays.asList(new SecurityConfig[] {new SecurityConfig( + "MOCK_INTERFACE_METHOD_MAKE_UPPER_CASE"), new SecurityConfig( + "RUN_AS")}); + + //~ Methods ================================================================ + + public Collection getAttributes(Class clazz) { + // Emphasise we return null for OtherTargetObject + if (clazz.equals(OtherTargetObject.class)) { + return null; + } + + // interface + if (clazz.equals(ITargetObject.class)) { + return interfaceAttributes; + } + + // class + if (clazz.equals(TargetObject.class)) { + return classAttributes; + } + + return null; + } + + public Collection getAttributes(Method method) { + // interface + if (method.getDeclaringClass().equals(ITargetObject.class)) { + if (method.getName().equals("countLength")) { + return interfaceMethodAttributesCountLength; + } + + if (method.getName().equals("makeLowerCase")) { + return interfaceMethodAttributesMakeLowerCase; + } + + if (method.getName().equals("makeUpperCase")) { + return interfaceMethodAttributesMakeUpperCase; + } + + if (method.getName().equals("publicMakeLowerCase")) { + throw new UnsupportedOperationException( + "mock support not implemented"); + } + } + + // class + if (method.getDeclaringClass().equals(TargetObject.class)) { + if (method.getName().equals("countLength")) { + return classMethodAttributesCountLength; + } + + if (method.getName().equals("makeLowerCase")) { + return classMethodAttributesMakeLowerCase; + } + + if (method.getName().equals("makeUpperCase")) { + return classMethodAttributesMakeUpperCase; + } + + if (method.getName().equals("publicMakeLowerCase")) { + throw new UnsupportedOperationException( + "mock support not implemented"); + } + } + + // other target object + if (method.getDeclaringClass().equals(OtherTargetObject.class)) { + if (method.getName().equals("countLength")) { + return classMethodAttributesCountLength; + } + + if (method.getName().equals("makeLowerCase")) { + return classMethodAttributesMakeLowerCase; + } + + if (method.getName().equals("makeUpperCase")) { + return null; // NB + } + + if (method.getName().equals("publicMakeLowerCase")) { + throw new UnsupportedOperationException( + "mock support not implemented"); + } + } + + return null; + } + + public Collection getAttributes(Class arg0, Class arg1) { + throw new UnsupportedOperationException("mock method not implemented"); + } + + public Collection getAttributes(Field arg0, Class arg1) { + throw new UnsupportedOperationException("mock method not implemented"); + } + + public Collection getAttributes(Field arg0) { + throw new UnsupportedOperationException("mock method not implemented"); + } + + public Collection getAttributes(Method arg0, Class arg1) { + throw new UnsupportedOperationException("mock method not implemented"); + } +} diff --git a/core/src/test/java/org/acegisecurity/MockAuthenticationManager.java b/core/src/test/java/org/acegisecurity/MockAuthenticationManager.java new file mode 100644 index 0000000000..33fa59d2ca --- /dev/null +++ b/core/src/test/java/org/acegisecurity/MockAuthenticationManager.java @@ -0,0 +1,31 @@ +/* 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; + +/** + * Simply accepts as valid whatever is passed to it. + * + * @author Ben Alex + * @version $Id$ + */ +public class MockAuthenticationManager implements AuthenticationManager { + //~ Methods ================================================================ + + public Authentication authenticate(Authentication authentication) + throws AuthenticationException { + return authentication; + } +} diff --git a/core/src/test/java/org/acegisecurity/MockRunAsAuthenticationToken.java b/core/src/test/java/org/acegisecurity/MockRunAsAuthenticationToken.java new file mode 100644 index 0000000000..9424150ffa --- /dev/null +++ b/core/src/test/java/org/acegisecurity/MockRunAsAuthenticationToken.java @@ -0,0 +1,54 @@ +/* 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.providers.AbstractAuthenticationToken; + + +/** + * Simple holder that indicates the {@link MockRunAsManager} returned a + * different Authentication object. + * + * @author Ben Alex + * @version $Id$ + */ +public class MockRunAsAuthenticationToken extends AbstractAuthenticationToken { + //~ Instance fields ======================================================== + + private boolean authenticated = false; + + //~ Methods ================================================================ + + public void setAuthenticated(boolean isAuthenticated) { + authenticated = isAuthenticated; + } + + public boolean isAuthenticated() { + return authenticated; + } + + public GrantedAuthority[] getAuthorities() { + return null; + } + + public Object getCredentials() { + return null; + } + + public Object getPrincipal() { + return null; + } +} diff --git a/core/src/test/java/org/acegisecurity/MockRunAsManager.java b/core/src/test/java/org/acegisecurity/MockRunAsManager.java new file mode 100644 index 0000000000..6c432e9f7e --- /dev/null +++ b/core/src/test/java/org/acegisecurity/MockRunAsManager.java @@ -0,0 +1,58 @@ +/* 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.aopalliance.intercept.MethodInvocation; + +import java.util.Iterator; + + +/** + * Returns a new run-as identity if configuration attribute RUN_AS is found. + * The new identity is simply an empty {@link MockRunAsAuthenticationToken}. + * + * @author Ben Alex + * @version $Id$ + */ +public class MockRunAsManager implements RunAsManager { + //~ Methods ================================================================ + + public Authentication buildRunAs(Authentication authentication, + MethodInvocation invocation, ConfigAttributeDefinition config) { + Iterator iter = config.getConfigAttributes(); + + while (iter.hasNext()) { + ConfigAttribute attr = (ConfigAttribute) iter.next(); + + if (this.supports(attr)) { + Authentication response = new MockRunAsAuthenticationToken(); + response.setAuthenticated(true); + + return response; + } + } + + return null; + } + + public boolean supports(ConfigAttribute attribute) { + if ("RUN_AS".equals(attribute.getAttribute())) { + return true; + } else { + return false; + } + } +} diff --git a/core/src/test/java/org/acegisecurity/OtherTargetObject.java b/core/src/test/java/org/acegisecurity/OtherTargetObject.java new file mode 100644 index 0000000000..58a45f6c05 --- /dev/null +++ b/core/src/test/java/org/acegisecurity/OtherTargetObject.java @@ -0,0 +1,56 @@ +/* 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; + +/** + * Simply extends {@link TargetObject} so we have a different object to put + * configuration attributes against. + * + *

+ * There is no different behaviour. We have to define each method so that + * Class.getMethod(methodName, args) returns a + * Method referencing this class rather than the parent class. + *

+ * + *

+ * We need to implement ITargetObject again because the + * MethodDefinitionAttributes only locates attributes on + * interfaces explicitly defined by the intercepted class (not the interfaces + * defined by its parent class or classes). + *

+ * + * @author Ben Alex + * @version $Id$ + */ +public class OtherTargetObject extends TargetObject implements ITargetObject { + //~ Methods ================================================================ + + public int countLength(String input) { + return super.countLength(input); + } + + public String makeLowerCase(String input) { + return super.makeLowerCase(input); + } + + public String makeUpperCase(String input) { + return super.makeUpperCase(input); + } + + public String publicMakeLowerCase(String input) { + return super.publicMakeLowerCase(input); + } +} diff --git a/core/src/test/java/org/acegisecurity/SecurityConfigTests.java b/core/src/test/java/org/acegisecurity/SecurityConfigTests.java new file mode 100644 index 0000000000..f95e1b4a47 --- /dev/null +++ b/core/src/test/java/org/acegisecurity/SecurityConfigTests.java @@ -0,0 +1,108 @@ +/* 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 junit.framework.TestCase; + + +/** + * Tests {@link SecurityConfig}. + * + * @author Ben Alex + * @version $Id$ + */ +public class SecurityConfigTests extends TestCase { + //~ Constructors =========================================================== + + public SecurityConfigTests() { + super(); + } + + public SecurityConfigTests(String arg0) { + super(arg0); + } + + //~ Methods ================================================================ + + public final void setUp() throws Exception { + super.setUp(); + } + + public static void main(String[] args) { + junit.textui.TestRunner.run(SecurityConfigTests.class); + } + + public void testHashCode() { + SecurityConfig config = new SecurityConfig("TEST"); + assertEquals("TEST".hashCode(), config.hashCode()); + } + + public void testNoArgsConstructor() { + try { + new SecurityConfig(); + fail("Should have thrown IllegalArgumentException"); + } catch (IllegalArgumentException expected) { + assertTrue(true); + } + } + + public void testObjectEquals() throws Exception { + SecurityConfig security1 = new SecurityConfig("TEST"); + SecurityConfig security2 = new SecurityConfig("TEST"); + assertEquals(security1, security2); + + String securityString1 = "TEST"; + assertEquals(security1, securityString1); + + String securityString2 = "NOT_EQUAL"; + assertTrue(!security1.equals(securityString2)); + + SecurityConfig security3 = new SecurityConfig("NOT_EQUAL"); + assertTrue(!security1.equals(security3)); + + MockConfigAttribute mock1 = new MockConfigAttribute("TEST"); + assertEquals(security1, mock1); + + MockConfigAttribute mock2 = new MockConfigAttribute("NOT_EQUAL"); + assertTrue(!security1.equals(mock2)); + + Integer int1 = new Integer(987); + assertTrue(!security1.equals(int1)); + } + + public void testToString() { + SecurityConfig config = new SecurityConfig("TEST"); + assertEquals("TEST", config.toString()); + } + + //~ Inner Classes ========================================================== + + private class MockConfigAttribute implements ConfigAttribute { + private String attribute; + + public MockConfigAttribute(String configuration) { + this.attribute = configuration; + } + + private MockConfigAttribute() { + super(); + } + + public String getAttribute() { + return this.attribute; + } + } +} diff --git a/core/src/test/java/org/acegisecurity/SecurityInterceptorTests.java b/core/src/test/java/org/acegisecurity/SecurityInterceptorTests.java new file mode 100644 index 0000000000..f96cede2db --- /dev/null +++ b/core/src/test/java/org/acegisecurity/SecurityInterceptorTests.java @@ -0,0 +1,420 @@ +/* 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 junit.framework.TestCase; + +import net.sf.acegisecurity.context.ContextHolder; +import net.sf.acegisecurity.context.ContextImpl; +import net.sf.acegisecurity.context.SecureContext; +import net.sf.acegisecurity.context.SecureContextImpl; +import net.sf.acegisecurity.providers.UsernamePasswordAuthenticationToken; + +import org.aopalliance.intercept.MethodInvocation; + +import org.springframework.beans.factory.support.DefaultListableBeanFactory; +import org.springframework.beans.factory.support.PropertiesBeanDefinitionReader; + +import java.util.Iterator; +import java.util.List; +import java.util.Properties; +import java.util.Vector; + + +/** + * Tests {@link SecurityInterceptor}. + * + * @author Ben Alex + * @version $Id$ + */ +public class SecurityInterceptorTests extends TestCase { + //~ Constructors =========================================================== + + public SecurityInterceptorTests() { + super(); + } + + public SecurityInterceptorTests(String arg0) { + super(arg0); + } + + //~ Methods ================================================================ + + public final void setUp() throws Exception { + super.setUp(); + } + + public static void main(String[] args) { + junit.textui.TestRunner.run(SecurityInterceptorTests.class); + } + + public void testCallingAPublicMethodFacadeWillNotRepeatSecurityChecksWhenPassedToTheSecuredMethodItFronts() + throws Exception { + ITargetObject target = makeInterceptedTarget(); + String result = target.publicMakeLowerCase("HELLO"); + assertEquals("hello ContextHolder Not Security Aware", result); + + ContextHolder.setContext(null); + } + + public void testCallingAPublicMethodWhenPresentingASecureContextButWithoutAnyAuthenticationObject() + throws Exception { + SecureContext context = new SecureContextImpl(); + ContextHolder.setContext(context); + + ITargetObject target = makeInterceptedTarget(); + String result = target.publicMakeLowerCase("HELLO"); + assertEquals("hello Authentication empty", result); + + ContextHolder.setContext(null); + } + + public void testCallingAPublicMethodWhenPresentingAnAuthenticationObjectWillProperlySetItsIsAuthenticatedProperty() + throws Exception { + SecureContext context = new SecureContextImpl(); + UsernamePasswordAuthenticationToken token = new UsernamePasswordAuthenticationToken("Test", + "Password", + new GrantedAuthority[] {new GrantedAuthorityImpl("MOCK_THIS_IS_NOT_REQUIRED_AS_IT_IS_PUBLIC")}); + assertTrue(!token.isAuthenticated()); + context.setAuthentication(token); + ContextHolder.setContext(context); + + ITargetObject target = makeInterceptedTarget(); + String result = target.publicMakeLowerCase("HELLO"); + assertEquals("hello net.sf.acegisecurity.providers.UsernamePasswordAuthenticationToken false", + result); + + ContextHolder.setContext(null); + } + + public void testDeniesWhenAppropriate() throws Exception { + SecureContext context = new SecureContextImpl(); + UsernamePasswordAuthenticationToken token = new UsernamePasswordAuthenticationToken("Test", + "Password", + new GrantedAuthority[] {new GrantedAuthorityImpl("MOCK_NO_BENEFIT_TO_THIS_GRANTED_AUTHORITY")}); + context.setAuthentication(token); + ContextHolder.setContext(context); + + ITargetObject target = makeInterceptedTarget(); + + try { + target.makeUpperCase("HELLO"); + fail("Should have thrown AccessDeniedException"); + } catch (AccessDeniedException expected) { + assertTrue(true); + } + + ContextHolder.setContext(null); + } + + public void testGetters() { + MockAccessDecisionManager accessDecision = new MockAccessDecisionManager(); + MockRunAsManager runAs = new MockRunAsManager(); + MockAuthenticationManager authManager = new MockAuthenticationManager(); + MockMethodDefinitionSource methodSource = new MockMethodDefinitionSource(false, + true); + + SecurityInterceptor si = new SecurityInterceptor(); + si.setAccessDecisionManager(accessDecision); + si.setRunAsManager(runAs); + si.setAuthenticationManager(authManager); + si.setMethodDefinitionSource(methodSource); + + assertEquals(accessDecision, si.getAccessDecisionManager()); + assertEquals(runAs, si.getRunAsManager()); + assertEquals(authManager, si.getAuthenticationManager()); + assertEquals(methodSource, si.getMethodDefinitionSource()); + } + + public void testMethodCallWithRunAsReplacement() throws Exception { + SecureContext context = new SecureContextImpl(); + UsernamePasswordAuthenticationToken token = new UsernamePasswordAuthenticationToken("Test", + "Password", + new GrantedAuthority[] {new GrantedAuthorityImpl("MOCK_UPPER")}); + context.setAuthentication(token); + ContextHolder.setContext(context); + + ITargetObject target = makeInterceptedTarget(); + String result = target.makeUpperCase("hello"); + assertEquals("HELLO net.sf.acegisecurity.MockRunAsAuthenticationToken true", + result); + + ContextHolder.setContext(null); + } + + public void testMethodCallWithoutRunAsReplacement() + 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 = makeInterceptedTarget(); + String result = target.makeLowerCase("HELLO"); + + // Note we check the isAuthenticated becomes true in following line + assertEquals("hello net.sf.acegisecurity.providers.UsernamePasswordAuthenticationToken true", + result); + + ContextHolder.setContext(null); + } + + public void testRejectionOfEmptyContextHolder() throws Exception { + ITargetObject target = makeInterceptedTarget(); + + try { + target.makeUpperCase("hello"); + fail( + "Should have thrown AuthenticationCredentialsNotFoundException"); + } catch (AuthenticationCredentialsNotFoundException expected) { + assertTrue(true); + } + } + + public void testRejectionOfNonSecureContextOnContextHolder() + throws Exception { + ContextHolder.setContext(new ContextImpl()); + + ITargetObject target = makeInterceptedTarget(); + + try { + target.makeUpperCase("hello"); + fail( + "Should have thrown AuthenticationCredentialsNotFoundException"); + } catch (AuthenticationCredentialsNotFoundException expected) { + assertTrue(true); + } + + ContextHolder.setContext(null); + } + + public void testRejectionOfSecureContextThatContainsNoAuthenticationObject() + throws Exception { + ContextHolder.setContext(new SecureContextImpl()); + + ITargetObject target = makeInterceptedTarget(); + + try { + target.makeUpperCase("hello"); + fail( + "Should have thrown AuthenticationCredentialsNotFoundException"); + } catch (AuthenticationCredentialsNotFoundException expected) { + assertTrue(true); + } + + ContextHolder.setContext(null); + } + + public void testStartupCheckForAccessDecisionManager() { + SecurityInterceptor si = new SecurityInterceptor(); + si.setRunAsManager(new MockRunAsManager()); + si.setAuthenticationManager(new MockAuthenticationManager()); + + si.setMethodDefinitionSource(new MockMethodDefinitionSource(false, true)); + + try { + si.afterPropertiesSet(); + fail("Should have thrown IllegalArgumentException"); + } catch (IllegalArgumentException expected) { + assertEquals("An AccessDecisionManager is required", + expected.getMessage()); + } + } + + public void testStartupCheckForAuthenticationManager() { + SecurityInterceptor si = new SecurityInterceptor(); + si.setAccessDecisionManager(new MockAccessDecisionManager()); + si.setRunAsManager(new MockRunAsManager()); + + si.setMethodDefinitionSource(new MockMethodDefinitionSource(false, true)); + + try { + si.afterPropertiesSet(); + fail("Should have thrown IllegalArgumentException"); + } catch (IllegalArgumentException expected) { + assertEquals("An AuthenticationManager is required", + expected.getMessage()); + } + } + + public void testStartupCheckForMethodDefinitionSource() { + SecurityInterceptor si = new SecurityInterceptor(); + si.setAccessDecisionManager(new MockAccessDecisionManager()); + si.setRunAsManager(new MockRunAsManager()); + si.setAuthenticationManager(new MockAuthenticationManager()); + + try { + si.afterPropertiesSet(); + fail("Should have thrown IllegalArgumentException"); + } catch (IllegalArgumentException expected) { + assertEquals("A MethodDefinitionSource is required", + expected.getMessage()); + } + } + + public void testStartupCheckForRunAsManager() { + SecurityInterceptor si = new SecurityInterceptor(); + si.setAccessDecisionManager(new MockAccessDecisionManager()); + si.setAuthenticationManager(new MockAuthenticationManager()); + + si.setMethodDefinitionSource(new MockMethodDefinitionSource(false, true)); + + try { + si.afterPropertiesSet(); + fail("Should have thrown IllegalArgumentException"); + } catch (IllegalArgumentException expected) { + assertEquals("A RunAsManager is required", expected.getMessage()); + } + } + + public void testValidationFailsIfInvalidAttributePresented() { + SecurityInterceptor si = new SecurityInterceptor(); + si.setAccessDecisionManager(new MockAccessDecisionManager()); + si.setRunAsManager(new MockRunAsManager()); + si.setAuthenticationManager(new MockAuthenticationManager()); + + assertTrue(si.isValidateConfigAttributes()); // check default + si.setMethodDefinitionSource(new MockMethodDefinitionSource(true, true)); + + try { + si.afterPropertiesSet(); + fail("Should have thrown IllegalArgumentException"); + } catch (IllegalArgumentException expected) { + assertEquals("Unsupported configuration attributes: [ANOTHER_INVALID, INVALID_ATTRIBUTE]", + expected.getMessage()); + } + } + + public void testValidationNotAttemptedIfIsValidateConfigAttributesSetToFalse() { + SecurityInterceptor si = new SecurityInterceptor(); + si.setAccessDecisionManager(new MockAccessDecisionManager()); + si.setRunAsManager(new MockRunAsManager()); + si.setAuthenticationManager(new MockAuthenticationManager()); + + assertTrue(si.isValidateConfigAttributes()); // check default + si.setValidateConfigAttributes(false); + assertTrue(!si.isValidateConfigAttributes()); // check changed + + si.setMethodDefinitionSource(new MockMethodDefinitionSource(true, true)); + si.afterPropertiesSet(); + assertTrue(true); + } + + public void testValidationNotAttemptedIfMethodDefinitionSourceCannotReturnIterator() { + SecurityInterceptor si = new SecurityInterceptor(); + si.setAccessDecisionManager(new MockAccessDecisionManager()); + si.setRunAsManager(new MockRunAsManager()); + si.setAuthenticationManager(new MockAuthenticationManager()); + + assertTrue(si.isValidateConfigAttributes()); // check default + si.setMethodDefinitionSource(new MockMethodDefinitionSource(true, false)); + si.afterPropertiesSet(); + assertTrue(true); + } + + 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 + "securityInterceptor.class", + "net.sf.acegisecurity.SecurityInterceptor"); + 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.methodDefinitionSource", + "net.sf.acegisecurity.ITargetObject.makeLower*=MOCK_LOWER\r\nnet.sf.acegisecurity.ITargetObject.makeUpper*=MOCK_UPPER,RUN_AS"); + + 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"); + } + + //~ Inner Classes ========================================================== + + private class MockMethodDefinitionSource implements MethodDefinitionSource { + private List list; + private boolean returnAnIterator; + + public MockMethodDefinitionSource(boolean includeInvalidAttributes, + boolean returnAnIteratorWhenRequested) { + returnAnIterator = returnAnIteratorWhenRequested; + list = new Vector(); + + ConfigAttributeDefinition def1 = new ConfigAttributeDefinition(); + def1.addConfigAttribute(new SecurityConfig("MOCK_LOWER")); + list.add(def1); + + if (includeInvalidAttributes) { + ConfigAttributeDefinition def2 = new ConfigAttributeDefinition(); + def2.addConfigAttribute(new SecurityConfig("MOCK_LOWER")); + def2.addConfigAttribute(new SecurityConfig("INVALID_ATTRIBUTE")); + list.add(def2); + } + + ConfigAttributeDefinition def3 = new ConfigAttributeDefinition(); + def3.addConfigAttribute(new SecurityConfig("MOCK_UPPER")); + def3.addConfigAttribute(new SecurityConfig("RUN_AS")); + list.add(def3); + + if (includeInvalidAttributes) { + ConfigAttributeDefinition def4 = new ConfigAttributeDefinition(); + def4.addConfigAttribute(new SecurityConfig("MOCK_SOMETHING")); + def4.addConfigAttribute(new SecurityConfig("ANOTHER_INVALID")); + list.add(def4); + } + } + + private MockMethodDefinitionSource() { + super(); + } + + public ConfigAttributeDefinition getAttributes( + MethodInvocation invocation) { + throw new UnsupportedOperationException( + "mock method not implemented"); + } + + public Iterator getConfigAttributeDefinitions() { + if (returnAnIterator) { + return list.iterator(); + } else { + return null; + } + } + } +} diff --git a/core/src/test/java/org/acegisecurity/TargetObject.java b/core/src/test/java/org/acegisecurity/TargetObject.java new file mode 100644 index 0000000000..4bd977553e --- /dev/null +++ b/core/src/test/java/org/acegisecurity/TargetObject.java @@ -0,0 +1,103 @@ +/* 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.context.Context; +import net.sf.acegisecurity.context.ContextHolder; +import net.sf.acegisecurity.context.SecureContext; + + +/** + * Represents a secured object. + * + * @author Ben Alex + * @version $Id$ + */ +public class TargetObject implements ITargetObject { + //~ Methods ================================================================ + + public int countLength(String input) { + return input.length(); + } + + /** + * Returns the lowercase string, followed by security environment + * information. + * + * @param input the message to make lowercase + * + * @return the lowercase message, a space, the Authentication + * class that was on the ContextHolder at the time of + * method invocation, and a boolean indicating if the + * Authentication object is authenticated or not + */ + public String makeLowerCase(String input) { + Context context = ContextHolder.getContext(); + + if ((context != null) && (context instanceof SecureContext)) { + Authentication auth = ((SecureContext) context).getAuthentication(); + + if (auth == null) { + return input.toLowerCase() + " Authentication empty"; + } else { + return input.toLowerCase() + " " + auth.getClass().getName() + + " " + auth.isAuthenticated(); + } + } else { + return input.toLowerCase() + " ContextHolder Not Security Aware"; + } + } + + /** + * Returns the uppercase string, followed by security environment + * information. + * + * @param input the message to make uppercase + * + * @return the uppercase message, a space, the Authentication + * class that was on the ContextHolder at the time of + * method invocation, and a boolean indicating if the + * Authentication object is authenticated or not + * + * @throws AccessDeniedException if for some reason this method was being + * called and the ContextHolder was null + * or did not hold a SecureContext + */ + public String makeUpperCase(String input) { + Context context = ContextHolder.getContext(); + + if ((context == null) || !(context instanceof SecureContext)) { + throw new AccessDeniedException( + "For some reason the SecurityInterceptor allowed this call, meaning the ContextHolder should have been populated, but it was not."); + } + + Authentication auth = ((SecureContext) context).getAuthentication(); + + return input.toUpperCase() + " " + auth.getClass().getName() + " " + + auth.isAuthenticated(); + } + + /** + * Delegates through to the {@link #toLowerCase(String)} method. + * + * @param input the method to be made uppercase + * + * @return + */ + public String publicMakeLowerCase(String input) { + return this.makeLowerCase(input); + } +} diff --git a/core/src/test/java/org/acegisecurity/adapters/AbstractAdapterAuthenticationTokenTests.java b/core/src/test/java/org/acegisecurity/adapters/AbstractAdapterAuthenticationTokenTests.java new file mode 100644 index 0000000000..a406cf064d --- /dev/null +++ b/core/src/test/java/org/acegisecurity/adapters/AbstractAdapterAuthenticationTokenTests.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.adapters; + +import junit.framework.TestCase; + +import net.sf.acegisecurity.GrantedAuthority; +import net.sf.acegisecurity.GrantedAuthorityImpl; + + +/** + * Tests {@link AbstractAdapterAuthenticationToken}. + * + * @author Ben Alex + * @version $Id$ + */ +public class AbstractAdapterAuthenticationTokenTests extends TestCase { + //~ Constructors =========================================================== + + public AbstractAdapterAuthenticationTokenTests() { + super(); + } + + public AbstractAdapterAuthenticationTokenTests(String arg0) { + super(arg0); + } + + //~ Methods ================================================================ + + public final void setUp() throws Exception { + super.setUp(); + } + + public static void main(String[] args) { + junit.textui.TestRunner.run(AbstractAdapterAuthenticationTokenTests.class); + } + + public void testGetters() throws Exception { + MockDecisionManagerImpl token = new MockDecisionManagerImpl("my_password", + "Test", "Password", + new GrantedAuthority[] {new GrantedAuthorityImpl("ROLE_ONE"), new GrantedAuthorityImpl( + "ROLE_TWO")}); + assertEquals("Test", token.getPrincipal()); + assertEquals("Password", token.getCredentials()); + assertEquals("my_password".hashCode(), token.getKeyHash()); + } + + public void testIsUserInRole() throws Exception { + MockDecisionManagerImpl token = new MockDecisionManagerImpl("my_password", + "Test", "Password", + new GrantedAuthority[] {new GrantedAuthorityImpl("ROLE_ONE"), new GrantedAuthorityImpl( + "ROLE_TWO")}); + assertTrue(token.isUserInRole("ROLE_ONE")); + assertTrue(token.isUserInRole("ROLE_TWO")); + assertTrue(!token.isUserInRole("")); + assertTrue(!token.isUserInRole("ROLE_ONE ")); + assertTrue(!token.isUserInRole("role_one")); + assertTrue(!token.isUserInRole("ROLE_XXXX")); + } + + public void testNoArgsConstructor() { + try { + new MockDecisionManagerImpl(); + fail("Should have thrown IllegalArgumentException"); + } catch (IllegalArgumentException expected) { + assertTrue(true); + } + } + + public void testObjectsEquals() throws Exception { + MockDecisionManagerImpl token1 = new MockDecisionManagerImpl("my_password", + "Test", "Password", + new GrantedAuthority[] {new GrantedAuthorityImpl("ROLE_ONE"), new GrantedAuthorityImpl( + "ROLE_TWO")}); + MockDecisionManagerImpl token2 = new MockDecisionManagerImpl("my_password", + "Test", "Password", + new GrantedAuthority[] {new GrantedAuthorityImpl("ROLE_ONE"), new GrantedAuthorityImpl( + "ROLE_TWO")}); + assertEquals(token1, token2); + + MockDecisionManagerImpl token3 = new MockDecisionManagerImpl("my_password", + "Test", "Password_Changed", + new GrantedAuthority[] {new GrantedAuthorityImpl("ROLE_ONE"), new GrantedAuthorityImpl( + "ROLE_TWO")}); + assertTrue(!token1.equals(token3)); + + MockDecisionManagerImpl token4 = new MockDecisionManagerImpl("my_password", + "Test_Changed", "Password", + new GrantedAuthority[] {new GrantedAuthorityImpl("ROLE_ONE"), new GrantedAuthorityImpl( + "ROLE_TWO")}); + assertTrue(!token1.equals(token4)); + + MockDecisionManagerImpl token5 = new MockDecisionManagerImpl("password_changed", + "Test", "Password", + new GrantedAuthority[] {new GrantedAuthorityImpl("ROLE_ONE"), new GrantedAuthorityImpl( + "ROLE_TWO")}); + assertTrue(!token1.equals(token5)); + + MockDecisionManagerImpl token6 = new MockDecisionManagerImpl("my_password", + "Test", "Password", + new GrantedAuthority[] {new GrantedAuthorityImpl("ROLE_ONE"), new GrantedAuthorityImpl( + "ROLE_TWO_CHANGED")}); + assertTrue(!token1.equals(token6)); + + MockDecisionManagerImpl token7 = new MockDecisionManagerImpl("my_password", + "Test", "Password", + new GrantedAuthority[] {new GrantedAuthorityImpl("ROLE_ONE")}); + assertTrue(!token1.equals(token7)); + + assertTrue(!token1.equals(new Integer(100))); + } + + public void testSetAuthenticatedAlwaysReturnsTrue() + throws Exception { + MockDecisionManagerImpl token = new MockDecisionManagerImpl("my_password", + "Test", "Password", + new GrantedAuthority[] {new GrantedAuthorityImpl("ROLE_ONE"), new GrantedAuthorityImpl( + "ROLE_TWO")}); + assertTrue(token.isAuthenticated()); + token.setAuthenticated(false); + assertTrue(token.isAuthenticated()); + } + + //~ Inner Classes ========================================================== + + private class MockDecisionManagerImpl + extends AbstractAdapterAuthenticationToken { + private String password; + private String username; + + public MockDecisionManagerImpl(String key, String username, + String password, GrantedAuthority[] authorities) { + super(key, authorities); + this.username = username; + this.password = password; + } + + private MockDecisionManagerImpl() { + throw new IllegalArgumentException(); + } + + public Object getCredentials() { + return this.password; + } + + public Object getPrincipal() { + return this.username; + } + } +} diff --git a/core/src/test/java/org/acegisecurity/adapters/adaptertest-invalid.xml b/core/src/test/java/org/acegisecurity/adapters/adaptertest-invalid.xml new file mode 100644 index 0000000000..d2d53302fa --- /dev/null +++ b/core/src/test/java/org/acegisecurity/adapters/adaptertest-invalid.xml @@ -0,0 +1,38 @@ + + + + + + + + + + + marissa=koala,ROLE_TELLER,ROLE_SUPERVISOR + dianne=emu,ROLE_TELLER + scott=wombat,ROLE_TELLER + peter=opal,disabled,ROLE_TELLER + + + + + + + diff --git a/core/src/test/java/org/acegisecurity/adapters/adaptertest-valid.xml b/core/src/test/java/org/acegisecurity/adapters/adaptertest-valid.xml new file mode 100644 index 0000000000..df0c6150ca --- /dev/null +++ b/core/src/test/java/org/acegisecurity/adapters/adaptertest-valid.xml @@ -0,0 +1,52 @@ + + + + + + + + + + + marissa=koala,ROLE_TELLER,ROLE_SUPERVISOR + dianne=emu,ROLE_TELLER + scott=wombat,ROLE_TELLER + peter=opal,disabled,ROLE_TELLER + + + + + + + + false + true + + + + + + + + + + + + diff --git a/core/src/test/java/org/acegisecurity/context/ContextHolderTests.java b/core/src/test/java/org/acegisecurity/context/ContextHolderTests.java new file mode 100644 index 0000000000..4bfaa583dd --- /dev/null +++ b/core/src/test/java/org/acegisecurity/context/ContextHolderTests.java @@ -0,0 +1,76 @@ +/* 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.context; + +import junit.framework.TestCase; + + +/** + * Tests {@link ContextHolder}. + * + * @author Ben Alex + * @version $Id$ + */ +public class ContextHolderTests extends TestCase { + //~ Constructors =========================================================== + + public ContextHolderTests() { + super(); + } + + public ContextHolderTests(String arg0) { + super(arg0); + } + + //~ Methods ================================================================ + + public final void setUp() throws Exception { + super.setUp(); + } + + public static void main(String[] args) { + junit.textui.TestRunner.run(ContextHolderTests.class); + } + + public void testContextHolderGetterSetter() { + assertEquals(null, ContextHolder.getContext()); + + MockContext context = new MockContext(); + context.setColour("red"); + ContextHolder.setContext(context); + + MockContext offContext = (MockContext) ContextHolder.getContext(); + assertEquals("red", offContext.getColour()); + } + + //~ Inner Classes ========================================================== + + private class MockContext implements Context { + private String colour; + + public void setColour(String colour) { + this.colour = colour; + } + + public String getColour() { + return colour; + } + + public void validate() throws ContextInvalidException { + return; + } + } +} diff --git a/core/src/test/java/org/acegisecurity/context/ContextImplTests.java b/core/src/test/java/org/acegisecurity/context/ContextImplTests.java new file mode 100644 index 0000000000..3be5ea613b --- /dev/null +++ b/core/src/test/java/org/acegisecurity/context/ContextImplTests.java @@ -0,0 +1,53 @@ +/* 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.context; + +import junit.framework.TestCase; + + +/** + * Tests {@link ContextImpl}. + * + * @author Ben Alex + * @version $Id$ + */ +public class ContextImplTests extends TestCase { + //~ Constructors =========================================================== + + public ContextImplTests() { + super(); + } + + public ContextImplTests(String arg0) { + super(arg0); + } + + //~ Methods ================================================================ + + public final void setUp() throws Exception { + super.setUp(); + } + + public static void main(String[] args) { + junit.textui.TestRunner.run(ContextImplTests.class); + } + + public void testConfirmsContextImplHasTheValidateMethod() { + Context context = new ContextImpl(); + context.validate(); + assertTrue(true); + } +} diff --git a/core/src/test/java/org/acegisecurity/context/ContextInterceptorTests.java b/core/src/test/java/org/acegisecurity/context/ContextInterceptorTests.java new file mode 100644 index 0000000000..4e0317582d --- /dev/null +++ b/core/src/test/java/org/acegisecurity/context/ContextInterceptorTests.java @@ -0,0 +1,106 @@ +/* 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.context; + +import junit.framework.TestCase; + +import org.springframework.beans.factory.support.DefaultListableBeanFactory; +import org.springframework.beans.factory.support.PropertiesBeanDefinitionReader; + +import java.util.Properties; + + +/** + * Tests {@link ContextInterceptor}. + * + * @author Ben Alex + * @version $Id$ + */ +public class ContextInterceptorTests extends TestCase { + //~ Constructors =========================================================== + + public ContextInterceptorTests() { + super(); + } + + public ContextInterceptorTests(String arg0) { + super(arg0); + } + + //~ Methods ================================================================ + + public final void setUp() throws Exception { + super.setUp(); + } + + public static void main(String[] args) { + junit.textui.TestRunner.run(ContextInterceptorTests.class); + } + + public ITargetObject makeInterceptedTarget() { + String PREFIX = "beans."; + DefaultListableBeanFactory lbf = new DefaultListableBeanFactory(); + Properties p = new Properties(); + p.setProperty(PREFIX + "contextInterceptor.class", + "net.sf.acegisecurity.context.ContextInterceptor"); + p.setProperty(PREFIX + "targetObject.class", + "net.sf.acegisecurity.context.TargetObject"); + p.setProperty(PREFIX + "target.class", + "org.springframework.aop.framework.ProxyFactoryBean"); + p.setProperty(PREFIX + "target.proxyInterfaces", + "net.sf.acegisecurity.context.ITargetObject"); + p.setProperty(PREFIX + "target.interceptorNames", + "contextInterceptor,targetObject"); + + int count = (new PropertiesBeanDefinitionReader(lbf)) + .registerBeanDefinitions(p, PREFIX); + + return (ITargetObject) lbf.getBean("target"); + } + + public void testInterceptorDetectsEmptyContextHolder() + throws Exception { + ITargetObject target = makeInterceptedTarget(); + + try { + target.makeUpperCase("hello"); + fail("Should have thrown ContextHolderEmptyException"); + } catch (ContextHolderEmptyException expected) { + assertTrue(true); + } + } + + public void testInterceptorDetectsInvalidContext() + throws Exception { + ITargetObject target = makeInterceptedTarget(); + ContextHolder.setContext(new SecureContextImpl()); // Authentication not set + + try { + target.makeUpperCase("hello"); + fail("Should have thrown ContextInvalidException"); + } catch (ContextInvalidException expected) { + assertTrue(true); + } + } + + public void testInterceptorNormalOperation() throws Exception { + ITargetObject target = makeInterceptedTarget(); + ContextHolder.setContext(new ContextImpl()); + + String result = target.makeUpperCase("hello"); + assertEquals("HELLO", result); + } +} diff --git a/core/src/test/java/org/acegisecurity/context/ITargetObject.java b/core/src/test/java/org/acegisecurity/context/ITargetObject.java new file mode 100644 index 0000000000..6e61727b49 --- /dev/null +++ b/core/src/test/java/org/acegisecurity/context/ITargetObject.java @@ -0,0 +1,28 @@ +/* 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.context; + +/** + * Represents the interface of a secured object. + * + * @author Ben Alex + * @version $Id$ + */ +public interface ITargetObject { + //~ Methods ================================================================ + + public String makeUpperCase(String input); +} diff --git a/core/src/test/java/org/acegisecurity/context/SecureContextImplTests.java b/core/src/test/java/org/acegisecurity/context/SecureContextImplTests.java new file mode 100644 index 0000000000..80617ceffb --- /dev/null +++ b/core/src/test/java/org/acegisecurity/context/SecureContextImplTests.java @@ -0,0 +1,82 @@ +/* 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.context; + +import junit.framework.TestCase; + +import net.sf.acegisecurity.Authentication; +import net.sf.acegisecurity.providers.UsernamePasswordAuthenticationToken; + + +/** + * Tests {@link SecureContextImpl}. + * + * @author Ben Alex + * @version $Id$ + */ +public class SecureContextImplTests extends TestCase { + //~ Constructors =========================================================== + + public SecureContextImplTests() { + super(); + } + + public SecureContextImplTests(String arg0) { + super(arg0); + } + + //~ Methods ================================================================ + + public final void setUp() throws Exception { + super.setUp(); + } + + public static void main(String[] args) { + junit.textui.TestRunner.run(SecureContextImplTests.class); + } + + public void testSecureContextCorrectOperation() { + SecureContext context = new SecureContextImpl(); + Authentication auth = new UsernamePasswordAuthenticationToken("marissa", + "koala"); + context.setAuthentication(auth); + context.validate(); + assertEquals(auth, context.getAuthentication()); + } + + public void testSecureContextDetectsMissingAuthenticationObject() { + SecureContext context = new SecureContextImpl(); + + try { + context.validate(); + fail("Should have thrown ContextInvalidException"); + } catch (ContextInvalidException expected) { + assertTrue(true); + } + } + + public void testSecureContextDetectsNullAuthenticationObject() { + SecureContext context = new SecureContextImpl(); + context.setAuthentication(null); + + try { + context.validate(); + fail("Should have thrown ContextInvalidException"); + } catch (ContextInvalidException expected) { + assertTrue(true); + } + } +} diff --git a/core/src/test/java/org/acegisecurity/context/TargetObject.java b/core/src/test/java/org/acegisecurity/context/TargetObject.java new file mode 100644 index 0000000000..805e1ce0ba --- /dev/null +++ b/core/src/test/java/org/acegisecurity/context/TargetObject.java @@ -0,0 +1,30 @@ +/* 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.context; + +/** + * Represents a secured object. + * + * @author Ben Alex + * @version $Id$ + */ +public class TargetObject implements ITargetObject { + //~ Methods ================================================================ + + public String makeUpperCase(String input) { + return input.toUpperCase(); + } +} diff --git a/core/src/test/java/org/acegisecurity/providers/AbstractAuthenticationTokenTests.java b/core/src/test/java/org/acegisecurity/providers/AbstractAuthenticationTokenTests.java new file mode 100644 index 0000000000..ad241da0e5 --- /dev/null +++ b/core/src/test/java/org/acegisecurity/providers/AbstractAuthenticationTokenTests.java @@ -0,0 +1,165 @@ +/* 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.providers; + +import junit.framework.TestCase; + +import net.sf.acegisecurity.GrantedAuthority; +import net.sf.acegisecurity.GrantedAuthorityImpl; + + +/** + * Tests {@link AbstractAuthenticationToken}. + * + * @author Ben Alex + * @version $Id$ + */ +public class AbstractAuthenticationTokenTests extends TestCase { + //~ Constructors =========================================================== + + public AbstractAuthenticationTokenTests() { + super(); + } + + public AbstractAuthenticationTokenTests(String arg0) { + super(arg0); + } + + //~ Methods ================================================================ + + public final void setUp() throws Exception { + super.setUp(); + } + + public static void main(String[] args) { + junit.textui.TestRunner.run(AbstractAuthenticationTokenTests.class); + } + + public void testGetters() throws Exception { + MockAuthenticationImpl token = new MockAuthenticationImpl("Test", + "Password", + new GrantedAuthority[] {new GrantedAuthorityImpl("ROLE_ONE"), new GrantedAuthorityImpl( + "ROLE_TWO")}); + assertEquals("Test", token.getPrincipal()); + assertEquals("Password", token.getCredentials()); + } + + public void testObjectsEquals() throws Exception { + MockAuthenticationImpl token1 = new MockAuthenticationImpl("Test", + "Password", + new GrantedAuthority[] {new GrantedAuthorityImpl("ROLE_ONE"), new GrantedAuthorityImpl( + "ROLE_TWO")}); + MockAuthenticationImpl token2 = new MockAuthenticationImpl("Test", + "Password", + new GrantedAuthority[] {new GrantedAuthorityImpl("ROLE_ONE"), new GrantedAuthorityImpl( + "ROLE_TWO")}); + assertEquals(token1, token2); + + MockAuthenticationImpl token3 = new MockAuthenticationImpl("Test", + "Password_Changed", + new GrantedAuthority[] {new GrantedAuthorityImpl("ROLE_ONE"), new GrantedAuthorityImpl( + "ROLE_TWO")}); + assertTrue(!token1.equals(token3)); + + MockAuthenticationImpl token4 = new MockAuthenticationImpl("Test_Changed", + "Password", + new GrantedAuthority[] {new GrantedAuthorityImpl("ROLE_ONE"), new GrantedAuthorityImpl( + "ROLE_TWO")}); + assertTrue(!token1.equals(token4)); + + MockAuthenticationImpl token5 = new MockAuthenticationImpl("Test", + "Password", + new GrantedAuthority[] {new GrantedAuthorityImpl("ROLE_ONE"), new GrantedAuthorityImpl( + "ROLE_TWO_CHANGED")}); + assertTrue(!token1.equals(token5)); + + MockAuthenticationImpl token6 = new MockAuthenticationImpl("Test", + "Password", + new GrantedAuthority[] {new GrantedAuthorityImpl("ROLE_ONE")}); + assertTrue(!token1.equals(token6)); + + MockAuthenticationImpl token7 = new MockAuthenticationImpl("Test", + "Password", null); + assertTrue(!token1.equals(token7)); + assertTrue(!token7.equals(token1)); + + assertTrue(!token1.equals(new Integer(100))); + } + + public void testSetAuthenticated() throws Exception { + MockAuthenticationImpl token = new MockAuthenticationImpl("Test", + "Password", + new GrantedAuthority[] {new GrantedAuthorityImpl("ROLE_ONE"), new GrantedAuthorityImpl( + "ROLE_TWO")}); + assertTrue(!token.isAuthenticated()); + token.setAuthenticated(true); + assertTrue(token.isAuthenticated()); + } + + public void testToStringWithAuthorities() { + MockAuthenticationImpl token = new MockAuthenticationImpl("Test", + "Password", + new GrantedAuthority[] {new GrantedAuthorityImpl("ROLE_ONE"), new GrantedAuthorityImpl( + "ROLE_TWO")}); + assertTrue(token.toString().lastIndexOf("ROLE_TWO") != -1); + } + + public void testToStringWithNullAuthorities() { + MockAuthenticationImpl token = new MockAuthenticationImpl("Test", + "Password", null); + assertTrue(token.toString().lastIndexOf("Not granted any authorities") != -1); + } + + //~ Inner Classes ========================================================== + + private class MockAuthenticationImpl extends AbstractAuthenticationToken { + private Object credentials; + private Object principal; + private GrantedAuthority[] authorities; + private boolean authenticated = false; + + public MockAuthenticationImpl(Object principal, Object credentials, + GrantedAuthority[] authorities) { + this.principal = principal; + this.credentials = credentials; + this.authorities = authorities; + } + + private MockAuthenticationImpl() { + super(); + } + + public void setAuthenticated(boolean isAuthenticated) { + this.authenticated = isAuthenticated; + } + + public boolean isAuthenticated() { + return this.authenticated; + } + + public GrantedAuthority[] getAuthorities() { + return this.authorities; + } + + public Object getCredentials() { + return this.credentials; + } + + public Object getPrincipal() { + return this.principal; + } + } +} diff --git a/core/src/test/java/org/acegisecurity/providers/ProviderManagerTests.java b/core/src/test/java/org/acegisecurity/providers/ProviderManagerTests.java new file mode 100644 index 0000000000..475f40130e --- /dev/null +++ b/core/src/test/java/org/acegisecurity/providers/ProviderManagerTests.java @@ -0,0 +1,171 @@ +/* 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.providers; + +import junit.framework.TestCase; + +import net.sf.acegisecurity.Authentication; +import net.sf.acegisecurity.AuthenticationException; +import net.sf.acegisecurity.AuthenticationServiceException; +import net.sf.acegisecurity.GrantedAuthority; +import net.sf.acegisecurity.GrantedAuthorityImpl; + +import java.util.List; +import java.util.Vector; + + +/** + * Tests {@link ProviderManager}. + * + * @author Ben Alex + * @version $Id$ + */ +public class ProviderManagerTests extends TestCase { + //~ Constructors =========================================================== + + public ProviderManagerTests() { + super(); + } + + public ProviderManagerTests(String arg0) { + super(arg0); + } + + //~ Methods ================================================================ + + public final void setUp() throws Exception { + super.setUp(); + } + + public static void main(String[] args) { + junit.textui.TestRunner.run(ProviderManagerTests.class); + } + + public void testAuthenticationFails() throws Exception { + UsernamePasswordAuthenticationToken token = new UsernamePasswordAuthenticationToken("Test", + "Password", + new GrantedAuthority[] {new GrantedAuthorityImpl("ROLE_ONE"), new GrantedAuthorityImpl( + "ROLE_TWO")}); + + ProviderManager mgr = makeProviderManager(); + + try { + mgr.authenticate(token); + fail("Should have thrown ProviderNotFoundException"); + } catch (ProviderNotFoundException expected) { + assertTrue(true); + } + } + + public void testAuthenticationSuccess() { + TestingAuthenticationToken token = new TestingAuthenticationToken("Test", + "Password", + new GrantedAuthority[] {new GrantedAuthorityImpl("ROLE_ONE"), new GrantedAuthorityImpl( + "ROLE_TWO")}); + + ProviderManager mgr = makeProviderManager(); + Authentication result = mgr.authenticate(token); + + if (!(result instanceof TestingAuthenticationToken)) { + fail("Should have returned instance of TestingAuthenticationToken"); + } + + TestingAuthenticationToken castResult = (TestingAuthenticationToken) result; + assertEquals("Test", castResult.getPrincipal()); + assertEquals("Password", castResult.getCredentials()); + assertEquals("ROLE_ONE", castResult.getAuthorities()[0].getAuthority()); + assertEquals("ROLE_TWO", castResult.getAuthorities()[1].getAuthority()); + } + + public void testStartupFailsIfProviderListDoesNotContainingProviders() + throws Exception { + List providers = new Vector(); + providers.add("THIS_IS_NOT_A_PROVIDER"); + + ProviderManager mgr = new ProviderManager(); + + try { + mgr.setProviders(providers); + fail("Should have thrown IllegalArgumentException"); + } catch (IllegalArgumentException expected) { + assertTrue(true); + } + } + + public void testStartupFailsIfProviderListNotSet() + throws Exception { + ProviderManager mgr = new ProviderManager(); + + try { + mgr.afterPropertiesSet(); + fail("Should have thrown IllegalArgumentException"); + } catch (IllegalArgumentException expected) { + assertTrue(true); + } + } + + public void testStartupFailsIfProviderListNull() throws Exception { + ProviderManager mgr = new ProviderManager(); + + try { + mgr.setProviders(null); + fail("Should have thrown IllegalArgumentException"); + } catch (IllegalArgumentException expected) { + assertTrue(true); + } + } + + public void testSuccessfulStartup() throws Exception { + ProviderManager mgr = makeProviderManager(); + mgr.afterPropertiesSet(); + assertTrue(true); + assertEquals(1, mgr.getProviders().size()); + } + + private ProviderManager makeProviderManager() { + MockProvider provider1 = new MockProvider(); + List providers = new Vector(); + providers.add(provider1); + + ProviderManager mgr = new ProviderManager(); + mgr.setProviders(providers); + + return mgr; + } + + //~ Inner Classes ========================================================== + + private class MockProvider implements AuthenticationProvider { + public Authentication authenticate(Authentication authentication) + throws AuthenticationException { + if (supports(authentication.getClass())) { + return authentication; + } else { + throw new AuthenticationServiceException( + "Don't support this class"); + } + } + + public boolean supports(Class authentication) { + if (TestingAuthenticationToken.class.isAssignableFrom( + authentication)) { + return true; + } else { + return false; + } + } + } +} diff --git a/core/src/test/java/org/acegisecurity/providers/TestingAuthenticationProviderTests.java b/core/src/test/java/org/acegisecurity/providers/TestingAuthenticationProviderTests.java new file mode 100644 index 0000000000..4179c463d0 --- /dev/null +++ b/core/src/test/java/org/acegisecurity/providers/TestingAuthenticationProviderTests.java @@ -0,0 +1,76 @@ +/* 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.providers; + +import junit.framework.TestCase; + +import net.sf.acegisecurity.Authentication; +import net.sf.acegisecurity.GrantedAuthority; +import net.sf.acegisecurity.GrantedAuthorityImpl; + + +/** + * Tests {@link TestingAuthenticationProvider}. + * + * @author Ben Alex + * @version $Id$ + */ +public class TestingAuthenticationProviderTests extends TestCase { + //~ Constructors =========================================================== + + public TestingAuthenticationProviderTests() { + super(); + } + + public TestingAuthenticationProviderTests(String arg0) { + super(arg0); + } + + //~ Methods ================================================================ + + public final void setUp() throws Exception { + super.setUp(); + } + + public static void main(String[] args) { + junit.textui.TestRunner.run(TestingAuthenticationProviderTests.class); + } + + public void testAuthenticates() { + TestingAuthenticationProvider provider = new TestingAuthenticationProvider(); + TestingAuthenticationToken token = new TestingAuthenticationToken("Test", + "Password", + new GrantedAuthority[] {new GrantedAuthorityImpl("ROLE_ONE"), new GrantedAuthorityImpl( + "ROLE_TWO")}); + Authentication result = provider.authenticate(token); + + if (!(result instanceof TestingAuthenticationToken)) { + fail("Should have returned instance of TestingAuthenticationToken"); + } + + TestingAuthenticationToken castResult = (TestingAuthenticationToken) result; + assertEquals("Test", castResult.getPrincipal()); + assertEquals("Password", castResult.getCredentials()); + assertEquals("ROLE_ONE", castResult.getAuthorities()[0].getAuthority()); + assertEquals("ROLE_TWO", castResult.getAuthorities()[1].getAuthority()); + } + + public void testSupports() { + TestingAuthenticationProvider provider = new TestingAuthenticationProvider(); + assertTrue(provider.supports(TestingAuthenticationToken.class)); + assertTrue(!provider.supports(String.class)); + } +} diff --git a/core/src/test/java/org/acegisecurity/providers/TestingAuthenticationTokenTests.java b/core/src/test/java/org/acegisecurity/providers/TestingAuthenticationTokenTests.java new file mode 100644 index 0000000000..edd6de76be --- /dev/null +++ b/core/src/test/java/org/acegisecurity/providers/TestingAuthenticationTokenTests.java @@ -0,0 +1,78 @@ +/* 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.providers; + +import junit.framework.TestCase; + +import net.sf.acegisecurity.GrantedAuthority; +import net.sf.acegisecurity.GrantedAuthorityImpl; + + +/** + * Tests {@link TestingAuthenticationToken}. + * + * @author Ben Alex + * @version $Id$ + */ +public class TestingAuthenticationTokenTests extends TestCase { + //~ Constructors =========================================================== + + public TestingAuthenticationTokenTests() { + super(); + } + + public TestingAuthenticationTokenTests(String arg0) { + super(arg0); + } + + //~ Methods ================================================================ + + public final void setUp() throws Exception { + super.setUp(); + } + + public static void main(String[] args) { + junit.textui.TestRunner.run(TestingAuthenticationTokenTests.class); + } + + public void testAuthenticated() { + TestingAuthenticationToken token = new TestingAuthenticationToken("Test", + "Password", null); + assertTrue(!token.isAuthenticated()); + token.setAuthenticated(true); + assertTrue(token.isAuthenticated()); + } + + public void testGetters() { + TestingAuthenticationToken token = new TestingAuthenticationToken("Test", + "Password", + new GrantedAuthority[] {new GrantedAuthorityImpl("ROLE_ONE"), new GrantedAuthorityImpl( + "ROLE_TWO")}); + assertEquals("Test", token.getPrincipal()); + assertEquals("Password", token.getCredentials()); + assertEquals("ROLE_ONE", token.getAuthorities()[0].getAuthority()); + assertEquals("ROLE_TWO", token.getAuthorities()[1].getAuthority()); + } + + public void testNoArgConstructor() { + try { + new TestingAuthenticationToken(); + fail("Should have thrown IllegalArgumentException"); + } catch (IllegalArgumentException expected) { + assertTrue(true); + } + } +} diff --git a/core/src/test/java/org/acegisecurity/providers/UsernamePasswordAuthenticationTokenTests.java b/core/src/test/java/org/acegisecurity/providers/UsernamePasswordAuthenticationTokenTests.java new file mode 100644 index 0000000000..4f0ba485cd --- /dev/null +++ b/core/src/test/java/org/acegisecurity/providers/UsernamePasswordAuthenticationTokenTests.java @@ -0,0 +1,91 @@ +/* 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.providers; + +import junit.framework.TestCase; + +import net.sf.acegisecurity.GrantedAuthority; +import net.sf.acegisecurity.GrantedAuthorityImpl; + + +/** + * Tests {@link UsernamePasswordAuthenticationToken}. + * + * @author Ben Alex + * @version $Id$ + */ +public class UsernamePasswordAuthenticationTokenTests extends TestCase { + //~ Constructors =========================================================== + + public UsernamePasswordAuthenticationTokenTests() { + super(); + } + + public UsernamePasswordAuthenticationTokenTests(String arg0) { + super(arg0); + } + + //~ Methods ================================================================ + + public final void setUp() throws Exception { + super.setUp(); + } + + public static void main(String[] args) { + junit.textui.TestRunner.run(UsernamePasswordAuthenticationTokenTests.class); + } + + public void testAuthenticated() { + UsernamePasswordAuthenticationToken token = new UsernamePasswordAuthenticationToken("Test", + "Password", null); + assertTrue(!token.isAuthenticated()); + token.setAuthenticated(true); + assertTrue(token.isAuthenticated()); + } + + public void testGetters() { + UsernamePasswordAuthenticationToken token = new UsernamePasswordAuthenticationToken("Test", + "Password", + new GrantedAuthority[] {new GrantedAuthorityImpl("ROLE_ONE"), new GrantedAuthorityImpl( + "ROLE_TWO")}); + assertEquals("Test", token.getPrincipal()); + assertEquals("Password", token.getCredentials()); + assertEquals("ROLE_ONE", token.getAuthorities()[0].getAuthority()); + assertEquals("ROLE_TWO", token.getAuthorities()[1].getAuthority()); + } + + public void testNewAuthorities() { + UsernamePasswordAuthenticationToken token = new UsernamePasswordAuthenticationToken("Test", + "Password", null); + assertEquals("Test", token.getPrincipal()); + assertEquals("Password", token.getCredentials()); + assertEquals(null, token.getAuthorities()); + + token.setAuthorities(new GrantedAuthority[] {new GrantedAuthorityImpl( + "ROLE_ONE"), new GrantedAuthorityImpl("ROLE_TWO")}); + assertEquals("ROLE_ONE", token.getAuthorities()[0].getAuthority()); + assertEquals("ROLE_TWO", token.getAuthorities()[1].getAuthority()); + } + + public void testNoArgConstructor() { + try { + new UsernamePasswordAuthenticationToken(); + fail("Should have thrown IllegalArgumentException"); + } catch (IllegalArgumentException expected) { + assertTrue(true); + } + } +} diff --git a/core/src/test/java/org/acegisecurity/providers/dao/DaoAuthenticationProviderTests.java b/core/src/test/java/org/acegisecurity/providers/dao/DaoAuthenticationProviderTests.java new file mode 100644 index 0000000000..a722193e65 --- /dev/null +++ b/core/src/test/java/org/acegisecurity/providers/dao/DaoAuthenticationProviderTests.java @@ -0,0 +1,266 @@ +/* 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.providers.dao; + +import junit.framework.TestCase; + +import net.sf.acegisecurity.Authentication; +import net.sf.acegisecurity.AuthenticationServiceException; +import net.sf.acegisecurity.BadCredentialsException; +import net.sf.acegisecurity.DisabledException; +import net.sf.acegisecurity.GrantedAuthority; +import net.sf.acegisecurity.GrantedAuthorityImpl; +import net.sf.acegisecurity.providers.TestingAuthenticationToken; +import net.sf.acegisecurity.providers.UsernamePasswordAuthenticationToken; + +import org.springframework.dao.DataAccessException; +import org.springframework.dao.DataRetrievalFailureException; + + +/** + * Tests {@link DaoAuthenticationProvider}. + * + * @author Ben Alex + * @version $Id$ + */ +public class DaoAuthenticationProviderTests extends TestCase { + //~ Constructors =========================================================== + + public DaoAuthenticationProviderTests() { + super(); + } + + public DaoAuthenticationProviderTests(String arg0) { + super(arg0); + } + + //~ Methods ================================================================ + + public final void setUp() throws Exception { + super.setUp(); + } + + public static void main(String[] args) { + junit.textui.TestRunner.run(DaoAuthenticationProviderTests.class); + } + + public void testAuthenticateFailsForIncorrectPasswordCase() { + UsernamePasswordAuthenticationToken token = new UsernamePasswordAuthenticationToken("marissa", + "KOala"); + + DaoAuthenticationProvider provider = new DaoAuthenticationProvider(); + provider.setAuthenticationDao(new MockAuthenticationDaoUserMarissa()); + assertTrue(!provider.isIgnorePasswordCase()); // default + + try { + provider.authenticate(token); + fail("Should have thrown BadCredentialsException"); + } catch (BadCredentialsException expected) { + assertTrue(true); + } + } + + public void testAuthenticateFailsIfUserDisabled() { + UsernamePasswordAuthenticationToken token = new UsernamePasswordAuthenticationToken("peter", + "opal"); + + DaoAuthenticationProvider provider = new DaoAuthenticationProvider(); + provider.setAuthenticationDao(new MockAuthenticationDaoUserPeter()); + + try { + provider.authenticate(token); + fail("Should have thrown DisabledException"); + } catch (DisabledException expected) { + assertTrue(true); + } + } + + public void testAuthenticateFailsWhenAuthenticationDaoHasBackendFailure() { + UsernamePasswordAuthenticationToken token = new UsernamePasswordAuthenticationToken("marissa", + "koala"); + + DaoAuthenticationProvider provider = new DaoAuthenticationProvider(); + provider.setAuthenticationDao(new MockAuthenticationDaoSimulateBackendError()); + + try { + provider.authenticate(token); + fail("Should have thrown AuthenticationServiceException"); + } catch (AuthenticationServiceException expected) { + assertTrue(true); + } + } + + public void testAuthenticateFailsWithInvalidPassword() { + UsernamePasswordAuthenticationToken token = new UsernamePasswordAuthenticationToken("marissa", + "INVALID_PASSWORD"); + + DaoAuthenticationProvider provider = new DaoAuthenticationProvider(); + provider.setAuthenticationDao(new MockAuthenticationDaoUserMarissa()); + + try { + provider.authenticate(token); + fail("Should have thrown BadCredentialsException"); + } catch (BadCredentialsException expected) { + assertTrue(true); + } + } + + public void testAuthenticateFailsWithInvalidUsername() { + UsernamePasswordAuthenticationToken token = new UsernamePasswordAuthenticationToken("INVALID_USER", + "koala"); + + DaoAuthenticationProvider provider = new DaoAuthenticationProvider(); + provider.setAuthenticationDao(new MockAuthenticationDaoUserMarissa()); + + try { + provider.authenticate(token); + fail("Should have thrown BadCredentialsException"); + } catch (BadCredentialsException expected) { + assertTrue(true); + } + } + + public void testAuthenticateFailsWithMixedCaseUsernameIfDefaultChanged() { + UsernamePasswordAuthenticationToken token = new UsernamePasswordAuthenticationToken("MaRiSSA", + "koala"); + + DaoAuthenticationProvider provider = new DaoAuthenticationProvider(); + provider.setAuthenticationDao(new MockAuthenticationDaoUserMarissa()); + assertTrue(provider.isIgnoreUsernameCase()); // default + provider.setIgnoreUsernameCase(false); + assertTrue(!provider.isIgnoreUsernameCase()); // changed + + try { + provider.authenticate(token); + fail("Should have thrown BadCredentialsException"); + } catch (BadCredentialsException expected) { + assertTrue(true); + } + } + + public void testAuthenticateSuccessfulWithMixedCaseIfDefaultChanged() { + UsernamePasswordAuthenticationToken token = new UsernamePasswordAuthenticationToken("marissa", + "KOAla"); + + DaoAuthenticationProvider provider = new DaoAuthenticationProvider(); + provider.setAuthenticationDao(new MockAuthenticationDaoUserMarissa()); + assertTrue(!provider.isIgnorePasswordCase()); // default + provider.setIgnorePasswordCase(true); + assertTrue(provider.isIgnorePasswordCase()); // changed + + Authentication result = provider.authenticate(token); + assertEquals("marissa", result.getPrincipal().toString()); + } + + public void testAuthenticateSuccessfulWithMixedCaseUsername() { + UsernamePasswordAuthenticationToken token = new UsernamePasswordAuthenticationToken("MaRiSSA", + "koala"); + + DaoAuthenticationProvider provider = new DaoAuthenticationProvider(); + provider.setAuthenticationDao(new MockAuthenticationDaoUserMarissa()); + assertTrue(provider.isIgnoreUsernameCase()); // default + + Authentication result = provider.authenticate(token); + assertEquals("marissa", result.getPrincipal().toString()); + } + + public void testAuthenticates() { + UsernamePasswordAuthenticationToken token = new UsernamePasswordAuthenticationToken("marissa", + "koala"); + + DaoAuthenticationProvider provider = new DaoAuthenticationProvider(); + provider.setAuthenticationDao(new MockAuthenticationDaoUserMarissa()); + + Authentication result = provider.authenticate(token); + + if (!(result instanceof UsernamePasswordAuthenticationToken)) { + fail( + "Should have returned instance of UsernamePasswordAuthenticationToken"); + } + + UsernamePasswordAuthenticationToken castResult = (UsernamePasswordAuthenticationToken) result; + assertEquals("marissa", castResult.getPrincipal()); + assertEquals("koala", castResult.getCredentials()); + assertEquals("ROLE_ONE", castResult.getAuthorities()[0].getAuthority()); + assertEquals("ROLE_TWO", castResult.getAuthorities()[1].getAuthority()); + } + + public void testStartupFailsIfNoAuthenticationDao() + throws Exception { + DaoAuthenticationProvider provider = new DaoAuthenticationProvider(); + + try { + provider.afterPropertiesSet(); + fail("Should have thrown IllegalArgumentException"); + } catch (IllegalArgumentException expected) { + assertTrue(true); + } + } + + public void testStartupSuccess() throws Exception { + DaoAuthenticationProvider provider = new DaoAuthenticationProvider(); + AuthenticationDao dao = new MockAuthenticationDaoUserMarissa(); + provider.setAuthenticationDao(dao); + assertEquals(dao, provider.getAuthenticationDao()); + provider.afterPropertiesSet(); + assertTrue(true); + } + + public void testSupports() { + DaoAuthenticationProvider provider = new DaoAuthenticationProvider(); + assertTrue(provider.supports(UsernamePasswordAuthenticationToken.class)); + assertTrue(!provider.supports(TestingAuthenticationToken.class)); + } + + //~ Inner Classes ========================================================== + + private class MockAuthenticationDaoSimulateBackendError + implements AuthenticationDao { + public User loadUserByUsername(String username) + throws UsernameNotFoundException, DataAccessException { + throw new DataRetrievalFailureException( + "This mock simulator is designed to fail"); + } + } + + private class MockAuthenticationDaoUserMarissa implements AuthenticationDao { + public User loadUserByUsername(String username) + throws UsernameNotFoundException, DataAccessException { + if ("marissa".equals(username.toLowerCase())) { + return new User("marissa", "koala", true, + new GrantedAuthority[] {new GrantedAuthorityImpl("ROLE_ONE"), new GrantedAuthorityImpl( + "ROLE_TWO")}); + } else { + throw new UsernameNotFoundException("Could not find: " + + username); + } + } + } + + private class MockAuthenticationDaoUserPeter implements AuthenticationDao { + public User loadUserByUsername(String username) + throws UsernameNotFoundException, DataAccessException { + if ("peter".equals(username.toLowerCase())) { + return new User("peter", "opal", false, + new GrantedAuthority[] {new GrantedAuthorityImpl("ROLE_ONE"), new GrantedAuthorityImpl( + "ROLE_TWO")}); + } else { + throw new UsernameNotFoundException("Could not find: " + + username); + } + } + } +} diff --git a/core/src/test/java/org/acegisecurity/providers/dao/UserTests.java b/core/src/test/java/org/acegisecurity/providers/dao/UserTests.java new file mode 100644 index 0000000000..d247fe36a5 --- /dev/null +++ b/core/src/test/java/org/acegisecurity/providers/dao/UserTests.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.providers.dao; + +import junit.framework.TestCase; + +import net.sf.acegisecurity.GrantedAuthority; +import net.sf.acegisecurity.GrantedAuthorityImpl; + + +/** + * Tests {@link User}. + * + * @author Ben Alex + * @version $Id$ + */ +public class UserTests extends TestCase { + //~ Constructors =========================================================== + + public UserTests() { + super(); + } + + public UserTests(String arg0) { + super(arg0); + } + + //~ Methods ================================================================ + + public final void setUp() throws Exception { + super.setUp(); + } + + public static void main(String[] args) { + junit.textui.TestRunner.run(UserTests.class); + } + + public void testNoArgsConstructor() throws Exception { + User user = new User(); + assertTrue(true); + } + + public void testNullValuesRejected() throws Exception { + try { + User user = new User(null, "koala", true, + new GrantedAuthority[] {new GrantedAuthorityImpl("ROLE_ONE"), new GrantedAuthorityImpl( + "ROLE_TWO")}); + fail("Should have thrown IllegalArgumentException"); + } catch (IllegalArgumentException expected) { + assertTrue(true); + } + + try { + User user = new User("marissa", null, true, + new GrantedAuthority[] {new GrantedAuthorityImpl("ROLE_ONE"), new GrantedAuthorityImpl( + "ROLE_TWO")}); + fail("Should have thrown IllegalArgumentException"); + } catch (IllegalArgumentException expected) { + assertTrue(true); + } + + try { + User user = new User("marissa", "koala", true, null); + fail("Should have thrown IllegalArgumentException"); + } catch (IllegalArgumentException expected) { + assertTrue(true); + } + } + + public void testUserGettersSetter() throws Exception { + User user = new User("marissa", "koala", true, + new GrantedAuthority[] {new GrantedAuthorityImpl("ROLE_ONE"), new GrantedAuthorityImpl( + "ROLE_TWO")}); + assertEquals("marissa", user.getUsername()); + assertEquals("koala", user.getPassword()); + assertTrue(user.isEnabled()); + assertEquals(new GrantedAuthorityImpl("ROLE_ONE"), + user.getAuthorities()[0]); + assertEquals(new GrantedAuthorityImpl("ROLE_TWO"), + user.getAuthorities()[1]); + } + + public void testUserIsEnabled() throws Exception { + User user = new User("marissa", "koala", false, + new GrantedAuthority[] {new GrantedAuthorityImpl("ROLE_ONE"), new GrantedAuthorityImpl( + "ROLE_TWO")}); + assertTrue(!user.isEnabled()); + } +} diff --git a/core/src/test/java/org/acegisecurity/providers/dao/memory/UserAttributeEditorTests.java b/core/src/test/java/org/acegisecurity/providers/dao/memory/UserAttributeEditorTests.java new file mode 100644 index 0000000000..ca01016c4a --- /dev/null +++ b/core/src/test/java/org/acegisecurity/providers/dao/memory/UserAttributeEditorTests.java @@ -0,0 +1,135 @@ +/* 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.providers.dao.memory; + +import junit.framework.TestCase; + + +/** + * Tests {@link UserAttributeEditor} and associated {@link + * UserAttributeDefinition}. + * + * @author Ben Alex + * @version $Id$ + */ +public class UserAttributeEditorTests extends TestCase { + //~ Constructors =========================================================== + + public UserAttributeEditorTests() { + super(); + } + + public UserAttributeEditorTests(String arg0) { + super(arg0); + } + + //~ Methods ================================================================ + + public final void setUp() throws Exception { + super.setUp(); + } + + public static void main(String[] args) { + junit.textui.TestRunner.run(UserAttributeEditorTests.class); + } + + public void testCorrectOperationWithoutEnabledDisabledKeyword() { + UserAttributeEditor editor = new UserAttributeEditor(); + editor.setAsText("password,ROLE_ONE,ROLE_TWO"); + + UserAttributeDefinition user = (UserAttributeDefinition) editor + .getValue(); + assertTrue(user.isValid()); + assertTrue(user.isEnabled()); // default + assertEquals("password", user.getPassword()); + assertEquals(2, user.getAuthorities().length); + assertEquals("ROLE_ONE", user.getAuthorities()[0].getAuthority()); + assertEquals("ROLE_TWO", user.getAuthorities()[1].getAuthority()); + } + + public void testDisabledKeyword() { + UserAttributeEditor editor = new UserAttributeEditor(); + editor.setAsText("password,disabled,ROLE_ONE,ROLE_TWO"); + + UserAttributeDefinition user = (UserAttributeDefinition) editor + .getValue(); + assertTrue(user.isValid()); + assertTrue(!user.isEnabled()); + assertEquals("password", user.getPassword()); + assertEquals(2, user.getAuthorities().length); + assertEquals("ROLE_ONE", user.getAuthorities()[0].getAuthority()); + assertEquals("ROLE_TWO", user.getAuthorities()[1].getAuthority()); + } + + public void testEmptyStringReturnsNull() { + UserAttributeEditor editor = new UserAttributeEditor(); + editor.setAsText(""); + + UserAttributeDefinition user = (UserAttributeDefinition) editor + .getValue(); + assertTrue(user == null); + } + + public void testEnabledKeyword() { + UserAttributeEditor editor = new UserAttributeEditor(); + editor.setAsText("password,ROLE_ONE,enabled,ROLE_TWO"); + + UserAttributeDefinition user = (UserAttributeDefinition) editor + .getValue(); + assertTrue(user.isValid()); + assertTrue(user.isEnabled()); + assertEquals("password", user.getPassword()); + assertEquals(2, user.getAuthorities().length); + assertEquals("ROLE_ONE", user.getAuthorities()[0].getAuthority()); + assertEquals("ROLE_TWO", user.getAuthorities()[1].getAuthority()); + } + + public void testMalformedStringReturnsNull() { + UserAttributeEditor editor = new UserAttributeEditor(); + editor.setAsText("MALFORMED_STRING"); + + UserAttributeDefinition user = (UserAttributeDefinition) editor + .getValue(); + assertTrue(user == null); + } + + public void testNoPasswordOrRolesReturnsNull() { + UserAttributeEditor editor = new UserAttributeEditor(); + editor.setAsText("disabled"); + + UserAttributeDefinition user = (UserAttributeDefinition) editor + .getValue(); + assertTrue(user == null); + } + + public void testNoRolesReturnsNull() { + UserAttributeEditor editor = new UserAttributeEditor(); + editor.setAsText("password,enabled"); + + UserAttributeDefinition user = (UserAttributeDefinition) editor + .getValue(); + assertTrue(user == null); + } + + public void testNullReturnsNull() { + UserAttributeEditor editor = new UserAttributeEditor(); + editor.setAsText(null); + + UserAttributeDefinition user = (UserAttributeDefinition) editor + .getValue(); + assertTrue(user == null); + } +} diff --git a/core/src/test/java/org/acegisecurity/providers/dao/memory/UserMapEditorTests.java b/core/src/test/java/org/acegisecurity/providers/dao/memory/UserMapEditorTests.java new file mode 100644 index 0000000000..b29d00fc78 --- /dev/null +++ b/core/src/test/java/org/acegisecurity/providers/dao/memory/UserMapEditorTests.java @@ -0,0 +1,103 @@ +/* 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.providers.dao.memory; + +import junit.framework.TestCase; + + +/** + * Tests {@link UserMapEditor}. + * + * @author Ben Alex + * @version $Id$ + */ +public class UserMapEditorTests extends TestCase { + //~ Constructors =========================================================== + + public UserMapEditorTests() { + super(); + } + + public UserMapEditorTests(String arg0) { + super(arg0); + } + + //~ Methods ================================================================ + + public final void setUp() throws Exception { + super.setUp(); + } + + public static void main(String[] args) { + junit.textui.TestRunner.run(UserMapEditorTests.class); + } + + public void testConvertedIntoUserSuccessfullyWhenDisabled() { + UserMapEditor editor = new UserMapEditor(); + editor.setAsText("marissa=koala,ROLE_ONE,ROLE_TWO,disabled"); + + UserMap map = (UserMap) editor.getValue(); + assertTrue(!map.getUser("marissa").isEnabled()); + } + + public void testConvertedIntoUserSuccessfullyWhenEnabled() { + UserMapEditor editor = new UserMapEditor(); + editor.setAsText("marissa=koala,ROLE_ONE,ROLE_TWO"); + + UserMap map = (UserMap) editor.getValue(); + assertEquals("marissa", map.getUser("marissa").getUsername()); + assertEquals("koala", map.getUser("marissa").getPassword()); + assertEquals("ROLE_ONE", + map.getUser("marissa").getAuthorities()[0].getAuthority()); + assertEquals("ROLE_TWO", + map.getUser("marissa").getAuthorities()[1].getAuthority()); + assertTrue(map.getUser("marissa").isEnabled()); + } + + public void testEmptyStringReturnsEmptyMap() { + UserMapEditor editor = new UserMapEditor(); + editor.setAsText(""); + + UserMap map = (UserMap) editor.getValue(); + assertEquals(0, map.getUserCount()); + } + + public void testMalformedStringReturnsEmptyMap() { + UserMapEditor editor = new UserMapEditor(); + editor.setAsText("MALFORMED_STRING"); + + UserMap map = (UserMap) editor.getValue(); + assertEquals(0, map.getUserCount()); + } + + public void testMultiUserParsing() { + UserMapEditor editor = new UserMapEditor(); + editor.setAsText( + "marissa=koala,ROLE_ONE,ROLE_TWO,enabled\r\nscott=wombat,ROLE_ONE,ROLE_TWO,enabled"); + + UserMap map = (UserMap) editor.getValue(); + assertEquals("marissa", map.getUser("marissa").getUsername()); + assertEquals("scott", map.getUser("scott").getUsername()); + } + + public void testNullReturnsEmptyMap() { + UserMapEditor editor = new UserMapEditor(); + editor.setAsText(null); + + UserMap map = (UserMap) editor.getValue(); + assertEquals(0, map.getUserCount()); + } +} diff --git a/core/src/test/java/org/acegisecurity/providers/dao/memory/UserMapTests.java b/core/src/test/java/org/acegisecurity/providers/dao/memory/UserMapTests.java new file mode 100644 index 0000000000..2961e1de30 --- /dev/null +++ b/core/src/test/java/org/acegisecurity/providers/dao/memory/UserMapTests.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.providers.dao.memory; + +import junit.framework.TestCase; + +import net.sf.acegisecurity.GrantedAuthority; +import net.sf.acegisecurity.GrantedAuthorityImpl; +import net.sf.acegisecurity.providers.dao.User; +import net.sf.acegisecurity.providers.dao.UsernameNotFoundException; + + +/** + * Tests {@link UserMap}. + * + * @author Ben Alex + * @version $Id$ + */ +public class UserMapTests extends TestCase { + //~ Constructors =========================================================== + + public UserMapTests() { + super(); + } + + public UserMapTests(String arg0) { + super(arg0); + } + + //~ Methods ================================================================ + + public final void setUp() throws Exception { + super.setUp(); + } + + public static void main(String[] args) { + junit.textui.TestRunner.run(UserMapTests.class); + } + + public void testAddAndRetrieveUser() { + User marissa = new User("marissa", "koala", true, + new GrantedAuthority[] {new GrantedAuthorityImpl("ROLE_ONE"), new GrantedAuthorityImpl( + "ROLE_TWO")}); + User scott = new User("scott", "wombat", true, + new GrantedAuthority[] {new GrantedAuthorityImpl("ROLE_ONE"), new GrantedAuthorityImpl( + "ROLE_THREE")}); + User peter = new User("peter", "opal", true, + new GrantedAuthority[] {new GrantedAuthorityImpl("ROLE_ONE"), new GrantedAuthorityImpl( + "ROLE_FOUR")}); + UserMap map = new UserMap(); + map.addUser(marissa); + map.addUser(scott); + map.addUser(peter); + assertEquals(3, map.getUserCount()); + + assertEquals(marissa, map.getUser("marissa")); + assertEquals(scott, map.getUser("scott")); + assertEquals(peter, map.getUser("peter")); + } + + public void testNullUserCannotBeAdded() { + UserMap map = new UserMap(); + assertEquals(0, map.getUserCount()); + + try { + map.addUser(null); + fail("Should have thrown IllegalArgumentException"); + } catch (IllegalArgumentException expected) { + assertTrue(true); + } + } + + public void testUnknownUserIsNotRetrieved() { + User marissa = new User("marissa", "koala", true, + new GrantedAuthority[] {new GrantedAuthorityImpl("ROLE_ONE"), new GrantedAuthorityImpl( + "ROLE_TWO")}); + UserMap map = new UserMap(); + assertEquals(0, map.getUserCount()); + map.addUser(marissa); + assertEquals(1, map.getUserCount()); + + try { + map.getUser("scott"); + fail("Should have thrown UsernameNotFoundException"); + } catch (UsernameNotFoundException expected) { + assertTrue(true); + } + } +} diff --git a/core/src/test/java/org/acegisecurity/runas/RunAsImplAuthenticationProviderTests.java b/core/src/test/java/org/acegisecurity/runas/RunAsImplAuthenticationProviderTests.java new file mode 100644 index 0000000000..75447c0752 --- /dev/null +++ b/core/src/test/java/org/acegisecurity/runas/RunAsImplAuthenticationProviderTests.java @@ -0,0 +1,113 @@ +/* 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.runas; + +import junit.framework.TestCase; + +import net.sf.acegisecurity.Authentication; +import net.sf.acegisecurity.BadCredentialsException; +import net.sf.acegisecurity.GrantedAuthority; +import net.sf.acegisecurity.GrantedAuthorityImpl; +import net.sf.acegisecurity.providers.TestingAuthenticationToken; +import net.sf.acegisecurity.providers.UsernamePasswordAuthenticationToken; + + +/** + * Tests {@link RunAsImplAuthenticationProvider}. + * + * @author Ben Alex + * @version $Id$ + */ +public class RunAsImplAuthenticationProviderTests extends TestCase { + //~ Constructors =========================================================== + + public RunAsImplAuthenticationProviderTests() { + super(); + } + + public RunAsImplAuthenticationProviderTests(String arg0) { + super(arg0); + } + + //~ Methods ================================================================ + + public final void setUp() throws Exception { + super.setUp(); + } + + public static void main(String[] args) { + junit.textui.TestRunner.run(RunAsImplAuthenticationProviderTests.class); + } + + public void testAuthenticationFailDueToWrongKey() { + RunAsUserToken token = new RunAsUserToken("WRONG_PASSWORD", "Test", + "Password", + new GrantedAuthority[] {new GrantedAuthorityImpl("ROLE_ONE"), new GrantedAuthorityImpl( + "ROLE_TWO")}, UsernamePasswordAuthenticationToken.class); + RunAsImplAuthenticationProvider provider = new RunAsImplAuthenticationProvider(); + provider.setKey("hello_world"); + + try { + provider.authenticate(token); + fail("Should have thrown BadCredentialsException"); + } catch (BadCredentialsException expected) { + assertTrue(true); + } + } + + public void testAuthenticationSuccess() { + RunAsUserToken token = new RunAsUserToken("my_password", "Test", + "Password", + new GrantedAuthority[] {new GrantedAuthorityImpl("ROLE_ONE"), new GrantedAuthorityImpl( + "ROLE_TWO")}, UsernamePasswordAuthenticationToken.class); + RunAsImplAuthenticationProvider provider = new RunAsImplAuthenticationProvider(); + provider.setKey("my_password"); + + Authentication result = provider.authenticate(token); + + if (!(result instanceof RunAsUserToken)) { + fail("Should have returned RunAsUserToken"); + } + + RunAsUserToken resultCast = (RunAsUserToken) result; + assertEquals("my_password".hashCode(), resultCast.getKeyHash()); + } + + public void testStartupFailsIfNoKey() throws Exception { + RunAsImplAuthenticationProvider provider = new RunAsImplAuthenticationProvider(); + + try { + provider.afterPropertiesSet(); + fail("Should have thrown IllegalArgumentException"); + } catch (IllegalArgumentException expected) { + assertTrue(true); + } + } + + public void testStartupSuccess() throws Exception { + RunAsImplAuthenticationProvider provider = new RunAsImplAuthenticationProvider(); + provider.setKey("hello_world"); + assertEquals("hello_world", provider.getKey()); + provider.afterPropertiesSet(); + assertTrue(true); + } + + public void testSupports() { + RunAsImplAuthenticationProvider provider = new RunAsImplAuthenticationProvider(); + assertTrue(provider.supports(RunAsUserToken.class)); + assertTrue(!provider.supports(TestingAuthenticationToken.class)); + } +} diff --git a/core/src/test/java/org/acegisecurity/runas/RunAsManagerImplTests.java b/core/src/test/java/org/acegisecurity/runas/RunAsManagerImplTests.java new file mode 100644 index 0000000000..d898cf52d8 --- /dev/null +++ b/core/src/test/java/org/acegisecurity/runas/RunAsManagerImplTests.java @@ -0,0 +1,128 @@ +/* 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.runas; + +import junit.framework.TestCase; + +import net.sf.acegisecurity.Authentication; +import net.sf.acegisecurity.ConfigAttributeDefinition; +import net.sf.acegisecurity.GrantedAuthority; +import net.sf.acegisecurity.GrantedAuthorityImpl; +import net.sf.acegisecurity.RunAsManager; +import net.sf.acegisecurity.SecurityConfig; +import net.sf.acegisecurity.providers.UsernamePasswordAuthenticationToken; + + +/** + * Tests {@link RunAsManagerImpl}. + * + * @author Ben Alex + * @version $Id$ + */ +public class RunAsManagerImplTests extends TestCase { + //~ Constructors =========================================================== + + public RunAsManagerImplTests() { + super(); + } + + public RunAsManagerImplTests(String arg0) { + super(arg0); + } + + //~ Methods ================================================================ + + public final void setUp() throws Exception { + super.setUp(); + } + + public static void main(String[] args) { + junit.textui.TestRunner.run(RunAsManagerImplTests.class); + } + + public void testDoesNotReturnAdditionalAuthoritiesIfCalledWithoutARunAsSetting() + throws Exception { + ConfigAttributeDefinition def = new ConfigAttributeDefinition(); + def.addConfigAttribute(new SecurityConfig("SOMETHING_WE_IGNORE")); + + UsernamePasswordAuthenticationToken inputToken = new UsernamePasswordAuthenticationToken("Test", + "Password", + new GrantedAuthority[] {new GrantedAuthorityImpl("ROLE_ONE"), new GrantedAuthorityImpl("ROLE_TWO")}); + + RunAsManagerImpl runAs = new RunAsManagerImpl(); + runAs.setKey("my_password"); + + Authentication resultingToken = runAs.buildRunAs(inputToken, null, def); + assertEquals(null, resultingToken); + } + + public void testReturnsAdditionalGrantedAuthorities() + throws Exception { + ConfigAttributeDefinition def = new ConfigAttributeDefinition(); + def.addConfigAttribute(new SecurityConfig("RUN_AS_SOMETHING")); + + UsernamePasswordAuthenticationToken inputToken = new UsernamePasswordAuthenticationToken("Test", + "Password", + new GrantedAuthority[] {new GrantedAuthorityImpl("ROLE_ONE"), new GrantedAuthorityImpl("ROLE_TWO")}); + + RunAsManagerImpl runAs = new RunAsManagerImpl(); + runAs.setKey("my_password"); + + Authentication resultingToken = runAs.buildRunAs(inputToken, null, def); + + if (!(resultingToken instanceof RunAsUserToken)) { + fail("Should have returned a RunAsUserToken"); + } + + assertEquals(inputToken.getPrincipal(), resultingToken.getPrincipal()); + assertEquals(inputToken.getCredentials(), + resultingToken.getCredentials()); + assertEquals("ROLE_RUN_AS_SOMETHING", + resultingToken.getAuthorities()[0].getAuthority()); + assertEquals("ROLE_ONE", + resultingToken.getAuthorities()[1].getAuthority()); + assertEquals("ROLE_TWO", + resultingToken.getAuthorities()[2].getAuthority()); + + RunAsUserToken resultCast = (RunAsUserToken) resultingToken; + assertEquals("my_password".hashCode(), resultCast.getKeyHash()); + } + + public void testStartupDetectsMissingKey() throws Exception { + RunAsManagerImpl runAs = new RunAsManagerImpl(); + + try { + runAs.afterPropertiesSet(); + fail("Should have thrown IllegalArgumentException"); + } catch (IllegalArgumentException expected) { + assertTrue(true); + } + } + + public void testStartupSuccessfulWithKey() throws Exception { + RunAsManagerImpl runAs = new RunAsManagerImpl(); + runAs.setKey("hello_world"); + runAs.afterPropertiesSet(); + assertEquals("hello_world", runAs.getKey()); + } + + public void testSupports() throws Exception { + RunAsManager runAs = new RunAsManagerImpl(); + assertTrue(runAs.supports(new SecurityConfig("RUN_AS_SOMETHING"))); + assertTrue(!runAs.supports(new SecurityConfig("ROLE_WHICH_IS_IGNORED"))); + assertTrue(!runAs.supports(new SecurityConfig("role_LOWER_CASE_FAILS"))); + } +} diff --git a/core/src/test/java/org/acegisecurity/runas/RunAsUserTokenTests.java b/core/src/test/java/org/acegisecurity/runas/RunAsUserTokenTests.java new file mode 100644 index 0000000000..4637680473 --- /dev/null +++ b/core/src/test/java/org/acegisecurity/runas/RunAsUserTokenTests.java @@ -0,0 +1,90 @@ +/* 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.runas; + +import junit.framework.TestCase; + +import net.sf.acegisecurity.GrantedAuthority; +import net.sf.acegisecurity.GrantedAuthorityImpl; +import net.sf.acegisecurity.providers.UsernamePasswordAuthenticationToken; + + +/** + * Tests {@link RunAsUserToken}. + * + * @author Ben Alex + * @version $Id$ + */ +public class RunAsUserTokenTests extends TestCase { + //~ Constructors =========================================================== + + public RunAsUserTokenTests() { + super(); + } + + public RunAsUserTokenTests(String arg0) { + super(arg0); + } + + //~ Methods ================================================================ + + public final void setUp() throws Exception { + super.setUp(); + } + + public static void main(String[] args) { + junit.textui.TestRunner.run(RunAsUserTokenTests.class); + } + + public void testAuthenticationSettingAlwaysReturnsTrue() { + RunAsUserToken token = new RunAsUserToken("my_password", "Test", + "Password", + new GrantedAuthority[] {new GrantedAuthorityImpl("ROLE_ONE"), new GrantedAuthorityImpl( + "ROLE_TWO")}, UsernamePasswordAuthenticationToken.class); + assertTrue(token.isAuthenticated()); + token.setAuthenticated(false); + assertTrue(token.isAuthenticated()); + } + + public void testGetters() { + RunAsUserToken token = new RunAsUserToken("my_password", "Test", + "Password", + new GrantedAuthority[] {new GrantedAuthorityImpl("ROLE_ONE"), new GrantedAuthorityImpl( + "ROLE_TWO")}, UsernamePasswordAuthenticationToken.class); + assertEquals("Test", token.getPrincipal()); + assertEquals("Password", token.getCredentials()); + assertEquals("my_password".hashCode(), token.getKeyHash()); + assertEquals(UsernamePasswordAuthenticationToken.class, + token.getOriginalAuthentication()); + } + + public void testNoArgsConstructor() { + try { + new RunAsUserToken(); + fail("Should have thrown IllegalArgumentException"); + } catch (IllegalArgumentException expected) { + assertTrue(true); + } + } + + public void testToString() { + RunAsUserToken token = new RunAsUserToken("my_password", "Test", + "Password", + new GrantedAuthority[] {new GrantedAuthorityImpl("ROLE_ONE"), new GrantedAuthorityImpl( + "ROLE_TWO")}, UsernamePasswordAuthenticationToken.class); + assertTrue(token.toString().lastIndexOf("Original Class:") != -1); + } +}