From cdc9d2fb83d11577e41f9aaec0d772641a0577ab Mon Sep 17 00:00:00 2001
From: Bastien Jansen
Date: Wed, 28 Oct 2020 17:39:17 +0100
Subject: [PATCH 1/5] Add support for JUnit 5 extensions (#57)
---
README.md | 22 +-
pom.xml | 10 +-
.../zapodot/junit/ldap/EmbeddedLdapRule.java | 57 +---
.../junit/ldap/EmbeddedLdapRuleBuilder.java | 256 +-----------------
.../junit/ldap/EmbeddedLdapServer.java | 60 ++++
.../internal/AbstractEmbeddedLdapBuilder.java | 240 ++++++++++++++++
.../internal/EmbeddedLdapExtensionImpl.java | 54 ++++
.../ldap/internal/EmbeddedLdapRuleImpl.java | 221 +--------------
.../ldap/internal/EmbeddedLdapServerImpl.java | 148 ++++++++++
.../ldap/junit5/EmbeddedLdapExtension.java | 14 +
.../junit5/EmbeddedLdapExtensionBuilder.java | 38 +++
.../EmbeddedLdapExtensionBuilderTest.java | 87 ++++++
.../EmbeddedLdapExtensionStaticTest.java | 28 ++
.../junit5/EmbeddedLdapExtensionTest.java | 94 +++++++
14 files changed, 805 insertions(+), 524 deletions(-)
create mode 100644 src/main/java/org/zapodot/junit/ldap/EmbeddedLdapServer.java
create mode 100644 src/main/java/org/zapodot/junit/ldap/internal/AbstractEmbeddedLdapBuilder.java
create mode 100644 src/main/java/org/zapodot/junit/ldap/internal/EmbeddedLdapExtensionImpl.java
create mode 100644 src/main/java/org/zapodot/junit/ldap/internal/EmbeddedLdapServerImpl.java
create mode 100644 src/main/java/org/zapodot/junit/ldap/junit5/EmbeddedLdapExtension.java
create mode 100644 src/main/java/org/zapodot/junit/ldap/junit5/EmbeddedLdapExtensionBuilder.java
create mode 100644 src/test/java/org/zapodot/junit/ldap/junit5/EmbeddedLdapExtensionBuilderTest.java
create mode 100644 src/test/java/org/zapodot/junit/ldap/junit5/EmbeddedLdapExtensionStaticTest.java
create mode 100644 src/test/java/org/zapodot/junit/ldap/junit5/EmbeddedLdapExtensionTest.java
diff --git a/README.md b/README.md
index f183537..8318b98 100755
--- a/README.md
+++ b/README.md
@@ -1,7 +1,7 @@
# embedded-ldap-junit
[](https://github.com/zapodot/embedded-ldap-junit/actions/workflows/maven.yml) [](https://codecov.io/gh/zapodot/embedded-ldap-junit) [](https://maven-badges.herokuapp.com/maven-central/org.zapodot/embedded-ldap-junit) [](https://libraries.io/github/zapodot/embedded-ldap-junit) [](https://github.com/zapodot/embedded-ldap-junit/blob/master/LICENSE) [](https://github.com/igrigorik/ga-beacon)
-A [JUnit Rule](//github.com/junit-team/junit/wiki/Rules) for running an embedded LDAP server in your JUnit test based on the wonderful [UnboundID LDAP SDK](https://www.ldap.com/unboundid-ldap-sdk-for-java). Inspired by the [Embedded Database JUnit Rule](//github.com/zapodot/embedded-db-junit).
+A [JUnit 4 Rule](//github.com/junit-team/junit/wiki/Rules) and [JUnit 5 Extension](https://junit.org/junit5/docs/current/user-guide/#extensions) for running an embedded LDAP server in your JUnit test based on the wonderful [UnboundID LDAP SDK](https://www.ldap.com/unboundid-ldap-sdk-for-java). Inspired by the [Embedded Database JUnit Rule](//github.com/zapodot/embedded-db-junit).
## Why?
* you want to test your LDAP integration code without affecting your LDAP server
@@ -29,7 +29,9 @@ See [releases](//github.com/zapodot/embedded-ldap-junit/releases)
```
-### Add to Junit test
+### Add to JUnit test
+
+#### JUnit 4
```java
import com.unboundid.ldap.sdk.LDAPInterface;
import javax.naming.Context;
@@ -79,3 +81,19 @@ public void testContext() throws Exception {
assertNotNull(user);
}
```
+
+#### JUnit 5
+For JUnit 5 tests, simply use `EmbeddedLdapExtensionBuilder` instead of `EmbeddedLdapRuleBuilder`:
+
+```java
+@RegisterExtension
+public EmbeddedLdapExtension embeddedLdapRule = EmbeddedLdapExtensionBuilder
+ .newInstance()
+ .usingDomainDsn("dc=example,dc=com")
+ .importingLdifs("example.ldif")
+ .build();
+
+...
+```
+
+Both JUnit 4 and JUnit 5 builders share the same API, as do the rule and the extension.
diff --git a/pom.xml b/pom.xml
index 1278128..1211eee 100644
--- a/pom.xml
+++ b/pom.xml
@@ -24,6 +24,7 @@
4.13.2
+ 5.7.0
6.0.6
1.7.36
31.1-jre
@@ -51,6 +52,12 @@
junit
${junit.version}
+
+ org.junit.jupiter
+ junit-jupiter-api
+ ${junit5.version}
+ true
+
com.google.guava
guava
@@ -270,4 +277,5 @@
-
\ No newline at end of file
+
+
diff --git a/src/main/java/org/zapodot/junit/ldap/EmbeddedLdapRule.java b/src/main/java/org/zapodot/junit/ldap/EmbeddedLdapRule.java
index 0b742b4..4aa70d4 100755
--- a/src/main/java/org/zapodot/junit/ldap/EmbeddedLdapRule.java
+++ b/src/main/java/org/zapodot/junit/ldap/EmbeddedLdapRule.java
@@ -1,65 +1,10 @@
package org.zapodot.junit.ldap;
-import com.unboundid.ldap.sdk.LDAPConnection;
-import com.unboundid.ldap.sdk.LDAPException;
-import com.unboundid.ldap.sdk.LDAPInterface;
import org.junit.rules.TestRule;
-import javax.naming.Context;
-import javax.naming.NamingException;
-import javax.naming.directory.DirContext;
-
/**
* A JUnit rule that may be used as either a @Rule or a @ClassRule
*/
-public interface EmbeddedLdapRule extends TestRule {
-
- /**
- * For tests depending on the UnboundID LDAP SDK. Returns a proxied version of an Unboundid interface that will be
- * closed when the test(s) have been invoked
- *
- * @return a shared LDAPConnection
- * @throws LDAPException if a connection can not be opened
- */
- LDAPInterface ldapConnection() throws LDAPException;
-
- /**
- * For tests depending on the UnboundID LDAP SDK that needs access to an ${link LDAPConnection} object
- * rather than the interface. If your code does not close the connection for you it will be closed on teardown
- *
- * @return a LDAPConnection connected to the embedded LDAP server
- * @throws LDAPException if an exception occurred while establishing the connection
- */
- LDAPConnection unsharedLdapConnection() throws LDAPException;
-
- /**
- * For tests depending on the standard Java JNDI API
- *
- * @return a shared Context connected to the in-memory LDAP server
- * @throws NamingException if context can not be created
- */
- Context context() throws NamingException;
-
- /**
- * Like {@link #context()}, but returns a DirContext
- *
- * @return a DirContext connected to the in-memory LDAP server
- * @throws NamingException if a LDAP failure happens during DirContext creation
- */
- DirContext dirContext() throws NamingException;
-
- /**
- * Gives access to the listening port for the currently running embedded LDAP server.
- * This will make it easier to use other integration mechanisms
- *
- * Note: the embedded LDAP server is by default configured to listen only on the loopback address
- * (i.e localhost/127.0.0.1) unless another address has been provided to the builder when the rule was built
- *
- *
- * @return the port number that the embedded server is listening to
- * @see org.zapodot.junit.ldap.EmbeddedLdapRuleBuilder#bindingToAddress(String)
- */
- int embeddedServerPort();
-
+public interface EmbeddedLdapRule extends EmbeddedLdapServer, TestRule {
}
diff --git a/src/main/java/org/zapodot/junit/ldap/EmbeddedLdapRuleBuilder.java b/src/main/java/org/zapodot/junit/ldap/EmbeddedLdapRuleBuilder.java
index 83ba6f5..b00771e 100755
--- a/src/main/java/org/zapodot/junit/ldap/EmbeddedLdapRuleBuilder.java
+++ b/src/main/java/org/zapodot/junit/ldap/EmbeddedLdapRuleBuilder.java
@@ -1,65 +1,14 @@
package org.zapodot.junit.ldap;
-import com.google.common.base.Function;
-import com.google.common.collect.Lists;
-import com.google.common.io.Resources;
-import com.unboundid.ldap.listener.InMemoryDirectoryServerConfig;
-import com.unboundid.ldap.listener.InMemoryListenerConfig;
-import com.unboundid.ldap.sdk.LDAPException;
-import com.unboundid.ldap.sdk.schema.Schema;
-import com.unboundid.ldif.LDIFException;
-import org.zapodot.junit.ldap.internal.AuthenticationConfiguration;
+import org.zapodot.junit.ldap.internal.AbstractEmbeddedLdapBuilder;
import org.zapodot.junit.ldap.internal.EmbeddedLdapRuleImpl;
-import javax.net.ssl.SSLSocketFactory;
-import java.io.File;
-import java.io.IOException;
-import java.net.InetAddress;
-import java.net.URISyntaxException;
-import java.net.UnknownHostException;
-import java.util.Arrays;
-import java.util.LinkedList;
-import java.util.List;
import java.util.Objects;
/**
* A builder providing a fluent way of defining EmbeddedLdapRule instances
*/
-public class EmbeddedLdapRuleBuilder {
-
- public static final String DEFAULT_DOMAIN = "dc=example,dc=com";
- public static final String DEFAULT_BIND_DSN = "cn=Directory manager";
- public static final String DEFAULT_BIND_CREDENTIALS = "password";
- public static final String LDAP_SERVER_LISTENER_NAME = "test-listener";
- public static final int MIN_PORT_EXCLUSIVE = 0;
- public static final int MAX_PORT_EXCLUSIVE = 65535;
- private List domainDsn = new LinkedList<>();
-
- private String bindDSN = DEFAULT_BIND_DSN;
-
- private String bindCredentials = DEFAULT_BIND_CREDENTIALS;
-
- private List ldifsToImport = new LinkedList<>();
-
- private List schemaLdifs = new LinkedList<>();
-
- private boolean addDefaultSchema = true;
-
- private Integer bindPort = 0;
-
- private InetAddress bindAddress = InetAddress.getLoopbackAddress();
-
- private AuthenticationConfiguration authenticationConfiguration;
-
- private InMemoryListenerConfig listenerConfig = null;
-
- private boolean useTls = false;
- private SSLSocketFactory socketFactory = null;
-
- private Integer maxSizeLimit = null;
-
- public EmbeddedLdapRuleBuilder() {
- }
+public class EmbeddedLdapRuleBuilder extends AbstractEmbeddedLdapBuilder {
/**
* Creates a new builder
@@ -70,119 +19,8 @@ public static EmbeddedLdapRuleBuilder newInstance() {
return new EmbeddedLdapRuleBuilder();
}
- /**
- * Sets a domainDsn to be used. May be multiple values. If not set, it will default to the value of the {@link #DEFAULT_DOMAIN DEFAULT_DOMAIN} field
- *
- * @param domainDsn a valid DSN string
- * @return same EmbeddedLdapRuleBuilder instance with the domainDsn field set
- */
- public EmbeddedLdapRuleBuilder usingDomainDsn(final String domainDsn) {
- this.domainDsn.add(domainDsn);
- return this;
- }
-
- /**
- * Sets the DSN to bind to when authenticating. If not set, it will default to the value of the {@link #DEFAULT_BIND_DSN DEFAULT_BIND_DSN} field
- *
- * @param bindDSN a valid DSN string
- * @return same EmbeddedLdapRuleBuilder instance with the bindDSN field set
- */
- public EmbeddedLdapRuleBuilder usingBindDSN(final String bindDSN) {
- this.bindDSN = bindDSN;
- return this;
- }
-
- /**
- * Sets the credentials to be used to authenticate. If not set, it will default to the value of the {@link #DEFAULT_BIND_CREDENTIALS DEFAULT_BIND_CREDENTIALS} field
- *
- * @param bindCredentials a password string
- * @return same EmbeddedLdapRuleBuilder instance with the bindCredentials field set
- */
- public EmbeddedLdapRuleBuilder usingBindCredentials(final String bindCredentials) {
- this.bindCredentials = bindCredentials;
- return this;
- }
-
- /**
- * Sets the port that the in-memory LDAP server will bind to. If not set, an available port will be picked automatically
- *
- * @param port a port number
- * @return same EmbeddedLdapRuleBuilder instance with the port field set
- * @throws IllegalArgumentException if the provided value for port is not between @{link MIN_PORT_EXCLUSIVE}
- * and @{MAX_PORT_EXCLUSIVE} (exclusive)
- */
- public EmbeddedLdapRuleBuilder bindingToPort(final int port) {
- if ((port < MIN_PORT_EXCLUSIVE) || (port > MAX_PORT_EXCLUSIVE)) {
- throw new IllegalArgumentException(String.format("Value \"%s\" is not a valid port number", port));
- }
- this.bindPort = Integer.valueOf(port);
- return this;
- }
-
- /**
- * Allows the listening address for the embedded LDAP server to be set. If not set it will bind to localhost/127.0.0.1.
- *
- * @param address a valid hostname or textual representation of an IP address
- * @return same EmbeddedLdapRuleBuilder instance with the bindAddress field set
- * @throws IllegalArgumentException if the value provided for \"address\" is invalid
- */
- public EmbeddedLdapRuleBuilder bindingToAddress(final String address) {
- Objects.requireNonNull(address);
- try {
- final InetAddress addressByName = InetAddress.getByName(address);
- this.bindAddress = addressByName;
- } catch (UnknownHostException e) {
- throw new IllegalArgumentException(String.format("Unknown host address \"%s\"", address), e);
- }
- return this;
- }
-
- public EmbeddedLdapRuleBuilder withMaxSizeLimit(final int maxSizeLimit) {
- this.maxSizeLimit = Integer.valueOf(maxSizeLimit);
- return this;
- }
-
- /**
- * Avoid adding UnboundID's default schema that contains the most common LDAP elements defined through various RFC's.
- *
- * @return same EmbeddedLdapRuleBuilder instance with the withoutDefaultSchema field set to FALSE
- */
- public EmbeddedLdapRuleBuilder withoutDefaultSchema() {
- this.addDefaultSchema = false;
- return this;
- }
-
- /**
- * Define schemas to be used for the server. If not defined, UnboundID will set up a default schema.
- *
- * @param ldifSchemaFiles LDIF-files containing schema element definitions
- * @return same EmbeddedLdapRuleBuilder with the given LDIF-files added to the internal schema file collection.
- */
- public EmbeddedLdapRuleBuilder withSchema(final String... ldifSchemaFiles) {
- this.schemaLdifs.addAll(Arrays.asList(ldifSchemaFiles));
- return this;
- }
-
- /**
- * Specify one or more LDIF resources to be imported on startup.
- *
- * @param ldifFiles LDIF-files to import
- * @return same EmbeddedLdapRuleBuilder instance with the provided ldifFiles added to the list of LDIF files to import
- */
- public EmbeddedLdapRuleBuilder importingLdifs(final String... ldifFiles) {
- if (ldifFiles != null) {
- ldifsToImport.addAll(Arrays.asList(ldifFiles));
- }
- return this;
- }
-
- public EmbeddedLdapRuleBuilder withListener(InMemoryListenerConfig listenerConfig) {
- this.listenerConfig = listenerConfig;
- return this;
- }
-
- public EmbeddedLdapRuleBuilder useTls(boolean useTls) {
- this.useTls = useTls;
+ @Override
+ protected EmbeddedLdapRuleBuilder getThis() {
return this;
}
@@ -195,91 +33,7 @@ public EmbeddedLdapRule build() {
Objects.requireNonNull(bindDSN, "\"bindDSN\" can not be null");
return EmbeddedLdapRuleImpl.createForConfiguration(createInMemoryServerConfiguration(),
authenticationConfiguration,
- ldifsToImport, useTls, socketFactory);
- }
-
- private InMemoryDirectoryServerConfig createInMemoryServerConfiguration() {
- try {
- final InMemoryDirectoryServerConfig inMemoryDirectoryServerConfig =
- new InMemoryDirectoryServerConfig(domainDsnArray());
-
- if (bindCredentials != null) {
- this.authenticationConfiguration = new AuthenticationConfiguration(bindDSN, bindCredentials);
- inMemoryDirectoryServerConfig.addAdditionalBindCredentials(bindDSN, bindCredentials);
- }
-
- if (listenerConfig == null) {
- listenerConfig = InMemoryListenerConfig.createLDAPConfig(
- LDAP_SERVER_LISTENER_NAME,
- bindAddress,
- bindPort,
- null);
- }
- inMemoryDirectoryServerConfig.setListenerConfigs(listenerConfig);
- inMemoryDirectoryServerConfig.setSchema(customSchema());
- if(maxSizeLimit != null) {
- inMemoryDirectoryServerConfig.setMaxSizeLimit(maxSizeLimit);
- }
- return inMemoryDirectoryServerConfig;
- } catch (LDAPException e) {
- throw new IllegalStateException(
- "Could not create configuration for the in-memory LDAP instance due to an exception",
- e);
- }
+ ldifsToImport);
}
- private String[] domainDsnArray() {
- if (domainDsn.size() == 0) {
- return new String[]{DEFAULT_DOMAIN};
- } else {
- return domainDsn.toArray(new String[]{});
- }
- }
-
- private Schema customSchema() {
- final List schemaFiles = schemaFiles();
-
- try {
- final Schema initialSchema = (addDefaultSchema ? Schema.getDefaultStandardSchema() : null);
- if (!schemaFiles.isEmpty()) {
- final Schema customSchema = initialSchema == null
- ? Schema.getSchema(schemaFiles)
- : Schema.mergeSchemas(initialSchema, Schema.getSchema(schemaFiles));
- return customSchema;
- } else {
- return null;
- }
-
- } catch (IOException | LDIFException | LDAPException e) {
- throw new IllegalArgumentException(
- "Could not create custom LDAP schema due, probably caused by an incorrectly formatted schema",
- e);
- }
- }
-
- private List schemaFiles() {
- return Lists.newArrayList(Lists.transform(this.schemaLdifs, new Function() {
- @Override
- public File apply(final String input) {
- try {
- final File file = new File(Resources.getResource(input).toURI());
- if (!file.isFile()) {
- throw new IllegalArgumentException(String.format(
- "The resource named \"%s\" can not be found or is not a file",
- input));
- }
- return file;
- } catch (URISyntaxException e) {
- throw new IllegalArgumentException(String.format(
- "The resource named \"%s\" is not a valid file reference",
- input), e);
- }
- }
- }));
- }
-
- public EmbeddedLdapRuleBuilder withSocketFactory(SSLSocketFactory socketFactory) {
- this.socketFactory = socketFactory;
- return this;
- }
}
diff --git a/src/main/java/org/zapodot/junit/ldap/EmbeddedLdapServer.java b/src/main/java/org/zapodot/junit/ldap/EmbeddedLdapServer.java
new file mode 100644
index 0000000..45191d9
--- /dev/null
+++ b/src/main/java/org/zapodot/junit/ldap/EmbeddedLdapServer.java
@@ -0,0 +1,60 @@
+package org.zapodot.junit.ldap;
+
+import com.unboundid.ldap.sdk.LDAPConnection;
+import com.unboundid.ldap.sdk.LDAPException;
+import com.unboundid.ldap.sdk.LDAPInterface;
+
+import javax.naming.Context;
+import javax.naming.NamingException;
+import javax.naming.directory.DirContext;
+
+public interface EmbeddedLdapServer {
+
+ /**
+ * For tests depending on the UnboundID LDAP SDK. Returns a proxied version of an Unboundid interface that will be
+ * closed when the test(s) have been invoked
+ *
+ * @return a shared LDAPConnection
+ * @throws LDAPException if a connection can not be opened
+ */
+ LDAPInterface ldapConnection() throws LDAPException;
+
+ /**
+ * For tests depending on the UnboundID LDAP SDK that needs access to an ${link LDAPConnection} object
+ * rather than the interface. If your code does not close the connection for you it will be closed on teardown
+ *
+ * @return a LDAPConnection connected to the embedded LDAP server
+ * @throws LDAPException if an exception occurred while establishing the connection
+ */
+ LDAPConnection unsharedLdapConnection() throws LDAPException;
+
+ /**
+ * For tests depending on the standard Java JNDI API
+ *
+ * @return a shared Context connected to the in-memory LDAP server
+ * @throws NamingException if context can not be created
+ */
+ Context context() throws NamingException;
+
+ /**
+ * Like {@link #context()}, but returns a DirContext
+ *
+ * @return a DirContext connected to the in-memory LDAP server
+ * @throws NamingException if a LDAP failure happens during DirContext creation
+ */
+ DirContext dirContext() throws NamingException;
+
+ /**
+ * Gives access to the listening port for the currently running embedded LDAP server.
+ * This will make it easier to use other integration mechanisms
+ *
+ * Note: the embedded LDAP server is by default configured to listen only on the loopback address
+ * (i.e localhost/127.0.0.1) unless another address has been provided to the builder when the rule was built
+ *
+ *
+ * @return the port number that the embedded server is listening to
+ * @see org.zapodot.junit.ldap.EmbeddedLdapRuleBuilder#bindingToAddress(String)
+ */
+ int embeddedServerPort();
+
+}
diff --git a/src/main/java/org/zapodot/junit/ldap/internal/AbstractEmbeddedLdapBuilder.java b/src/main/java/org/zapodot/junit/ldap/internal/AbstractEmbeddedLdapBuilder.java
new file mode 100644
index 0000000..e5326ea
--- /dev/null
+++ b/src/main/java/org/zapodot/junit/ldap/internal/AbstractEmbeddedLdapBuilder.java
@@ -0,0 +1,240 @@
+package org.zapodot.junit.ldap.internal;
+
+import com.google.common.base.Function;
+import com.google.common.collect.Lists;
+import com.google.common.io.Resources;
+import com.unboundid.ldap.listener.InMemoryDirectoryServerConfig;
+import com.unboundid.ldap.listener.InMemoryListenerConfig;
+import com.unboundid.ldap.sdk.LDAPException;
+import com.unboundid.ldap.sdk.schema.Schema;
+import com.unboundid.ldif.LDIFException;
+
+import java.io.File;
+import java.io.IOException;
+import java.net.InetAddress;
+import java.net.URISyntaxException;
+import java.net.UnknownHostException;
+import java.util.Arrays;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Objects;
+
+/**
+ * A builder providing a fluent way of defining {@link org.zapodot.junit.ldap.EmbeddedLdapRule}
+ * or {@link org.zapodot.junit.ldap.junit5.EmbeddedLdapExtension} instances.
+ */
+public abstract class AbstractEmbeddedLdapBuilder> {
+
+ public static final String DEFAULT_DOMAIN = "dc=example,dc=com";
+ public static final String DEFAULT_BIND_DSN = "cn=Directory manager";
+ public static final String DEFAULT_BIND_CREDENTIALS = "password";
+ public static final String LDAP_SERVER_LISTENER_NAME = "test-listener";
+ public static final int MIN_PORT_EXCLUSIVE = 0;
+ public static final int MAX_PORT_EXCLUSIVE = 65535;
+ private List domainDsn = new LinkedList<>();
+
+ protected String bindDSN = DEFAULT_BIND_DSN;
+
+ private String bindCredentials = DEFAULT_BIND_CREDENTIALS;
+
+ protected List ldifsToImport = new LinkedList<>();
+
+ private List schemaLdifs = new LinkedList<>();
+
+ private boolean addDefaultSchema = true;
+
+ private Integer bindPort = 0;
+
+ private InetAddress bindAddress = InetAddress.getLoopbackAddress();
+
+ protected AuthenticationConfiguration authenticationConfiguration;
+
+ private InMemoryListenerConfig listenerConfig = null;
+
+ /**
+ * Sets a domainDsn to be used. May be multiple values. If not set, it will default to the value of the {@link #DEFAULT_DOMAIN DEFAULT_DOMAIN} field
+ *
+ * @param domainDsn a valid DSN string
+ * @return same builder instance with the domainDsn field set
+ */
+ public Self usingDomainDsn(final String domainDsn) {
+ this.domainDsn.add(domainDsn);
+ return getThis();
+ }
+
+ /**
+ * Sets the DSN to bind to when authenticating. If not set, it will default to the value of the {@link #DEFAULT_BIND_DSN DEFAULT_BIND_DSN} field
+ *
+ * @param bindDSN a valid DSN string
+ * @return same builder instance with the bindDSN field set
+ */
+ public Self usingBindDSN(final String bindDSN) {
+ this.bindDSN = bindDSN;
+ return getThis();
+ }
+
+ /**
+ * Sets the credentials to be used to authenticate. If not set, it will default to the value of the {@link #DEFAULT_BIND_CREDENTIALS DEFAULT_BIND_CREDENTIALS} field
+ *
+ * @param bindCredentials a password string
+ * @return same builder instance with the bindCredentials field set
+ */
+ public Self usingBindCredentials(final String bindCredentials) {
+ this.bindCredentials = bindCredentials;
+ return getThis();
+ }
+
+ /**
+ * Sets the port that the in-memory LDAP server will bind to. If not set, an available port will be picked automatically
+ *
+ * @param port a port number
+ * @return same builder instance with the port field set
+ * @throws IllegalArgumentException if the provided value for port is not between @{link MIN_PORT_EXCLUSIVE}
+ * and @{MAX_PORT_EXCLUSIVE} (exclusive)
+ */
+ public Self bindingToPort(final int port) {
+ if ((port < MIN_PORT_EXCLUSIVE) || (port > MAX_PORT_EXCLUSIVE)) {
+ throw new IllegalArgumentException(String.format("Value \"%s\" is not a valid port number", port));
+ }
+ this.bindPort = Integer.valueOf(port);
+ return getThis();
+ }
+
+ /**
+ * Allows the listening address for the embedded LDAP server to be set. If not set it will bind to localhost/127.0.0.1.
+ *
+ * @param address a valid hostname or textual representation of an IP address
+ * @return same builder instance with the bindAddress field set
+ * @throws IllegalArgumentException if the value provided for \"address\" is invalid
+ */
+ public Self bindingToAddress(final String address) {
+ Objects.requireNonNull(address);
+ try {
+ final InetAddress addressByName = InetAddress.getByName(address);
+ this.bindAddress = addressByName;
+ } catch (UnknownHostException e) {
+ throw new IllegalArgumentException(String.format("Unknown host address \"%s\"", address), e);
+ }
+ return getThis();
+ }
+
+ /**
+ * Avoid adding UnboundID's default schema that contains the most common LDAP elements defined through various RFC's.
+ *
+ * @return same builder instance with the withoutDefaultSchema field set to FALSE
+ */
+ public Self withoutDefaultSchema() {
+ this.addDefaultSchema = false;
+ return getThis();
+ }
+
+ /**
+ * Define schemas to be used for the server. If not defined, UnboundID will set up a default schema.
+ *
+ * @param ldifSchemaFiles LDIF-files containing schema element definitions
+ * @return same builder with the given LDIF-files added to the internal schema file collection.
+ */
+ public Self withSchema(final String... ldifSchemaFiles) {
+ this.schemaLdifs.addAll(Arrays.asList(ldifSchemaFiles));
+ return getThis();
+ }
+
+ /**
+ * Specify one or more LDIF resources to be imported on startup.
+ *
+ * @param ldifFiles LDIF-files to import
+ * @return same builder instance with the provided ldifFiles added to the list of LDIF files to import
+ */
+ public Self importingLdifs(final String... ldifFiles) {
+ if (ldifFiles != null) {
+ ldifsToImport.addAll(Arrays.asList(ldifFiles));
+ }
+ return getThis();
+ }
+
+ public Self withListener(InMemoryListenerConfig listenerConfig) {
+ this.listenerConfig = listenerConfig;
+ return getThis();
+ }
+
+ protected abstract Self getThis();
+
+ protected InMemoryDirectoryServerConfig createInMemoryServerConfiguration() {
+ try {
+ final InMemoryDirectoryServerConfig inMemoryDirectoryServerConfig =
+ new InMemoryDirectoryServerConfig(domainDsnArray());
+
+ if (bindCredentials != null) {
+ this.authenticationConfiguration = new AuthenticationConfiguration(bindDSN, bindCredentials);
+ inMemoryDirectoryServerConfig.addAdditionalBindCredentials(bindDSN, bindCredentials);
+ }
+
+ if (listenerConfig == null) {
+ listenerConfig = InMemoryListenerConfig.createLDAPConfig(
+ LDAP_SERVER_LISTENER_NAME,
+ bindAddress,
+ bindPort,
+ null);
+ }
+ inMemoryDirectoryServerConfig.setListenerConfigs(listenerConfig);
+ inMemoryDirectoryServerConfig.setSchema(customSchema());
+ return inMemoryDirectoryServerConfig;
+ } catch (LDAPException e) {
+ throw new IllegalStateException(
+ "Could not create configuration for the in-memory LDAP instance due to an exception",
+ e);
+ }
+ }
+
+ private String[] domainDsnArray() {
+ if (domainDsn.size() == 0) {
+ return new String[]{DEFAULT_DOMAIN};
+ } else {
+ return domainDsn.toArray(new String[]{});
+ }
+ }
+
+ private Schema customSchema() {
+ final List schemaFiles = schemaFiles();
+
+ try {
+ final Schema initialSchema = (addDefaultSchema ? Schema.getDefaultStandardSchema() : null);
+ if (!schemaFiles.isEmpty()) {
+ final Schema customSchema = initialSchema == null
+ ? Schema.getSchema(schemaFiles)
+ : Schema.mergeSchemas(initialSchema, Schema.getSchema(schemaFiles));
+ return customSchema;
+ } else {
+ return null;
+ }
+
+ } catch (IOException | LDIFException | LDAPException e) {
+ throw new IllegalArgumentException(
+ "Could not create custom LDAP schema due, probably caused by an incorrectly formatted schema",
+ e);
+ }
+ }
+
+ private List schemaFiles() {
+ return Lists.newArrayList(Lists.transform(this.schemaLdifs, new Function() {
+ @Override
+ public File apply(final String input) {
+ try {
+ final File file = new File(Resources.getResource(input).toURI());
+ if (!file.isFile()) {
+ throw new IllegalArgumentException(String.format(
+ "The resource named \"%s\" can not be found or is not a file",
+ input));
+ }
+ return file;
+ } catch (URISyntaxException e) {
+ throw new IllegalArgumentException(String.format(
+ "The resource named \"%s\" is not a valid file reference",
+ input), e);
+ }
+ }
+ }));
+ }
+
+
+}
diff --git a/src/main/java/org/zapodot/junit/ldap/internal/EmbeddedLdapExtensionImpl.java b/src/main/java/org/zapodot/junit/ldap/internal/EmbeddedLdapExtensionImpl.java
new file mode 100644
index 0000000..1daf1ab
--- /dev/null
+++ b/src/main/java/org/zapodot/junit/ldap/internal/EmbeddedLdapExtensionImpl.java
@@ -0,0 +1,54 @@
+package org.zapodot.junit.ldap.internal;
+
+import com.unboundid.ldap.listener.InMemoryDirectoryServer;
+import com.unboundid.ldap.listener.InMemoryDirectoryServerConfig;
+import com.unboundid.ldap.sdk.LDAPException;
+import org.junit.jupiter.api.extension.ExtensionContext;
+import org.zapodot.junit.ldap.junit5.EmbeddedLdapExtension;
+
+import java.util.List;
+
+public class EmbeddedLdapExtensionImpl extends EmbeddedLdapServerImpl implements EmbeddedLdapExtension {
+
+ public static EmbeddedLdapExtension createForConfiguration(final InMemoryDirectoryServerConfig inMemoryDirectoryServerConfig,
+ final AuthenticationConfiguration authenticationConfiguration,
+ final List ldifs) {
+ try {
+ return new EmbeddedLdapExtensionImpl(createServer(inMemoryDirectoryServerConfig, ldifs),
+ authenticationConfiguration);
+ } catch (LDAPException e) {
+ throw new IllegalStateException("Can not initiate in-memory LDAP server due to an exception", e);
+ }
+ }
+
+ private boolean isStartedBeforeAll = false;
+
+ public EmbeddedLdapExtensionImpl(InMemoryDirectoryServer inMemoryDirectoryServer, AuthenticationConfiguration authenticationConfiguration1) {
+ super(inMemoryDirectoryServer, authenticationConfiguration1);
+ }
+
+ @Override
+ public void beforeAll(ExtensionContext extensionContext) throws Exception {
+ isStartedBeforeAll = true;
+ startEmbeddedLdapServer();
+ }
+
+ @Override
+ public void afterAll(ExtensionContext extensionContext) {
+ takeDownEmbeddedLdapServer();
+ }
+
+ @Override
+ public void beforeEach(ExtensionContext extensionContext) throws Exception {
+ if (!isStartedBeforeAll) {
+ startEmbeddedLdapServer();
+ }
+ }
+
+ @Override
+ public void afterEach(ExtensionContext extensionContext) {
+ if (!isStartedBeforeAll) {
+ takeDownEmbeddedLdapServer();
+ }
+ }
+}
diff --git a/src/main/java/org/zapodot/junit/ldap/internal/EmbeddedLdapRuleImpl.java b/src/main/java/org/zapodot/junit/ldap/internal/EmbeddedLdapRuleImpl.java
index a394874..9f33d28 100755
--- a/src/main/java/org/zapodot/junit/ldap/internal/EmbeddedLdapRuleImpl.java
+++ b/src/main/java/org/zapodot/junit/ldap/internal/EmbeddedLdapRuleImpl.java
@@ -1,216 +1,31 @@
package org.zapodot.junit.ldap.internal;
-import com.google.common.base.Charsets;
-import com.google.common.io.Resources;
import com.unboundid.ldap.listener.InMemoryDirectoryServer;
import com.unboundid.ldap.listener.InMemoryDirectoryServerConfig;
-import com.unboundid.ldap.sdk.LDAPConnection;
import com.unboundid.ldap.sdk.LDAPException;
-import com.unboundid.ldap.sdk.LDAPInterface;
import org.junit.runner.Description;
import org.junit.runners.model.Statement;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
import org.zapodot.junit.ldap.EmbeddedLdapRule;
-import org.zapodot.junit.ldap.internal.jndi.ContextProxyFactory;
-import org.zapodot.junit.ldap.internal.unboundid.LDAPInterfaceProxyFactory;
-import javax.naming.Context;
-import javax.naming.NamingException;
-import javax.naming.directory.DirContext;
-import javax.naming.directory.InitialDirContext;
-import javax.naming.ldap.LdapContext;
-import java.io.UnsupportedEncodingException;
-import java.lang.reflect.Modifier;
-
-import javax.net.SocketFactory;
-import javax.net.ssl.SSLSocketFactory;
-
-import java.io.IOException;
-import java.io.UnsupportedEncodingException;
-import java.net.InetAddress;
-import java.net.Socket;
-import java.net.URLDecoder;
-import java.net.UnknownHostException;
-import java.util.Hashtable;
import java.util.List;
-import net.bytebuddy.ByteBuddy;
-import net.bytebuddy.dynamic.loading.ClassLoadingStrategy;
-import net.bytebuddy.implementation.FixedValue;
-
-public class EmbeddedLdapRuleImpl implements EmbeddedLdapRule {
-
- private static final String JAVA_RT_CONTROL_FACTORY = "com.sun.jndi.ldap.DefaultResponseControlFactory";
-
- private static final String JAVA_RT_CONTEXT_FACTORY = "com.sun.jndi.ldap.LdapCtxFactory";
+public class EmbeddedLdapRuleImpl extends EmbeddedLdapServerImpl implements EmbeddedLdapRule {
- private static Logger logger = LoggerFactory.getLogger(EmbeddedLdapRuleImpl.class);
- private final InMemoryDirectoryServer inMemoryDirectoryServer;
- private final AuthenticationConfiguration authenticationConfiguration;
- private LDAPConnection ldapConnection;
- private InitialDirContext initialDirContext;
- private boolean isStarted = false;
- private final boolean useTls;
- private final SSLSocketFactory socketFactory;
-
- private EmbeddedLdapRuleImpl(final InMemoryDirectoryServer inMemoryDirectoryServer,
- final AuthenticationConfiguration authenticationConfiguration1,
- final boolean useTls, SSLSocketFactory socketFactory) {
- this.inMemoryDirectoryServer = inMemoryDirectoryServer;
- this.authenticationConfiguration = authenticationConfiguration1;
- this.useTls = useTls;
- this.socketFactory = socketFactory;
- }
-
- public static EmbeddedLdapRule createForConfiguration(
- final InMemoryDirectoryServerConfig inMemoryDirectoryServerConfig,
- final AuthenticationConfiguration authenticationConfiguration,
- final List ldifs, boolean useTls, SSLSocketFactory socketFactory) {
+ public static EmbeddedLdapRule createForConfiguration(final InMemoryDirectoryServerConfig inMemoryDirectoryServerConfig,
+ final AuthenticationConfiguration authenticationConfiguration,
+ final List ldifs) {
try {
return new EmbeddedLdapRuleImpl(createServer(inMemoryDirectoryServerConfig, ldifs),
- authenticationConfiguration, useTls, socketFactory);
+ authenticationConfiguration);
} catch (LDAPException e) {
throw new IllegalStateException("Can not initiate in-memory LDAP server due to an exception", e);
}
}
- private static InMemoryDirectoryServer createServer(final InMemoryDirectoryServerConfig inMemoryDirectoryServerConfig,
- final List ldifs) throws LDAPException {
- final InMemoryDirectoryServer ldapServer =
- new InMemoryDirectoryServer(inMemoryDirectoryServerConfig);
- if (ldifs != null && !ldifs.isEmpty()) {
- for (final String ldif : ldifs) {
- try {
- ldapServer.importFromLDIF(false, URLDecoder.decode(Resources.getResource(ldif).getPath(),
- Charsets.UTF_8.name()));
- } catch (UnsupportedEncodingException e) {
- throw new IllegalStateException("Can not URL decode path:" + Resources.getResource(ldif).getPath(),
- e);
- }
- }
- }
- return ldapServer;
+ public EmbeddedLdapRuleImpl(InMemoryDirectoryServer inMemoryDirectoryServer, AuthenticationConfiguration authenticationConfiguration1) {
+ super(inMemoryDirectoryServer, authenticationConfiguration1);
}
- @Override
- public LDAPInterface ldapConnection() throws LDAPException {
- return LDAPInterfaceProxyFactory.createProxy(createOrGetLdapConnection());
- }
-
- @Override
- public LDAPConnection unsharedLdapConnection() throws LDAPException {
- return createOrGetLdapConnection();
- }
-
- private LDAPConnection createOrGetLdapConnection() throws LDAPException {
- if (isStarted) {
- if (ldapConnection == null || ! ldapConnection.isConnected()) {
- ldapConnection = inMemoryDirectoryServer.getConnection();
- }
- return ldapConnection;
- } else {
- throw new IllegalStateException(
- "Can not get a LdapConnection before the embedded LDAP server has been started");
- }
- }
-
- @Override
- public Context context() throws NamingException {
- return ContextProxyFactory.asDelegatingContext(createOrGetInitialDirContext());
- }
-
- @Override
- public DirContext dirContext() throws NamingException {
- return ContextProxyFactory.asDelegatingDirContext(createOrGetInitialDirContext());
- }
-
- @Override
- public int embeddedServerPort() {
- if(isStarted) {
- return inMemoryDirectoryServer.getListenPort();
- } else {
- throw new IllegalStateException("The embedded server must be started prior to accessing the listening port");
- }
- }
-
- private InitialDirContext createOrGetInitialDirContext() throws NamingException {
- if (isStarted) {
- if (initialDirContext == null) {
- initialDirContext = new InitialDirContext(createLdapEnvironment());
- }
- return initialDirContext;
- } else {
- throw new IllegalStateException(
- "Can not get an InitialDirContext before the embedded LDAP server has been started");
- }
- }
-
- public static abstract class AbstractDelegatingSocketFactory extends SocketFactory {
- public static AbstractDelegatingSocketFactory INSTANCE;
-
- public static AbstractDelegatingSocketFactory getDefault() {
- return INSTANCE;
- }
-
- protected abstract SocketFactory getDelegate();
-
- @Override
- public Socket createSocket() throws IOException, UnknownHostException {
- return getDelegate().createSocket();
- }
-
- @Override
- public Socket createSocket(String host, int port) throws IOException, UnknownHostException {
- return getDelegate().createSocket(host, port);
- }
-
- @Override
- public Socket createSocket(String host, int port, InetAddress localHost, int localPort)
- throws IOException, UnknownHostException {
- return getDelegate().createSocket(host, port, localHost, localPort);
- }
-
- @Override
- public Socket createSocket(InetAddress host, int port) throws IOException {
- return getDelegate().createSocket(host, port);
- }
-
- @Override
- public Socket createSocket(InetAddress address, int port, InetAddress localAddress, int localPort)
- throws IOException {
- return getDelegate().createSocket(address, port, localAddress, localPort);
- }
- }
-
- private Hashtable createLdapEnvironment() {
- final Hashtable environment = new Hashtable<>();
- if (socketFactory != null) {
- final Class> delegator = (new ByteBuddy()).subclass(AbstractDelegatingSocketFactory.class)
- .defineMethod("getDelegate", SocketFactory.class, Modifier.PROTECTED)
- .intercept(FixedValue.value(socketFactory))
- .make()
- .load(getClass().getClassLoader(), ClassLoadingStrategy.Default.INJECTION)
- .getLoaded();
- try {
- final Object instance = delegator.newInstance();
- delegator.getField("INSTANCE").set(instance, instance);
- } catch (InstantiationException | IllegalAccessException | NoSuchFieldException e) {
- throw new IllegalStateException(e);
- }
- environment.put("java.naming.ldap.factory.socket", delegator.getCanonicalName());
- }
- environment.put(LdapContext.CONTROL_FACTORIES, JAVA_RT_CONTROL_FACTORY);
- environment.put(Context.PROVIDER_URL, String.format("%s://%s:%s",
- useTls ? "ldaps" : "ldap",
- inMemoryDirectoryServer.getListenAddress().getHostName(),
- embeddedServerPort()));
- environment.put(Context.INITIAL_CONTEXT_FACTORY, JAVA_RT_CONTEXT_FACTORY);
- if (authenticationConfiguration != null) {
- environment.putAll(authenticationConfiguration.toAuthenticationEnvironment());
- }
- return environment;
- }
@Override
public Statement apply(final Statement base, final Description description) {
@@ -231,26 +46,4 @@ public void evaluate() throws Throwable {
};
}
- private void startEmbeddedLdapServer() throws LDAPException {
- inMemoryDirectoryServer.startListening();
- isStarted = true;
- }
-
- private void takeDownEmbeddedLdapServer() {
- try {
- if (ldapConnection != null && ldapConnection.isConnected()) {
- ldapConnection.close();
- }
- if (initialDirContext != null) {
- initialDirContext.close();
- }
- } catch (NamingException e) {
- logger.info("Could not close initial context, forcing server shutdown anyway", e);
- } finally {
- inMemoryDirectoryServer.shutDown(true);
- }
-
- }
-
-
}
diff --git a/src/main/java/org/zapodot/junit/ldap/internal/EmbeddedLdapServerImpl.java b/src/main/java/org/zapodot/junit/ldap/internal/EmbeddedLdapServerImpl.java
new file mode 100644
index 0000000..161ee12
--- /dev/null
+++ b/src/main/java/org/zapodot/junit/ldap/internal/EmbeddedLdapServerImpl.java
@@ -0,0 +1,148 @@
+package org.zapodot.junit.ldap.internal;
+
+import com.google.common.base.Charsets;
+import com.google.common.io.Resources;
+import com.unboundid.ldap.listener.InMemoryDirectoryServer;
+import com.unboundid.ldap.listener.InMemoryDirectoryServerConfig;
+import com.unboundid.ldap.sdk.LDAPConnection;
+import com.unboundid.ldap.sdk.LDAPException;
+import com.unboundid.ldap.sdk.LDAPInterface;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.zapodot.junit.ldap.EmbeddedLdapServer;
+import org.zapodot.junit.ldap.internal.jndi.ContextProxyFactory;
+import org.zapodot.junit.ldap.internal.unboundid.LDAPInterfaceProxyFactory;
+
+import javax.naming.Context;
+import javax.naming.NamingException;
+import javax.naming.directory.DirContext;
+import javax.naming.directory.InitialDirContext;
+import javax.naming.ldap.LdapContext;
+import java.io.UnsupportedEncodingException;
+import java.net.URLDecoder;
+import java.util.Hashtable;
+import java.util.List;
+
+abstract class EmbeddedLdapServerImpl implements EmbeddedLdapServer {
+ private static final String JAVA_RT_CONTROL_FACTORY = "com.sun.jndi.ldap.DefaultResponseControlFactory";
+
+ private static final String JAVA_RT_CONTEXT_FACTORY = "com.sun.jndi.ldap.LdapCtxFactory";
+
+ private static Logger logger = LoggerFactory.getLogger(EmbeddedLdapExtensionImpl.class);
+ private final InMemoryDirectoryServer inMemoryDirectoryServer;
+ private final AuthenticationConfiguration authenticationConfiguration;
+ private LDAPConnection ldapConnection;
+ private InitialDirContext initialDirContext;
+ private boolean isStarted = false;
+
+ public EmbeddedLdapServerImpl(final InMemoryDirectoryServer inMemoryDirectoryServer,
+ final AuthenticationConfiguration authenticationConfiguration1) {
+ this.inMemoryDirectoryServer = inMemoryDirectoryServer;
+ this.authenticationConfiguration = authenticationConfiguration1;
+ }
+
+ protected static InMemoryDirectoryServer createServer(final InMemoryDirectoryServerConfig inMemoryDirectoryServerConfig,
+ final List ldifs) throws LDAPException {
+ final InMemoryDirectoryServer ldapServer =
+ new InMemoryDirectoryServer(inMemoryDirectoryServerConfig);
+ if (ldifs != null && !ldifs.isEmpty()) {
+ for (final String ldif : ldifs) {
+ try {
+ ldapServer.importFromLDIF(false, URLDecoder.decode(Resources.getResource(ldif).getPath(),
+ Charsets.UTF_8.name()));
+ } catch (UnsupportedEncodingException e) {
+ throw new IllegalStateException("Can not URL decode path:" + Resources.getResource(ldif).getPath(),
+ e);
+ }
+ }
+ }
+ return ldapServer;
+ }
+
+ @Override
+ public LDAPInterface ldapConnection() throws LDAPException {
+ return LDAPInterfaceProxyFactory.createProxy(createOrGetLdapConnection());
+ }
+
+ @Override
+ public LDAPConnection unsharedLdapConnection() throws LDAPException {
+ return createOrGetLdapConnection();
+ }
+
+ private LDAPConnection createOrGetLdapConnection() throws LDAPException {
+ if (isStarted) {
+ if (ldapConnection == null || ! ldapConnection.isConnected()) {
+ ldapConnection = inMemoryDirectoryServer.getConnection();
+ }
+ return ldapConnection;
+ } else {
+ throw new IllegalStateException(
+ "Can not get a LdapConnection before the embedded LDAP server has been started");
+ }
+ }
+
+ @Override
+ public Context context() throws NamingException {
+ return ContextProxyFactory.asDelegatingContext(createOrGetInitialDirContext());
+ }
+
+ @Override
+ public DirContext dirContext() throws NamingException {
+ return ContextProxyFactory.asDelegatingDirContext(createOrGetInitialDirContext());
+ }
+
+ @Override
+ public int embeddedServerPort() {
+ if(isStarted) {
+ return inMemoryDirectoryServer.getListenPort();
+ } else {
+ throw new IllegalStateException("The embedded server must be started prior to accessing the listening port");
+ }
+ }
+
+ private InitialDirContext createOrGetInitialDirContext() throws NamingException {
+ if (isStarted) {
+ if (initialDirContext == null) {
+ initialDirContext = new InitialDirContext(createLdapEnvironment());
+ }
+ return initialDirContext;
+ } else {
+ throw new IllegalStateException(
+ "Can not get an InitialDirContext before the embedded LDAP server has been started");
+ }
+ }
+
+ private Hashtable createLdapEnvironment() {
+ final Hashtable environment = new Hashtable<>();
+ environment.put(LdapContext.CONTROL_FACTORIES, JAVA_RT_CONTROL_FACTORY);
+ environment.put(Context.PROVIDER_URL, String.format("ldap://%s:%s",
+ inMemoryDirectoryServer.getListenAddress().getHostName(),
+ embeddedServerPort()));
+ environment.put(Context.INITIAL_CONTEXT_FACTORY, JAVA_RT_CONTEXT_FACTORY);
+ if (authenticationConfiguration != null) {
+ environment.putAll(authenticationConfiguration.toAuthenticationEnvironment());
+ }
+ return environment;
+ }
+
+ protected void startEmbeddedLdapServer() throws LDAPException {
+ inMemoryDirectoryServer.startListening();
+ isStarted = true;
+ }
+
+ protected void takeDownEmbeddedLdapServer() {
+ try {
+ if (ldapConnection != null && ldapConnection.isConnected()) {
+ ldapConnection.close();
+ }
+ if (initialDirContext != null) {
+ initialDirContext.close();
+ }
+ } catch (NamingException e) {
+ logger.info("Could not close initial context, forcing server shutdown anyway", e);
+ } finally {
+ inMemoryDirectoryServer.shutDown(true);
+ }
+
+ }
+}
diff --git a/src/main/java/org/zapodot/junit/ldap/junit5/EmbeddedLdapExtension.java b/src/main/java/org/zapodot/junit/ldap/junit5/EmbeddedLdapExtension.java
new file mode 100644
index 0000000..10ccbf3
--- /dev/null
+++ b/src/main/java/org/zapodot/junit/ldap/junit5/EmbeddedLdapExtension.java
@@ -0,0 +1,14 @@
+package org.zapodot.junit.ldap.junit5;
+
+import org.junit.jupiter.api.extension.*;
+import org.zapodot.junit.ldap.EmbeddedLdapServer;
+
+/**
+ * A JUnit 5 extension that can be registered with @{@link RegisterExtension}
+ * (supports both {@code static} and instance fields).
+ */
+public interface EmbeddedLdapExtension extends EmbeddedLdapServer, Extension,
+ BeforeEachCallback, AfterEachCallback,
+ BeforeAllCallback, AfterAllCallback {
+
+}
diff --git a/src/main/java/org/zapodot/junit/ldap/junit5/EmbeddedLdapExtensionBuilder.java b/src/main/java/org/zapodot/junit/ldap/junit5/EmbeddedLdapExtensionBuilder.java
new file mode 100644
index 0000000..3bee8b7
--- /dev/null
+++ b/src/main/java/org/zapodot/junit/ldap/junit5/EmbeddedLdapExtensionBuilder.java
@@ -0,0 +1,38 @@
+package org.zapodot.junit.ldap.junit5;
+
+import org.zapodot.junit.ldap.internal.AbstractEmbeddedLdapBuilder;
+import org.zapodot.junit.ldap.internal.EmbeddedLdapExtensionImpl;
+
+import java.util.Objects;
+
+/**
+ * A builder providing a fluent way of defining {@link EmbeddedLdapExtension} instances.
+ */
+public class EmbeddedLdapExtensionBuilder extends AbstractEmbeddedLdapBuilder {
+
+ /**
+ * Creates a new builder
+ *
+ * @return a new EmbeddedLdapExtensionBuilder instance
+ */
+ public static EmbeddedLdapExtensionBuilder newInstance() {
+ return new EmbeddedLdapExtensionBuilder();
+ }
+
+ /**
+ * Creates a new extension based on the information that was previously provided
+ *
+ * @return a new EmbeddedLdapExtension instance
+ */
+ public EmbeddedLdapExtension build() {
+ Objects.requireNonNull(bindDSN, "\"bindDSN\" can not be null");
+ return EmbeddedLdapExtensionImpl.createForConfiguration(createInMemoryServerConfiguration(),
+ authenticationConfiguration,
+ ldifsToImport);
+ }
+
+ @Override
+ protected EmbeddedLdapExtensionBuilder getThis() {
+ return this;
+ }
+}
diff --git a/src/test/java/org/zapodot/junit/ldap/junit5/EmbeddedLdapExtensionBuilderTest.java b/src/test/java/org/zapodot/junit/ldap/junit5/EmbeddedLdapExtensionBuilderTest.java
new file mode 100644
index 0000000..77d0d1e
--- /dev/null
+++ b/src/test/java/org/zapodot/junit/ldap/junit5/EmbeddedLdapExtensionBuilderTest.java
@@ -0,0 +1,87 @@
+package org.zapodot.junit.ldap.junit5;
+
+import org.junit.Test;
+
+import static org.junit.Assert.assertNotNull;
+
+public class EmbeddedLdapExtensionBuilderTest {
+
+ @Test
+ public void bindingToLegalPort() {
+ assertNotNull(EmbeddedLdapExtensionBuilder.newInstance().bindingToPort(9999));
+ }
+
+ @Test(expected = IllegalStateException.class)
+ public void testPrematureLdapConnection() throws Exception {
+ EmbeddedLdapExtensionBuilder.newInstance().build().ldapConnection();
+
+ }
+
+ @Test(expected = IllegalStateException.class)
+ public void testPrematureContext() throws Exception {
+ EmbeddedLdapExtensionBuilder.newInstance().build().context();
+
+ }
+
+ @Test(expected = IllegalArgumentException.class)
+ public void testUnknownLDIF() {
+ EmbeddedLdapExtensionBuilder.newInstance().importingLdifs("nonExisting.ldif").build();
+
+ }
+
+ @Test
+ public void testNullLDIF() {
+ assertNotNull(EmbeddedLdapExtensionBuilder.newInstance().importingLdifs(null).build());
+
+ }
+
+ @Test(expected = IllegalStateException.class)
+ public void testIllegalDSN() {
+ EmbeddedLdapExtensionBuilder.newInstance().usingBindDSN("bindDsn").build();
+
+ }
+
+ @Test(expected = IllegalArgumentException.class)
+ public void testIllegalPort() {
+ EmbeddedLdapExtensionBuilder.newInstance().bindingToPort(Integer.MIN_VALUE).build();
+
+ }
+
+ @Test(expected = IllegalArgumentException.class)
+ public void testSchemaNotFound() {
+ EmbeddedLdapExtensionBuilder.newInstance().withSchema("non-existing-schema.ldif").build();
+
+ }
+
+ @Test(expected = IllegalArgumentException.class)
+ public void testSchemaIsNotAFile() {
+ EmbeddedLdapExtensionBuilder.newInstance().withSchema("folder").build();
+
+ }
+
+ @Test(expected = IllegalArgumentException.class)
+ public void testSchemaIsInvalid() {
+ EmbeddedLdapExtensionBuilder.newInstance().withSchema("invalid.ldif").build();
+
+ }
+
+ @Test(expected = IllegalArgumentException.class)
+ public void testSchemaFileUnsupportedIsInvalid() {
+ EmbeddedLdapExtensionBuilder.newInstance().withSchema("\"#%¤&&%/¤##¤¤").build();
+
+ }
+
+ @Test(expected = IllegalArgumentException.class)
+ public void testInvalidPort() {
+ EmbeddedLdapExtensionBuilder.newInstance().bindingToPort(Integer.MAX_VALUE);
+
+ }
+
+ @Test(expected = IllegalArgumentException.class)
+ public void testInvalidBindAddress() {
+ EmbeddedLdapExtensionBuilder.newInstance().bindingToAddress("åpsldfåpl");
+
+ }
+
+
+}
diff --git a/src/test/java/org/zapodot/junit/ldap/junit5/EmbeddedLdapExtensionStaticTest.java b/src/test/java/org/zapodot/junit/ldap/junit5/EmbeddedLdapExtensionStaticTest.java
new file mode 100644
index 0000000..5fa054f
--- /dev/null
+++ b/src/test/java/org/zapodot/junit/ldap/junit5/EmbeddedLdapExtensionStaticTest.java
@@ -0,0 +1,28 @@
+package org.zapodot.junit.ldap.junit5;
+
+import com.unboundid.ldap.sdk.LDAPInterface;
+import com.unboundid.ldap.sdk.SearchScope;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.RegisterExtension;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+
+class EmbeddedLdapExtensionStaticTest {
+ public static final String DOMAIN_DSN = "dc=zapodot,dc=org";
+
+ @RegisterExtension
+ public static EmbeddedLdapExtension embeddedLdapExtension = EmbeddedLdapExtensionBuilder
+ .newInstance()
+ .usingDomainDsn(DOMAIN_DSN)
+ .usingBindDSN("cn=Directory manager")
+ .usingBindCredentials("testPass")
+ .importingLdifs("example.ldif")
+ .build();
+
+ @Test
+ void testCheck() throws Exception {
+ final LDAPInterface ldapConnection = embeddedLdapExtension.ldapConnection();
+ assertEquals(4, ldapConnection.search(DOMAIN_DSN, SearchScope.SUB, "(objectClass=*)").getEntryCount());
+
+ }
+}
diff --git a/src/test/java/org/zapodot/junit/ldap/junit5/EmbeddedLdapExtensionTest.java b/src/test/java/org/zapodot/junit/ldap/junit5/EmbeddedLdapExtensionTest.java
new file mode 100644
index 0000000..d2e40f7
--- /dev/null
+++ b/src/test/java/org/zapodot/junit/ldap/junit5/EmbeddedLdapExtensionTest.java
@@ -0,0 +1,94 @@
+package org.zapodot.junit.ldap.junit5;
+
+import com.google.common.collect.Iterators;
+import com.unboundid.ldap.sdk.*;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.RegisterExtension;
+
+import javax.naming.Context;
+import javax.naming.NamingEnumeration;
+import javax.naming.directory.DirContext;
+import javax.naming.directory.SearchControls;
+import java.util.Arrays;
+
+import static org.junit.jupiter.api.Assertions.*;
+
+class EmbeddedLdapExtensionTest {
+
+ public static final String DOMAIN_DSN = "dc=zapodot,dc=org";
+
+ @RegisterExtension
+ public EmbeddedLdapExtension embeddedLdapExtension = EmbeddedLdapExtensionBuilder
+ .newInstance()
+ .usingDomainDsn(DOMAIN_DSN)
+ .importingLdifs("example.ldif")
+ .build();
+
+ @Test
+ void testLdapConnection() throws Exception {
+ final LDAPInterface ldapConnection = embeddedLdapExtension.ldapConnection();
+ final SearchResult searchResult = ldapConnection.search(DOMAIN_DSN, SearchScope.SUB, "(objectClass=person)");
+ assertEquals(1, searchResult.getEntryCount());
+ }
+
+ @Test
+ void testRawLdapConnection() throws Exception {
+ final String commonName = "Test person";
+ final String dn = String.format(
+ "cn=%s,ou=people,dc=zapodot,dc=org",
+ commonName);
+ LDAPConnection ldapConnection = embeddedLdapExtension.unsharedLdapConnection();
+ try {
+ ldapConnection.add(new AddRequest(dn, Arrays.asList(
+ new Attribute("objectclass", "top", "person", "organizationalPerson", "inetOrgPerson"),
+ new Attribute("cn", commonName), new Attribute("sn", "Person"), new Attribute("uid", "test"))));
+ } finally {
+ // Forces the LDAP connection to be closed. This is not necessary as the rule will usually close it for you.
+ ldapConnection.close();
+ }
+ ldapConnection = embeddedLdapExtension.unsharedLdapConnection();
+ final SearchResultEntry entry = ldapConnection.searchForEntry(new SearchRequest(dn,
+ SearchScope.BASE,
+ "(objectClass=person)"));
+ assertNotNull(entry);
+ }
+
+ @Test
+ void testDirContext() throws Exception {
+ final DirContext dirContext = embeddedLdapExtension.dirContext();
+ final SearchControls searchControls = new SearchControls();
+ searchControls.setSearchScope(SearchControls.SUBTREE_SCOPE);
+ final NamingEnumeration resultNamingEnumeration =
+ dirContext.search(DOMAIN_DSN, "(objectClass=person)", searchControls);
+ assertEquals(1, Iterators.size(Iterators.forEnumeration(resultNamingEnumeration)));
+ }
+
+ @Test
+ void testContext() throws Exception {
+ final Context context = embeddedLdapExtension.context();
+ final Object user = context.lookup("cn=Sondre Eikanger Kvalo,ou=people,dc=zapodot,dc=org");
+ assertNotNull(user);
+ }
+
+ @Test
+ void testContextClose() throws Exception {
+ final Context context = embeddedLdapExtension.context();
+ context.close();
+ assertNotNull(context.getNameInNamespace());
+
+ }
+
+ @Test
+ void testEmbeddedServerPort() {
+ assertTrue(embeddedLdapExtension.embeddedServerPort() > 0);
+
+ }
+
+ @Test
+ void testNoPortAssignedYet() {
+ final EmbeddedLdapExtension embeddedLdapRule = new EmbeddedLdapExtensionBuilder().build();
+
+ assertThrows(IllegalStateException.class, embeddedLdapRule::embeddedServerPort);
+
+ }
+}
From cde99b652f7c2012fcd668564d8d33e8516efa47 Mon Sep 17 00:00:00 2001
From: Bastien Jansen
Date: Thu, 29 Oct 2020 10:32:02 +0100
Subject: [PATCH 2/5] Make Maven run JUnit 5 tests as well
---
pom.xml | 16 ++++++++++++++++
1 file changed, 16 insertions(+)
diff --git a/pom.xml b/pom.xml
index 1211eee..d72f06c 100644
--- a/pom.xml
+++ b/pom.xml
@@ -91,6 +91,18 @@
${bouncycastle.version}
test
+
+ org.junit.jupiter
+ junit-jupiter-engine
+ 5.7.0
+ test
+
+
+ org.junit.vintage
+ junit-vintage-engine
+ ${junit5.version}
+ test
+
@@ -196,6 +208,10 @@
${java.version}
+
+ maven-surefire-plugin
+ 2.22.2
+
From dceadfd17a9f90117d5d0dd01eed8870971b28a8 Mon Sep 17 00:00:00 2001
From: Bastien Jansen
Date: Thu, 29 Oct 2020 11:30:34 +0100
Subject: [PATCH 3/5] Split the JUnit 4 rule and JUnit 5 extension into
separate Maven modules
---
embedded-ldap-core/pom.xml | 37 +++
.../junit/ldap/EmbeddedLdapServer.java | 2 +-
.../internal/AbstractEmbeddedLdapBuilder.java | 4 +-
.../internal/AuthenticationConfiguration.java | 0
.../ldap/internal/EmbeddedLdapServerImpl.java | 2 +-
.../internal/jndi/ContextInterceptor.java | 0
.../ldap/internal/jndi/ContextProxy.java | 0
.../internal/jndi/ContextProxyFactory.java | 0
.../ldap/internal/jndi/DirContextProxy.java | 0
.../junit/ldap/internal/package-info.java | 0
.../unboundid/LDAPConnectionProxy.java | 0
.../unboundid/LDAPInterfaceProxyFactory.java | 0
.../org/zapodot/junit/ldap/package-info.java | 0
embedded-ldap-junit/pom.xml | 48 ++++
.../zapodot/junit/ldap/EmbeddedLdapRule.java | 0
.../junit/ldap/EmbeddedLdapRuleBuilder.java | 0
.../ldap/internal/EmbeddedLdapRuleImpl.java | 2 +-
.../ldap/EmbeddedLdapRuleBuilderTest.java | 0
.../ldap/EmbeddedLdapRuleClassRuleTest.java | 0
...dedLdapRuleCustomSchemaDuplicatedTest.java | 0
...RuleCustomStandardAndCustomSchemaTest.java | 0
...beddedLdapRuleCustomWithoutSchemaTest.java | 0
...apRuleCustomWithoutStandardSchemaTest.java | 0
.../ldap/EmbeddedLdapRuleMultipleDSNs.java | 0
.../ldap/EmbeddedLdapRuleNoAuthTest.java | 0
.../ldap/EmbeddedLdapRuleStandardContext.java | 0
.../ldap/EmbeddedLdapRuleStarttlsTest.java | 0
.../junit/ldap/EmbeddedLdapRuleTest.java | 0
...pRuleWithListeningAddressProvidedTest.java | 0
.../ldap/EmbeddedLdapRuleWithSpacesTest.java | 0
.../AuthenticationConfigurationTest.java | 0
.../jndi/ContextProxyFactoryTest.java | 0
.../LDAPInterfaceProxyFactoryTest.java | 0
.../src}/test/resources/custom-schema.ldif | 0
.../src}/test/resources/example.ldif | 0
.../resources/folder with space/example.ldif | 0
.../src}/test/resources/folder/.placeholder | 0
.../src}/test/resources/invalid.ldif | 0
.../src}/test/resources/standard-schema.ldif | 0
embedded-ldap-junit5/pom.xml | 35 +++
.../internal/EmbeddedLdapExtensionImpl.java | 0
.../ldap/junit5/EmbeddedLdapExtension.java | 0
.../junit5/EmbeddedLdapExtensionBuilder.java | 0
.../EmbeddedLdapExtensionBuilderTest.java | 99 ++++++++
.../EmbeddedLdapExtensionStaticTest.java | 0
.../junit5/EmbeddedLdapExtensionTest.java | 0
.../src/test/resources/example.ldif | 28 +++
pom.xml | 75 +-----
.../junit/ldap/EmbeddedLdapRuleTlsTest.java | 216 ------------------
.../EmbeddedLdapExtensionBuilderTest.java | 87 -------
50 files changed, 262 insertions(+), 373 deletions(-)
create mode 100644 embedded-ldap-core/pom.xml
rename {src => embedded-ldap-core/src}/main/java/org/zapodot/junit/ldap/EmbeddedLdapServer.java (95%)
rename {src => embedded-ldap-core/src}/main/java/org/zapodot/junit/ldap/internal/AbstractEmbeddedLdapBuilder.java (98%)
rename {src => embedded-ldap-core/src}/main/java/org/zapodot/junit/ldap/internal/AuthenticationConfiguration.java (100%)
mode change 100755 => 100644
rename {src => embedded-ldap-core/src}/main/java/org/zapodot/junit/ldap/internal/EmbeddedLdapServerImpl.java (99%)
rename {src => embedded-ldap-core/src}/main/java/org/zapodot/junit/ldap/internal/jndi/ContextInterceptor.java (100%)
mode change 100755 => 100644
rename {src => embedded-ldap-core/src}/main/java/org/zapodot/junit/ldap/internal/jndi/ContextProxy.java (100%)
mode change 100755 => 100644
rename {src => embedded-ldap-core/src}/main/java/org/zapodot/junit/ldap/internal/jndi/ContextProxyFactory.java (100%)
mode change 100755 => 100644
rename {src => embedded-ldap-core/src}/main/java/org/zapodot/junit/ldap/internal/jndi/DirContextProxy.java (100%)
mode change 100755 => 100644
rename {src => embedded-ldap-core/src}/main/java/org/zapodot/junit/ldap/internal/package-info.java (100%)
mode change 100755 => 100644
rename {src => embedded-ldap-core/src}/main/java/org/zapodot/junit/ldap/internal/unboundid/LDAPConnectionProxy.java (100%)
mode change 100755 => 100644
rename {src => embedded-ldap-core/src}/main/java/org/zapodot/junit/ldap/internal/unboundid/LDAPInterfaceProxyFactory.java (100%)
mode change 100755 => 100644
rename {src => embedded-ldap-core/src}/main/java/org/zapodot/junit/ldap/package-info.java (100%)
mode change 100755 => 100644
create mode 100644 embedded-ldap-junit/pom.xml
rename {src => embedded-ldap-junit/src}/main/java/org/zapodot/junit/ldap/EmbeddedLdapRule.java (100%)
mode change 100755 => 100644
rename {src => embedded-ldap-junit/src}/main/java/org/zapodot/junit/ldap/EmbeddedLdapRuleBuilder.java (100%)
mode change 100755 => 100644
rename {src => embedded-ldap-junit/src}/main/java/org/zapodot/junit/ldap/internal/EmbeddedLdapRuleImpl.java (93%)
mode change 100755 => 100644
rename {src => embedded-ldap-junit/src}/test/java/org/zapodot/junit/ldap/EmbeddedLdapRuleBuilderTest.java (100%)
mode change 100755 => 100644
rename {src => embedded-ldap-junit/src}/test/java/org/zapodot/junit/ldap/EmbeddedLdapRuleClassRuleTest.java (100%)
mode change 100755 => 100644
rename {src => embedded-ldap-junit/src}/test/java/org/zapodot/junit/ldap/EmbeddedLdapRuleCustomSchemaDuplicatedTest.java (100%)
mode change 100755 => 100644
rename {src => embedded-ldap-junit/src}/test/java/org/zapodot/junit/ldap/EmbeddedLdapRuleCustomStandardAndCustomSchemaTest.java (100%)
mode change 100755 => 100644
rename {src => embedded-ldap-junit/src}/test/java/org/zapodot/junit/ldap/EmbeddedLdapRuleCustomWithoutSchemaTest.java (100%)
mode change 100755 => 100644
rename {src => embedded-ldap-junit/src}/test/java/org/zapodot/junit/ldap/EmbeddedLdapRuleCustomWithoutStandardSchemaTest.java (100%)
mode change 100755 => 100644
rename {src => embedded-ldap-junit/src}/test/java/org/zapodot/junit/ldap/EmbeddedLdapRuleMultipleDSNs.java (100%)
mode change 100755 => 100644
rename {src => embedded-ldap-junit/src}/test/java/org/zapodot/junit/ldap/EmbeddedLdapRuleNoAuthTest.java (100%)
mode change 100755 => 100644
rename {src => embedded-ldap-junit/src}/test/java/org/zapodot/junit/ldap/EmbeddedLdapRuleStandardContext.java (100%)
mode change 100755 => 100644
rename {src => embedded-ldap-junit/src}/test/java/org/zapodot/junit/ldap/EmbeddedLdapRuleStarttlsTest.java (100%)
mode change 100755 => 100644
rename {src => embedded-ldap-junit/src}/test/java/org/zapodot/junit/ldap/EmbeddedLdapRuleTest.java (100%)
mode change 100755 => 100644
rename {src => embedded-ldap-junit/src}/test/java/org/zapodot/junit/ldap/EmbeddedLdapRuleWithListeningAddressProvidedTest.java (100%)
mode change 100755 => 100644
rename {src => embedded-ldap-junit/src}/test/java/org/zapodot/junit/ldap/EmbeddedLdapRuleWithSpacesTest.java (100%)
mode change 100755 => 100644
rename {src => embedded-ldap-junit/src}/test/java/org/zapodot/junit/ldap/internal/AuthenticationConfigurationTest.java (100%)
mode change 100755 => 100644
rename {src => embedded-ldap-junit/src}/test/java/org/zapodot/junit/ldap/internal/jndi/ContextProxyFactoryTest.java (100%)
rename {src => embedded-ldap-junit/src}/test/java/org/zapodot/junit/ldap/internal/unboundid/LDAPInterfaceProxyFactoryTest.java (100%)
rename {src => embedded-ldap-junit/src}/test/resources/custom-schema.ldif (100%)
mode change 100755 => 100644
rename {src => embedded-ldap-junit/src}/test/resources/example.ldif (100%)
mode change 100755 => 100644
rename {src => embedded-ldap-junit/src}/test/resources/folder with space/example.ldif (100%)
mode change 100755 => 100644
rename {src => embedded-ldap-junit/src}/test/resources/folder/.placeholder (100%)
mode change 100755 => 100644
rename {src => embedded-ldap-junit/src}/test/resources/invalid.ldif (100%)
mode change 100755 => 100644
rename {src => embedded-ldap-junit/src}/test/resources/standard-schema.ldif (100%)
mode change 100755 => 100644
create mode 100644 embedded-ldap-junit5/pom.xml
rename {src => embedded-ldap-junit5/src}/main/java/org/zapodot/junit/ldap/internal/EmbeddedLdapExtensionImpl.java (100%)
rename {src => embedded-ldap-junit5/src}/main/java/org/zapodot/junit/ldap/junit5/EmbeddedLdapExtension.java (100%)
rename {src => embedded-ldap-junit5/src}/main/java/org/zapodot/junit/ldap/junit5/EmbeddedLdapExtensionBuilder.java (100%)
create mode 100644 embedded-ldap-junit5/src/test/java/org/zapodot/junit/ldap/junit5/EmbeddedLdapExtensionBuilderTest.java
rename {src => embedded-ldap-junit5/src}/test/java/org/zapodot/junit/ldap/junit5/EmbeddedLdapExtensionStaticTest.java (100%)
rename {src => embedded-ldap-junit5/src}/test/java/org/zapodot/junit/ldap/junit5/EmbeddedLdapExtensionTest.java (100%)
create mode 100644 embedded-ldap-junit5/src/test/resources/example.ldif
delete mode 100755 src/test/java/org/zapodot/junit/ldap/EmbeddedLdapRuleTlsTest.java
delete mode 100644 src/test/java/org/zapodot/junit/ldap/junit5/EmbeddedLdapExtensionBuilderTest.java
diff --git a/embedded-ldap-core/pom.xml b/embedded-ldap-core/pom.xml
new file mode 100644
index 0000000..60a0918
--- /dev/null
+++ b/embedded-ldap-core/pom.xml
@@ -0,0 +1,37 @@
+
+
+ 4.0.0
+
+
+ embedded-ldap-parent
+ org.zapodot
+ 0.9-SNAPSHOT
+
+
+ embedded-ldap-core
+
+
+
+ com.unboundid
+ unboundid-ldapsdk
+ ${unboundid-ldapsdk.version}
+
+
+ com.google.guava
+ guava
+ ${guava.version}
+
+
+ net.bytebuddy
+ byte-buddy
+ ${byte-buddy.version}
+
+
+ org.slf4j
+ slf4j-api
+ ${slf4j.version}
+
+
+
diff --git a/src/main/java/org/zapodot/junit/ldap/EmbeddedLdapServer.java b/embedded-ldap-core/src/main/java/org/zapodot/junit/ldap/EmbeddedLdapServer.java
similarity index 95%
rename from src/main/java/org/zapodot/junit/ldap/EmbeddedLdapServer.java
rename to embedded-ldap-core/src/main/java/org/zapodot/junit/ldap/EmbeddedLdapServer.java
index 45191d9..b73a258 100644
--- a/src/main/java/org/zapodot/junit/ldap/EmbeddedLdapServer.java
+++ b/embedded-ldap-core/src/main/java/org/zapodot/junit/ldap/EmbeddedLdapServer.java
@@ -53,7 +53,7 @@ public interface EmbeddedLdapServer {
*
*
* @return the port number that the embedded server is listening to
- * @see org.zapodot.junit.ldap.EmbeddedLdapRuleBuilder#bindingToAddress(String)
+ * @see org.zapodot.junit.ldap.internal.AbstractEmbeddedLdapBuilder#bindingToAddress(String)
*/
int embeddedServerPort();
diff --git a/src/main/java/org/zapodot/junit/ldap/internal/AbstractEmbeddedLdapBuilder.java b/embedded-ldap-core/src/main/java/org/zapodot/junit/ldap/internal/AbstractEmbeddedLdapBuilder.java
similarity index 98%
rename from src/main/java/org/zapodot/junit/ldap/internal/AbstractEmbeddedLdapBuilder.java
rename to embedded-ldap-core/src/main/java/org/zapodot/junit/ldap/internal/AbstractEmbeddedLdapBuilder.java
index e5326ea..5e03337 100644
--- a/src/main/java/org/zapodot/junit/ldap/internal/AbstractEmbeddedLdapBuilder.java
+++ b/embedded-ldap-core/src/main/java/org/zapodot/junit/ldap/internal/AbstractEmbeddedLdapBuilder.java
@@ -20,8 +20,8 @@
import java.util.Objects;
/**
- * A builder providing a fluent way of defining {@link org.zapodot.junit.ldap.EmbeddedLdapRule}
- * or {@link org.zapodot.junit.ldap.junit5.EmbeddedLdapExtension} instances.
+ * A builder providing a fluent way of defining EmbeddedLdapRule
+ * or EmbeddedLdapExtension instances.
*/
public abstract class AbstractEmbeddedLdapBuilder> {
diff --git a/src/main/java/org/zapodot/junit/ldap/internal/AuthenticationConfiguration.java b/embedded-ldap-core/src/main/java/org/zapodot/junit/ldap/internal/AuthenticationConfiguration.java
old mode 100755
new mode 100644
similarity index 100%
rename from src/main/java/org/zapodot/junit/ldap/internal/AuthenticationConfiguration.java
rename to embedded-ldap-core/src/main/java/org/zapodot/junit/ldap/internal/AuthenticationConfiguration.java
diff --git a/src/main/java/org/zapodot/junit/ldap/internal/EmbeddedLdapServerImpl.java b/embedded-ldap-core/src/main/java/org/zapodot/junit/ldap/internal/EmbeddedLdapServerImpl.java
similarity index 99%
rename from src/main/java/org/zapodot/junit/ldap/internal/EmbeddedLdapServerImpl.java
rename to embedded-ldap-core/src/main/java/org/zapodot/junit/ldap/internal/EmbeddedLdapServerImpl.java
index 161ee12..b848614 100644
--- a/src/main/java/org/zapodot/junit/ldap/internal/EmbeddedLdapServerImpl.java
+++ b/embedded-ldap-core/src/main/java/org/zapodot/junit/ldap/internal/EmbeddedLdapServerImpl.java
@@ -28,7 +28,7 @@ abstract class EmbeddedLdapServerImpl implements EmbeddedLdapServer {
private static final String JAVA_RT_CONTEXT_FACTORY = "com.sun.jndi.ldap.LdapCtxFactory";
- private static Logger logger = LoggerFactory.getLogger(EmbeddedLdapExtensionImpl.class);
+ private static Logger logger = LoggerFactory.getLogger(EmbeddedLdapServerImpl.class);
private final InMemoryDirectoryServer inMemoryDirectoryServer;
private final AuthenticationConfiguration authenticationConfiguration;
private LDAPConnection ldapConnection;
diff --git a/src/main/java/org/zapodot/junit/ldap/internal/jndi/ContextInterceptor.java b/embedded-ldap-core/src/main/java/org/zapodot/junit/ldap/internal/jndi/ContextInterceptor.java
old mode 100755
new mode 100644
similarity index 100%
rename from src/main/java/org/zapodot/junit/ldap/internal/jndi/ContextInterceptor.java
rename to embedded-ldap-core/src/main/java/org/zapodot/junit/ldap/internal/jndi/ContextInterceptor.java
diff --git a/src/main/java/org/zapodot/junit/ldap/internal/jndi/ContextProxy.java b/embedded-ldap-core/src/main/java/org/zapodot/junit/ldap/internal/jndi/ContextProxy.java
old mode 100755
new mode 100644
similarity index 100%
rename from src/main/java/org/zapodot/junit/ldap/internal/jndi/ContextProxy.java
rename to embedded-ldap-core/src/main/java/org/zapodot/junit/ldap/internal/jndi/ContextProxy.java
diff --git a/src/main/java/org/zapodot/junit/ldap/internal/jndi/ContextProxyFactory.java b/embedded-ldap-core/src/main/java/org/zapodot/junit/ldap/internal/jndi/ContextProxyFactory.java
old mode 100755
new mode 100644
similarity index 100%
rename from src/main/java/org/zapodot/junit/ldap/internal/jndi/ContextProxyFactory.java
rename to embedded-ldap-core/src/main/java/org/zapodot/junit/ldap/internal/jndi/ContextProxyFactory.java
diff --git a/src/main/java/org/zapodot/junit/ldap/internal/jndi/DirContextProxy.java b/embedded-ldap-core/src/main/java/org/zapodot/junit/ldap/internal/jndi/DirContextProxy.java
old mode 100755
new mode 100644
similarity index 100%
rename from src/main/java/org/zapodot/junit/ldap/internal/jndi/DirContextProxy.java
rename to embedded-ldap-core/src/main/java/org/zapodot/junit/ldap/internal/jndi/DirContextProxy.java
diff --git a/src/main/java/org/zapodot/junit/ldap/internal/package-info.java b/embedded-ldap-core/src/main/java/org/zapodot/junit/ldap/internal/package-info.java
old mode 100755
new mode 100644
similarity index 100%
rename from src/main/java/org/zapodot/junit/ldap/internal/package-info.java
rename to embedded-ldap-core/src/main/java/org/zapodot/junit/ldap/internal/package-info.java
diff --git a/src/main/java/org/zapodot/junit/ldap/internal/unboundid/LDAPConnectionProxy.java b/embedded-ldap-core/src/main/java/org/zapodot/junit/ldap/internal/unboundid/LDAPConnectionProxy.java
old mode 100755
new mode 100644
similarity index 100%
rename from src/main/java/org/zapodot/junit/ldap/internal/unboundid/LDAPConnectionProxy.java
rename to embedded-ldap-core/src/main/java/org/zapodot/junit/ldap/internal/unboundid/LDAPConnectionProxy.java
diff --git a/src/main/java/org/zapodot/junit/ldap/internal/unboundid/LDAPInterfaceProxyFactory.java b/embedded-ldap-core/src/main/java/org/zapodot/junit/ldap/internal/unboundid/LDAPInterfaceProxyFactory.java
old mode 100755
new mode 100644
similarity index 100%
rename from src/main/java/org/zapodot/junit/ldap/internal/unboundid/LDAPInterfaceProxyFactory.java
rename to embedded-ldap-core/src/main/java/org/zapodot/junit/ldap/internal/unboundid/LDAPInterfaceProxyFactory.java
diff --git a/src/main/java/org/zapodot/junit/ldap/package-info.java b/embedded-ldap-core/src/main/java/org/zapodot/junit/ldap/package-info.java
old mode 100755
new mode 100644
similarity index 100%
rename from src/main/java/org/zapodot/junit/ldap/package-info.java
rename to embedded-ldap-core/src/main/java/org/zapodot/junit/ldap/package-info.java
diff --git a/embedded-ldap-junit/pom.xml b/embedded-ldap-junit/pom.xml
new file mode 100644
index 0000000..16ac926
--- /dev/null
+++ b/embedded-ldap-junit/pom.xml
@@ -0,0 +1,48 @@
+
+
+ 4.0.0
+
+
+ embedded-ldap-parent
+ org.zapodot
+ 0.9-SNAPSHOT
+
+
+ embedded-ldap-junit
+
+
+
+ org.zapodot
+ embedded-ldap-core
+ ${project.version}
+
+
+
+ junit
+ junit
+ ${junit.version}
+
+
+
+
+ ch.qos.logback
+ logback-classic
+ ${logback.version}
+ test
+
+
+ org.bouncycastle
+ bcprov-jdk15on
+ ${bouncycastle.version}
+ test
+
+
+ org.bouncycastle
+ bcpkix-jdk15on
+ ${bouncycastle.version}
+ test
+
+
+
diff --git a/src/main/java/org/zapodot/junit/ldap/EmbeddedLdapRule.java b/embedded-ldap-junit/src/main/java/org/zapodot/junit/ldap/EmbeddedLdapRule.java
old mode 100755
new mode 100644
similarity index 100%
rename from src/main/java/org/zapodot/junit/ldap/EmbeddedLdapRule.java
rename to embedded-ldap-junit/src/main/java/org/zapodot/junit/ldap/EmbeddedLdapRule.java
diff --git a/src/main/java/org/zapodot/junit/ldap/EmbeddedLdapRuleBuilder.java b/embedded-ldap-junit/src/main/java/org/zapodot/junit/ldap/EmbeddedLdapRuleBuilder.java
old mode 100755
new mode 100644
similarity index 100%
rename from src/main/java/org/zapodot/junit/ldap/EmbeddedLdapRuleBuilder.java
rename to embedded-ldap-junit/src/main/java/org/zapodot/junit/ldap/EmbeddedLdapRuleBuilder.java
diff --git a/src/main/java/org/zapodot/junit/ldap/internal/EmbeddedLdapRuleImpl.java b/embedded-ldap-junit/src/main/java/org/zapodot/junit/ldap/internal/EmbeddedLdapRuleImpl.java
old mode 100755
new mode 100644
similarity index 93%
rename from src/main/java/org/zapodot/junit/ldap/internal/EmbeddedLdapRuleImpl.java
rename to embedded-ldap-junit/src/main/java/org/zapodot/junit/ldap/internal/EmbeddedLdapRuleImpl.java
index 9f33d28..e55bd7f
--- a/src/main/java/org/zapodot/junit/ldap/internal/EmbeddedLdapRuleImpl.java
+++ b/embedded-ldap-junit/src/main/java/org/zapodot/junit/ldap/internal/EmbeddedLdapRuleImpl.java
@@ -15,7 +15,7 @@ public static EmbeddedLdapRule createForConfiguration(final InMemoryDirectorySer
final AuthenticationConfiguration authenticationConfiguration,
final List ldifs) {
try {
- return new EmbeddedLdapRuleImpl(createServer(inMemoryDirectoryServerConfig, ldifs),
+ return new EmbeddedLdapRuleImpl(EmbeddedLdapServerImpl.createServer(inMemoryDirectoryServerConfig, ldifs),
authenticationConfiguration);
} catch (LDAPException e) {
throw new IllegalStateException("Can not initiate in-memory LDAP server due to an exception", e);
diff --git a/src/test/java/org/zapodot/junit/ldap/EmbeddedLdapRuleBuilderTest.java b/embedded-ldap-junit/src/test/java/org/zapodot/junit/ldap/EmbeddedLdapRuleBuilderTest.java
old mode 100755
new mode 100644
similarity index 100%
rename from src/test/java/org/zapodot/junit/ldap/EmbeddedLdapRuleBuilderTest.java
rename to embedded-ldap-junit/src/test/java/org/zapodot/junit/ldap/EmbeddedLdapRuleBuilderTest.java
diff --git a/src/test/java/org/zapodot/junit/ldap/EmbeddedLdapRuleClassRuleTest.java b/embedded-ldap-junit/src/test/java/org/zapodot/junit/ldap/EmbeddedLdapRuleClassRuleTest.java
old mode 100755
new mode 100644
similarity index 100%
rename from src/test/java/org/zapodot/junit/ldap/EmbeddedLdapRuleClassRuleTest.java
rename to embedded-ldap-junit/src/test/java/org/zapodot/junit/ldap/EmbeddedLdapRuleClassRuleTest.java
diff --git a/src/test/java/org/zapodot/junit/ldap/EmbeddedLdapRuleCustomSchemaDuplicatedTest.java b/embedded-ldap-junit/src/test/java/org/zapodot/junit/ldap/EmbeddedLdapRuleCustomSchemaDuplicatedTest.java
old mode 100755
new mode 100644
similarity index 100%
rename from src/test/java/org/zapodot/junit/ldap/EmbeddedLdapRuleCustomSchemaDuplicatedTest.java
rename to embedded-ldap-junit/src/test/java/org/zapodot/junit/ldap/EmbeddedLdapRuleCustomSchemaDuplicatedTest.java
diff --git a/src/test/java/org/zapodot/junit/ldap/EmbeddedLdapRuleCustomStandardAndCustomSchemaTest.java b/embedded-ldap-junit/src/test/java/org/zapodot/junit/ldap/EmbeddedLdapRuleCustomStandardAndCustomSchemaTest.java
old mode 100755
new mode 100644
similarity index 100%
rename from src/test/java/org/zapodot/junit/ldap/EmbeddedLdapRuleCustomStandardAndCustomSchemaTest.java
rename to embedded-ldap-junit/src/test/java/org/zapodot/junit/ldap/EmbeddedLdapRuleCustomStandardAndCustomSchemaTest.java
diff --git a/src/test/java/org/zapodot/junit/ldap/EmbeddedLdapRuleCustomWithoutSchemaTest.java b/embedded-ldap-junit/src/test/java/org/zapodot/junit/ldap/EmbeddedLdapRuleCustomWithoutSchemaTest.java
old mode 100755
new mode 100644
similarity index 100%
rename from src/test/java/org/zapodot/junit/ldap/EmbeddedLdapRuleCustomWithoutSchemaTest.java
rename to embedded-ldap-junit/src/test/java/org/zapodot/junit/ldap/EmbeddedLdapRuleCustomWithoutSchemaTest.java
diff --git a/src/test/java/org/zapodot/junit/ldap/EmbeddedLdapRuleCustomWithoutStandardSchemaTest.java b/embedded-ldap-junit/src/test/java/org/zapodot/junit/ldap/EmbeddedLdapRuleCustomWithoutStandardSchemaTest.java
old mode 100755
new mode 100644
similarity index 100%
rename from src/test/java/org/zapodot/junit/ldap/EmbeddedLdapRuleCustomWithoutStandardSchemaTest.java
rename to embedded-ldap-junit/src/test/java/org/zapodot/junit/ldap/EmbeddedLdapRuleCustomWithoutStandardSchemaTest.java
diff --git a/src/test/java/org/zapodot/junit/ldap/EmbeddedLdapRuleMultipleDSNs.java b/embedded-ldap-junit/src/test/java/org/zapodot/junit/ldap/EmbeddedLdapRuleMultipleDSNs.java
old mode 100755
new mode 100644
similarity index 100%
rename from src/test/java/org/zapodot/junit/ldap/EmbeddedLdapRuleMultipleDSNs.java
rename to embedded-ldap-junit/src/test/java/org/zapodot/junit/ldap/EmbeddedLdapRuleMultipleDSNs.java
diff --git a/src/test/java/org/zapodot/junit/ldap/EmbeddedLdapRuleNoAuthTest.java b/embedded-ldap-junit/src/test/java/org/zapodot/junit/ldap/EmbeddedLdapRuleNoAuthTest.java
old mode 100755
new mode 100644
similarity index 100%
rename from src/test/java/org/zapodot/junit/ldap/EmbeddedLdapRuleNoAuthTest.java
rename to embedded-ldap-junit/src/test/java/org/zapodot/junit/ldap/EmbeddedLdapRuleNoAuthTest.java
diff --git a/src/test/java/org/zapodot/junit/ldap/EmbeddedLdapRuleStandardContext.java b/embedded-ldap-junit/src/test/java/org/zapodot/junit/ldap/EmbeddedLdapRuleStandardContext.java
old mode 100755
new mode 100644
similarity index 100%
rename from src/test/java/org/zapodot/junit/ldap/EmbeddedLdapRuleStandardContext.java
rename to embedded-ldap-junit/src/test/java/org/zapodot/junit/ldap/EmbeddedLdapRuleStandardContext.java
diff --git a/src/test/java/org/zapodot/junit/ldap/EmbeddedLdapRuleStarttlsTest.java b/embedded-ldap-junit/src/test/java/org/zapodot/junit/ldap/EmbeddedLdapRuleStarttlsTest.java
old mode 100755
new mode 100644
similarity index 100%
rename from src/test/java/org/zapodot/junit/ldap/EmbeddedLdapRuleStarttlsTest.java
rename to embedded-ldap-junit/src/test/java/org/zapodot/junit/ldap/EmbeddedLdapRuleStarttlsTest.java
diff --git a/src/test/java/org/zapodot/junit/ldap/EmbeddedLdapRuleTest.java b/embedded-ldap-junit/src/test/java/org/zapodot/junit/ldap/EmbeddedLdapRuleTest.java
old mode 100755
new mode 100644
similarity index 100%
rename from src/test/java/org/zapodot/junit/ldap/EmbeddedLdapRuleTest.java
rename to embedded-ldap-junit/src/test/java/org/zapodot/junit/ldap/EmbeddedLdapRuleTest.java
diff --git a/src/test/java/org/zapodot/junit/ldap/EmbeddedLdapRuleWithListeningAddressProvidedTest.java b/embedded-ldap-junit/src/test/java/org/zapodot/junit/ldap/EmbeddedLdapRuleWithListeningAddressProvidedTest.java
old mode 100755
new mode 100644
similarity index 100%
rename from src/test/java/org/zapodot/junit/ldap/EmbeddedLdapRuleWithListeningAddressProvidedTest.java
rename to embedded-ldap-junit/src/test/java/org/zapodot/junit/ldap/EmbeddedLdapRuleWithListeningAddressProvidedTest.java
diff --git a/src/test/java/org/zapodot/junit/ldap/EmbeddedLdapRuleWithSpacesTest.java b/embedded-ldap-junit/src/test/java/org/zapodot/junit/ldap/EmbeddedLdapRuleWithSpacesTest.java
old mode 100755
new mode 100644
similarity index 100%
rename from src/test/java/org/zapodot/junit/ldap/EmbeddedLdapRuleWithSpacesTest.java
rename to embedded-ldap-junit/src/test/java/org/zapodot/junit/ldap/EmbeddedLdapRuleWithSpacesTest.java
diff --git a/src/test/java/org/zapodot/junit/ldap/internal/AuthenticationConfigurationTest.java b/embedded-ldap-junit/src/test/java/org/zapodot/junit/ldap/internal/AuthenticationConfigurationTest.java
old mode 100755
new mode 100644
similarity index 100%
rename from src/test/java/org/zapodot/junit/ldap/internal/AuthenticationConfigurationTest.java
rename to embedded-ldap-junit/src/test/java/org/zapodot/junit/ldap/internal/AuthenticationConfigurationTest.java
diff --git a/src/test/java/org/zapodot/junit/ldap/internal/jndi/ContextProxyFactoryTest.java b/embedded-ldap-junit/src/test/java/org/zapodot/junit/ldap/internal/jndi/ContextProxyFactoryTest.java
similarity index 100%
rename from src/test/java/org/zapodot/junit/ldap/internal/jndi/ContextProxyFactoryTest.java
rename to embedded-ldap-junit/src/test/java/org/zapodot/junit/ldap/internal/jndi/ContextProxyFactoryTest.java
diff --git a/src/test/java/org/zapodot/junit/ldap/internal/unboundid/LDAPInterfaceProxyFactoryTest.java b/embedded-ldap-junit/src/test/java/org/zapodot/junit/ldap/internal/unboundid/LDAPInterfaceProxyFactoryTest.java
similarity index 100%
rename from src/test/java/org/zapodot/junit/ldap/internal/unboundid/LDAPInterfaceProxyFactoryTest.java
rename to embedded-ldap-junit/src/test/java/org/zapodot/junit/ldap/internal/unboundid/LDAPInterfaceProxyFactoryTest.java
diff --git a/src/test/resources/custom-schema.ldif b/embedded-ldap-junit/src/test/resources/custom-schema.ldif
old mode 100755
new mode 100644
similarity index 100%
rename from src/test/resources/custom-schema.ldif
rename to embedded-ldap-junit/src/test/resources/custom-schema.ldif
diff --git a/src/test/resources/example.ldif b/embedded-ldap-junit/src/test/resources/example.ldif
old mode 100755
new mode 100644
similarity index 100%
rename from src/test/resources/example.ldif
rename to embedded-ldap-junit/src/test/resources/example.ldif
diff --git a/src/test/resources/folder with space/example.ldif b/embedded-ldap-junit/src/test/resources/folder with space/example.ldif
old mode 100755
new mode 100644
similarity index 100%
rename from src/test/resources/folder with space/example.ldif
rename to embedded-ldap-junit/src/test/resources/folder with space/example.ldif
diff --git a/src/test/resources/folder/.placeholder b/embedded-ldap-junit/src/test/resources/folder/.placeholder
old mode 100755
new mode 100644
similarity index 100%
rename from src/test/resources/folder/.placeholder
rename to embedded-ldap-junit/src/test/resources/folder/.placeholder
diff --git a/src/test/resources/invalid.ldif b/embedded-ldap-junit/src/test/resources/invalid.ldif
old mode 100755
new mode 100644
similarity index 100%
rename from src/test/resources/invalid.ldif
rename to embedded-ldap-junit/src/test/resources/invalid.ldif
diff --git a/src/test/resources/standard-schema.ldif b/embedded-ldap-junit/src/test/resources/standard-schema.ldif
old mode 100755
new mode 100644
similarity index 100%
rename from src/test/resources/standard-schema.ldif
rename to embedded-ldap-junit/src/test/resources/standard-schema.ldif
diff --git a/embedded-ldap-junit5/pom.xml b/embedded-ldap-junit5/pom.xml
new file mode 100644
index 0000000..b366ad8
--- /dev/null
+++ b/embedded-ldap-junit5/pom.xml
@@ -0,0 +1,35 @@
+
+
+
+ embedded-ldap-parent
+ org.zapodot
+ 0.9-SNAPSHOT
+
+ 4.0.0
+
+ embedded-ldap-junit5
+
+
+
+ org.zapodot
+ embedded-ldap-core
+ ${project.version}
+
+
+
+ org.junit.jupiter
+ junit-jupiter-api
+ ${junit5.version}
+
+
+
+
+ org.junit.jupiter
+ junit-jupiter-engine
+ ${junit5.version}
+ test
+
+
+
diff --git a/src/main/java/org/zapodot/junit/ldap/internal/EmbeddedLdapExtensionImpl.java b/embedded-ldap-junit5/src/main/java/org/zapodot/junit/ldap/internal/EmbeddedLdapExtensionImpl.java
similarity index 100%
rename from src/main/java/org/zapodot/junit/ldap/internal/EmbeddedLdapExtensionImpl.java
rename to embedded-ldap-junit5/src/main/java/org/zapodot/junit/ldap/internal/EmbeddedLdapExtensionImpl.java
diff --git a/src/main/java/org/zapodot/junit/ldap/junit5/EmbeddedLdapExtension.java b/embedded-ldap-junit5/src/main/java/org/zapodot/junit/ldap/junit5/EmbeddedLdapExtension.java
similarity index 100%
rename from src/main/java/org/zapodot/junit/ldap/junit5/EmbeddedLdapExtension.java
rename to embedded-ldap-junit5/src/main/java/org/zapodot/junit/ldap/junit5/EmbeddedLdapExtension.java
diff --git a/src/main/java/org/zapodot/junit/ldap/junit5/EmbeddedLdapExtensionBuilder.java b/embedded-ldap-junit5/src/main/java/org/zapodot/junit/ldap/junit5/EmbeddedLdapExtensionBuilder.java
similarity index 100%
rename from src/main/java/org/zapodot/junit/ldap/junit5/EmbeddedLdapExtensionBuilder.java
rename to embedded-ldap-junit5/src/main/java/org/zapodot/junit/ldap/junit5/EmbeddedLdapExtensionBuilder.java
diff --git a/embedded-ldap-junit5/src/test/java/org/zapodot/junit/ldap/junit5/EmbeddedLdapExtensionBuilderTest.java b/embedded-ldap-junit5/src/test/java/org/zapodot/junit/ldap/junit5/EmbeddedLdapExtensionBuilderTest.java
new file mode 100644
index 0000000..bb8c546
--- /dev/null
+++ b/embedded-ldap-junit5/src/test/java/org/zapodot/junit/ldap/junit5/EmbeddedLdapExtensionBuilderTest.java
@@ -0,0 +1,99 @@
+package org.zapodot.junit.ldap.junit5;
+
+import org.junit.jupiter.api.Test;
+
+import static org.junit.jupiter.api.Assertions.assertNotNull;
+import static org.junit.jupiter.api.Assertions.assertThrows;
+
+class EmbeddedLdapExtensionBuilderTest {
+
+ @Test
+ void bindingToLegalPort() {
+ assertNotNull(EmbeddedLdapExtensionBuilder.newInstance().bindingToPort(9999));
+ }
+
+ @Test
+ void testPrematureLdapConnection() {
+ assertThrows(IllegalStateException.class, () ->
+ EmbeddedLdapExtensionBuilder.newInstance().build().ldapConnection()
+ );
+ }
+
+ @Test
+ void testPrematureContext() {
+ assertThrows(IllegalStateException.class, () ->
+ EmbeddedLdapExtensionBuilder.newInstance().build().context()
+ );
+ }
+
+ @Test
+ void testUnknownLDIF() {
+ assertThrows(IllegalArgumentException.class, () ->
+ EmbeddedLdapExtensionBuilder.newInstance().importingLdifs("nonExisting.ldif").build()
+ );
+ }
+
+ @Test
+ void testNullLDIF() {
+ assertNotNull(EmbeddedLdapExtensionBuilder.newInstance().importingLdifs(null).build());
+
+ }
+
+ @Test
+ void testIllegalDSN() {
+ assertThrows(IllegalStateException.class, () ->
+ EmbeddedLdapExtensionBuilder.newInstance().usingBindDSN("bindDsn").build()
+ );
+ }
+
+ @Test
+ void testIllegalPort() {
+ assertThrows(IllegalArgumentException.class, () ->
+ EmbeddedLdapExtensionBuilder.newInstance().bindingToPort(Integer.MIN_VALUE).build()
+ );
+ }
+
+ @Test
+ void testSchemaNotFound() {
+ assertThrows(IllegalArgumentException.class, () ->
+ EmbeddedLdapExtensionBuilder.newInstance().withSchema("non-existing-schema.ldif").build()
+ );
+ }
+
+ @Test
+ void testSchemaIsNotAFile() {
+ assertThrows(IllegalArgumentException.class, () ->
+ EmbeddedLdapExtensionBuilder.newInstance().withSchema("folder").build()
+ );
+ }
+
+ @Test
+ void testSchemaIsInvalid() {
+ assertThrows(IllegalArgumentException.class, () ->
+ EmbeddedLdapExtensionBuilder.newInstance().withSchema("invalid.ldif").build()
+ );
+ }
+
+ @Test
+ void testSchemaFileUnsupportedIsInvalid() {
+ assertThrows(IllegalArgumentException.class, () ->
+ EmbeddedLdapExtensionBuilder.newInstance().withSchema("\"#%¤&&%/¤##¤¤").build()
+ );
+ }
+
+ @Test
+ void testInvalidPort() {
+ assertThrows(IllegalArgumentException.class, () ->
+ EmbeddedLdapExtensionBuilder.newInstance().bindingToPort(Integer.MAX_VALUE)
+ );
+ }
+
+ @Test
+ void testInvalidBindAddress() {
+ assertThrows(IllegalArgumentException.class, () ->
+ EmbeddedLdapExtensionBuilder.newInstance().bindingToAddress("åpsldfåpl")
+ );
+ }
+
+
+}
diff --git a/src/test/java/org/zapodot/junit/ldap/junit5/EmbeddedLdapExtensionStaticTest.java b/embedded-ldap-junit5/src/test/java/org/zapodot/junit/ldap/junit5/EmbeddedLdapExtensionStaticTest.java
similarity index 100%
rename from src/test/java/org/zapodot/junit/ldap/junit5/EmbeddedLdapExtensionStaticTest.java
rename to embedded-ldap-junit5/src/test/java/org/zapodot/junit/ldap/junit5/EmbeddedLdapExtensionStaticTest.java
diff --git a/src/test/java/org/zapodot/junit/ldap/junit5/EmbeddedLdapExtensionTest.java b/embedded-ldap-junit5/src/test/java/org/zapodot/junit/ldap/junit5/EmbeddedLdapExtensionTest.java
similarity index 100%
rename from src/test/java/org/zapodot/junit/ldap/junit5/EmbeddedLdapExtensionTest.java
rename to embedded-ldap-junit5/src/test/java/org/zapodot/junit/ldap/junit5/EmbeddedLdapExtensionTest.java
diff --git a/embedded-ldap-junit5/src/test/resources/example.ldif b/embedded-ldap-junit5/src/test/resources/example.ldif
new file mode 100644
index 0000000..5eb286a
--- /dev/null
+++ b/embedded-ldap-junit5/src/test/resources/example.ldif
@@ -0,0 +1,28 @@
+version: 1
+
+dn: dc=zapodot,dc=org
+objectClass: domain
+objectClass: top
+dc: zapodot
+
+dn: ou=groups,dc=zapodot,dc=org
+objectclass: top
+objectclass: organizationalUnit
+ou: groups
+
+dn: ou=people,dc=zapodot,dc=org
+objectclass: top
+objectclass: organizationalUnit
+ou: people
+
+dn: cn=Sondre Eikanger Kvalo,ou=people,dc=zapodot,dc=org
+objectclass: top
+objectclass: person
+objectclass: organizationalPerson
+objectclass: inetOrgPerson
+uid: zapodot
+userPassword: password
+cn: Sondre Eikanger Kvalo
+cn:: U29uZHJlIEVpa2FuZ2VyIEt2YWzDuA==
+sn: Person
+description: Developer
\ No newline at end of file
diff --git a/pom.xml b/pom.xml
index d72f06c..cda93fa 100644
--- a/pom.xml
+++ b/pom.xml
@@ -5,10 +5,17 @@
4.0.0
org.zapodot
- embedded-ldap-junit
+ embedded-ldap-parent
+ pom
0.9.1-SNAPSHOT
+
+
+ embedded-ldap-core
+ embedded-ldap-junit
+ embedded-ldap-junit5
+
${project.artifactId}
- Library that provides a JUnit rule for setting up an in-memory LDAP server by using the glorious Unboundid LDAP SDK
+ Library that provides a JUnit rule and extension for setting up an in-memory LDAP server by using the glorious Unboundid LDAP SDK
https://github.com/zapodot/embedded-ldap-junit
2015
@@ -41,69 +48,7 @@
8
0.8.8
-
-
- com.unboundid
- unboundid-ldapsdk
- ${unboundid-ldapsdk.version}
-
-
- junit
- junit
- ${junit.version}
-
-
- org.junit.jupiter
- junit-jupiter-api
- ${junit5.version}
- true
-
-
- com.google.guava
- guava
- ${guava.version}
-
-
- net.bytebuddy
- byte-buddy
- ${byte-buddy.version}
-
-
- org.slf4j
- slf4j-api
- ${slf4j.version}
-
-
- ch.qos.logback
- logback-classic
- ${logback.version}
- test
-
-
- org.bouncycastle
- bcprov-jdk15on
- ${bouncycastle.version}
- test
-
-
- org.bouncycastle
- bcpkix-jdk15on
- ${bouncycastle.version}
- test
-
-
- org.junit.jupiter
- junit-jupiter-engine
- 5.7.0
- test
-
-
- org.junit.vintage
- junit-vintage-engine
- ${junit5.version}
- test
-
-
+
diff --git a/src/test/java/org/zapodot/junit/ldap/EmbeddedLdapRuleTlsTest.java b/src/test/java/org/zapodot/junit/ldap/EmbeddedLdapRuleTlsTest.java
deleted file mode 100755
index 43c703d..0000000
--- a/src/test/java/org/zapodot/junit/ldap/EmbeddedLdapRuleTlsTest.java
+++ /dev/null
@@ -1,216 +0,0 @@
-package org.zapodot.junit.ldap;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertTrue;
-
-import java.util.Arrays;
-import java.io.IOException;
-import java.math.BigInteger;
-import java.net.InetAddress;
-import java.security.KeyManagementException;
-import java.security.KeyPair;
-import java.security.KeyPairGenerator;
-import java.security.KeyStore;
-import java.security.KeyStoreException;
-import java.security.NoSuchAlgorithmException;
-import java.security.Provider;
-import java.security.Security;
-import java.security.UnrecoverableKeyException;
-import java.security.cert.Certificate;
-import java.security.cert.CertificateException;
-import java.security.cert.X509Certificate;
-import java.util.Arrays;
-import java.util.Calendar;
-import java.util.Date;
-
-import javax.naming.Context;
-import javax.naming.NamingEnumeration;
-import javax.naming.directory.DirContext;
-import javax.naming.directory.SearchControls;
-
-import javax.net.ssl.KeyManager;
-import javax.net.ssl.KeyManagerFactory;
-import javax.net.ssl.SSLContext;
-import javax.net.ssl.TrustManager;
-import javax.net.ssl.TrustManagerFactory;
-
-import org.bouncycastle.asn1.ASN1ObjectIdentifier;
-import org.bouncycastle.asn1.x509.BasicConstraints;
-import org.bouncycastle.cert.X509CertificateHolder;
-import org.bouncycastle.cert.jcajce.JcaX509CertificateConverter;
-import org.bouncycastle.cert.jcajce.JcaX509v3CertificateBuilder;
-import org.bouncycastle.jce.provider.BouncyCastleProvider;
-import org.bouncycastle.operator.ContentSigner;
-import org.bouncycastle.operator.OperatorCreationException;
-import org.bouncycastle.operator.jcajce.JcaContentSignerBuilder;
-import org.junit.Rule;
-import org.junit.Test;
-
-import com.google.common.collect.Iterators;
-import com.unboundid.ldap.listener.InMemoryListenerConfig;
-import com.unboundid.ldap.sdk.AddRequest;
-import com.unboundid.ldap.sdk.Attribute;
-import com.unboundid.ldap.sdk.LDAPConnection;
-import com.unboundid.ldap.sdk.LDAPInterface;
-import com.unboundid.ldap.sdk.SearchRequest;
-import com.unboundid.ldap.sdk.SearchResult;
-import com.unboundid.ldap.sdk.SearchResultEntry;
-import com.unboundid.ldap.sdk.SearchScope;
-
-public class EmbeddedLdapRuleTlsTest {
-
- public static final String DOMAIN_DSN = "dc=zapodot,dc=org";
-
- final SSLContext sslContext;
- {
- try {
- sslContext = buildSslContext();
- } catch (Exception e) {
- throw new IllegalStateException("Failed to create LDAPS config", e);
- }
- }
-
- @Rule
- public EmbeddedLdapRule embeddedLdapRule = EmbeddedLdapRuleBuilder
- .newInstance()
- .usingDomainDsn(DOMAIN_DSN)
- .importingLdifs("example.ldif")
- .withListener(getListenerConfig())
- .useTls(true)
- .withSocketFactory(sslContext.getSocketFactory())
- .build();
-
- private InMemoryListenerConfig getListenerConfig() {
- try {
- return InMemoryListenerConfig.createLDAPSConfig(
- "tls", InetAddress.getLoopbackAddress(), 0, sslContext.getServerSocketFactory(),
- sslContext.getSocketFactory()
- );
- } catch (Exception e) {
- throw new IllegalStateException("Failed to create LDAPS config", e);
- }
- }
-
- @Test
- public void testLdapConnection() throws Exception {
- final LDAPInterface ldapConnection = embeddedLdapRule.ldapConnection();
- final SearchResult searchResult = ldapConnection.search(DOMAIN_DSN, SearchScope.SUB, "(objectClass=person)");
- assertEquals(1, searchResult.getEntryCount());
- }
-
- @Test
- public void testRawLdapConnection() throws Exception {
- final String commonName = "Test person";
- final String dn = String.format(
- "cn=%s,ou=people,dc=zapodot,dc=org",
- commonName);
- LDAPConnection ldapConnection = embeddedLdapRule.unsharedLdapConnection();
- try {
- ldapConnection.add(new AddRequest(dn, Arrays.asList(
- new Attribute("objectclass", "top", "person", "organizationalPerson", "inetOrgPerson"),
- new Attribute("cn", commonName), new Attribute("sn", "Person"), new Attribute("uid", "test"))));
- } finally {
- // Forces the LDAP connection to be closed. This is not necessary as the rule will usually close it for you.
- ldapConnection.close();
- }
- ldapConnection = embeddedLdapRule.unsharedLdapConnection();
- final SearchResultEntry entry = ldapConnection.searchForEntry(new SearchRequest(dn,
- SearchScope.BASE,
- "(objectClass=person)"));
- assertNotNull(entry);
- }
-
- @Test
- public void testDirContext() throws Exception {
- final DirContext dirContext = embeddedLdapRule.dirContext();
- final SearchControls searchControls = new SearchControls();
- searchControls.setSearchScope(SearchControls.SUBTREE_SCOPE);
- final NamingEnumeration resultNamingEnumeration =
- dirContext.search(DOMAIN_DSN, "(objectClass=person)", searchControls);
- assertEquals(1, Iterators.size(Iterators.forEnumeration(resultNamingEnumeration)));
- }
-
- @Test
- public void testContext() throws Exception {
- final Context context = embeddedLdapRule.context();
- final Object user = context.lookup("cn=Sondre Eikanger Kvalo,ou=people,dc=zapodot,dc=org");
- assertNotNull(user);
- }
-
- @Test
- public void testContextClose() throws Exception {
- final Context context = embeddedLdapRule.context();
- context.close();
- assertNotNull(context.getNameInNamespace());
-
- }
-
- @Test
- public void testEmbeddedServerPort() throws Exception {
- assertTrue(embeddedLdapRule.embeddedServerPort() > 0);
-
- }
-
- @Test(expected = IllegalStateException.class)
- public void testNoPortAssignedYet() throws Exception {
- final EmbeddedLdapRule embeddedLdapRule = new EmbeddedLdapRuleBuilder().build();
- embeddedLdapRule.embeddedServerPort();
-
- }
-
- public static SSLContext buildSslContext()
- throws KeyStoreException, IOException, CertificateException, NoSuchAlgorithmException,
- UnrecoverableKeyException, KeyManagementException, OperatorCreationException {
- KeyStore keystore = KeyStore.getInstance("jks");
- keystore.load(null, new char[] {});
- KeyPairGenerator gen = KeyPairGenerator.getInstance("RSA");
- gen.initialize(2014);
- final KeyPair keyPair = gen.generateKeyPair();
-
- Provider bcProvider = new BouncyCastleProvider();
- Security.addProvider(bcProvider);
-
- long now = System.currentTimeMillis();
- Date startDate = new Date(now);
-
- org.bouncycastle.asn1.x500.X500Name dn = new org.bouncycastle.asn1.x500.X500Name("cn=localhost");
- BigInteger sn = new BigInteger(Long.toString(now));
-
- Calendar calendar = Calendar.getInstance();
- calendar.setTime(startDate);
- calendar.add(Calendar.HOUR, 1);
- Date endDate = calendar.getTime();
-
- String signatureAlgorithm = "SHA256WithRSA";
-
- final ContentSigner contentSigner = new JcaContentSignerBuilder(signatureAlgorithm).build(keyPair.getPrivate());
-
- final X509CertificateHolder holder =
- new JcaX509v3CertificateBuilder(dn, sn, startDate, endDate, dn, keyPair.getPublic())
- .addExtension(new ASN1ObjectIdentifier("2.5.29.19"), true, new BasicConstraints(true))
- .build(contentSigner);
- final X509Certificate cert = new JcaX509CertificateConverter()
- .setProvider(bcProvider)
- .getCertificate(holder);
- keystore.setCertificateEntry("test", cert);
- keystore.setKeyEntry("key", keyPair.getPrivate(), new char[] {}, new Certificate[] { cert });
-
- final KeyManagerFactory kmfactory = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
- kmfactory.init(keystore, new char[] {});
- final KeyManager[] kms = kmfactory.getKeyManagers();
-
- KeyStore truststore = KeyStore.getInstance("jks");
- truststore.load(null, new char[] {});
- truststore.setCertificateEntry("test", cert);
-
- final TrustManagerFactory tmfactory = TrustManagerFactory.getInstance(
- TrustManagerFactory.getDefaultAlgorithm()
- );
- tmfactory.init(truststore);
- final TrustManager[] tms = tmfactory.getTrustManagers();
- final SSLContext sslcontext = SSLContext.getInstance("TLS");
- sslcontext.init(kms, tms, null);
- return sslcontext;
- }
-}
diff --git a/src/test/java/org/zapodot/junit/ldap/junit5/EmbeddedLdapExtensionBuilderTest.java b/src/test/java/org/zapodot/junit/ldap/junit5/EmbeddedLdapExtensionBuilderTest.java
deleted file mode 100644
index 77d0d1e..0000000
--- a/src/test/java/org/zapodot/junit/ldap/junit5/EmbeddedLdapExtensionBuilderTest.java
+++ /dev/null
@@ -1,87 +0,0 @@
-package org.zapodot.junit.ldap.junit5;
-
-import org.junit.Test;
-
-import static org.junit.Assert.assertNotNull;
-
-public class EmbeddedLdapExtensionBuilderTest {
-
- @Test
- public void bindingToLegalPort() {
- assertNotNull(EmbeddedLdapExtensionBuilder.newInstance().bindingToPort(9999));
- }
-
- @Test(expected = IllegalStateException.class)
- public void testPrematureLdapConnection() throws Exception {
- EmbeddedLdapExtensionBuilder.newInstance().build().ldapConnection();
-
- }
-
- @Test(expected = IllegalStateException.class)
- public void testPrematureContext() throws Exception {
- EmbeddedLdapExtensionBuilder.newInstance().build().context();
-
- }
-
- @Test(expected = IllegalArgumentException.class)
- public void testUnknownLDIF() {
- EmbeddedLdapExtensionBuilder.newInstance().importingLdifs("nonExisting.ldif").build();
-
- }
-
- @Test
- public void testNullLDIF() {
- assertNotNull(EmbeddedLdapExtensionBuilder.newInstance().importingLdifs(null).build());
-
- }
-
- @Test(expected = IllegalStateException.class)
- public void testIllegalDSN() {
- EmbeddedLdapExtensionBuilder.newInstance().usingBindDSN("bindDsn").build();
-
- }
-
- @Test(expected = IllegalArgumentException.class)
- public void testIllegalPort() {
- EmbeddedLdapExtensionBuilder.newInstance().bindingToPort(Integer.MIN_VALUE).build();
-
- }
-
- @Test(expected = IllegalArgumentException.class)
- public void testSchemaNotFound() {
- EmbeddedLdapExtensionBuilder.newInstance().withSchema("non-existing-schema.ldif").build();
-
- }
-
- @Test(expected = IllegalArgumentException.class)
- public void testSchemaIsNotAFile() {
- EmbeddedLdapExtensionBuilder.newInstance().withSchema("folder").build();
-
- }
-
- @Test(expected = IllegalArgumentException.class)
- public void testSchemaIsInvalid() {
- EmbeddedLdapExtensionBuilder.newInstance().withSchema("invalid.ldif").build();
-
- }
-
- @Test(expected = IllegalArgumentException.class)
- public void testSchemaFileUnsupportedIsInvalid() {
- EmbeddedLdapExtensionBuilder.newInstance().withSchema("\"#%¤&&%/¤##¤¤").build();
-
- }
-
- @Test(expected = IllegalArgumentException.class)
- public void testInvalidPort() {
- EmbeddedLdapExtensionBuilder.newInstance().bindingToPort(Integer.MAX_VALUE);
-
- }
-
- @Test(expected = IllegalArgumentException.class)
- public void testInvalidBindAddress() {
- EmbeddedLdapExtensionBuilder.newInstance().bindingToAddress("åpsldfåpl");
-
- }
-
-
-}
From bd1152625a7f0368cf8d134e9c8565cc7f95aaf0 Mon Sep 17 00:00:00 2001
From: Bastien Jansen
Date: Mon, 2 Nov 2020 13:14:34 +0100
Subject: [PATCH 4/5] Moved most of the unit tests from embedded-ldap-junit to
embedded-ldap-core
---
embedded-ldap-core/pom.xml | 20 +
.../AbstractEmbeddedLdapBuilderTest.java | 88 +
.../AuthenticationConfigurationTest.java | 0
...dLdapServerCustomSchemaDuplicatedTest.java | 35 +
...rverCustomStandardAndCustomSchemaTest.java | 37 +
...ddedLdapServerCustomWithoutSchemaTest.java | 35 +
...ServerCustomWithoutStandardSchemaTest.java | 36 +
.../EmbeddedLdapServerMultipleDSNs.java | 40 +
.../EmbeddedLdapServerNoAuthTest.java | 35 +
.../EmbeddedLdapServerStandardContext.java | 33 +
.../EmbeddedLdapServerStarttlsTest.java | 151 ++
.../ldap/internal/EmbeddedLdapServerTest.java | 104 ++
...erverWithListeningAddressProvidedTest.java | 46 +
.../EmbeddedLdapServerWithSpacesTest.java | 34 +
.../internal/FakeEmbeddedLdapBuilder.java | 32 +
.../jndi/ContextProxyFactoryTest.java | 0
.../LDAPInterfaceProxyFactoryTest.java | 0
.../src/test/resources/custom-schema.ldif | 7 +
.../src/test/resources/example.ldif | 28 +
.../resources/folder with space/example.ldif | 28 +
.../src/test/resources/folder/.placeholder | 0
.../src/test/resources/invalid.ldif | 2 +
.../src/test/resources/standard-schema.ldif | 1546 +++++++++++++++++
23 files changed, 2337 insertions(+)
create mode 100644 embedded-ldap-core/src/test/java/org/zapodot/junit/ldap/internal/AbstractEmbeddedLdapBuilderTest.java
rename {embedded-ldap-junit => embedded-ldap-core}/src/test/java/org/zapodot/junit/ldap/internal/AuthenticationConfigurationTest.java (100%)
create mode 100644 embedded-ldap-core/src/test/java/org/zapodot/junit/ldap/internal/EmbeddedLdapServerCustomSchemaDuplicatedTest.java
create mode 100644 embedded-ldap-core/src/test/java/org/zapodot/junit/ldap/internal/EmbeddedLdapServerCustomStandardAndCustomSchemaTest.java
create mode 100644 embedded-ldap-core/src/test/java/org/zapodot/junit/ldap/internal/EmbeddedLdapServerCustomWithoutSchemaTest.java
create mode 100644 embedded-ldap-core/src/test/java/org/zapodot/junit/ldap/internal/EmbeddedLdapServerCustomWithoutStandardSchemaTest.java
create mode 100644 embedded-ldap-core/src/test/java/org/zapodot/junit/ldap/internal/EmbeddedLdapServerMultipleDSNs.java
create mode 100644 embedded-ldap-core/src/test/java/org/zapodot/junit/ldap/internal/EmbeddedLdapServerNoAuthTest.java
create mode 100644 embedded-ldap-core/src/test/java/org/zapodot/junit/ldap/internal/EmbeddedLdapServerStandardContext.java
create mode 100644 embedded-ldap-core/src/test/java/org/zapodot/junit/ldap/internal/EmbeddedLdapServerStarttlsTest.java
create mode 100644 embedded-ldap-core/src/test/java/org/zapodot/junit/ldap/internal/EmbeddedLdapServerTest.java
create mode 100644 embedded-ldap-core/src/test/java/org/zapodot/junit/ldap/internal/EmbeddedLdapServerWithListeningAddressProvidedTest.java
create mode 100644 embedded-ldap-core/src/test/java/org/zapodot/junit/ldap/internal/EmbeddedLdapServerWithSpacesTest.java
create mode 100644 embedded-ldap-core/src/test/java/org/zapodot/junit/ldap/internal/FakeEmbeddedLdapBuilder.java
rename {embedded-ldap-junit => embedded-ldap-core}/src/test/java/org/zapodot/junit/ldap/internal/jndi/ContextProxyFactoryTest.java (100%)
rename {embedded-ldap-junit => embedded-ldap-core}/src/test/java/org/zapodot/junit/ldap/internal/unboundid/LDAPInterfaceProxyFactoryTest.java (100%)
create mode 100644 embedded-ldap-core/src/test/resources/custom-schema.ldif
create mode 100644 embedded-ldap-core/src/test/resources/example.ldif
create mode 100644 embedded-ldap-core/src/test/resources/folder with space/example.ldif
create mode 100644 embedded-ldap-core/src/test/resources/folder/.placeholder
create mode 100644 embedded-ldap-core/src/test/resources/invalid.ldif
create mode 100644 embedded-ldap-core/src/test/resources/standard-schema.ldif
diff --git a/embedded-ldap-core/pom.xml b/embedded-ldap-core/pom.xml
index 60a0918..dde3d64 100644
--- a/embedded-ldap-core/pom.xml
+++ b/embedded-ldap-core/pom.xml
@@ -33,5 +33,25 @@
slf4j-api
${slf4j.version}
+
+
+
+ junit
+ junit
+ ${junit.version}
+ test
+
+
+ org.bouncycastle
+ bcprov-jdk15on
+ ${bouncycastle.version}
+ test
+
+
+ org.bouncycastle
+ bcpkix-jdk15on
+ ${bouncycastle.version}
+ test
+
diff --git a/embedded-ldap-core/src/test/java/org/zapodot/junit/ldap/internal/AbstractEmbeddedLdapBuilderTest.java b/embedded-ldap-core/src/test/java/org/zapodot/junit/ldap/internal/AbstractEmbeddedLdapBuilderTest.java
new file mode 100644
index 0000000..9754cb4
--- /dev/null
+++ b/embedded-ldap-core/src/test/java/org/zapodot/junit/ldap/internal/AbstractEmbeddedLdapBuilderTest.java
@@ -0,0 +1,88 @@
+package org.zapodot.junit.ldap.internal;
+
+import org.junit.Test;
+
+import static org.junit.Assert.assertNotNull;
+
+public class AbstractEmbeddedLdapBuilderTest {
+
+ @Test
+ public void bindingToLegalPort() {
+ assertNotNull(FakeEmbeddedLdapBuilder.newInstance().bindingToPort(9999));
+ }
+
+ @Test(expected = IllegalStateException.class)
+ public void testPrematureLdapConnection() throws Exception {
+ FakeEmbeddedLdapBuilder.newInstance().build().ldapConnection();
+
+ }
+
+ @Test(expected = IllegalStateException.class)
+ public void testPrematureContext() throws Exception {
+ FakeEmbeddedLdapBuilder.newInstance().build().context();
+
+ }
+
+ @Test(expected = IllegalArgumentException.class)
+ public void testUnknownLDIF() {
+ FakeEmbeddedLdapBuilder.newInstance().importingLdifs("nonExisting.ldif").build();
+
+ }
+
+ @Test
+ public void testNullLDIF() {
+ assertNotNull(FakeEmbeddedLdapBuilder.newInstance().importingLdifs(null).build());
+
+ }
+
+ @Test(expected = IllegalStateException.class)
+ public void testIllegalDSN() {
+ FakeEmbeddedLdapBuilder.newInstance().usingBindDSN("bindDsn").build();
+
+ }
+
+ @Test(expected = IllegalArgumentException.class)
+ public void testIllegalPort() {
+ FakeEmbeddedLdapBuilder.newInstance().bindingToPort(Integer.MIN_VALUE).build();
+
+ }
+
+ @Test(expected = IllegalArgumentException.class)
+ public void testSchemaNotFound() {
+ FakeEmbeddedLdapBuilder.newInstance().withSchema("non-existing-schema.ldif").build();
+
+ }
+
+ @Test(expected = IllegalArgumentException.class)
+ public void testSchemaIsNotAFile() {
+ FakeEmbeddedLdapBuilder.newInstance().withSchema("folder").build();
+
+ }
+
+ @Test(expected = IllegalArgumentException.class)
+ public void testSchemaIsInvalid() {
+ FakeEmbeddedLdapBuilder.newInstance().withSchema("invalid.ldif").build();
+
+ }
+
+ @Test(expected = IllegalArgumentException.class)
+ public void testSchemaFileUnsupportedIsInvalid() {
+ FakeEmbeddedLdapBuilder.newInstance().withSchema("\"#%¤&&%/¤##¤¤").build();
+
+ }
+
+ @Test(expected = IllegalArgumentException.class)
+ public void testInvalidPort() {
+ FakeEmbeddedLdapBuilder.newInstance().bindingToPort(Integer.MAX_VALUE);
+
+ }
+
+ @Test(expected = IllegalArgumentException.class)
+ public void testInvalidBindAddress() {
+ FakeEmbeddedLdapBuilder.newInstance().bindingToAddress("åpsldfåpl");
+
+ }
+
+
+}
+
diff --git a/embedded-ldap-junit/src/test/java/org/zapodot/junit/ldap/internal/AuthenticationConfigurationTest.java b/embedded-ldap-core/src/test/java/org/zapodot/junit/ldap/internal/AuthenticationConfigurationTest.java
similarity index 100%
rename from embedded-ldap-junit/src/test/java/org/zapodot/junit/ldap/internal/AuthenticationConfigurationTest.java
rename to embedded-ldap-core/src/test/java/org/zapodot/junit/ldap/internal/AuthenticationConfigurationTest.java
diff --git a/embedded-ldap-core/src/test/java/org/zapodot/junit/ldap/internal/EmbeddedLdapServerCustomSchemaDuplicatedTest.java b/embedded-ldap-core/src/test/java/org/zapodot/junit/ldap/internal/EmbeddedLdapServerCustomSchemaDuplicatedTest.java
new file mode 100644
index 0000000..2afa57d
--- /dev/null
+++ b/embedded-ldap-core/src/test/java/org/zapodot/junit/ldap/internal/EmbeddedLdapServerCustomSchemaDuplicatedTest.java
@@ -0,0 +1,35 @@
+package org.zapodot.junit.ldap.internal;
+
+import com.unboundid.ldap.sdk.LDAPException;
+import com.unboundid.ldap.sdk.schema.AttributeTypeDefinition;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.zapodot.junit.ldap.EmbeddedLdapServer;
+
+import static org.junit.Assert.assertNotNull;
+
+public class EmbeddedLdapServerCustomSchemaDuplicatedTest {
+
+ private final EmbeddedLdapServer embeddedLdapRule = FakeEmbeddedLdapBuilder.newInstance()
+ .withSchema("standard-schema.ldif")
+ .build();
+
+ @Before
+ public void setup() throws LDAPException {
+ ((EmbeddedLdapServerImpl) embeddedLdapRule).startEmbeddedLdapServer();
+ }
+
+ @After
+ public void teardown() throws LDAPException {
+ ((EmbeddedLdapServerImpl) embeddedLdapRule).takeDownEmbeddedLdapServer();
+ }
+
+ @Test
+ public void testFindCustomAttribute() throws Exception {
+ final AttributeTypeDefinition changelogAttribute =
+ embeddedLdapRule.ldapConnection().getSchema().getAttributeType("changelog");
+ assertNotNull(changelogAttribute);
+
+ }
+}
diff --git a/embedded-ldap-core/src/test/java/org/zapodot/junit/ldap/internal/EmbeddedLdapServerCustomStandardAndCustomSchemaTest.java b/embedded-ldap-core/src/test/java/org/zapodot/junit/ldap/internal/EmbeddedLdapServerCustomStandardAndCustomSchemaTest.java
new file mode 100644
index 0000000..eba39eb
--- /dev/null
+++ b/embedded-ldap-core/src/test/java/org/zapodot/junit/ldap/internal/EmbeddedLdapServerCustomStandardAndCustomSchemaTest.java
@@ -0,0 +1,37 @@
+package org.zapodot.junit.ldap.internal;
+
+import com.unboundid.ldap.sdk.LDAPException;
+import com.unboundid.ldap.sdk.schema.AttributeTypeDefinition;
+import com.unboundid.ldap.sdk.schema.Schema;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.zapodot.junit.ldap.EmbeddedLdapServer;
+
+import static org.junit.Assert.assertNotNull;
+
+public class EmbeddedLdapServerCustomStandardAndCustomSchemaTest {
+
+ private final EmbeddedLdapServer embeddedLdapRule = FakeEmbeddedLdapBuilder.newInstance()
+ .withSchema("custom-schema.ldif")
+ .build();
+
+ @Before
+ public void setup() throws LDAPException {
+ ((EmbeddedLdapServerImpl) embeddedLdapRule).startEmbeddedLdapServer();
+ }
+
+ @After
+ public void teardown() throws LDAPException {
+ ((EmbeddedLdapServerImpl) embeddedLdapRule).takeDownEmbeddedLdapServer();
+ }
+
+ @Test
+ public void testFindCustomAttribute() throws Exception {
+ final Schema currentSchema = embeddedLdapRule.ldapConnection().getSchema();
+ final AttributeTypeDefinition changelogAttribute =
+ currentSchema.getAttributeType("attribute");
+ assertNotNull(changelogAttribute);
+ assertNotNull(currentSchema.getObjectClass("type"));
+ }
+}
diff --git a/embedded-ldap-core/src/test/java/org/zapodot/junit/ldap/internal/EmbeddedLdapServerCustomWithoutSchemaTest.java b/embedded-ldap-core/src/test/java/org/zapodot/junit/ldap/internal/EmbeddedLdapServerCustomWithoutSchemaTest.java
new file mode 100644
index 0000000..3daaceb
--- /dev/null
+++ b/embedded-ldap-core/src/test/java/org/zapodot/junit/ldap/internal/EmbeddedLdapServerCustomWithoutSchemaTest.java
@@ -0,0 +1,35 @@
+package org.zapodot.junit.ldap.internal;
+
+import com.unboundid.ldap.sdk.LDAPException;
+import com.unboundid.ldap.sdk.schema.Schema;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.zapodot.junit.ldap.EmbeddedLdapServer;
+
+import static org.junit.Assert.assertTrue;
+
+public class EmbeddedLdapServerCustomWithoutSchemaTest {
+
+ private final EmbeddedLdapServer embeddedLdapRule = FakeEmbeddedLdapBuilder.newInstance()
+ .withoutDefaultSchema()
+ .build();
+
+ @Before
+ public void setup() throws LDAPException {
+ ((EmbeddedLdapServerImpl) embeddedLdapRule).startEmbeddedLdapServer();
+ }
+
+ @After
+ public void teardown() throws LDAPException {
+ ((EmbeddedLdapServerImpl) embeddedLdapRule).takeDownEmbeddedLdapServer();
+ }
+
+ @Test
+ public void testEmptySchema() throws Exception {
+ final Schema schema =
+ embeddedLdapRule.ldapConnection().getSchema();
+ assertTrue(schema.getAttributeTypes().isEmpty());
+
+ }
+}
diff --git a/embedded-ldap-core/src/test/java/org/zapodot/junit/ldap/internal/EmbeddedLdapServerCustomWithoutStandardSchemaTest.java b/embedded-ldap-core/src/test/java/org/zapodot/junit/ldap/internal/EmbeddedLdapServerCustomWithoutStandardSchemaTest.java
new file mode 100644
index 0000000..84e8639
--- /dev/null
+++ b/embedded-ldap-core/src/test/java/org/zapodot/junit/ldap/internal/EmbeddedLdapServerCustomWithoutStandardSchemaTest.java
@@ -0,0 +1,36 @@
+package org.zapodot.junit.ldap.internal;
+
+import com.unboundid.ldap.sdk.LDAPException;
+import com.unboundid.ldap.sdk.schema.AttributeTypeDefinition;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.zapodot.junit.ldap.EmbeddedLdapServer;
+
+import static org.junit.Assert.assertNotNull;
+
+public class EmbeddedLdapServerCustomWithoutStandardSchemaTest {
+
+ private final EmbeddedLdapServer embeddedLdapRule = FakeEmbeddedLdapBuilder.newInstance()
+ .withoutDefaultSchema()
+ .withSchema("standard-schema.ldif")
+ .build();
+
+ @Before
+ public void setup() throws LDAPException {
+ ((EmbeddedLdapServerImpl) embeddedLdapRule).startEmbeddedLdapServer();
+ }
+
+ @After
+ public void teardown() throws LDAPException {
+ ((EmbeddedLdapServerImpl) embeddedLdapRule).takeDownEmbeddedLdapServer();
+ }
+
+ @Test
+ public void testFindCustomAttribute() throws Exception {
+ final AttributeTypeDefinition changelogAttribute =
+ embeddedLdapRule.ldapConnection().getSchema().getAttributeType("changelog");
+ assertNotNull(changelogAttribute);
+
+ }
+}
diff --git a/embedded-ldap-core/src/test/java/org/zapodot/junit/ldap/internal/EmbeddedLdapServerMultipleDSNs.java b/embedded-ldap-core/src/test/java/org/zapodot/junit/ldap/internal/EmbeddedLdapServerMultipleDSNs.java
new file mode 100644
index 0000000..7ec4dab
--- /dev/null
+++ b/embedded-ldap-core/src/test/java/org/zapodot/junit/ldap/internal/EmbeddedLdapServerMultipleDSNs.java
@@ -0,0 +1,40 @@
+package org.zapodot.junit.ldap.internal;
+
+import com.unboundid.ldap.sdk.LDAPException;
+import com.unboundid.ldap.sdk.LDAPInterface;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.zapodot.junit.ldap.EmbeddedLdapServer;
+
+import static org.junit.Assert.assertArrayEquals;
+
+public class EmbeddedLdapServerMultipleDSNs {
+
+ public static final String DSN_ROOT_ONE = "dc=zapodot,dc=com";
+ public static final String DSN_ROOT_TWO = "dc=zapodot,dc=org";
+
+ private final EmbeddedLdapServer embeddedLdapRule = FakeEmbeddedLdapBuilder.newInstance()
+ .usingDomainDsn(DSN_ROOT_ONE)
+ .usingDomainDsn(DSN_ROOT_TWO)
+ .importingLdifs("example.ldif")
+ .build();
+
+ @Before
+ public void setup() throws LDAPException {
+ ((EmbeddedLdapServerImpl) embeddedLdapRule).startEmbeddedLdapServer();
+ }
+
+ @After
+ public void teardown() throws LDAPException {
+ ((EmbeddedLdapServerImpl) embeddedLdapRule).takeDownEmbeddedLdapServer();
+ }
+
+ @Test
+ public void testCheckNamingContexts() throws Exception {
+ final LDAPInterface ldapConnection = embeddedLdapRule.ldapConnection();
+ final String[] namingContextDNs = ldapConnection.getRootDSE().getNamingContextDNs();
+ assertArrayEquals(new String[]{DSN_ROOT_ONE, DSN_ROOT_TWO}, namingContextDNs);
+
+ }
+}
diff --git a/embedded-ldap-core/src/test/java/org/zapodot/junit/ldap/internal/EmbeddedLdapServerNoAuthTest.java b/embedded-ldap-core/src/test/java/org/zapodot/junit/ldap/internal/EmbeddedLdapServerNoAuthTest.java
new file mode 100644
index 0000000..39e5fe3
--- /dev/null
+++ b/embedded-ldap-core/src/test/java/org/zapodot/junit/ldap/internal/EmbeddedLdapServerNoAuthTest.java
@@ -0,0 +1,35 @@
+package org.zapodot.junit.ldap.internal;
+
+import com.unboundid.ldap.sdk.LDAPException;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.zapodot.junit.ldap.EmbeddedLdapServer;
+
+import static org.junit.Assert.assertNotNull;
+
+public class EmbeddedLdapServerNoAuthTest {
+
+ private final EmbeddedLdapServer embeddedLdapRule = FakeEmbeddedLdapBuilder
+ .newInstance()
+ .usingBindCredentials(null)
+ .usingDomainDsn("dc=zapodot,dc=org")
+ .importingLdifs("example.ldif")
+ .build();
+
+ @Before
+ public void setup() throws LDAPException {
+ ((EmbeddedLdapServerImpl) embeddedLdapRule).startEmbeddedLdapServer();
+ }
+
+ @After
+ public void teardown() throws LDAPException {
+ ((EmbeddedLdapServerImpl) embeddedLdapRule).takeDownEmbeddedLdapServer();
+ }
+
+ @Test
+ public void testConnect() throws Exception {
+ assertNotNull(embeddedLdapRule.dirContext().search("cn=Sondre Eikanger Kvalo,ou=people,dc=zapodot,dc=org", null));
+
+ }
+}
diff --git a/embedded-ldap-core/src/test/java/org/zapodot/junit/ldap/internal/EmbeddedLdapServerStandardContext.java b/embedded-ldap-core/src/test/java/org/zapodot/junit/ldap/internal/EmbeddedLdapServerStandardContext.java
new file mode 100644
index 0000000..1848975
--- /dev/null
+++ b/embedded-ldap-core/src/test/java/org/zapodot/junit/ldap/internal/EmbeddedLdapServerStandardContext.java
@@ -0,0 +1,33 @@
+package org.zapodot.junit.ldap.internal;
+
+import com.unboundid.ldap.sdk.LDAPException;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.zapodot.junit.ldap.EmbeddedLdapServer;
+
+import static org.junit.Assert.assertArrayEquals;
+
+public class EmbeddedLdapServerStandardContext {
+
+ private final EmbeddedLdapServer embeddedLdapRule = FakeEmbeddedLdapBuilder.newInstance()
+ .build();
+
+ @Before
+ public void setup() throws LDAPException {
+ ((EmbeddedLdapServerImpl) embeddedLdapRule).startEmbeddedLdapServer();
+ }
+
+ @After
+ public void teardown() throws LDAPException {
+ ((EmbeddedLdapServerImpl) embeddedLdapRule).takeDownEmbeddedLdapServer();
+ }
+
+ @Test
+ public void testUsingDefaultDomain() throws Exception {
+ assertArrayEquals(new String[]{FakeEmbeddedLdapBuilder.DEFAULT_DOMAIN},
+ embeddedLdapRule.ldapConnection().getRootDSE().getNamingContextDNs());
+
+
+ }
+}
diff --git a/embedded-ldap-core/src/test/java/org/zapodot/junit/ldap/internal/EmbeddedLdapServerStarttlsTest.java b/embedded-ldap-core/src/test/java/org/zapodot/junit/ldap/internal/EmbeddedLdapServerStarttlsTest.java
new file mode 100644
index 0000000..a19a991
--- /dev/null
+++ b/embedded-ldap-core/src/test/java/org/zapodot/junit/ldap/internal/EmbeddedLdapServerStarttlsTest.java
@@ -0,0 +1,151 @@
+package org.zapodot.junit.ldap.internal;
+
+import com.unboundid.ldap.listener.InMemoryListenerConfig;
+import com.unboundid.ldap.sdk.*;
+import com.unboundid.ldap.sdk.extensions.StartTLSExtendedRequest;
+import org.bouncycastle.asn1.ASN1ObjectIdentifier;
+import org.bouncycastle.asn1.x509.BasicConstraints;
+import org.bouncycastle.cert.X509CertificateHolder;
+import org.bouncycastle.cert.jcajce.JcaX509CertificateConverter;
+import org.bouncycastle.cert.jcajce.JcaX509v3CertificateBuilder;
+import org.bouncycastle.jce.provider.BouncyCastleProvider;
+import org.bouncycastle.operator.ContentSigner;
+import org.bouncycastle.operator.OperatorCreationException;
+import org.bouncycastle.operator.jcajce.JcaContentSignerBuilder;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.zapodot.junit.ldap.EmbeddedLdapServer;
+
+import javax.net.ssl.*;
+import java.io.IOException;
+import java.math.BigInteger;
+import java.net.InetAddress;
+import java.security.*;
+import java.security.cert.Certificate;
+import java.security.cert.CertificateException;
+import java.security.cert.X509Certificate;
+import java.util.Arrays;
+import java.util.Calendar;
+import java.util.Date;
+
+import static org.junit.Assert.assertNotNull;
+
+public class EmbeddedLdapServerStarttlsTest {
+
+ public static final String DOMAIN_DSN = "dc=zapodot,dc=org";
+
+ final SSLContext sslContext;
+ {
+ try {
+ sslContext = buildSslContext();
+ } catch (Exception e) {
+ throw new IllegalStateException("Failed to create LDAPS config", e);
+ }
+ }
+
+ private final EmbeddedLdapServer embeddedLdapRule = FakeEmbeddedLdapBuilder
+ .newInstance()
+ .usingDomainDsn(DOMAIN_DSN)
+ .importingLdifs("example.ldif")
+ .withListener(getListenerConfig())
+ .build();
+
+ @Before
+ public void setup() throws LDAPException {
+ ((EmbeddedLdapServerImpl) embeddedLdapRule).startEmbeddedLdapServer();
+ }
+
+ @After
+ public void teardown() throws LDAPException {
+ ((EmbeddedLdapServerImpl) embeddedLdapRule).takeDownEmbeddedLdapServer();
+ }
+
+ private InMemoryListenerConfig getListenerConfig() {
+ try {
+ return InMemoryListenerConfig.createLDAPConfig(
+ "tls", InetAddress.getLoopbackAddress(), 0, sslContext.getSocketFactory()
+ );
+ } catch (Exception e) {
+ throw new IllegalStateException("Failed to create LDAPS config", e);
+ }
+ }
+
+ @Test
+ public void testRawLdapConnection() throws Exception {
+ final String commonName = "Test person";
+ final String dn = String.format(
+ "cn=%s,ou=people,dc=zapodot,dc=org",
+ commonName);
+ LDAPConnection ldapConnection = embeddedLdapRule.unsharedLdapConnection();
+ ldapConnection.processExtendedOperation(new StartTLSExtendedRequest(sslContext));
+ try {
+ ldapConnection.add(new AddRequest(dn, Arrays.asList(
+ new Attribute("objectclass", "top", "person", "organizationalPerson", "inetOrgPerson"),
+ new Attribute("cn", commonName), new Attribute("sn", "Person"), new Attribute("uid", "test"))));
+ } finally {
+ // Forces the LDAP connection to be closed. This is not necessary as the rule will usually close it for you.
+ ldapConnection.close();
+ }
+ ldapConnection = embeddedLdapRule.unsharedLdapConnection();
+ final SearchResultEntry entry = ldapConnection.searchForEntry(new SearchRequest(dn,
+ SearchScope.BASE,
+ "(objectClass=person)"));
+ assertNotNull(entry);
+ }
+
+ public static SSLContext buildSslContext()
+ throws KeyStoreException, IOException, CertificateException, NoSuchAlgorithmException,
+ UnrecoverableKeyException, KeyManagementException, OperatorCreationException {
+ KeyStore keystore = KeyStore.getInstance("jks");
+ keystore.load(null, new char[] {});
+ KeyPairGenerator gen = KeyPairGenerator.getInstance("RSA");
+ gen.initialize(2014);
+ final KeyPair keyPair = gen.generateKeyPair();
+
+ Provider bcProvider = new BouncyCastleProvider();
+ Security.addProvider(bcProvider);
+
+ long now = System.currentTimeMillis();
+ Date startDate = new Date(now);
+
+ org.bouncycastle.asn1.x500.X500Name dn = new org.bouncycastle.asn1.x500.X500Name("cn=localhost");
+ BigInteger sn = new BigInteger(Long.toString(now));
+
+ Calendar calendar = Calendar.getInstance();
+ calendar.setTime(startDate);
+ calendar.add(Calendar.HOUR, 1);
+ Date endDate = calendar.getTime();
+
+ String signatureAlgorithm = "SHA256WithRSA";
+
+ final ContentSigner contentSigner = new JcaContentSignerBuilder(signatureAlgorithm).build(keyPair.getPrivate());
+
+ final X509CertificateHolder holder =
+ new JcaX509v3CertificateBuilder(dn, sn, startDate, endDate, dn, keyPair.getPublic())
+ .addExtension(new ASN1ObjectIdentifier("2.5.29.19"), true, new BasicConstraints(true))
+ .build(contentSigner);
+ final X509Certificate cert = new JcaX509CertificateConverter()
+ .setProvider(bcProvider)
+ .getCertificate(holder);
+ keystore.setCertificateEntry("test", cert);
+ keystore.setKeyEntry("key", keyPair.getPrivate(), new char[] {}, new Certificate[] { cert });
+
+ final KeyManagerFactory kmfactory = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
+ kmfactory.init(keystore, new char[] {});
+ final KeyManager[] kms = kmfactory.getKeyManagers();
+
+ KeyStore truststore = KeyStore.getInstance("jks");
+ truststore.load(null, new char[] {});
+ truststore.setCertificateEntry("test", cert);
+
+ final TrustManagerFactory tmfactory = TrustManagerFactory.getInstance(
+ TrustManagerFactory.getDefaultAlgorithm()
+ );
+ tmfactory.init(truststore);
+ final TrustManager[] tms = tmfactory.getTrustManagers();
+ final SSLContext sslcontext = SSLContext.getInstance("TLS");
+ sslcontext.init(kms, tms, null);
+ return sslcontext;
+ }
+}
diff --git a/embedded-ldap-core/src/test/java/org/zapodot/junit/ldap/internal/EmbeddedLdapServerTest.java b/embedded-ldap-core/src/test/java/org/zapodot/junit/ldap/internal/EmbeddedLdapServerTest.java
new file mode 100644
index 0000000..7267fcf
--- /dev/null
+++ b/embedded-ldap-core/src/test/java/org/zapodot/junit/ldap/internal/EmbeddedLdapServerTest.java
@@ -0,0 +1,104 @@
+package org.zapodot.junit.ldap.internal;
+
+import com.google.common.collect.Iterators;
+import com.unboundid.ldap.sdk.*;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.zapodot.junit.ldap.EmbeddedLdapServer;
+
+import javax.naming.Context;
+import javax.naming.NamingEnumeration;
+import javax.naming.directory.DirContext;
+import javax.naming.directory.SearchControls;
+import java.util.Arrays;
+
+import static org.junit.Assert.*;
+
+public class EmbeddedLdapServerTest {
+
+ public static final String DOMAIN_DSN = "dc=zapodot,dc=org";
+
+ private final EmbeddedLdapServer embeddedLdapRule = FakeEmbeddedLdapBuilder
+ .newInstance()
+ .usingDomainDsn(DOMAIN_DSN)
+ .importingLdifs("example.ldif")
+ .build();
+
+ @Before
+ public void setup() throws LDAPException {
+ ((EmbeddedLdapServerImpl) embeddedLdapRule).startEmbeddedLdapServer();
+ }
+
+ @After
+ public void teardown() throws LDAPException {
+ ((EmbeddedLdapServerImpl) embeddedLdapRule).takeDownEmbeddedLdapServer();
+ }
+
+ @Test
+ public void testLdapConnection() throws Exception {
+ final LDAPInterface ldapConnection = embeddedLdapRule.ldapConnection();
+ final SearchResult searchResult = ldapConnection.search(DOMAIN_DSN, SearchScope.SUB, "(objectClass=person)");
+ assertEquals(1, searchResult.getEntryCount());
+ }
+
+ @Test
+ public void testRawLdapConnection() throws Exception {
+ final String commonName = "Test person";
+ final String dn = String.format(
+ "cn=%s,ou=people,dc=zapodot,dc=org",
+ commonName);
+ LDAPConnection ldapConnection = embeddedLdapRule.unsharedLdapConnection();
+ try {
+ ldapConnection.add(new AddRequest(dn, Arrays.asList(
+ new Attribute("objectclass", "top", "person", "organizationalPerson", "inetOrgPerson"),
+ new Attribute("cn", commonName), new Attribute("sn", "Person"), new Attribute("uid", "test"))));
+ } finally {
+ // Forces the LDAP connection to be closed. This is not necessary as the rule will usually close it for you.
+ ldapConnection.close();
+ }
+ ldapConnection = embeddedLdapRule.unsharedLdapConnection();
+ final SearchResultEntry entry = ldapConnection.searchForEntry(new SearchRequest(dn,
+ SearchScope.BASE,
+ "(objectClass=person)"));
+ assertNotNull(entry);
+ }
+
+ @Test
+ public void testDirContext() throws Exception {
+ final DirContext dirContext = embeddedLdapRule.dirContext();
+ final SearchControls searchControls = new SearchControls();
+ searchControls.setSearchScope(SearchControls.SUBTREE_SCOPE);
+ final NamingEnumeration resultNamingEnumeration =
+ dirContext.search(DOMAIN_DSN, "(objectClass=person)", searchControls);
+ assertEquals(1, Iterators.size(Iterators.forEnumeration(resultNamingEnumeration)));
+ }
+
+ @Test
+ public void testContext() throws Exception {
+ final Context context = embeddedLdapRule.context();
+ final Object user = context.lookup("cn=Sondre Eikanger Kvalo,ou=people,dc=zapodot,dc=org");
+ assertNotNull(user);
+ }
+
+ @Test
+ public void testContextClose() throws Exception {
+ final Context context = embeddedLdapRule.context();
+ context.close();
+ assertNotNull(context.getNameInNamespace());
+
+ }
+
+ @Test
+ public void testEmbeddedServerPort() throws Exception {
+ assertTrue(embeddedLdapRule.embeddedServerPort() > 0);
+
+ }
+
+ @Test(expected = IllegalStateException.class)
+ public void testNoPortAssignedYet() throws Exception {
+ final EmbeddedLdapServer embeddedLdapRule = new FakeEmbeddedLdapBuilder().build();
+ embeddedLdapRule.embeddedServerPort();
+
+ }
+}
diff --git a/embedded-ldap-core/src/test/java/org/zapodot/junit/ldap/internal/EmbeddedLdapServerWithListeningAddressProvidedTest.java b/embedded-ldap-core/src/test/java/org/zapodot/junit/ldap/internal/EmbeddedLdapServerWithListeningAddressProvidedTest.java
new file mode 100644
index 0000000..f653ca5
--- /dev/null
+++ b/embedded-ldap-core/src/test/java/org/zapodot/junit/ldap/internal/EmbeddedLdapServerWithListeningAddressProvidedTest.java
@@ -0,0 +1,46 @@
+package org.zapodot.junit.ldap.internal;
+
+import com.unboundid.ldap.sdk.LDAPException;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.BeforeClass;
+import org.junit.Test;
+import org.zapodot.junit.ldap.EmbeddedLdapServer;
+
+import java.net.InetAddress;
+
+import static org.junit.Assert.assertEquals;
+
+public class EmbeddedLdapServerWithListeningAddressProvidedTest {
+
+ public static InetAddress inetAddress;
+
+ private final EmbeddedLdapServer embeddedLdapRule = FakeEmbeddedLdapBuilder
+ .newInstance()
+ .usingDomainDsn("dc=zapodot,dc=org")
+ .importingLdifs("example.ldif")
+ .bindingToAddress(inetAddress.getHostAddress())
+ .build();
+
+ @Before
+ public void setup() throws LDAPException {
+ ((EmbeddedLdapServerImpl) embeddedLdapRule).startEmbeddedLdapServer();
+ }
+
+ @After
+ public void teardown() throws LDAPException {
+ ((EmbeddedLdapServerImpl) embeddedLdapRule).takeDownEmbeddedLdapServer();
+ }
+
+ @BeforeClass
+ public static void setupAddress() throws Exception {
+ inetAddress = InetAddress.getLocalHost();
+ }
+
+ @Test
+ public void testLookupAddress() throws Exception {
+ assertEquals(inetAddress.getHostAddress(),
+ embeddedLdapRule.unsharedLdapConnection().getConnectedAddress());
+
+ }
+}
diff --git a/embedded-ldap-core/src/test/java/org/zapodot/junit/ldap/internal/EmbeddedLdapServerWithSpacesTest.java b/embedded-ldap-core/src/test/java/org/zapodot/junit/ldap/internal/EmbeddedLdapServerWithSpacesTest.java
new file mode 100644
index 0000000..7b5ec78
--- /dev/null
+++ b/embedded-ldap-core/src/test/java/org/zapodot/junit/ldap/internal/EmbeddedLdapServerWithSpacesTest.java
@@ -0,0 +1,34 @@
+package org.zapodot.junit.ldap.internal;
+
+import com.unboundid.ldap.sdk.LDAPException;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.zapodot.junit.ldap.EmbeddedLdapServer;
+
+import static org.junit.Assert.assertNotNull;
+
+public class EmbeddedLdapServerWithSpacesTest {
+
+ private final EmbeddedLdapServer embeddedLdapRule = FakeEmbeddedLdapBuilder
+ .newInstance()
+ .usingDomainDsn("dc=zapodot,dc=org")
+ .importingLdifs("folder with space/example.ldif")
+ .build();
+
+ @Before
+ public void setup() throws LDAPException {
+ ((EmbeddedLdapServerImpl) embeddedLdapRule).startEmbeddedLdapServer();
+ }
+
+ @After
+ public void teardown() throws LDAPException {
+ ((EmbeddedLdapServerImpl) embeddedLdapRule).takeDownEmbeddedLdapServer();
+ }
+
+ @Test
+ public void testIsUp() throws Exception {
+ assertNotNull(embeddedLdapRule.ldapConnection().getRootDSE());
+
+ }
+}
diff --git a/embedded-ldap-core/src/test/java/org/zapodot/junit/ldap/internal/FakeEmbeddedLdapBuilder.java b/embedded-ldap-core/src/test/java/org/zapodot/junit/ldap/internal/FakeEmbeddedLdapBuilder.java
new file mode 100644
index 0000000..04ceae4
--- /dev/null
+++ b/embedded-ldap-core/src/test/java/org/zapodot/junit/ldap/internal/FakeEmbeddedLdapBuilder.java
@@ -0,0 +1,32 @@
+package org.zapodot.junit.ldap.internal;
+
+import com.unboundid.ldap.listener.InMemoryDirectoryServer;
+import com.unboundid.ldap.sdk.LDAPException;
+import org.zapodot.junit.ldap.EmbeddedLdapServer;
+
+import static org.zapodot.junit.ldap.internal.EmbeddedLdapServerImpl.createServer;
+
+class FakeEmbeddedLdapBuilder extends AbstractEmbeddedLdapBuilder {
+
+ static FakeEmbeddedLdapBuilder newInstance() {
+ return new FakeEmbeddedLdapBuilder();
+ }
+
+ @Override
+ protected FakeEmbeddedLdapBuilder getThis() {
+ return this;
+ }
+
+ EmbeddedLdapServer build() {
+ try {
+ InMemoryDirectoryServer server = createServer(createInMemoryServerConfiguration(), ldifsToImport);
+ return new EmbeddedLdapServerImpl(
+ server,
+ authenticationConfiguration) {
+
+ };
+ } catch (LDAPException e) {
+ throw new IllegalStateException("Can not initiate in-memory LDAP server due to an exception", e);
+ }
+ }
+}
diff --git a/embedded-ldap-junit/src/test/java/org/zapodot/junit/ldap/internal/jndi/ContextProxyFactoryTest.java b/embedded-ldap-core/src/test/java/org/zapodot/junit/ldap/internal/jndi/ContextProxyFactoryTest.java
similarity index 100%
rename from embedded-ldap-junit/src/test/java/org/zapodot/junit/ldap/internal/jndi/ContextProxyFactoryTest.java
rename to embedded-ldap-core/src/test/java/org/zapodot/junit/ldap/internal/jndi/ContextProxyFactoryTest.java
diff --git a/embedded-ldap-junit/src/test/java/org/zapodot/junit/ldap/internal/unboundid/LDAPInterfaceProxyFactoryTest.java b/embedded-ldap-core/src/test/java/org/zapodot/junit/ldap/internal/unboundid/LDAPInterfaceProxyFactoryTest.java
similarity index 100%
rename from embedded-ldap-junit/src/test/java/org/zapodot/junit/ldap/internal/unboundid/LDAPInterfaceProxyFactoryTest.java
rename to embedded-ldap-core/src/test/java/org/zapodot/junit/ldap/internal/unboundid/LDAPInterfaceProxyFactoryTest.java
diff --git a/embedded-ldap-core/src/test/resources/custom-schema.ldif b/embedded-ldap-core/src/test/resources/custom-schema.ldif
new file mode 100644
index 0000000..552eeca
--- /dev/null
+++ b/embedded-ldap-core/src/test/resources/custom-schema.ldif
@@ -0,0 +1,7 @@
+dn: cn=custom-schema
+objectClass: top
+objectClass: ldapSubEntry
+objectClass: subschema
+cn: custom-schema
+attributeTypes: ( 1.3.6.1.4.1.41609.1.75 NAME 'attribute' DESC 'A simple attribute' SUP name SINGLE-VALUE )
+objectClasses: ( 1.3.6.1.4.1.41609.2.13 NAME 'type' DESC 'A simple objectClass' SUP top STRUCTURAL MUST ( cn $ attribute ) MAY ( description ) )
diff --git a/embedded-ldap-core/src/test/resources/example.ldif b/embedded-ldap-core/src/test/resources/example.ldif
new file mode 100644
index 0000000..5eb286a
--- /dev/null
+++ b/embedded-ldap-core/src/test/resources/example.ldif
@@ -0,0 +1,28 @@
+version: 1
+
+dn: dc=zapodot,dc=org
+objectClass: domain
+objectClass: top
+dc: zapodot
+
+dn: ou=groups,dc=zapodot,dc=org
+objectclass: top
+objectclass: organizationalUnit
+ou: groups
+
+dn: ou=people,dc=zapodot,dc=org
+objectclass: top
+objectclass: organizationalUnit
+ou: people
+
+dn: cn=Sondre Eikanger Kvalo,ou=people,dc=zapodot,dc=org
+objectclass: top
+objectclass: person
+objectclass: organizationalPerson
+objectclass: inetOrgPerson
+uid: zapodot
+userPassword: password
+cn: Sondre Eikanger Kvalo
+cn:: U29uZHJlIEVpa2FuZ2VyIEt2YWzDuA==
+sn: Person
+description: Developer
\ No newline at end of file
diff --git a/embedded-ldap-core/src/test/resources/folder with space/example.ldif b/embedded-ldap-core/src/test/resources/folder with space/example.ldif
new file mode 100644
index 0000000..5eb286a
--- /dev/null
+++ b/embedded-ldap-core/src/test/resources/folder with space/example.ldif
@@ -0,0 +1,28 @@
+version: 1
+
+dn: dc=zapodot,dc=org
+objectClass: domain
+objectClass: top
+dc: zapodot
+
+dn: ou=groups,dc=zapodot,dc=org
+objectclass: top
+objectclass: organizationalUnit
+ou: groups
+
+dn: ou=people,dc=zapodot,dc=org
+objectclass: top
+objectclass: organizationalUnit
+ou: people
+
+dn: cn=Sondre Eikanger Kvalo,ou=people,dc=zapodot,dc=org
+objectclass: top
+objectclass: person
+objectclass: organizationalPerson
+objectclass: inetOrgPerson
+uid: zapodot
+userPassword: password
+cn: Sondre Eikanger Kvalo
+cn:: U29uZHJlIEVpa2FuZ2VyIEt2YWzDuA==
+sn: Person
+description: Developer
\ No newline at end of file
diff --git a/embedded-ldap-core/src/test/resources/folder/.placeholder b/embedded-ldap-core/src/test/resources/folder/.placeholder
new file mode 100644
index 0000000..e69de29
diff --git a/embedded-ldap-core/src/test/resources/invalid.ldif b/embedded-ldap-core/src/test/resources/invalid.ldif
new file mode 100644
index 0000000..bbd8c77
--- /dev/null
+++ b/embedded-ldap-core/src/test/resources/invalid.ldif
@@ -0,0 +1,2 @@
+zndskjnckjdsn
+daf
diff --git a/embedded-ldap-core/src/test/resources/standard-schema.ldif b/embedded-ldap-core/src/test/resources/standard-schema.ldif
new file mode 100644
index 0000000..063a7d8
--- /dev/null
+++ b/embedded-ldap-core/src/test/resources/standard-schema.ldif
@@ -0,0 +1,1546 @@
+# Retrieved from the UnboundID LDAP SDK repository http://sourceforge.net/p/ldap-sdk/code/HEAD/tree/trunk/resource/standard-schema.ldif
+# This file contains a set of standard schema definitions from various RFCs and
+# Internet Drafts. It is not intended to be a complete comprehensive schema
+# for all purposes, but it may be used by the LDAP SDK for cases in which
+# schema information may be required and no other definitions are available.
+#
+# Definitions in this class come from the following sources:
+# * RFC 2798:
+# Definition of the inetOrgPerson LDAP Object Class
+# * RFC 3045:
+# Storing Vendor Information in the LDAP Root DSE
+# * RFC 3112:
+# LDAP Authentication Password Schema
+# * RFC 3296:
+# Named Subordinate References in LDAP Directories
+# * RFC 4512:
+# LDAP Directory Information Models
+# * RFC 4519:
+# LDAP Schema for User Applications
+# * RFC 4523:
+# LDAP Schema Definitions for X.509 Certificates
+# * RFC 4524:
+# COSINE LDAP/X.500 Schema
+# * RFC 4530:
+# LDAP entryUUID Operational Attribute
+# * RFC 5020:
+# The LDAP entryDN Operational Attribute
+# * draft-good-ldap-changelog:
+# Definition of an Object Class to Hold LDAP Change Records
+# * draft-howard-namedobject:
+# A Structural Object Class for Arbitrary Auxiliary Object Classes
+# * draft-ietf-boreham-numsubordinates:
+# numSubordinates LDAP Operational Attribute
+# * draft-ietf-ldup-subentry:
+# LDAP Subentry Schema
+dn: cn=schema
+objectClass: top
+objectClass: ldapSubEntry
+objectClass: subschema
+cn: schema
+ldapSyntaxes: ( 1.3.6.1.4.1.1466.115.121.1.3
+ DESC 'Attribute Type Description'
+ X-ORIGIN 'RFC 4517' )
+ldapSyntaxes: ( 1.3.6.1.4.1.1466.115.121.1.6
+ DESC 'Bit String'
+ X-ORIGIN 'RFC 4517')
+ldapSyntaxes: ( 1.3.6.1.4.1.1466.115.121.1.7
+ DESC 'Boolean'
+ X-ORIGIN 'RFC 4517')
+ldapSyntaxes: ( 1.3.6.1.4.1.1466.115.121.1.11
+ DESC 'Country String'
+ X-ORIGIN 'RFC 4517')
+ldapSyntaxes: ( 1.3.6.1.4.1.1466.115.121.1.14
+ DESC 'Delivery Method'
+ X-ORIGIN 'RFC 4517')
+ldapSyntaxes: ( 1.3.6.1.4.1.1466.115.121.1.15
+ DESC 'Directory String'
+ X-ORIGIN 'RFC 4517')
+ldapSyntaxes: ( 1.3.6.1.4.1.1466.115.121.1.16
+ DESC 'DIT Content Rule Description'
+ X-ORIGIN 'RFC 4517')
+ldapSyntaxes: ( 1.3.6.1.4.1.1466.115.121.1.17
+ DESC 'DIT Structure Rule Description'
+ X-ORIGIN 'RFC 4517')
+ldapSyntaxes: ( 1.3.6.1.4.1.1466.115.121.1.12
+ DESC 'DN'
+ X-ORIGIN 'RFC 4517')
+ldapSyntaxes: ( 1.3.6.1.4.1.1466.115.121.1.21
+ DESC 'Enhanced Guide'
+ X-ORIGIN 'RFC 4517')
+ldapSyntaxes: ( 1.3.6.1.4.1.1466.115.121.1.22
+ DESC 'Facsimile Telephone Number'
+ X-ORIGIN 'RFC 4517')
+ldapSyntaxes: ( 1.3.6.1.4.1.1466.115.121.1.23
+ DESC 'Fax'
+ X-ORIGIN 'RFC 4517')
+ldapSyntaxes: ( 1.3.6.1.4.1.1466.115.121.1.24
+ DESC 'Generalized Time'
+ X-ORIGIN 'RFC 4517')
+ldapSyntaxes: ( 1.3.6.1.4.1.1466.115.121.1.25
+ DESC 'Guide'
+ X-ORIGIN 'RFC 4517')
+ldapSyntaxes: ( 1.3.6.1.4.1.1466.115.121.1.26
+ DESC 'IA5 String'
+ X-ORIGIN 'RFC 4517')
+ldapSyntaxes: ( 1.3.6.1.4.1.1466.115.121.1.27
+ DESC 'INTEGER'
+ X-ORIGIN 'RFC 4517')
+ldapSyntaxes: ( 1.3.6.1.4.1.1466.115.121.1.28
+ DESC 'JPEG'
+ X-ORIGIN 'RFC 4517')
+ldapSyntaxes: ( 1.3.6.1.4.1.1466.115.121.1.54
+ DESC 'LDAP Syntax Description'
+ X-ORIGIN 'RFC 4517')
+ldapSyntaxes: ( 1.3.6.1.4.1.1466.115.121.1.30
+ DESC 'Matching Rule Description'
+ X-ORIGIN 'RFC 4517')
+ldapSyntaxes: ( 1.3.6.1.4.1.1466.115.121.1.31
+ DESC 'Matching Rule Use Description'
+ X-ORIGIN 'RFC 4517')
+ldapSyntaxes: ( 1.3.6.1.4.1.1466.115.121.1.34
+ DESC 'Name And Optional UID'
+ X-ORIGIN 'RFC 4517')
+ldapSyntaxes: ( 1.3.6.1.4.1.1466.115.121.1.35
+ DESC 'Name Form Description'
+ X-ORIGIN 'RFC 4517')
+ldapSyntaxes: ( 1.3.6.1.4.1.1466.115.121.1.36
+ DESC 'Numeric String'
+ X-ORIGIN 'RFC 4517')
+ldapSyntaxes: ( 1.3.6.1.4.1.1466.115.121.1.37
+ DESC 'Object Class Description'
+ X-ORIGIN 'RFC 4517')
+ldapSyntaxes: ( 1.3.6.1.4.1.1466.115.121.1.40
+ DESC 'Octet String'
+ X-ORIGIN 'RFC 4517')
+ldapSyntaxes: ( 1.3.6.1.4.1.1466.115.121.1.38
+ DESC 'OID'
+ X-ORIGIN 'RFC 4517')
+ldapSyntaxes: ( 1.3.6.1.4.1.1466.115.121.1.39
+ DESC 'Other Mailbox'
+ X-ORIGIN 'RFC 4517')
+ldapSyntaxes: ( 1.3.6.1.4.1.1466.115.121.1.41
+ DESC 'Postal Address'
+ X-ORIGIN 'RFC 4517')
+ldapSyntaxes: ( 1.3.6.1.4.1.1466.115.121.1.44
+ DESC 'Printable String'
+ X-ORIGIN 'RFC 4517')
+ldapSyntaxes: ( 1.3.6.1.4.1.1466.115.121.1.58
+ DESC 'Substring Assertion'
+ X-ORIGIN 'RFC 4517')
+ldapSyntaxes: ( 1.3.6.1.4.1.1466.115.121.1.50
+ DESC 'Telephone Number'
+ X-ORIGIN 'RFC 4517')
+ldapSyntaxes: ( 1.3.6.1.4.1.1466.115.121.1.51
+ DESC 'Teletex Terminal Identifier'
+ X-ORIGIN 'RFC 4517')
+ldapSyntaxes: ( 1.3.6.1.4.1.1466.115.121.1.52
+ DESC 'Telex Number'
+ X-ORIGIN 'RFC 4517')
+ldapSyntaxes: ( 1.3.6.1.4.1.1466.115.121.1.53
+ DESC 'UTC Time'
+ X-ORIGIN 'RFC 4517')
+matchingRules: ( 2.5.13.16
+ NAME 'bitStringMatch'
+ SYNTAX 1.3.6.1.4.1.1466.115.121.1.6
+ X-ORIGIN 'RFC 4517' )
+matchingRules: ( 2.5.13.13
+ NAME 'booleanMatch'
+ SYNTAX 1.3.6.1.4.1.1466.115.121.1.7
+ X-ORIGIN 'RFC 4517' )
+matchingRules: ( 1.3.6.1.4.1.1466.109.114.1
+ NAME 'caseExactIA5Match'
+ SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
+ X-ORIGIN 'RFC 4517' )
+matchingRules: ( 2.5.13.5
+ NAME 'caseExactMatch'
+ SYNTAX 1.3.6.1.4.1.1466.115.121.1.15
+ X-ORIGIN 'RFC 4517' )
+matchingRules: ( 2.5.13.6
+ NAME 'caseExactOrderingMatch'
+ SYNTAX 1.3.6.1.4.1.1466.115.121.1.15
+ X-ORIGIN 'RFC 4517' )
+matchingRules: ( 2.5.13.7
+ NAME 'caseExactSubstringsMatch'
+ SYNTAX 1.3.6.1.4.1.1466.115.121.1.58
+ X-ORIGIN 'RFC 4517' )
+matchingRules: ( 1.3.6.1.4.1.1466.109.114.2
+ NAME 'caseIgnoreIA5Match'
+ SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
+ X-ORIGIN 'RFC 4517' )
+matchingRules: ( 1.3.6.1.4.1.1466.109.114.3
+ NAME 'caseIgnoreIA5SubstringsMatch'
+ SYNTAX 1.3.6.1.4.1.1466.115.121.1.58
+ X-ORIGIN 'RFC 4517' )
+matchingRules: ( 2.5.13.11
+ NAME 'caseIgnoreListMatch'
+ SYNTAX 1.3.6.1.4.1.1466.115.121.1.41
+ X-ORIGIN 'RFC 4517' )
+matchingRules: ( 2.5.13.12
+ NAME 'caseIgnoreListSubstringsMatch'
+ SYNTAX 1.3.6.1.4.1.1466.115.121.1.58
+ X-ORIGIN 'RFC 4517' )
+matchingRules: ( 2.5.13.2
+ NAME 'caseIgnoreMatch'
+ SYNTAX 1.3.6.1.4.1.1466.115.121.1.15
+ X-ORIGIN 'RFC 4517' )
+matchingRules: ( 2.5.13.3
+ NAME 'caseIgnoreOrderingMatch'
+ SYNTAX 1.3.6.1.4.1.1466.115.121.1.15
+ X-ORIGIN 'RFC 4517' )
+matchingRules: ( 2.5.13.4
+ NAME 'caseIgnoreSubstringsMatch'
+ SYNTAX 1.3.6.1.4.1.1466.115.121.1.58
+ X-ORIGIN 'RFC 4517' )
+matchingRules: ( 2.5.13.31
+ NAME 'directoryStringFirstComponentMatch'
+ SYNTAX 1.3.6.1.4.1.1466.115.121.1.15
+ X-ORIGIN 'RFC 4517' )
+matchingRules: ( 2.5.13.1
+ NAME 'distinguishedNameMatch'
+ SYNTAX 1.3.6.1.4.1.1466.115.121.1.12
+ X-ORIGIN 'RFC 4517' )
+matchingRules: ( 2.5.13.27
+ NAME 'generalizedTimeMatch'
+ SYNTAX 1.3.6.1.4.1.1466.115.121.1.24
+ X-ORIGIN 'RFC 4517' )
+matchingRules: ( 2.5.13.28
+ NAME 'generalizedTimeOrderingMatch'
+ SYNTAX 1.3.6.1.4.1.1466.115.121.1.24
+ X-ORIGIN 'RFC 4517' )
+matchingRules: ( 2.5.13.29
+ NAME 'integerFirstComponentMatch'
+ SYNTAX 1.3.6.1.4.1.1466.115.121.1.27
+ X-ORIGIN 'RFC 4517' )
+matchingRules: ( 2.5.13.14
+ NAME 'integerMatch'
+ SYNTAX 1.3.6.1.4.1.1466.115.121.1.27
+ X-ORIGIN 'RFC 4517' )
+matchingRules: ( 2.5.13.15
+ NAME 'integerOrderingMatch'
+ SYNTAX 1.3.6.1.4.1.1466.115.121.1.27
+ X-ORIGIN 'RFC 4517' )
+matchingRules: ( 2.5.13.33
+ NAME 'keywordMatch'
+ SYNTAX 1.3.6.1.4.1.1466.115.121.1.15
+ X-ORIGIN 'RFC 4517' )
+matchingRules: ( 2.5.13.8
+ NAME 'numericStringMatch'
+ SYNTAX 1.3.6.1.4.1.1466.115.121.1.36
+ X-ORIGIN 'RFC 4517' )
+matchingRules: ( 2.5.13.9
+ NAME 'numericStringOrderingMatch'
+ SYNTAX 1.3.6.1.4.1.1466.115.121.1.36
+ X-ORIGIN 'RFC 4517' )
+matchingRules: ( 2.5.13.10
+ NAME 'numericStringSubstringsMatch'
+ SYNTAX 1.3.6.1.4.1.1466.115.121.1.58
+ X-ORIGIN 'RFC 4517' )
+matchingRules: ( 2.5.13.30
+ NAME 'objectIdentifierFirstComponentMatch'
+ SYNTAX 1.3.6.1.4.1.1466.115.121.1.38
+ X-ORIGIN 'RFC 4517' )
+matchingRules: ( 2.5.13.0
+ NAME 'objectIdentifierMatch'
+ SYNTAX 1.3.6.1.4.1.1466.115.121.1.38
+ X-ORIGIN 'RFC 4517' )
+matchingRules: ( 2.5.13.17
+ NAME 'octetStringMatch'
+ SYNTAX 1.3.6.1.4.1.1466.115.121.1.40
+ X-ORIGIN 'RFC 4517' )
+matchingRules: ( 2.5.13.18
+ NAME 'octetStringOrderingMatch'
+ SYNTAX 1.3.6.1.4.1.1466.115.121.1.40
+ X-ORIGIN 'RFC 4517' )
+matchingRules: ( 2.5.13.20
+ NAME 'telephoneNumberMatch'
+ SYNTAX 1.3.6.1.4.1.1466.115.121.1.50
+ X-ORIGIN 'RFC 4517' )
+matchingRules: ( 2.5.13.21
+ NAME 'telephoneNumberSubstringsMatch'
+ SYNTAX 1.3.6.1.4.1.1466.115.121.1.58
+ X-ORIGIN 'RFC 4517' )
+matchingRules: ( 2.5.13.23
+ NAME 'uniqueMemberMatch'
+ SYNTAX 1.3.6.1.4.1.1466.115.121.1.34
+ X-ORIGIN 'RFC 4517' )
+matchingRules: ( 2.5.13.32
+ NAME 'wordMatch'
+ SYNTAX 1.3.6.1.4.1.1466.115.121.1.15
+ X-ORIGIN 'RFC 4517' )
+attributeTypes: ( 2.5.4.0
+ NAME 'objectClass'
+ EQUALITY objectIdentifierMatch
+ SYNTAX 1.3.6.1.4.1.1466.115.121.1.38
+ X-ORIGIN 'RFC 4512' )
+attributeTypes: ( 2.5.4.1
+ NAME 'aliasedObjectName'
+ EQUALITY distinguishedNameMatch
+ SYNTAX 1.3.6.1.4.1.1466.115.121.1.12
+ SINGLE-VALUE
+ X-ORIGIN 'RFC 4512' )
+attributeTypes: ( 2.5.18.3
+ NAME 'creatorsName'
+ EQUALITY distinguishedNameMatch
+ SYNTAX 1.3.6.1.4.1.1466.115.121.1.12
+ SINGLE-VALUE
+ NO-USER-MODIFICATION
+ USAGE directoryOperation
+ X-ORIGIN 'RFC 4512' )
+attributeTypes: ( 2.5.18.1
+ NAME 'createTimestamp'
+ EQUALITY generalizedTimeMatch
+ ORDERING generalizedTimeOrderingMatch
+ SYNTAX 1.3.6.1.4.1.1466.115.121.1.24
+ SINGLE-VALUE
+ NO-USER-MODIFICATION
+ USAGE directoryOperation
+ X-ORIGIN 'RFC 4512' )
+attributeTypes: ( 2.5.18.4
+ NAME 'modifiersName'
+ EQUALITY distinguishedNameMatch
+ SYNTAX 1.3.6.1.4.1.1466.115.121.1.12
+ SINGLE-VALUE
+ NO-USER-MODIFICATION
+ USAGE directoryOperation
+ X-ORIGIN 'RFC 4512' )
+attributeTypes: ( 2.5.18.2
+ NAME 'modifyTimestamp'
+ EQUALITY generalizedTimeMatch
+ ORDERING generalizedTimeOrderingMatch
+ SYNTAX 1.3.6.1.4.1.1466.115.121.1.24
+ SINGLE-VALUE
+ NO-USER-MODIFICATION
+ USAGE directoryOperation
+ X-ORIGIN 'RFC 4512' )
+attributeTypes: ( 2.5.21.9
+ NAME 'structuralObjectClass'
+ EQUALITY objectIdentifierMatch
+ SYNTAX 1.3.6.1.4.1.1466.115.121.1.38
+ SINGLE-VALUE
+ NO-USER-MODIFICATION
+ USAGE directoryOperation
+ X-ORIGIN 'RFC 4512' )
+attributeTypes: ( 2.5.21.10
+ NAME 'governingStructureRule'
+ EQUALITY integerMatch
+ SYNTAX 1.3.6.1.4.1.1466.115.121.1.27
+ SINGLE-VALUE
+ NO-USER-MODIFICATION
+ USAGE directoryOperation
+ X-ORIGIN 'RFC 4512' )
+attributeTypes: ( 2.5.18.10
+ NAME 'subschemaSubentry'
+ EQUALITY distinguishedNameMatch
+ SYNTAX 1.3.6.1.4.1.1466.115.121.1.12
+ SINGLE-VALUE
+ NO-USER-MODIFICATION
+ USAGE directoryOperation
+ X-ORIGIN 'RFC 4512' )
+attributeTypes: ( 2.5.21.6
+ NAME 'objectClasses'
+ EQUALITY objectIdentifierFirstComponentMatch
+ SYNTAX 1.3.6.1.4.1.1466.115.121.1.37
+ USAGE directoryOperation
+ X-ORIGIN 'RFC 4512' )
+attributeTypes: ( 2.5.21.5
+ NAME 'attributeTypes'
+ EQUALITY objectIdentifierFirstComponentMatch
+ SYNTAX 1.3.6.1.4.1.1466.115.121.1.3
+ USAGE directoryOperation
+ X-ORIGIN 'RFC 4512' )
+attributeTypes: ( 2.5.21.4
+ NAME 'matchingRules'
+ EQUALITY objectIdentifierFirstComponentMatch
+ SYNTAX 1.3.6.1.4.1.1466.115.121.1.30
+ USAGE directoryOperation
+ X-ORIGIN 'RFC 4512' )
+attributeTypes: ( 2.5.21.8
+ NAME 'matchingRuleUse'
+ EQUALITY objectIdentifierFirstComponentMatch
+ SYNTAX 1.3.6.1.4.1.1466.115.121.1.31
+ USAGE directoryOperation
+ X-ORIGIN 'RFC 4512' )
+attributeTypes: ( 1.3.6.1.4.1.1466.101.120.16
+ NAME 'ldapSyntaxes'
+ EQUALITY objectIdentifierFirstComponentMatch
+ SYNTAX 1.3.6.1.4.1.1466.115.121.1.54
+ USAGE directoryOperation
+ X-ORIGIN 'RFC 4512' )
+attributeTypes: ( 2.5.21.2
+ NAME 'dITContentRules'
+ EQUALITY objectIdentifierFirstComponentMatch
+ SYNTAX 1.3.6.1.4.1.1466.115.121.1.16
+ USAGE directoryOperation
+ X-ORIGIN 'RFC 4512' )
+attributeTypes: ( 2.5.21.1
+ NAME 'dITStructureRules'
+ EQUALITY integerFirstComponentMatch
+ SYNTAX 1.3.6.1.4.1.1466.115.121.1.17
+ USAGE directoryOperation
+ X-ORIGIN 'RFC 4512' )
+attributeTypes: ( 2.5.21.7
+ NAME 'nameForms'
+ EQUALITY objectIdentifierFirstComponentMatch
+ SYNTAX 1.3.6.1.4.1.1466.115.121.1.35
+ USAGE directoryOperation
+ X-ORIGIN 'RFC 4512' )
+attributeTypes: ( 1.3.6.1.4.1.1466.101.120.6
+ NAME 'altServer'
+ SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
+ USAGE dSAOperation
+ X-ORIGIN 'RFC 4512' )
+attributeTypes: ( 1.3.6.1.4.1.1466.101.120.5
+ NAME 'namingContexts'
+ SYNTAX 1.3.6.1.4.1.1466.115.121.1.12
+ USAGE dSAOperation
+ X-ORIGIN 'RFC 4512' )
+attributeTypes: ( 1.3.6.1.4.1.1466.101.120.13
+ NAME 'supportedControl'
+ SYNTAX 1.3.6.1.4.1.1466.115.121.1.38
+ USAGE dSAOperation
+ X-ORIGIN 'RFC 4512' )
+attributeTypes: ( 1.3.6.1.4.1.1466.101.120.7
+ NAME 'supportedExtension'
+ SYNTAX 1.3.6.1.4.1.1466.115.121.1.38
+ USAGE dSAOperation
+ X-ORIGIN 'RFC 4512' )
+attributeTypes: ( 1.3.6.1.4.1.4203.1.3.5
+ NAME 'supportedFeatures'
+ EQUALITY objectIdentifierMatch
+ SYNTAX 1.3.6.1.4.1.1466.115.121.1.38
+ USAGE dSAOperation
+ X-ORIGIN 'RFC 4512' )
+attributeTypes: ( 1.3.6.1.4.1.1466.101.120.15
+ NAME 'supportedLDAPVersion'
+ SYNTAX 1.3.6.1.4.1.1466.115.121.1.27
+ USAGE dSAOperation
+ X-ORIGIN 'RFC 4512' )
+attributeTypes: ( 1.3.6.1.4.1.1466.101.120.14
+ NAME 'supportedSASLMechanisms'
+ SYNTAX 1.3.6.1.4.1.1466.115.121.1.15
+ USAGE dSAOperation
+ X-ORIGIN 'RFC 4512' )
+attributeTypes: ( 2.5.4.41
+ NAME 'name'
+ EQUALITY caseIgnoreMatch
+ SUBSTR caseIgnoreSubstringsMatch
+ SYNTAX 1.3.6.1.4.1.1466.115.121.1.15
+ X-ORIGIN 'RFC 4519' )
+attributeTypes: ( 2.5.4.15
+ NAME 'businessCategory'
+ EQUALITY caseIgnoreMatch
+ SUBSTR caseIgnoreSubstringsMatch
+ SYNTAX 1.3.6.1.4.1.1466.115.121.1.15
+ X-ORIGIN 'RFC 4519' )
+attributeTypes: ( 2.5.4.6
+ NAME 'c'
+ SUP name
+ SYNTAX 1.3.6.1.4.1.1466.115.121.1.11
+ SINGLE-VALUE
+ X-ORIGIN 'RFC 4519' )
+attributeTypes: ( 2.5.4.3
+ NAME 'cn'
+ SUP name
+ X-ORIGIN 'RFC 4519' )
+attributeTypes: ( 0.9.2342.19200300.100.1.25
+ NAME 'dc'
+ EQUALITY caseIgnoreIA5Match
+ SUBSTR caseIgnoreIA5SubstringsMatch
+ SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
+ SINGLE-VALUE
+ X-ORIGIN 'RFC 4519' )
+attributeTypes: ( 2.5.4.13
+ NAME 'description'
+ EQUALITY caseIgnoreMatch
+ SUBSTR caseIgnoreSubstringsMatch
+ SYNTAX 1.3.6.1.4.1.1466.115.121.1.15
+ X-ORIGIN 'RFC 4519' )
+attributeTypes: ( 2.5.4.27
+ NAME 'destinationIndicator'
+ EQUALITY caseIgnoreMatch
+ SUBSTR caseIgnoreSubstringsMatch
+ SYNTAX 1.3.6.1.4.1.1466.115.121.1.44
+ X-ORIGIN 'RFC 4519' )
+attributeTypes: ( 2.5.4.49
+ NAME 'distinguishedName'
+ EQUALITY distinguishedNameMatch
+ SYNTAX 1.3.6.1.4.1.1466.115.121.1.12
+ X-ORIGIN 'RFC 4519' )
+attributeTypes: ( 2.5.4.46
+ NAME 'dnQualifier'
+ EQUALITY caseIgnoreMatch
+ ORDERING caseIgnoreOrderingMatch
+ SUBSTR caseIgnoreSubstringsMatch
+ SYNTAX 1.3.6.1.4.1.1466.115.121.1.44
+ X-ORIGIN 'RFC 4519' )
+attributeTypes: ( 2.5.4.47
+ NAME 'enhancedSearchGuide'
+ SYNTAX 1.3.6.1.4.1.1466.115.121.1.21
+ X-ORIGIN 'RFC 4519' )
+attributeTypes: ( 2.5.4.23
+ NAME 'facsimileTelephoneNumber'
+ SYNTAX 1.3.6.1.4.1.1466.115.121.1.22
+ X-ORIGIN 'RFC 4519' )
+attributeTypes: ( 2.5.4.44
+ NAME 'generationQualifier'
+ SUP name
+ X-ORIGIN 'RFC 4519' )
+attributeTypes: ( 2.5.4.42
+ NAME 'givenName'
+ SUP name
+ X-ORIGIN 'RFC 4519' )
+attributeTypes: ( 2.5.4.51
+ NAME 'houseIdentifier'
+ EQUALITY caseIgnoreMatch
+ SUBSTR caseIgnoreSubstringsMatch
+ SYNTAX 1.3.6.1.4.1.1466.115.121.1.15
+ X-ORIGIN 'RFC 4519' )
+attributeTypes: ( 2.5.4.43
+ NAME 'initials'
+ SUP name
+ X-ORIGIN 'RFC 4519' )
+attributeTypes: ( 2.5.4.25
+ NAME 'internationalISDNNumber'
+ EQUALITY numericStringMatch
+ SUBSTR numericStringSubstringsMatch
+ SYNTAX 1.3.6.1.4.1.1466.115.121.1.36
+ X-ORIGIN 'RFC 4519' )
+attributeTypes: ( 2.5.4.7
+ NAME 'l'
+ SUP name
+ X-ORIGIN 'RFC 4519' )
+attributeTypes: ( 2.5.4.31
+ NAME 'member'
+ SUP distinguishedName
+ X-ORIGIN 'RFC 4519' )
+attributeTypes: ( 2.5.4.10
+ NAME 'o'
+ SUP name
+ X-ORIGIN 'RFC 4519' )
+attributeTypes: ( 2.5.4.11
+ NAME 'ou'
+ SUP name
+ X-ORIGIN 'RFC 4519' )
+attributeTypes: ( 2.5.4.32
+ NAME 'owner'
+ SUP distinguishedName
+ X-ORIGIN 'RFC 4519' )
+attributeTypes: ( 2.5.4.19
+ NAME 'physicalDeliveryOfficeName'
+ EQUALITY caseIgnoreMatch
+ SUBSTR caseIgnoreSubstringsMatch
+ SYNTAX 1.3.6.1.4.1.1466.115.121.1.15
+ X-ORIGIN 'RFC 4519' )
+attributeTypes: ( 2.5.4.16
+ NAME 'postalAddress'
+ EQUALITY caseIgnoreListMatch
+ SUBSTR caseIgnoreListSubstringsMatch
+ SYNTAX 1.3.6.1.4.1.1466.115.121.1.41
+ X-ORIGIN 'RFC 4519' )
+attributeTypes: ( 2.5.4.17
+ NAME 'postalCode'
+ EQUALITY caseIgnoreMatch
+ SUBSTR caseIgnoreSubstringsMatch
+ SYNTAX 1.3.6.1.4.1.1466.115.121.1.15
+ X-ORIGIN 'RFC 4519' )
+attributeTypes: ( 2.5.4.18
+ NAME 'postOfficeBox'
+ EQUALITY caseIgnoreMatch
+ SUBSTR caseIgnoreSubstringsMatch
+ SYNTAX 1.3.6.1.4.1.1466.115.121.1.15
+ X-ORIGIN 'RFC 4519' )
+attributeTypes: ( 2.5.4.28
+ NAME 'preferredDeliveryMethod'
+ SYNTAX 1.3.6.1.4.1.1466.115.121.1.14
+ SINGLE-VALUE
+ X-ORIGIN 'RFC 4519' )
+attributeTypes: ( 2.5.4.26
+ NAME 'registeredAddress'
+ SUP postalAddress
+ SYNTAX 1.3.6.1.4.1.1466.115.121.1.41
+ X-ORIGIN 'RFC 4519' )
+attributeTypes: ( 2.5.4.33
+ NAME 'roleOccupant'
+ SUP distinguishedName
+ X-ORIGIN 'RFC 4519' )
+attributeTypes: ( 2.5.4.14
+ NAME 'searchGuide'
+ SYNTAX 1.3.6.1.4.1.1466.115.121.1.25
+ X-ORIGIN 'RFC 4519' )
+attributeTypes: ( 2.5.4.34
+ NAME 'seeAlso'
+ SUP distinguishedName
+ X-ORIGIN 'RFC 4519' )
+attributeTypes: ( 2.5.4.5
+ NAME 'serialNumber'
+ EQUALITY caseIgnoreMatch
+ SUBSTR caseIgnoreSubstringsMatch
+ SYNTAX 1.3.6.1.4.1.1466.115.121.1.44
+ X-ORIGIN 'RFC 4519' )
+attributeTypes: ( 2.5.4.4
+ NAME 'sn'
+ SUP name
+ X-ORIGIN 'RFC 4519' )
+attributeTypes: ( 2.5.4.8
+ NAME 'st'
+ SUP name
+ X-ORIGIN 'RFC 4519' )
+attributeTypes: ( 2.5.4.9
+ NAME 'street'
+ EQUALITY caseIgnoreMatch
+ SUBSTR caseIgnoreSubstringsMatch
+ SYNTAX 1.3.6.1.4.1.1466.115.121.1.15
+ X-ORIGIN 'RFC 4519' )
+attributeTypes: ( 2.5.4.20
+ NAME 'telephoneNumber'
+ EQUALITY telephoneNumberMatch
+ SUBSTR telephoneNumberSubstringsMatch
+ SYNTAX 1.3.6.1.4.1.1466.115.121.1.50
+ X-ORIGIN 'RFC 4519' )
+attributeTypes: ( 2.5.4.22
+ NAME 'teletexTerminalIdentifier'
+ SYNTAX 1.3.6.1.4.1.1466.115.121.1.51
+ X-ORIGIN 'RFC 4519' )
+attributeTypes: ( 2.5.4.21
+ NAME 'telexNumber'
+ SYNTAX 1.3.6.1.4.1.1466.115.121.1.52
+ X-ORIGIN 'RFC 4519' )
+attributeTypes: ( 2.5.4.12
+ NAME 'title'
+ SUP name
+ X-ORIGIN 'RFC 4519' )
+attributeTypes: ( 0.9.2342.19200300.100.1.1
+ NAME 'uid'
+ EQUALITY caseIgnoreMatch
+ SUBSTR caseIgnoreSubstringsMatch
+ SYNTAX 1.3.6.1.4.1.1466.115.121.1.15
+ X-ORIGIN 'RFC 4519' )
+attributeTypes: ( 2.5.4.50
+ NAME 'uniqueMember'
+ EQUALITY uniqueMemberMatch
+ SYNTAX 1.3.6.1.4.1.1466.115.121.1.34
+ X-ORIGIN 'RFC 4519' )
+attributeTypes: ( 2.5.4.35
+ NAME 'userPassword'
+ EQUALITY octetStringMatch
+ SYNTAX 1.3.6.1.4.1.1466.115.121.1.40
+ X-ORIGIN 'RFC 4519' )
+attributeTypes: ( 2.5.4.24
+ NAME 'x121Address'
+ EQUALITY numericStringMatch
+ SUBSTR numericStringSubstringsMatch
+ SYNTAX 1.3.6.1.4.1.1466.115.121.1.36
+ X-ORIGIN 'RFC 4519' )
+attributeTypes: ( 2.5.4.45
+ NAME 'x500UniqueIdentifier'
+ EQUALITY bitStringMatch
+ SYNTAX 1.3.6.1.4.1.1466.115.121.1.6
+ X-ORIGIN 'RFC 4519' )
+attributeTypes: ( 2.16.840.1.113730.3.1.1
+ NAME 'carLicense'
+ DESC 'vehicle license or registration plate'
+ EQUALITY caseIgnoreMatch
+ SUBSTR caseIgnoreSubstringsMatch
+ SYNTAX 1.3.6.1.4.1.1466.115.121.1.15
+ X-ORIGIN 'RFC 2798' )
+attributeTypes: ( 2.16.840.1.113730.3.1.2
+ NAME 'departmentNumber'
+ DESC 'identifies a department within an organization'
+ EQUALITY caseIgnoreMatch
+ SUBSTR caseIgnoreSubstringsMatch
+ SYNTAX 1.3.6.1.4.1.1466.115.121.1.15
+ X-ORIGIN 'RFC 2798' )
+attributeTypes: ( 2.16.840.1.113730.3.1.241
+ NAME 'displayName'
+ DESC 'preferred name of a person to be used when displaying entries'
+ EQUALITY caseIgnoreMatch
+ SUBSTR caseIgnoreSubstringsMatch
+ SYNTAX 1.3.6.1.4.1.1466.115.121.1.15
+ SINGLE-VALUE
+ X-ORIGIN 'RFC 2798' )
+attributeTypes: ( 2.16.840.1.113730.3.1.3
+ NAME 'employeeNumber'
+ DESC 'numerically identifies an employee within an organization'
+ EQUALITY caseIgnoreMatch
+ SUBSTR caseIgnoreSubstringsMatch
+ SYNTAX 1.3.6.1.4.1.1466.115.121.1.15
+ SINGLE-VALUE
+ X-ORIGIN 'RFC 2798' )
+attributeTypes: ( 2.16.840.1.113730.3.1.4
+ NAME 'employeeType'
+ DESC 'type of employment for a person'
+ EQUALITY caseIgnoreMatch
+ SUBSTR caseIgnoreSubstringsMatch
+ SYNTAX 1.3.6.1.4.1.1466.115.121.1.15
+ X-ORIGIN 'RFC 2798' )
+attributeTypes: ( 0.9.2342.19200300.100.1.60
+ NAME 'jpegPhoto'
+ DESC 'a JPEG image'
+ SYNTAX 1.3.6.1.4.1.1466.115.121.1.28
+ X-ORIGIN 'RFC 2798' )
+attributeTypes: ( 2.16.840.1.113730.3.1.39
+ NAME 'preferredLanguage'
+ DESC 'preferred written or spoken language for a person'
+ EQUALITY caseIgnoreMatch
+ SUBSTR caseIgnoreSubstringsMatch
+ SYNTAX 1.3.6.1.4.1.1466.115.121.1.15
+ SINGLE-VALUE
+ X-ORIGIN 'RFC 2798' )
+attributeTypes: ( 2.16.840.1.113730.3.1.40
+ NAME 'userSMIMECertificate'
+ DESC 'PKCS#7 SignedData used to support S/MIME'
+ SYNTAX 1.3.6.1.4.1.1466.115.121.1.5
+ X-ORIGIN 'RFC 2798' )
+attributeTypes: ( 2.16.840.1.113730.3.1.216
+ NAME 'userPKCS12'
+ DESC 'PKCS #12 PFX PDU for exchange of personal identity information'
+ SYNTAX 1.3.6.1.4.1.1466.115.121.1.5
+ X-ORIGIN 'RFC 2798' )
+attributeTypes: ( 2.5.4.36
+ NAME 'userCertificate'
+ DESC 'X.509 user certificate'
+ EQUALITY certificateExactMatch
+ SYNTAX 1.3.6.1.4.1.1466.115.121.1.8
+ X-ORIGIN 'RFC 4523' )
+attributeTypes: ( 2.5.4.37
+ NAME 'cACertificate'
+ DESC 'X.509 CA certificate'
+ EQUALITY certificateExactMatch
+ SYNTAX 1.3.6.1.4.1.1466.115.121.1.8
+ X-ORIGIN 'RFC 4523' )
+attributeTypes: ( 2.5.4.40
+ NAME 'crossCertificatePair'
+ DESC 'X.509 cross certificate pair'
+ EQUALITY certificatePairExactMatch
+ SYNTAX 1.3.6.1.4.1.1466.115.121.1.10
+ X-ORIGIN 'RFC 4523' )
+attributeTypes: ( 2.5.4.39
+ NAME 'certificateRevocationList'
+ DESC 'X.509 certificate revocation list'
+ EQUALITY certificateListExactMatch
+ SYNTAX 1.3.6.1.4.1.1466.115.121.1.9
+ X-ORIGIN 'RFC 4523' )
+attributeTypes: ( 2.5.4.38
+ NAME 'authorityRevocationList'
+ DESC 'X.509 authority revocation list'
+ EQUALITY certificateListExactMatch
+ SYNTAX 1.3.6.1.4.1.1466.115.121.1.9
+ X-ORIGIN 'RFC 4523' )
+attributeTypes: ( 2.5.4.53
+ NAME 'deltaRevocationList'
+ DESC 'X.509 delta revocation list'
+ EQUALITY certificateListExactMatch
+ SYNTAX 1.3.6.1.4.1.1466.115.121.1.9
+ X-ORIGIN 'RFC 4523' )
+attributeTypes: ( 2.5.4.52
+ NAME 'supportedAlgorithms'
+ DESC 'X.509 supported algorithms'
+ EQUALITY algorithmIdentifierMatch
+ SYNTAX 1.3.6.1.4.1.1466.115.121.1.49
+ X-ORIGIN 'RFC 4523' )
+attributeTypes: ( 0.9.2342.19200300.100.1.37
+ NAME 'associatedDomain'
+ EQUALITY caseIgnoreIA5Match
+ SUBSTR caseIgnoreIA5SubstringsMatch
+ SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
+ X-ORIGIN 'RFC 4524' )
+attributeTypes: ( 0.9.2342.19200300.100.1.38
+ NAME 'associatedName'
+ EQUALITY distinguishedNameMatch
+ SYNTAX 1.3.6.1.4.1.1466.115.121.1.12
+ X-ORIGIN 'RFC 4524' )
+attributeTypes: ( 0.9.2342.19200300.100.1.48
+ NAME 'buildingName'
+ EQUALITY caseIgnoreMatch
+ SUBSTR caseIgnoreSubstringsMatch
+ SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{256}
+ X-ORIGIN 'RFC 4524' )
+attributeTypes: ( 0.9.2342.19200300.100.1.43
+ NAME 'co'
+ EQUALITY caseIgnoreMatch
+ SUBSTR caseIgnoreSubstringsMatch
+ SYNTAX 1.3.6.1.4.1.1466.115.121.1.15
+ X-ORIGIN 'RFC 4524' )
+attributeTypes: ( 0.9.2342.19200300.100.1.14
+ NAME 'documentAuthor'
+ EQUALITY distinguishedNameMatch
+ SYNTAX 1.3.6.1.4.1.1466.115.121.1.12
+ X-ORIGIN 'RFC 4524' )
+attributeTypes: ( 0.9.2342.19200300.100.1.11
+ NAME 'documentIdentifier'
+ EQUALITY caseIgnoreMatch
+ SUBSTR caseIgnoreSubstringsMatch
+ SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{256}
+ X-ORIGIN 'RFC 4524' )
+attributeTypes: ( 0.9.2342.19200300.100.1.15
+ NAME 'documentLocation'
+ EQUALITY caseIgnoreMatch
+ SUBSTR caseIgnoreSubstringsMatch
+ SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{256}
+ X-ORIGIN 'RFC 4524' )
+attributeTypes: ( 0.9.2342.19200300.100.1.56
+ NAME 'documentPublisher'
+ EQUALITY caseIgnoreMatch
+ SUBSTR caseIgnoreSubstringsMatch
+ SYNTAX 1.3.6.1.4.1.1466.115.121.1.15
+ X-ORIGIN 'RFC 4524' )
+attributeTypes: ( 0.9.2342.19200300.100.1.12
+ NAME 'documentTitle'
+ EQUALITY caseIgnoreMatch
+ SUBSTR caseIgnoreSubstringsMatch
+ SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{256}
+ X-ORIGIN 'RFC 4524' )
+attributeTypes: ( 0.9.2342.19200300.100.1.13
+ NAME 'documentVersion'
+ EQUALITY caseIgnoreMatch
+ SUBSTR caseIgnoreSubstringsMatch
+ SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{256}
+ X-ORIGIN 'RFC 4524' )
+attributeTypes: ( 0.9.2342.19200300.100.1.5
+ NAME 'drink'
+ EQUALITY caseIgnoreMatch
+ SUBSTR caseIgnoreSubstringsMatch
+ SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{256}
+ X-ORIGIN 'RFC 4524' )
+attributeTypes: ( 0.9.2342.19200300.100.1.20
+ NAME 'homePhone'
+ EQUALITY telephoneNumberMatch
+ SUBSTR telephoneNumberSubstringsMatch
+ SYNTAX 1.3.6.1.4.1.1466.115.121.1.50
+ X-ORIGIN 'RFC 4524' )
+attributeTypes: ( 0.9.2342.19200300.100.1.39
+ NAME 'homePostalAddress'
+ EQUALITY caseIgnoreListMatch
+ SUBSTR caseIgnoreListSubstringsMatch
+ SYNTAX 1.3.6.1.4.1.1466.115.121.1.41
+ X-ORIGIN 'RFC 4524' )
+attributeTypes: ( 0.9.2342.19200300.100.1.9
+ NAME 'host'
+ EQUALITY caseIgnoreMatch
+ SUBSTR caseIgnoreSubstringsMatch
+ SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{256}
+ X-ORIGIN 'RFC 4524' )
+attributeTypes: ( 0.9.2342.19200300.100.1.4
+ NAME 'info'
+ EQUALITY caseIgnoreMatch
+ SUBSTR caseIgnoreSubstringsMatch
+ SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{2048}
+ X-ORIGIN 'RFC 4524' )
+attributeTypes: ( 0.9.2342.19200300.100.1.3
+ NAME 'mail'
+ EQUALITY caseIgnoreIA5Match
+ SUBSTR caseIgnoreIA5SubstringsMatch
+ SYNTAX 1.3.6.1.4.1.1466.115.121.1.26{256}
+ X-ORIGIN 'RFC 4524' )
+attributeTypes: ( 0.9.2342.19200300.100.1.10
+ NAME 'manager'
+ EQUALITY distinguishedNameMatch
+ SYNTAX 1.3.6.1.4.1.1466.115.121.1.12
+ X-ORIGIN 'RFC 4524' )
+attributeTypes: ( 0.9.2342.19200300.100.1.41
+ NAME 'mobile'
+ EQUALITY telephoneNumberMatch
+ SUBSTR telephoneNumberSubstringsMatch
+ SYNTAX 1.3.6.1.4.1.1466.115.121.1.50
+ X-ORIGIN 'RFC 4524' )
+attributeTypes: ( 0.9.2342.19200300.100.1.45
+ NAME 'organizationalStatus'
+ EQUALITY caseIgnoreMatch
+ SUBSTR caseIgnoreSubstringsMatch
+ SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{256}
+ X-ORIGIN 'RFC 4524' )
+attributeTypes: ( 0.9.2342.19200300.100.1.42
+ NAME 'pager'
+ EQUALITY telephoneNumberMatch
+ SUBSTR telephoneNumberSubstringsMatch
+ SYNTAX 1.3.6.1.4.1.1466.115.121.1.50
+ X-ORIGIN 'RFC 4524' )
+attributeTypes: ( 0.9.2342.19200300.100.1.40
+ NAME 'personalTitle'
+ EQUALITY caseIgnoreMatch
+ SUBSTR caseIgnoreSubstringsMatch
+ SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{256}
+ X-ORIGIN 'RFC 4524' )
+attributeTypes: ( 0.9.2342.19200300.100.1.6
+ NAME 'roomNumber'
+ EQUALITY caseIgnoreMatch
+ SUBSTR caseIgnoreSubstringsMatch
+ SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{256}
+ X-ORIGIN 'RFC 4524' )
+attributeTypes: ( 0.9.2342.19200300.100.1.21
+ NAME 'secretary'
+ EQUALITY distinguishedNameMatch
+ SYNTAX 1.3.6.1.4.1.1466.115.121.1.12
+ X-ORIGIN 'RFC 4524' )
+attributeTypes: ( 0.9.2342.19200300.100.1.44
+ NAME 'uniqueIdentifier'
+ EQUALITY caseIgnoreMatch
+ SUBSTR caseIgnoreSubstringsMatch
+ SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{256}
+ X-ORIGIN 'RFC 4524' )
+attributeTypes: ( 0.9.2342.19200300.100.1.8
+ NAME 'userClass'
+ EQUALITY caseIgnoreMatch
+ SUBSTR caseIgnoreSubstringsMatch
+ SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{256}
+ X-ORIGIN 'RFC 4524' )
+attributeTypes: ( 0.9.2342.19200300.100.1.55
+ NAME 'audio'
+ EQUALITY octetStringMatch
+ SYNTAX 1.3.6.1.4.1.1466.115.121.1.40{250000}
+ X-ORIGIN 'RFC 2798' )
+attributeTypes: ( 0.9.2342.19200300.100.1.7
+ NAME 'photo'
+ X-ORIGIN 'RFC 2798' )
+attributeTypes: ( 1.3.6.1.4.1.250.1.57
+ NAME 'labeledURI'
+ EQUALITY caseExactMatch
+ SUBSTR caseExactSubstringsMatch
+ SYNTAX 1.3.6.1.4.1.1466.115.121.1.15
+ X-ORIGIN 'RFC 2798' )
+attributeTypes: ( 1.3.6.1.1.20
+ NAME 'entryDN'
+ DESC 'DN of the entry'
+ EQUALITY distinguishedNameMatch
+ SYNTAX 1.3.6.1.4.1.1466.115.121.1.12
+ SINGLE-VALUE
+ NO-USER-MODIFICATION
+ USAGE directoryOperation
+ X-ORIGIN 'RFC 5020' )
+attributeTypes: ( 2.16.840.1.113730.3.1.34
+ NAME 'ref'
+ DESC 'named reference - a labeledURI'
+ EQUALITY caseExactMatch
+ SYNTAX 1.3.6.1.4.1.1466.115.121.1.15
+ USAGE distributedOperation
+ X-ORIGIN 'RFC 3296' )
+attributeTypes: ( 1.3.6.1.1.4
+ NAME 'vendorName'
+ EQUALITY 1.3.6.1.4.1.1466.109.114.1
+ SYNTAX 1.3.6.1.4.1.1466.115.121.1.15
+ SINGLE-VALUE
+ NO-USER-MODIFICATION
+ USAGE dSAOperation
+ X-ORIGIN 'RFC 3045' )
+attributeTypes: ( 1.3.6.1.1.5
+ NAME 'vendorVersion'
+ EQUALITY 1.3.6.1.4.1.1466.109.114.1
+ SYNTAX 1.3.6.1.4.1.1466.115.121.1.15
+ SINGLE-VALUE
+ NO-USER-MODIFICATION
+ USAGE dSAOperation
+ X-ORIGIN 'RFC 3045' )
+attributeTypes: ( 1.3.6.1.1.16.4
+ NAME 'entryUUID'
+ DESC 'UUID of the entry'
+ EQUALITY uuidMatch
+ ORDERING uuidOrderingMatch
+ SYNTAX 1.3.6.1.1.16.1
+ SINGLE-VALUE
+ NO-USER-MODIFICATION
+ USAGE directoryOperation
+ X-ORIGIN 'RFC 4530' )
+attributeTypes: ( 1.3.6.1.4.1.453.16.2.103
+ NAME 'numSubordinates'
+ DESC 'count of immediate subordinates'
+ EQUALITY integerMatch
+ ORDERING integerOrderingMatch
+ SYNTAX 1.3.6.1.4.1.453.16.2.103
+ SINGLE-VALUE
+ NO-USER-MODIFICATION
+ USAGE directoryOperation
+ X-ORIGIN 'draft-ietf-boreham-numsubordinates' )
+attributeTypes: ( 1.3.6.1.4.1.7628.5.4.1
+ NAME 'inheritable'
+ SYNTAX BOOLEAN
+ SINGLE-VALUE
+ NO-USER-MODIFICATION
+ USAGE dSAOperation
+ X-ORIGIN 'draft-ietf-ldup-subentry' )
+attributeTypes: ( 1.3.6.1.4.1.7628.5.4.2
+ NAME 'blockInheritance'
+ SYNTAX BOOLEAN
+ SINGLE-VALUE
+ NO-USER-MODIFICATION
+ USAGE dSAOperation
+ X-ORIGIN 'draft-ietf-ldup-subentry' )
+attributeTypes: ( 2.16.840.1.113730.3.1.5
+ NAME 'changeNumber'
+ DESC 'a number which uniquely identifies a change made to a directory entry'
+ SYNTAX 1.3.6.1.4.1.1466.115.121.1.27
+ EQUALITY integerMatch
+ ORDERING integerOrderingMatch
+ SINGLE-VALUE
+ X-ORIGIN 'draft-good-ldap-changelog' )
+attributeTypes: ( 2.16.840.1.113730.3.1.6
+ NAME 'targetDN'
+ DESC 'the DN of the entry which was modified'
+ EQUALITY distinguishedNameMatch
+ SYNTAX 1.3.6.1.4.1.1466.115.121.1.12
+ SINGLE-VALUE
+ X-ORIGIN 'draft-good-ldap-changelog' )
+attributeTypes: ( 2.16.840.1.113730.3.1.7
+ NAME 'changeType'
+ DESC 'the type of change made to an entry'
+ EQUALITY caseIgnoreMatch
+ SYNTAX 1.3.6.1.4.1.1466.115.121.1.15
+ SINGLE-VALUE
+ X-ORIGIN 'draft-good-ldap-changelog' )
+attributeTypes: ( 2.16.840.1.113730.3.1.8
+ NAME 'changes'
+ DESC 'a set of changes to apply to an entry'
+ SYNTAX 1.3.6.1.4.1.1466.115.121.1.40
+ X-ORIGIN 'draft-good-ldap-changelog' )
+attributeTypes: ( 2.16.840.1.113730.3.1.9
+ NAME 'newRDN'
+ DESC 'the new RDN of an entry which is the target of a modrdn operation'
+ EQUALITY distinguishedNameMatch
+ SYNTAX 1.3.6.1.4.1.1466.115.121.1.12
+ SINGLE-VALUE
+ X-ORIGIN 'draft-good-ldap-changelog' )
+attributeTypes: ( 2.16.840.1.113730.3.1.10
+ NAME 'deleteOldRDN'
+ DESC 'a flag which indicates if the old RDN should be retained as an
+ attribute of the entry'
+ EQUALITY booleanMatch
+ SYNTAX 1.3.6.1.4.1.1466.115.121.1.7
+ SINGLE-VALUE
+ X-ORIGIN 'draft-good-ldap-changelog' )
+attributeTypes: ( 2.16.840.1.113730.3.1.11
+ NAME 'newSuperior'
+ DESC 'the new parent of an entry which is the target of a moddn operation'
+ EQUALITY distinguishedNameMatch
+ SYNTAX 1.3.6.1.4.1.1466.115.121.1.12
+ SINGLE-VALUE
+ X-ORIGIN 'draft-good-ldap-changelog' )
+attributeTypes: ( 2.16.840.1.113730.3.1.35
+ NAME 'changelog'
+ DESC 'the distinguished name of the entry which contains the set of entries
+ comprising the server changelog'
+ EQUALITY distinguishedNameMatch
+ SYNTAX 1.3.6.1.4.1.1466.115.121.1.12
+ X-ORIGIN 'draft-good-ldap-changelog' )
+attributeTypes: ( 1.3.6.1.4.1.4203.1.3.3
+ NAME 'supportedAuthPasswordSchemes'
+ DESC 'supported password storage schemes'
+ EQUALITY caseExactIA5Match
+ SYNTAX 1.3.6.1.4.1.1466.115.121.1.26{32}
+ USAGE dSAOperation
+ X-ORIGIN 'RFC 3112' )
+attributeTypes: ( 1.3.6.1.4.1.4203.1.3.4
+ NAME 'authPassword'
+ DESC 'password authentication information'
+ EQUALITY 1.3.6.1.4.1.4203.1.2.2
+ SYNTAX 1.3.6.1.4.1.4203.1.1.2
+ X-ORIGIN 'RFC 3112' )
+attributeTypes: ( 2.16.840.1.113730.3.1.55
+ NAME 'aci'
+ SYNTAX 1.3.6.1.4.1.1466.115.121.1.15
+ USAGE directoryOperation
+ X-ORIGIN 'De facto standard' )
+objectClasses: ( 2.5.6.0
+ NAME 'top'
+ ABSTRACT
+ MUST objectClass
+ X-ORIGIN 'RFC 4512' )
+objectClasses: ( 2.5.6.1
+ NAME 'alias'
+ SUP top
+ STRUCTURAL
+ MUST aliasedObjectName
+ X-ORIGIN 'RFC 4512' )
+objectClasses: ( 1.3.6.1.4.1.1466.101.120.111
+ NAME 'extensibleObject'
+ SUP top
+ AUXILIARY
+ X-ORIGIN 'RFC 4512' )
+objectClasses: ( 2.5.20.1
+ NAME 'subschema'
+ AUXILIARY
+ MAY ( dITStructureRules $
+ nameForms $
+ ditContentRules $
+ objectClasses $
+ attributeTypes $
+ matchingRules $
+ matchingRuleUse )
+ X-ORIGIN 'RFC 4512' )
+objectClasses: ( 2.5.6.11
+ NAME 'applicationProcess'
+ SUP top
+ STRUCTURAL
+ MUST cn
+ MAY ( seeAlso $
+ ou $
+ l $
+ description )
+ X-ORIGIN 'RFC 4519' )
+objectClasses: ( 2.5.6.2
+ NAME 'country'
+ SUP top
+ STRUCTURAL
+ MUST c
+ MAY ( searchGuide $
+ description )
+ X-ORIGIN 'RFC 4519' )
+objectClasses: ( 1.3.6.1.4.1.1466.344
+ NAME 'dcObject'
+ SUP top
+ AUXILIARY
+ MUST dc
+ X-ORIGIN 'RFC 4519' )
+objectClasses: ( 2.5.6.14
+ NAME 'device'
+ SUP top
+ STRUCTURAL
+ MUST cn
+ MAY ( serialNumber $
+ seeAlso $
+ owner $
+ ou $
+ o $
+ l $
+ description )
+ X-ORIGIN 'RFC 4519' )
+objectClasses: ( 2.5.6.9
+ NAME 'groupOfNames'
+ SUP top
+ STRUCTURAL
+ MUST cn
+ MAY ( member $
+ businessCategory $
+ seeAlso $
+ owner $
+ ou $
+ o $
+ description )
+ X-ORIGIN 'RFC 4519' )
+objectClasses: ( 2.5.6.17
+ NAME 'groupOfUniqueNames'
+ SUP top
+ STRUCTURAL
+ MUST cn
+ MAY ( uniqueMember $
+ businessCategory $
+ seeAlso $
+ owner $
+ ou $
+ o $
+ description )
+ X-ORIGIN 'RFC 4519' )
+objectClasses: ( 2.5.6.3
+ NAME 'locality'
+ SUP top
+ STRUCTURAL
+ MAY ( street $
+ seeAlso $
+ searchGuide $
+ st $
+ l $
+ description )
+ X-ORIGIN 'RFC 4519' )
+objectClasses: ( 2.5.6.4
+ NAME 'organization'
+ SUP top
+ STRUCTURAL
+ MUST o
+ MAY ( userPassword $
+ searchGuide $
+ seeAlso $
+ businessCategory $
+ x121Address $
+ registeredAddress $
+ destinationIndicator $
+ preferredDeliveryMethod $
+ telexNumber $
+ teletexTerminalIdentifier $
+ telephoneNumber $
+ internationalISDNNumber $
+ facsimileTelephoneNumber $
+ street $
+ postOfficeBox $
+ postalCode $
+ postalAddress $
+ physicalDeliveryOfficeName $
+ st $
+ l $
+ description )
+ X-ORIGIN 'RFC 4519' )
+objectClasses: ( 2.5.6.6
+ NAME 'person'
+ SUP top
+ STRUCTURAL
+ MUST ( sn $
+ cn )
+ MAY ( userPassword $
+ telephoneNumber $
+ seeAlso $
+ description )
+ X-ORIGIN 'RFC 4519' )
+objectClasses: ( 2.5.6.7
+ NAME 'organizationalPerson'
+ SUP person
+ STRUCTURAL
+ MAY ( title $
+ x121Address $
+ registeredAddress $
+ destinationIndicator $
+ preferredDeliveryMethod $
+ telexNumber $
+ teletexTerminalIdentifier $
+ telephoneNumber $
+ internationalISDNNumber $
+ facsimileTelephoneNumber $
+ street $
+ postOfficeBox $
+ postalCode $
+ postalAddress $
+ physicalDeliveryOfficeName $
+ ou $
+ st $
+ l )
+ X-ORIGIN 'RFC 4519' )
+objectClasses: ( 2.5.6.8
+ NAME 'organizationalRole'
+ SUP top
+ STRUCTURAL
+ MUST cn
+ MAY ( x121Address $
+ registeredAddress $
+ destinationIndicator $
+ preferredDeliveryMethod $
+ telexNumber $
+ teletexTerminalIdentifier $
+ telephoneNumber $
+ internationalISDNNumber $
+ facsimileTelephoneNumber $
+ seeAlso $
+ roleOccupant $
+ preferredDeliveryMethod $
+ street $
+ postOfficeBox $
+ postalCode $
+ postalAddress $
+ physicalDeliveryOfficeName $
+ ou $
+ st $
+ l $
+ description )
+ X-ORIGIN 'RFC 4519' )
+objectClasses: ( 2.5.6.5
+ NAME 'organizationalUnit'
+ SUP top
+ STRUCTURAL
+ MUST ou
+ MAY ( businessCategory $
+ description $
+ destinationIndicator $
+ facsimileTelephoneNumber $
+ internationalISDNNumber $
+ l $
+ physicalDeliveryOfficeName $
+ postalAddress $
+ postalCode $
+ postOfficeBox $
+ preferredDeliveryMethod $
+ registeredAddress $
+ searchGuide $
+ seeAlso $
+ st $
+ street $
+ telephoneNumber $
+ teletexTerminalIdentifier $
+ telexNumber $
+ userPassword $
+ x121Address )
+ X-ORIGIN 'RFC 4519' )
+objectClasses: ( 2.5.6.10
+ NAME 'residentialPerson'
+ SUP person
+ STRUCTURAL
+ MUST l
+ MAY ( businessCategory $
+ x121Address $
+ registeredAddress $
+ destinationIndicator $
+ preferredDeliveryMethod $
+ telexNumber $
+ teletexTerminalIdentifier $
+ telephoneNumber $
+ internationalISDNNumber $
+ facsimileTelephoneNumber $
+ preferredDeliveryMethod $
+ street $
+ postOfficeBox $
+ postalCode $
+ postalAddress $
+ physicalDeliveryOfficeName $
+ st $
+ l )
+ X-ORIGIN 'RFC 4519' )
+objectClasses: ( 1.3.6.1.1.3.1
+ NAME 'uidObject'
+ SUP top
+ AUXILIARY
+ MUST uid
+ X-ORIGIN 'RFC 4519' )
+objectClasses: ( 2.16.840.1.113730.3.2.2
+ NAME 'inetOrgPerson'
+ SUP organizationalPerson
+ STRUCTURAL
+ MAY ( audio $
+ businessCategory $
+ carLicense $
+ departmentNumber $
+ displayName $
+ employeeNumber $
+ employeeType $
+ givenName $
+ homePhone $
+ homePostalAddress $
+ initials $
+ jpegPhoto $
+ labeledURI $
+ mail $
+ manager $
+ mobile $
+ o $
+ pager $
+ photo $
+ roomNumber $
+ secretary $
+ uid $
+ userCertificate $
+ x500uniqueIdentifier $
+ preferredLanguage $
+ userSMIMECertificate $
+ userPKCS12 )
+ X-ORIGIN 'RFC 2798' )
+objectClasses: ( 2.5.6.21
+ NAME 'pkiUser'
+ DESC 'X.509 PKI User'
+ SUP top AUXILIARY
+ MAY userCertificate
+ X-ORIGIN 'RFC 4523' )
+objectClasses: ( 2.5.6.22
+ NAME 'pkiCA'
+ DESC 'X.509 PKI Certificate Authority'
+ SUP top
+ AUXILIARY
+ MAY ( cACertificate $
+ certificateRevocationList $
+ authorityRevocationList $
+ crossCertificatePair )
+ X-ORIGIN 'RFC 4523' )
+objectClasses: ( 2.5.6.19
+ NAME 'cRLDistributionPoint'
+ DESC 'X.509 CRL distribution point'
+ SUP top
+ STRUCTURAL
+ MUST cn
+ MAY ( certificateRevocationList $
+ authorityRevocationList $
+ deltaRevocationList )
+ X-ORIGIN 'RFC 4523' )
+objectClasses: ( 2.5.6.23
+ NAME 'deltaCRL'
+ DESC 'X.509 delta CRL'
+ SUP top
+ AUXILIARY
+ MAY deltaRevocationList
+ X-ORIGIN 'RFC 4523' )
+objectClasses: ( 2.5.6.15
+ NAME 'strongAuthenticationUser'
+ DESC 'X.521 strong authentication user'
+ SUP top
+ AUXILIARY
+ MUST userCertificate
+ X-ORIGIN 'RFC 4523' )
+objectClasses: ( 2.5.6.18
+ NAME 'userSecurityInformation'
+ DESC 'X.521 user security information'
+ SUP top
+ AUXILIARY
+ MAY ( supportedAlgorithms )
+ X-ORIGIN 'RFC 4523' )
+objectClasses: ( 2.5.6.16
+ NAME 'certificationAuthority'
+ DESC 'X.509 certificate authority'
+ SUP top
+ AUXILIARY
+ MUST ( authorityRevocationList $
+ certificateRevocationList $
+ cACertificate )
+ MAY crossCertificatePair
+ X-ORIGIN 'RFC 4523' )
+objectClasses: ( 2.5.6.16.2
+ NAME 'certificationAuthority-V2'
+ DESC 'X.509 certificate authority, version 2'
+ SUP certificationAuthority
+ AUXILIARY
+ MAY deltaRevocationList
+ X-ORIGIN 'RFC 4523' )
+objectClasses: ( 0.9.2342.19200300.100.4.5
+ NAME 'account'
+ SUP top STRUCTURAL
+ MUST uid
+ MAY ( description $
+ seeAlso $
+ l $
+ o $
+ ou $
+ host )
+ X-ORIGIN 'RFC 4524' )
+objectClasses: ( 0.9.2342.19200300.100.4.6
+ NAME 'document'
+ SUP top STRUCTURAL
+ MUST documentIdentifier
+ MAY ( cn $
+ description $
+ seeAlso $
+ l $
+ o $
+ ou $
+ documentTitle $
+ documentVersion $
+ documentAuthor $
+ documentLocation $
+ documentPublisher )
+ X-ORIGIN 'RFC 4524' )
+objectClasses: ( 0.9.2342.19200300.100.4.9
+ NAME 'documentSeries'
+ SUP top STRUCTURAL
+ MUST cn
+ MAY ( description $
+ l $
+ o $
+ ou $
+ seeAlso $
+ telephonenumber )
+ X-ORIGIN 'RFC 4524' )
+objectClasses: ( 0.9.2342.19200300.100.4.13
+ NAME 'domain'
+ SUP top
+ STRUCTURAL
+ MUST dc
+ MAY ( userPassword $
+ searchGuide $
+ seeAlso $
+ businessCategory $
+ x121Address $
+ registeredAddress $
+ destinationIndicator $
+ preferredDeliveryMethod $
+ telexNumber $
+ teletexTerminalIdentifier $
+ telephoneNumber $
+ internationaliSDNNumber $
+ facsimileTelephoneNumber $
+ street $
+ postOfficeBox $
+ postalCode $
+ postalAddress $
+ physicalDeliveryOfficeName $
+ st $
+ l $
+ description $
+ o $
+ associatedName )
+ X-ORIGIN 'RFC 4524' )
+objectClasses: ( 0.9.2342.19200300.100.4.17
+ NAME 'domainRelatedObject'
+ SUP top
+ AUXILIARY
+ MUST associatedDomain
+ X-ORIGIN 'RFC 4524' )
+objectClasses: ( 0.9.2342.19200300.100.4.18
+ NAME 'friendlyCountry'
+ SUP country
+ STRUCTURAL
+ MUST co
+ X-ORIGIN 'RFC 4524' )
+objectClasses: ( 0.9.2342.19200300.100.4.14
+ NAME 'rFC822localPart'
+ SUP domain
+ STRUCTURAL
+ MAY ( cn $
+ description $
+ destinationIndicator $
+ facsimileTelephoneNumber $
+ internationaliSDNNumber $
+ physicalDeliveryOfficeName $
+ postalAddress $
+ postalCode $
+ postOfficeBox $
+ preferredDeliveryMethod $
+ registeredAddress $
+ seeAlso $
+ sn $
+ street $
+ telephoneNumber $
+ teletexTerminalIdentifier $
+ telexNumber $
+ x121Address )
+ X-ORIGIN 'RFC 4524' )
+objectClasses: ( 0.9.2342.19200300.100.4.7
+ NAME 'room'
+ SUP top
+ STRUCTURAL
+ MUST cn
+ MAY ( roomNumber $
+ description $
+ seeAlso $
+ telephoneNumber )
+ X-ORIGIN 'RFC 4524' )
+objectClasses: ( 0.9.2342.19200300.100.4.19
+ NAME 'simpleSecurityObject'
+ SUP top
+ AUXILIARY
+ MUST userPassword
+ X-ORIGIN 'RFC 4524' )
+objectClasses: ( 2.16.840.1.113730.3.2.6
+ NAME 'referral'
+ DESC 'named subordinate reference object'
+ STRUCTURAL
+ MUST ref
+ X-ORIGIN 'RFC 3296' )
+objectClasses: ( 1.3.6.1.4.1.5322.13.1.1
+ NAME 'namedObject'
+ SUP top
+ STRUCTURAL MAY cn
+ X-ORIGIN 'draft-howard-namedobject' )
+objectClasses: ( 2.16.840.1.113719.2.142.6.1.1
+ NAME 'ldapSubEntry'
+ DESC 'LDAP Subentry class, version 1'
+ SUP top
+ STRUCTURAL
+ MAY ( cn )
+ X-ORIGIN 'draft-ietf-ldup-subentry' )
+objectClasses: ( 1.3.6.1.4.1.7628.5.6.1.1
+ NAME 'inheritableLDAPSubEntry'
+ DESC 'Inheritable LDAP Subentry class, version 1'
+ SUP ldapSubEntry
+ STRUCTURAL
+ MUST ( inheritable )
+ MAY ( blockInheritance )
+ X-ORIGIN 'draft-ietf-ldup-subentry' )
+objectClasses: ( 2.16.840.1.113730.3.2.1
+ NAME 'changeLogEntry'
+ SUP top
+ STRUCTURAL
+ MUST ( changeNumber $
+ targetDN $
+ changeType )
+ MAY ( changes $
+ newRDN $
+ deleteOldRDN $
+ newSuperior )
+ X-ORIGIN 'draft-good-ldap-changelog' )
+objectClasses: ( 1.3.6.1.4.1.4203.1.4.7
+ NAME 'authPasswordObject'
+ DESC 'authentication password mix in class'
+ AUXILIARY
+ MAY authPassword
+ X-ORIGIN 'RFC 3112' )
+
From d87f91008bf1d1ecc1afd9c2c0ac101f6eff03ca Mon Sep 17 00:00:00 2001
From: Bastien Jansen
Date: Mon, 26 Dec 2022 09:49:51 +0100
Subject: [PATCH 5/5] Rebase from master
---
.../internal/AbstractEmbeddedLdapBuilder.java | 25 +-
.../ldap/internal/EmbeddedLdapServerImpl.java | 72 +++++-
.../internal/FakeEmbeddedLdapBuilder.java | 4 +-
.../junit/ldap/EmbeddedLdapRuleBuilder.java | 10 +-
.../ldap/internal/EmbeddedLdapRuleImpl.java | 10 +-
.../junit/ldap/EmbeddedLdapRuleTlsTest.java | 215 ++++++++++++++++++
.../internal/EmbeddedLdapExtensionImpl.java | 10 +-
.../junit5/EmbeddedLdapExtensionBuilder.java | 10 +-
8 files changed, 336 insertions(+), 20 deletions(-)
create mode 100644 embedded-ldap-junit/src/test/java/org/zapodot/junit/ldap/EmbeddedLdapRuleTlsTest.java
diff --git a/embedded-ldap-core/src/main/java/org/zapodot/junit/ldap/internal/AbstractEmbeddedLdapBuilder.java b/embedded-ldap-core/src/main/java/org/zapodot/junit/ldap/internal/AbstractEmbeddedLdapBuilder.java
index 5e03337..240cdd4 100644
--- a/embedded-ldap-core/src/main/java/org/zapodot/junit/ldap/internal/AbstractEmbeddedLdapBuilder.java
+++ b/embedded-ldap-core/src/main/java/org/zapodot/junit/ldap/internal/AbstractEmbeddedLdapBuilder.java
@@ -9,6 +9,7 @@
import com.unboundid.ldap.sdk.schema.Schema;
import com.unboundid.ldif.LDIFException;
+import javax.net.ssl.SSLSocketFactory;
import java.io.File;
import java.io.IOException;
import java.net.InetAddress;
@@ -51,6 +52,12 @@ public abstract class AbstractEmbeddedLdapBuilder createLdapEnvironment() {
final Hashtable environment = new Hashtable<>();
+ if (socketFactory != null) {
+ final Class> delegator = (new ByteBuddy()).subclass(AbstractDelegatingSocketFactory.class)
+ .defineMethod("getDelegate", SocketFactory.class, Modifier.PROTECTED)
+ .intercept(FixedValue.value(socketFactory))
+ .make()
+ .load(getClass().getClassLoader(), ClassLoadingStrategy.Default.INJECTION)
+ .getLoaded();
+ try {
+ final Object instance = delegator.newInstance();
+ delegator.getField("INSTANCE").set(instance, instance);
+ } catch (InstantiationException | IllegalAccessException | NoSuchFieldException e) {
+ throw new IllegalStateException(e);
+ }
+ environment.put("java.naming.ldap.factory.socket", delegator.getCanonicalName());
+ }
environment.put(LdapContext.CONTROL_FACTORIES, JAVA_RT_CONTROL_FACTORY);
- environment.put(Context.PROVIDER_URL, String.format("ldap://%s:%s",
+ environment.put(Context.PROVIDER_URL, String.format("%s://%s:%s",
+ useTls ? "ldaps" : "ldap",
inMemoryDirectoryServer.getListenAddress().getHostName(),
embeddedServerPort()));
environment.put(Context.INITIAL_CONTEXT_FACTORY, JAVA_RT_CONTEXT_FACTORY);
diff --git a/embedded-ldap-core/src/test/java/org/zapodot/junit/ldap/internal/FakeEmbeddedLdapBuilder.java b/embedded-ldap-core/src/test/java/org/zapodot/junit/ldap/internal/FakeEmbeddedLdapBuilder.java
index 04ceae4..e23ba63 100644
--- a/embedded-ldap-core/src/test/java/org/zapodot/junit/ldap/internal/FakeEmbeddedLdapBuilder.java
+++ b/embedded-ldap-core/src/test/java/org/zapodot/junit/ldap/internal/FakeEmbeddedLdapBuilder.java
@@ -20,9 +20,7 @@ protected FakeEmbeddedLdapBuilder getThis() {
EmbeddedLdapServer build() {
try {
InMemoryDirectoryServer server = createServer(createInMemoryServerConfiguration(), ldifsToImport);
- return new EmbeddedLdapServerImpl(
- server,
- authenticationConfiguration) {
+ return new EmbeddedLdapServerImpl(server, authenticationConfiguration, false, null) {
};
} catch (LDAPException e) {
diff --git a/embedded-ldap-junit/src/main/java/org/zapodot/junit/ldap/EmbeddedLdapRuleBuilder.java b/embedded-ldap-junit/src/main/java/org/zapodot/junit/ldap/EmbeddedLdapRuleBuilder.java
index b00771e..b43e4d8 100644
--- a/embedded-ldap-junit/src/main/java/org/zapodot/junit/ldap/EmbeddedLdapRuleBuilder.java
+++ b/embedded-ldap-junit/src/main/java/org/zapodot/junit/ldap/EmbeddedLdapRuleBuilder.java
@@ -31,9 +31,13 @@ protected EmbeddedLdapRuleBuilder getThis() {
*/
public EmbeddedLdapRule build() {
Objects.requireNonNull(bindDSN, "\"bindDSN\" can not be null");
- return EmbeddedLdapRuleImpl.createForConfiguration(createInMemoryServerConfiguration(),
- authenticationConfiguration,
- ldifsToImport);
+ return EmbeddedLdapRuleImpl.createForConfiguration(
+ createInMemoryServerConfiguration(),
+ authenticationConfiguration,
+ ldifsToImport,
+ useTls,
+ socketFactory
+ );
}
}
diff --git a/embedded-ldap-junit/src/main/java/org/zapodot/junit/ldap/internal/EmbeddedLdapRuleImpl.java b/embedded-ldap-junit/src/main/java/org/zapodot/junit/ldap/internal/EmbeddedLdapRuleImpl.java
index e55bd7f..aeac793 100644
--- a/embedded-ldap-junit/src/main/java/org/zapodot/junit/ldap/internal/EmbeddedLdapRuleImpl.java
+++ b/embedded-ldap-junit/src/main/java/org/zapodot/junit/ldap/internal/EmbeddedLdapRuleImpl.java
@@ -7,23 +7,25 @@
import org.junit.runners.model.Statement;
import org.zapodot.junit.ldap.EmbeddedLdapRule;
+import javax.net.ssl.SSLSocketFactory;
import java.util.List;
public class EmbeddedLdapRuleImpl extends EmbeddedLdapServerImpl implements EmbeddedLdapRule {
public static EmbeddedLdapRule createForConfiguration(final InMemoryDirectoryServerConfig inMemoryDirectoryServerConfig,
final AuthenticationConfiguration authenticationConfiguration,
- final List ldifs) {
+ final List ldifs, boolean useTls, SSLSocketFactory socketFactory) {
try {
return new EmbeddedLdapRuleImpl(EmbeddedLdapServerImpl.createServer(inMemoryDirectoryServerConfig, ldifs),
- authenticationConfiguration);
+ authenticationConfiguration, useTls, socketFactory);
} catch (LDAPException e) {
throw new IllegalStateException("Can not initiate in-memory LDAP server due to an exception", e);
}
}
- public EmbeddedLdapRuleImpl(InMemoryDirectoryServer inMemoryDirectoryServer, AuthenticationConfiguration authenticationConfiguration1) {
- super(inMemoryDirectoryServer, authenticationConfiguration1);
+ public EmbeddedLdapRuleImpl(InMemoryDirectoryServer inMemoryDirectoryServer, AuthenticationConfiguration authenticationConfiguration1,
+ boolean useTls, SSLSocketFactory socketFactory) {
+ super(inMemoryDirectoryServer, authenticationConfiguration1, useTls, socketFactory);
}
diff --git a/embedded-ldap-junit/src/test/java/org/zapodot/junit/ldap/EmbeddedLdapRuleTlsTest.java b/embedded-ldap-junit/src/test/java/org/zapodot/junit/ldap/EmbeddedLdapRuleTlsTest.java
new file mode 100644
index 0000000..bedf39f
--- /dev/null
+++ b/embedded-ldap-junit/src/test/java/org/zapodot/junit/ldap/EmbeddedLdapRuleTlsTest.java
@@ -0,0 +1,215 @@
+package org.zapodot.junit.ldap;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+
+import java.util.Arrays;
+import java.io.IOException;
+import java.math.BigInteger;
+import java.net.InetAddress;
+import java.security.KeyManagementException;
+import java.security.KeyPair;
+import java.security.KeyPairGenerator;
+import java.security.KeyStore;
+import java.security.KeyStoreException;
+import java.security.NoSuchAlgorithmException;
+import java.security.Provider;
+import java.security.Security;
+import java.security.UnrecoverableKeyException;
+import java.security.cert.Certificate;
+import java.security.cert.CertificateException;
+import java.security.cert.X509Certificate;
+import java.util.Calendar;
+import java.util.Date;
+
+import javax.naming.Context;
+import javax.naming.NamingEnumeration;
+import javax.naming.directory.DirContext;
+import javax.naming.directory.SearchControls;
+
+import javax.net.ssl.KeyManager;
+import javax.net.ssl.KeyManagerFactory;
+import javax.net.ssl.SSLContext;
+import javax.net.ssl.TrustManager;
+import javax.net.ssl.TrustManagerFactory;
+
+import org.bouncycastle.asn1.ASN1ObjectIdentifier;
+import org.bouncycastle.asn1.x509.BasicConstraints;
+import org.bouncycastle.cert.X509CertificateHolder;
+import org.bouncycastle.cert.jcajce.JcaX509CertificateConverter;
+import org.bouncycastle.cert.jcajce.JcaX509v3CertificateBuilder;
+import org.bouncycastle.jce.provider.BouncyCastleProvider;
+import org.bouncycastle.operator.ContentSigner;
+import org.bouncycastle.operator.OperatorCreationException;
+import org.bouncycastle.operator.jcajce.JcaContentSignerBuilder;
+import org.junit.Rule;
+import org.junit.Test;
+
+import com.google.common.collect.Iterators;
+import com.unboundid.ldap.listener.InMemoryListenerConfig;
+import com.unboundid.ldap.sdk.AddRequest;
+import com.unboundid.ldap.sdk.Attribute;
+import com.unboundid.ldap.sdk.LDAPConnection;
+import com.unboundid.ldap.sdk.LDAPInterface;
+import com.unboundid.ldap.sdk.SearchRequest;
+import com.unboundid.ldap.sdk.SearchResult;
+import com.unboundid.ldap.sdk.SearchResultEntry;
+import com.unboundid.ldap.sdk.SearchScope;
+
+public class EmbeddedLdapRuleTlsTest {
+
+ public static final String DOMAIN_DSN = "dc=zapodot,dc=org";
+
+ final SSLContext sslContext;
+ {
+ try {
+ sslContext = buildSslContext();
+ } catch (Exception e) {
+ throw new IllegalStateException("Failed to create LDAPS config", e);
+ }
+ }
+
+ @Rule
+ public EmbeddedLdapRule embeddedLdapRule = EmbeddedLdapRuleBuilder
+ .newInstance()
+ .usingDomainDsn(DOMAIN_DSN)
+ .importingLdifs("example.ldif")
+ .withListener(getListenerConfig())
+ .useTls(true)
+ .withSocketFactory(sslContext.getSocketFactory())
+ .build();
+
+ private InMemoryListenerConfig getListenerConfig() {
+ try {
+ return InMemoryListenerConfig.createLDAPSConfig(
+ "tls", InetAddress.getLoopbackAddress(), 0, sslContext.getServerSocketFactory(),
+ sslContext.getSocketFactory()
+ );
+ } catch (Exception e) {
+ throw new IllegalStateException("Failed to create LDAPS config", e);
+ }
+ }
+
+ @Test
+ public void testLdapConnection() throws Exception {
+ final LDAPInterface ldapConnection = embeddedLdapRule.ldapConnection();
+ final SearchResult searchResult = ldapConnection.search(DOMAIN_DSN, SearchScope.SUB, "(objectClass=person)");
+ assertEquals(1, searchResult.getEntryCount());
+ }
+
+ @Test
+ public void testRawLdapConnection() throws Exception {
+ final String commonName = "Test person";
+ final String dn = String.format(
+ "cn=%s,ou=people,dc=zapodot,dc=org",
+ commonName);
+ LDAPConnection ldapConnection = embeddedLdapRule.unsharedLdapConnection();
+ try {
+ ldapConnection.add(new AddRequest(dn, Arrays.asList(
+ new Attribute("objectclass", "top", "person", "organizationalPerson", "inetOrgPerson"),
+ new Attribute("cn", commonName), new Attribute("sn", "Person"), new Attribute("uid", "test"))));
+ } finally {
+ // Forces the LDAP connection to be closed. This is not necessary as the rule will usually close it for you.
+ ldapConnection.close();
+ }
+ ldapConnection = embeddedLdapRule.unsharedLdapConnection();
+ final SearchResultEntry entry = ldapConnection.searchForEntry(new SearchRequest(dn,
+ SearchScope.BASE,
+ "(objectClass=person)"));
+ assertNotNull(entry);
+ }
+
+ @Test
+ public void testDirContext() throws Exception {
+ final DirContext dirContext = embeddedLdapRule.dirContext();
+ final SearchControls searchControls = new SearchControls();
+ searchControls.setSearchScope(SearchControls.SUBTREE_SCOPE);
+ final NamingEnumeration resultNamingEnumeration =
+ dirContext.search(DOMAIN_DSN, "(objectClass=person)", searchControls);
+ assertEquals(1, Iterators.size(Iterators.forEnumeration(resultNamingEnumeration)));
+ }
+
+ @Test
+ public void testContext() throws Exception {
+ final Context context = embeddedLdapRule.context();
+ final Object user = context.lookup("cn=Sondre Eikanger Kvalo,ou=people,dc=zapodot,dc=org");
+ assertNotNull(user);
+ }
+
+ @Test
+ public void testContextClose() throws Exception {
+ final Context context = embeddedLdapRule.context();
+ context.close();
+ assertNotNull(context.getNameInNamespace());
+
+ }
+
+ @Test
+ public void testEmbeddedServerPort() throws Exception {
+ assertTrue(embeddedLdapRule.embeddedServerPort() > 0);
+
+ }
+
+ @Test(expected = IllegalStateException.class)
+ public void testNoPortAssignedYet() throws Exception {
+ final EmbeddedLdapRule embeddedLdapRule = new EmbeddedLdapRuleBuilder().build();
+ embeddedLdapRule.embeddedServerPort();
+
+ }
+
+ public static SSLContext buildSslContext()
+ throws KeyStoreException, IOException, CertificateException, NoSuchAlgorithmException,
+ UnrecoverableKeyException, KeyManagementException, OperatorCreationException {
+ KeyStore keystore = KeyStore.getInstance("jks");
+ keystore.load(null, new char[] {});
+ KeyPairGenerator gen = KeyPairGenerator.getInstance("RSA");
+ gen.initialize(2014);
+ final KeyPair keyPair = gen.generateKeyPair();
+
+ Provider bcProvider = new BouncyCastleProvider();
+ Security.addProvider(bcProvider);
+
+ long now = System.currentTimeMillis();
+ Date startDate = new Date(now);
+
+ org.bouncycastle.asn1.x500.X500Name dn = new org.bouncycastle.asn1.x500.X500Name("cn=localhost");
+ BigInteger sn = new BigInteger(Long.toString(now));
+
+ Calendar calendar = Calendar.getInstance();
+ calendar.setTime(startDate);
+ calendar.add(Calendar.HOUR, 1);
+ Date endDate = calendar.getTime();
+
+ String signatureAlgorithm = "SHA256WithRSA";
+
+ final ContentSigner contentSigner = new JcaContentSignerBuilder(signatureAlgorithm).build(keyPair.getPrivate());
+
+ final X509CertificateHolder holder =
+ new JcaX509v3CertificateBuilder(dn, sn, startDate, endDate, dn, keyPair.getPublic())
+ .addExtension(new ASN1ObjectIdentifier("2.5.29.19"), true, new BasicConstraints(true))
+ .build(contentSigner);
+ final X509Certificate cert = new JcaX509CertificateConverter()
+ .setProvider(bcProvider)
+ .getCertificate(holder);
+ keystore.setCertificateEntry("test", cert);
+ keystore.setKeyEntry("key", keyPair.getPrivate(), new char[] {}, new Certificate[] { cert });
+
+ final KeyManagerFactory kmfactory = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
+ kmfactory.init(keystore, new char[] {});
+ final KeyManager[] kms = kmfactory.getKeyManagers();
+
+ KeyStore truststore = KeyStore.getInstance("jks");
+ truststore.load(null, new char[] {});
+ truststore.setCertificateEntry("test", cert);
+
+ final TrustManagerFactory tmfactory = TrustManagerFactory.getInstance(
+ TrustManagerFactory.getDefaultAlgorithm()
+ );
+ tmfactory.init(truststore);
+ final TrustManager[] tms = tmfactory.getTrustManagers();
+ final SSLContext sslcontext = SSLContext.getInstance("TLS");
+ sslcontext.init(kms, tms, null);
+ return sslcontext;
+ }
+}
diff --git a/embedded-ldap-junit5/src/main/java/org/zapodot/junit/ldap/internal/EmbeddedLdapExtensionImpl.java b/embedded-ldap-junit5/src/main/java/org/zapodot/junit/ldap/internal/EmbeddedLdapExtensionImpl.java
index 1daf1ab..66dd274 100644
--- a/embedded-ldap-junit5/src/main/java/org/zapodot/junit/ldap/internal/EmbeddedLdapExtensionImpl.java
+++ b/embedded-ldap-junit5/src/main/java/org/zapodot/junit/ldap/internal/EmbeddedLdapExtensionImpl.java
@@ -6,16 +6,17 @@
import org.junit.jupiter.api.extension.ExtensionContext;
import org.zapodot.junit.ldap.junit5.EmbeddedLdapExtension;
+import javax.net.ssl.SSLSocketFactory;
import java.util.List;
public class EmbeddedLdapExtensionImpl extends EmbeddedLdapServerImpl implements EmbeddedLdapExtension {
public static EmbeddedLdapExtension createForConfiguration(final InMemoryDirectoryServerConfig inMemoryDirectoryServerConfig,
final AuthenticationConfiguration authenticationConfiguration,
- final List ldifs) {
+ final List ldifs, boolean useTls, SSLSocketFactory socketFactory) {
try {
return new EmbeddedLdapExtensionImpl(createServer(inMemoryDirectoryServerConfig, ldifs),
- authenticationConfiguration);
+ authenticationConfiguration, useTls, socketFactory);
} catch (LDAPException e) {
throw new IllegalStateException("Can not initiate in-memory LDAP server due to an exception", e);
}
@@ -23,8 +24,9 @@ public static EmbeddedLdapExtension createForConfiguration(final InMemoryDirecto
private boolean isStartedBeforeAll = false;
- public EmbeddedLdapExtensionImpl(InMemoryDirectoryServer inMemoryDirectoryServer, AuthenticationConfiguration authenticationConfiguration1) {
- super(inMemoryDirectoryServer, authenticationConfiguration1);
+ public EmbeddedLdapExtensionImpl(InMemoryDirectoryServer inMemoryDirectoryServer, AuthenticationConfiguration authenticationConfiguration1,
+ boolean useTls, SSLSocketFactory socketFactory) {
+ super(inMemoryDirectoryServer, authenticationConfiguration1, useTls, socketFactory);
}
@Override
diff --git a/embedded-ldap-junit5/src/main/java/org/zapodot/junit/ldap/junit5/EmbeddedLdapExtensionBuilder.java b/embedded-ldap-junit5/src/main/java/org/zapodot/junit/ldap/junit5/EmbeddedLdapExtensionBuilder.java
index 3bee8b7..dc37aaa 100644
--- a/embedded-ldap-junit5/src/main/java/org/zapodot/junit/ldap/junit5/EmbeddedLdapExtensionBuilder.java
+++ b/embedded-ldap-junit5/src/main/java/org/zapodot/junit/ldap/junit5/EmbeddedLdapExtensionBuilder.java
@@ -26,9 +26,13 @@ public static EmbeddedLdapExtensionBuilder newInstance() {
*/
public EmbeddedLdapExtension build() {
Objects.requireNonNull(bindDSN, "\"bindDSN\" can not be null");
- return EmbeddedLdapExtensionImpl.createForConfiguration(createInMemoryServerConfiguration(),
- authenticationConfiguration,
- ldifsToImport);
+ return EmbeddedLdapExtensionImpl.createForConfiguration(
+ createInMemoryServerConfiguration(),
+ authenticationConfiguration,
+ ldifsToImport,
+ useTls,
+ socketFactory
+ );
}
@Override