Fix for LDAP-83

This commit is contained in:
Mattias Arthursson
2007-10-18 19:57:35 +00:00
parent a127240d96
commit 10e2eaa9db
2 changed files with 689 additions and 698 deletions

View File

@@ -61,478 +61,455 @@ import org.springframework.ldap.support.LdapUtils;
* @author Adam Skogman
* @author Ulrik Sandberg
*/
public abstract class AbstractContextSource implements ContextSource,
InitializingBean {
private static final Class DEFAULT_CONTEXT_FACTORY = com.sun.jndi.ldap.LdapCtxFactory.class;
private static final Class DEFAULT_DIR_OBJECT_FACTORY = DefaultDirObjectFactory.class;
private Class dirObjectFactory = DEFAULT_DIR_OBJECT_FACTORY;
private Class contextFactory = DEFAULT_CONTEXT_FACTORY;
private DistinguishedName base = DistinguishedName.EMPTY_PATH;
protected String userDn = "";
protected String password = "";
private String[] urls;
private boolean pooled = true;
private Hashtable baseEnv = new Hashtable();
private Hashtable anonymousEnv;
private AuthenticationSource authenticationSource;
private boolean cacheEnvironmentProperties = true;
private boolean anonymousReadOnly = false;
private static final Log log = LogFactory.getLog(LdapContextSource.class);
public static final String SUN_LDAP_POOLING_FLAG = "com.sun.jndi.ldap.connect.pool";
private static final String JDK_142 = "1.4.2";
/*
* (non-Javadoc)
*
* @see org.springframework.ldap.core.ContextSource#getReadOnlyContext()
*/
public DirContext getReadOnlyContext() {
if (!anonymousReadOnly) {
return createContext(getAuthenticatedEnv());
} else {
return createContext(getAnonymousEnv());
}
}
/*
* (non-Javadoc)
*
* @see org.springframework.ldap.core.ContextSource#getReadWriteContext()
*/
public DirContext getReadWriteContext() {
return createContext(getAuthenticatedEnv());
}
/**
* Default implementation of setting the environment up to be authenticated.
* Override in subclass if necessary.
*
* @param env
* the environment to modify.
*/
protected void setupAuthenticatedEnvironment(Hashtable env) {
env
.put(Context.SECURITY_PRINCIPAL, authenticationSource
.getPrincipal());
log.debug("Principal: '" + userDn + "'");
env.put(Context.SECURITY_CREDENTIALS, authenticationSource
.getCredentials());
}
/**
* Close the context and swallow any exceptions.
*
* @param ctx
* the DirContext to close.
*/
private void closeContext(DirContext ctx) {
if (ctx != null) {
try {
ctx.close();
} catch (Exception e) {
}
}
}
/**
* Assemble a valid url String from all registered urls to add as
* <code>PROVIDER_URL</code> to the environment.
*
* @param ldapUrls
* all individual url Strings.
* @return the full url String
*/
protected String assembleProviderUrlString(String[] ldapUrls) {
StringBuffer providerUrlBuffer = new StringBuffer(1024);
for (int i = 0; i < ldapUrls.length; i++) {
providerUrlBuffer.append(ldapUrls[i]);
if (!DistinguishedName.EMPTY_PATH.equals(base)) {
if (!ldapUrls[i].endsWith("/")) {
providerUrlBuffer.append("/");
}
}
providerUrlBuffer.append(base.toUrl());
providerUrlBuffer.append(' ');
}
return providerUrlBuffer.toString().trim();
}
/**
* Set the base suffix from which all operations should origin. If a base
* suffix is set, you will not have to (and, indeed, must not) specify the
* full distinguished names in any operations performed.
*
* @param base
* the base suffix.
*/
public void setBase(String base) {
this.base = new DistinguishedName(base);
}
/**
* Get the base suffix from which all operations should originate. If a base
* suffix is set, you will not have to (and, indeed, must not) specify the
* full distinguished names in any operations performed.
*
* @return the base suffix
*/
protected DistinguishedName getBase() {
return base;
}
/**
* Create a DirContext using the supplied environment.
*
* @param environment
* the Ldap environment to use when creating the
* <code>DirContext</code>.
* @return a new DirContext implpementation initialized with the supplied
* environment.
*/
DirContext createContext(Hashtable environment) {
DirContext ctx = null;
try {
ctx = getDirContextInstance(environment);
if (log.isInfoEnabled()) {
Hashtable ctxEnv = ctx.getEnvironment();
String ldapUrl = (String) ctxEnv.get(Context.PROVIDER_URL);
log.debug("Got Ldap context on server '" + ldapUrl + "'");
}
return ctx;
} catch (NamingException e) {
closeContext(ctx);
throw LdapUtils.convertLdapException(e);
}
}
/**
* Set the context factory. Default is com.sun.jndi.ldap.LdapCtxFactory.
*
* @param contextFactory
* the context factory used when creating Contexts.
*/
public void setContextFactory(Class contextFactory) {
this.contextFactory = contextFactory;
}
/**
* Get the context factory.
*
* @return the context factory used when creating Contexts.
*/
public Class getContextFactory() {
return contextFactory;
}
/**
* Set the DirObjectFactory to use. Default is
* {@link DefaultDirObjectFactory}. The specified class needs to be an
* implementation of javax.naming.spi.DirObjectFactory. <b>Note: </b>Setting
* this value to null may have cause connection leaks when using
* ContextMapper methods in LdapTemplate.
*
* @param dirObjectFactory
* the DirObjectFactory to be used. Null means that no
* DirObjectFactory will be used.
*/
public void setDirObjectFactory(Class dirObjectFactory) {
this.dirObjectFactory = dirObjectFactory;
}
/**
* Get the DirObjectFactory to use.
*
* @return the DirObjectFactory to be used. <code>null</code> means that
* no DirObjectFactory will be used.
*/
public Class getDirObjectFactory() {
return dirObjectFactory;
}
/**
* Checks that all necessary data is set and that there is no compatibility
* issues, after which the instance is initialized. Note that you need to
* call this method explicitly after setting all desired properties if using
* the class outside of a Spring Context.
*/
public void afterPropertiesSet() throws Exception {
if (ArrayUtils.isEmpty(urls)) {
throw new IllegalArgumentException(
"At least one server url must be set");
}
if (!DistinguishedName.EMPTY_PATH.equals(base)
&& getJdkVersion().compareTo(JDK_142) < 0) {
throw new IllegalArgumentException(
"Base path is not supported for JDK versions < 1.4.2");
}
if (authenticationSource == null) {
log.debug("AuthenticationSource not set - "
+ "using default implementation");
if (StringUtils.isBlank(userDn)) {
log
.info("Property 'userDn' not set - "
+ "anonymous context will be used for read-write operations");
} else if (StringUtils.isBlank(password)) {
log.info("Property 'password' not set - "
+ "blank password will be used");
}
authenticationSource = new SimpleAuthenticationSource();
}
if (cacheEnvironmentProperties) {
anonymousEnv = setupAnonymousEnv();
}
}
private Hashtable setupAnonymousEnv() {
if (pooled) {
baseEnv.put(SUN_LDAP_POOLING_FLAG, "true");
log.debug("Using LDAP pooling.");
} else {
log.debug("Not using LDAP pooling");
}
Hashtable env = new Hashtable(baseEnv);
env.put(Context.INITIAL_CONTEXT_FACTORY, contextFactory.getName());
env.put(Context.PROVIDER_URL, assembleProviderUrlString(urls));
if (dirObjectFactory != null) {
env.put(Context.OBJECT_FACTORIES, dirObjectFactory.getName());
}
if (!DistinguishedName.EMPTY_PATH.equals(base)) {
// Save the base path for use in the DefaultDirObjectFactory.
env.put(DefaultDirObjectFactory.JNDI_ENV_BASE_PATH_KEY, base);
}
log.debug("Trying provider Urls: " + assembleProviderUrlString(urls));
return env;
}
/**
* Set the password (credentials) to use for getting authenticated contexts.
*
* @param password
* the password.
*/
public void setPassword(String password) {
this.password = password;
}
/**
* Set the user distinguished name (principal) to use for getting
* authenticated contexts.
*
* @param userDn
* the user distinguished name.
*/
public void setUserDn(String userDn) {
this.userDn = userDn;
}
/**
* Set the user distinguished name (principal) to use for getting
* authenticated contexts.
*
* @param userName
* the user distinguished name.
* @deprecated Use {@link #setUserDn(String)} instead.
*/
public void setUserName(String userName) {
setUserDn(userName);
}
/**
* Set the urls of the LDAP servers. Use this method if several servers are
* required.
*
* @param urls
* the urls of all servers.
*/
public void setUrls(String[] urls) {
this.urls = urls;
}
/**
* Get the urls of the LDAP servers.
*
* @return the urls of all servers.
*/
public String[] getUrls() {
return urls;
}
/**
* Set the url of the LDAP server. Utility method if only one server is
* used.
*
* @param url
* the url of the LDAP server.
*/
public void setUrl(String url) {
this.urls = new String[] { url };
}
/**
* Set whether the pooling flag should be set. Default is true. Note that
* since LDAP pooling is system wide, full configuration of this needs be
* done using system parameters as specified in the LDAP/JNDI documentation.
* Also note, that pooling is done on user dn basis, i.e. each individually
* authenticated connection will be pooled separately. This means that LDAP
* pooling will be most efficient using anonymous connections or connections
* authenticated using one single system user.
*
* @param pooled
* whether Contexts should be pooled.
*/
public void setPooled(boolean pooled) {
this.pooled = pooled;
}
/**
* Get whether the pooling flag should be set.
*
* @return whether Contexts should be pooled.
*/
public boolean isPooled() {
return pooled;
}
/**
* If any custom environment properties are needed, these can be set using
* this method.
*
* @param baseEnvironmentProperties
*/
public void setBaseEnvironmentProperties(Map baseEnvironmentProperties) {
this.baseEnv = new Hashtable(baseEnvironmentProperties);
}
String getJdkVersion() {
return JdkVersion.getJavaVersion();
}
protected Hashtable getAnonymousEnv() {
if (cacheEnvironmentProperties) {
return anonymousEnv;
} else {
return setupAnonymousEnv();
}
}
protected Hashtable getAuthenticatedEnv() {
// The authenticated environment should always be rebuilt.
Hashtable env = new Hashtable(getAnonymousEnv());
setupAuthenticatedEnvironment(env);
return env;
}
/**
* Set the authentication source to use when retrieving user principal and
* credentials.
*
* @param authenticationSource
* the {@link AuthenticationSource} that will provide user info.
*/
public void setAuthenticationSource(
AuthenticationSource authenticationSource) {
this.authenticationSource = authenticationSource;
}
/**
* Get the authentication source.
*
* @return the {@link AuthenticationSource} that will provide user info.
*/
public AuthenticationSource getAuthenticationSource() {
return authenticationSource;
}
/**
* Set whether environment properties should be cached between requsts for
* anonymous environment. Default is <code>true</code>; setting this
* property to <code>false</code> causes the environment Hashmap to be
* rebuilt from the current property settings of this instance between each
* request for an anonymous environment.
*
* @param cacheEnvironmentProperties
* <code>true</code> causes that the anonymous environment
* properties should be cached, <code>false</code> causes the
* Hashmap to be rebuilt for each request.
*/
public void setCacheEnvironmentProperties(boolean cacheEnvironmentProperties) {
this.cacheEnvironmentProperties = cacheEnvironmentProperties;
}
/**
* Set whether an anonymous environment should be used for read-only
* operations. Default is <code>false</code>.
*
* @param anonymousReadOnly
* <code>true</code> if an anonymous environment should be used
* for read-only operations, <code>false</code> otherwise.
*/
public void setAnonymousReadOnly(boolean anonymousReadOnly) {
this.anonymousReadOnly = anonymousReadOnly;
}
/**
* Get whether an anonymous environment should be used for read-only
* operations.
*
* @return <code>true</code> if an anonymous environment should be used
* for read-only operations, <code>false</code> otherwise.
*/
public boolean isAnonymousReadOnly() {
return anonymousReadOnly;
}
/**
* Implement in subclass to create a DirContext of the desired type (e.g.
* InitialDirContext or InitialLdapContext).
*
* @param environment
* the environment to use when creating the instance.
* @return a new DirContext instance.
* @throws NamingException
* if one is encountered when creating the instance.
*/
protected abstract DirContext getDirContextInstance(Hashtable environment)
throws NamingException;
class SimpleAuthenticationSource implements AuthenticationSource {
public String getPrincipal() {
return userDn;
}
public String getCredentials() {
return password;
}
}
public abstract class AbstractContextSource implements ContextSource, InitializingBean {
private static final Class DEFAULT_CONTEXT_FACTORY = com.sun.jndi.ldap.LdapCtxFactory.class;
private static final Class DEFAULT_DIR_OBJECT_FACTORY = DefaultDirObjectFactory.class;
private Class dirObjectFactory = DEFAULT_DIR_OBJECT_FACTORY;
private Class contextFactory = DEFAULT_CONTEXT_FACTORY;
private DistinguishedName base = DistinguishedName.EMPTY_PATH;
protected String userDn = "";
protected String password = "";
private String[] urls;
private boolean pooled = true;
private Hashtable baseEnv = new Hashtable();
private Hashtable anonymousEnv;
private AuthenticationSource authenticationSource;
private boolean cacheEnvironmentProperties = true;
private boolean anonymousReadOnly = false;
private static final Log log = LogFactory.getLog(LdapContextSource.class);
public static final String SUN_LDAP_POOLING_FLAG = "com.sun.jndi.ldap.connect.pool";
private static final String JDK_142 = "1.4.2";
/*
* (non-Javadoc)
*
* @see org.springframework.ldap.core.ContextSource#getReadOnlyContext()
*/
public DirContext getReadOnlyContext() {
if (!anonymousReadOnly) {
return createContext(getAuthenticatedEnv());
}
else {
return createContext(getAnonymousEnv());
}
}
/*
* (non-Javadoc)
*
* @see org.springframework.ldap.core.ContextSource#getReadWriteContext()
*/
public DirContext getReadWriteContext() {
return createContext(getAuthenticatedEnv());
}
/**
* Default implementation of setting the environment up to be authenticated.
* Override in subclass if necessary.
*
* @param env the environment to modify.
*/
protected void setupAuthenticatedEnvironment(Hashtable env) {
env.put(Context.SECURITY_PRINCIPAL, authenticationSource.getPrincipal());
log.debug("Principal: '" + userDn + "'");
env.put(Context.SECURITY_CREDENTIALS, authenticationSource.getCredentials());
}
/**
* Close the context and swallow any exceptions.
*
* @param ctx the DirContext to close.
*/
private void closeContext(DirContext ctx) {
if (ctx != null) {
try {
ctx.close();
}
catch (Exception e) {
}
}
}
/**
* Assemble a valid url String from all registered urls to add as
* <code>PROVIDER_URL</code> to the environment.
*
* @param ldapUrls all individual url Strings.
* @return the full url String
*/
protected String assembleProviderUrlString(String[] ldapUrls) {
StringBuffer providerUrlBuffer = new StringBuffer(1024);
for (int i = 0; i < ldapUrls.length; i++) {
providerUrlBuffer.append(ldapUrls[i]);
if (!DistinguishedName.EMPTY_PATH.equals(base)) {
if (!ldapUrls[i].endsWith("/")) {
providerUrlBuffer.append("/");
}
}
providerUrlBuffer.append(base.toUrl());
providerUrlBuffer.append(' ');
}
return providerUrlBuffer.toString().trim();
}
/**
* Set the base suffix from which all operations should origin. If a base
* suffix is set, you will not have to (and, indeed, must not) specify the
* full distinguished names in any operations performed.
*
* @param base the base suffix.
*/
public void setBase(String base) {
this.base = new DistinguishedName(base);
}
/**
* Get the base suffix from which all operations should originate. If a base
* suffix is set, you will not have to (and, indeed, must not) specify the
* full distinguished names in any operations performed.
*
* @return the base suffix
*/
protected DistinguishedName getBase() {
return base;
}
/**
* Create a DirContext using the supplied environment.
*
* @param environment the Ldap environment to use when creating the
* <code>DirContext</code>.
* @return a new DirContext implpementation initialized with the supplied
* environment.
*/
DirContext createContext(Hashtable environment) {
DirContext ctx = null;
try {
ctx = getDirContextInstance(environment);
if (log.isInfoEnabled()) {
Hashtable ctxEnv = ctx.getEnvironment();
String ldapUrl = (String) ctxEnv.get(Context.PROVIDER_URL);
log.debug("Got Ldap context on server '" + ldapUrl + "'");
}
return ctx;
}
catch (NamingException e) {
closeContext(ctx);
throw LdapUtils.convertLdapException(e);
}
}
/**
* Set the context factory. Default is com.sun.jndi.ldap.LdapCtxFactory.
*
* @param contextFactory the context factory used when creating Contexts.
*/
public void setContextFactory(Class contextFactory) {
this.contextFactory = contextFactory;
}
/**
* Get the context factory.
*
* @return the context factory used when creating Contexts.
*/
public Class getContextFactory() {
return contextFactory;
}
/**
* Set the DirObjectFactory to use. Default is
* {@link DefaultDirObjectFactory}. The specified class needs to be an
* implementation of javax.naming.spi.DirObjectFactory. <b>Note: </b>Setting
* this value to null may have cause connection leaks when using
* ContextMapper methods in LdapTemplate.
*
* @param dirObjectFactory the DirObjectFactory to be used. Null means that
* no DirObjectFactory will be used.
*/
public void setDirObjectFactory(Class dirObjectFactory) {
this.dirObjectFactory = dirObjectFactory;
}
/**
* Get the DirObjectFactory to use.
*
* @return the DirObjectFactory to be used. <code>null</code> means that
* no DirObjectFactory will be used.
*/
public Class getDirObjectFactory() {
return dirObjectFactory;
}
/**
* Checks that all necessary data is set and that there is no compatibility
* issues, after which the instance is initialized. Note that you need to
* call this method explicitly after setting all desired properties if using
* the class outside of a Spring Context.
*/
public void afterPropertiesSet() throws Exception {
if (ArrayUtils.isEmpty(urls)) {
throw new IllegalArgumentException("At least one server url must be set");
}
if (!DistinguishedName.EMPTY_PATH.equals(base) && getJdkVersion().compareTo(JDK_142) < 0) {
throw new IllegalArgumentException("Base path is not supported for JDK versions < 1.4.2");
}
if (authenticationSource == null) {
log.debug("AuthenticationSource not set - " + "using default implementation");
if (StringUtils.isBlank(userDn)) {
log.info("Property 'userDn' not set - " + "anonymous context will be used for read-write operations");
}
else if (StringUtils.isBlank(password)) {
log.info("Property 'password' not set - " + "blank password will be used");
}
authenticationSource = new SimpleAuthenticationSource();
}
if (cacheEnvironmentProperties) {
anonymousEnv = setupAnonymousEnv();
}
}
private Hashtable setupAnonymousEnv() {
if (pooled) {
baseEnv.put(SUN_LDAP_POOLING_FLAG, "true");
log.debug("Using LDAP pooling.");
}
else {
baseEnv.remove(SUN_LDAP_POOLING_FLAG);
log.debug("Not using LDAP pooling");
}
Hashtable env = new Hashtable(baseEnv);
env.put(Context.INITIAL_CONTEXT_FACTORY, contextFactory.getName());
env.put(Context.PROVIDER_URL, assembleProviderUrlString(urls));
if (dirObjectFactory != null) {
env.put(Context.OBJECT_FACTORIES, dirObjectFactory.getName());
}
if (!DistinguishedName.EMPTY_PATH.equals(base)) {
// Save the base path for use in the DefaultDirObjectFactory.
env.put(DefaultDirObjectFactory.JNDI_ENV_BASE_PATH_KEY, base);
}
log.debug("Trying provider Urls: " + assembleProviderUrlString(urls));
return env;
}
/**
* Set the password (credentials) to use for getting authenticated contexts.
*
* @param password the password.
*/
public void setPassword(String password) {
this.password = password;
}
/**
* Set the user distinguished name (principal) to use for getting
* authenticated contexts.
*
* @param userDn the user distinguished name.
*/
public void setUserDn(String userDn) {
this.userDn = userDn;
}
/**
* Set the user distinguished name (principal) to use for getting
* authenticated contexts.
*
* @param userName the user distinguished name.
* @deprecated Use {@link #setUserDn(String)} instead.
*/
public void setUserName(String userName) {
setUserDn(userName);
}
/**
* Set the urls of the LDAP servers. Use this method if several servers are
* required.
*
* @param urls the urls of all servers.
*/
public void setUrls(String[] urls) {
this.urls = urls;
}
/**
* Get the urls of the LDAP servers.
*
* @return the urls of all servers.
*/
public String[] getUrls() {
return urls;
}
/**
* Set the url of the LDAP server. Utility method if only one server is
* used.
*
* @param url the url of the LDAP server.
*/
public void setUrl(String url) {
this.urls = new String[] { url };
}
/**
* Set whether the pooling flag should be set. Default is true. Note that
* since LDAP pooling is system wide, full configuration of this needs be
* done using system parameters as specified in the LDAP/JNDI documentation.
* Also note, that pooling is done on user dn basis, i.e. each individually
* authenticated connection will be pooled separately. This means that LDAP
* pooling will be most efficient using anonymous connections or connections
* authenticated using one single system user.
*
* @param pooled whether Contexts should be pooled.
*/
public void setPooled(boolean pooled) {
this.pooled = pooled;
}
/**
* Get whether the pooling flag should be set.
*
* @return whether Contexts should be pooled.
*/
public boolean isPooled() {
return pooled;
}
/**
* If any custom environment properties are needed, these can be set using
* this method.
*
* @param baseEnvironmentProperties
*/
public void setBaseEnvironmentProperties(Map baseEnvironmentProperties) {
this.baseEnv = new Hashtable(baseEnvironmentProperties);
}
String getJdkVersion() {
return JdkVersion.getJavaVersion();
}
protected Hashtable getAnonymousEnv() {
if (cacheEnvironmentProperties) {
return anonymousEnv;
}
else {
return setupAnonymousEnv();
}
}
protected Hashtable getAuthenticatedEnv() {
// The authenticated environment should always be rebuilt.
Hashtable env = new Hashtable(getAnonymousEnv());
setupAuthenticatedEnvironment(env);
return env;
}
/**
* Set the authentication source to use when retrieving user principal and
* credentials.
*
* @param authenticationSource the {@link AuthenticationSource} that will
* provide user info.
*/
public void setAuthenticationSource(AuthenticationSource authenticationSource) {
this.authenticationSource = authenticationSource;
}
/**
* Get the authentication source.
*
* @return the {@link AuthenticationSource} that will provide user info.
*/
public AuthenticationSource getAuthenticationSource() {
return authenticationSource;
}
/**
* Set whether environment properties should be cached between requsts for
* anonymous environment. Default is <code>true</code>; setting this
* property to <code>false</code> causes the environment Hashmap to be
* rebuilt from the current property settings of this instance between each
* request for an anonymous environment.
*
* @param cacheEnvironmentProperties <code>true</code> causes that the
* anonymous environment properties should be cached, <code>false</code>
* causes the Hashmap to be rebuilt for each request.
*/
public void setCacheEnvironmentProperties(boolean cacheEnvironmentProperties) {
this.cacheEnvironmentProperties = cacheEnvironmentProperties;
}
/**
* Set whether an anonymous environment should be used for read-only
* operations. Default is <code>false</code>.
*
* @param anonymousReadOnly <code>true</code> if an anonymous environment
* should be used for read-only operations, <code>false</code> otherwise.
*/
public void setAnonymousReadOnly(boolean anonymousReadOnly) {
this.anonymousReadOnly = anonymousReadOnly;
}
/**
* Get whether an anonymous environment should be used for read-only
* operations.
*
* @return <code>true</code> if an anonymous environment should be used
* for read-only operations, <code>false</code> otherwise.
*/
public boolean isAnonymousReadOnly() {
return anonymousReadOnly;
}
/**
* Implement in subclass to create a DirContext of the desired type (e.g.
* InitialDirContext or InitialLdapContext).
*
* @param environment the environment to use when creating the instance.
* @return a new DirContext instance.
* @throws NamingException if one is encountered when creating the instance.
*/
protected abstract DirContext getDirContextInstance(Hashtable environment) throws NamingException;
class SimpleAuthenticationSource implements AuthenticationSource {
public String getPrincipal() {
return userDn;
}
public String getCredentials() {
return password;
}
}
}

View File

@@ -16,6 +16,7 @@
package org.springframework.ldap.core.support;
import java.util.HashMap;
import java.util.Hashtable;
import javax.naming.Context;
@@ -37,265 +38,278 @@ import com.sun.jndi.ldap.ctl.ResponseControlFactory;
*/
public class LdapContextSourceTest extends TestCase {
private LdapContextSource tested;
private LdapContextSource tested;
protected void setUp() throws Exception {
tested = new LdapContextSource();
}
protected void setUp() throws Exception {
tested = new LdapContextSource();
}
protected void tearDown() throws Exception {
tested = null;
}
protected void tearDown() throws Exception {
tested = null;
}
public void testAfterPropertiesSet_NoUrl() throws Exception {
try {
tested.afterPropertiesSet();
fail("IllegalArgumentException expected");
} catch (IllegalArgumentException expected) {
assertTrue(true);
}
}
public void testAfterPropertiesSet_NoUrl() throws Exception {
try {
tested.afterPropertiesSet();
fail("IllegalArgumentException expected");
}
catch (IllegalArgumentException expected) {
assertTrue(true);
}
}
public void testAfterPropertiesSet_BaseAndTooEarlyJdk() throws Exception {
tested = new LdapContextSource() {
String getJdkVersion() {
return "1.4.1_03";
}
};
public void testAfterPropertiesSet_BaseAndTooEarlyJdk() throws Exception {
tested = new LdapContextSource() {
String getJdkVersion() {
return "1.4.1_03";
}
};
tested.setUrl("http://ldap.example.com:389");
tested.setBase("dc=jayway,dc=se");
try {
tested.afterPropertiesSet();
fail("IllegalArgumentException expected");
} catch (IllegalArgumentException expected) {
assertTrue(true);
}
}
tested.setUrl("http://ldap.example.com:389");
tested.setBase("dc=jayway,dc=se");
try {
tested.afterPropertiesSet();
fail("IllegalArgumentException expected");
}
catch (IllegalArgumentException expected) {
assertTrue(true);
}
}
public void testGetAnonymousEnv() throws Exception {
tested.setBase("dc=example,dc=se");
tested.setUrl("ldap://ldap.example.com:389");
tested.setPooled(true);
tested.setUserDn("cn=Some User");
tested.setPassword("secret");
tested.afterPropertiesSet();
Hashtable env = tested.getAnonymousEnv();
assertEquals("ldap://ldap.example.com:389/dc=example,dc=se", env
.get(Context.PROVIDER_URL));
assertEquals("true", env.get(LdapContextSource.SUN_LDAP_POOLING_FLAG));
assertNull(env.get(Context.SECURITY_PRINCIPAL));
assertNull(env.get(Context.SECURITY_CREDENTIALS));
public void testGetAnonymousEnv() throws Exception {
tested.setBase("dc=example,dc=se");
tested.setUrl("ldap://ldap.example.com:389");
tested.setPooled(true);
tested.setUserDn("cn=Some User");
tested.setPassword("secret");
tested.afterPropertiesSet();
Hashtable env = tested.getAnonymousEnv();
assertEquals("ldap://ldap.example.com:389/dc=example,dc=se", env.get(Context.PROVIDER_URL));
assertEquals("true", env.get(LdapContextSource.SUN_LDAP_POOLING_FLAG));
assertNull(env.get(Context.SECURITY_PRINCIPAL));
assertNull(env.get(Context.SECURITY_CREDENTIALS));
// check that base was added to environment
assertEquals(new DistinguishedName("dc=example,dc=se"), env
.get(DefaultDirObjectFactory.JNDI_ENV_BASE_PATH_KEY));
// check that base was added to environment
assertEquals(new DistinguishedName("dc=example,dc=se"), env.get(DefaultDirObjectFactory.JNDI_ENV_BASE_PATH_KEY));
// Verify that changing values does not change the environment values.
tested.setBase("dc=other,dc=se");
tested.setUrl("ldap://ldap2.example.com:389");
tested.setPooled(false);
// Verify that changing values does not change the environment values.
tested.setBase("dc=other,dc=se");
tested.setUrl("ldap://ldap2.example.com:389");
tested.setPooled(false);
env = tested.getAnonymousEnv();
assertEquals("ldap://ldap.example.com:389/dc=example,dc=se", env
.get(Context.PROVIDER_URL));
assertEquals("true", env.get(LdapContextSource.SUN_LDAP_POOLING_FLAG));
assertNull(env.get(Context.SECURITY_PRINCIPAL));
assertNull(env.get(Context.SECURITY_CREDENTIALS));
env = tested.getAnonymousEnv();
assertEquals("ldap://ldap.example.com:389/dc=example,dc=se", env.get(Context.PROVIDER_URL));
assertEquals("true", env.get(LdapContextSource.SUN_LDAP_POOLING_FLAG));
assertNull(env.get(Context.SECURITY_PRINCIPAL));
assertNull(env.get(Context.SECURITY_CREDENTIALS));
assertEquals(new DistinguishedName("dc=example,dc=se"), env
.get(DefaultDirObjectFactory.JNDI_ENV_BASE_PATH_KEY));
}
assertEquals(new DistinguishedName("dc=example,dc=se"), env.get(DefaultDirObjectFactory.JNDI_ENV_BASE_PATH_KEY));
}
public void testGetAnonymousEnvWithNoBaseSet() throws Exception {
tested.setUrl("ldap://ldap.example.com:389");
tested.afterPropertiesSet();
Hashtable env = tested.getAnonymousEnv();
assertEquals("ldap://ldap.example.com:389", env
.get(Context.PROVIDER_URL));
public void testGetAnonymousEnvWithNoBaseSet() throws Exception {
tested.setUrl("ldap://ldap.example.com:389");
tested.afterPropertiesSet();
Hashtable env = tested.getAnonymousEnv();
assertEquals("ldap://ldap.example.com:389", env.get(Context.PROVIDER_URL));
// check that base was not added to environment
assertNull(env.get(DefaultDirObjectFactory.JNDI_ENV_BASE_PATH_KEY));
}
// check that base was not added to environment
assertNull(env.get(DefaultDirObjectFactory.JNDI_ENV_BASE_PATH_KEY));
}
public void testGetAnonymousEnvWithEmptyBaseSet() throws Exception {
tested.setUrl("ldap://ldap.example.com:389");
tested.setBase(null);
tested.afterPropertiesSet();
Hashtable env = tested.getAnonymousEnv();
assertEquals("ldap://ldap.example.com:389", env
.get(Context.PROVIDER_URL));
public void testGetAnonymousEnvWithBaseEnvironment() throws Exception {
tested.setUrl("ldap://ldap.example.com:389");
HashMap map = new HashMap();
map.put(LdapContextSource.SUN_LDAP_POOLING_FLAG, "true");
tested.setBaseEnvironmentProperties(map);
tested.afterPropertiesSet();
Hashtable env = tested.getAnonymousEnv();
assertEquals("ldap://ldap.example.com:389", env.get(Context.PROVIDER_URL));
assertEquals("true", env.get(LdapContextSource.SUN_LDAP_POOLING_FLAG));
}
// check that base was not added to environment
assertNull(env.get(DefaultDirObjectFactory.JNDI_ENV_BASE_PATH_KEY));
}
public void testGetAnonymousEnvWithPoolingInBaseEnvironmentAndPoolingOff() throws Exception {
tested.setUrl("ldap://ldap.example.com:389");
HashMap map = new HashMap();
map.put(LdapContextSource.SUN_LDAP_POOLING_FLAG, "true");
tested.setBaseEnvironmentProperties(map);
tested.setPooled(false);
tested.afterPropertiesSet();
Hashtable env = tested.getAnonymousEnv();
assertEquals("ldap://ldap.example.com:389", env.get(Context.PROVIDER_URL));
assertNull(env.get(LdapContextSource.SUN_LDAP_POOLING_FLAG));
}
public void testOldJdkWithNoBaseSetShouldWork() throws Exception {
tested = new LdapContextSource() {
String getJdkVersion() {
return "1.3";
}
};
tested.setUrl("ldap://ldap.example.com:389");
tested.afterPropertiesSet();
public void testGetAnonymousEnvWithEmptyBaseSet() throws Exception {
tested.setUrl("ldap://ldap.example.com:389");
tested.setBase(null);
tested.afterPropertiesSet();
Hashtable env = tested.getAnonymousEnv();
assertEquals("ldap://ldap.example.com:389", env.get(Context.PROVIDER_URL));
// check that base was not added to environment
Hashtable env = tested.getAnonymousEnv();
assertNull(env.get(DefaultDirObjectFactory.JNDI_ENV_BASE_PATH_KEY));
}
// check that base was not added to environment
assertNull(env.get(DefaultDirObjectFactory.JNDI_ENV_BASE_PATH_KEY));
}
public void testOldJdkWithBaseSetShouldNotWork() throws Exception {
tested = new LdapContextSource() {
String getJdkVersion() {
return "1.3";
}
};
tested.setUrl("ldap://ldap.example.com:389");
tested.setBase("dc=example,dc=com");
try {
tested.afterPropertiesSet();
fail("IllegalArgumentException expected");
} catch (IllegalArgumentException expected) {
assertTrue(true);
}
}
public void testOldJdkWithNoBaseSetShouldWork() throws Exception {
tested = new LdapContextSource() {
String getJdkVersion() {
return "1.3";
}
};
tested.setUrl("ldap://ldap.example.com:389");
tested.afterPropertiesSet();
public void testOldJdkWithBaseSetToEmptyPathShouldWork() throws Exception {
tested = new LdapContextSource() {
String getJdkVersion() {
return "1.3";
}
};
tested.setUrl("ldap://ldap.example.com:389");
tested.setBase(null);
tested.afterPropertiesSet();
// check that base was not added to environment
Hashtable env = tested.getAnonymousEnv();
assertNull(env.get(DefaultDirObjectFactory.JNDI_ENV_BASE_PATH_KEY));
}
// check that base was not added to environment
Hashtable env = tested.getAnonymousEnv();
assertNull(env.get(DefaultDirObjectFactory.JNDI_ENV_BASE_PATH_KEY));
}
public void testGetAuthenticatedEnv() throws Exception {
tested.setBase("dc=example,dc=se");
tested.setUrl("ldap://ldap.example.com:389");
tested.setPooled(true);
tested.setUserDn("cn=Some User");
tested.setPassword("secret");
tested.afterPropertiesSet();
public void testOldJdkWithBaseSetShouldNotWork() throws Exception {
tested = new LdapContextSource() {
String getJdkVersion() {
return "1.3";
}
};
tested.setUrl("ldap://ldap.example.com:389");
tested.setBase("dc=example,dc=com");
try {
tested.afterPropertiesSet();
fail("IllegalArgumentException expected");
}
catch (IllegalArgumentException expected) {
assertTrue(true);
}
}
Hashtable env = tested.getAuthenticatedEnv();
assertEquals("ldap://ldap.example.com:389/dc=example,dc=se", env
.get(Context.PROVIDER_URL));
assertEquals("true", env.get(LdapContextSource.SUN_LDAP_POOLING_FLAG));
assertEquals("cn=Some User", env.get(Context.SECURITY_PRINCIPAL));
assertEquals("secret", env.get(Context.SECURITY_CREDENTIALS));
public void testOldJdkWithBaseSetToEmptyPathShouldWork() throws Exception {
tested = new LdapContextSource() {
String getJdkVersion() {
return "1.3";
}
};
tested.setUrl("ldap://ldap.example.com:389");
tested.setBase(null);
tested.afterPropertiesSet();
// check that base was added to environment
assertEquals(new DistinguishedName("dc=example,dc=se"), env
.get(DefaultDirObjectFactory.JNDI_ENV_BASE_PATH_KEY));
}
// check that base was not added to environment
Hashtable env = tested.getAnonymousEnv();
assertNull(env.get(DefaultDirObjectFactory.JNDI_ENV_BASE_PATH_KEY));
}
public void testGetAuthenticatedEnv_DummyAuthenticationProvider()
throws Exception {
tested.setBase("dc=example,dc=se");
tested.setUrl("ldap://ldap.example.com:389");
tested.setPooled(true);
DummyAuthenticationProvider authenticationProvider = new DummyAuthenticationProvider();
tested.setAuthenticationSource(authenticationProvider);
authenticationProvider.setPrincipal("cn=Some User");
authenticationProvider.setCredentials("secret");
tested.afterPropertiesSet();
public void testGetAuthenticatedEnv() throws Exception {
tested.setBase("dc=example,dc=se");
tested.setUrl("ldap://ldap.example.com:389");
tested.setPooled(true);
tested.setUserDn("cn=Some User");
tested.setPassword("secret");
tested.afterPropertiesSet();
Hashtable env = tested.getAuthenticatedEnv();
assertEquals("ldap://ldap.example.com:389/dc=example,dc=se", env
.get(Context.PROVIDER_URL));
assertEquals("true", env.get(LdapContextSource.SUN_LDAP_POOLING_FLAG));
assertEquals("cn=Some User", env.get(Context.SECURITY_PRINCIPAL));
assertEquals("secret", env.get(Context.SECURITY_CREDENTIALS));
}
Hashtable env = tested.getAuthenticatedEnv();
assertEquals("ldap://ldap.example.com:389/dc=example,dc=se", env.get(Context.PROVIDER_URL));
assertEquals("true", env.get(LdapContextSource.SUN_LDAP_POOLING_FLAG));
assertEquals("cn=Some User", env.get(Context.SECURITY_PRINCIPAL));
assertEquals("secret", env.get(Context.SECURITY_CREDENTIALS));
public void testGetAuthenticatedEnv_DummyAuthenticationProvider_Changed()
throws Exception {
tested.setBase("dc=example,dc=se");
tested.setUrl("ldap://ldap.example.com:389");
tested.setPooled(true);
DummyAuthenticationProvider authenticationProvider = new DummyAuthenticationProvider();
tested.setAuthenticationSource(authenticationProvider);
authenticationProvider.setPrincipal("cn=Some User");
authenticationProvider.setCredentials("secret");
tested.afterPropertiesSet();
// check that base was added to environment
assertEquals(new DistinguishedName("dc=example,dc=se"), env.get(DefaultDirObjectFactory.JNDI_ENV_BASE_PATH_KEY));
}
authenticationProvider.setPrincipal("cn=Some Other User");
authenticationProvider.setCredentials("other secret");
public void testGetAuthenticatedEnv_DummyAuthenticationProvider() throws Exception {
tested.setBase("dc=example,dc=se");
tested.setUrl("ldap://ldap.example.com:389");
tested.setPooled(true);
DummyAuthenticationProvider authenticationProvider = new DummyAuthenticationProvider();
tested.setAuthenticationSource(authenticationProvider);
authenticationProvider.setPrincipal("cn=Some User");
authenticationProvider.setCredentials("secret");
tested.afterPropertiesSet();
Hashtable env = tested.getAuthenticatedEnv();
assertEquals("cn=Some Other User", env.get(Context.SECURITY_PRINCIPAL));
assertEquals("other secret", env.get(Context.SECURITY_CREDENTIALS));
}
Hashtable env = tested.getAuthenticatedEnv();
assertEquals("ldap://ldap.example.com:389/dc=example,dc=se", env.get(Context.PROVIDER_URL));
assertEquals("true", env.get(LdapContextSource.SUN_LDAP_POOLING_FLAG));
assertEquals("cn=Some User", env.get(Context.SECURITY_PRINCIPAL));
assertEquals("secret", env.get(Context.SECURITY_CREDENTIALS));
}
public void testGetAnonymousEnvWhenCacheIsOff() throws Exception {
tested.setBase("dc=example,dc=se");
tested.setUrl("ldap://ldap.example.com:389");
tested.setPooled(true);
tested.setUserDn("cn=Some User");
tested.setPassword("secret");
tested.setCacheEnvironmentProperties(false);
tested.afterPropertiesSet();
Hashtable env = tested.getAnonymousEnv();
assertEquals("ldap://ldap.example.com:389/dc=example,dc=se", env
.get(Context.PROVIDER_URL));
assertEquals("true", env.get(LdapContextSource.SUN_LDAP_POOLING_FLAG));
assertNull(env.get(Context.SECURITY_PRINCIPAL));
assertNull(env.get(Context.SECURITY_CREDENTIALS));
public void testGetAuthenticatedEnv_DummyAuthenticationProvider_Changed() throws Exception {
tested.setBase("dc=example,dc=se");
tested.setUrl("ldap://ldap.example.com:389");
tested.setPooled(true);
DummyAuthenticationProvider authenticationProvider = new DummyAuthenticationProvider();
tested.setAuthenticationSource(authenticationProvider);
authenticationProvider.setPrincipal("cn=Some User");
authenticationProvider.setCredentials("secret");
tested.afterPropertiesSet();
tested.setUrl("ldap://ldap2.example.com:389");
env = tested.getAnonymousEnv();
assertEquals("ldap://ldap2.example.com:389/dc=example,dc=se", env
.get(Context.PROVIDER_URL));
}
authenticationProvider.setPrincipal("cn=Some Other User");
authenticationProvider.setCredentials("other secret");
public void testSetResponseControlFactoryToNull() throws Exception {
tested.setResponseControlFactory(null);
assertNotNull(tested.getResponseControlFactory());
assertEquals(ResponseControlFactory.class, tested
.getResponseControlFactory());
}
Hashtable env = tested.getAuthenticatedEnv();
assertEquals("cn=Some Other User", env.get(Context.SECURITY_PRINCIPAL));
assertEquals("other secret", env.get(Context.SECURITY_CREDENTIALS));
}
public void testSetValidResponseControlFactory() throws Exception {
Class validClass = ControlFactory.class;
tested.setResponseControlFactory(validClass);
assertEquals(validClass, tested.getResponseControlFactory());
}
public void testGetAnonymousEnvWhenCacheIsOff() throws Exception {
tested.setBase("dc=example,dc=se");
tested.setUrl("ldap://ldap.example.com:389");
tested.setPooled(true);
tested.setUserDn("cn=Some User");
tested.setPassword("secret");
tested.setCacheEnvironmentProperties(false);
tested.afterPropertiesSet();
Hashtable env = tested.getAnonymousEnv();
assertEquals("ldap://ldap.example.com:389/dc=example,dc=se", env.get(Context.PROVIDER_URL));
assertEquals("true", env.get(LdapContextSource.SUN_LDAP_POOLING_FLAG));
assertNull(env.get(Context.SECURITY_PRINCIPAL));
assertNull(env.get(Context.SECURITY_CREDENTIALS));
public void testSetInvalidResponseControlFactory() throws Exception {
try {
Class invalidClass = Control.class;
tested.setResponseControlFactory(invalidClass);
fail("IllegalArgumentException expected");
} catch (IllegalArgumentException expected) {
assertTrue(true);
}
}
tested.setUrl("ldap://ldap2.example.com:389");
env = tested.getAnonymousEnv();
assertEquals("ldap://ldap2.example.com:389/dc=example,dc=se", env.get(Context.PROVIDER_URL));
}
private class DummyAuthenticationProvider implements AuthenticationSource {
private String principal;
public void testSetResponseControlFactoryToNull() throws Exception {
tested.setResponseControlFactory(null);
assertNotNull(tested.getResponseControlFactory());
assertEquals(ResponseControlFactory.class, tested.getResponseControlFactory());
}
private String credentials;
public void testSetValidResponseControlFactory() throws Exception {
Class validClass = ControlFactory.class;
tested.setResponseControlFactory(validClass);
assertEquals(validClass, tested.getResponseControlFactory());
}
public void setCredentials(String credentials) {
this.credentials = credentials;
}
public void testSetInvalidResponseControlFactory() throws Exception {
try {
Class invalidClass = Control.class;
tested.setResponseControlFactory(invalidClass);
fail("IllegalArgumentException expected");
}
catch (IllegalArgumentException expected) {
assertTrue(true);
}
}
public void setPrincipal(String principal) {
this.principal = principal;
}
private class DummyAuthenticationProvider implements AuthenticationSource {
private String principal;
public String getPrincipal() {
return principal;
}
private String credentials;
public String getCredentials() {
return credentials;
}
}
public void setCredentials(String credentials) {
this.credentials = credentials;
}
public void setPrincipal(String principal) {
this.principal = principal;
}
public String getPrincipal() {
return principal;
}
public String getCredentials() {
return credentials;
}
}
}