You are viewing a plain text version of this content. The canonical link for it is here.
Posted to notifications@james.apache.org by rc...@apache.org on 2021/06/21 04:20:55 UTC

[james-project] branch master updated: JAMES-3602 AmqpForwardAttribute should use credentials configured in the URI

This is an automated email from the ASF dual-hosted git repository.

rcordier pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/james-project.git


The following commit(s) were added to refs/heads/master by this push:
     new 2039267  JAMES-3602 AmqpForwardAttribute should use credentials configured in the URI
2039267 is described below

commit 2039267aae797626e8781dc1d2c2e51132bb5d2c
Author: Benoit Tellier <bt...@linagora.com>
AuthorDate: Sat Jun 19 14:05:22 2021 +0700

    JAMES-3602 AmqpForwardAttribute should use credentials configured in the URI
---
 .../transport/mailets/AmqpForwardAttribute.java    | 41 ++++++++++++++++++----
 .../mailets/AmqpForwardAttributeTest.java          | 37 +++++++++++++++++++
 2 files changed, 71 insertions(+), 7 deletions(-)

diff --git a/mailet/amqp/src/main/java/org/apache/james/transport/mailets/AmqpForwardAttribute.java b/mailet/amqp/src/main/java/org/apache/james/transport/mailets/AmqpForwardAttribute.java
index 324cf9e..bce20aa 100644
--- a/mailet/amqp/src/main/java/org/apache/james/transport/mailets/AmqpForwardAttribute.java
+++ b/mailet/amqp/src/main/java/org/apache/james/transport/mailets/AmqpForwardAttribute.java
@@ -45,8 +45,13 @@ import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
 import com.github.fge.lambdas.Throwing;
+import com.github.steveash.guavate.Guavate;
 import com.google.common.annotations.VisibleForTesting;
+import com.google.common.base.Joiner;
+import com.google.common.base.Preconditions;
+import com.google.common.base.Splitter;
 import com.google.common.base.Strings;
+import com.google.common.collect.ImmutableList;
 import com.google.common.collect.ImmutableSet;
 import com.rabbitmq.client.AlreadyClosedException;
 import com.rabbitmq.client.ConnectionFactory;
@@ -85,7 +90,7 @@ public class AmqpForwardAttribute extends GenericMailet {
     private static final String DEFAULT_USER = "guest";
     private static final String DEFAULT_PASSWORD_STRING = "guest";
     private static final char[] DEFAULT_PASSWORD = DEFAULT_PASSWORD_STRING.toCharArray();
-    private static final RabbitMQConfiguration.ManagementCredentials DEFAULT_MANAGEMENT_CREDENTIAL = new RabbitMQConfiguration.ManagementCredentials(DEFAULT_USER, DEFAULT_PASSWORD);
+    static final RabbitMQConfiguration.ManagementCredentials DEFAULT_MANAGEMENT_CREDENTIAL = new RabbitMQConfiguration.ManagementCredentials(DEFAULT_USER, DEFAULT_PASSWORD);
 
 
     public static final String URI_PARAMETER_NAME = "uri";
@@ -94,8 +99,6 @@ public class AmqpForwardAttribute extends GenericMailet {
     public static final String ATTRIBUTE_PARAMETER_NAME = "attribute";
 
     public static final String ROUTING_KEY_DEFAULT_VALUE = "";
-    public static final int MAX_ATTEMPTS = 8;
-    public static final Duration MIN_BACKOFF = Duration.ofSeconds(1);
 
     private String exchange;
     private AttributeName attribute;
@@ -111,10 +114,11 @@ public class AmqpForwardAttribute extends GenericMailet {
         String uri = preInit(mailetConfig);
 
         try {
+            URI amqpUri = new URI(uri);
             RabbitMQConfiguration rabbitMQConfiguration = RabbitMQConfiguration.builder()
-                .amqpUri(new URI(uri))
-                .managementUri(new URI(uri))
-                .managementCredentials(DEFAULT_MANAGEMENT_CREDENTIAL)
+                .amqpUri(amqpUri)
+                .managementUri(amqpUri)
+                .managementCredentials(retrieveCredentials(amqpUri))
                 .maxRetries(MAX_THREE_RETRIES)
                 .minDelayInMs(MIN_DELAY_OF_TEN_MILLISECONDS)
                 .connectionTimeoutInMs(CONNECTION_TIMEOUT_OF_ONE_HUNDRED_MILLISECOND)
@@ -135,7 +139,30 @@ public class AmqpForwardAttribute extends GenericMailet {
         } catch (URISyntaxException e) {
             throw new RuntimeException(e);
         }
-}
+    }
+
+    @VisibleForTesting
+    RabbitMQConfiguration.ManagementCredentials retrieveCredentials(URI amqpUri) {
+        return Optional.ofNullable(amqpUri.getUserInfo())
+            .map(this::parseUserInfo)
+            .orElse(DEFAULT_MANAGEMENT_CREDENTIAL);
+    }
+
+    private RabbitMQConfiguration.ManagementCredentials parseUserInfo(String userInfo) {
+        Preconditions.checkArgument(userInfo.contains(":"), "User info needs a password part");
+
+        List<String> parts = Splitter.on(':')
+            .splitToList(userInfo);
+        ImmutableList<String> passwordParts = parts.stream()
+            .skip(1)
+            .collect(Guavate.toImmutableList());
+
+        return new RabbitMQConfiguration.ManagementCredentials(
+            parts.get(0),
+            Joiner.on(':')
+                .join(passwordParts)
+                .toCharArray());
+    }
 
     @VisibleForTesting
     String preInit(MailetConfig mailetConfig) throws MailetException {
diff --git a/mailet/amqp/src/test/java/org/apache/james/transport/mailets/AmqpForwardAttributeTest.java b/mailet/amqp/src/test/java/org/apache/james/transport/mailets/AmqpForwardAttributeTest.java
index c2a6a56..28feea8 100644
--- a/mailet/amqp/src/test/java/org/apache/james/transport/mailets/AmqpForwardAttributeTest.java
+++ b/mailet/amqp/src/test/java/org/apache/james/transport/mailets/AmqpForwardAttributeTest.java
@@ -19,16 +19,19 @@
 
 package org.apache.james.transport.mailets;
 
+import static org.apache.james.transport.mailets.AmqpForwardAttribute.DEFAULT_MANAGEMENT_CREDENTIAL;
 import static org.assertj.core.api.Assertions.assertThat;
 import static org.assertj.core.api.Assertions.assertThatThrownBy;
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.when;
 
+import java.net.URI;
 import java.nio.charset.StandardCharsets;
 import java.util.Optional;
 
 import javax.mail.MessagingException;
 
+import org.apache.james.backends.rabbitmq.RabbitMQConfiguration.ManagementCredentials;
 import org.apache.mailet.Attribute;
 import org.apache.mailet.AttributeName;
 import org.apache.mailet.AttributeValue;
@@ -38,6 +41,7 @@ import org.apache.mailet.MailetException;
 import org.apache.mailet.base.test.FakeMailContext;
 import org.apache.mailet.base.test.FakeMailetConfig;
 import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Nested;
 import org.junit.jupiter.api.Test;
 import org.slf4j.Logger;
 
@@ -153,4 +157,37 @@ class AmqpForwardAttributeTest {
         assertThatThrownBy(() -> mailet.service(mail))
             .isInstanceOf(MailetException.class);
     }
+
+    @Nested
+    class CreadentialTests {
+        @Test
+        void shouldReturnDefaultCredentialsWhenNoUserInfo() throws Exception {
+            assertThat(mailet.retrieveCredentials(new URI(AMQP_URI)))
+                .isEqualTo(DEFAULT_MANAGEMENT_CREDENTIAL);
+        }
+
+        @Test
+        void shouldThrowWhenNoPassword() throws Exception {
+            assertThatThrownBy(() -> mailet.retrieveCredentials(new URI("amqp://user@host")))
+                .isInstanceOf(IllegalArgumentException.class);
+        }
+
+        @Test
+        void shouldReturnUriCredentials() throws Exception {
+            assertThat(mailet.retrieveCredentials(new URI("amqp://user:pass@host")))
+                .isEqualTo(new ManagementCredentials("user", "pass".toCharArray()));
+        }
+
+        @Test
+        void passwordCanContainSemiColon() throws Exception {
+            assertThat(mailet.retrieveCredentials(new URI("amqp://user:pass:part2@host")))
+                .isEqualTo(new ManagementCredentials("user", "pass:part2".toCharArray()));
+        }
+
+        @Test
+        void shouldDecodeUserInfo() throws Exception {
+            assertThat(mailet.retrieveCredentials(new URI("amqp://Arnab_Kundu%E2%82%AC:pass@host")))
+                .isEqualTo(new ManagementCredentials("Arnab_Kundu€", "pass".toCharArray()));
+        }
+    }
 }

---------------------------------------------------------------------
To unsubscribe, e-mail: notifications-unsubscribe@james.apache.org
For additional commands, e-mail: notifications-help@james.apache.org