This is an automated email from the ASF dual-hosted git repository. jhelou pushed a commit to branch pulsar-authentication in repository https://gitbox.apache.org/repos/asf/james-project.git
commit a2ca77601da3eae981ecf7d57e4942da59ecc620 Author: Jean Helou <[email protected]> AuthorDate: Thu Nov 24 23:28:00 2022 +0100 [JAMES-3687] adds support for authentication scheme in the configuration --- .../backends/pulsar/PulsarConfiguration.scala | 59 ++++++++++-- .../backends/pulsar/DockerPulsarExtension.java | 4 +- .../backends/pulsar/PulsarConfigurationTest.java | 103 ++++++++++++++++++++- 3 files changed, 157 insertions(+), 9 deletions(-) diff --git a/backends-common/pulsar/src/main/scala/org/apache/james/backends/pulsar/PulsarConfiguration.scala b/backends-common/pulsar/src/main/scala/org/apache/james/backends/pulsar/PulsarConfiguration.scala index b3cbda2bd8..7e790f29c6 100644 --- a/backends-common/pulsar/src/main/scala/org/apache/james/backends/pulsar/PulsarConfiguration.scala +++ b/backends-common/pulsar/src/main/scala/org/apache/james/backends/pulsar/PulsarConfiguration.scala @@ -1,4 +1,4 @@ -/**************************************************************** +/** ************************************************************** * 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 * @@ -6,16 +6,16 @@ * 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 * - * * + * * + * 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.backends.pulsar @@ -27,16 +27,45 @@ object PulsarConfiguration { val BROKER_URI_PROPERTY_NAME = "broker.uri" val ADMIN_URI_PROPERTY_NAME = "admin.uri" val NAMESPACE_PROPERTY_NAME = "namespace" + val AUTHENTICATION_TYPE_PROPERTY_NAME = "authentication.type" + val AUTHENTICATION_TYPE_NO_AUTH = "no-auth" + val AUTHENTICATION_TYPE_AUTH_TOKEN = "token" + val AUTHENTICATION_TYPE_AUTH_BASIC = "basic" + val AUTHENTICATION_TOKEN_PROPERTY_NAME = "authentication.token" + val AUTHENTICATION_BASIC_USERID_PROPERTY_NAME = "authentication.basic.userId" + val AUTHENTICATION_BASIC_PASSWORD_PROPERTY_NAME = "authentication.basic.password" + def from(configuration: Configuration): PulsarConfiguration = { val brokerUri: String = extractUri(configuration, BROKER_URI_PROPERTY_NAME) val adminUri: String = extractUri(configuration, ADMIN_URI_PROPERTY_NAME) + val authTypeString: String = configuration.getString(AUTHENTICATION_TYPE_PROPERTY_NAME, AUTHENTICATION_TYPE_NO_AUTH); + val auth = authTypeString match { + case AUTHENTICATION_TYPE_NO_AUTH => Auth.NoAuth + + case AUTHENTICATION_TYPE_AUTH_TOKEN => + val token = configuration.getString(AUTHENTICATION_TOKEN_PROPERTY_NAME) + if (Strings.isNullOrEmpty(token)) + throw new IllegalStateException(s"You need to specify a non-empty value for ${AUTHENTICATION_TOKEN_PROPERTY_NAME}") + Auth.Token(token) + + case AUTHENTICATION_TYPE_AUTH_BASIC => + val userId = configuration.getString(AUTHENTICATION_BASIC_USERID_PROPERTY_NAME) + if (Strings.isNullOrEmpty(userId)) + throw new IllegalStateException(s"You need to specify a non-empty value for ${AUTHENTICATION_BASIC_USERID_PROPERTY_NAME}") + val password = configuration.getString(AUTHENTICATION_BASIC_PASSWORD_PROPERTY_NAME) + if (Strings.isNullOrEmpty(password)) + throw new IllegalStateException(s"You need to specify a non-empty value for ${AUTHENTICATION_BASIC_PASSWORD_PROPERTY_NAME}") + Auth.Basic(userId, password) + case _ => + throw new NotImplementedError(s"Authentication type $authTypeString is not implemented") + } val namespace = configuration.getString(NAMESPACE_PROPERTY_NAME) if (Strings.isNullOrEmpty(namespace)) throw new IllegalStateException(s"You need to specify the pulsar namespace as ${NAMESPACE_PROPERTY_NAME}") - new PulsarConfiguration(brokerUri, adminUri, Namespace(namespace)) + new PulsarConfiguration(brokerUri, adminUri, Namespace(namespace), auth) } private def extractUri(configuration: Configuration, uriPropertyName: String): String = { @@ -55,4 +84,20 @@ object PulsarConfiguration { case class Namespace(asString: String) -case class PulsarConfiguration(brokerUri: String, adminUri: String, namespace: Namespace) \ No newline at end of file +sealed trait Auth + +object Auth { + def noAuth() = NoAuth + + case object NoAuth extends Auth + + def token(value: String) = Token(value) + + case class Token(value: String) extends Auth + + def basic(userId: String, password: String) = Basic(userId, password) + + case class Basic(userId: String, password: String) extends Auth +} + +case class PulsarConfiguration(brokerUri: String, adminUri: String, namespace: Namespace, auth: Auth = Auth.NoAuth) \ No newline at end of file diff --git a/backends-common/pulsar/src/test/java/org/apache/james/backends/pulsar/DockerPulsarExtension.java b/backends-common/pulsar/src/test/java/org/apache/james/backends/pulsar/DockerPulsarExtension.java index 12b418676f..d535ba390d 100644 --- a/backends-common/pulsar/src/test/java/org/apache/james/backends/pulsar/DockerPulsarExtension.java +++ b/backends-common/pulsar/src/test/java/org/apache/james/backends/pulsar/DockerPulsarExtension.java @@ -70,7 +70,9 @@ public class DockerPulsarExtension implements return new PulsarConfiguration( container.getPulsarBrokerUrl(), container.getHttpServiceUrl(), - new Namespace("test/" + RandomStringUtils.randomAlphabetic(10))); + new Namespace("test/" + RandomStringUtils.randomAlphabetic(10)), + Auth.noAuth() + ); } public PulsarConfiguration getConfiguration() { diff --git a/backends-common/pulsar/src/test/java/org/apache/james/backends/pulsar/PulsarConfigurationTest.java b/backends-common/pulsar/src/test/java/org/apache/james/backends/pulsar/PulsarConfigurationTest.java index 43eb4463a5..9fedee288f 100644 --- a/backends-common/pulsar/src/test/java/org/apache/james/backends/pulsar/PulsarConfigurationTest.java +++ b/backends-common/pulsar/src/test/java/org/apache/james/backends/pulsar/PulsarConfigurationTest.java @@ -20,7 +20,10 @@ package org.apache.james.backends.pulsar; import org.apache.commons.configuration2.PropertiesConfiguration; +import org.apache.james.backends.pulsar.Auth.NoAuth$; import org.junit.jupiter.api.Test; +import org.testcontainers.shaded.org.apache.commons.lang3.NotImplementedException; +import scala.NotImplementedError; import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatThrownBy; @@ -155,8 +158,106 @@ class PulsarConfigurationTest { configuration.addProperty("namespace", namespace); assertThat(PulsarConfiguration.from(configuration)) - .isEqualTo(new PulsarConfiguration(brokerUri, adminUri, new Namespace(namespace))); + .isEqualTo(new PulsarConfiguration(brokerUri, adminUri, new Namespace(namespace), Auth.noAuth())); } + @Test + void fromShouldThrowWithTokenAuthenticationWhenTokenIsMissing() { + PropertiesConfiguration configuration = new PropertiesConfiguration(); + String brokerUri = "pulsar://localhost.test:6650/"; + String adminUri = "http://localhost:8090"; + String authenticationType = "token"; + + configuration.addProperty("broker.uri", brokerUri); + configuration.addProperty("admin.uri", adminUri); + configuration.addProperty("authentication.type", authenticationType); + + String namespace = "namespace"; + + configuration.addProperty("namespace", namespace); + assertThatThrownBy(() -> PulsarConfiguration.from(configuration)) + .isInstanceOf(IllegalStateException.class) + .hasMessage("You need to specify a non-empty value for " + PulsarConfiguration.AUTHENTICATION_TOKEN_PROPERTY_NAME()); + } + @Test + void fromShouldReturnTheConfigurationWithTokenAuthenticationWhenRequiredParametersAreGiven() { + PropertiesConfiguration configuration = new PropertiesConfiguration(); + String brokerUri = "pulsar://localhost.test:6650/"; + String adminUri = "http://localhost:8090"; + String authenticationType = "basic"; + String authenticationUserId = "userId"; + String authenticationPassword = "password"; + + configuration.addProperty("broker.uri", brokerUri); + configuration.addProperty("admin.uri", adminUri); + configuration.addProperty("authentication.type", authenticationType); + configuration.addProperty("authentication.basic.userId", authenticationUserId); + configuration.addProperty("authentication.basic.password", authenticationPassword); + + String namespace = "namespace"; + + configuration.addProperty("namespace", namespace); + assertThat(PulsarConfiguration.from(configuration)) + .isEqualTo(new PulsarConfiguration(brokerUri, adminUri, new Namespace(namespace), Auth.basic(authenticationUserId, authenticationPassword))); + } + @Test + void fromShouldThrowWithBasicAuthenticationWhenUserIdIsMissing() { + PropertiesConfiguration configuration = new PropertiesConfiguration(); + String brokerUri = "pulsar://localhost.test:6650/"; + String adminUri = "http://localhost:8090"; + String authenticationType = "basic"; + String authenticationUserId = "userId"; + String authenticationPassword = "password"; + + configuration.addProperty("broker.uri", brokerUri); + configuration.addProperty("admin.uri", adminUri); + configuration.addProperty("authentication.type", authenticationType); + configuration.addProperty("authentication.basic.password", authenticationPassword); + String namespace = "namespace"; + + configuration.addProperty("namespace", namespace); + assertThatThrownBy(() -> PulsarConfiguration.from(configuration)) + .isInstanceOf(IllegalStateException.class) + .hasMessage("You need to specify a non-empty value for " + PulsarConfiguration.AUTHENTICATION_BASIC_USERID_PROPERTY_NAME()); + } + @Test + void fromShouldThrowWithBasicAuthenticationWhenPasswordIsMissing() { + PropertiesConfiguration configuration = new PropertiesConfiguration(); + String brokerUri = "pulsar://localhost.test:6650/"; + String adminUri = "http://localhost:8090"; + String authenticationType = "basic"; + String authenticationUserId = "userId"; + String authenticationPassword = "password"; + + configuration.addProperty("broker.uri", brokerUri); + configuration.addProperty("admin.uri", adminUri); + configuration.addProperty("authentication.type", authenticationType); + configuration.addProperty("authentication.basic.userId", authenticationUserId); + + String namespace = "namespace"; + + configuration.addProperty("namespace", namespace); + assertThatThrownBy(() -> PulsarConfiguration.from(configuration)) + .isInstanceOf(IllegalStateException.class) + .hasMessage("You need to specify a non-empty value for " + PulsarConfiguration.AUTHENTICATION_BASIC_PASSWORD_PROPERTY_NAME()); + } + + @Test + void fromShouldThrowWithUnknownAuthenticationType() { + PropertiesConfiguration configuration = new PropertiesConfiguration(); + String brokerUri = "pulsar://localhost.test:6650/"; + String adminUri = "http://localhost:8090"; + + configuration.addProperty("broker.uri", brokerUri); + configuration.addProperty("admin.uri", adminUri); + configuration.addProperty("authentication.type", "biscuit"); + + String namespace = "namespace"; + + configuration.addProperty("namespace", namespace); + assertThatThrownBy(() -> PulsarConfiguration.from(configuration)) + .isInstanceOf(NotImplementedError.class) + .hasMessage("Authentication type biscuit is not implemented"); + } } \ No newline at end of file --------------------------------------------------------------------- To unsubscribe, e-mail: [email protected] For additional commands, e-mail: [email protected]
