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

btellier 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 5a62eceb21 [ENHANCEMENT]  Integration tests for MaxRcptHandler (#2448)
5a62eceb21 is described below

commit 5a62eceb21ff8fd7b34bff387e273f8dc7b8d69e
Author: florentos17 <fazav...@linagora.com>
AuthorDate: Tue Oct 15 09:04:35 2024 +0200

    [ENHANCEMENT]  Integration tests for MaxRcptHandler (#2448)
---
 .../smtp/core/fastfail/MaxRcptHandler.java         |   2 +-
 .../mailets/configuration/SmtpConfiguration.java   |  50 ++++++++--
 .../src/main/resources/smtpserver.xml              |  12 ++-
 .../configuration/SmtpConfigurationTest.java       |  30 ++++++
 .../apache/james/smtp/SmtpMaxRcptHandlerTest.java  | 108 +++++++++++++++++++++
 .../james/smtpserver/fastfail/MaxRcptHandler.java  |   2 +-
 6 files changed, 190 insertions(+), 14 deletions(-)

diff --git 
a/protocols/smtp/src/main/java/org/apache/james/protocols/smtp/core/fastfail/MaxRcptHandler.java
 
b/protocols/smtp/src/main/java/org/apache/james/protocols/smtp/core/fastfail/MaxRcptHandler.java
index c3ae9b467b..632d69be5e 100644
--- 
a/protocols/smtp/src/main/java/org/apache/james/protocols/smtp/core/fastfail/MaxRcptHandler.java
+++ 
b/protocols/smtp/src/main/java/org/apache/james/protocols/smtp/core/fastfail/MaxRcptHandler.java
@@ -45,7 +45,7 @@ public class MaxRcptHandler implements RcptHook {
 
 
     /**
-     * Set the max rcpt for wich should be accepted
+     * Set the max rcpt for which a mail should be accepted
      * 
      * @param maxRcpt
      *            The max rcpt count
diff --git 
a/server/mailet/integration-testing/src/main/java/org/apache/james/mailets/configuration/SmtpConfiguration.java
 
b/server/mailet/integration-testing/src/main/java/org/apache/james/mailets/configuration/SmtpConfiguration.java
index 743754f46b..39088fa329 100644
--- 
a/server/mailet/integration-testing/src/main/java/org/apache/james/mailets/configuration/SmtpConfiguration.java
+++ 
b/server/mailet/integration-testing/src/main/java/org/apache/james/mailets/configuration/SmtpConfiguration.java
@@ -27,6 +27,8 @@ import java.io.StringReader;
 import java.io.Writer;
 import java.nio.charset.StandardCharsets;
 import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
 import java.util.Optional;
 
 import org.apache.commons.io.IOUtils;
@@ -44,9 +46,23 @@ public class SmtpConfiguration implements SerializableAsXml {
 
     static class HookConfigurationEntry {
         String hookFqcn;
+        Map<String, String> hookConfig;
+
+        HookConfigurationEntry(String hookFqcn, Map<String, String> 
hookConfig) {
+            this.hookFqcn = hookFqcn;
+            this.hookConfig = hookConfig;
+        }
 
         HookConfigurationEntry(String hookFqcn) {
             this.hookFqcn = hookFqcn;
+            this.hookConfig = new HashMap<>();
+        }
+
+        private static Map<String, Object> 
asMustacheScopes(HookConfigurationEntry hook) {
+            Map<String, Object> hookScope = new HashMap<>();
+            hookScope.put("hookFqcn", hook.hookFqcn);
+            hookScope.put("hookConfigAsXML", hook.hookConfig.entrySet());
+            return hookScope;
         }
     }
 
@@ -58,7 +74,7 @@ public class SmtpConfiguration implements SerializableAsXml {
         private Optional<SMTPConfiguration.SenderVerificationMode> 
verifyIndentity;
         private Optional<Boolean> bracketEnforcement;
         private Optional<String> authorizedAddresses;
-        private ImmutableList.Builder<HookConfigurationEntry> addittionalHooks;
+        private ImmutableList.Builder<HookConfigurationEntry> additionalHooks;
 
         public Builder() {
             authorizedAddresses = Optional.empty();
@@ -66,7 +82,7 @@ public class SmtpConfiguration implements SerializableAsXml {
             verifyIndentity = Optional.empty();
             maxMessageSize = Optional.empty();
             bracketEnforcement = Optional.empty();
-            addittionalHooks = ImmutableList.builder();
+            additionalHooks = ImmutableList.builder();
         }
 
         public Builder withAutorizedAddresses(String authorizedAddresses) {
@@ -111,7 +127,12 @@ public class SmtpConfiguration implements 
SerializableAsXml {
         }
 
         public Builder addHook(String hookFQCN) {
-            this.addittionalHooks.add(new HookConfigurationEntry(hookFQCN));
+            this.additionalHooks.add(new HookConfigurationEntry(hookFQCN));
+            return this;
+        }
+
+        public Builder addHook(String hookFQCN, Map<String, String> 
hookConfig) {
+            this.additionalHooks.add(new HookConfigurationEntry(hookFQCN, 
hookConfig));
             return this;
         }
 
@@ -121,7 +142,7 @@ public class SmtpConfiguration implements SerializableAsXml 
{
                 bracketEnforcement.orElse(true),
                 
verifyIndentity.orElse(SMTPConfiguration.SenderVerificationMode.DISABLED),
                 maxMessageSize.orElse(DEFAULT_DISABLED),
-                addittionalHooks.build());
+                additionalHooks.build());
         }
     }
 
@@ -134,16 +155,20 @@ public class SmtpConfiguration implements 
SerializableAsXml {
     private final boolean bracketEnforcement;
     private final SMTPConfiguration.SenderVerificationMode verifyIndentity;
     private final String maxMessageSize;
-    private final ImmutableList<HookConfigurationEntry> addittionalHooks;
-
-    private SmtpConfiguration(Optional<String> authorizedAddresses, boolean 
authRequired, boolean bracketEnforcement,
-                              SMTPConfiguration.SenderVerificationMode 
verifyIndentity, String maxMessageSize, ImmutableList<HookConfigurationEntry> 
addittionalHooks) {
+    private final ImmutableList<HookConfigurationEntry> additionalHooks;
+
+    private SmtpConfiguration(Optional<String> authorizedAddresses,
+                              boolean authRequired,
+                              boolean bracketEnforcement,
+                              SMTPConfiguration.SenderVerificationMode 
verifyIndentity,
+                              String maxMessageSize,
+                              ImmutableList<HookConfigurationEntry> 
additionalHooks) {
         this.authorizedAddresses = authorizedAddresses;
         this.authRequired = authRequired;
         this.bracketEnforcement = bracketEnforcement;
         this.verifyIndentity = verifyIndentity;
         this.maxMessageSize = maxMessageSize;
-        this.addittionalHooks = addittionalHooks;
+        this.additionalHooks = additionalHooks;
     }
 
     @Override
@@ -155,7 +180,12 @@ public class SmtpConfiguration implements 
SerializableAsXml {
         scopes.put("verifyIdentity", verifyIndentity.toString());
         scopes.put("maxmessagesize", maxMessageSize);
         scopes.put("bracketEnforcement", bracketEnforcement);
-        scopes.put("hooks", addittionalHooks);
+
+        List<Map<String, Object>> additionalHooksWithConfig = 
additionalHooks.stream()
+            .map(HookConfigurationEntry::asMustacheScopes)
+            .collect(ImmutableList.toImmutableList());
+
+        scopes.put("hooks", additionalHooksWithConfig);
 
         ByteArrayOutputStream byteArrayOutputStream = new 
ByteArrayOutputStream();
         Writer writer = new OutputStreamWriter(byteArrayOutputStream);
diff --git 
a/server/mailet/integration-testing/src/main/resources/smtpserver.xml 
b/server/mailet/integration-testing/src/main/resources/smtpserver.xml
index 4f0a039742..2d314ac085 100644
--- a/server/mailet/integration-testing/src/main/resources/smtpserver.xml
+++ b/server/mailet/integration-testing/src/main/resources/smtpserver.xml
@@ -49,7 +49,11 @@
             <handler 
class="org.apache.james.smtpserver.fastfail.ValidRcptHandler"/>
             <handler class="org.apache.james.smtpserver.CoreCmdHandlerLoader"/>
             {{#hooks}}
-            <handler class="{{hookFqcn}}"/>
+            <handler class="{{hookFqcn}}">
+                {{#hookConfigAsXML}}
+                <{{key}}>{{value}}</{{key}}>
+                {{/hookConfigAsXML}}
+            </handler>
             {{/hooks}}
         </handlerchain>
         <gracefulShutdown>false</gracefulShutdown>
@@ -87,7 +91,11 @@
             <handler 
class="org.apache.james.smtpserver.fastfail.ValidRcptHandler"/>
             <handler class="org.apache.james.smtpserver.CoreCmdHandlerLoader"/>
             {{#hooks}}
-            <handler class="{{hookFqcn}}"/>
+            <handler class="{{hookFqcn}}">
+                {{#hookConfigAsXML}}
+                <{{key}}>{{value}}</{{key}}>
+                {{/hookConfigAsXML}}
+            </handler>
             {{/hooks}}
         </handlerchain>
         <gracefulShutdown>false</gracefulShutdown>
diff --git 
a/server/mailet/integration-testing/src/test/java/org/apache/james/mailets/configuration/SmtpConfigurationTest.java
 
b/server/mailet/integration-testing/src/test/java/org/apache/james/mailets/configuration/SmtpConfigurationTest.java
index ef029cfd5a..58724e8bf2 100644
--- 
a/server/mailet/integration-testing/src/test/java/org/apache/james/mailets/configuration/SmtpConfigurationTest.java
+++ 
b/server/mailet/integration-testing/src/test/java/org/apache/james/mailets/configuration/SmtpConfigurationTest.java
@@ -24,6 +24,7 @@ import static org.hamcrest.MatcherAssert.assertThat;
 import static org.xmlunit.matchers.EvaluateXPathMatcher.hasXPath;
 
 import java.io.IOException;
+import java.util.Map;
 
 import javax.xml.transform.Source;
 
@@ -180,4 +181,33 @@ public class SmtpConfigurationTest {
             hasXPath("/smtpservers/smtpserver/verifyIdentity/text()",
                 is("DISABLED")));
     }
+
+    @Test
+    public void addHookShouldRegisterHookWithoutConfig() throws IOException {
+        String hookFqcn = "com.example.hooks.MyCustomHook";
+
+        SmtpConfiguration configuration = SmtpConfiguration.builder()
+                .addHook(hookFqcn)
+                .build();
+
+        assertThat(configuration.serializeAsXml(),
+                
hasXPath("/smtpservers/smtpserver/handlerchain/handler[@class='" + hookFqcn + 
"']/@class", is(hookFqcn)));
+    }
+
+    @Test
+    public void addHookShouldRegisterHookWithConfig() throws IOException {
+        String hookFqcn = "com.example.hooks.MyCustomHook";
+        Map<String, String> hookConfig = Map.of("param1", "value1", "param2", 
"value2");
+
+        SmtpConfiguration configuration = SmtpConfiguration.builder()
+                .addHook(hookFqcn, hookConfig)
+                .build();
+
+        String xmlOutput = configuration.serializeAsXml();
+        assertThat(xmlOutput, 
hasXPath("/smtpservers/smtpserver/handlerchain/handler[@class='" + hookFqcn + 
"']/@class", is(hookFqcn)));
+        assertThat(xmlOutput, 
hasXPath("/smtpservers/smtpserver/handlerchain/handler[@class='" + hookFqcn + 
"']/param1/text()", is("value1")));
+        assertThat(xmlOutput, 
hasXPath("/smtpservers/smtpserver/handlerchain/handler[@class='" + hookFqcn + 
"']/param2/text()", is("value2")));
+    }
+
+
 }
diff --git 
a/server/mailet/integration-testing/src/test/java/org/apache/james/smtp/SmtpMaxRcptHandlerTest.java
 
b/server/mailet/integration-testing/src/test/java/org/apache/james/smtp/SmtpMaxRcptHandlerTest.java
new file mode 100644
index 0000000000..77e5fbb37e
--- /dev/null
+++ 
b/server/mailet/integration-testing/src/test/java/org/apache/james/smtp/SmtpMaxRcptHandlerTest.java
@@ -0,0 +1,108 @@
+/****************************************************************
+ * 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.smtp;
+
+import static org.apache.james.mailets.configuration.Constants.DEFAULT_DOMAIN;
+import static org.apache.james.mailets.configuration.Constants.LOCALHOST_IP;
+import static org.apache.james.mailets.configuration.Constants.PASSWORD;
+import static org.assertj.core.api.Assertions.assertThatThrownBy;
+import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
+
+import java.io.File;
+import java.util.List;
+import java.util.Map;
+import java.util.stream.IntStream;
+
+import org.apache.james.mailets.TemporaryJamesServer;
+import org.apache.james.mailets.configuration.SmtpConfiguration;
+import org.apache.james.modules.protocols.SmtpGuiceProbe;
+import org.apache.james.probe.DataProbe;
+import org.apache.james.smtpserver.fastfail.MaxRcptHandler;
+import org.apache.james.utils.DataProbeImpl;
+import org.apache.james.utils.SMTPMessageSender;
+import org.apache.james.utils.SMTPSendingException;
+import org.apache.james.utils.SmtpSendingStep;
+import org.junit.jupiter.api.AfterEach;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.RegisterExtension;
+import org.junit.jupiter.api.io.TempDir;
+
+import com.github.fge.lambdas.Throwing;
+import com.google.common.collect.ImmutableList;
+
+class SmtpMaxRcptHandlerTest {
+    private static final String USER = "user@" + DEFAULT_DOMAIN;
+    private static final Integer DEFAULT_MAX_RCPT = 50;
+
+    @RegisterExtension
+    public SMTPMessageSender messageSender = new 
SMTPMessageSender(DEFAULT_DOMAIN);
+
+    private TemporaryJamesServer jamesServer;
+
+    @BeforeEach
+    public void createJamesServer(@TempDir File temporaryFolder) throws 
Exception {
+        SmtpConfiguration.Builder smtpConfiguration = 
SmtpConfiguration.builder()
+                .doNotVerifyIdentity()
+                .addHook(MaxRcptHandler.class.getName(),
+                        Map.of("maxRcpt", DEFAULT_MAX_RCPT.toString()));
+
+        jamesServer = TemporaryJamesServer.builder()
+            .withSmtpConfiguration(smtpConfiguration)
+            .build(temporaryFolder);
+        jamesServer.start();
+
+        DataProbe dataProbe = jamesServer.getProbe(DataProbeImpl.class);
+        dataProbe.addDomain(DEFAULT_DOMAIN);
+        dataProbe.addUser(USER, PASSWORD);
+        IntStream.range(0, DEFAULT_MAX_RCPT + 1).forEach(Throwing.intConsumer((
+                i -> dataProbe.addUser("recipient" + i + "@" + DEFAULT_DOMAIN, 
PASSWORD))));
+    }
+
+    @AfterEach
+    void tearDown() {
+        if (jamesServer != null) {
+            jamesServer.shutdown();
+        }
+    }
+
+    @Test
+    void messageShouldNotBeAcceptedWhenMaxRcptHandlerExceeded() throws 
Exception {
+        assertThatThrownBy(() ->
+            messageSender.connect(LOCALHOST_IP, 
jamesServer.getProbe(SmtpGuiceProbe.class).getSmtpPort())
+                .authenticate(USER, PASSWORD)
+                .sendMessageWithHeaders(USER, getRecipients(DEFAULT_MAX_RCPT + 
1), "message"))
+            .isEqualTo(new SMTPSendingException(SmtpSendingStep.RCPT, "452 
4.5.3 Requested action not taken: max recipients reached\n"));
+    }
+
+    @Test
+    void messageShouldBeAcceptedWhenMaxRcptHandlerWithinLimit() throws 
Exception {
+        assertDoesNotThrow(() ->
+            messageSender.connect(LOCALHOST_IP, 
jamesServer.getProbe(SmtpGuiceProbe.class).getSmtpPort())
+                .authenticate(USER, PASSWORD)
+                .sendMessageWithHeaders(USER, getRecipients(DEFAULT_MAX_RCPT), 
"message"));
+    }
+
+    private List<String> getRecipients(Integer n) {
+        return IntStream.range(0, n)
+                .mapToObj(i -> "recipient" + i + "@" + DEFAULT_DOMAIN)
+                .collect(ImmutableList.toImmutableList());
+    }
+}
diff --git 
a/server/protocols/protocols-smtp/src/main/java/org/apache/james/smtpserver/fastfail/MaxRcptHandler.java
 
b/server/protocols/protocols-smtp/src/main/java/org/apache/james/smtpserver/fastfail/MaxRcptHandler.java
index 8c957601af..b85340b42f 100644
--- 
a/server/protocols/protocols-smtp/src/main/java/org/apache/james/smtpserver/fastfail/MaxRcptHandler.java
+++ 
b/server/protocols/protocols-smtp/src/main/java/org/apache/james/smtpserver/fastfail/MaxRcptHandler.java
@@ -27,6 +27,6 @@ public class MaxRcptHandler extends 
org.apache.james.protocols.smtp.core.fastfai
     @Override
     public void init(Configuration config) throws ConfigurationException {
         int maxRcpt = config.getInt("maxRcpt", 0);
-        setMaxRcpt(maxRcpt);        
+        setMaxRcpt(maxRcpt);
     }
 }


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

Reply via email to