/*
* LdapTest.java
* JUnit based test
*
* Created on November 27, 2007, 11:10 AM
*
* Copyright 2007, 2008, 2009 Jakim Friant
*
* This file is part of ResetPassword.
*
* ResetPassword is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* ResetPassword is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with ResetPassword. If not, see <http://www.gnu.org/licenses/>.
*/
package org.cfcc.services;
import com.vladium.utils.PropertyLoader;
import junit.framework.*;
import java.util.ArrayList;
import java.util.Hashtable;
import java.util.Properties;
import javax.naming.*;
import javax.naming.directory.*;
import javax.naming.ldap.InitialLdapContext;
import org.cfcc.CryptoException;
import org.cfcc.LdapChangeException;
import org.cfcc.utils.BlindSSLSocketFactory;
import org.cfcc.utils.Crypto;
/**
*
* @author jfriant
*/
public class LdapTest extends TestCase {
private static final boolean READ_ONLY = false;
private Ldap ld;
private Properties test_prop;
public LdapTest(String testName) {
super(testName);
}
/**
* Set up the test routines by loading the properties and creating an LDAP
* instance.
* @throws java.lang.Exception if either the property file fails to load or the ldap instance fails to create.
*/
@Override
protected void setUp() throws Exception {
/* use the following code to test self-signed certificates that are in
* a local keystore
* /
//Security.addProvider(new com.sun.net.ssl.internal.ssl.Provider());
/* set up access to an alternate keystore */
//String keystore = "/home/jfriant/src/cfcc/ldap/doc/keystore.jks";
//System.setProperty("javax.net.ssl.trustStore", keystore);
test_prop = PropertyLoader.loadProperties("org.cfcc.services.LdapTest");
ld = new Ldap(test_prop.getProperty("LDAP_SERVER"), false, test_prop.getProperty("PRIV_DN"), test_prop.getProperty("LDAP_PASSWORD"), test_prop.getProperty("SEARCH_BASE"));
}
public void testProperties() throws Exception {
assertNotNull(test_prop.getProperty("ID_FIELD"));
}
/**
* Test of search method, of class org.cfcc.services.Ldap.
*/
public void testSearch() throws Exception {
System.out.println("search");
String filter = test_prop.getProperty("ID_FIELD") + "=" + test_prop.getProperty("UID");
NamingEnumeration<?> result = ld.search(filter);
assertTrue(result.hasMore());
ld.formatResults(result);
}
/**
* Test of getEmployeeNumber method, of class org.cfcc.services.Ldap.
*/
public void testGetEmployeeNumber() throws Exception {
System.out.println("getEmployeeNumber");
try {
String expResult = test_prop.getProperty("EXP_PERSON_ID");
String result = ld.getEmployeeNumber(test_prop.getProperty("UID"));
assertEquals(expResult, result);
System.out.println("getEmployeeNumber (uses lastdn)");
result = ld.getEmployeeNumber();
assertEquals(expResult, result);
} catch (org.cfcc.NoPersonIdException ex) {
if (!ld.username_field.equals("uid")) {
throw ex;
} else {
System.out.println("Skipped test while using ActiveDirectory");
}
}
}
public void testGetEmployeeNumberAltField() throws Exception {
System.out.println("getEmployeeNumberAltField");
ld.setUsernameField(test_prop.getProperty("ID_FIELD"));
String expResult = test_prop.getProperty("EXP_PERSON_ID");
String result = ld.getEmployeeNumber(test_prop.getProperty("UID"));
assertEquals(expResult, result);
}
/**
* Test of getDnByEmployeeNumber method, of class org.cfcc.services.Ldap.
*/
public void testGetDnByEmployeeNumber() throws Exception {
System.out.println("getDnByEmployeeNumber");
String person_id = test_prop.getProperty("EXP_PERSON_ID");
String expResult = test_prop.getProperty("EXPECTED_DN");
String result = ld.getDnByEmployeeNumber(person_id);
assertEquals(expResult, result);
}
/**
* Test of getDN method, of class org.cfcc.services.Ldap.
*/
public void testGetDN() throws Exception {
System.out.println("getDN");
ld.setUsernameField(test_prop.getProperty("ID_FIELD"));
String user_id = test_prop.getProperty("UID");
String expResult = test_prop.getProperty("EXPECTED_DN");
String result = ld.getDN(user_id);
assertEquals(expResult, result);
}
/**
* Test of getLastDn method, of class org.cfcc.services.Ldap.
*/
public void testGetLastDn() {
System.out.println("getLastDn");
String expResult = test_prop.getProperty("EXPECTED_DN");
try {
ld.setLastDn(test_prop.getProperty("EXPECTED_DN"));
} catch (StringIndexOutOfBoundsException e) {
fail("Unable to set DN");
}
String result = ld.getLastDn();
assertEquals(expResult, result);
}
/**
* Test of getLastUsername method, of class org.cfcc.services.Ldap.
*/
public void testGetLastUsername() {
System.out.println("getLastUsername");
String expResult = test_prop.getProperty("UID");
try {
ld.setLastDn(test_prop.getProperty("EXPECTED_DN"));
} catch (StringIndexOutOfBoundsException e) {
fail("Unable to set DN");
}
String result = ld.getLastUsername();
assertEquals(expResult, result);
}
/**
* Test retrieving the user password. This only works with OpenLDAP.
*/
public void testGetPassword() throws Exception {
if (!test_prop.getProperty("USE_UNICODE_PASSWORD")
.contentEquals("true")) {
String dn = ld.getDN(test_prop.getProperty("UID"));
ld.setLastDn(dn);
String expResult = "";
String result = ld.getPassword();
System.out.println("getPassword result = |" + result + "|");
assertFalse(expResult.equals(result));
}
}
/**
* Test of setPassword method, of class org.cfcc.services.Ldap.
*/
// public void testSetPassword() throws Exception {
// System.out.println("setPassword");
//
// String new_passwd = "";
// Ldap instance = null;
//
// //instance.setPassword(new_passwd);
//
// // TODO review the generated test code and remove the default call to fail.
// fail("The test case is a prototype.");
// }
//
/**
* Test of setUnicodePassword method, of class org.cfcc.services.ldap
*/
public void testSetADPassword() throws Exception {
System.out.println("setADPassword");
assertFalse(READ_ONLY);
try {
ld.setLastDn(test_prop.getProperty("EXPECTED_DN"));
ld.setUnicodePassword("Mighty_8");
} catch (StringIndexOutOfBoundsException e) {
fail("Unable to set DN: " + e.getMessage());
} catch (LdapChangeException ex) {
System.out.println("Skipping test, not an Active Directory server.");
}
}
public void testSetPassword() throws Exception {
System.out.println("setPassword");
boolean use_salt = true;
assertFalse(READ_ONLY);
ld.setLastDn(test_prop.getProperty("EXPECTED_DN"));
ld.setPassword("simple", use_salt);
}
/**
* Test creating a time stamp for shadowLastChange
*/
public void testTimeStamp() throws Exception {
System.out.println("timeStamp");
String ts = ld.ldapTimestamp();
System.out.println("timeStamp(): ts = " + ts);
}
/**
* Test of newPassword method, of class org.cfcc.services.Ldap.
* Generate a random password and save it to the LDAP record.
*/
public void testNewPassword() throws Exception {
System.out.println("newPassword");
assertFalse(READ_ONLY);
try {
ld.setLastDn(test_prop.getProperty("EXPECTED_DN"));
} catch (StringIndexOutOfBoundsException e) {
fail("Unable to set DN: " + e.getMessage());
}
String result = ld.newPassword();
assertNotNull(result);
}
/**
* Test of setEmployeeType method, of class org.cfcc.services.Ldap.
*/
public void testSetEmployeeType() throws Exception {
System.out.println("setEmployeeType");
assertFalse(READ_ONLY);
ArrayList<String> office_codes = new ArrayList<String>(2);
office_codes.add("IT");
office_codes.add("CU");
try {
ld.setLastDn(test_prop.getProperty("EXPECTED_DN"));
} catch (StringIndexOutOfBoundsException e) {
fail("Unable to set DN");
}
try {
ld.setEmployeeType(office_codes);
} catch (Exception e) {
fail("Unable to set Employee Type: " + e);
}
}
/**
* Test of convertToPosixAccount method, of class org.cfcc.services.Ldap.
*/
// public void testConvertToPosixAccount() throws Exception {
// System.out.println("convertToPosixAccount");
//
// String person_id = "";
// Ldap instance = null;
//
// //instance.convertToPosixAccount(person_id);
//
// // TODO review the generated test code and remove the default call to fail.
// fail("The test case is a prototype.");
// }
//
/**
* Test of getSearchBase method, of class org.cfcc.services.Ldap.
*/
public void testGetSearchBase() {
System.out.println("getSearchBase");
String result = ld.getSearchBase();
System.out.println("getSearchBase: " + result);
assertNotNull(result);
}
/**
* Test of getContext method, of class org.cfcc.services.Ldap.
*/
public void testGetContext() throws Exception {
System.out.println("getContext");
Ldap instance = new Ldap(test_prop.getProperty("LDAP_SERVER"), false, test_prop.getProperty("PRIV_DN"), test_prop.getProperty("LDAP_PASSWORD"), test_prop.getProperty("SEARCH_BASE"));
DirContext result = instance.getContext();
assertNotNull(result);
}
/**
* Test of getContext method, of class org.services.ldap. This test uses a
* SSL connection to validate that it works that way as well.
* @throws java.lang.Exception if the connection cannot be established.
*/
public void testSSLGetContext() throws Exception {
System.out.println("getContext - SSL");
Ldap instance = new Ldap(test_prop.getProperty("LDAP_SERVER"), //test_prop.getProperty("LDAP_SERVER"),
true, // Use SSL
test_prop.getProperty("PRIV_DN"),
test_prop.getProperty("LDAP_PASSWORD"),
test_prop.getProperty("SEARCH_BASE"));
DirContext result = instance.getContext();
assertNotNull(result);
result.close();
}
/**
* Test a unverified SSL connection to LDAP.
* @throws java.lang.Exception if the connection cannot be established
*/
public void testSSLNotVerified() throws Exception {
System.out.println("getContext - SSL unverified");
Ldap instance = new Ldap(test_prop.getProperty("LDAP_SERVER"),
test_prop.getProperty("USE_SSL"),
"false", // ssl_validate_cert
test_prop.getProperty("PRIV_DN"),
test_prop.getProperty("LDAP_PASSWORD"),
test_prop.getProperty("SEARCH_BASE"),
test_prop.getProperty("ID_FIELD"));
DirContext result = instance.getContext();
Attributes sample = result.getAttributes(test_prop.getProperty("EXPECTED_DN"));
assertNotNull(sample);
System.out.println("testSSLNotVerified: " + sample.get("cn"));
result.close();
}
/**
* Additional test routine to make sure the BlindSSLSocketFactory is working
* correctly.
* @throws Exception
*/
public void testBlindSSL() throws Exception {
String bind_pw = test_prop.getProperty("LDAP_PASSWORD");
if (bind_pw.startsWith(Crypto.prefix())) {
Crypto c = new Crypto();
try {
bind_pw = c.decrypt(bind_pw);
} catch (CryptoException ex) {
throw new NamingException(ex.toString());
}
}
Hashtable<String, String> env = new Hashtable<String, String>(11);
env.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory");
env.put(Context.PROVIDER_URL, "ldaps://172.18.0.100");
env.put(Context.SECURITY_PROTOCOL, "ssl");
env.put("java.naming.ldap.factory.socket", BlindSSLSocketFactory.class.getName());
env.put(Context.SECURITY_AUTHENTICATION, "simple");
env.put(Context.SECURITY_PRINCIPAL, test_prop.getProperty("PRIV_DN"));
env.put(Context.SECURITY_CREDENTIALS, bind_pw);
DirContext ctx = new InitialLdapContext(env, null);
assertNotNull(ctx);
Attributes sample = ctx.getAttributes(test_prop.getProperty("EXPECTED_DN"));
assertNotNull(sample);
System.out.println("testBlindSSL: " + sample.get("cn"));
ctx.close();
}
}