Repository: james-project Updated Branches: refs/heads/master b076dab85 -> ce8cf479a
JAMES-2615 Merge data-ldap and data-ldap-integration-test Project: http://git-wip-us.apache.org/repos/asf/james-project/repo Commit: http://git-wip-us.apache.org/repos/asf/james-project/commit/ffded847 Tree: http://git-wip-us.apache.org/repos/asf/james-project/tree/ffded847 Diff: http://git-wip-us.apache.org/repos/asf/james-project/diff/ffded847 Branch: refs/heads/master Commit: ffded8479d75afe29abacc2bb66b5b0eeebd81b1 Parents: b076dab Author: datph <[email protected]> Authored: Thu Nov 29 15:37:46 2018 +0700 Committer: Benoit Tellier <[email protected]> Committed: Mon Dec 3 08:55:52 2018 +0700 ---------------------------------------------------------------------- .../james/user/ldap/DockerLdapSingleton.java | 36 ---- .../james/user/ldap/LdapGenericContainer.java | 114 ------------ .../ldap/ReadOnlyUsersLDAPRepositoryTest.java | 180 ------------------- .../src/test/resources/ldif-files/Dockerfile | 3 - .../src/test/resources/ldif-files/populate.ldif | 12 -- .../src/test/resources/logback-test.xml | 22 --- server/data/data-ldap/pom.xml | 10 ++ .../james/user/ldap/DockerLdapSingleton.java | 36 ++++ .../james/user/ldap/LdapGenericContainer.java | 114 ++++++++++++ .../ldap/ReadOnlyUsersLDAPRepositoryTest.java | 134 +++++++++++++- .../src/test/resources/ldif-files/Dockerfile | 3 + .../src/test/resources/ldif-files/populate.ldif | 12 ++ .../src/test/resources/logback-test.xml | 22 +++ server/pom.xml | 1 - 14 files changed, 327 insertions(+), 372 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/james-project/blob/ffded847/server/data/data-ldap-integration-testing/src/test/java/org/apache/james/user/ldap/DockerLdapSingleton.java ---------------------------------------------------------------------- diff --git a/server/data/data-ldap-integration-testing/src/test/java/org/apache/james/user/ldap/DockerLdapSingleton.java b/server/data/data-ldap-integration-testing/src/test/java/org/apache/james/user/ldap/DockerLdapSingleton.java deleted file mode 100644 index ca8fdaa..0000000 --- a/server/data/data-ldap-integration-testing/src/test/java/org/apache/james/user/ldap/DockerLdapSingleton.java +++ /dev/null @@ -1,36 +0,0 @@ -/**************************************************************** - * Licensed to the Apache Software Foundation (ASF) under one * - * or more contributor license agreements. See the NOTICE file * - * distributed with this work for additional information * - * regarding copyright ownership. The ASF licenses this file * - * to you under the Apache License, Version 2.0 (the * - * "License"); you may not use this file except in compliance * - * with the License. You may obtain a copy of the License at * - * * - * http://www.apache.org/licenses/LICENSE-2.0 * - * * - * Unless required by applicable law or agreed to in writing, * - * software distributed under the License is distributed on an * - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * - * KIND, either express or implied. See the License for the * - * specific language governing permissions and limitations * - * under the License. * - ****************************************************************/ - -package org.apache.james.user.ldap; - -public class DockerLdapSingleton { - public static final String JAMES_USER = "james-user"; - public static final String PASSWORD = "secret"; - public static final String DOMAIN = "james.org"; - public static final String ADMIN_PASSWORD = "mysecretpassword"; - - public static final LdapGenericContainer ldapContainer = LdapGenericContainer.builder() - .domain(DOMAIN) - .password(ADMIN_PASSWORD) - .build(); - - static { - ldapContainer.start(); - } -} http://git-wip-us.apache.org/repos/asf/james-project/blob/ffded847/server/data/data-ldap-integration-testing/src/test/java/org/apache/james/user/ldap/LdapGenericContainer.java ---------------------------------------------------------------------- diff --git a/server/data/data-ldap-integration-testing/src/test/java/org/apache/james/user/ldap/LdapGenericContainer.java b/server/data/data-ldap-integration-testing/src/test/java/org/apache/james/user/ldap/LdapGenericContainer.java deleted file mode 100644 index 40ee62d..0000000 --- a/server/data/data-ldap-integration-testing/src/test/java/org/apache/james/user/ldap/LdapGenericContainer.java +++ /dev/null @@ -1,114 +0,0 @@ -/**************************************************************** - * Licensed to the Apache Software Foundation (ASF) under one * - * or more contributor license agreements. See the NOTICE file * - * distributed with this work for additional information * - * regarding copyright ownership. The ASF licenses this file * - * to you under the Apache License, Version 2.0 (the * - * "License"); you may not use this file except in compliance * - * with the License. You may obtain a copy of the License at * - * * - * http://www.apache.org/licenses/LICENSE-2.0 * - * * - * Unless required by applicable law or agreed to in writing, * - * software distributed under the License is distributed on an * - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * - * KIND, either express or implied. See the License for the * - * specific language governing permissions and limitations * - * under the License. * - ****************************************************************/ -package org.apache.james.user.ldap; - -import org.apache.james.util.docker.RateLimiters; -import org.apache.james.util.docker.SwarmGenericContainer; -import org.junit.rules.ExternalResource; -import org.testcontainers.containers.wait.strategy.HostPortWaitStrategy; -import org.testcontainers.images.builder.ImageFromDockerfile; - -import com.google.common.base.Preconditions; -import com.google.common.base.Strings; - -public class LdapGenericContainer extends ExternalResource { - - public static final int DEFAULT_LDAP_PORT = 389; - - public static Builder builder() { - return new Builder(); - } - - public static class Builder { - - private String domain; - private String password; - - private Builder() { - } - - public Builder domain(String domain) { - this.domain = domain; - return this; - } - - public Builder password(String password) { - this.password = password; - return this; - } - - public LdapGenericContainer build() { - Preconditions.checkState(!Strings.isNullOrEmpty(domain), "'domain' is mandatory"); - Preconditions.checkState(!Strings.isNullOrEmpty(password), "'password' is mandatory"); - return new LdapGenericContainer(createContainer()); - } - - private SwarmGenericContainer createContainer() { - return new SwarmGenericContainer( - new ImageFromDockerfile() - .withFileFromClasspath("populate.ldif", "ldif-files/populate.ldif") - .withFileFromClasspath("Dockerfile", "ldif-files/Dockerfile")) - .withAffinityToContainer() - .withEnv("SLAPD_DOMAIN", domain) - .withEnv("SLAPD_PASSWORD", password) - .withEnv("SLAPD_CONFIG_PASSWORD", password) - .withExposedPorts(LdapGenericContainer.DEFAULT_LDAP_PORT) - .waitingFor(new HostPortWaitStrategy().withRateLimiter(RateLimiters.TWENTIES_PER_SECOND)); - } - } - - private final SwarmGenericContainer container; - - private LdapGenericContainer(SwarmGenericContainer container) { - this.container = container; - } - - @Override - protected void before() { - start(); - } - - @Override - protected void after() { - stop(); - } - - public void start() { - container.start(); - } - - public void stop() { - container.stop(); - } - - public void pause() { - container.pause(); - } - - public void unpause() { - container.unpause(); - } - - public String getLdapHost() { - return "ldap://" + - container.getContainerIp() + - ":" + - LdapGenericContainer.DEFAULT_LDAP_PORT; - } -} http://git-wip-us.apache.org/repos/asf/james-project/blob/ffded847/server/data/data-ldap-integration-testing/src/test/java/org/apache/james/user/ldap/ReadOnlyUsersLDAPRepositoryTest.java ---------------------------------------------------------------------- diff --git a/server/data/data-ldap-integration-testing/src/test/java/org/apache/james/user/ldap/ReadOnlyUsersLDAPRepositoryTest.java b/server/data/data-ldap-integration-testing/src/test/java/org/apache/james/user/ldap/ReadOnlyUsersLDAPRepositoryTest.java deleted file mode 100644 index 25d4622..0000000 --- a/server/data/data-ldap-integration-testing/src/test/java/org/apache/james/user/ldap/ReadOnlyUsersLDAPRepositoryTest.java +++ /dev/null @@ -1,180 +0,0 @@ -/**************************************************************** - * Licensed to the Apache Software Foundation (ASF) under one * - * or more contributor license agreements. See the NOTICE file * - * distributed with this work for additional information * - * regarding copyright ownership. The ASF licenses this file * - * to you under the Apache License, Version 2.0 (the * - * "License"); you may not use this file except in compliance * - * with the License. You may obtain a copy of the License at * - * * - * http://www.apache.org/licenses/LICENSE-2.0 * - * * - * Unless required by applicable law or agreed to in writing, * - * software distributed under the License is distributed on an * - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * - * KIND, either express or implied. See the License for the * - * specific language governing permissions and limitations * - * under the License. * - ****************************************************************/ -package org.apache.james.user.ldap; - -import static org.apache.james.user.ldap.DockerLdapSingleton.ADMIN_PASSWORD; -import static org.apache.james.user.ldap.DockerLdapSingleton.DOMAIN; -import static org.apache.james.user.ldap.DockerLdapSingleton.JAMES_USER; -import static org.apache.james.user.ldap.DockerLdapSingleton.PASSWORD; -import static org.assertj.core.api.Assertions.assertThat; -import static org.mockito.Mockito.mock; - -import org.apache.commons.configuration.HierarchicalConfiguration; -import org.apache.commons.configuration.plist.PropertyListConfiguration; -import org.apache.james.core.MailAddress; -import org.apache.james.domainlist.api.DomainList; -import org.junit.Before; -import org.junit.ClassRule; -import org.junit.Test; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -public class ReadOnlyUsersLDAPRepositoryTest { - - private static final Logger LOGGER = LoggerFactory.getLogger(ReadOnlyUsersLDAPRepositoryTest.class); - private static final String JAMES_USER_MAIL = JAMES_USER + "@" + DOMAIN; - private static final String UNKNOWN = "unknown"; - private static final String BAD_PASSWORD = "badpassword"; - - @ClassRule - public static LdapGenericContainer ldapContainer = LdapGenericContainer.builder() - .domain(DOMAIN) - .password(ADMIN_PASSWORD) - .build(); - - private ReadOnlyUsersLDAPRepository ldapRepository; - private DomainList domainList; - - @Before - public void setup() { - domainList = mock(DomainList.class); - } - - private void startUsersRepository(HierarchicalConfiguration ldapRepositoryConfiguration) throws Exception { - ldapRepository = new ReadOnlyUsersLDAPRepository(domainList); - ldapRepository.configure(ldapRepositoryConfiguration); - ldapRepository.init(); - } - - private HierarchicalConfiguration ldapRepositoryConfiguration() { - PropertyListConfiguration configuration = new PropertyListConfiguration(); - configuration.addProperty("[@ldapHost]", ldapContainer.getLdapHost()); - configuration.addProperty("[@principal]", "cn=admin\\,dc=james\\,dc=org"); - configuration.addProperty("[@credentials]", ADMIN_PASSWORD); - configuration.addProperty("[@userBase]", "ou=People\\,dc=james\\,dc=org"); - configuration.addProperty("[@userIdAttribute]", "uid"); - configuration.addProperty("[@userObjectClass]", "inetOrgPerson"); - configuration.addProperty("[@maxRetries]", "4"); - configuration.addProperty("[@retryStartInterval]", "0"); - configuration.addProperty("[@retryMaxInterval]", "8"); - configuration.addProperty("[@retryIntervalScale]", "1000"); - return configuration; - } - - private HierarchicalConfiguration ldapRepositoryConfigurationWithVirtualHosting() { - PropertyListConfiguration configuration = new PropertyListConfiguration(); - configuration.addProperty("[@ldapHost]", ldapContainer.getLdapHost()); - configuration.addProperty("[@principal]", "cn=admin\\,dc=james\\,dc=org"); - configuration.addProperty("[@credentials]", ADMIN_PASSWORD); - configuration.addProperty("[@userBase]", "ou=People\\,dc=james\\,dc=org"); - configuration.addProperty("[@userIdAttribute]", "mail"); - configuration.addProperty("[@userObjectClass]", "inetOrgPerson"); - configuration.addProperty("[@maxRetries]", "4"); - configuration.addProperty("[@retryStartInterval]", "0"); - configuration.addProperty("[@retryMaxInterval]", "8"); - configuration.addProperty("[@retryIntervalScale]", "1000"); - configuration.addProperty("supportsVirtualHosting", true); - return configuration; - } - - @Test - public void knownUserShouldBeAbleToLogInWhenPasswordIsCorrect() throws Exception { - startUsersRepository(ldapRepositoryConfiguration()); - assertThat(ldapRepository.test(JAMES_USER, PASSWORD)).isTrue(); - } - - @Test - public void knownUserShouldNotBeAbleToLogInWhenPasswordIsNotCorrect() throws Exception { - startUsersRepository(ldapRepositoryConfiguration()); - assertThat(ldapRepository.test(JAMES_USER, BAD_PASSWORD)).isFalse(); - } - - @Test - public void unknownUserShouldNotBeAbleToLogIn() throws Exception { - startUsersRepository(ldapRepositoryConfiguration()); - assertThat(ldapRepository.test(UNKNOWN, BAD_PASSWORD)).isFalse(); - } - - @Test - public void unknownUserShouldNotBeAbleToLogInWhenPasswordIsCorrect() throws Exception { - startUsersRepository(ldapRepositoryConfiguration()); - assertThat(ldapRepository.test(UNKNOWN, PASSWORD)).isFalse(); - } - - @Test - public void knownUserShouldBeAbleToLogInWhenPasswordIsCorrectWithVirtualHosting() throws Exception { - startUsersRepository(ldapRepositoryConfigurationWithVirtualHosting()); - assertThat(ldapRepository.test(JAMES_USER_MAIL, PASSWORD)).isTrue(); - } - - @Test - public void testShouldStillWorksAfterRestartingLDAP() throws Exception { - startUsersRepository(ldapRepositoryConfigurationWithVirtualHosting()); - ldapRepository.test(JAMES_USER_MAIL, PASSWORD); - - ldapContainer.pause(); - try { - ldapRepository.test(JAMES_USER_MAIL, PASSWORD); - } catch (Exception e) { - LOGGER.info("This exception is expected as we shut down the LDAP and forced its use", e); - } - ldapContainer.unpause(); - - assertThat(ldapRepository.test(JAMES_USER_MAIL, PASSWORD)).isTrue(); - } - - - @Test - public void knownUserShouldNotBeAbleToLogInWhenPasswordIsNotCorrectWithVirtualHosting() throws Exception { - startUsersRepository(ldapRepositoryConfigurationWithVirtualHosting()); - assertThat(ldapRepository.test(JAMES_USER, BAD_PASSWORD)).isFalse(); - } - - @Test - public void unknownUserShouldNotBeAbleToLogInWithVirtualHosting() throws Exception { - startUsersRepository(ldapRepositoryConfigurationWithVirtualHosting()); - assertThat(ldapRepository.test(UNKNOWN, BAD_PASSWORD)).isFalse(); - } - - @Test - public void unknownUserShouldNotBeAbleToLogInWhenPasswordIsCorrectWithVirtualHosting() throws Exception { - startUsersRepository(ldapRepositoryConfigurationWithVirtualHosting()); - assertThat(ldapRepository.test(UNKNOWN, PASSWORD)).isFalse(); - } - - @Test - public void containsWithGetUserShouldBeTrue() throws Exception { - startUsersRepository(ldapRepositoryConfiguration()); - assertThat(ldapRepository.contains(ldapRepository.getUser(new MailAddress(JAMES_USER_MAIL)))).isTrue(); - } - - @Test - public void containsWithGetUserShouldBeTrueWithVirtualHosting() throws Exception { - startUsersRepository(ldapRepositoryConfigurationWithVirtualHosting()); - assertThat(ldapRepository.contains(ldapRepository.getUser(new MailAddress(JAMES_USER_MAIL)))).isTrue(); - } - - @Test - public void specialCharacterInUserInputShouldBeSanitized() throws Exception { - String patternMatchingMultipleUsers = "j*"; - - startUsersRepository(ldapRepositoryConfigurationWithVirtualHosting()); - assertThat(ldapRepository.test(patternMatchingMultipleUsers, PASSWORD)).isFalse(); - } -} http://git-wip-us.apache.org/repos/asf/james-project/blob/ffded847/server/data/data-ldap-integration-testing/src/test/resources/ldif-files/Dockerfile ---------------------------------------------------------------------- diff --git a/server/data/data-ldap-integration-testing/src/test/resources/ldif-files/Dockerfile b/server/data/data-ldap-integration-testing/src/test/resources/ldif-files/Dockerfile deleted file mode 100644 index d889a35..0000000 --- a/server/data/data-ldap-integration-testing/src/test/resources/ldif-files/Dockerfile +++ /dev/null @@ -1,3 +0,0 @@ -FROM dinkel/openldap:latest - -COPY populate.ldif /etc/ldap/prepopulate/prepop.ldif http://git-wip-us.apache.org/repos/asf/james-project/blob/ffded847/server/data/data-ldap-integration-testing/src/test/resources/ldif-files/populate.ldif ---------------------------------------------------------------------- diff --git a/server/data/data-ldap-integration-testing/src/test/resources/ldif-files/populate.ldif b/server/data/data-ldap-integration-testing/src/test/resources/ldif-files/populate.ldif deleted file mode 100644 index 95f3391..0000000 --- a/server/data/data-ldap-integration-testing/src/test/resources/ldif-files/populate.ldif +++ /dev/null @@ -1,12 +0,0 @@ -dn: ou=people, dc=james,dc=org -ou: people -objectClass: organizationalUnit - -dn: uid=james-user, ou=people, dc=james,dc=org -objectClass: inetOrgPerson -uid: james-user -cn: james-user -sn: james-user -mail: [email protected] -userPassword: secret -description: James user http://git-wip-us.apache.org/repos/asf/james-project/blob/ffded847/server/data/data-ldap-integration-testing/src/test/resources/logback-test.xml ---------------------------------------------------------------------- diff --git a/server/data/data-ldap-integration-testing/src/test/resources/logback-test.xml b/server/data/data-ldap-integration-testing/src/test/resources/logback-test.xml deleted file mode 100644 index ddbf62c..0000000 --- a/server/data/data-ldap-integration-testing/src/test/resources/logback-test.xml +++ /dev/null @@ -1,22 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<configuration> - - <contextListener class="ch.qos.logback.classic.jul.LevelChangePropagator"> - <resetJUL>true</resetJUL> - </contextListener> - - <appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender"> - <encoder> - <pattern>%d{HH:mm:ss.SSS} [%-5level] %logger{15} - %msg%n%rEx</pattern> - <immediateFlush>false</immediateFlush> - </encoder> - </appender> - - <root level="WARN"> - <appender-ref ref="CONSOLE" /> - </root> - - <logger name="org.testcontainers" level="WARN"/> - <logger name="org.apache.james" level="WARN"/> - -</configuration> http://git-wip-us.apache.org/repos/asf/james-project/blob/ffded847/server/data/data-ldap/pom.xml ---------------------------------------------------------------------- diff --git a/server/data/data-ldap/pom.xml b/server/data/data-ldap/pom.xml index 3c5ae38..4b72c98 100644 --- a/server/data/data-ldap/pom.xml +++ b/server/data/data-ldap/pom.xml @@ -88,6 +88,16 @@ <groupId>org.slf4j</groupId> <artifactId>slf4j-api</artifactId> </dependency> + <dependency> + <groupId>org.testcontainers</groupId> + <artifactId>testcontainers</artifactId> + <scope>test</scope> + </dependency> + <dependency> + <groupId>org.apache.james</groupId> + <artifactId>james-server-testing</artifactId> + <scope>test</scope> + </dependency> </dependencies> <build> http://git-wip-us.apache.org/repos/asf/james-project/blob/ffded847/server/data/data-ldap/src/test/java/org/apache/james/user/ldap/DockerLdapSingleton.java ---------------------------------------------------------------------- diff --git a/server/data/data-ldap/src/test/java/org/apache/james/user/ldap/DockerLdapSingleton.java b/server/data/data-ldap/src/test/java/org/apache/james/user/ldap/DockerLdapSingleton.java new file mode 100644 index 0000000..ca8fdaa --- /dev/null +++ b/server/data/data-ldap/src/test/java/org/apache/james/user/ldap/DockerLdapSingleton.java @@ -0,0 +1,36 @@ +/**************************************************************** + * Licensed to the Apache Software Foundation (ASF) under one * + * or more contributor license agreements. See the NOTICE file * + * distributed with this work for additional information * + * regarding copyright ownership. The ASF licenses this file * + * to you under the Apache License, Version 2.0 (the * + * "License"); you may not use this file except in compliance * + * with the License. You may obtain a copy of the License at * + * * + * http://www.apache.org/licenses/LICENSE-2.0 * + * * + * Unless required by applicable law or agreed to in writing, * + * software distributed under the License is distributed on an * + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * + * KIND, either express or implied. See the License for the * + * specific language governing permissions and limitations * + * under the License. * + ****************************************************************/ + +package org.apache.james.user.ldap; + +public class DockerLdapSingleton { + public static final String JAMES_USER = "james-user"; + public static final String PASSWORD = "secret"; + public static final String DOMAIN = "james.org"; + public static final String ADMIN_PASSWORD = "mysecretpassword"; + + public static final LdapGenericContainer ldapContainer = LdapGenericContainer.builder() + .domain(DOMAIN) + .password(ADMIN_PASSWORD) + .build(); + + static { + ldapContainer.start(); + } +} http://git-wip-us.apache.org/repos/asf/james-project/blob/ffded847/server/data/data-ldap/src/test/java/org/apache/james/user/ldap/LdapGenericContainer.java ---------------------------------------------------------------------- diff --git a/server/data/data-ldap/src/test/java/org/apache/james/user/ldap/LdapGenericContainer.java b/server/data/data-ldap/src/test/java/org/apache/james/user/ldap/LdapGenericContainer.java new file mode 100644 index 0000000..40ee62d --- /dev/null +++ b/server/data/data-ldap/src/test/java/org/apache/james/user/ldap/LdapGenericContainer.java @@ -0,0 +1,114 @@ +/**************************************************************** + * Licensed to the Apache Software Foundation (ASF) under one * + * or more contributor license agreements. See the NOTICE file * + * distributed with this work for additional information * + * regarding copyright ownership. The ASF licenses this file * + * to you under the Apache License, Version 2.0 (the * + * "License"); you may not use this file except in compliance * + * with the License. You may obtain a copy of the License at * + * * + * http://www.apache.org/licenses/LICENSE-2.0 * + * * + * Unless required by applicable law or agreed to in writing, * + * software distributed under the License is distributed on an * + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * + * KIND, either express or implied. See the License for the * + * specific language governing permissions and limitations * + * under the License. * + ****************************************************************/ +package org.apache.james.user.ldap; + +import org.apache.james.util.docker.RateLimiters; +import org.apache.james.util.docker.SwarmGenericContainer; +import org.junit.rules.ExternalResource; +import org.testcontainers.containers.wait.strategy.HostPortWaitStrategy; +import org.testcontainers.images.builder.ImageFromDockerfile; + +import com.google.common.base.Preconditions; +import com.google.common.base.Strings; + +public class LdapGenericContainer extends ExternalResource { + + public static final int DEFAULT_LDAP_PORT = 389; + + public static Builder builder() { + return new Builder(); + } + + public static class Builder { + + private String domain; + private String password; + + private Builder() { + } + + public Builder domain(String domain) { + this.domain = domain; + return this; + } + + public Builder password(String password) { + this.password = password; + return this; + } + + public LdapGenericContainer build() { + Preconditions.checkState(!Strings.isNullOrEmpty(domain), "'domain' is mandatory"); + Preconditions.checkState(!Strings.isNullOrEmpty(password), "'password' is mandatory"); + return new LdapGenericContainer(createContainer()); + } + + private SwarmGenericContainer createContainer() { + return new SwarmGenericContainer( + new ImageFromDockerfile() + .withFileFromClasspath("populate.ldif", "ldif-files/populate.ldif") + .withFileFromClasspath("Dockerfile", "ldif-files/Dockerfile")) + .withAffinityToContainer() + .withEnv("SLAPD_DOMAIN", domain) + .withEnv("SLAPD_PASSWORD", password) + .withEnv("SLAPD_CONFIG_PASSWORD", password) + .withExposedPorts(LdapGenericContainer.DEFAULT_LDAP_PORT) + .waitingFor(new HostPortWaitStrategy().withRateLimiter(RateLimiters.TWENTIES_PER_SECOND)); + } + } + + private final SwarmGenericContainer container; + + private LdapGenericContainer(SwarmGenericContainer container) { + this.container = container; + } + + @Override + protected void before() { + start(); + } + + @Override + protected void after() { + stop(); + } + + public void start() { + container.start(); + } + + public void stop() { + container.stop(); + } + + public void pause() { + container.pause(); + } + + public void unpause() { + container.unpause(); + } + + public String getLdapHost() { + return "ldap://" + + container.getContainerIp() + + ":" + + LdapGenericContainer.DEFAULT_LDAP_PORT; + } +} http://git-wip-us.apache.org/repos/asf/james-project/blob/ffded847/server/data/data-ldap/src/test/java/org/apache/james/user/ldap/ReadOnlyUsersLDAPRepositoryTest.java ---------------------------------------------------------------------- diff --git a/server/data/data-ldap/src/test/java/org/apache/james/user/ldap/ReadOnlyUsersLDAPRepositoryTest.java b/server/data/data-ldap/src/test/java/org/apache/james/user/ldap/ReadOnlyUsersLDAPRepositoryTest.java index f7b7a6b..39626ad 100644 --- a/server/data/data-ldap/src/test/java/org/apache/james/user/ldap/ReadOnlyUsersLDAPRepositoryTest.java +++ b/server/data/data-ldap/src/test/java/org/apache/james/user/ldap/ReadOnlyUsersLDAPRepositoryTest.java @@ -19,23 +19,43 @@ package org.apache.james.user.ldap; +import static org.apache.james.user.ldap.DockerLdapSingleton.ADMIN_PASSWORD; +import static org.apache.james.user.ldap.DockerLdapSingleton.DOMAIN; +import static org.apache.james.user.ldap.DockerLdapSingleton.JAMES_USER; +import static org.apache.james.user.ldap.DockerLdapSingleton.PASSWORD; import static org.assertj.core.api.Assertions.assertThat; import static org.mockito.Mockito.mock; -import org.apache.commons.configuration.ConfigurationException; import org.apache.commons.configuration.ConversionException; import org.apache.commons.configuration.HierarchicalConfiguration; import org.apache.commons.configuration.plist.PropertyListConfiguration; +import org.apache.james.core.MailAddress; import org.apache.james.domainlist.api.DomainList; import org.junit.Before; +import org.junit.ClassRule; import org.junit.Rule; import org.junit.Test; import org.junit.rules.ExpectedException; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; public class ReadOnlyUsersLDAPRepositoryTest { + private static final Logger LOGGER = LoggerFactory.getLogger(ReadOnlyUsersLDAPRepositoryTest.class); + private static final String JAMES_USER_MAIL = JAMES_USER + "@" + DOMAIN; + private static final String UNKNOWN = "unknown"; + private static final String BAD_PASSWORD = "badpassword"; + @Rule public ExpectedException expectedException = ExpectedException.none(); + + @ClassRule + public static LdapGenericContainer ldapContainer = LdapGenericContainer.builder() + .domain(DOMAIN) + .password(ADMIN_PASSWORD) + .build(); + + private ReadOnlyUsersLDAPRepository ldapRepository; private DomainList domainList; @Before @@ -43,6 +63,12 @@ public class ReadOnlyUsersLDAPRepositoryTest { domainList = mock(DomainList.class); } + private void startUsersRepository(HierarchicalConfiguration ldapRepositoryConfiguration) throws Exception { + ldapRepository = new ReadOnlyUsersLDAPRepository(domainList); + ldapRepository.configure(ldapRepositoryConfiguration); + ldapRepository.init(); + } + @Test public void supportVirtualHostingShouldReturnFalseByDefault() throws Exception { ReadOnlyUsersLDAPRepository usersLDAPRepository = new ReadOnlyUsersLDAPRepository(domainList); @@ -85,11 +111,11 @@ public class ReadOnlyUsersLDAPRepositoryTest { usersLDAPRepository.configure(configuration); } - private HierarchicalConfiguration ldapRepositoryConfiguration() throws ConfigurationException { + private HierarchicalConfiguration ldapRepositoryConfiguration() { PropertyListConfiguration configuration = new PropertyListConfiguration(); - configuration.addProperty("[@ldapHost]", "ldap://127.0.0.1"); + configuration.addProperty("[@ldapHost]", ldapContainer.getLdapHost()); configuration.addProperty("[@principal]", "cn=admin\\,dc=james\\,dc=org"); - configuration.addProperty("[@credentials]", "secret"); + configuration.addProperty("[@credentials]", ADMIN_PASSWORD); configuration.addProperty("[@userBase]", "ou=People\\,dc=james\\,dc=org"); configuration.addProperty("[@userIdAttribute]", "uid"); configuration.addProperty("[@userObjectClass]", "inetOrgPerson"); @@ -100,4 +126,104 @@ public class ReadOnlyUsersLDAPRepositoryTest { return configuration; } + private HierarchicalConfiguration ldapRepositoryConfigurationWithVirtualHosting() { + PropertyListConfiguration configuration = new PropertyListConfiguration(); + configuration.addProperty("[@ldapHost]", ldapContainer.getLdapHost()); + configuration.addProperty("[@principal]", "cn=admin\\,dc=james\\,dc=org"); + configuration.addProperty("[@credentials]", ADMIN_PASSWORD); + configuration.addProperty("[@userBase]", "ou=People\\,dc=james\\,dc=org"); + configuration.addProperty("[@userIdAttribute]", "mail"); + configuration.addProperty("[@userObjectClass]", "inetOrgPerson"); + configuration.addProperty("[@maxRetries]", "4"); + configuration.addProperty("[@retryStartInterval]", "0"); + configuration.addProperty("[@retryMaxInterval]", "8"); + configuration.addProperty("[@retryIntervalScale]", "1000"); + configuration.addProperty("supportsVirtualHosting", true); + return configuration; + } + + @Test + public void knownUserShouldBeAbleToLogInWhenPasswordIsCorrect() throws Exception { + startUsersRepository(ldapRepositoryConfiguration()); + assertThat(ldapRepository.test(JAMES_USER, PASSWORD)).isTrue(); + } + + @Test + public void knownUserShouldNotBeAbleToLogInWhenPasswordIsNotCorrect() throws Exception { + startUsersRepository(ldapRepositoryConfiguration()); + assertThat(ldapRepository.test(JAMES_USER, BAD_PASSWORD)).isFalse(); + } + + @Test + public void unknownUserShouldNotBeAbleToLogIn() throws Exception { + startUsersRepository(ldapRepositoryConfiguration()); + assertThat(ldapRepository.test(UNKNOWN, BAD_PASSWORD)).isFalse(); + } + + @Test + public void unknownUserShouldNotBeAbleToLogInWhenPasswordIsCorrect() throws Exception { + startUsersRepository(ldapRepositoryConfiguration()); + assertThat(ldapRepository.test(UNKNOWN, PASSWORD)).isFalse(); + } + + @Test + public void knownUserShouldBeAbleToLogInWhenPasswordIsCorrectWithVirtualHosting() throws Exception { + startUsersRepository(ldapRepositoryConfigurationWithVirtualHosting()); + assertThat(ldapRepository.test(JAMES_USER_MAIL, PASSWORD)).isTrue(); + } + + @Test + public void testShouldStillWorksAfterRestartingLDAP() throws Exception { + startUsersRepository(ldapRepositoryConfigurationWithVirtualHosting()); + ldapRepository.test(JAMES_USER_MAIL, PASSWORD); + + ldapContainer.pause(); + try { + ldapRepository.test(JAMES_USER_MAIL, PASSWORD); + } catch (Exception e) { + LOGGER.info("This exception is expected as we shut down the LDAP and forced its use", e); + } + ldapContainer.unpause(); + + assertThat(ldapRepository.test(JAMES_USER_MAIL, PASSWORD)).isTrue(); + } + + + @Test + public void knownUserShouldNotBeAbleToLogInWhenPasswordIsNotCorrectWithVirtualHosting() throws Exception { + startUsersRepository(ldapRepositoryConfigurationWithVirtualHosting()); + assertThat(ldapRepository.test(JAMES_USER, BAD_PASSWORD)).isFalse(); + } + + @Test + public void unknownUserShouldNotBeAbleToLogInWithVirtualHosting() throws Exception { + startUsersRepository(ldapRepositoryConfigurationWithVirtualHosting()); + assertThat(ldapRepository.test(UNKNOWN, BAD_PASSWORD)).isFalse(); + } + + @Test + public void unknownUserShouldNotBeAbleToLogInWhenPasswordIsCorrectWithVirtualHosting() throws Exception { + startUsersRepository(ldapRepositoryConfigurationWithVirtualHosting()); + assertThat(ldapRepository.test(UNKNOWN, PASSWORD)).isFalse(); + } + + @Test + public void containsWithGetUserShouldBeTrue() throws Exception { + startUsersRepository(ldapRepositoryConfiguration()); + assertThat(ldapRepository.contains(ldapRepository.getUser(new MailAddress(JAMES_USER_MAIL)))).isTrue(); + } + + @Test + public void containsWithGetUserShouldBeTrueWithVirtualHosting() throws Exception { + startUsersRepository(ldapRepositoryConfigurationWithVirtualHosting()); + assertThat(ldapRepository.contains(ldapRepository.getUser(new MailAddress(JAMES_USER_MAIL)))).isTrue(); + } + + @Test + public void specialCharacterInUserInputShouldBeSanitized() throws Exception { + String patternMatchingMultipleUsers = "j*"; + + startUsersRepository(ldapRepositoryConfigurationWithVirtualHosting()); + assertThat(ldapRepository.test(patternMatchingMultipleUsers, PASSWORD)).isFalse(); + } } http://git-wip-us.apache.org/repos/asf/james-project/blob/ffded847/server/data/data-ldap/src/test/resources/ldif-files/Dockerfile ---------------------------------------------------------------------- diff --git a/server/data/data-ldap/src/test/resources/ldif-files/Dockerfile b/server/data/data-ldap/src/test/resources/ldif-files/Dockerfile new file mode 100644 index 0000000..d889a35 --- /dev/null +++ b/server/data/data-ldap/src/test/resources/ldif-files/Dockerfile @@ -0,0 +1,3 @@ +FROM dinkel/openldap:latest + +COPY populate.ldif /etc/ldap/prepopulate/prepop.ldif http://git-wip-us.apache.org/repos/asf/james-project/blob/ffded847/server/data/data-ldap/src/test/resources/ldif-files/populate.ldif ---------------------------------------------------------------------- diff --git a/server/data/data-ldap/src/test/resources/ldif-files/populate.ldif b/server/data/data-ldap/src/test/resources/ldif-files/populate.ldif new file mode 100644 index 0000000..95f3391 --- /dev/null +++ b/server/data/data-ldap/src/test/resources/ldif-files/populate.ldif @@ -0,0 +1,12 @@ +dn: ou=people, dc=james,dc=org +ou: people +objectClass: organizationalUnit + +dn: uid=james-user, ou=people, dc=james,dc=org +objectClass: inetOrgPerson +uid: james-user +cn: james-user +sn: james-user +mail: [email protected] +userPassword: secret +description: James user http://git-wip-us.apache.org/repos/asf/james-project/blob/ffded847/server/data/data-ldap/src/test/resources/logback-test.xml ---------------------------------------------------------------------- diff --git a/server/data/data-ldap/src/test/resources/logback-test.xml b/server/data/data-ldap/src/test/resources/logback-test.xml new file mode 100644 index 0000000..ddbf62c --- /dev/null +++ b/server/data/data-ldap/src/test/resources/logback-test.xml @@ -0,0 +1,22 @@ +<?xml version="1.0" encoding="UTF-8"?> +<configuration> + + <contextListener class="ch.qos.logback.classic.jul.LevelChangePropagator"> + <resetJUL>true</resetJUL> + </contextListener> + + <appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender"> + <encoder> + <pattern>%d{HH:mm:ss.SSS} [%-5level] %logger{15} - %msg%n%rEx</pattern> + <immediateFlush>false</immediateFlush> + </encoder> + </appender> + + <root level="WARN"> + <appender-ref ref="CONSOLE" /> + </root> + + <logger name="org.testcontainers" level="WARN"/> + <logger name="org.apache.james" level="WARN"/> + +</configuration> http://git-wip-us.apache.org/repos/asf/james-project/blob/ffded847/server/pom.xml ---------------------------------------------------------------------- diff --git a/server/pom.xml b/server/pom.xml index f3fa630..6ba5754 100644 --- a/server/pom.xml +++ b/server/pom.xml @@ -63,7 +63,6 @@ <module>data/data-jmap-cassandra</module> <module>data/data-jpa</module> <module>data/data-ldap</module> - <module>data/data-ldap-integration-testing</module> <module>data/data-library</module> <module>data/data-memory</module> --------------------------------------------------------------------- To unsubscribe, e-mail: [email protected] For additional commands, e-mail: [email protected]
