From fa8f0a61364127dc6dc2455642f66c8f5de33f3d Mon Sep 17 00:00:00 2001 From: Mathieu Ouellet Date: Sat, 4 Feb 2017 10:54:09 -0500 Subject: [PATCH] Add schema validation options for embedded LDAP See gh-8195 --- .../EmbeddedLdapAutoConfiguration.java | 18 ++++++++ .../ldap/embedded/EmbeddedLdapProperties.java | 41 +++++++++++++++++++ .../EmbeddedLdapAutoConfigurationTests.java | 23 +++++++++++ .../test/resources/custom-schema-sample.ldif | 7 ++++ .../src/test/resources/custom-schema.ldif | 17 ++++++++ 5 files changed, 106 insertions(+) create mode 100644 spring-boot-autoconfigure/src/test/resources/custom-schema-sample.ldif create mode 100644 spring-boot-autoconfigure/src/test/resources/custom-schema.ldif diff --git a/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/ldap/embedded/EmbeddedLdapAutoConfiguration.java b/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/ldap/embedded/EmbeddedLdapAutoConfiguration.java index 3d0670be3c..c7805d123e 100644 --- a/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/ldap/embedded/EmbeddedLdapAutoConfiguration.java +++ b/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/ldap/embedded/EmbeddedLdapAutoConfiguration.java @@ -26,6 +26,7 @@ import com.unboundid.ldap.listener.InMemoryDirectoryServer; import com.unboundid.ldap.listener.InMemoryDirectoryServerConfig; import com.unboundid.ldap.listener.InMemoryListenerConfig; import com.unboundid.ldap.sdk.LDAPException; +import com.unboundid.ldap.sdk.schema.Schema; import com.unboundid.ldif.LDIFReader; import org.springframework.boot.autoconfigure.AutoConfigureBefore; @@ -55,6 +56,7 @@ import org.springframework.util.StringUtils; * {@link EnableAutoConfiguration Auto-configuration} for Embedded LDAP. * * @author Eddú Meléndez + * @author Mathieu Ouellet * @since 1.5.0 */ @Configuration @@ -107,6 +109,22 @@ public class EmbeddedLdapAutoConfiguration { this.embeddedProperties.getCredential().getUsername(), this.embeddedProperties.getCredential().getPassword()); } + + if (!this.embeddedProperties.getValidation().isEnabled()) { + config.setSchema(null); + } + else if (this.embeddedProperties.getValidation().getSchema() != null) { + Resource schemaLocation = this.embeddedProperties.getValidation().getSchema(); + try { + config.setSchema(Schema.mergeSchemas(Schema.getDefaultStandardSchema(), + Schema.getSchema(schemaLocation.getFile()))); + } + catch (Exception ex) { + throw new IllegalStateException( + "Unable to load schema " + schemaLocation.getDescription(), ex); + } + } + InMemoryListenerConfig listenerConfig = InMemoryListenerConfig .createLDAPConfig("LDAP", this.embeddedProperties.getPort()); config.setListenerConfigs(listenerConfig); diff --git a/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/ldap/embedded/EmbeddedLdapProperties.java b/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/ldap/embedded/EmbeddedLdapProperties.java index 1a4ac083ed..8e4d0b6927 100644 --- a/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/ldap/embedded/EmbeddedLdapProperties.java +++ b/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/ldap/embedded/EmbeddedLdapProperties.java @@ -17,11 +17,13 @@ package org.springframework.boot.autoconfigure.ldap.embedded; import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.core.io.Resource; /** * Configuration properties for Embedded LDAP. * * @author Eddú Meléndez + * @author Mathieu Ouellet * @since 1.5.0 */ @ConfigurationProperties(prefix = "spring.ldap.embedded") @@ -47,6 +49,11 @@ public class EmbeddedLdapProperties { */ private String ldif = "classpath:schema.ldif"; + /** + * Schema validation + */ + private Validation validation = new Validation(); + public int getPort() { return this.port; } @@ -79,6 +86,10 @@ public class EmbeddedLdapProperties { this.ldif = ldif; } + public Validation getValidation() { + return this.validation; + } + static class Credential { /** @@ -109,4 +120,34 @@ public class EmbeddedLdapProperties { } + static class Validation { + + /** + * Enable LDAP schema validation + */ + private boolean enabled = true; + + /** + * Path to the custom schema file + */ + private Resource schema; + + public boolean isEnabled() { + return this.enabled; + } + + public void setEnabled(boolean enabled) { + this.enabled = enabled; + } + + public Resource getSchema() { + return this.schema; + } + + public void setSchema(Resource schema) { + this.schema = schema; + } + + } + } diff --git a/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/ldap/embedded/EmbeddedLdapAutoConfigurationTests.java b/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/ldap/embedded/EmbeddedLdapAutoConfigurationTests.java index d5d5e54dae..5643eda946 100644 --- a/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/ldap/embedded/EmbeddedLdapAutoConfigurationTests.java +++ b/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/ldap/embedded/EmbeddedLdapAutoConfigurationTests.java @@ -131,6 +131,29 @@ public class EmbeddedLdapAutoConfigurationTests { 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(); + } + + @Test + public void testCustomSchemaValidation() throws LDAPException { + load("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); + + assertThat(server.getSchema().getObjectClass("exampleAuxiliaryClass")) + .isNotNull(); + assertThat(server.getSchema().getAttributeType("exampleAttributeName")) + .isNotNull(); + } + private void load(String... properties) { EnvironmentTestUtils.addEnvironment(this.context, properties); this.context.register(EmbeddedLdapAutoConfiguration.class, diff --git a/spring-boot-autoconfigure/src/test/resources/custom-schema-sample.ldif b/spring-boot-autoconfigure/src/test/resources/custom-schema-sample.ldif new file mode 100644 index 0000000000..c5b81e84ce --- /dev/null +++ b/spring-boot-autoconfigure/src/test/resources/custom-schema-sample.ldif @@ -0,0 +1,7 @@ +dn: dc=spring,dc=org +objectclass: top +objectclass: domain +objectclass: extensibleObject +objectClass: exampleAuxiliaryClass +dc: spring +exampleAttributeName: exampleAttributeName diff --git a/spring-boot-autoconfigure/src/test/resources/custom-schema.ldif b/spring-boot-autoconfigure/src/test/resources/custom-schema.ldif new file mode 100644 index 0000000000..a561a201cb --- /dev/null +++ b/spring-boot-autoconfigure/src/test/resources/custom-schema.ldif @@ -0,0 +1,17 @@ +dn: cn=schema +attributeTypes: ( 1.3.6.1.4.1.32473.1.1.1 + NAME 'exampleAttributeName' + DESC 'An example attribute type definition' + EQUALITY caseIgnoreMatch + ORDERING caseIgnoreOrderingMatch + SUBSTR caseIgnoreSubstringsMatch + SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 + SINGLE-VALUE + X-ORIGIN 'Managing Schema Document' ) +objectClasses: ( 1.3.6.1.4.1.32473.1.2.2 + NAME 'exampleAuxiliaryClass' + DESC 'An example auxiliary object class definition' + SUP top + AUXILIARY + MAY exampleAttributeName + X-ORIGIN 'Managing Schema Document' ) \ No newline at end of file