package co.codewizards.cloudstore.rest.server.ldap;
import javax.ws.rs.WebApplicationException;
import net.jcip.annotations.NotThreadSafe;
import org.apache.directory.api.ldap.model.entry.DefaultEntry;
import org.apache.directory.api.ldap.model.exception.LdapException;
import org.apache.directory.ldap.client.api.LdapConnection;
import org.apache.directory.ldap.client.api.LdapConnectionConfig;
import org.apache.directory.ldap.client.api.LdapNetworkConnection;
import org.apache.directory.server.annotations.CreateLdapServer;
import org.apache.directory.server.annotations.CreateTransport;
import org.apache.directory.server.core.annotations.ContextEntry;
import org.apache.directory.server.core.annotations.CreateDS;
import org.apache.directory.server.core.annotations.CreatePartition;
import org.apache.directory.server.core.integ.AbstractLdapTestUnit;
import org.apache.directory.server.core.integ.FrameworkRunner;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import co.codewizards.cloudstore.rest.server.auth.Auth;
@RunWith(FrameworkRunner.class)
@CreateLdapServer(transports =
{
@CreateTransport(protocol = "LDAP")
})
@CreateDS(
name = "AddExampleCom",
partitions =
{
@CreatePartition(
name = "example",
suffix = "dc=example,dc=com",
contextEntry = @ContextEntry(
entryLdif =
"dn: dc=example,dc=com\n" +
"dc: example\n" +
"objectClass: top\n" +
"objectClass: domain\n\n"))
},
enableChangeLog = true)
@NotThreadSafe
public class QueryLdapClientTest extends AbstractLdapTestUnit{
private static final String ADMIN_DN = "uid=admin,ou=system";
private static final String ADMIN_PASSWORD = "secret";
private static final String USER_NAME = "testUser";
private static final String USER_PASSWORD = "testUserPassword";
private static final String QUERY = "(&(|(cn=${login})(mail=${login}))(objectClass=inetOrgPerson))";
private LdapConnection connection;
private QueryLdapClient client;
@Before
public void setup() throws Exception {
LdapConnectionConfig config = new LdapConnectionConfig();
config.setLdapHost( "localhost" );
config.setLdapPort( ldapServer.getPort() );
config.setName(ADMIN_DN);
config.setCredentials(ADMIN_PASSWORD);
connection = new LdapNetworkConnection( config);
}
@After
public void shutdown() throws Exception{
if(connection != null) {
connection.close();
}
}
@Test
public void when_query_returns_one_result_and_this_result_is_bounded_to_context_then_authenticate() throws LdapException{
addUser(USER_NAME, USER_PASSWORD, "");
client = client(QUERY, "dc=example,dc=com");
client.authenticate(new Auth(USER_NAME, USER_PASSWORD.toCharArray()));
}
@Test(expected = WebApplicationException.class)
public void when_query_returns_result_but_password_is_wrong_then_throw_WAE() throws LdapException{
addUser(USER_NAME, USER_PASSWORD, "");
client = client(QUERY, "ou=system");
client.authenticate(new Auth(USER_NAME, "wrongPassword".toCharArray()));
}
@Test
public void when_there_exist_multiple_results_for_query_and_password_is_correct_only_for_the_last_result_then_still_authenticate() throws LdapException{
String user2Password = "user2Password";
String email = "test@test.com";
// two users with the same email
addUser(USER_NAME, USER_PASSWORD, email);
addUser("testUser2", user2Password, email);
client = client(QUERY, "dc=example,dc=com");
client.authenticate(new Auth("test@test.com", user2Password.toCharArray()));
}
private void addUser(String cn, String password, String email) throws LdapException{
connection.bind(ADMIN_DN, ADMIN_PASSWORD);
connection.add(
new DefaultEntry(getService().getSchemaManager(),
"cn=" + cn + ",dc=example,dc=com",
"ObjectClass: top",
"ObjectClass: person",
"ObjectClass: inetOrgPerson",
"userPassword", password,
"cn",cn,
"sn",cn,
"mail", email
) );
}
private QueryLdapClient client(String query, String queryDn) {
return new QueryLdapClient(query, queryDn, "ldap://localhost:"+ ldapServer.getPort(), ADMIN_DN, ADMIN_PASSWORD.toCharArray());
}
}