From acb02246e092dbae77c5c7faf527fc48029d7da6 Mon Sep 17 00:00:00 2001 From: Luke Taylor Date: Tue, 2 Oct 2007 10:52:06 +0000 Subject: [PATCH] Refactored embedded LDAP server tests to make use of new namespace configuration. Use Junit 4 annotations in preference to AbstractDependencyInjectionSpringContextTests so that it is possible to clear up the context after each class is run rather than at JVM shutdown (causes problems with running embedded apache DS). --- .../ldap/DefaultInitialDirContextFactory.java | 6 +- .../security/ldap/LdapUtils.java | 8 +- .../ldap/LdapAuthenticationProvider.java | 10 +- .../DefaultLdapAuthoritiesPopulator.java | 10 +- .../ldap/AbstractLdapIntegrationTests.java | 107 ++++++++++--- .../security/ldap/ConfigEnvHelper.java | 65 -------- .../DefaultInitialDirContextFactoryTests.java | 45 ++++-- .../security/ldap/LdapServerManager.java | 144 ------------------ .../security/ldap/LdapUtilsTests.java | 22 +-- .../ldap/SpringSecurityLdapTemplateTests.java | 37 +++-- .../FilterBasedLdapUserSearchTests.java | 11 +- .../ldap/LdapAuthenticationProviderTests.java | 4 +- .../authenticator/BindAuthenticatorTests.java | 9 +- ...swordComparisonAuthenticatorMockTests.java | 4 +- .../PasswordComparisonAuthenticatorTests.java | 72 +++++---- .../DefaultLdapAuthoritiesPopulatorTests.java | 19 ++- .../ldap/LdapUserDetailsManagerTests.java | 23 ++- .../security/ldap/apacheDsContext.xml | 81 ---------- .../ldap/ldapIntegrationTestContext.xml | 32 +--- .../security/ldap/ldapserver.properties | 5 - .../security/ldap/setup_data.ldif | 56 ------- .../providers/ldap/ldif/acegisecurity.ldif | 56 ------- ...applicationContext-acegi-security-ldap.xml | 4 +- .../security/config/ldap-config.xml | 14 +- 24 files changed, 272 insertions(+), 572 deletions(-) delete mode 100644 core/src/test/java/org/springframework/security/ldap/ConfigEnvHelper.java delete mode 100644 core/src/test/java/org/springframework/security/ldap/LdapServerManager.java delete mode 100644 core/src/test/resources/org/springframework/security/ldap/apacheDsContext.xml delete mode 100644 core/src/test/resources/org/springframework/security/ldap/ldapserver.properties delete mode 100644 core/src/test/resources/org/springframework/security/ldap/setup_data.ldif delete mode 100644 core/src/test/resources/org/springframework/security/providers/ldap/ldif/acegisecurity.ldif diff --git a/core/src/main/java/org/springframework/security/ldap/DefaultInitialDirContextFactory.java b/core/src/main/java/org/springframework/security/ldap/DefaultInitialDirContextFactory.java index 39f4d90186..180b1b0c70 100644 --- a/core/src/main/java/org/springframework/security/ldap/DefaultInitialDirContextFactory.java +++ b/core/src/main/java/org/springframework/security/ldap/DefaultInitialDirContextFactory.java @@ -48,7 +48,7 @@ import javax.naming.directory.InitialDirContext; * DirContext references. *

* The directory location is configured using by setting the constructor argument - * providerUrl. This should be in the form ldap://monkeymachine.co.uk:389/dc=acegisecurity,dc=org. + * providerUrl. This should be in the form ldap://monkeymachine.co.uk:389/dc=springframework,dc=org. * The Sun JNDI provider also supports lists of space-separated URLs, each of which will be tried in turn until a * connection is obtained. *

@@ -226,8 +226,8 @@ public class DefaultInitialDirContextFactory implements InitialDirContextFactory /** * Returns the root DN of the configured provider URL. For example, if the URL is - * ldap://monkeymachine.co.uk:389/dc=acegisecurity,dc=org the value will be - * dc=acegisecurity,dc=org. + * ldap://monkeymachine.co.uk:389/dc=springframework,dc=org the value will be + * dc=springframework,dc=org. * * @return the root DN calculated from the path of the LDAP url. */ diff --git a/core/src/main/java/org/springframework/security/ldap/LdapUtils.java b/core/src/main/java/org/springframework/security/ldap/LdapUtils.java index 693b76bea4..8e5807cb91 100644 --- a/core/src/main/java/org/springframework/security/ldap/LdapUtils.java +++ b/core/src/main/java/org/springframework/security/ldap/LdapUtils.java @@ -62,8 +62,8 @@ public final class LdapUtils { /** * Obtains the part of a DN relative to a supplied base context. - *

If the DN is "cn=bob,ou=people,dc=acegisecurity,dc=org" and the base context name is - * "ou=people,dc=acegisecurity,dc=org" it would return "cn=bob". + *

If the DN is "cn=bob,ou=people,dc=springframework,dc=org" and the base context name is + * "ou=people,dc=springframework,dc=org" it would return "cn=bob". *

* * @param fullDn the DN @@ -144,7 +144,7 @@ public final class LdapUtils { /** * Works out the root DN for an LDAP URL.

For example, the URL - * ldap://monkeymachine:11389/dc=acegisecurity,dc=org has the root DN "dc=acegisecurity,dc=org".

+ * ldap://monkeymachine:11389/dc=springframework,dc=org has the root DN "dc=springframework,dc=org".

* * @param url the LDAP URL * @@ -185,7 +185,7 @@ public final class LdapUtils { // removed for 1.3 compatibility /** * Parses the supplied LDAP URL. - * @param url the URL (e.g. ldap://monkeymachine:11389/dc=acegisecurity,dc=org). + * @param url the URL (e.g. ldap://monkeymachine:11389/dc=springframework,dc=org). * @return the URI object created from the URL * @throws IllegalArgumentException if the URL is null, empty or the URI syntax is invalid. */ diff --git a/core/src/main/java/org/springframework/security/providers/ldap/LdapAuthenticationProvider.java b/core/src/main/java/org/springframework/security/providers/ldap/LdapAuthenticationProvider.java index 2d1180ba1d..f3b935e429 100644 --- a/core/src/main/java/org/springframework/security/providers/ldap/LdapAuthenticationProvider.java +++ b/core/src/main/java/org/springframework/security/providers/ldap/LdapAuthenticationProvider.java @@ -73,8 +73,8 @@ import org.springframework.ldap.core.DirContextOperations; * A simple configuration might be as follows: *
  *    <bean id="initialDirContextFactory" class="org.springframework.security.providers.ldap.DefaultInitialDirContextFactory">
- *      <constructor-arg value="ldap://monkeymachine:389/dc=acegisecurity,dc=org"/>
- *      <property name="managerDn"><value>cn=manager,dc=acegisecurity,dc=org</value></property>
+ *      <constructor-arg value="ldap://monkeymachine:389/dc=springframework,dc=org"/>
+ *      <property name="managerDn"><value>cn=manager,dc=springframework,dc=org</value></property>
  *      <property name="managerPassword"><value>password</value></property>
  *    </bean>
  *
@@ -95,10 +95,10 @@ import org.springframework.ldap.core.DirContextOperations;
  *    </bean>
* *

This would set up the provider to access an LDAP server with URL - * ldap://monkeymachine:389/dc=acegisecurity,dc=org. Authentication will be performed by attempting to bind - * with the DN uid=<user-login-name>,ou=people,dc=acegisecurity,dc=org. After successful + * ldap://monkeymachine:389/dc=springframework,dc=org. Authentication will be performed by attempting to bind + * with the DN uid=<user-login-name>,ou=people,dc=springframework,dc=org. After successful * authentication, roles will be assigned to the user by searching under the DN - * ou=groups,dc=acegisecurity,dc=org with the default filter (member=<user's-DN>). The role + * ou=groups,dc=springframework,dc=org with the default filter (member=<user's-DN>). The role * name will be taken from the "ou" attribute of each match.

*

* The authenticate method will reject empty passwords outright. LDAP servers may allow an anonymous diff --git a/core/src/main/java/org/springframework/security/providers/ldap/populator/DefaultLdapAuthoritiesPopulator.java b/core/src/main/java/org/springframework/security/providers/ldap/populator/DefaultLdapAuthoritiesPopulator.java index 7a3c2fd9cc..1834cfcb1c 100644 --- a/core/src/main/java/org/springframework/security/providers/ldap/populator/DefaultLdapAuthoritiesPopulator.java +++ b/core/src/main/java/org/springframework/security/providers/ldap/populator/DefaultLdapAuthoritiesPopulator.java @@ -45,13 +45,13 @@ import javax.naming.directory.SearchControls; * A typical group search scenario would be where each group/role is specified using the groupOfNames * (or groupOfUniqueNames) LDAP objectClass and the user's DN is listed in the member (or * uniqueMember) attribute to indicate that they should be assigned that role. The following LDIF sample has - * the groups stored under the DN ou=groups,dc=acegisecurity,dc=org and a group called "developers" with + * the groups stored under the DN ou=groups,dc=springframework,dc=org and a group called "developers" with * "ben" and "marissa" as members: *

- * dn: ou=groups,dc=acegisecurity,dc=orgobjectClass: top
- * objectClass: organizationalUnitou: groupsdn: cn=developers,ou=groups,dc=acegisecurity,dc=org
+ * dn: ou=groups,dc=springframework,dc=orgobjectClass: top
+ * objectClass: organizationalUnitou: groupsdn: cn=developers,ou=groups,dc=springframework,dc=org
  * objectClass: groupOfNamesobjectClass: topcn: developersdescription: Acegi Security Developers
- * member: uid=ben,ou=people,dc=acegisecurity,dc=orgmember: uid=marissa,ou=people,dc=acegisecurity,dc=orgou: developer
+ * member: uid=ben,ou=people,dc=springframework,dc=orgmember: uid=marissa,ou=people,dc=springframework,dc=orgou: developer
  * 
*

*

@@ -75,7 +75,7 @@ import javax.naming.directory.SearchControls; * <property name="convertToUpperCase"><value>true</value></property> * </bean> * - * A search for roles for user "uid=ben,ou=people,dc=acegisecurity,dc=org" would return the single granted authority + * A search for roles for user "uid=ben,ou=people,dc=springframework,dc=org" would return the single granted authority * "ROLE_DEVELOPER". *

*

diff --git a/core/src/test/java/org/springframework/security/ldap/AbstractLdapIntegrationTests.java b/core/src/test/java/org/springframework/security/ldap/AbstractLdapIntegrationTests.java index 3f12d29eda..d8de681a56 100644 --- a/core/src/test/java/org/springframework/security/ldap/AbstractLdapIntegrationTests.java +++ b/core/src/test/java/org/springframework/security/ldap/AbstractLdapIntegrationTests.java @@ -14,9 +14,23 @@ */ package org.springframework.security.ldap; -import org.springframework.test.AbstractDependencyInjectionSpringContextTests; import org.springframework.ldap.core.ContextSource; +import org.springframework.ldap.core.DistinguishedName; import org.springframework.core.io.ClassPathResource; +import org.springframework.context.support.ClassPathXmlApplicationContext; +import org.junit.BeforeClass; +import org.junit.Before; +import org.junit.AfterClass; +import org.junit.After; +import org.apache.directory.server.protocol.shared.store.LdifFileLoader; + +import javax.naming.directory.DirContext; +import javax.naming.Name; +import javax.naming.NamingException; +import javax.naming.NamingEnumeration; +import javax.naming.Binding; +import javax.naming.ContextNotEmptyException; +import javax.naming.NameNotFoundException; /** * Based on class borrowed from Spring Ldap project. @@ -24,42 +38,62 @@ import org.springframework.core.io.ClassPathResource; * @author Luke Taylor * @version $Id$ */ -public abstract class AbstractLdapIntegrationTests extends AbstractDependencyInjectionSpringContextTests { - private LdapServerManager ldapServerManager; - private ContextSource contextSource; - private DefaultInitialDirContextFactory initialDirContextFactory; +public abstract class AbstractLdapIntegrationTests { + private static ClassPathXmlApplicationContext appContext; + private boolean dirty = false; protected AbstractLdapIntegrationTests() { - super.setAutowireMode(AUTOWIRE_BY_NAME); } - protected String[] getConfigLocations() { - return new String[] {"/org/springframework/security/ldap/ldapIntegrationTestContext.xml"}; + @BeforeClass + public static void loadContext() { + appContext = new ClassPathXmlApplicationContext("/org/springframework/security/ldap/ldapIntegrationTestContext.xml"); } + @AfterClass + public static void closeContext() { + appContext.close(); + } - protected void onSetUp() throws Exception { - super.onSetUp(); + @Before + public void onSetUp() throws Exception { + } - ClassPathResource ldifs = new ClassPathResource("org/springframework/security/ldap/setup_data.ldif"); + /** Reloads the server data file */ + protected void setDirty() { + dirty = true; + } + + @After + public final void reloadServerDataIfDirty() throws Exception { +// if (!dirty) { +// return; +// } + +// closeContext(); +// loadContext(); + ClassPathResource ldifs = new ClassPathResource("test-server.ldif"); if (!ldifs.getFile().exists()) { throw new IllegalStateException("Ldif file not found: " + ldifs.getFile().getAbsolutePath()); } - ldapServerManager.cleanAndSetup(ldifs.getFile().getAbsolutePath()); - } + DirContext ctx = getContextSource().getReadWriteContext(); - public void setLdapServerManager(LdapServerManager ldapServerManager) { - this.ldapServerManager = ldapServerManager; + // First of all, make sure the database is empty. + Name startingPoint = new DistinguishedName("dc=springframework,dc=org"); + + try { + clearSubContexts(ctx, startingPoint); + LdifFileLoader loader = new LdifFileLoader(ctx, ldifs.getFile().getAbsolutePath()); + loader.execute(); + } finally { + ctx.close(); + } } public ContextSource getContextSource() { - return contextSource; - } - - public void setContextSource(ContextSource contextSource) { - this.contextSource = contextSource; + return (ContextSource) appContext.getBean("contextSource"); } /** @@ -67,11 +101,36 @@ public abstract class AbstractLdapIntegrationTests extends AbstractDependencyInj * the cleanAndSetup method so any mods during tests can mess it up. * TODO: Once the initialdircontextfactory stuff has been refactored, revisit this and remove this property. */ - public DefaultInitialDirContextFactory getInitialDirContextFactory() { - return initialDirContextFactory; + protected DefaultInitialDirContextFactory getInitialDirContextFactory() { + return (DefaultInitialDirContextFactory) appContext.getBean("initialDirContextFactory"); } - public void setInitialDirContextFactory(DefaultInitialDirContextFactory initialDirContextFactory) { - this.initialDirContextFactory = initialDirContextFactory; + private void clearSubContexts(DirContext ctx, Name name) throws NamingException { + + NamingEnumeration enumeration = null; + try { + enumeration = ctx.listBindings(name); + while (enumeration.hasMore()) { + Binding element = (Binding) enumeration.next(); + DistinguishedName childName = new DistinguishedName(element.getName()); + childName.prepend((DistinguishedName) name); + + try { + ctx.destroySubcontext(childName); + } catch (ContextNotEmptyException e) { + clearSubContexts(ctx, childName); + ctx.destroySubcontext(childName); + } + } + } catch(NameNotFoundException ignored) { + } + catch (NamingException e) { + e.printStackTrace(); + } finally { + try { + enumeration.close(); + } catch (Exception ignored) { + } + } } } diff --git a/core/src/test/java/org/springframework/security/ldap/ConfigEnvHelper.java b/core/src/test/java/org/springframework/security/ldap/ConfigEnvHelper.java deleted file mode 100644 index fd0766d34f..0000000000 --- a/core/src/test/java/org/springframework/security/ldap/ConfigEnvHelper.java +++ /dev/null @@ -1,65 +0,0 @@ -/* - * Copyright 2005-2007 the original author or authors. - * - * 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 org.springframework.security.ldap; - -import java.io.File; -import java.util.Hashtable; - -import javax.naming.Context; - -import org.apache.directory.server.configuration.MutableServerStartupConfiguration; -import org.apache.directory.server.jndi.ServerContextFactory; -import org.springframework.beans.factory.InitializingBean; - -/** - * Helper class to simplify Spring configuration of ApacheDS. - * - * @author Mattias Arthursson - * @author Luke Taylor (borrowed from Spring Ldap project). - */ -public class ConfigEnvHelper implements InitializingBean { - private final MutableServerStartupConfiguration configuration; - - private final Hashtable initialEnv; - - public ConfigEnvHelper(Hashtable initialEnv, - MutableServerStartupConfiguration configuration) { - - this.initialEnv = initialEnv; - this.configuration = configuration; - } - - public Hashtable getEnv() { - return initialEnv; - } - - public void afterPropertiesSet() throws Exception { - // Attempt to use the maven target directory for the apache ds store. Property is passed - // through surefire plugin setup in pom.xml. - - String apacheWorkDir = System.getProperty("apacheDSWorkDir"); - - if (apacheWorkDir == null) { - apacheWorkDir = System.getProperty("java.io.tmpdir") + File.separator + "apacheds-spring-security"; - } - - File workingDir = new File(apacheWorkDir); - - initialEnv.put(Context.INITIAL_CONTEXT_FACTORY, ServerContextFactory.class.getName()); - configuration.setWorkingDirectory(workingDir); - initialEnv.putAll(configuration.toJndiEnvironment()); - } -} diff --git a/core/src/test/java/org/springframework/security/ldap/DefaultInitialDirContextFactoryTests.java b/core/src/test/java/org/springframework/security/ldap/DefaultInitialDirContextFactoryTests.java index 895f8c15ea..be0e8e1237 100644 --- a/core/src/test/java/org/springframework/security/ldap/DefaultInitialDirContextFactoryTests.java +++ b/core/src/test/java/org/springframework/security/ldap/DefaultInitialDirContextFactoryTests.java @@ -24,6 +24,8 @@ import java.util.Hashtable; import javax.naming.Context; import javax.naming.directory.DirContext; +import static org.junit.Assert.*; +import org.junit.Test; /** * Tests {@link org.springframework.security.ldap.DefaultInitialDirContextFactory}. @@ -44,6 +46,7 @@ public class DefaultInitialDirContextFactoryTests extends AbstractLdapIntegratio idf.setMessageSource(new AcegiMessageSource()); } + @Test public void testAnonymousBindSucceeds() throws Exception { DirContext ctx = idf.newInitialDirContext(); // Connection pooling should be set by default for anon users. @@ -52,9 +55,10 @@ public class DefaultInitialDirContextFactoryTests extends AbstractLdapIntegratio ctx.close(); } + @Test public void testBaseDnIsParsedFromCorrectlyFromUrl() { - idf = new DefaultInitialDirContextFactory("ldap://acegisecurity.org/dc=acegisecurity,dc=org"); - assertEquals("dc=acegisecurity,dc=org", idf.getRootDn()); + idf = new DefaultInitialDirContextFactory("ldap://acegisecurity.org/dc=springframework,dc=org"); + assertEquals("dc=springframework,dc=org", idf.getRootDn()); // Check with an empty root idf = new DefaultInitialDirContextFactory("ldap://acegisecurity.org/"); @@ -65,8 +69,9 @@ public class DefaultInitialDirContextFactoryTests extends AbstractLdapIntegratio assertEquals("", idf.getRootDn()); } + @Test public void testBindAsManagerFailsIfNoPasswordSet() throws Exception { - idf.setManagerDn("uid=bob,ou=people,dc=acegisecurity,dc=org"); + idf.setManagerDn("uid=bob,ou=people,dc=springframework,dc=org"); DirContext ctx = null; @@ -81,9 +86,10 @@ public class DefaultInitialDirContextFactoryTests extends AbstractLdapIntegratio LdapUtils.closeContext(ctx); } + @Test public void testBindAsManagerSucceeds() throws Exception { idf.setManagerPassword("bobspassword"); - idf.setManagerDn("uid=bob,ou=people,dc=acegisecurity,dc=org"); + idf.setManagerDn("uid=bob,ou=people,dc=springframework,dc=org"); DirContext ctx = idf.newInitialDirContext(); // Can't rely on this property being there with embedded server @@ -91,14 +97,16 @@ public class DefaultInitialDirContextFactoryTests extends AbstractLdapIntegratio ctx.close(); } + @Test public void testConnectionAsSpecificUserSucceeds() throws Exception { - DirContext ctx = idf.newInitialDirContext("uid=Bob,ou=people,dc=acegisecurity,dc=org", "bobspassword"); + DirContext ctx = idf.newInitialDirContext("uid=Bob,ou=people,dc=springframework,dc=org", "bobspassword"); // We don't want pooling for specific users. // assertNull(ctx.getEnvironment().get("com.sun.jndi.ldap.connect.pool")); // com.sun.jndi.ldap.LdapPoolManager.showStats(System.out); ctx.close(); } + @Test public void testConnectionFailure() throws Exception { // Use the wrong port idf = new DefaultInitialDirContextFactory("ldap://localhost:60389"); @@ -115,6 +123,7 @@ public class DefaultInitialDirContextFactoryTests extends AbstractLdapIntegratio } catch (UncategorizedLdapException expected) {} } + @Test public void testEnvironment() { idf = new DefaultInitialDirContextFactory("ldap://acegisecurity.org/"); @@ -144,9 +153,9 @@ public class DefaultInitialDirContextFactoryTests extends AbstractLdapIntegratio assertEquals("extravarvalue", env.get("extravar")); } - public void testInvalidPasswordCausesBadCredentialsException() - throws Exception { - idf.setManagerDn("uid=bob,ou=people,dc=acegisecurity,dc=org"); + @Test + public void testInvalidPasswordCausesBadCredentialsException() throws Exception { + idf.setManagerDn("uid=bob,ou=people,dc=springframework,dc=org"); idf.setManagerPassword("wrongpassword"); DirContext ctx = null; @@ -159,28 +168,31 @@ public class DefaultInitialDirContextFactoryTests extends AbstractLdapIntegratio LdapUtils.closeContext(ctx); } + @Test public void testMultipleProviderUrlsAreAccepted() { - idf = new DefaultInitialDirContextFactory("ldaps://security.org/dc=acegisecurity,dc=org " - + "ldap://monkeymachine.co.uk/dc=acegisecurity,dc=org"); + idf = new DefaultInitialDirContextFactory("ldaps://security.org/dc=springframework,dc=org " + + "ldap://monkeymachine.co.uk/dc=springframework,dc=org"); } + @Test public void testMultipleProviderUrlsWithDifferentRootsAreRejected() { try { - idf = new DefaultInitialDirContextFactory("ldap://security.org/dc=acegisecurity,dc=org " + idf = new DefaultInitialDirContextFactory("ldap://security.org/dc=springframework,dc=org " + "ldap://monkeymachine.co.uk/dc=someotherplace,dc=org"); fail("Different root DNs should cause an exception"); } catch (IllegalArgumentException expected) {} } + @Test public void testSecureLdapUrlIsSupported() { - idf = new DefaultInitialDirContextFactory("ldaps://localhost/dc=acegisecurity,dc=org"); - assertEquals("dc=acegisecurity,dc=org", idf.getRootDn()); + idf = new DefaultInitialDirContextFactory("ldaps://localhost/dc=springframework,dc=org"); + assertEquals("dc=springframework,dc=org", idf.getRootDn()); } // public void testNonLdapUrlIsRejected() throws Exception { // DefaultInitialDirContextFactory idf = new DefaultInitialDirContextFactory(); // -// idf.setUrl("http://security.org/dc=acegisecurity,dc=org"); +// idf.setUrl("http://security.org/dc=springframework,dc=org"); // idf.setInitialContextFactory(CoreContextFactory.class.getName()); // // try { @@ -189,8 +201,9 @@ public class DefaultInitialDirContextFactoryTests extends AbstractLdapIntegratio // } catch(IllegalArgumentException expected) { // } // } + @Test public void testServiceLocationUrlIsSupported() { - idf = new DefaultInitialDirContextFactory("ldap:///dc=acegisecurity,dc=org"); - assertEquals("dc=acegisecurity,dc=org", idf.getRootDn()); + idf = new DefaultInitialDirContextFactory("ldap:///dc=springframework,dc=org"); + assertEquals("dc=springframework,dc=org", idf.getRootDn()); } } diff --git a/core/src/test/java/org/springframework/security/ldap/LdapServerManager.java b/core/src/test/java/org/springframework/security/ldap/LdapServerManager.java deleted file mode 100644 index cfe59848cf..0000000000 --- a/core/src/test/java/org/springframework/security/ldap/LdapServerManager.java +++ /dev/null @@ -1,144 +0,0 @@ -/* - * Copyright 2005-2007 the original author or authors. - * - * 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 org.springframework.security.ldap; - -import java.util.Properties; - -import javax.naming.Binding; -import javax.naming.Context; -import javax.naming.ContextNotEmptyException; -import javax.naming.InitialContext; -import javax.naming.Name; -import javax.naming.NamingEnumeration; -import javax.naming.NamingException; -import javax.naming.NameNotFoundException; -import javax.naming.directory.DirContext; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import org.apache.directory.server.core.configuration.ShutdownConfiguration; -import org.apache.directory.server.jndi.ServerContextFactory; -import org.apache.directory.server.protocol.shared.store.LdifFileLoader; - -import org.springframework.beans.factory.DisposableBean; -import org.springframework.beans.factory.InitializingBean; -import org.springframework.ldap.core.ContextSource; -import org.springframework.ldap.core.DistinguishedName; -import org.springframework.ldap.core.support.DefaultDirObjectFactory; -import org.springframework.core.io.Resource; - - -/** - * Utility class to initialize the apache directory server for use in the integration tests. - * - * @author Mattias Arthursson - * @author Luke Taylor (borrowed from Spring Ldap project). - * - */ -public class LdapServerManager implements DisposableBean, InitializingBean { - private static Log log = LogFactory.getLog(LdapServerManager.class); - - private ContextSource contextSource; - private Resource ldifFile; - - public void setContextSource(ContextSource contextSource) { - this.contextSource = contextSource; - } - - public void destroy() throws Exception { - Properties env = new Properties(); - env.setProperty(Context.INITIAL_CONTEXT_FACTORY, - ServerContextFactory.class.getName()); - env.setProperty(Context.SECURITY_AUTHENTICATION, "simple"); - env.setProperty(Context.SECURITY_PRINCIPAL, "uid=admin,ou=system"); - env.setProperty(Context.SECURITY_CREDENTIALS, "secret"); - - ShutdownConfiguration configuration = new ShutdownConfiguration(); - env.putAll(configuration.toJndiEnvironment()); - - new InitialContext(env); - } - - - public void afterPropertiesSet() throws Exception { - if (ldifFile != null) { - cleanAndSetup(ldifFile.getFile().getAbsolutePath()); - } - } - - public void setLdifFile(Resource ldifFile) { - this.ldifFile = ldifFile; - } - - public void cleanAndSetup(String ldifFile) throws Exception { - DirContext ctx = contextSource.getReadWriteContext(); - - // First of all, make sure the database is empty. - Name startingPoint = null; - - // Different test cases have different base paths. This means that the - // starting point will be different. - if (ctx.getEnvironment().get( - DefaultDirObjectFactory.JNDI_ENV_BASE_PATH_KEY) != null) { - startingPoint = DistinguishedName.EMPTY_PATH; - } else { - startingPoint = new DistinguishedName("dc=acegisecurity,dc=org"); - } - - try { - log.info("Cleaning all present data."); - clearSubContexts(ctx, startingPoint); - // Load the ldif to the recently started server - log.info("Loading setup data"); - LdifFileLoader loader = new LdifFileLoader(ctx, ldifFile); - loader.execute(); - } finally { - ctx.close(); - } - } - - private void clearSubContexts(DirContext ctx, Name name) throws NamingException { - - NamingEnumeration enumeration = null; - try { - enumeration = ctx.listBindings(name); - while (enumeration.hasMore()) { - Binding element = (Binding) enumeration.next(); - DistinguishedName childName = new DistinguishedName(element.getName()); - childName.prepend((DistinguishedName) name); - - try { - ctx.destroySubcontext(childName); - } catch (ContextNotEmptyException e) { - clearSubContexts(ctx, childName); - ctx.destroySubcontext(childName); - } - } - } catch(NameNotFoundException ignored) { - } - catch (NamingException e) { - e.printStackTrace(); - } finally { - try { - enumeration.close(); - } catch (Exception e) { - // Never mind this - } - } - } -} - diff --git a/core/src/test/java/org/springframework/security/ldap/LdapUtilsTests.java b/core/src/test/java/org/springframework/security/ldap/LdapUtilsTests.java index c54b148710..8226e4249c 100644 --- a/core/src/test/java/org/springframework/security/ldap/LdapUtilsTests.java +++ b/core/src/test/java/org/springframework/security/ldap/LdapUtilsTests.java @@ -45,9 +45,9 @@ public class LdapUtilsTests extends MockObjectTestCase { throws Exception { Mock mockCtx = mock(DirContext.class); - mockCtx.expects(atLeastOnce()).method("getNameInNamespace").will(returnValue("dc=acegisecurity,dc=org")); + mockCtx.expects(atLeastOnce()).method("getNameInNamespace").will(returnValue("dc=springframework,dc=org")); - assertEquals("", LdapUtils.getRelativeName("dc=acegisecurity,dc=org", (Context) mockCtx.proxy())); + assertEquals("", LdapUtils.getRelativeName("dc=springframework,dc=org", (Context) mockCtx.proxy())); } public void testGetRelativeNameReturnsFullDnWithEmptyBaseName() @@ -56,8 +56,8 @@ public class LdapUtilsTests extends MockObjectTestCase { mockCtx.expects(atLeastOnce()).method("getNameInNamespace").will(returnValue("")); - assertEquals("cn=jane,dc=acegisecurity,dc=org", - LdapUtils.getRelativeName("cn=jane,dc=acegisecurity,dc=org", (Context) mockCtx.proxy())); + assertEquals("cn=jane,dc=springframework,dc=org", + LdapUtils.getRelativeName("cn=jane,dc=springframework,dc=org", (Context) mockCtx.proxy())); } public void testGetRelativeNameWorksWithArbitrarySpaces() @@ -74,12 +74,12 @@ public class LdapUtilsTests extends MockObjectTestCase { assertEquals("", LdapUtils.parseRootDnFromUrl("ldap://monkeymachine")); assertEquals("", LdapUtils.parseRootDnFromUrl("ldap://monkeymachine/")); assertEquals("", LdapUtils.parseRootDnFromUrl("ldap://monkeymachine.co.uk/")); - assertEquals("dc=acegisecurity,dc=org", - LdapUtils.parseRootDnFromUrl("ldaps://monkeymachine.co.uk/dc=acegisecurity,dc=org")); - assertEquals("dc=acegisecurity,dc=org", LdapUtils.parseRootDnFromUrl("ldap:///dc=acegisecurity,dc=org")); - assertEquals("dc=acegisecurity,dc=org", - LdapUtils.parseRootDnFromUrl("ldap://monkeymachine/dc=acegisecurity,dc=org")); - assertEquals("dc=acegisecurity,dc=org/ou=blah", - LdapUtils.parseRootDnFromUrl("ldap://monkeymachine.co.uk/dc=acegisecurity,dc=org/ou=blah")); + assertEquals("dc=springframework,dc=org", + LdapUtils.parseRootDnFromUrl("ldaps://monkeymachine.co.uk/dc=springframework,dc=org")); + assertEquals("dc=springframework,dc=org", LdapUtils.parseRootDnFromUrl("ldap:///dc=springframework,dc=org")); + assertEquals("dc=springframework,dc=org", + LdapUtils.parseRootDnFromUrl("ldap://monkeymachine/dc=springframework,dc=org")); + assertEquals("dc=springframework,dc=org/ou=blah", + LdapUtils.parseRootDnFromUrl("ldap://monkeymachine.co.uk/dc=springframework,dc=org/ou=blah")); } } diff --git a/core/src/test/java/org/springframework/security/ldap/SpringSecurityLdapTemplateTests.java b/core/src/test/java/org/springframework/security/ldap/SpringSecurityLdapTemplateTests.java index 4aa514401e..7d2083c08c 100644 --- a/core/src/test/java/org/springframework/security/ldap/SpringSecurityLdapTemplateTests.java +++ b/core/src/test/java/org/springframework/security/ldap/SpringSecurityLdapTemplateTests.java @@ -17,13 +17,14 @@ package org.springframework.security.ldap; import org.springframework.ldap.UncategorizedLdapException; import org.springframework.ldap.core.ContextExecutor; +import org.junit.Test; +import static org.junit.Assert.*; import java.util.Set; import javax.naming.NamingException; import javax.naming.directory.DirContext; - /** * @author Luke Taylor * @version $Id$ @@ -35,35 +36,43 @@ public class SpringSecurityLdapTemplateTests extends AbstractLdapIntegrationTest //~ Methods ======================================================================================================== - protected void onSetUp() throws Exception { + public void onSetUp() throws Exception { super.onSetUp(); + template = new SpringSecurityLdapTemplate(getContextSource()); } - public void testCompareOfCorrectByteValueSucceeds() { - assertTrue(template.compare("uid=bob,ou=people,dc=acegisecurity,dc=org", "userPassword", LdapUtils.getUtf8Bytes("bobspassword"))); - } - + @Test public void testCompareOfCorrectValueSucceeds() { - assertTrue(template.compare("uid=bob,ou=people,dc=acegisecurity,dc=org", "uid", "bob")); + assertTrue(template.compare("uid=bob,ou=people,dc=springframework,dc=org", "uid", "bob")); } + @Test + public void testCompareOfCorrectByteValueSucceeds() { + assertTrue(template.compare("uid=bob,ou=people,dc=springframework,dc=org", "userPassword", LdapUtils.getUtf8Bytes("bobspassword"))); + } + + @Test public void testCompareOfWrongByteValueFails() { - assertFalse(template.compare("uid=bob,ou=people,dc=acegisecurity,dc=org", "userPassword", LdapUtils.getUtf8Bytes("wrongvalue"))); + assertFalse(template.compare("uid=bob,ou=people,dc=springframework,dc=org", "userPassword", LdapUtils.getUtf8Bytes("wrongvalue"))); } + @Test public void testCompareOfWrongValueFails() { - assertFalse(template.compare("uid=bob,ou=people,dc=acegisecurity,dc=org", "uid", "wrongvalue")); + assertFalse(template.compare("uid=bob,ou=people,dc=springframework,dc=org", "uid", "wrongvalue")); } + @Test public void testNameExistsForInValidNameFails() { - assertFalse(template.nameExists("ou=doesntexist,dc=acegisecurity,dc=org")); + assertFalse(template.nameExists("ou=doesntexist,dc=springframework,dc=org")); } + @Test public void testNameExistsForValidNameSucceeds() { - assertTrue(template.nameExists("ou=groups,dc=acegisecurity,dc=org")); + assertTrue(template.nameExists("ou=groups,dc=springframework,dc=org")); } + @Test public void testNamingExceptionIsTranslatedCorrectly() { try { template.executeReadOnly(new ContextExecutor() { @@ -75,8 +84,9 @@ public class SpringSecurityLdapTemplateTests extends AbstractLdapIntegrationTest } catch (UncategorizedLdapException expected) {} } + @Test public void testRoleSearchReturnsCorrectNumberOfRoles() { - String param = "uid=ben,ou=people,dc=acegisecurity,dc=org"; + String param = "uid=ben,ou=people,dc=springframework,dc=org"; Set values = template.searchForSingleAttributeValues("ou=groups", "(member={0})", new String[] {param}, "ou"); @@ -86,8 +96,9 @@ public class SpringSecurityLdapTemplateTests extends AbstractLdapIntegrationTest assertTrue(values.contains("submanager")); } + @Test public void testRoleSearchForMissingAttributeFailsGracefully() { - String param = "uid=ben,ou=people,dc=acegisecurity,dc=org"; + String param = "uid=ben,ou=people,dc=springframework,dc=org"; Set values = template.searchForSingleAttributeValues("ou=groups", "(member={0})", new String[] {param}, "mail"); diff --git a/core/src/test/java/org/springframework/security/ldap/search/FilterBasedLdapUserSearchTests.java b/core/src/test/java/org/springframework/security/ldap/search/FilterBasedLdapUserSearchTests.java index 6ff1230dd9..41a076005f 100644 --- a/core/src/test/java/org/springframework/security/ldap/search/FilterBasedLdapUserSearchTests.java +++ b/core/src/test/java/org/springframework/security/ldap/search/FilterBasedLdapUserSearchTests.java @@ -22,7 +22,9 @@ import org.springframework.security.userdetails.UsernameNotFoundException; import org.springframework.dao.IncorrectResultSizeDataAccessException; import org.springframework.ldap.core.DirContextOperations; +import org.junit.Test; +import static org.junit.Assert.*; /** * Tests for FilterBasedLdapUserSearch. @@ -42,6 +44,7 @@ public class FilterBasedLdapUserSearchTests extends AbstractLdapIntegrationTests dirCtxFactory = (DefaultInitialDirContextFactory) getContextSource(); } + @Test public void testBasicSearch() { FilterBasedLdapUserSearch locator = new FilterBasedLdapUserSearch("ou=people", "(uid={0})", dirCtxFactory); locator.setSearchSubtree(false); @@ -52,10 +55,11 @@ public class FilterBasedLdapUserSearchTests extends AbstractLdapIntegrationTests assertEquals("bob", bob.getStringAttribute("uid")); // name is wrong with embedded apacheDS -// assertEquals("uid=bob,ou=people,dc=acegisecurity,dc=org", bob.getDn()); +// assertEquals("uid=bob,ou=people,dc=springframework,dc=org", bob.getDn()); } // Try some funny business with filters. + @Test public void testExtraFilterPartToExcludeBob() throws Exception { FilterBasedLdapUserSearch locator = new FilterBasedLdapUserSearch("ou=people", "(&(cn=*)(!(|(uid={0})(uid=marissa))))", dirCtxFactory); @@ -67,6 +71,7 @@ public class FilterBasedLdapUserSearchTests extends AbstractLdapIntegrationTests // assertEquals("uid=ben,ou=people,"+ROOT_DN, ben.getDn()); } + @Test public void testFailsOnMultipleMatches() { FilterBasedLdapUserSearch locator = new FilterBasedLdapUserSearch("ou=people", "(cn=*)", dirCtxFactory); @@ -76,6 +81,7 @@ public class FilterBasedLdapUserSearchTests extends AbstractLdapIntegrationTests } catch (IncorrectResultSizeDataAccessException expected) {} } + @Test public void testSearchForInvalidUserFails() { FilterBasedLdapUserSearch locator = new FilterBasedLdapUserSearch("ou=people", "(uid={0})", dirCtxFactory); @@ -85,6 +91,7 @@ public class FilterBasedLdapUserSearchTests extends AbstractLdapIntegrationTests } catch (UsernameNotFoundException expected) {} } + @Test public void testSubTreeSearchSucceeds() { // Don't set the searchBase, so search from the root. FilterBasedLdapUserSearch locator = new FilterBasedLdapUserSearch("", "(cn={0})", dirCtxFactory); @@ -93,7 +100,7 @@ public class FilterBasedLdapUserSearchTests extends AbstractLdapIntegrationTests DirContextOperations ben = locator.searchForUser("Ben Alex"); assertEquals("ben", ben.getStringAttribute("uid")); -// assertEquals("uid=ben,ou=people,dc=acegisecurity,dc=org", ben.getDn()); +// assertEquals("uid=ben,ou=people,dc=springframework,dc=org", ben.getDn()); } // TODO: Add test with non-uid username diff --git a/core/src/test/java/org/springframework/security/providers/ldap/LdapAuthenticationProviderTests.java b/core/src/test/java/org/springframework/security/providers/ldap/LdapAuthenticationProviderTests.java index 5bf62001b2..f8227e19ef 100644 --- a/core/src/test/java/org/springframework/security/providers/ldap/LdapAuthenticationProviderTests.java +++ b/core/src/test/java/org/springframework/security/providers/ldap/LdapAuthenticationProviderTests.java @@ -140,12 +140,12 @@ public class LdapAuthenticationProviderTests extends TestCase { if (username.equals("ben") && password.equals("benspassword")) { - ctx.setDn(new DistinguishedName("cn=ben,ou=people,dc=acegisecurity,dc=org")); + ctx.setDn(new DistinguishedName("cn=ben,ou=people,dc=springframework,dc=org")); ctx.setAttributeValue("userPassword","{SHA}nFCebWjxfaLbHHG1Qk5UU4trbvQ="); return ctx; } else if (username.equals("jen") && password.equals("")) { - ctx.setDn(new DistinguishedName("cn=jen,ou=people,dc=acegisecurity,dc=org")); + ctx.setDn(new DistinguishedName("cn=jen,ou=people,dc=springframework,dc=org")); return ctx; } diff --git a/core/src/test/java/org/springframework/security/providers/ldap/authenticator/BindAuthenticatorTests.java b/core/src/test/java/org/springframework/security/providers/ldap/authenticator/BindAuthenticatorTests.java index 591a7c6c0f..f9dee7f286 100644 --- a/core/src/test/java/org/springframework/security/providers/ldap/authenticator/BindAuthenticatorTests.java +++ b/core/src/test/java/org/springframework/security/providers/ldap/authenticator/BindAuthenticatorTests.java @@ -27,6 +27,8 @@ import org.springframework.ldap.core.DirContextAdapter; import org.springframework.ldap.core.DistinguishedName; import org.springframework.ldap.core.DirContextOperations; +import static org.junit.Assert.*; +import org.junit.Test; /** * Tests for {@link BindAuthenticator}. @@ -52,6 +54,7 @@ public class BindAuthenticatorTests extends AbstractLdapIntegrationTests { } + @Test public void testAuthenticationWithCorrectPasswordSucceeds() { authenticator.setUserDnPatterns(new String[] {"uid={0},ou=people"}); @@ -59,6 +62,7 @@ public class BindAuthenticatorTests extends AbstractLdapIntegrationTests { assertEquals("bob", user.getStringAttribute("uid")); } + @Test public void testAuthenticationWithInvalidUserNameFails() { authenticator.setUserDnPatterns(new String[] {"uid={0},ou=people"}); @@ -68,14 +72,16 @@ public class BindAuthenticatorTests extends AbstractLdapIntegrationTests { } catch (BadCredentialsException expected) {} } + @Test public void testAuthenticationWithUserSearch() throws Exception { - DirContextAdapter ctx = new DirContextAdapter(new DistinguishedName("uid=bob,ou=people,dc=acegisecurity,dc=org")); + DirContextAdapter ctx = new DirContextAdapter(new DistinguishedName("uid=bob,ou=people,dc=springframework,dc=org")); authenticator.setUserSearch(new MockUserSearch(ctx)); authenticator.afterPropertiesSet(); authenticator.authenticate(bob); } + @Test public void testAuthenticationWithWrongPasswordFails() { authenticator.setUserDnPatterns(new String[] {"uid={0},ou=people"}); @@ -85,6 +91,7 @@ public class BindAuthenticatorTests extends AbstractLdapIntegrationTests { } catch (BadCredentialsException expected) {} } + @Test public void testUserDnPatternReturnsCorrectDn() { authenticator.setUserDnPatterns(new String[] {"cn={0},ou=people"}); assertEquals("cn=Joe,ou=people," + ((InitialDirContextFactory)getContextSource()).getRootDn(), authenticator.getUserDns("Joe").get(0)); diff --git a/core/src/test/java/org/springframework/security/providers/ldap/authenticator/PasswordComparisonAuthenticatorMockTests.java b/core/src/test/java/org/springframework/security/providers/ldap/authenticator/PasswordComparisonAuthenticatorMockTests.java index 0eb10c2b35..c3e078fdcf 100644 --- a/core/src/test/java/org/springframework/security/providers/ldap/authenticator/PasswordComparisonAuthenticatorMockTests.java +++ b/core/src/test/java/org/springframework/security/providers/ldap/authenticator/PasswordComparisonAuthenticatorMockTests.java @@ -41,12 +41,12 @@ public class PasswordComparisonAuthenticatorMockTests extends MockObjectTestCase attrs.put(new BasicAttribute("uid", "bob")); PasswordComparisonAuthenticator authenticator = new PasswordComparisonAuthenticator(new MockInitialDirContextFactory( - (DirContext) mockCtx.proxy(), "dc=acegisecurity,dc=org")); + (DirContext) mockCtx.proxy(), "dc=springframework,dc=org")); authenticator.setUserDnPatterns(new String[] {"cn={0},ou=people"}); // Get the mock to return an empty attribute set - mockCtx.expects(atLeastOnce()).method("getNameInNamespace").will(returnValue("dc=acegisecurity,dc=org")); + mockCtx.expects(atLeastOnce()).method("getNameInNamespace").will(returnValue("dc=springframework,dc=org")); mockCtx.expects(once()).method("lookup").with(eq("cn=Bob, ou=people")).will(returnValue(true)); mockCtx.expects(once()).method("getAttributes").with(eq("cn=Bob, ou=people"), NULL) .will(returnValue(attrs)); diff --git a/core/src/test/java/org/springframework/security/providers/ldap/authenticator/PasswordComparisonAuthenticatorTests.java b/core/src/test/java/org/springframework/security/providers/ldap/authenticator/PasswordComparisonAuthenticatorTests.java index 2ad0064c92..cdba0bb024 100644 --- a/core/src/test/java/org/springframework/security/providers/ldap/authenticator/PasswordComparisonAuthenticatorTests.java +++ b/core/src/test/java/org/springframework/security/providers/ldap/authenticator/PasswordComparisonAuthenticatorTests.java @@ -29,6 +29,8 @@ import org.springframework.ldap.core.DirContextAdapter; import org.springframework.ldap.core.DistinguishedName; import org.springframework.ldap.core.DirContextOperations; +import static org.junit.Assert.*; +import org.junit.Test; /** * Tests for {@link PasswordComparisonAuthenticator}. @@ -53,17 +55,14 @@ public class PasswordComparisonAuthenticatorTests extends AbstractLdapIntegratio ben = new UsernamePasswordAuthenticationToken("ben", "benspassword"); } - public void onTearDown() throws Exception { - super.onTearDown(); - // com.sun.jndi.ldap.LdapPoolManager.showStats(System.out); - } - + @Test public void testAllAttributesAreRetrievedByDefault() { DirContextAdapter user = (DirContextAdapter) authenticator.authenticate(bob); //System.out.println(user.getAttributes().toString()); assertEquals("User should have 5 attributes", 5, user.getAttributes().size()); } + @Test public void testFailedSearchGivesUserNotFoundException() throws Exception { authenticator = new PasswordComparisonAuthenticator((InitialDirContextFactory) getContextSource()); assertTrue("User DN matches shouldn't be available", authenticator.getUserDns("Bob").isEmpty()); @@ -76,11 +75,13 @@ public class PasswordComparisonAuthenticatorTests extends AbstractLdapIntegratio } catch (UsernameNotFoundException expected) {} } + @Test public void testLocalComparisonSucceedsWithShaEncodedPassword() { // Ben's password is SHA encoded authenticator.authenticate(ben); } + @Test public void testLocalPasswordComparisonFailsWithWrongPassword() { try { authenticator.authenticate(new UsernamePasswordAuthenticationToken("bob", "wrongpass")); @@ -88,17 +89,18 @@ public class PasswordComparisonAuthenticatorTests extends AbstractLdapIntegratio } catch (BadCredentialsException expected) {} } - - public void testLdapPasswordCompareFailsWithWrongPassword() { + @Test + public void testLdapPasswordCompareFailsWithWrongPassword() { // Don't retrieve the password - authenticator.setUserAttributes(new String[] {"uid", "cn", "sn"}); - try { + authenticator.setUserAttributes(new String[] {"uid", "cn", "sn"}); + try { authenticator.authenticate(new UsernamePasswordAuthenticationToken("bob", "wrongpass")); fail("Authentication should fail with wrong password."); - } catch(BadCredentialsException expected) { - } - } + } catch(BadCredentialsException expected) { + } + } + @Test public void testLocalPasswordComparisonSucceedsWithCorrectPassword() { DirContextOperations user = authenticator.authenticate(bob); // check username is retrieved. @@ -107,11 +109,13 @@ public class PasswordComparisonAuthenticatorTests extends AbstractLdapIntegratio assertEquals("bobspassword", password); } + @Test public void testMultipleDnPatternsWorkOk() { authenticator.setUserDnPatterns(new String[] {"uid={0},ou=nonexistent", "uid={0},ou=people"}); authenticator.authenticate(bob); } + @Test public void testOnlySpecifiedAttributesAreRetrieved() throws Exception { authenticator.setUserAttributes(new String[] {"uid", "userPassword"}); authenticator.setPasswordEncoder(new PlaintextPasswordEncoder()); @@ -120,20 +124,23 @@ public class PasswordComparisonAuthenticatorTests extends AbstractLdapIntegratio assertEquals("Should have retrieved 2 attribute (uid, userPassword)", 2, user.getAttributes().size()); } - public void testLdapCompareSucceedsWithCorrectPassword() { - // Don't retrieve the password - authenticator.setUserAttributes(new String[] {"uid"}); - // Bob has a plaintext password. - authenticator.setPasswordEncoder(new PlaintextPasswordEncoder()); - authenticator.authenticate(bob); - } + @Test + public void testLdapCompareSucceedsWithCorrectPassword() { + // Don't retrieve the password + authenticator.setUserAttributes(new String[] {"uid"}); + // Bob has a plaintext password. + authenticator.setPasswordEncoder(new PlaintextPasswordEncoder()); + authenticator.authenticate(bob); + } - public void testLdapCompareSucceedsWithShaEncodedPassword() { - // Don't retrieve the password - authenticator.setUserAttributes(new String[] {"uid"}); - authenticator.authenticate(ben); - } + @Test + public void testLdapCompareSucceedsWithShaEncodedPassword() { + // Don't retrieve the password + authenticator.setUserAttributes(new String[] {"uid"}); + authenticator.authenticate(ben); + } + @Test public void testPasswordEncoderCantBeNull() { try { authenticator.setPasswordEncoder(null); @@ -141,23 +148,26 @@ public class PasswordComparisonAuthenticatorTests extends AbstractLdapIntegratio } catch (IllegalArgumentException expected) {} } + @Test public void testUseOfDifferentPasswordAttributeSucceeds() { authenticator.setPasswordAttributeName("uid"); authenticator.authenticate(new UsernamePasswordAuthenticationToken("bob", "bob")); } - public void testLdapCompareWithDifferentPasswordAttributeSucceeds() { - authenticator.setUserAttributes(new String[] {"uid"}); - authenticator.setPasswordEncoder(new PlaintextPasswordEncoder()); - authenticator.setPasswordAttributeName("cn"); - authenticator.authenticate(new UsernamePasswordAuthenticationToken("ben", "Ben Alex")); - } + @Test + public void testLdapCompareWithDifferentPasswordAttributeSucceeds() { + authenticator.setUserAttributes(new String[] {"uid"}); + authenticator.setPasswordEncoder(new PlaintextPasswordEncoder()); + authenticator.setPasswordAttributeName("cn"); + authenticator.authenticate(new UsernamePasswordAuthenticationToken("ben", "Ben Alex")); + } + @Test public void testWithUserSearch() { authenticator = new PasswordComparisonAuthenticator((InitialDirContextFactory) getContextSource()); assertTrue("User DN matches shouldn't be available", authenticator.getUserDns("Bob").isEmpty()); - DirContextAdapter ctx = new DirContextAdapter(new DistinguishedName("uid=Bob,ou=people,dc=acegisecurity,dc=org")); + DirContextAdapter ctx = new DirContextAdapter(new DistinguishedName("uid=Bob,ou=people,dc=springframework,dc=org")); ctx.setAttributeValue("userPassword", "bobspassword"); authenticator.setUserSearch(new MockUserSearch(ctx)); diff --git a/core/src/test/java/org/springframework/security/providers/ldap/populator/DefaultLdapAuthoritiesPopulatorTests.java b/core/src/test/java/org/springframework/security/providers/ldap/populator/DefaultLdapAuthoritiesPopulatorTests.java index 4b4e11cac3..69b5a455f9 100644 --- a/core/src/test/java/org/springframework/security/providers/ldap/populator/DefaultLdapAuthoritiesPopulatorTests.java +++ b/core/src/test/java/org/springframework/security/providers/ldap/populator/DefaultLdapAuthoritiesPopulatorTests.java @@ -26,9 +26,11 @@ import org.springframework.ldap.core.DistinguishedName; import java.util.HashSet; import java.util.Set; +import static org.junit.Assert.*; +import org.junit.Test; + /** - * DOCUMENT ME! * * @author Luke Taylor * @version $Id$ @@ -37,13 +39,14 @@ public class DefaultLdapAuthoritiesPopulatorTests extends AbstractLdapIntegratio private DefaultLdapAuthoritiesPopulator populator; //~ Methods ======================================================================================================== - protected void onSetUp() throws Exception { + public void onSetUp() throws Exception { super.onSetUp(); populator = new DefaultLdapAuthoritiesPopulator((InitialDirContextFactory) getContextSource(), "ou=groups"); } + @Test public void testDefaultRoleIsAssignedWhenSet() { populator.setDefaultRole("ROLE_USER"); @@ -55,6 +58,7 @@ public class DefaultLdapAuthoritiesPopulatorTests extends AbstractLdapIntegratio assertEquals("ROLE_USER", authorities[0].getAuthority()); } + @Test public void testGroupSearchReturnsExpectedRoles() { populator.setRolePrefix("ROLE_"); populator.setGroupRoleAttribute("ou"); @@ -63,7 +67,7 @@ public class DefaultLdapAuthoritiesPopulatorTests extends AbstractLdapIntegratio populator.setConvertToUpperCase(true); populator.setGroupSearchFilter("(member={0})"); - DirContextAdapter ctx = new DirContextAdapter(new DistinguishedName("uid=ben,ou=people,dc=acegisecurity,dc=org")); + DirContextAdapter ctx = new DirContextAdapter(new DistinguishedName("uid=ben,ou=people,dc=springframework,dc=org")); GrantedAuthority[] authorities = populator.getGrantedAuthorities(ctx, "ben"); @@ -76,12 +80,13 @@ public class DefaultLdapAuthoritiesPopulatorTests extends AbstractLdapIntegratio assertTrue(roles.contains("ROLE_MANAGER")); } + @Test public void testUseOfUsernameParameterReturnsExpectedRoles() { populator.setGroupRoleAttribute("ou"); populator.setConvertToUpperCase(true); populator.setGroupSearchFilter("(ou={1})"); - DirContextAdapter ctx = new DirContextAdapter(new DistinguishedName("uid=ben,ou=people,dc=acegisecurity,dc=org")); + DirContextAdapter ctx = new DirContextAdapter(new DistinguishedName("uid=ben,ou=people,dc=springframework,dc=org")); GrantedAuthority[] authorities = populator.getGrantedAuthorities(ctx, "manager"); @@ -89,11 +94,12 @@ public class DefaultLdapAuthoritiesPopulatorTests extends AbstractLdapIntegratio assertEquals("ROLE_MANAGER", authorities[0].getAuthority()); } + @Test public void testSubGroupRolesAreNotFoundByDefault() { populator.setGroupRoleAttribute("ou"); populator.setConvertToUpperCase(true); - DirContextAdapter ctx = new DirContextAdapter(new DistinguishedName("uid=ben,ou=people,dc=acegisecurity,dc=org")); + DirContextAdapter ctx = new DirContextAdapter(new DistinguishedName("uid=ben,ou=people,dc=springframework,dc=org")); GrantedAuthority[] authorities = populator.getGrantedAuthorities(ctx, "manager"); @@ -105,12 +111,13 @@ public class DefaultLdapAuthoritiesPopulatorTests extends AbstractLdapIntegratio assertTrue(roles.contains("ROLE_DEVELOPER")); } + @Test public void testSubGroupRolesAreFoundWhenSubtreeSearchIsEnabled() { populator.setGroupRoleAttribute("ou"); populator.setConvertToUpperCase(true); populator.setSearchSubtree(true); - DirContextAdapter ctx = new DirContextAdapter(new DistinguishedName("uid=ben,ou=people,dc=acegisecurity,dc=org")); + DirContextAdapter ctx = new DirContextAdapter(new DistinguishedName("uid=ben,ou=people,dc=springframework,dc=org")); GrantedAuthority[] authorities = populator.getGrantedAuthorities(ctx, "manager"); diff --git a/core/src/test/java/org/springframework/security/userdetails/ldap/LdapUserDetailsManagerTests.java b/core/src/test/java/org/springframework/security/userdetails/ldap/LdapUserDetailsManagerTests.java index bd41ee3d38..7cb3d599cb 100644 --- a/core/src/test/java/org/springframework/security/userdetails/ldap/LdapUserDetailsManagerTests.java +++ b/core/src/test/java/org/springframework/security/userdetails/ldap/LdapUserDetailsManagerTests.java @@ -26,6 +26,10 @@ import org.springframework.security.context.SecurityContextHolder; import org.springframework.ldap.core.DirContextAdapter; +import static org.junit.Assert.*; +import org.junit.After; +import org.junit.Test; + /** * @author Luke Taylor * @version $Id$ @@ -36,7 +40,7 @@ public class LdapUserDetailsManagerTests extends AbstractLdapIntegrationTests { private LdapUserDetailsManager mgr; private SpringSecurityLdapTemplate template; - protected void onSetUp() throws Exception { + public void onSetUp() throws Exception { super.onSetUp(); mgr = new LdapUserDetailsManager(getContextSource()); template = new SpringSecurityLdapTemplate(getContextSource()); @@ -53,7 +57,7 @@ public class LdapUserDetailsManagerTests extends AbstractLdapIntegrationTests { group.setAttributeValue("objectclass", "groupOfNames"); group.setAttributeValue("cn", "clowns"); - group.setAttributeValue("member", "cn=nobody,ou=testpeople,dc=acegisecurity,dc=org"); + group.setAttributeValue("member", "cn=nobody,ou=testpeople,dc=springframework,dc=org"); template.bind("cn=clowns,ou=testgroups", group, null); group.setAttributeValue("cn", "acrobats"); @@ -66,8 +70,8 @@ public class LdapUserDetailsManagerTests extends AbstractLdapIntegrationTests { mgr.setUserDetailsMapper(new PersonContextMapper()); } - - protected void onTearDown() throws Exception { + @After + public void onTearDown() throws Exception { // Iterator people = template.list("ou=testpeople").iterator(); // DirContext rootCtx = new DirContextAdapter(new DistinguishedName(getInitialCtxFactory().getRootDn())); @@ -80,9 +84,9 @@ public class LdapUserDetailsManagerTests extends AbstractLdapIntegrationTests { template.unbind("ou=testgroups",true); SecurityContextHolder.clearContext(); - super.onTearDown(); } + @Test public void testLoadUserByUsernameReturnsCorrectData() { mgr.setUserDnBase("ou=people"); mgr.setGroupSearchBase("ou=groups"); @@ -94,6 +98,7 @@ public class LdapUserDetailsManagerTests extends AbstractLdapIntegrationTests { assertEquals(1, bob.getAuthorities().length); } + @Test public void testLoadingInvalidUsernameThrowsUsernameNotFoundException() { try { @@ -104,15 +109,18 @@ public class LdapUserDetailsManagerTests extends AbstractLdapIntegrationTests { } } + @Test public void testUserExistsReturnsTrueForValidUser() { mgr.setUserDnBase("ou=people"); assertTrue(mgr.userExists("bob")); } + @Test public void testUserExistsReturnsFalseForInValidUser() { assertFalse(mgr.userExists("jim")); } + @Test public void testCreateNewUserSucceeds() { InetOrgPerson.Essence p = new InetOrgPerson.Essence(); p.setCn(new String[] {"Joe Smeth"}); @@ -123,6 +131,7 @@ public class LdapUserDetailsManagerTests extends AbstractLdapIntegrationTests { mgr.createUser(p.createUserDetails()); } + @Test public void testDeleteUserSucceeds() { InetOrgPerson.Essence p = new InetOrgPerson.Essence(); p.setCn(new String[] {"Don Smeth"}); @@ -150,6 +159,7 @@ public class LdapUserDetailsManagerTests extends AbstractLdapIntegrationTests { assertEquals(0, mgr.getUserAuthorities(mgr.buildDn("don"), "don").length); } + @Test public void testPasswordChangeWithCorrectOldPasswordSucceeds() { InetOrgPerson.Essence p = new InetOrgPerson.Essence(); p.setCn(new String[] {"John Yossarian"}); @@ -165,10 +175,11 @@ public class LdapUserDetailsManagerTests extends AbstractLdapIntegrationTests { mgr.changePassword("yossarianspassword", "yossariansnewpassword"); - assertTrue(template.compare("uid=johnyossarian,ou=testpeople,dc=acegisecurity,dc=org", + assertTrue(template.compare("uid=johnyossarian,ou=testpeople,dc=springframework,dc=org", "userPassword", "yossariansnewpassword")); } + @Test public void testPasswordChangeWithWrongOldPasswordFails() { InetOrgPerson.Essence p = new InetOrgPerson.Essence(); p.setCn(new String[] {"John Yossarian"}); diff --git a/core/src/test/resources/org/springframework/security/ldap/apacheDsContext.xml b/core/src/test/resources/org/springframework/security/ldap/apacheDsContext.xml deleted file mode 100644 index 4f3e40a0b5..0000000000 --- a/core/src/test/resources/org/springframework/security/ldap/apacheDsContext.xml +++ /dev/null @@ -1,81 +0,0 @@ - - - - - - - - - - simple - - - ${userDn} - - - ${password} - - - - - - - - - - - - - - - - objectClass: top - objectClass: domain - objectClass: extensibleObject - dc: acegisecurity - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/core/src/test/resources/org/springframework/security/ldap/ldapIntegrationTestContext.xml b/core/src/test/resources/org/springframework/security/ldap/ldapIntegrationTestContext.xml index c0cef29064..f904fe92e0 100644 --- a/core/src/test/resources/org/springframework/security/ldap/ldapIntegrationTestContext.xml +++ b/core/src/test/resources/org/springframework/security/ldap/ldapIntegrationTestContext.xml @@ -1,34 +1,16 @@ + xmlns:security="http://www.springframework.org/schema/security" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd + http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security-2.0.xsd"> - + - - - - - - - - - - - + - - + diff --git a/core/src/test/resources/org/springframework/security/ldap/ldapserver.properties b/core/src/test/resources/org/springframework/security/ldap/ldapserver.properties deleted file mode 100644 index ad3658b615..0000000000 --- a/core/src/test/resources/org/springframework/security/ldap/ldapserver.properties +++ /dev/null @@ -1,5 +0,0 @@ -urls=ldap://127.0.0.1:3999 -userDn=uid=admin,ou=system -password=secret -base=dc=acegisecurity,dc=org -fullUrl=ldap://127.0.0.1:3999/dc=acegisecurity,dc=org \ No newline at end of file diff --git a/core/src/test/resources/org/springframework/security/ldap/setup_data.ldif b/core/src/test/resources/org/springframework/security/ldap/setup_data.ldif deleted file mode 100644 index f3e9d8b1f2..0000000000 --- a/core/src/test/resources/org/springframework/security/ldap/setup_data.ldif +++ /dev/null @@ -1,56 +0,0 @@ -dn: ou=groups,dc=acegisecurity,dc=org -objectclass: top -objectclass: organizationalUnit -ou: groups - -dn: ou=subgroups,ou=groups,dc=acegisecurity,dc=org -objectclass: top -objectclass: organizationalUnit -ou: subgroups - -dn: ou=people,dc=acegisecurity,dc=org -objectclass: top -objectclass: organizationalUnit -ou: groups - -dn: uid=ben,ou=people,dc=acegisecurity,dc=org -objectclass: top -objectclass: person -objectclass: organizationalPerson -objectclass: inetOrgPerson -cn: Ben Alex -sn: Alex -uid: ben -userPassword: {SHA}nFCebWjxfaLbHHG1Qk5UU4trbvQ= - -dn: uid=bob,ou=people,dc=acegisecurity,dc=org -objectclass: top -objectclass: person -objectclass: organizationalPerson -objectclass: inetOrgPerson -cn: Bob Hamilton -sn: Hamilton -uid: bob -userPassword: bobspassword - -dn: cn=developers,ou=groups,dc=acegisecurity,dc=org -objectclass: top -objectclass: groupOfNames -cn: developers -ou: developer -member: uid=ben,ou=people,dc=acegisecurity,dc=org -member: uid=bob,ou=people,dc=acegisecurity,dc=org - -dn: cn=managers,ou=groups,dc=acegisecurity,dc=org -objectclass: top -objectclass: groupOfNames -cn: managers -ou: manager -member: uid=ben,ou=people,dc=acegisecurity,dc=org - -dn: cn=submanagers,ou=subgroups,ou=groups,dc=acegisecurity,dc=org -objectclass: top -objectclass: groupOfNames -cn: submanagers -ou: submanager -member: uid=ben,ou=people,dc=acegisecurity,dc=org diff --git a/core/src/test/resources/org/springframework/security/providers/ldap/ldif/acegisecurity.ldif b/core/src/test/resources/org/springframework/security/providers/ldap/ldif/acegisecurity.ldif deleted file mode 100644 index a4ea0db615..0000000000 --- a/core/src/test/resources/org/springframework/security/providers/ldap/ldif/acegisecurity.ldif +++ /dev/null @@ -1,56 +0,0 @@ -version: 1 -dn: dc=acegisecurity,dc=org -objectClass: dcObject -objectClass: organization -dc: acegisecurity -description: Acegi Security (Test LDAP DIT) -o: Monkey Machine Ltd. - -dn: ou=people,dc=acegisecurity,dc=org -objectClass: organizationalUnit -description: All people in organisation -ou: people - -dn: cn=Ben Alex,ou=people,dc=acegisecurity,dc=org -objectClass: inetOrgPerson -objectClass: organizationalPerson -objectClass: person -objectClass: top -cn: Ben Alex -ou:: 5a6J5YWo -sn: Alex -uid: Ben -userPassword:: e1NIQX1uRkNlYldqeGZhTGJISEcxUWs1VVU0dHJidlE9 - -dn: uid=bob,ou=people,dc=acegisecurity,dc=org -objectClass: inetOrgPerson -objectClass: organizationalPerson -objectClass: person -objectClass: top -cn: Bob Hamilton -sn: Hamilton -uid: bob -userPassword:: Ym9ic3Bhc3N3b3Jk - -dn: ou=groups,dc=acegisecurity,dc=org -objectClass: top -objectClass: organizationalUnit -ou: groups - -dn: cn=developers,ou=groups,dc=acegisecurity,dc=org -objectClass: groupOfNames -objectClass: top -cn: developers -description: Acegi Security Developers -member: uid=bob,ou=people,dc=acegisecurity,dc=org -member: cn=ben alex,ou=people,dc=acegisecurity,dc=org -o: Acegi Security System for Spring -ou: developer - -dn: cn=managers,ou=groups,dc=acegisecurity,dc=org -objectClass: groupOfNames -objectClass: top -cn: managers -member: cn=ben alex,ou=people,dc=acegisecurity,dc=org -ou: manager - diff --git a/samples/contacts/src/main/webapp/WEB-INF/applicationContext-acegi-security-ldap.xml b/samples/contacts/src/main/webapp/WEB-INF/applicationContext-acegi-security-ldap.xml index bee1699068..077f1bdf6d 100644 --- a/samples/contacts/src/main/webapp/WEB-INF/applicationContext-acegi-security-ldap.xml +++ b/samples/contacts/src/main/webapp/WEB-INF/applicationContext-acegi-security-ldap.xml @@ -37,8 +37,8 @@ - - + + diff --git a/sandbox/spring-security-config/src/test/resources/org/springframework/security/config/ldap-config.xml b/sandbox/spring-security-config/src/test/resources/org/springframework/security/config/ldap-config.xml index 0f9a3338c1..6aac32af73 100644 --- a/sandbox/spring-security-config/src/test/resources/org/springframework/security/config/ldap-config.xml +++ b/sandbox/spring-security-config/src/test/resources/org/springframework/security/config/ldap-config.xml @@ -4,7 +4,7 @@ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:security="http://www.springframework.org/schema/security" xmlns:beans="http://www.springframework.org/schema/beans" - xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd + xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security-2.0.xsd"> @@ -12,9 +12,9 @@ - @@ -29,15 +29,15 @@