├── .gitignore ├── .travis.yml ├── LICENSE.md ├── README.md ├── pom.xml ├── src ├── main │ └── java │ │ └── com │ │ └── github │ │ └── trevershick │ │ └── test │ │ └── ldap │ │ ├── LdapServerResource.java │ │ ├── annotations │ │ ├── LdapAttribute.java │ │ ├── LdapConfiguration.java │ │ ├── LdapEntry.java │ │ └── Ldif.java │ │ └── junit4 │ │ └── LdapServerRule.java └── test │ ├── java │ └── com │ │ └── github │ │ └── trevershick │ │ └── test │ │ └── ldap │ │ ├── AnnotationsAreInheritedTest.java │ │ ├── BasicCustomAnnotationsTest.java │ │ ├── CustomEntriesAnnotationsTest.java │ │ ├── DefaultAnnotationsTest.java │ │ ├── DontFallBackToRandomTest.java │ │ ├── FallBackToRandomTest.java │ │ ├── LdifLoadTest.java │ │ ├── LdifSchemaLoadTest.java │ │ ├── LoginWithUserTest.java │ │ ├── Utils.java │ │ └── junit4 │ │ ├── Junit4DefaultAnnotationsTest.java │ │ ├── Junit4SchemaOnByDefaultTest.java │ │ └── Junit4UseSchemaFalseTest.java │ └── resources │ ├── schematest.ldif │ └── test.ldif └── travis-settings.xml /.gitignore: -------------------------------------------------------------------------------- 1 | target 2 | .idea/ 3 | ldap-test-utils.iml 4 | .project 5 | .settings 6 | .classpath 7 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: java 2 | jdk: 3 | - oraclejdk8 4 | env: 5 | global: 6 | - secure: asfSFa+J2vwX9urY7RLFLVNN5C4g3HPJTb0wgzMsF/OaIRY3Z+9HZDWl1Fv1KjwVXZ3Ju3BMUXaEwb4yZS7kwys84D7l3hHXujPriKq2dw0F/eaPzmv5rzzc5lWtgizq6CSOzm3OYMUolnkCFR0AavTO0QzXKwauIkyrsCy7Wxg= 7 | - secure: b2Lf4OVrshIw557wtD+9t9WPkoCQ46sgmz/TN0VJKJvFkflUKAgsqyeU2RjhBGgW88jZ2eOEWsEKkKt92lJqADcrEw8+ZO0urk4MtOec/8dM0YLreb9NCfrBHmWDT5LygNdNv6ggMBQd5sE0QqecK9TFJkSsOu6R2/FLcr/G/X0= 8 | - secure: YhRRfOntaOaNR6WsJ+2k/peOp8qnBVHmuSIKSagvyLhHqyk8CFW85WtTG+l/0jn7W+nm6+lxLeweDKGqPaXRMdNWJZk25nDwOB3nJN2OO9jq57nqjDtoV8a4ARDroumWjQZsxRvGTKkjILdvdPbyRLvqtKa7gYfQMAg9dJlHR1Q= 9 | after_success: 10 | - mvn clean test jacoco:report coveralls:report deploy --settings travis-settings.xml 11 | -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | Copyright © 2013 Trever Shick, http://github.com/trevershick/ldap-test-utils 3 | 4 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 5 | 6 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 7 | 8 | THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 9 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | Test Utilities for working with LDAP 2 | ==================================== 3 | [![Maven Status](https://maven-badges.herokuapp.com/maven-central/com.github.trevershick/ldap-test-utils/badge.svg?style=flat)](http://mvnrepository.com/artifact/com.github.trevershick/ldap-test-utils) 4 | [![Build Status](https://travis-ci.org/trevershick/ldap-test-utils.png?branch=master)](https://travis-ci.org/trevershick/ldap-test-utils) 5 | [![Coverage Status](https://coveralls.io/repos/github/trevershick/ldap-test-utils/badge.svg?branch=master)](https://coveralls.io/github/trevershick/ldap-test-utils?branch=master) 6 | [![Dependency Status](https://www.versioneye.com/user/projects/582bad90c8dd330040426f8d/badge.svg?style=flat-square)](https://www.versioneye.com/user/projects/5827c5f22f4754004186d0b3) 7 | [![License](http://img.shields.io/:license-mit-brightgreen.svg)](http://www.apache.org/licenses/LICENSE-2.0.html) 8 | 9 | 10 | This is a simple library that you can use which will make setting up 11 | unboundid's embedded LDAP server a snap for your unit tests. 12 | 13 | I credit [this Stack Overflow answer](http://stackoverflow.com/questions/7269697/embedded-memory-ldap-server-solution/7274215), as well as [this blog post](http://ff1959.wordpress.com/2011/11/01/ldap-in-memory-directory-server-using-unboundid-ldap-sdk/) for getting me pointed in the right direction. 14 | 15 | After playing around with the LDAP SDK and writing some tests, I found myself writing 16 | a lot of boilerplate code. I figured i'd extract out the details and make it REALLY 17 | easy to write an LDAP backed test. 18 | 19 | Getting Started 20 | --------------- 21 | 22 | *Note* - I don't have this code deployed in a Maven repository anywhere. Thus, you'll have to download it and build it yourself. If you have an internal repository yourself, you can deploy it there. 23 | 24 | *JUnit users can use the supplied JUnit ``Rule`` (see further down)* 25 | 26 | 1. Import the dependency into your POM. 27 | 2. Create your test class 28 | 3. Annotate your test class (optional) 29 | 4. Create an instance of ``LdapServerResource`` in your setup code 30 | 5. Tear down the instance of ``LdapServerResource`` in your tear down code. 31 | 6. Run your test 32 | 33 | The Dependency 34 | -------------- 35 | 36 | 37 | com.trevershick.test 38 | ldap-test-utils 39 | 1.0.0-SNAPSHOT 40 | test 41 | 42 | 43 | ## Example Tests 44 | 45 | 46 | ### Default Configuration (no annotations) 47 | 48 | Calling ``new LdapServerResource()`` with no constructor arguments forces the use of defaults. All default values can be found in the ``LdapConfiguration`` annotation. 49 | 50 | public class DefaultAnnotationsTest { 51 | private LdapServerResource server; 52 | 53 | @Before 54 | public void startup() throws Exception { 55 | server = new LdapServerResource().start(); 56 | } 57 | 58 | @After 59 | public void shutdown() { server.stop(); } 60 | 61 | 62 | @Test 63 | public void testStartsUpWithDefaults() throws Exception { 64 | LdapContextSource s = new LdapContextSource(); 65 | s.setPassword(LdapConfiguration.DEFAULT_PASSWORD); 66 | ... 67 | } 68 | } 69 | 70 | ### Configuration via Annotations 71 | 72 | The following example shows how to use annotations to alter the default configuration. 73 | 74 | 75 | package com.chickenshick.test.ldap; 76 | @LdapConfiguration( 77 | bindDn = "cn=Directory Manager", 78 | password = "mypass", 79 | port = 11111, 80 | base = @LdapEntry(dn = "dc=myroot", 81 | objectclass = { "top", "domain" }) 82 | ) 83 | public class BasicCustomAnnotationsTest { 84 | 85 | private LdapServerResource server; 86 | 87 | @Before 88 | public void startup() throws Exception { 89 | server = new LdapServerResource(this).start(); 90 | } 91 | 92 | @After 93 | public void shutdown() { 94 | server.stop(); 95 | } 96 | 97 | ### Creating LDAP Entries via Annotations 98 | 99 | By using the ``LdapEntry`` annotation, you can add entries to the LDAP server upon startup. The example test below will add an *organizationalUnit* with the DN *ou=Groups,dc=root* to the LDAP DIT. 100 | 101 | @LdapConfiguration( 102 | entries={ 103 | @LdapEntry(dn="ou=Groups,dc=root",objectclass="organizationalUnit",attributes={@LdapAttribute(name="ou",value="Groups")}) 104 | } 105 | ) 106 | public class CustomEntriesAnnotationsTest { 107 | ... 108 | } 109 | 110 | ### Creating LDAP Entries via LDIF Files 111 | 112 | Alternately, you can use LDIF files to add entries (or schema changes). The example below shows a test that will use the ``test.ldif`` file in the root of the classpath. 113 | 114 | @LdapConfiguration( 115 | ldifs = @Ldif("/test.ldif") 116 | ) 117 | public class LdifLoadTest { 118 | ... 119 | } 120 | 121 | ### Updating the LDAP Schema via LDIF Files 122 | 123 | The in memory ldap server's schema can be altered via LDIF files. The following stanza 124 | comes from schematest.ldif in the src/test folder of the project. This file can be loaded 125 | just like any other LDIF file. 126 | 127 | dn: cn=schema 128 | changetype: modify 129 | add: attributetypes 130 | attributetypes: ( 1.2.3.4.5.6.7 NAME 'userPrincipalName' DESC 'userPrincipalName as per Active Directory' EQUALITY caseIgnoreMatch SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' ) 131 | 132 | 133 | ## Example JUnit Test 134 | 135 | package com.github.trevershick.test.ldap.junit4; 136 | 137 | 138 | @LdapConfiguration(useRandomPortAsFallback=true) 139 | public class Junit4DefaultAnnotationsTest { 140 | 141 | /** 142 | * Initializes the server 143 | */ 144 | @Rule 145 | public LdapServerRule rule = new LdapServerRule(this); 146 | 147 | @Test 148 | public void testStartsUpWithDefaults() throws Exception { 149 | LdapTemplate t = new LdapTemplate(); 150 | ... 151 | } 152 | } 153 | 154 | ## Useful Configuration Attributes 155 | ### useRandomPortAsFallback 156 | By default, the LdapServer is configured to bind to port 10389. This is fine if you're running the tasks on your machine manually. However, if running in a CI environment with multiple LDAP tests running concurrently you could run into a BindException. By default, ``LdapServerResource`` does NOT fallback to a random port. If it can't bind to 10389 (or your configured port #) then it throws a ``BindException``. 157 | 158 | You can alter this configuration option by specifying ``useRandomPortAsFallback=true`` on the ``@LdapConfiguration`` annotation. 159 | 160 | The following test illustrates this feature. 161 | 162 | package com.github.trevershick.test.ldap; 163 | 164 | 165 | @LdapConfiguration(useRandomPortAsFallback=true) 166 | public class FallBackToRandomTest { 167 | 168 | @Test 169 | public void wontFallbackToRandom() throws Exception { 170 | LdapServerResource s1 = new LdapServerResource().start(); 171 | assertEquals(LdapConfiguration.DEFAULT_PORT, s1.port()); 172 | 173 | LdapServerResource s2 = new LdapServerResource(this).start(); 174 | assertTrue(s2.isStarted()); 175 | assertTrue(s2.port() != LdapConfiguration.DEFAULT_PORT); 176 | 177 | s1.stop(); 178 | s2.stop(); 179 | } 180 | } 181 | 182 | ### useSchema 183 | By default, the LDAP server will use schema. 184 | To disable this (particularly useful when you're doing TDD and building 185 | things up gradually) you can disable schema validation completely. 186 | 187 | 188 | @LdapConfiguration(useSchema=false) 189 | public class DisableSchemaTest { 190 | 191 | @Test 192 | public void wontValidateSchema() throws Exception { 193 | LdapServerResource s1 = new LdapServerResource(this); 194 | assertEquals("Schema should be null", null, s1.getServer().getConfig().getSchema()); 195 | } 196 | } -------------------------------------------------------------------------------- /pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4.0.0 3 | 4 | 5 | org.sonatype.oss 6 | oss-parent 7 | 7 8 | 9 | 10 | com.github.trevershick 11 | ldap-test-utils 12 | 2.0.2-SNAPSHOT 13 | jar 14 | Test Utilities for working with LDAP 15 | Client library that makes it easy to test with an embedded LDAP server (from unboundid). 16 | https://github.com/trevershick/ldap-test-utils 17 | 18 | 19 | 1.8 20 | 1.8 21 | UTF-8 22 | 23 | 24 | 25 | 26 | MIT 27 | http://www.apache.org/licenses/LICENSE-2.0.html 28 | 29 | 30 | 31 | scm:git:git@github.com:trevershick/ldap-test-utils.git 32 | scm:git:git@github.com:trevershick/ldap-test-utils.git 33 | scm:git:git@github.com:trevershick/ldap-test-utils.git 34 | HEAD 35 | 36 | 37 | 38 | 39 | Trever Shick 40 | trever@shick.io 41 | 42 | 43 | 44 | 45 | ossrh 46 | https://oss.sonatype.org/content/repositories/snapshots 47 | 48 | 49 | ossrh 50 | https://oss.sonatype.org/service/local/staging/deploy/maven2/ 51 | 52 | 53 | 54 | 55 | 56 | org.jacoco 57 | jacoco-maven-plugin 58 | 0.7.9 59 | 60 | 61 | prepare-agent 62 | 63 | prepare-agent 64 | 65 | 66 | 67 | 68 | 69 | org.apache.maven.plugins 70 | maven-source-plugin 71 | 3.0.1 72 | 73 | 74 | attach-sources 75 | 76 | jar-no-fork 77 | 78 | 79 | 80 | 81 | 82 | org.apache.maven.plugins 83 | maven-javadoc-plugin 84 | 2.10.4 85 | 86 | public 87 | true 88 | 89 | 90 | todo 91 | a 92 | To do: 93 | 94 | 95 | 96 | 97 | 98 | attach-javadocs 99 | 100 | jar 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | maven-compiler-plugin 110 | 3.6.2 111 | 112 | 113 | org.eluder.coveralls 114 | coveralls-maven-plugin 115 | 4.3.0 116 | 117 | ${env.COVERALLS_TOKEN} 118 | 119 | 120 | 121 | 122 | org.apache.maven.plugins 123 | maven-release-plugin 124 | 2.5.3 125 | 126 | true 127 | false 128 | release 129 | deploy 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | com.unboundid 139 | unboundid-ldapsdk 140 | 4.0.0 141 | compile 142 | 143 | 144 | junit 145 | junit 146 | 4.12 147 | true 148 | 149 | 150 | org.springframework.ldap 151 | spring-ldap-core 152 | 2.3.1.RELEASE 153 | test 154 | 155 | 156 | 157 | 158 | 159 | release 160 | 161 | 162 | 163 | org.apache.maven.plugins 164 | maven-gpg-plugin 165 | 1.6 166 | 167 | 168 | sign-artifacts 169 | verify 170 | 171 | sign 172 | 173 | 174 | 175 | 176 | 177 | 178 | 179 | 180 | 181 | 182 | -------------------------------------------------------------------------------- /src/main/java/com/github/trevershick/test/ldap/LdapServerResource.java: -------------------------------------------------------------------------------- 1 | package com.github.trevershick.test.ldap; 2 | 3 | import com.github.trevershick.test.ldap.annotations.LdapAttribute; 4 | import com.github.trevershick.test.ldap.annotations.LdapConfiguration; 5 | import com.github.trevershick.test.ldap.annotations.LdapEntry; 6 | import com.github.trevershick.test.ldap.annotations.Ldif; 7 | import com.unboundid.ldap.listener.InMemoryDirectoryServer; 8 | import com.unboundid.ldap.listener.InMemoryDirectoryServerConfig; 9 | import com.unboundid.ldap.listener.InMemoryListenerConfig; 10 | import com.unboundid.ldap.sdk.DN; 11 | import com.unboundid.ldap.sdk.Entry; 12 | import com.unboundid.ldap.sdk.LDAPException; 13 | import com.unboundid.ldap.sdk.SearchResultEntry; 14 | import com.unboundid.ldif.LDIFChangeRecord; 15 | import com.unboundid.ldif.LDIFReader; 16 | 17 | import java.io.FileNotFoundException; 18 | import java.io.InputStream; 19 | import java.net.BindException; 20 | import java.util.ArrayList; 21 | import java.util.List; 22 | 23 | @LdapConfiguration 24 | public class LdapServerResource { 25 | 26 | private InMemoryDirectoryServer server; 27 | private LdapConfiguration config; 28 | private Class annotatedClass; 29 | 30 | public LdapServerResource() { 31 | this(null); 32 | } 33 | 34 | public LdapServerResource(Object annotated) { 35 | this.config = annotated == null ? null : annotated.getClass().getAnnotation(LdapConfiguration.class); 36 | if (this.config == null) { 37 | this.config = defaultConfiguration(); 38 | } else { 39 | annotatedClass = annotated.getClass(); 40 | } 41 | } 42 | 43 | public int port() { 44 | if (!isStarted()) { 45 | throw new IllegalStateException("The LDAP server is not started"); 46 | } 47 | return this.server.getListenPort(); 48 | } 49 | 50 | public void stop() { 51 | if (server != null) { 52 | server.shutDown(true); 53 | } 54 | server = null; 55 | } 56 | 57 | public boolean isStarted() { 58 | return this.server != null; 59 | } 60 | 61 | public boolean isStopped() { 62 | return !isStarted(); 63 | } 64 | 65 | public boolean isUsingSchema() throws LDAPException { 66 | return this.server.getSchema() != null; 67 | } 68 | 69 | 70 | public LdapServerResource start() throws Exception { 71 | if (server != null) { 72 | throw new IllegalStateException("server is already initialized"); 73 | } 74 | 75 | try { 76 | server = configureWithPort(config.port()); 77 | } catch (BindException be) { 78 | if (config.useRandomPortAsFallback()) { 79 | server = configureWithPort(0); 80 | } else { 81 | throw be; 82 | } 83 | } 84 | 85 | // initialize the user store 86 | loadLdifFiles(); 87 | loadRootEntry(); 88 | loadEntries(); 89 | return this; 90 | } 91 | 92 | protected InMemoryDirectoryServer configureWithPort(int port) throws LDAPException, BindException { 93 | InMemoryListenerConfig listenerConfig = (port > 0) ? 94 | InMemoryListenerConfig.createLDAPConfig("default", config.port()) : 95 | InMemoryListenerConfig.createLDAPConfig("default"); 96 | 97 | InMemoryDirectoryServerConfig c = new InMemoryDirectoryServerConfig(new DN(config.base().dn())); 98 | c.setListenerConfigs(listenerConfig); 99 | c.addAdditionalBindCredentials(config.bindDn(), config.password()); 100 | if (!config.useSchema()) { 101 | c.setSchema(null); 102 | } 103 | server = new InMemoryDirectoryServer(c); 104 | try { 105 | server.startListening(); 106 | return server; 107 | } catch (LDAPException ldape) { 108 | if (ldape.getMessage().contains("BindException")) { 109 | throw new BindException(ldape.getMessage()); 110 | } 111 | throw ldape; 112 | } 113 | } 114 | 115 | protected LdapConfiguration defaultConfiguration() { 116 | return LdapServerResource.class.getAnnotation(LdapConfiguration.class); 117 | } 118 | 119 | protected void loadRootEntry() throws LDAPException { 120 | SearchResultEntry entry = this.server.getEntry(config.base().dn()); 121 | if (entry == null) { 122 | this.server.add(entry(config.base())); 123 | } 124 | } 125 | 126 | protected void loadEntries() throws LDAPException { 127 | LdapEntry[] entries = config.entries(); 128 | if (entries == null || entries.length == 0) { 129 | return; 130 | } 131 | // build an entry from the annotation 132 | for (int i = 0; i < entries.length; i++) { 133 | Entry entry = entry(entries[i]); 134 | this.server.add(entry); 135 | } 136 | } 137 | 138 | /** 139 | * Build an LDAP entry from the @LdapEntry annotation 140 | */ 141 | private Entry entry(LdapEntry ldapEntry) { 142 | Entry e = new Entry(ldapEntry.dn()); 143 | e.addAttribute("objectClass", ldapEntry.objectclass()); 144 | LdapAttribute[] attrs = ldapEntry.attributes(); 145 | for (int i = 0; attrs != null && i < attrs.length; i++) { 146 | e.addAttribute(attrs[i].name(), attrs[i].value()); 147 | } 148 | return e; 149 | } 150 | 151 | /** 152 | * Load any LDIF files identified within the annotation @Ldif 153 | */ 154 | protected void loadLdifFiles() throws Exception { 155 | Iterable ldifResources = ldifResources(); 156 | for (String ldif : ldifResources) { 157 | Class clazz = (annotatedClass != null) ? annotatedClass : getClass(); 158 | InputStream resourceAsStream = clazz.getResourceAsStream(ldif); 159 | if (resourceAsStream == null) { 160 | throw new FileNotFoundException("Should be able to load " + ldif); 161 | } 162 | LDIFReader r = new LDIFReader(resourceAsStream); 163 | LDIFChangeRecord readEntry = null; 164 | while ((readEntry = r.readChangeRecord()) != null) { 165 | readEntry.processChange(server); 166 | } 167 | resourceAsStream.close(); 168 | } 169 | } 170 | 171 | protected Iterable ldifResources() { 172 | Ldif[] annotation = config.ldifs(); 173 | List ldifs = new ArrayList(0); 174 | for (int i = 0; annotation != null && i < annotation.length; i++) { 175 | ldifs.add(annotation[i].value()); 176 | } 177 | return ldifs; 178 | } 179 | } 180 | -------------------------------------------------------------------------------- /src/main/java/com/github/trevershick/test/ldap/annotations/LdapAttribute.java: -------------------------------------------------------------------------------- 1 | package com.github.trevershick.test.ldap.annotations; 2 | 3 | public @interface LdapAttribute { 4 | String name(); 5 | 6 | String[] value(); 7 | } 8 | -------------------------------------------------------------------------------- /src/main/java/com/github/trevershick/test/ldap/annotations/LdapConfiguration.java: -------------------------------------------------------------------------------- 1 | package com.github.trevershick.test.ldap.annotations; 2 | 3 | import java.lang.annotation.ElementType; 4 | import java.lang.annotation.Inherited; 5 | import java.lang.annotation.Retention; 6 | import java.lang.annotation.RetentionPolicy; 7 | import java.lang.annotation.Target; 8 | 9 | @Inherited 10 | @Retention(RetentionPolicy.RUNTIME) 11 | @Target(ElementType.TYPE) 12 | public @interface LdapConfiguration { 13 | String DEFAULT_ROOT_OBJECT_DN = "dc=root"; 14 | String DEFAULT_ROOT_ENTRY_OBJECTCLASS = "domain"; 15 | int DEFAULT_PORT = 10389; 16 | String DEFAULT_PASSWORD = "password"; 17 | String DEFAULT_BIND_DN = "cn=admin"; 18 | 19 | boolean useRandomPortAsFallback() default false; 20 | 21 | int port() default DEFAULT_PORT; 22 | 23 | LdapEntry base() default @LdapEntry(objectclass = DEFAULT_ROOT_ENTRY_OBJECTCLASS, dn = DEFAULT_ROOT_OBJECT_DN); 24 | 25 | LdapEntry[] entries() default {}; 26 | 27 | Ldif[] ldifs() default {}; 28 | 29 | String bindDn() default DEFAULT_BIND_DN; 30 | 31 | String password() default DEFAULT_PASSWORD; 32 | 33 | boolean useSchema() default true; 34 | } 35 | -------------------------------------------------------------------------------- /src/main/java/com/github/trevershick/test/ldap/annotations/LdapEntry.java: -------------------------------------------------------------------------------- 1 | package com.github.trevershick.test.ldap.annotations; 2 | 3 | import java.lang.annotation.Retention; 4 | import java.lang.annotation.RetentionPolicy; 5 | 6 | @Retention(RetentionPolicy.RUNTIME) 7 | public abstract @interface LdapEntry { 8 | String dn(); 9 | 10 | String[] objectclass(); 11 | 12 | LdapAttribute[] attributes() default {}; 13 | } 14 | -------------------------------------------------------------------------------- /src/main/java/com/github/trevershick/test/ldap/annotations/Ldif.java: -------------------------------------------------------------------------------- 1 | package com.github.trevershick.test.ldap.annotations; 2 | 3 | import java.lang.annotation.Retention; 4 | import java.lang.annotation.RetentionPolicy; 5 | 6 | @Retention(RetentionPolicy.RUNTIME) 7 | public @interface Ldif { 8 | String value(); 9 | } 10 | -------------------------------------------------------------------------------- /src/main/java/com/github/trevershick/test/ldap/junit4/LdapServerRule.java: -------------------------------------------------------------------------------- 1 | package com.github.trevershick.test.ldap.junit4; 2 | 3 | import com.unboundid.ldap.sdk.LDAPException; 4 | import org.junit.rules.TestRule; 5 | import org.junit.runner.Description; 6 | import org.junit.runners.model.Statement; 7 | 8 | import com.github.trevershick.test.ldap.LdapServerResource; 9 | 10 | public class LdapServerRule implements TestRule { 11 | private LdapServerResource ldapServer; 12 | 13 | private Object target; 14 | 15 | public LdapServerRule() { 16 | 17 | } 18 | 19 | public LdapServerRule(Object target) { 20 | this.target = target; 21 | } 22 | 23 | public Statement apply(final Statement base, Description description) { 24 | return new Statement() { 25 | @Override 26 | public void evaluate() throws Throwable { 27 | ldapServer = new LdapServerResource(target); 28 | try { 29 | ldapServer.start(); 30 | base.evaluate(); 31 | } finally { 32 | if (ldapServer.isStarted()) { 33 | ldapServer.stop(); 34 | } 35 | } 36 | ldapServer = null; 37 | } 38 | }; 39 | } 40 | 41 | public int port() { 42 | return ldapServer.port(); 43 | } 44 | 45 | public boolean serverIsStarted() { 46 | return ldapServer != null && ldapServer.isStarted(); 47 | } 48 | 49 | public boolean serverIsStopped() { 50 | return ldapServer != null && ldapServer.isStopped(); 51 | } 52 | 53 | public boolean isUsingSchema() throws Exception { 54 | return this.ldapServer.isUsingSchema(); 55 | } 56 | 57 | LdapServerResource getServer() { 58 | return this.ldapServer; 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /src/test/java/com/github/trevershick/test/ldap/AnnotationsAreInheritedTest.java: -------------------------------------------------------------------------------- 1 | package com.github.trevershick.test.ldap; 2 | 3 | import org.junit.Test; 4 | 5 | public class AnnotationsAreInheritedTest extends CustomEntriesAnnotationsTest { 6 | 7 | /** 8 | * This should inherit the custom configuration from CustomEntriesAnnotationTest. 9 | * Thus, it can call the parent class test and it should still pass. I can't change 10 | * the inherited attribute of the annotation to false for a negative test, but i 11 | * did remove the @Inherited from the annotation and reran the test and this test 12 | * then fails. 13 | */ 14 | @Test 15 | public void shouldInheritConfigFromParentClass() throws Exception { 16 | super.testStartsUpWithMyEntries(); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /src/test/java/com/github/trevershick/test/ldap/BasicCustomAnnotationsTest.java: -------------------------------------------------------------------------------- 1 | package com.github.trevershick.test.ldap; 2 | 3 | import static com.github.trevershick.test.ldap.Utils.Filters.OBJECTCLASS_PRESENT; 4 | import static com.github.trevershick.test.ldap.Utils.Mappers.DN_MAPPER; 5 | import static com.github.trevershick.test.ldap.Utils.Spring.ldapTemplate; 6 | import static org.hamcrest.CoreMatchers.hasItems; 7 | import static org.junit.Assert.assertThat; 8 | 9 | import java.util.List; 10 | 11 | import org.junit.Rule; 12 | import org.junit.Test; 13 | import org.springframework.ldap.core.LdapTemplate; 14 | 15 | import com.github.trevershick.test.ldap.annotations.LdapConfiguration; 16 | import com.github.trevershick.test.ldap.annotations.LdapEntry; 17 | import com.github.trevershick.test.ldap.junit4.LdapServerRule; 18 | 19 | @LdapConfiguration( 20 | bindDn = "cn=Directory Manager", 21 | password = "mypass", 22 | port = 11111, 23 | base = @LdapEntry(dn = "dc=myroot", objectclass = {"top", "domain"}) 24 | ) 25 | public class BasicCustomAnnotationsTest { 26 | 27 | @Rule 28 | public LdapServerRule rule = new LdapServerRule(this); 29 | 30 | @Test 31 | public void testStartsUpWithMyValues() throws Exception { 32 | final LdapTemplate t = ldapTemplate("cn=Directory Manager", 33 | "mypass", 34 | 11111); 35 | 36 | final List dns = t.search("", OBJECTCLASS_PRESENT, DN_MAPPER); 37 | 38 | assertThat(dns, hasItems("dc=myroot")); 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /src/test/java/com/github/trevershick/test/ldap/CustomEntriesAnnotationsTest.java: -------------------------------------------------------------------------------- 1 | package com.github.trevershick.test.ldap; 2 | 3 | import static com.github.trevershick.test.ldap.Utils.Filters.OU_PRESENT; 4 | import static com.github.trevershick.test.ldap.Utils.Mappers.DN_MAPPER; 5 | import static com.github.trevershick.test.ldap.Utils.Spring.ldapTemplate; 6 | import static org.hamcrest.CoreMatchers.hasItems; 7 | import static org.junit.Assert.assertThat; 8 | 9 | import java.util.List; 10 | 11 | import org.junit.Rule; 12 | import org.junit.Test; 13 | import org.springframework.ldap.core.LdapTemplate; 14 | 15 | import com.github.trevershick.test.ldap.annotations.LdapAttribute; 16 | import com.github.trevershick.test.ldap.annotations.LdapConfiguration; 17 | import com.github.trevershick.test.ldap.annotations.LdapEntry; 18 | import com.github.trevershick.test.ldap.junit4.LdapServerRule; 19 | 20 | @LdapConfiguration( 21 | entries = { 22 | @LdapEntry(dn = "ou=Groups,dc=root", objectclass = "organizationalUnit", attributes = { 23 | @LdapAttribute(name = "ou", value = "Groups")}) 24 | } 25 | ) 26 | public class CustomEntriesAnnotationsTest { 27 | @Rule 28 | public LdapServerRule rule = new LdapServerRule(this); 29 | 30 | @Test 31 | public void testStartsUpWithMyEntries() throws Exception { 32 | LdapTemplate t = ldapTemplate(LdapConfiguration.DEFAULT_BIND_DN, 33 | LdapConfiguration.DEFAULT_PASSWORD, 34 | LdapConfiguration.DEFAULT_PORT); 35 | 36 | final List dns = t.search("", OU_PRESENT, DN_MAPPER); 37 | 38 | assertThat("My OU should have been returned", dns, hasItems("ou=Groups,dc=root")); 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /src/test/java/com/github/trevershick/test/ldap/DefaultAnnotationsTest.java: -------------------------------------------------------------------------------- 1 | package com.github.trevershick.test.ldap; 2 | 3 | import static com.github.trevershick.test.ldap.Utils.Filters.OBJECTCLASS_PRESENT; 4 | import static com.github.trevershick.test.ldap.Utils.Mappers.DN_MAPPER; 5 | import static com.github.trevershick.test.ldap.Utils.Spring.ldapTemplate; 6 | import static org.hamcrest.CoreMatchers.hasItems; 7 | import static org.junit.Assert.assertThat; 8 | 9 | import java.util.List; 10 | 11 | import org.junit.Rule; 12 | import org.junit.Test; 13 | import org.springframework.ldap.core.LdapTemplate; 14 | 15 | import com.github.trevershick.test.ldap.annotations.LdapConfiguration; 16 | import com.github.trevershick.test.ldap.junit4.LdapServerRule; 17 | 18 | public class DefaultAnnotationsTest { 19 | 20 | @Rule 21 | public LdapServerRule rule = new LdapServerRule(this); 22 | 23 | @Test 24 | public void testStartsUpWithDefaults() throws Exception { 25 | LdapTemplate t = ldapTemplate(LdapConfiguration.DEFAULT_BIND_DN, 26 | LdapConfiguration.DEFAULT_PASSWORD, 27 | LdapConfiguration.DEFAULT_PORT); 28 | 29 | final List dns = t.search("", OBJECTCLASS_PRESENT, DN_MAPPER); 30 | 31 | assertThat(dns, hasItems(LdapConfiguration.DEFAULT_ROOT_OBJECT_DN)); 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /src/test/java/com/github/trevershick/test/ldap/DontFallBackToRandomTest.java: -------------------------------------------------------------------------------- 1 | package com.github.trevershick.test.ldap; 2 | 3 | import static org.junit.Assert.assertEquals; 4 | 5 | import java.net.BindException; 6 | 7 | import org.junit.After; 8 | import org.junit.Test; 9 | 10 | import com.github.trevershick.test.ldap.annotations.LdapConfiguration; 11 | 12 | public class DontFallBackToRandomTest { 13 | 14 | private LdapServerResource s1; 15 | 16 | @After 17 | public void cleanup() { 18 | s1.stop(); 19 | } 20 | 21 | @Test(expected = BindException.class) 22 | public void wontFallbackToRandom() throws Exception { 23 | s1 = new LdapServerResource().start(); 24 | assertEquals(LdapConfiguration.DEFAULT_PORT, s1.port()); 25 | 26 | new LdapServerResource().start(); 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /src/test/java/com/github/trevershick/test/ldap/FallBackToRandomTest.java: -------------------------------------------------------------------------------- 1 | package com.github.trevershick.test.ldap; 2 | 3 | import static org.junit.Assert.assertEquals; 4 | import static org.junit.Assert.assertTrue; 5 | 6 | import org.junit.After; 7 | import org.junit.Test; 8 | 9 | import com.github.trevershick.test.ldap.annotations.LdapConfiguration; 10 | 11 | @LdapConfiguration(useRandomPortAsFallback = true) 12 | public class FallBackToRandomTest { 13 | 14 | private LdapServerResource s1; 15 | private LdapServerResource s2; 16 | 17 | @After 18 | public void cleanup1() { 19 | s1.stop(); 20 | } 21 | 22 | @After 23 | public void cleanup2() { 24 | s2.stop(); 25 | } 26 | 27 | @Test 28 | public void wontFallbackToRandom() throws Exception { 29 | s1 = new LdapServerResource().start(); 30 | assertEquals(LdapConfiguration.DEFAULT_PORT, s1.port()); 31 | 32 | s2 = new LdapServerResource(this).start(); 33 | assertTrue(s2.isStarted()); 34 | assertTrue(s2.port() != LdapConfiguration.DEFAULT_PORT); 35 | 36 | s1.stop(); 37 | s2.stop(); 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /src/test/java/com/github/trevershick/test/ldap/LdifLoadTest.java: -------------------------------------------------------------------------------- 1 | package com.github.trevershick.test.ldap; 2 | 3 | import static com.github.trevershick.test.ldap.Utils.Filters.DC_PRESENT; 4 | import static com.github.trevershick.test.ldap.Utils.Mappers.DN_MAPPER; 5 | import static com.github.trevershick.test.ldap.Utils.Spring.ldapTemplate; 6 | import static org.hamcrest.CoreMatchers.hasItems; 7 | import static org.junit.Assert.assertThat; 8 | 9 | import java.util.List; 10 | 11 | import org.junit.Rule; 12 | import org.junit.Test; 13 | import org.springframework.ldap.core.LdapTemplate; 14 | 15 | import com.github.trevershick.test.ldap.annotations.LdapConfiguration; 16 | import com.github.trevershick.test.ldap.annotations.Ldif; 17 | import com.github.trevershick.test.ldap.junit4.LdapServerRule; 18 | 19 | @LdapConfiguration(ldifs = @Ldif("/test.ldif")) 20 | public class LdifLoadTest { 21 | 22 | @Rule 23 | public LdapServerRule rule = new LdapServerRule(this); 24 | 25 | @Test 26 | public void testMyLdifFileWasLoaded() throws Exception { 27 | LdapTemplate t = ldapTemplate(LdapConfiguration.DEFAULT_BIND_DN, 28 | LdapConfiguration.DEFAULT_PASSWORD, 29 | rule.port()); 30 | 31 | final List dns = t.search("", DC_PRESENT, DN_MAPPER); 32 | 33 | assertThat(dns, hasItems("dc=root", "dc=child,dc=root")); 34 | } 35 | 36 | @Test 37 | public void canLoginWithLdifDefinedUser() throws Exception { 38 | 39 | LdapTemplate t = ldapTemplate("cn=tshick2,dc=root", 40 | "thepassword2", 41 | rule.port()); 42 | 43 | final List dns = t.search("", DC_PRESENT, DN_MAPPER); 44 | 45 | assertThat(dns, hasItems("dc=root", "dc=child,dc=root")); 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /src/test/java/com/github/trevershick/test/ldap/LdifSchemaLoadTest.java: -------------------------------------------------------------------------------- 1 | package com.github.trevershick.test.ldap; 2 | 3 | import com.github.trevershick.test.ldap.annotations.LdapConfiguration; 4 | import com.github.trevershick.test.ldap.annotations.Ldif; 5 | import com.github.trevershick.test.ldap.junit4.LdapServerRule; 6 | import org.junit.Rule; 7 | import org.junit.Test; 8 | import org.springframework.ldap.core.LdapTemplate; 9 | 10 | import java.util.List; 11 | 12 | import static com.github.trevershick.test.ldap.Utils.Filters.DC_PRESENT; 13 | import static com.github.trevershick.test.ldap.Utils.Filters.USERPRINCIPAL_PRESENT; 14 | import static com.github.trevershick.test.ldap.Utils.Mappers.DN_MAPPER; 15 | import static com.github.trevershick.test.ldap.Utils.Spring.ldapTemplate; 16 | import static org.hamcrest.CoreMatchers.hasItems; 17 | import static org.junit.Assert.assertThat; 18 | 19 | @LdapConfiguration(ldifs = @Ldif("/schematest.ldif")) 20 | public class LdifSchemaLoadTest { 21 | 22 | @Rule 23 | public LdapServerRule rule = new LdapServerRule(this); 24 | 25 | @Test 26 | public void testMyLdifFileWasLoaded() throws Exception { 27 | LdapTemplate t = ldapTemplate(LdapConfiguration.DEFAULT_BIND_DN, 28 | LdapConfiguration.DEFAULT_PASSWORD, 29 | rule.port()); 30 | 31 | // our schematest.ldif file altered the schema and imported a user 32 | // with 'userPrincipal' that was not there prior to the schema alteration 33 | // we pull the entry here and verify that it came back (which illustrates we 34 | // can modify the schema via ldif files) 35 | final List dns = t.search("", USERPRINCIPAL_PRESENT, DN_MAPPER); 36 | assertThat(dns, hasItems("cn=tshick2,dc=root")); 37 | } 38 | 39 | } 40 | -------------------------------------------------------------------------------- /src/test/java/com/github/trevershick/test/ldap/LoginWithUserTest.java: -------------------------------------------------------------------------------- 1 | package com.github.trevershick.test.ldap; 2 | 3 | import static com.github.trevershick.test.ldap.Utils.Filters.OBJECTCLASS_PRESENT; 4 | import static com.github.trevershick.test.ldap.Utils.Mappers.DN_MAPPER; 5 | import static com.github.trevershick.test.ldap.Utils.Spring.ldapTemplate; 6 | import static org.hamcrest.CoreMatchers.hasItems; 7 | import static org.junit.Assert.assertThat; 8 | 9 | import java.util.List; 10 | 11 | import org.junit.Rule; 12 | import org.junit.Test; 13 | import org.springframework.ldap.core.LdapTemplate; 14 | 15 | import com.github.trevershick.test.ldap.annotations.LdapAttribute; 16 | import com.github.trevershick.test.ldap.annotations.LdapConfiguration; 17 | import com.github.trevershick.test.ldap.annotations.LdapEntry; 18 | import com.github.trevershick.test.ldap.junit4.LdapServerRule; 19 | 20 | @LdapConfiguration( 21 | bindDn = "cn=Directory Manager", 22 | password = "mypass", 23 | port = 11111, 24 | base = @LdapEntry(dn = "dc=myroot", objectclass = {"top", "domain"}), 25 | entries = { 26 | @LdapEntry(dn = "cn=tshick,dc=myroot", 27 | objectclass = {"top", "person"}, 28 | attributes = { 29 | @LdapAttribute(name = "userPassword", value = "thepassword"), 30 | @LdapAttribute(name = "sn", value = "Shick"), 31 | @LdapAttribute(name = "cn", value = "tshick") 32 | }) 33 | } 34 | ) 35 | public class LoginWithUserTest { 36 | 37 | @Rule 38 | public LdapServerRule rule = new LdapServerRule(this); 39 | 40 | @Test 41 | public void canLoginWithUserDefinedInAnnotation() throws Exception { 42 | LdapTemplate t = ldapTemplate("cn=tshick,dc=myroot", 43 | "thepassword", 44 | rule.port()); 45 | 46 | final List dns = t.search("", OBJECTCLASS_PRESENT, DN_MAPPER); 47 | 48 | assertThat(dns, hasItems("dc=myroot", "cn=tshick,dc=myroot")); 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /src/test/java/com/github/trevershick/test/ldap/Utils.java: -------------------------------------------------------------------------------- 1 | package com.github.trevershick.test.ldap; 2 | 3 | import org.springframework.ldap.core.ContextMapper; 4 | import org.springframework.ldap.core.DirContextAdapter; 5 | import org.springframework.ldap.core.LdapTemplate; 6 | import org.springframework.ldap.core.support.LdapContextSource; 7 | import org.springframework.ldap.filter.PresentFilter; 8 | 9 | public class Utils { 10 | public static class Spring { 11 | 12 | public static LdapTemplate ldapTemplate(String bindDn, String password, int port) { 13 | LdapTemplate t = new LdapTemplate(); 14 | LdapContextSource s = new LdapContextSource(); 15 | s.setPassword(password); 16 | s.setUserDn(bindDn); 17 | s.setUrl(String.format("ldap://localhost:%d", port)); 18 | t.setContextSource(s); 19 | 20 | try { 21 | t.afterPropertiesSet(); 22 | } catch (Exception e) { 23 | throw new RuntimeException(e); 24 | } 25 | s.afterPropertiesSet(); 26 | return t; 27 | } 28 | } 29 | 30 | public static class Mappers { 31 | 32 | public static final ContextMapper DN_MAPPER = new ContextMapper() { 33 | public Object mapFromContext(Object ctx) { 34 | DirContextAdapter context = (DirContextAdapter) ctx; 35 | return context.getDn().toString(); 36 | } 37 | }; 38 | } 39 | 40 | public static class Filters { 41 | public static final String OBJECTCLASS_PRESENT = new PresentFilter("objectclass").encode(); 42 | 43 | public static final String DC_PRESENT = new PresentFilter("objectclass").encode(); 44 | 45 | public static final String OU_PRESENT = new PresentFilter("ou").encode(); 46 | 47 | public static final String USERPRINCIPAL_PRESENT = new PresentFilter("userPrincipalName").encode(); 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /src/test/java/com/github/trevershick/test/ldap/junit4/Junit4DefaultAnnotationsTest.java: -------------------------------------------------------------------------------- 1 | package com.github.trevershick.test.ldap.junit4; 2 | 3 | import com.github.trevershick.test.ldap.annotations.LdapConfiguration; 4 | import com.unboundid.ldap.listener.InMemoryDirectoryServer; 5 | import com.unboundid.ldap.sdk.LDAPException; 6 | import com.unboundid.ldap.sdk.schema.Schema; 7 | import org.junit.Rule; 8 | import org.junit.Test; 9 | import org.springframework.ldap.core.LdapTemplate; 10 | 11 | import java.util.List; 12 | 13 | import static com.github.trevershick.test.ldap.Utils.Filters.OBJECTCLASS_PRESENT; 14 | import static com.github.trevershick.test.ldap.Utils.Mappers.DN_MAPPER; 15 | import static com.github.trevershick.test.ldap.Utils.Spring.ldapTemplate; 16 | import static org.junit.Assert.assertEquals; 17 | import static org.junit.Assert.assertNull; 18 | import static org.junit.Assert.assertTrue; 19 | 20 | @LdapConfiguration(useRandomPortAsFallback = true) 21 | public class Junit4DefaultAnnotationsTest { 22 | 23 | /** 24 | * This rule will start and stop the server 'around' the test 25 | */ 26 | @Rule 27 | public LdapServerRule rule = new LdapServerRule(this); 28 | 29 | /** 30 | * You should not do this, but this is here for 'secondRuleStartsRandomPort' 31 | */ 32 | @Rule 33 | public LdapServerRule rule2 = new LdapServerRule(this); 34 | 35 | @Test 36 | public void secondRuleStartsRandomPort() { 37 | assertTrue(rule.serverIsStarted()); 38 | assertTrue(rule2.serverIsStarted()); 39 | assertTrue("One of the 'rules' is using the default port", 40 | LdapConfiguration.DEFAULT_PORT == rule.port() || 41 | LdapConfiguration.DEFAULT_PORT == rule2.port()); 42 | } 43 | 44 | @Test 45 | public void testStartsUpWithDefaults() throws Exception { 46 | final LdapTemplate t = ldapTemplate(LdapConfiguration.DEFAULT_BIND_DN, 47 | LdapConfiguration.DEFAULT_PASSWORD, 48 | LdapConfiguration.DEFAULT_PORT); 49 | 50 | @SuppressWarnings("unchecked") 51 | List dns = t.search("", OBJECTCLASS_PRESENT, DN_MAPPER); 52 | 53 | assertEquals(1, dns.size()); 54 | assertEquals(LdapConfiguration.DEFAULT_ROOT_OBJECT_DN, dns.get(0)); 55 | } 56 | 57 | } 58 | -------------------------------------------------------------------------------- /src/test/java/com/github/trevershick/test/ldap/junit4/Junit4SchemaOnByDefaultTest.java: -------------------------------------------------------------------------------- 1 | package com.github.trevershick.test.ldap.junit4; 2 | 3 | import com.github.trevershick.test.ldap.LdapServerResource; 4 | import com.github.trevershick.test.ldap.annotations.LdapConfiguration; 5 | import com.unboundid.ldap.listener.InMemoryDirectoryServer; 6 | import org.junit.Rule; 7 | import org.junit.Test; 8 | import org.springframework.ldap.core.LdapTemplate; 9 | 10 | import java.lang.reflect.Field; 11 | import java.util.List; 12 | 13 | import static com.github.trevershick.test.ldap.Utils.Filters.OBJECTCLASS_PRESENT; 14 | import static com.github.trevershick.test.ldap.Utils.Mappers.DN_MAPPER; 15 | import static com.github.trevershick.test.ldap.Utils.Spring.ldapTemplate; 16 | import static org.hamcrest.CoreMatchers.is; 17 | import static org.hamcrest.CoreMatchers.not; 18 | import static org.hamcrest.CoreMatchers.nullValue; 19 | import static org.junit.Assert.assertEquals; 20 | import static org.junit.Assert.assertThat; 21 | import static org.junit.Assert.assertTrue; 22 | 23 | @LdapConfiguration(useRandomPortAsFallback = true) 24 | public class Junit4SchemaOnByDefaultTest { 25 | 26 | @Rule 27 | public LdapServerRule rule = new LdapServerRule(this); 28 | 29 | @Test 30 | public void testSchemaTurnedOff() throws Exception { 31 | Field serverField = LdapServerResource.class.getDeclaredField("server"); 32 | // i do not expose the server to anyone outside the package so 33 | // we have to make this accessible 34 | serverField.setAccessible(true); 35 | InMemoryDirectoryServer imds = (InMemoryDirectoryServer) serverField.get(rule.getServer()); 36 | assertThat("The schema in the underlying implementation should NOT be null", 37 | imds.getSchema(), 38 | is(not(nullValue()))); 39 | assertThat(rule.isUsingSchema(), is(true)); 40 | } 41 | 42 | } 43 | -------------------------------------------------------------------------------- /src/test/java/com/github/trevershick/test/ldap/junit4/Junit4UseSchemaFalseTest.java: -------------------------------------------------------------------------------- 1 | package com.github.trevershick.test.ldap.junit4; 2 | 3 | import com.github.trevershick.test.ldap.LdapServerResource; 4 | import com.github.trevershick.test.ldap.annotations.LdapConfiguration; 5 | import com.unboundid.ldap.listener.InMemoryDirectoryServer; 6 | import com.unboundid.ldap.sdk.LDAPException; 7 | import com.unboundid.ldap.sdk.schema.Schema; 8 | import org.junit.After; 9 | import org.junit.Before; 10 | import org.junit.Rule; 11 | import org.junit.Test; 12 | import org.springframework.ldap.core.LdapTemplate; 13 | 14 | import java.lang.reflect.Field; 15 | import java.util.List; 16 | 17 | import static com.github.trevershick.test.ldap.Utils.Filters.OBJECTCLASS_PRESENT; 18 | import static com.github.trevershick.test.ldap.Utils.Mappers.DN_MAPPER; 19 | import static com.github.trevershick.test.ldap.Utils.Spring.ldapTemplate; 20 | import static org.hamcrest.CoreMatchers.is; 21 | import static org.hamcrest.CoreMatchers.nullValue; 22 | import static org.junit.Assert.*; 23 | 24 | /** 25 | * Verify that we can startup the ldap server without a schema. 26 | */ 27 | @LdapConfiguration(useRandomPortAsFallback = true, useSchema = false) 28 | public class Junit4UseSchemaFalseTest { 29 | 30 | @Rule 31 | public LdapServerRule rule = new LdapServerRule(this); 32 | 33 | @Test 34 | public void testSchemaTurnedOff() throws Exception { 35 | Field serverField = LdapServerResource.class.getDeclaredField("server"); 36 | // i do not expose the server to anyone outside the package so 37 | // we have to make this accessible 38 | serverField.setAccessible(true); 39 | InMemoryDirectoryServer imds = (InMemoryDirectoryServer) serverField.get(rule.getServer()); 40 | assertThat("The schema in the underlying implementation should be null", 41 | imds.getSchema(), 42 | is(nullValue())); 43 | assertThat(rule.isUsingSchema(), is(false)); 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /src/test/resources/schematest.ldif: -------------------------------------------------------------------------------- 1 | dn: cn=schema 2 | changetype: modify 3 | add: attributetypes 4 | attributetypes: ( 1.2.3.4.5.6.7 NAME 'userPrincipalName' DESC 'userPrincipalName as per Active Directory' EQUALITY caseIgnoreMatch SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' ) 5 | 6 | dn: cn=schema 7 | changetype: modify 8 | delete: objectClasses 9 | objectClasses: ( 2.5.6.6 10 | NAME 'person' 11 | SUP top 12 | STRUCTURAL 13 | MUST ( sn $ 14 | cn ) 15 | MAY ( userPassword $ 16 | telephoneNumber $ 17 | seeAlso $ 18 | description ) 19 | X-ORIGIN 'RFC 4519' ) 20 | 21 | dn: cn=schema 22 | changetype: modify 23 | add: objectClasses 24 | objectClasses: ( 2.5.6.6 25 | NAME 'person' 26 | SUP top 27 | STRUCTURAL 28 | MUST ( sn $ 29 | cn $ 30 | userPrincipalName ) 31 | MAY ( userPassword $ 32 | telephoneNumber $ 33 | seeAlso $ 34 | description ) ) 35 | 36 | dn: dc=root 37 | changetype: add 38 | objectclass: domain 39 | dc: root 40 | 41 | dn: dc=child,dc=root 42 | changetype: add 43 | objectclass: domain 44 | dc: child 45 | 46 | dn: cn=tshick2,dc=root 47 | changetype: add 48 | objectclass: person 49 | userPassword: thepassword2 50 | userPrincipalName: trever.shick 51 | sn: Shick 52 | cn: tshick 53 | 54 | 55 | -------------------------------------------------------------------------------- /src/test/resources/test.ldif: -------------------------------------------------------------------------------- 1 | dn: dc=root 2 | changetype: add 3 | objectclass: domain 4 | dc: root 5 | 6 | dn: dc=child,dc=root 7 | changetype: add 8 | objectclass: domain 9 | dc: child 10 | 11 | dn: cn=tshick2,dc=root 12 | changetype: add 13 | objectclass: person 14 | userPassword: thepassword2 15 | sn: Shick 16 | cn: tshick 17 | 18 | 19 | -------------------------------------------------------------------------------- /travis-settings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | ossrh 5 | ${env.CI_DEPLOY_USERNAME} 6 | ${env.CI_DEPLOY_PASSWORD} 7 | 8 | 9 | 10 | --------------------------------------------------------------------------------