From 44ad630de3f82866c1d4a4dec6a09567c6995b4c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Edd=C3=BA=20Mel=C3=A9ndez?= Date: Wed, 24 Jan 2018 21:40:48 -0500 Subject: [PATCH 1/3] Migrate LDAP tests to use ApplicationContextRunner --- .../EmbeddedLdapAutoConfigurationTests.java | 172 +++++++++--------- 1 file changed, 89 insertions(+), 83 deletions(-) diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/ldap/embedded/EmbeddedLdapAutoConfigurationTests.java b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/ldap/embedded/EmbeddedLdapAutoConfigurationTests.java index 095fdd5d563..aa0cda48956 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/ldap/embedded/EmbeddedLdapAutoConfigurationTests.java +++ b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/ldap/embedded/EmbeddedLdapAutoConfigurationTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2017 the original author or authors. + * Copyright 2012-2018 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -21,14 +21,14 @@ import com.unboundid.ldap.sdk.BindResult; import com.unboundid.ldap.sdk.DN; import com.unboundid.ldap.sdk.LDAPConnection; import com.unboundid.ldap.sdk.LDAPException; -import org.junit.After; -import org.junit.Before; import org.junit.Test; import org.springframework.beans.factory.annotation.Value; +import org.springframework.boot.autoconfigure.AutoConfigurations; import org.springframework.boot.autoconfigure.context.PropertyPlaceholderAutoConfiguration; import org.springframework.boot.autoconfigure.data.ldap.LdapDataAutoConfiguration; import org.springframework.boot.autoconfigure.ldap.LdapAutoConfiguration; +import org.springframework.boot.test.context.runner.ApplicationContextRunner; import org.springframework.boot.test.util.TestPropertyValues; import org.springframework.context.annotation.AnnotationConfigApplicationContext; import org.springframework.context.annotation.Bean; @@ -44,121 +44,127 @@ import static org.assertj.core.api.Assertions.assertThat; */ public class EmbeddedLdapAutoConfigurationTests { - private AnnotationConfigApplicationContext context; - - @Before - public void setup() { - this.context = new AnnotationConfigApplicationContext(); - } - - @After - public void close() { - if (this.context != null) { - this.context.close(); - } - } + private ApplicationContextRunner contextRunner = new ApplicationContextRunner() + .withConfiguration( + AutoConfigurations.of(EmbeddedLdapAutoConfiguration.class)); @Test public void testSetDefaultPort() { - load("spring.ldap.embedded.port:1234", - "spring.ldap.embedded.base-dn:dc=spring,dc=org"); - InMemoryDirectoryServer server = this.context - .getBean(InMemoryDirectoryServer.class); - assertThat(server.getListenPort()).isEqualTo(1234); + this.contextRunner.withPropertyValues("spring.ldap.embedded.port:1234", + "spring.ldap.embedded.base-dn:dc=spring,dc=org").run(context -> { + InMemoryDirectoryServer server = context + .getBean(InMemoryDirectoryServer.class); + assertThat(server.getListenPort()).isEqualTo(1234); + }); } @Test public void testRandomPortWithEnvironment() { - load("spring.ldap.embedded.base-dn:dc=spring,dc=org"); - InMemoryDirectoryServer server = this.context - .getBean(InMemoryDirectoryServer.class); - assertThat(server.getListenPort()).isEqualTo(this.context.getEnvironment() - .getProperty("local.ldap.port", Integer.class)); + this.contextRunner + .withPropertyValues("spring.ldap.embedded.base-dn:dc=spring,dc=org") + .run(context -> { + InMemoryDirectoryServer server = context + .getBean(InMemoryDirectoryServer.class); + assertThat(server.getListenPort()).isEqualTo(context.getEnvironment() + .getProperty("local.ldap.port", Integer.class)); + }); } @Test public void testRandomPortWithValueAnnotation() { + AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(); TestPropertyValues.of("spring.ldap.embedded.base-dn:dc=spring,dc=org") - .applyTo(this.context); - this.context.register(EmbeddedLdapAutoConfiguration.class, + .applyTo(context); + context.register(EmbeddedLdapAutoConfiguration.class, LdapClientConfiguration.class, PropertyPlaceholderAutoConfiguration.class); - this.context.refresh(); - LDAPConnection connection = this.context.getBean(LDAPConnection.class); - assertThat(connection.getConnectedPort()).isEqualTo(this.context.getEnvironment() - .getProperty("local.ldap.port", Integer.class)); + context.refresh(); + LDAPConnection connection = context.getBean(LDAPConnection.class); + assertThat(connection.getConnectedPort()).isEqualTo( + context.getEnvironment().getProperty("local.ldap.port", Integer.class)); } @Test - public void testSetCredentials() throws LDAPException { - load("spring.ldap.embedded.base-dn:dc=spring,dc=org", - "spring.ldap.embedded.credential.username:uid=root", - "spring.ldap.embedded.credential.password:boot"); - InMemoryDirectoryServer server = this.context - .getBean(InMemoryDirectoryServer.class); - BindResult result = server.bind("uid=root", "boot"); - assertThat(result).isNotNull(); + public void testSetCredentials() { + this.contextRunner + .withPropertyValues("spring.ldap.embedded.base-dn:dc=spring,dc=org", + "spring.ldap.embedded.credential.username:uid=root", + "spring.ldap.embedded.credential.password:boot") + .run(context -> { + InMemoryDirectoryServer server = context + .getBean(InMemoryDirectoryServer.class); + BindResult result = server.bind("uid=root", "boot"); + assertThat(result).isNotNull(); + }); } @Test - public void testSetPartitionSuffix() throws LDAPException { - load("spring.ldap.embedded.base-dn:dc=spring,dc=org"); - InMemoryDirectoryServer server = this.context - .getBean(InMemoryDirectoryServer.class); - assertThat(server.getBaseDNs()).containsExactly(new DN("dc=spring,dc=org")); + public void testSetPartitionSuffix() { + this.contextRunner + .withPropertyValues("spring.ldap.embedded.base-dn:dc=spring,dc=org") + .run(context -> { + InMemoryDirectoryServer server = context + .getBean(InMemoryDirectoryServer.class); + assertThat(server.getBaseDNs()) + .containsExactly(new DN("dc=spring,dc=org")); + }); } @Test - public void testSetLdifFile() throws LDAPException { - load("spring.ldap.embedded.base-dn:dc=spring,dc=org"); - InMemoryDirectoryServer server = this.context - .getBean(InMemoryDirectoryServer.class); - assertThat(server.countEntriesBelow("ou=company1,c=Sweden,dc=spring,dc=org")) - .isEqualTo(5); + public void testSetLdifFile() { + this.contextRunner + .withPropertyValues("spring.ldap.embedded.base-dn:dc=spring,dc=org") + .run(context -> { + InMemoryDirectoryServer server = context + .getBean(InMemoryDirectoryServer.class); + assertThat(server + .countEntriesBelow("ou=company1,c=Sweden,dc=spring,dc=org")) + .isEqualTo(5); + }); } @Test public void testQueryEmbeddedLdap() { - TestPropertyValues.of("spring.ldap.embedded.base-dn:dc=spring,dc=org") - .applyTo(this.context); - this.context.register(EmbeddedLdapAutoConfiguration.class, - LdapAutoConfiguration.class, LdapDataAutoConfiguration.class, - PropertyPlaceholderAutoConfiguration.class); - this.context.refresh(); - assertThat(this.context.getBeanNamesForType(LdapTemplate.class).length) - .isEqualTo(1); - LdapTemplate ldapTemplate = this.context.getBean(LdapTemplate.class); - assertThat(ldapTemplate.list("ou=company1,c=Sweden,dc=spring,dc=org")).hasSize(4); + this.contextRunner + .withPropertyValues("spring.ldap.embedded.base-dn:dc=spring,dc=org") + .withConfiguration(AutoConfigurations.of(LdapAutoConfiguration.class, + LdapDataAutoConfiguration.class)) + .run(context -> { + assertThat(context.getBeanNamesForType(LdapTemplate.class).length) + .isEqualTo(1); + LdapTemplate ldapTemplate = context.getBean(LdapTemplate.class); + assertThat(ldapTemplate.list("ou=company1,c=Sweden,dc=spring,dc=org")) + .hasSize(4); + }); } @Test - public void testDisableSchemaValidation() throws LDAPException { - load("spring.ldap.embedded.validation.enabled:false", - "spring.ldap.embedded.base-dn:dc=spring,dc=org"); - InMemoryDirectoryServer server = this.context - .getBean(InMemoryDirectoryServer.class); - assertThat(server.getSchema()).isNull(); + public void testDisableSchemaValidation() { + this.contextRunner + .withPropertyValues("spring.ldap.embedded.validation.enabled:false", + "spring.ldap.embedded.base-dn:dc=spring,dc=org") + .run(context -> { + InMemoryDirectoryServer server = context + .getBean(InMemoryDirectoryServer.class); + assertThat(server.getSchema()).isNull(); + }); } @Test - public void testCustomSchemaValidation() throws LDAPException { - load("spring.ldap.embedded.validation.schema:classpath:custom-schema.ldif", + public void testCustomSchemaValidation() { + this.contextRunner.withPropertyValues( + "spring.ldap.embedded.validation.schema:classpath:custom-schema.ldif", "spring.ldap.embedded.ldif:classpath:custom-schema-sample.ldif", - "spring.ldap.embedded.base-dn:dc=spring,dc=org"); - InMemoryDirectoryServer server = this.context - .getBean(InMemoryDirectoryServer.class); + "spring.ldap.embedded.base-dn:dc=spring,dc=org").run(context -> { + InMemoryDirectoryServer server = context + .getBean(InMemoryDirectoryServer.class); - assertThat(server.getSchema().getObjectClass("exampleAuxiliaryClass")) - .isNotNull(); - assertThat(server.getSchema().getAttributeType("exampleAttributeName")) - .isNotNull(); - } - - private void load(String... properties) { - TestPropertyValues.of(properties).applyTo(this.context); - this.context.register(EmbeddedLdapAutoConfiguration.class, - PropertyPlaceholderAutoConfiguration.class); - this.context.refresh(); + assertThat(server.getSchema().getObjectClass("exampleAuxiliaryClass")) + .isNotNull(); + assertThat( + server.getSchema().getAttributeType("exampleAttributeName")) + .isNotNull(); + }); } @Configuration From 270dc2cd7281ae80f595133ea6cf547e45856d08 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Edd=C3=BA=20Mel=C3=A9ndez?= Date: Wed, 24 Jan 2018 21:49:44 -0500 Subject: [PATCH 2/3] Add support for multi baseDn Update LDAP properties and auto-configuration to support multiple base DN values. See gh-11764 --- .../EmbeddedLdapAutoConfiguration.java | 9 +- .../ldap/embedded/EmbeddedLdapProperties.java | 8 +- .../EmbeddedLdapAutoConfigurationTests.java | 48 ++++++-- .../test/resources/schema-multi-basedn.ldif | 114 ++++++++++++++++++ .../main/asciidoc/spring-boot-features.adoc | 2 + 5 files changed, 162 insertions(+), 19 deletions(-) create mode 100644 spring-boot-project/spring-boot-autoconfigure/src/test/resources/schema-multi-basedn.ldif diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/ldap/embedded/EmbeddedLdapAutoConfiguration.java b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/ldap/embedded/EmbeddedLdapAutoConfiguration.java index c4605e9c101..74d5807659d 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/ldap/embedded/EmbeddedLdapAutoConfiguration.java +++ b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/ldap/embedded/EmbeddedLdapAutoConfiguration.java @@ -20,6 +20,7 @@ import java.io.InputStream; import java.util.HashMap; import java.util.Map; +import javax.annotation.PostConstruct; import javax.annotation.PreDestroy; import com.unboundid.ldap.listener.InMemoryDirectoryServer; @@ -33,7 +34,6 @@ import org.springframework.boot.autoconfigure.AutoConfigureBefore; import org.springframework.boot.autoconfigure.EnableAutoConfiguration; import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; -import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; import org.springframework.boot.autoconfigure.ldap.LdapAutoConfiguration; import org.springframework.boot.autoconfigure.ldap.LdapProperties; import org.springframework.boot.autoconfigure.ldap.embedded.EmbeddedLdapProperties.Credential; @@ -50,6 +50,7 @@ import org.springframework.core.env.PropertySource; import org.springframework.core.io.Resource; import org.springframework.ldap.core.ContextSource; import org.springframework.ldap.core.support.LdapContextSource; +import org.springframework.util.Assert; import org.springframework.util.StringUtils; /** @@ -64,7 +65,6 @@ import org.springframework.util.StringUtils; @EnableConfigurationProperties({ LdapProperties.class, EmbeddedLdapProperties.class }) @AutoConfigureBefore(LdapAutoConfiguration.class) @ConditionalOnClass(InMemoryDirectoryServer.class) -@ConditionalOnProperty(prefix = "spring.ldap.embedded", name = "base-dn") public class EmbeddedLdapAutoConfiguration { private static final String PROPERTY_SOURCE_NAME = "ldap.ports"; @@ -88,6 +88,11 @@ public class EmbeddedLdapAutoConfiguration { this.environment = environment; } + @PostConstruct + public void validateBaseDns() { + Assert.notEmpty(this.embeddedProperties.getBaseDn(), "No baseDn found."); + } + @Bean @DependsOn("directoryServer") @ConditionalOnMissingBean diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/ldap/embedded/EmbeddedLdapProperties.java b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/ldap/embedded/EmbeddedLdapProperties.java index 6b82c7a94f0..a42bd120691 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/ldap/embedded/EmbeddedLdapProperties.java +++ b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/ldap/embedded/EmbeddedLdapProperties.java @@ -40,9 +40,9 @@ public class EmbeddedLdapProperties { private Credential credential = new Credential(); /** - * The base DN. + * List of base DN. */ - private String baseDn; + private String[] baseDn = new String[0]; /** * Schema (LDIF) script resource reference. @@ -70,11 +70,11 @@ public class EmbeddedLdapProperties { this.credential = credential; } - public String getBaseDn() { + public String[] getBaseDn() { return this.baseDn; } - public void setBaseDn(String baseDn) { + public void setBaseDn(String[] baseDn) { this.baseDn = baseDn; } diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/ldap/embedded/EmbeddedLdapAutoConfigurationTests.java b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/ldap/embedded/EmbeddedLdapAutoConfigurationTests.java index aa0cda48956..b07364fbd1a 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/ldap/embedded/EmbeddedLdapAutoConfigurationTests.java +++ b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/ldap/embedded/EmbeddedLdapAutoConfigurationTests.java @@ -50,8 +50,10 @@ public class EmbeddedLdapAutoConfigurationTests { @Test public void testSetDefaultPort() { - this.contextRunner.withPropertyValues("spring.ldap.embedded.port:1234", - "spring.ldap.embedded.base-dn:dc=spring,dc=org").run(context -> { + this.contextRunner + .withPropertyValues("spring.ldap.embedded.port:1234", + "spring.ldap.embedded.base-dn[0]:dc=spring,dc=org") + .run(context -> { InMemoryDirectoryServer server = context .getBean(InMemoryDirectoryServer.class); assertThat(server.getListenPort()).isEqualTo(1234); @@ -61,7 +63,7 @@ public class EmbeddedLdapAutoConfigurationTests { @Test public void testRandomPortWithEnvironment() { this.contextRunner - .withPropertyValues("spring.ldap.embedded.base-dn:dc=spring,dc=org") + .withPropertyValues("spring.ldap.embedded.base-dn[0]:dc=spring,dc=org") .run(context -> { InMemoryDirectoryServer server = context .getBean(InMemoryDirectoryServer.class); @@ -73,7 +75,7 @@ public class EmbeddedLdapAutoConfigurationTests { @Test public void testRandomPortWithValueAnnotation() { AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(); - TestPropertyValues.of("spring.ldap.embedded.base-dn:dc=spring,dc=org") + TestPropertyValues.of("spring.ldap.embedded.base-dn[0]:dc=spring,dc=org") .applyTo(context); context.register(EmbeddedLdapAutoConfiguration.class, LdapClientConfiguration.class, @@ -87,7 +89,7 @@ public class EmbeddedLdapAutoConfigurationTests { @Test public void testSetCredentials() { this.contextRunner - .withPropertyValues("spring.ldap.embedded.base-dn:dc=spring,dc=org", + .withPropertyValues("spring.ldap.embedded.base-dn[0]:dc=spring,dc=org", "spring.ldap.embedded.credential.username:uid=root", "spring.ldap.embedded.credential.password:boot") .run(context -> { @@ -101,7 +103,7 @@ public class EmbeddedLdapAutoConfigurationTests { @Test public void testSetPartitionSuffix() { this.contextRunner - .withPropertyValues("spring.ldap.embedded.base-dn:dc=spring,dc=org") + .withPropertyValues("spring.ldap.embedded.base-dn[0]:dc=spring,dc=org") .run(context -> { InMemoryDirectoryServer server = context .getBean(InMemoryDirectoryServer.class); @@ -113,7 +115,7 @@ public class EmbeddedLdapAutoConfigurationTests { @Test public void testSetLdifFile() { this.contextRunner - .withPropertyValues("spring.ldap.embedded.base-dn:dc=spring,dc=org") + .withPropertyValues("spring.ldap.embedded.base-dn[0]:dc=spring,dc=org") .run(context -> { InMemoryDirectoryServer server = context .getBean(InMemoryDirectoryServer.class); @@ -126,7 +128,7 @@ public class EmbeddedLdapAutoConfigurationTests { @Test public void testQueryEmbeddedLdap() { this.contextRunner - .withPropertyValues("spring.ldap.embedded.base-dn:dc=spring,dc=org") + .withPropertyValues("spring.ldap.embedded.base-dn[0]:dc=spring,dc=org") .withConfiguration(AutoConfigurations.of(LdapAutoConfiguration.class, LdapDataAutoConfiguration.class)) .run(context -> { @@ -142,7 +144,7 @@ public class EmbeddedLdapAutoConfigurationTests { public void testDisableSchemaValidation() { this.contextRunner .withPropertyValues("spring.ldap.embedded.validation.enabled:false", - "spring.ldap.embedded.base-dn:dc=spring,dc=org") + "spring.ldap.embedded.base-dn[0]:dc=spring,dc=org") .run(context -> { InMemoryDirectoryServer server = context .getBean(InMemoryDirectoryServer.class); @@ -152,10 +154,12 @@ public class EmbeddedLdapAutoConfigurationTests { @Test public void testCustomSchemaValidation() { - this.contextRunner.withPropertyValues( - "spring.ldap.embedded.validation.schema:classpath:custom-schema.ldif", - "spring.ldap.embedded.ldif:classpath:custom-schema-sample.ldif", - "spring.ldap.embedded.base-dn:dc=spring,dc=org").run(context -> { + this.contextRunner + .withPropertyValues( + "spring.ldap.embedded.validation.schema:classpath:custom-schema.ldif", + "spring.ldap.embedded.ldif:classpath:custom-schema-sample.ldif", + "spring.ldap.embedded.base-dn[0]:dc=spring,dc=org") + .run(context -> { InMemoryDirectoryServer server = context .getBean(InMemoryDirectoryServer.class); @@ -167,6 +171,24 @@ public class EmbeddedLdapAutoConfigurationTests { }); } + @Test + public void testMultiBaseDn() { + this.contextRunner + .withPropertyValues( + "spring.ldap.embedded.ldif:classpath:schema-multi-basedn.ldif", + "spring.ldap.embedded.base-dn[0]:dc=spring,dc=org", + "spring.ldap.embedded.base-dn[1]:dc=pivotal,dc=io") + .run(context -> { + InMemoryDirectoryServer server = context + .getBean(InMemoryDirectoryServer.class); + assertThat(server + .countEntriesBelow("ou=company1,c=Sweden,dc=spring,dc=org")) + .isEqualTo(5); + assertThat(server.countEntriesBelow("c=Sweden,dc=pivotal,dc=io")) + .isEqualTo(2); + }); + } + @Configuration static class LdapClientConfiguration { diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/resources/schema-multi-basedn.ldif b/spring-boot-project/spring-boot-autoconfigure/src/test/resources/schema-multi-basedn.ldif new file mode 100644 index 00000000000..1bf396af5ba --- /dev/null +++ b/spring-boot-project/spring-boot-autoconfigure/src/test/resources/schema-multi-basedn.ldif @@ -0,0 +1,114 @@ +dn: dc=spring,dc=org +objectclass: top +objectclass: domain +objectclass: extensibleObject +dc: spring + +dn: ou=groups,dc=spring,dc=org +objectclass: top +objectclass: organizationalUnit +ou: groups + +dn: cn=ROLE_USER,ou=groups,dc=spring,dc=org +objectclass: top +objectclass: groupOfUniqueNames +cn: ROLE_USER +uniqueMember: cn=Some Person,ou=company1,c=Sweden,dc=spring,dc=org +uniqueMember: cn=Some Person2,ou=company1,c=Sweden,dc=spring,dc=org +uniqueMember: cn=Some Person,ou=company1,c=Sweden,dc=spring,dc=org +uniqueMember: cn=Some Person3,ou=company1,c=Sweden,dc=spring,dc=org + +dn: cn=ROLE_ADMIN,ou=groups,dc=spring,dc=org +objectclass: top +objectclass: groupOfUniqueNames +cn: ROLE_ADMIN +uniqueMember: cn=Some Person2,ou=company1,c=Sweden,dc=spring,dc=org + +dn: c=Sweden,dc=spring,dc=org +objectclass: top +objectclass: country +c: Sweden +description: The country of Sweden + +dn: ou=company1,c=Sweden,dc=spring,dc=org +objectclass: top +objectclass: organizationalUnit +ou: company1 +description: First company in Sweden + +dn: cn=Some Person,ou=company1,c=Sweden,dc=spring,dc=org +objectclass: top +objectclass: person +objectclass: organizationalPerson +objectclass: inetOrgPerson +uid: some.person +userPassword: password +cn: Some Person +sn: Person +description: Sweden, Company1, Some Person +telephoneNumber: +46 555-123456 + +dn: cn=Some Person2,ou=company1,c=Sweden,dc=spring,dc=org +objectclass: top +objectclass: person +objectclass: organizationalPerson +objectclass: inetOrgPerson +uid: some.person2 +userPassword: password +cn: Some Person2 +sn: Person2 +description: Sweden, Company1, Some Person2 +telephoneNumber: +46 555-654321 + +dn: cn=Some Person3,ou=company1,c=Sweden,dc=spring,dc=org +objectclass: top +objectclass: person +objectclass: organizationalPerson +objectclass: inetOrgPerson +uid: some.person3 +userPassword: password +cn: Some Person3 +sn: Person3 +description: Sweden, Company1, Some Person3 +telephoneNumber: +46 555-123654 + +dn: cn=Some Person4,ou=company1,c=Sweden,dc=spring,dc=org +objectclass: top +objectclass: person +objectclass: organizationalPerson +objectclass: inetOrgPerson +uid: some.person4 +userPassword: password +cn: Some Person +sn: Person +description: Sweden, Company1, Some Person +telephoneNumber: +46 555-456321 + +dn: dc=pivotal,dc=io +objectclass: top +objectclass: domain +objectclass: extensibleObject +dc: pivotal + +dn: ou=groups,dc=pivotal,dc=io +objectclass: top +objectclass: organizationalUnit +ou: groups + +dn: c=Sweden,dc=pivotal,dc=io +objectclass: top +objectclass: country +c: Sweden +description:The country of Sweden + +dn: cn=Some Random Person,c=Sweden,dc=pivotal,dc=io +objectclass: top +objectclass: person +objectclass: organizationalPerson +objectclass: inetOrgPerson +uid: some.random.person +userPassword: password +cn: Some Random Person +sn: Person +description: Sweden, Pivotal, Some Random Person +telephoneNumber: +46 555-123456 diff --git a/spring-boot-project/spring-boot-docs/src/main/asciidoc/spring-boot-features.adoc b/spring-boot-project/spring-boot-docs/src/main/asciidoc/spring-boot-features.adoc index 955f1e5a7b0..95b5532f76d 100644 --- a/spring-boot-project/spring-boot-docs/src/main/asciidoc/spring-boot-features.adoc +++ b/spring-boot-project/spring-boot-docs/src/main/asciidoc/spring-boot-features.adoc @@ -4417,6 +4417,8 @@ follows: spring.ldap.embedded.base-dn=dc=spring,dc=io ---- +WARNING: `spring.ldap.embedded.base-dn` supports multi base DN, so it must define as follows `spring.ldap.embedded.base-dn[0]=dc=spring,dc=io` + By default, the server starts on a random port and triggers the regular LDAP support. There is no need to specify a `spring.ldap.urls` property. From eab0b84a80e4e70bbf84289e1318e99c70ff899e Mon Sep 17 00:00:00 2001 From: Phillip Webb Date: Sun, 4 Feb 2018 10:39:29 -0800 Subject: [PATCH 3/3] Polish 'Add support for multi baseDn; Update multi baseDn support to use the recently introduced `@Delimter` annotation Closes gh-11764 --- .../EmbeddedLdapAutoConfiguration.java | 11 ++----- .../ldap/embedded/EmbeddedLdapProperties.java | 13 +++++--- .../EmbeddedLdapAutoConfigurationTests.java | 30 ++++++++----------- .../main/asciidoc/spring-boot-features.adoc | 24 +++++++++++++++ 4 files changed, 49 insertions(+), 29 deletions(-) diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/ldap/embedded/EmbeddedLdapAutoConfiguration.java b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/ldap/embedded/EmbeddedLdapAutoConfiguration.java index 74d5807659d..12c6f80f2ac 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/ldap/embedded/EmbeddedLdapAutoConfiguration.java +++ b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/ldap/embedded/EmbeddedLdapAutoConfiguration.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2017 the original author or authors. + * Copyright 2012-2018 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -20,7 +20,6 @@ import java.io.InputStream; import java.util.HashMap; import java.util.Map; -import javax.annotation.PostConstruct; import javax.annotation.PreDestroy; import com.unboundid.ldap.listener.InMemoryDirectoryServer; @@ -86,10 +85,6 @@ public class EmbeddedLdapAutoConfiguration { this.properties = properties; this.applicationContext = applicationContext; this.environment = environment; - } - - @PostConstruct - public void validateBaseDns() { Assert.notEmpty(this.embeddedProperties.getBaseDn(), "No baseDn found."); } @@ -108,8 +103,8 @@ public class EmbeddedLdapAutoConfiguration { @Bean public InMemoryDirectoryServer directoryServer() throws LDAPException { - InMemoryDirectoryServerConfig config = new InMemoryDirectoryServerConfig( - this.embeddedProperties.getBaseDn()); + String[] baseDn = this.embeddedProperties.getBaseDn().toArray(new String[0]); + InMemoryDirectoryServerConfig config = new InMemoryDirectoryServerConfig(baseDn); if (hasCredentials(this.embeddedProperties.getCredential())) { config.addAdditionalBindCredentials( this.embeddedProperties.getCredential().getUsername(), diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/ldap/embedded/EmbeddedLdapProperties.java b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/ldap/embedded/EmbeddedLdapProperties.java index a42bd120691..0076d9364b1 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/ldap/embedded/EmbeddedLdapProperties.java +++ b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/ldap/embedded/EmbeddedLdapProperties.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2017 the original author or authors. + * Copyright 2012-2018 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -16,7 +16,11 @@ package org.springframework.boot.autoconfigure.ldap.embedded; +import java.util.ArrayList; +import java.util.List; + import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.boot.context.properties.bind.convert.Delimiter; import org.springframework.core.io.Resource; /** @@ -42,7 +46,8 @@ public class EmbeddedLdapProperties { /** * List of base DN. */ - private String[] baseDn = new String[0]; + @Delimiter(Delimiter.NONE) + private List baseDn = new ArrayList<>(); /** * Schema (LDIF) script resource reference. @@ -70,11 +75,11 @@ public class EmbeddedLdapProperties { this.credential = credential; } - public String[] getBaseDn() { + public List getBaseDn() { return this.baseDn; } - public void setBaseDn(String[] baseDn) { + public void setBaseDn(List baseDn) { this.baseDn = baseDn; } diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/ldap/embedded/EmbeddedLdapAutoConfigurationTests.java b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/ldap/embedded/EmbeddedLdapAutoConfigurationTests.java index b07364fbd1a..ddfeb7d95f8 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/ldap/embedded/EmbeddedLdapAutoConfigurationTests.java +++ b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/ldap/embedded/EmbeddedLdapAutoConfigurationTests.java @@ -50,10 +50,8 @@ public class EmbeddedLdapAutoConfigurationTests { @Test public void testSetDefaultPort() { - this.contextRunner - .withPropertyValues("spring.ldap.embedded.port:1234", - "spring.ldap.embedded.base-dn[0]:dc=spring,dc=org") - .run(context -> { + this.contextRunner.withPropertyValues("spring.ldap.embedded.port:1234", + "spring.ldap.embedded.base-dn:dc=spring,dc=org").run(context -> { InMemoryDirectoryServer server = context .getBean(InMemoryDirectoryServer.class); assertThat(server.getListenPort()).isEqualTo(1234); @@ -63,7 +61,7 @@ public class EmbeddedLdapAutoConfigurationTests { @Test public void testRandomPortWithEnvironment() { this.contextRunner - .withPropertyValues("spring.ldap.embedded.base-dn[0]:dc=spring,dc=org") + .withPropertyValues("spring.ldap.embedded.base-dn:dc=spring,dc=org") .run(context -> { InMemoryDirectoryServer server = context .getBean(InMemoryDirectoryServer.class); @@ -75,7 +73,7 @@ public class EmbeddedLdapAutoConfigurationTests { @Test public void testRandomPortWithValueAnnotation() { AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(); - TestPropertyValues.of("spring.ldap.embedded.base-dn[0]:dc=spring,dc=org") + TestPropertyValues.of("spring.ldap.embedded.base-dn:dc=spring,dc=org") .applyTo(context); context.register(EmbeddedLdapAutoConfiguration.class, LdapClientConfiguration.class, @@ -89,7 +87,7 @@ public class EmbeddedLdapAutoConfigurationTests { @Test public void testSetCredentials() { this.contextRunner - .withPropertyValues("spring.ldap.embedded.base-dn[0]:dc=spring,dc=org", + .withPropertyValues("spring.ldap.embedded.base-dn:dc=spring,dc=org", "spring.ldap.embedded.credential.username:uid=root", "spring.ldap.embedded.credential.password:boot") .run(context -> { @@ -103,7 +101,7 @@ public class EmbeddedLdapAutoConfigurationTests { @Test public void testSetPartitionSuffix() { this.contextRunner - .withPropertyValues("spring.ldap.embedded.base-dn[0]:dc=spring,dc=org") + .withPropertyValues("spring.ldap.embedded.base-dn:dc=spring,dc=org") .run(context -> { InMemoryDirectoryServer server = context .getBean(InMemoryDirectoryServer.class); @@ -115,7 +113,7 @@ public class EmbeddedLdapAutoConfigurationTests { @Test public void testSetLdifFile() { this.contextRunner - .withPropertyValues("spring.ldap.embedded.base-dn[0]:dc=spring,dc=org") + .withPropertyValues("spring.ldap.embedded.base-dn:dc=spring,dc=org") .run(context -> { InMemoryDirectoryServer server = context .getBean(InMemoryDirectoryServer.class); @@ -128,7 +126,7 @@ public class EmbeddedLdapAutoConfigurationTests { @Test public void testQueryEmbeddedLdap() { this.contextRunner - .withPropertyValues("spring.ldap.embedded.base-dn[0]:dc=spring,dc=org") + .withPropertyValues("spring.ldap.embedded.base-dn:dc=spring,dc=org") .withConfiguration(AutoConfigurations.of(LdapAutoConfiguration.class, LdapDataAutoConfiguration.class)) .run(context -> { @@ -144,7 +142,7 @@ public class EmbeddedLdapAutoConfigurationTests { public void testDisableSchemaValidation() { this.contextRunner .withPropertyValues("spring.ldap.embedded.validation.enabled:false", - "spring.ldap.embedded.base-dn[0]:dc=spring,dc=org") + "spring.ldap.embedded.base-dn:dc=spring,dc=org") .run(context -> { InMemoryDirectoryServer server = context .getBean(InMemoryDirectoryServer.class); @@ -154,12 +152,10 @@ public class EmbeddedLdapAutoConfigurationTests { @Test public void testCustomSchemaValidation() { - this.contextRunner - .withPropertyValues( - "spring.ldap.embedded.validation.schema:classpath:custom-schema.ldif", - "spring.ldap.embedded.ldif:classpath:custom-schema-sample.ldif", - "spring.ldap.embedded.base-dn[0]:dc=spring,dc=org") - .run(context -> { + this.contextRunner.withPropertyValues( + "spring.ldap.embedded.validation.schema:classpath:custom-schema.ldif", + "spring.ldap.embedded.ldif:classpath:custom-schema-sample.ldif", + "spring.ldap.embedded.base-dn:dc=spring,dc=org").run(context -> { InMemoryDirectoryServer server = context .getBean(InMemoryDirectoryServer.class); diff --git a/spring-boot-project/spring-boot-docs/src/main/asciidoc/spring-boot-features.adoc b/spring-boot-project/spring-boot-docs/src/main/asciidoc/spring-boot-features.adoc index 95b5532f76d..6ce1cac6a49 100644 --- a/spring-boot-project/spring-boot-docs/src/main/asciidoc/spring-boot-features.adoc +++ b/spring-boot-project/spring-boot-docs/src/main/asciidoc/spring-boot-features.adoc @@ -4417,6 +4417,30 @@ follows: spring.ldap.embedded.base-dn=dc=spring,dc=io ---- +[NOTE] +==== +It is possible to define multiple base-dn values, however, since distinguished names +usually contain commas, they must be defined using the correct notation. + +In yaml files, you can use the yaml list notation: + +[source,yaml,indent=0] +---- + spring.ldap.embedded.base-dn: + - dc=spring,dc=io + - dc=pivotal,dc=io +---- + +in properties files, you must include the index as part of the property name: + +[source,properties,indent=0] +---- + spring.ldap.embedded.base-dn[0]=dc=spring,dc=io + spring.ldap.embedded.base-dn[1]=dc=pivotal,dc=io +---- + +==== + WARNING: `spring.ldap.embedded.base-dn` supports multi base DN, so it must define as follows `spring.ldap.embedded.base-dn[0]=dc=spring,dc=io` By default, the server starts on a random port and triggers the regular LDAP support.