Commonize & simplify LDAP and LDAPS auth
This makes it easy for further instances and projects
outside the IDS to use Kustvakt-full with their own LDAP.
Change-Id: I710f50079348d6cff9fd33376aebda33bc9f408e
diff --git a/full/src/test/java/de/ids_mannheim/korap/authentication/LdapAuth3Test.java b/full/src/test/java/de/ids_mannheim/korap/authentication/LdapAuth3Test.java
new file mode 100644
index 0000000..dc9e3ae
--- /dev/null
+++ b/full/src/test/java/de/ids_mannheim/korap/authentication/LdapAuth3Test.java
@@ -0,0 +1,135 @@
+package de.ids_mannheim.korap.authentication;
+
+import com.unboundid.ldap.listener.InMemoryDirectoryServer;
+import com.unboundid.ldap.listener.InMemoryDirectoryServerConfig;
+import com.unboundid.ldap.listener.InMemoryListenerConfig;
+import com.unboundid.ldap.sdk.LDAPException;
+import com.unboundid.util.Base64;
+import com.unboundid.util.StaticUtils;
+import com.unboundid.util.ssl.KeyStoreKeyManager;
+import com.unboundid.util.ssl.SSLUtil;
+import com.unboundid.util.ssl.TrustAllTrustManager;
+import com.unboundid.util.ssl.TrustStoreTrustManager;
+import org.junit.AfterClass;
+import org.junit.BeforeClass;
+import org.junit.Test;
+
+import java.security.GeneralSecurityException;
+
+import static de.ids_mannheim.korap.authentication.LdapAuth3.LDAP_AUTH_ROK;
+import static de.ids_mannheim.korap.authentication.LdapAuth3.LDAP_AUTH_RNAUTH;
+import static org.junit.Assert.assertEquals;
+
+public class LdapAuth3Test {
+ public static final String TEST_LDAP_PROPERTIES = "src/test/resources/test-ldap.properties";
+ public static final String TEST_LDAPS_PROPERTIES = "src/test/resources/test-ldaps.properties";
+ public static final String TEST_LDAPS_TS_PROPERTIES = "src/test/resources/test-ldaps-with-truststore.properties";
+ public static final String TEST_LDAP_USERS_LDIF = "src/test/resources/test-ldap-users.ldif";
+ private static final String keyStorePath = "src/test/resources/keystore.p12";
+ static InMemoryDirectoryServer server;
+
+ @BeforeClass
+ public static void startDirectoryServer() throws LDAPException, GeneralSecurityException {
+ InMemoryDirectoryServerConfig config = new InMemoryDirectoryServerConfig("dc=example,dc=com");
+ config.addAdditionalBindCredentials("cn=admin,dc=example,dc=com", "adminpassword");
+ config.setSchema(null);
+
+ final SSLUtil serverSSLUtil = new SSLUtil(new KeyStoreKeyManager(keyStorePath, "password".toCharArray(), "PKCS12", "server-cert"), new TrustStoreTrustManager(keyStorePath));
+
+ final SSLUtil clientSslUtil = new SSLUtil(new TrustAllTrustManager());
+
+ config.setListenerConfigs(InMemoryListenerConfig.createLDAPConfig("LDAP", // Listener name
+ null, // Listen address. (null = listen on all interfaces)
+ 3268, // Listen port (0 = automatically choose an available port)
+ clientSslUtil.createSSLSocketFactory()), // StartTLS factory
+ InMemoryListenerConfig.createLDAPSConfig("LDAPS", // Listener name
+ null, // Listen address. (null = listen on all interfaces)
+ 3269, // Listen port (0 = automatically choose an available port)
+ serverSSLUtil.createSSLServerSocketFactory(), clientSslUtil.createSSLSocketFactory()));
+ server = new InMemoryDirectoryServer(config);
+
+ String configPath = TEST_LDAP_USERS_LDIF;
+ server.importFromLDIF(true, configPath);
+ server.startListening();
+ }
+
+ @AfterClass
+ public static void ShutDownDirectoryServer() {
+ server.shutDown(true);
+ }
+
+ @Test
+ public void testLoginWithUsername() throws LDAPException {
+ assertEquals(LDAP_AUTH_ROK, LdapAuth3.login("testuser", "topsecret", TEST_LDAP_PROPERTIES));
+ }
+
+ @Test
+ public void testLoginWithUid() throws LDAPException {
+ final byte[] passwordBytes = StaticUtils.getBytes("password");
+ String pw = Base64.encode(passwordBytes);
+ assertEquals(LDAP_AUTH_ROK, LdapAuth3.login("testuser", pw, TEST_LDAP_PROPERTIES));
+ }
+
+ @Test
+ public void testLoginWithEmail() throws LDAPException {
+ final byte[] passwordBytes = StaticUtils.getBytes("password");
+ String pw = Base64.encode(passwordBytes);
+ assertEquals(LDAP_AUTH_ROK, LdapAuth3.login("testuser@example.com", pw, TEST_LDAP_PROPERTIES));
+ }
+
+ @Test
+ public void testFailingLoginWithWrongEmail() throws LDAPException {
+ assertEquals(LDAP_AUTH_RNAUTH, LdapAuth3.login("notestuser@example.com", "topsecret", TEST_LDAP_PROPERTIES));
+ }
+
+ @Test
+ public void testFailingLoginWithEmailAndWrongPassword() throws LDAPException {
+ assertEquals(LDAP_AUTH_RNAUTH, LdapAuth3.login("testuser@example.com", "wrongpw", TEST_LDAP_PROPERTIES));
+ }
+
+ @Test
+ public void testFailingLoginWithUsernameAndWrongPassword() throws LDAPException {
+ assertEquals(LDAP_AUTH_RNAUTH, LdapAuth3.login("testuser", "wrongpw", TEST_LDAP_PROPERTIES));
+ }
+
+ @Test
+ public void testFailingLoginWithoutC2Attr() throws LDAPException {
+ assertEquals(LDAP_AUTH_RNAUTH, LdapAuth3.login("doe", "topsecret", TEST_LDAP_PROPERTIES));
+ }
+
+ @Test
+ public void testFailingLoginWithoutBadStatus() throws LDAPException {
+ assertEquals(LDAP_AUTH_RNAUTH, LdapAuth3.login("berserker", "topsecret", TEST_LDAP_PROPERTIES));
+ }
+
+ @Test
+ public void testSecureLoginWithUsername() throws LDAPException {
+ assertEquals(LDAP_AUTH_ROK, LdapAuth3.login("testuser", "topsecret", TEST_LDAPS_PROPERTIES));
+ }
+
+ @Test
+ public void testSecureLoginWithTrustStoreAndUsername() throws LDAPException {
+ assertEquals(LDAP_AUTH_ROK, LdapAuth3.login("testuser", "topsecret", TEST_LDAPS_TS_PROPERTIES));
+ }
+
+ @Test
+ public void testFailingSecureLoginWithTrustStoreAndUsernameAndWrongPW() throws LDAPException {
+ assertEquals(LDAP_AUTH_RNAUTH, LdapAuth3.login("testuser", "topsecrets", TEST_LDAPS_TS_PROPERTIES));
+ }
+
+ @Test
+ public void testPasswordWithAsterisk() throws LDAPException {
+ assertEquals(LDAP_AUTH_ROK, LdapAuth3.login("test", "top*ecret", TEST_LDAPS_PROPERTIES));
+ }
+
+ @Test
+ public void testFailingEscapedPW() throws LDAPException {
+ assertEquals(LDAP_AUTH_RNAUTH, LdapAuth3.login("testuser", "top*", TEST_LDAPS_TS_PROPERTIES));
+ }
+
+ @Test
+ public void testFailingIllegalPW() throws LDAPException {
+ assertEquals(LDAP_AUTH_RNAUTH, LdapAuth3.login("testuser", "*", TEST_LDAPS_TS_PROPERTIES));
+ }
+
+}
diff --git a/full/src/test/resources/keystore.p12 b/full/src/test/resources/keystore.p12
new file mode 100644
index 0000000..a1d7980
--- /dev/null
+++ b/full/src/test/resources/keystore.p12
Binary files differ
diff --git a/full/src/test/resources/test-ldap-users.ldif b/full/src/test/resources/test-ldap-users.ldif
new file mode 100644
index 0000000..a965181
--- /dev/null
+++ b/full/src/test/resources/test-ldap-users.ldif
@@ -0,0 +1,66 @@
+dn: dc=example,dc=com
+dc: example
+ou: people
+objectClass: dcObject
+objectClass: organizationalUnit
+
+dn: ou=people,dc=example,dc=com
+ou: people
+objectClass: organizationalUnit
+
+dn: uid=testuser,ou=people,dc=example,dc=com
+cn: Peter Testuser
+sn: Testuser
+givenName: Peter
+mail: testuser@example.com
+userPassword: cGFzc3dvcmQ=
+displayName: Dr. Peter Testuser
+idsC2: TRUE
+idsC2Profile: testuser
+idsC2Password: topsecret
+idsC2News: TRUE
+title: Herr
+uid: testuser
+
+dn: uid=test,ou=people,dc=example,dc=com
+cn: Peter Test
+sn: Test
+givenName: Peter
+mail: test@example.com
+userPassword: top*ecret
+displayName: Dr. Peter Test
+idsC2: TRUE
+idsStatus: 1
+idsC2Profile: test
+idsC2Password: top*ecret
+uid: test
+
+dn: uid=doe,ou=people,dc=example,dc=com
+cn: John Doe
+sn: doe
+givenName: John
+mail: doe@example.com
+userPassword: cGFzc3dvcmQ=
+displayName: Dr. John Doe
+idsStatus: 0
+idsC2: FALSE
+idsC2Profile: doe
+idsC2Password: topsecret
+idsC2News: TRUE
+title: Herr
+uid: doe
+
+dn: uid=berserker,ou=people,dc=example,dc=com
+cn: Bernd Berserker
+sn: berserker
+givenName: Joe
+mail: berserker@example.com
+userPassword: cGFzc3dvcmQ=
+displayName: berserk
+idsStatus: 2
+idsC2: TRUE
+idsC2Profile: doe
+idsC2Password: topsecret
+idsC2News: TRUE
+title: Herr
+uid: berserk
diff --git a/full/src/test/resources/test-ldap.properties b/full/src/test/resources/test-ldap.properties
new file mode 100644
index 0000000..aa27f14
--- /dev/null
+++ b/full/src/test/resources/test-ldap.properties
@@ -0,0 +1,6 @@
+ldapHost=localhost
+ldapPort=3268
+ldapBase=dc=example,dc=com
+sLoginDN=cn=admin,dc=example,dc=com
+pwd=adminpassword
+ldapFilter=(&(|(&(|(uid=${username})(mail=${username}))(userPassword=${password}))(&(idsC2Profile=${username})(idsC2Password=${password})))(&(idsC2=TRUE)(|(idsStatus=1)(|(idsStatus=0)(!(idsStatus=*))))))
diff --git a/full/src/test/resources/test-ldaps-with-truststore.properties b/full/src/test/resources/test-ldaps-with-truststore.properties
new file mode 100644
index 0000000..d785301
--- /dev/null
+++ b/full/src/test/resources/test-ldaps-with-truststore.properties
@@ -0,0 +1,8 @@
+ldapHost=localhost
+ldapPort=3269
+ldapS=true
+trustStore=src/test/resources/truststore.jks
+ldapBase=dc=example,dc=com
+sLoginDN=cn=admin,dc=example,dc=com
+pwd=adminpassword
+ldapFilter=(&(|(&(|(uid=${username})(mail=${username}))(userPassword=${password}))(&(idsC2Profile=${username})(idsC2Password=${password})))(&(idsC2=TRUE)(|(idsStatus=1)(|(idsStatus=0)(!(idsStatus=*))))))
diff --git a/full/src/test/resources/test-ldaps.properties b/full/src/test/resources/test-ldaps.properties
new file mode 100644
index 0000000..732076f
--- /dev/null
+++ b/full/src/test/resources/test-ldaps.properties
@@ -0,0 +1,8 @@
+ldapHost=localhost
+ldapPort=3269
+ldapS=true
+trustStore=
+ldapBase=dc=example,dc=com
+sLoginDN=cn=admin,dc=example,dc=com
+pwd=adminpassword
+ldapFilter=(&(|(&(|(uid=${username})(mail=${username}))(userPassword=${password}))(&(idsC2Profile=${username})(idsC2Password=${password})))(&(idsC2=TRUE)(|(idsStatus=1)(|(idsStatus=0)(!(idsStatus=*))))))
diff --git a/full/src/test/resources/truststore.jks b/full/src/test/resources/truststore.jks
new file mode 100644
index 0000000..50804be
--- /dev/null
+++ b/full/src/test/resources/truststore.jks
Binary files differ