/*
* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* This file has been modified to work in the NXLDAPDirectory test setup.
* The original file can be found at the following URL:
*
* https://svn.sourceforge.net/svnroot/acegisecurity/trunk/acegisecurity/
* core/src/test/java/org/acegisecurity/ldap/LdapTestServer.java
*/
package org.nuxeo.ecm.directory.ldap;
import java.io.File;
import java.util.HashSet;
import java.util.Hashtable;
import java.util.Properties;
import java.util.Set;
import javax.naming.Context;
import javax.naming.NameAlreadyBoundException;
import javax.naming.NamingException;
import javax.naming.directory.Attribute;
import javax.naming.directory.Attributes;
import javax.naming.directory.BasicAttribute;
import javax.naming.directory.BasicAttributes;
import javax.naming.directory.DirContext;
import javax.naming.directory.InitialDirContext;
import javax.naming.ldap.InitialLdapContext;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.directory.server.core.configuration.Configuration;
import org.apache.directory.server.core.configuration.MutablePartitionConfiguration;
import org.apache.directory.server.core.configuration.MutableStartupConfiguration;
import org.apache.directory.server.core.configuration.ShutdownConfiguration;
import org.apache.directory.server.core.jndi.CoreContextFactory;
import org.apache.directory.server.core.partition.PartitionNexus;
import org.apache.directory.server.core.prefs.ServerSystemPreferenceException;
/**
* An embedded LDAP test server, complete with test data for running the unit tests against.
*
* @author Luke Taylor
* @version $Id: LdapTestServer.java 1496 2006-05-23 13:38:33Z benalex $
*/
public class MockLdapServer implements ContextProvider {
private static final String BASE_DN = "dc=example,dc=com";
// ~ Instance fields
// ================================================================================================
private static final Log log = LogFactory.getLog(MockLdapServer.class);
private DirContext serverContext;
// Move the working dir to the temp directory
private File workingDir;
private MutableStartupConfiguration cfg;
// ~ Constructors
// ===================================================================================================
/**
* Starts up and configures ApacheDS.
*/
public MockLdapServer(File basedir) {
workingDir = new File(basedir, "apacheds");
workingDir.delete();
workingDir.mkdirs();
startLdapServer();
}
// ~ Methods
// ========================================================================================================
public void createGroup(String cn, String ou, String[] memberDns) {
Attributes group = new BasicAttributes("cn", cn);
Attribute members = new BasicAttribute("member");
Attribute orgUnit = new BasicAttribute("ou", ou);
for (String memberDn : memberDns) {
members.add(memberDn);
}
Attribute objectClass = new BasicAttribute("objectClass");
objectClass.add("top");
objectClass.add("groupOfNames");
group.put(objectClass);
group.put(members);
group.put(orgUnit);
try {
serverContext.createSubcontext("cn=" + cn + ",ou=groups", group);
} catch (NameAlreadyBoundException ignore) {
// System.out.println(" group " + cn + " already exists.");
} catch (NamingException ne) {
log.error("Failed to create group", ne);
}
}
public void createManagerUser() {
Attributes user = new BasicAttributes("cn", "manager", true);
user.put("userPassword", "secret");
Attribute objectClass = new BasicAttribute("objectClass");
user.put(objectClass);
objectClass.add("top");
objectClass.add("person");
objectClass.add("organizationalPerson");
objectClass.add("inetOrgPerson");
user.put("sn", "Manager");
user.put("cn", "manager");
try {
serverContext.createSubcontext("cn=manager", user);
} catch (NameAlreadyBoundException ignore) {
log.warn("Manager user already exists.");
} catch (NamingException ne) {
log.error("Failed to create manager user", ne);
}
}
public void createOu(String name) {
Attributes ou = new BasicAttributes("ou", name);
Attribute objectClass = new BasicAttribute("objectClass");
objectClass.add("top");
objectClass.add("organizationalUnit");
ou.put(objectClass);
try {
serverContext.createSubcontext("ou=" + name, ou);
} catch (NameAlreadyBoundException ignore) {
log.warn("ou " + name + " already exists.");
} catch (NamingException ne) {
log.error("Failed to create ou: ", ne);
}
}
public void createUser(String uid, String cn, String password) {
Attributes user = new BasicAttributes("uid", uid);
user.put("cn", cn);
user.put("userPassword", password);
Attribute objectClass = new BasicAttribute("objectClass");
user.put(objectClass);
objectClass.add("top");
objectClass.add("person");
objectClass.add("organizationalPerson");
objectClass.add("inetOrgPerson");
user.put("sn", uid);
try {
serverContext.createSubcontext("uid=" + uid + ",ou=people", user);
} catch (NameAlreadyBoundException ignore) {
// System.out.println(" user " + uid + " already exists.");
} catch (NamingException ne) {
System.err.println("Failed to create user.");
ne.printStackTrace();
}
}
public Configuration getConfiguration() {
return cfg;
}
@Override
public DirContext getContext() {
// ensure the context server is not closed
startLdapServer();
return serverContext;
}
private void initConfiguration() throws NamingException {
// Create the partition for the tests
MutablePartitionConfiguration testPartition = new MutablePartitionConfiguration();
testPartition.setId("NuxeoTestLdapServer");
testPartition.setSuffix(BASE_DN);
BasicAttributes attributes = new BasicAttributes();
BasicAttribute objectClass = new BasicAttribute("objectClass");
objectClass.add("top");
objectClass.add("domain");
objectClass.add("extensibleObject");
attributes.put(objectClass);
testPartition.setContextEntry(attributes);
Set<Object> indexedAttrs = new HashSet<Object>();
indexedAttrs.add("objectClass");
indexedAttrs.add("uid");
indexedAttrs.add("cn");
indexedAttrs.add("ou");
indexedAttrs.add("uniqueMember");
// POSIX RFC-2307 schema.
indexedAttrs.add("gidNumber");
indexedAttrs.add("uidNumber");
testPartition.setIndexedAttributes(indexedAttrs);
Set<MutablePartitionConfiguration> partitions = new HashSet<MutablePartitionConfiguration>();
partitions.add(testPartition);
cfg.setPartitionConfigurations(partitions);
}
public void startLdapServer() {
cfg = new MutableStartupConfiguration();
cfg.setWorkingDirectory(workingDir);
log.debug("Working directory is " + workingDir.getAbsolutePath());
Properties env = new Properties();
env.setProperty(Context.PROVIDER_URL, BASE_DN);
env.setProperty(Context.INITIAL_CONTEXT_FACTORY, CoreContextFactory.class.getName());
env.setProperty(Context.SECURITY_AUTHENTICATION, "simple");
env.setProperty(Context.SECURITY_PRINCIPAL, PartitionNexus.ADMIN_PRINCIPAL);
env.setProperty(Context.SECURITY_CREDENTIALS, PartitionNexus.ADMIN_PASSWORD);
try {
initConfiguration();
env.putAll(cfg.toJndiEnvironment());
serverContext = new InitialDirContext(env);
} catch (NamingException e) {
log.error("Failed to start Apache DS: ", e);
}
}
public void shutdownLdapServer() {
Hashtable<String, Object> env = new Hashtable<>(new ShutdownConfiguration().toJndiEnvironment());
env.put(Context.INITIAL_CONTEXT_FACTORY, CoreContextFactory.class.getName());
env.put(Context.PROVIDER_URL, BASE_DN);
try {
new InitialLdapContext(env, null);
} catch (Exception e) {
throw new ServerSystemPreferenceException("Failed to shutdown ldap server.", e);
}
}
}