Skip to content

Commit ec4e139

Browse files
committed
Bind to the loopback device by default. Expose builder method that allows the bindingAddress to be set thus resolving #3
1 parent 0d082e9 commit ec4e139

File tree

8 files changed

+152
-25
lines changed

8 files changed

+152
-25
lines changed

src/main/java/org/zapodot/junit/ldap/EmbeddedLdapRule.java

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -51,11 +51,12 @@ public interface EmbeddedLdapRule extends TestRule {
5151
/**
5252
* Gives access to the listening port for the currently running embedded LDAP server.
5353
* This will make it easier to use other integration
54-
*
55-
* Note: the listening address is always <em>0.0.0.0</em> which means the server will listen to all available NIC-s.
56-
* This may change in a future release (should ideally only be listening on the loopback device)
54+
* <p/>
55+
* Note: the embedded LDAP server is by default configured to listen only on the loopback address
56+
* (i.e <em>localhost/127.0.0.1</em>) unless another address has been provided to the builder when the rule was built
5757
*
5858
* @return the port number that the embedded server is listening to
59+
* @see org.zapodot.junit.ldap.EmbeddedLdapRuleBuilder#bindingToAddress(String)
5960
*/
6061
int embeddedServerPort();
6162

src/main/java/org/zapodot/junit/ldap/EmbeddedLdapRuleBuilder.java

Lines changed: 37 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,9 @@
1414

1515
import java.io.File;
1616
import java.io.IOException;
17+
import java.net.InetAddress;
1718
import java.net.URISyntaxException;
19+
import java.net.UnknownHostException;
1820
import java.util.Arrays;
1921
import java.util.LinkedList;
2022
import java.util.List;
@@ -29,6 +31,8 @@ public class EmbeddedLdapRuleBuilder {
2931
public static final String DEFAULT_BIND_DSN = "cn=Directory manager";
3032
public static final String DEFAULT_BIND_CREDENTIALS = "password";
3133
public static final String LDAP_SERVER_LISTENER_NAME = "test-listener";
34+
public static final int MIN_PORT_EXCLUSIVE = 0;
35+
public static final int MAX_PORT_EXCLUSIVE = 65535;
3236
private List<String> domainDsn = new LinkedList<>();
3337

3438
private String bindDSN = DEFAULT_BIND_DSN;
@@ -39,7 +43,9 @@ public class EmbeddedLdapRuleBuilder {
3943

4044
private List<String> schemaLdifs = new LinkedList<>();
4145

42-
private Integer port = null;
46+
private Integer bindPort = 0;
47+
48+
private InetAddress bindAddress = InetAddress.getLoopbackAddress();
4349

4450
private AuthenticationConfiguration authenticationConfiguration;
4551

@@ -93,9 +99,32 @@ public EmbeddedLdapRuleBuilder usingBindCredentials(final String bindCredentials
9399
*
94100
* @param port a port number
95101
* @return same EmbeddedLdapRuleBuilder instance with the port field set
102+
* @throws IllegalArgumentException if the provided value for port is not between @{link MIN_PORT_EXCLUSIVE}
103+
* and @{MAX_PORT_EXCLUSIVE} (exclusive)
96104
*/
97105
public EmbeddedLdapRuleBuilder bindingToPort(final int port) {
98-
this.port = Integer.valueOf(port);
106+
if ((port < MIN_PORT_EXCLUSIVE) || (port > MAX_PORT_EXCLUSIVE)) {
107+
throw new IllegalArgumentException(String.format("Value \"%s\" is not a valid port number", port));
108+
}
109+
this.bindPort = Integer.valueOf(port);
110+
return this;
111+
}
112+
113+
/**
114+
* Allows the listening address for the embedded LDAP server to be set. If not set it will bind to <em>localhost/127.0.0.1</em>.
115+
*
116+
* @param address a valid hostname or textual representation of an IP address
117+
* @return same EmbeddedLdapRuleBuilder instance with the bindAddress field set
118+
* @throws IllegalArgumentException if the value provided for \"address\" is invalid
119+
*/
120+
public EmbeddedLdapRuleBuilder bindingToAddress(final String address) {
121+
Objects.requireNonNull(address);
122+
try {
123+
final InetAddress addressByName = InetAddress.getByName(address);
124+
this.bindAddress = addressByName;
125+
} catch (UnknownHostException e) {
126+
throw new IllegalArgumentException(String.format("Unknown host address \"%s\"", address), e);
127+
}
99128
return this;
100129
}
101130

@@ -145,14 +174,12 @@ private InMemoryDirectoryServerConfig createInMemoryServerConfiguration() {
145174
inMemoryDirectoryServerConfig.addAdditionalBindCredentials(bindDSN, bindCredentials);
146175
}
147176

148-
if (port != null) {
149-
inMemoryDirectoryServerConfig.setListenerConfigs(InMemoryListenerConfig.createLDAPConfig(
150-
LDAP_SERVER_LISTENER_NAME,
151-
port));
152-
} else {
153-
inMemoryDirectoryServerConfig.setListenerConfigs(InMemoryListenerConfig.createLDAPConfig(
154-
LDAP_SERVER_LISTENER_NAME));
155-
}
177+
final InMemoryListenerConfig listenerConfig = InMemoryListenerConfig.createLDAPConfig(
178+
LDAP_SERVER_LISTENER_NAME,
179+
bindAddress,
180+
bindPort,
181+
null);
182+
inMemoryDirectoryServerConfig.setListenerConfigs(listenerConfig);
156183
for (Schema s : customSchema().asSet()) {
157184
inMemoryDirectoryServerConfig.setSchema(s);
158185
}
Lines changed: 13 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,13 @@
11
package org.zapodot.junit.ldap.internal;
22

3+
import com.google.common.collect.ImmutableMap;
4+
35
import javax.naming.Context;
4-
import java.util.HashMap;
56
import java.util.Map;
67

78
/**
89
* LDAP authentication POJO.
9-
*
10+
* <p/>
1011
* This class is part of the internal API and may thus be changed or removed without warning.
1112
*/
1213
public class AuthenticationConfiguration {
@@ -20,14 +21,16 @@ public AuthenticationConfiguration(final String userDn, final String credentials
2021

2122

2223
public Map<String, String> toAuthenticationEnvironment() {
23-
final HashMap<String, String> authenticationConfiguration = new HashMap<>();
24-
if (userDn != null && credentials != null) {
25-
authenticationConfiguration.put(Context.SECURITY_PRINCIPAL, userDn);
26-
authenticationConfiguration.put(Context.SECURITY_PROTOCOL, "simple");
27-
authenticationConfiguration.put(Context.SECURITY_CREDENTIALS, credentials);
28-
} else {
29-
authenticationConfiguration.put(Context.SECURITY_PROTOCOL, "none");
24+
25+
if (userDn == null || credentials == null) {
26+
throw new IllegalStateException("userDn and credentials must be set before generating the "
27+
+ "authentication environment");
3028
}
31-
return authenticationConfiguration;
29+
30+
return ImmutableMap.<String, String>builder()
31+
.put(Context.SECURITY_PRINCIPAL, userDn)
32+
.put(Context.SECURITY_PROTOCOL, "simple")
33+
.put(Context.SECURITY_CREDENTIALS, credentials)
34+
.build();
3235
}
3336
}

src/main/java/org/zapodot/junit/ldap/internal/EmbeddedLdapRuleImpl.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -119,7 +119,7 @@ private Hashtable<String, String> createLdapEnvironment() {
119119
final Hashtable<String, String> environment = new Hashtable<>();
120120
environment.put(LdapContext.CONTROL_FACTORIES, DefaultResponseControlFactory.class.getName());
121121
environment.put(Context.PROVIDER_URL, String.format("ldap://%s:%s",
122-
"localhost",
122+
inMemoryDirectoryServer.getListenAddress().getHostName(),
123123
embeddedServerPort()));
124124
environment.put(Context.INITIAL_CONTEXT_FACTORY, LdapCtxFactory.class.getName());
125125
if (authenticationConfiguration != null) {

src/test/java/org/zapodot/junit/ldap/EmbeddedLdapRuleBuilderTest.java

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ public void testIllegalDSN() throws Exception {
3636

3737
}
3838

39-
@Test(expected = IllegalStateException.class)
39+
@Test(expected = IllegalArgumentException.class)
4040
public void testIllegalPort() throws Exception {
4141
EmbeddedLdapRuleBuilder.newInstance().bindingToPort(Integer.MIN_VALUE).build();
4242

@@ -59,4 +59,18 @@ public void testSchemaIsInvalid() throws Exception {
5959
EmbeddedLdapRuleBuilder.newInstance().withSchema("invalid.ldif").build();
6060

6161
}
62+
63+
@Test(expected = IllegalArgumentException.class)
64+
public void testInvalidPort() throws Exception {
65+
EmbeddedLdapRuleBuilder.newInstance().bindingToPort(Integer.MAX_VALUE);
66+
67+
}
68+
69+
@Test(expected = IllegalArgumentException.class)
70+
public void testInvalidBindAddress() throws Exception {
71+
EmbeddedLdapRuleBuilder.newInstance().bindingToAddress("åpsldfåpl");
72+
73+
}
74+
75+
6276
}
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
package org.zapodot.junit.ldap;
2+
3+
import org.junit.Rule;
4+
import org.junit.Test;
5+
6+
import static org.junit.Assert.assertNotNull;
7+
8+
public class EmbeddedLdapRuleNoAuthTest {
9+
10+
@Rule
11+
public EmbeddedLdapRule embeddedLdapRule = EmbeddedLdapRuleBuilder
12+
.newInstance()
13+
.usingBindCredentials(null)
14+
.usingDomainDsn("dc=zapodot,dc=org")
15+
.importingLdifs("example.ldif")
16+
.build();
17+
18+
@Test
19+
public void testConnect() throws Exception {
20+
assertNotNull(embeddedLdapRule.dirContext().search("cn=Sondre Eikanger Kvalo,ou=people,dc=zapodot,dc=org", null));
21+
22+
}
23+
}
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
package org.zapodot.junit.ldap;
2+
3+
import org.junit.BeforeClass;
4+
import org.junit.Rule;
5+
import org.junit.Test;
6+
7+
import java.net.InetAddress;
8+
9+
import static org.junit.Assert.assertEquals;
10+
11+
public class EmbeddedLdapRuleWithListeningAddressProvidedTest {
12+
13+
public static InetAddress inetAddress;
14+
15+
@Rule
16+
public EmbeddedLdapRule embeddedLdapRule = EmbeddedLdapRuleBuilder
17+
.newInstance()
18+
.usingDomainDsn("dc=zapodot,dc=org")
19+
.importingLdifs("example.ldif")
20+
.bindingToAddress(inetAddress.getHostAddress())
21+
.build();
22+
23+
@BeforeClass
24+
public static void setupAddress() throws Exception {
25+
inetAddress = InetAddress.getLocalHost();
26+
}
27+
28+
@Test
29+
public void testLookupAddress() throws Exception {
30+
assertEquals(inetAddress.getHostAddress(),
31+
embeddedLdapRule.unsharedLdapConnection().getConnectedAddress());
32+
33+
}
34+
}
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
package org.zapodot.junit.ldap.internal;
2+
3+
import org.junit.Test;
4+
5+
import java.util.Map;
6+
7+
import static org.junit.Assert.assertEquals;
8+
9+
public class AuthenticationConfigurationTest {
10+
11+
@Test
12+
public void testToAuthenticationEnvironment() throws Exception {
13+
final AuthenticationConfiguration authenticationConfiguration = new AuthenticationConfiguration(
14+
"cn=someone,ou=people,dc=net",
15+
"credentials");
16+
final Map<String, String> environment = authenticationConfiguration.toAuthenticationEnvironment();
17+
assertEquals(3, environment.size());
18+
}
19+
20+
@Test(expected = IllegalStateException.class)
21+
public void testNotSet() throws Exception {
22+
new AuthenticationConfiguration(null, null).toAuthenticationEnvironment();
23+
24+
}
25+
}

0 commit comments

Comments
 (0)