JAMES-1958 Add a HttpsConfiguration
Project: http://git-wip-us.apache.org/repos/asf/james-project/repo Commit: http://git-wip-us.apache.org/repos/asf/james-project/commit/ef84ed71 Tree: http://git-wip-us.apache.org/repos/asf/james-project/tree/ef84ed71 Diff: http://git-wip-us.apache.org/repos/asf/james-project/diff/ef84ed71 Branch: refs/heads/master Commit: ef84ed711275c5d7ecdab05fc2e54e5955381ca3 Parents: da41f83 Author: benwa <btell...@linagora.com> Authored: Wed Mar 8 15:14:15 2017 +0700 Committer: benwa <btell...@linagora.com> Committed: Wed Mar 15 09:01:53 2017 +0700 ---------------------------------------------------------------------- .../james/webadmin/HttpsConfiguration.java | 148 +++++++++++++++++++ .../james/webadmin/WebAdminConfiguration.java | 21 ++- .../james/webadmin/HttpsConfigurationTest.java | 101 +++++++++++++ .../webadmin/WebAdminConfigurationTest.java | 20 ++- 4 files changed, 286 insertions(+), 4 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/james-project/blob/ef84ed71/server/protocols/webadmin/src/main/java/org/apache/james/webadmin/HttpsConfiguration.java ---------------------------------------------------------------------- diff --git a/server/protocols/webadmin/src/main/java/org/apache/james/webadmin/HttpsConfiguration.java b/server/protocols/webadmin/src/main/java/org/apache/james/webadmin/HttpsConfiguration.java new file mode 100644 index 0000000..3c6a49e --- /dev/null +++ b/server/protocols/webadmin/src/main/java/org/apache/james/webadmin/HttpsConfiguration.java @@ -0,0 +1,148 @@ +/**************************************************************** + * 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.webadmin; + +import java.util.Objects; +import java.util.Optional; + +import com.google.common.annotations.VisibleForTesting; +import com.google.common.base.Preconditions; + +public class HttpsConfiguration { + + public static Builder builder() { + return new Builder(); + } + + public static class Builder { + private Optional<Boolean> enabled = Optional.empty(); + private String keystoreFilePath; + private String keystorePassword; + private String truststoreFilePath; + private String truststorePassword; + + public Builder enable(boolean isEnabled) { + this.enabled = Optional.of(isEnabled); + return this; + } + + public Builder enabled() { + return enable(true); + } + + public Builder disabled() { + return enable(false); + } + + public Builder raw(String keystoreFilePath, + String keystorePassword, + String truststoreFilePath, + String truststorePassword){ + Preconditions.checkNotNull(keystoreFilePath); + Preconditions.checkNotNull(keystorePassword); + + this.keystoreFilePath = keystoreFilePath; + this.keystorePassword = keystorePassword; + this.truststoreFilePath = truststoreFilePath; + this.truststorePassword = truststorePassword; + return this; + } + + public Builder selfSigned(String keystoreFilePath, String keystorePassword){ + Preconditions.checkNotNull(keystoreFilePath); + Preconditions.checkNotNull(keystorePassword); + + this.enabled = Optional.of(true); + this.keystoreFilePath = keystoreFilePath; + this.keystorePassword = keystorePassword; + return this; + } + + public HttpsConfiguration build() { + Preconditions.checkState(enabled.isPresent(), "You need to specify if https is enabled"); + Preconditions.checkState(!enabled.get() || hasKeystoreInformation(), "If enabled, you need to provide keystore information"); + Preconditions.checkState(optionalHasTrustStoreInformation(), "You need to provide both information about trustStore"); + return new HttpsConfiguration(enabled.get(), keystoreFilePath, keystorePassword, truststoreFilePath, truststorePassword); + } + + private boolean optionalHasTrustStoreInformation() { + return (truststoreFilePath == null) == (truststorePassword == null); + } + + private boolean hasKeystoreInformation() { + return keystorePassword != null && keystoreFilePath != null; + } + + } + + private final boolean enabled; + private final String keystoreFilePath; + private final String keystorePassword; + private final String truststoreFilePath; + private final String truststorePassword; + + @VisibleForTesting + HttpsConfiguration(boolean enabled, String keystoreFilePath, String keystorePassword, String truststoreFilePath, String truststorePassword) { + this.enabled = enabled; + this.keystoreFilePath = keystoreFilePath; + this.keystorePassword = keystorePassword; + this.truststoreFilePath = truststoreFilePath; + this.truststorePassword = truststorePassword; + } + + public boolean isEnabled() { + return enabled; + } + + public String getKeystoreFilePath() { + return keystoreFilePath; + } + + public String getKeystorePassword() { + return keystorePassword; + } + + public String getTruststoreFilePath() { + return truststoreFilePath; + } + + public String getTruststorePassword() { + return truststorePassword; + } + + @Override + public final boolean equals(Object o) { + if (o instanceof HttpsConfiguration) { + HttpsConfiguration that = (HttpsConfiguration) o; + + return Objects.equals(this.enabled, that.enabled) + && Objects.equals(this.keystoreFilePath, that.keystoreFilePath) + && Objects.equals(this.keystorePassword, that.keystorePassword) + && Objects.equals(this.truststoreFilePath, that.truststoreFilePath) + && Objects.equals(this.truststorePassword, that.truststorePassword); + } + return false; + } + + @Override + public final int hashCode() { + return Objects.hash(enabled, keystoreFilePath, keystorePassword, truststoreFilePath, truststorePassword); + } +} http://git-wip-us.apache.org/repos/asf/james-project/blob/ef84ed71/server/protocols/webadmin/src/main/java/org/apache/james/webadmin/WebAdminConfiguration.java ---------------------------------------------------------------------- diff --git a/server/protocols/webadmin/src/main/java/org/apache/james/webadmin/WebAdminConfiguration.java b/server/protocols/webadmin/src/main/java/org/apache/james/webadmin/WebAdminConfiguration.java index b21749c..8cb022a 100644 --- a/server/protocols/webadmin/src/main/java/org/apache/james/webadmin/WebAdminConfiguration.java +++ b/server/protocols/webadmin/src/main/java/org/apache/james/webadmin/WebAdminConfiguration.java @@ -35,6 +35,12 @@ public class WebAdminConfiguration { public static class Builder { private Optional<Boolean> enabled = Optional.empty(); private Port port; + private Optional<HttpsConfiguration> httpsConfiguration = Optional.empty(); + + public Builder https(HttpsConfiguration httpsConfiguration) { + this.httpsConfiguration = Optional.of(httpsConfiguration); + return this; + } public Builder port(Port port) { this.port = port; @@ -57,17 +63,24 @@ public class WebAdminConfiguration { public WebAdminConfiguration build() { Preconditions.checkState(enabled.isPresent(), "You need to explicitly enable or disable WebAdmin server"); Preconditions.checkState(!enabled.get() || port != null, "You need to specify a port for WebAdminConfiguration"); - return new WebAdminConfiguration(enabled.get(), port); + return new WebAdminConfiguration(enabled.get(), + port, + httpsConfiguration.orElse( + HttpsConfiguration.builder() + .disabled() + .build())); } } private final boolean enabled; private final Port port; + private final HttpsConfiguration httpsConfiguration; @VisibleForTesting - WebAdminConfiguration(boolean enabled, Port port) { + WebAdminConfiguration(boolean enabled, Port port, HttpsConfiguration httpsConfiguration) { this.enabled = enabled; this.port = port; + this.httpsConfiguration = httpsConfiguration; } public boolean isEnabled() { @@ -78,6 +91,10 @@ public class WebAdminConfiguration { return port; } + public HttpsConfiguration getHttpsConfiguration() { + return httpsConfiguration; + } + @Override public final boolean equals(Object o) { if (o instanceof WebAdminConfiguration) { http://git-wip-us.apache.org/repos/asf/james-project/blob/ef84ed71/server/protocols/webadmin/src/test/java/org/apache/james/webadmin/HttpsConfigurationTest.java ---------------------------------------------------------------------- diff --git a/server/protocols/webadmin/src/test/java/org/apache/james/webadmin/HttpsConfigurationTest.java b/server/protocols/webadmin/src/test/java/org/apache/james/webadmin/HttpsConfigurationTest.java new file mode 100644 index 0000000..0d69cbe --- /dev/null +++ b/server/protocols/webadmin/src/test/java/org/apache/james/webadmin/HttpsConfigurationTest.java @@ -0,0 +1,101 @@ +/**************************************************************** + * 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.webadmin; + +import static org.assertj.core.api.Assertions.assertThat; + +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.ExpectedException; + +import nl.jqno.equalsverifier.EqualsVerifier; + +public class HttpsConfigurationTest { + + @Rule + public ExpectedException expectedException = ExpectedException.none(); + + @Test + public void buildShouldThrowWhenNotEnabled() { + expectedException.expect(IllegalStateException.class); + + HttpsConfiguration.builder().build(); + } + + @Test + public void buildShouldThrowWhenEnableWithoutKeystore() { + expectedException.expect(IllegalStateException.class); + + HttpsConfiguration.builder().enabled().build(); + } + + @Test + public void selfSignedShouldThrowOnNullKeyStorePath() { + expectedException.expect(NullPointerException.class); + + HttpsConfiguration.builder() + .enabled() + .selfSigned(null, "abc"); + } + + @Test + public void selfSignedShouldThrowOnNullKeyStorePassword() { + expectedException.expect(NullPointerException.class); + + HttpsConfiguration.builder() + .enabled() + .selfSigned("abc", null); + } + + @Test + public void buildShouldWorkOnDisabledHttps() { + assertThat( + HttpsConfiguration.builder() + .disabled() + .build()) + .isEqualTo(new HttpsConfiguration(false, null, null, null, null)); + } + + @Test + public void buildShouldWorkOnSelfSignedHttps() { + assertThat( + HttpsConfiguration.builder() + .enabled() + .selfSigned("abcd", "efgh") + .build()) + .isEqualTo(new HttpsConfiguration(true, "abcd", "efgh", null, null)); + } + + @Test + public void buildShouldWorkOnTrustedHttps() { + assertThat( + HttpsConfiguration.builder() + .enabled() + .raw("a", "b", "c", "d") + .build()) + .isEqualTo(new HttpsConfiguration(true, "a", "b", "c", "d")); + } + + @Test + public void shouldRespectBeanContract() { + EqualsVerifier.forClass(HttpsConfiguration.class).verify(); + } + +} http://git-wip-us.apache.org/repos/asf/james-project/blob/ef84ed71/server/protocols/webadmin/src/test/java/org/apache/james/webadmin/WebAdminConfigurationTest.java ---------------------------------------------------------------------- diff --git a/server/protocols/webadmin/src/test/java/org/apache/james/webadmin/WebAdminConfigurationTest.java b/server/protocols/webadmin/src/test/java/org/apache/james/webadmin/WebAdminConfigurationTest.java index 01f3c2a..d20100c 100644 --- a/server/protocols/webadmin/src/test/java/org/apache/james/webadmin/WebAdminConfigurationTest.java +++ b/server/protocols/webadmin/src/test/java/org/apache/james/webadmin/WebAdminConfigurationTest.java @@ -46,7 +46,7 @@ public class WebAdminConfigurationTest { assertThat(WebAdminConfiguration.builder() .disabled() .build()) - .isEqualTo(new WebAdminConfiguration(false, null)); + .isEqualTo(new WebAdminConfiguration(false, null, HttpsConfiguration.builder().disabled().build())); } @Test @@ -63,7 +63,23 @@ public class WebAdminConfigurationTest { .enabled() .port(PORT) .build()) - .isEqualTo(new WebAdminConfiguration(true, PORT)); + .isEqualTo(new WebAdminConfiguration(true, PORT, HttpsConfiguration.builder().disabled().build())); + } + + @Test + public void builderShouldAcceptHttps() { + HttpsConfiguration httpsConfiguration = HttpsConfiguration.builder() + .enable(true) + .selfSigned("abcd", "efgh") + .build(); + + assertThat( + WebAdminConfiguration.builder() + .enabled() + .https(httpsConfiguration) + .port(PORT) + .build()) + .isEqualTo(new WebAdminConfiguration(true, PORT, httpsConfiguration)); } @Test --------------------------------------------------------------------- To unsubscribe, e-mail: server-dev-unsubscr...@james.apache.org For additional commands, e-mail: server-dev-h...@james.apache.org