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

commit 2b80ac3444edbe676efffc6dba949ac83993b806
Author: Benoit Tellier <[email protected]>
AuthorDate: Thu Mar 12 20:28:24 2020 +0700

    JAMES-3113 Mails send from an alias should be considered as localSender
---
 .../mailets/SenderIsLocalIntegrationTest.java      | 141 +++++++++++++++++++++
 .../james/mailets/configuration/Constants.java     |   1 +
 .../mailetcontainer/impl/JamesMailetContext.java   |  28 +++-
 .../impl/JamesMailetContextTest.java               |   5 +-
 4 files changed, 171 insertions(+), 4 deletions(-)

diff --git 
a/server/mailet/integration-testing/src/test/java/org/apache/james/mailets/SenderIsLocalIntegrationTest.java
 
b/server/mailet/integration-testing/src/test/java/org/apache/james/mailets/SenderIsLocalIntegrationTest.java
new file mode 100644
index 0000000..57e2898
--- /dev/null
+++ 
b/server/mailet/integration-testing/src/test/java/org/apache/james/mailets/SenderIsLocalIntegrationTest.java
@@ -0,0 +1,141 @@
+/****************************************************************
+ * 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.mailets;
+
+import static org.apache.james.mailets.configuration.Constants.ALIAS;
+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.apache.james.mailets.configuration.Constants.RECIPIENT;
+import static org.apache.james.mailets.configuration.Constants.RECIPIENT2;
+import static 
org.apache.james.mailets.configuration.Constants.awaitAtMostOneMinute;
+
+import org.apache.james.MemoryJamesServerMain;
+import org.apache.james.mailets.configuration.CommonProcessors;
+import org.apache.james.mailets.configuration.MailetConfiguration;
+import org.apache.james.mailets.configuration.MailetContainer;
+import org.apache.james.mailets.configuration.ProcessorConfiguration;
+import org.apache.james.mailrepository.api.MailRepositoryUrl;
+import org.apache.james.modules.protocols.ImapGuiceProbe;
+import org.apache.james.modules.protocols.SmtpGuiceProbe;
+import org.apache.james.probe.DataProbe;
+import org.apache.james.transport.mailets.Bounce;
+import org.apache.james.transport.mailets.DSNBounce;
+import org.apache.james.transport.mailets.Forward;
+import org.apache.james.transport.mailets.LocalDelivery;
+import org.apache.james.transport.mailets.NotifyPostmaster;
+import org.apache.james.transport.mailets.NotifySender;
+import org.apache.james.transport.mailets.Redirect;
+import org.apache.james.transport.mailets.Resend;
+import org.apache.james.transport.mailets.ToRepository;
+import org.apache.james.transport.matchers.All;
+import org.apache.james.transport.matchers.RecipientIs;
+import org.apache.james.transport.matchers.SenderIsLocal;
+import org.apache.james.utils.DataProbeImpl;
+import org.apache.james.utils.IMAPMessageReader;
+import org.apache.james.utils.MailRepositoryProbeImpl;
+import org.apache.james.utils.SMTPMessageSender;
+import org.apache.james.utils.WebAdminGuiceProbe;
+import org.apache.james.webadmin.WebAdminUtils;
+import org.apache.james.webadmin.routes.AliasRoutes;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.TemporaryFolder;
+
+import io.restassured.specification.RequestSpecification;
+
+public class SenderIsLocalIntegrationTest {
+    private static final String POSTMASTER = "postmaster@" + DEFAULT_DOMAIN;
+    private static final MailRepositoryUrl LOCAL_SENDER_REPOSITORY = 
MailRepositoryUrl.from("memory://var/mail/local/sender/");
+    private static final MailRepositoryUrl REMOTE_SENDER_REPOSITORY = 
MailRepositoryUrl.from("memory://var/mail/remote/sender/");
+
+    @Rule
+    public TemporaryFolder temporaryFolder = new TemporaryFolder();
+    @Rule
+    public IMAPMessageReader imapMessageReader = new IMAPMessageReader();
+    @Rule
+    public SMTPMessageSender messageSender = new 
SMTPMessageSender(DEFAULT_DOMAIN);
+
+    private TemporaryJamesServer jamesServer;
+    private MailRepositoryProbeImpl probe;
+    private RequestSpecification webAdminApi;
+
+    @Before
+    public void setUp() throws Exception {
+        jamesServer = TemporaryJamesServer.builder()
+            .withBase(MemoryJamesServerMain.IN_MEMORY_SERVER_AGGREGATE_MODULE)
+            
.withMailetContainer(TemporaryJamesServer.DEFAULT_MAILET_CONTAINER_CONFIGURATION
+                .postmaster(POSTMASTER)
+                .putProcessor(transport()))
+            .build(temporaryFolder.newFolder());
+        probe = jamesServer.getProbe(MailRepositoryProbeImpl.class);
+
+        DataProbe dataProbe = jamesServer.getProbe(DataProbeImpl.class);
+        dataProbe.addDomain(DEFAULT_DOMAIN);
+        dataProbe.addUser(RECIPIENT, PASSWORD);
+        webAdminApi = 
WebAdminUtils.spec(jamesServer.getProbe(WebAdminGuiceProbe.class).getWebAdminPort());
+    }
+
+    @After
+    public void tearDown() {
+        jamesServer.shutdown();
+    }
+
+    @Test
+    public void shouldMatchLocalSender() throws Exception {
+        messageSender.connect(LOCALHOST_IP, 
jamesServer.getProbe(SmtpGuiceProbe.class).getSmtpPort())
+            .sendMessage(RECIPIENT, RECIPIENT);
+
+        awaitAtMostOneMinute.until(() -> 
probe.getRepositoryMailCount(LOCAL_SENDER_REPOSITORY) == 1);
+    }
+
+    @Test
+    public void shouldMatchLocalSenderAlias() throws Exception {
+        webAdminApi.put(AliasRoutes.ROOT_PATH + "/" + RECIPIENT + "/sources/" 
+ ALIAS);
+
+        messageSender.connect(LOCALHOST_IP, 
jamesServer.getProbe(SmtpGuiceProbe.class).getSmtpPort())
+            .sendMessage(ALIAS, RECIPIENT);
+
+        awaitAtMostOneMinute.until(() -> 
probe.getRepositoryMailCount(LOCAL_SENDER_REPOSITORY) == 1);
+    }
+
+    @Test
+    public void shouldNotMatchRemoteSender() throws Exception {
+        messageSender.connect(LOCALHOST_IP, 
jamesServer.getProbe(SmtpGuiceProbe.class).getSmtpPort())
+            .sendMessage("[email protected]", RECIPIENT);
+
+        awaitAtMostOneMinute.until(() -> 
probe.getRepositoryMailCount(REMOTE_SENDER_REPOSITORY) == 1);
+    }
+
+    private ProcessorConfiguration.Builder transport() {
+        return ProcessorConfiguration.transport()
+            .addMailet(MailetConfiguration.builder()
+                .matcher(SenderIsLocal.class)
+                .mailet(ToRepository.class)
+                .addProperty("repositoryPath", 
LOCAL_SENDER_REPOSITORY.asString()))
+            .addMailet(MailetConfiguration.builder()
+                .matcher(All.class)
+                .mailet(ToRepository.class)
+                .addProperty("repositoryPath", 
REMOTE_SENDER_REPOSITORY.asString()))
+            .addMailetsFrom(CommonProcessors.transport());
+    }
+}
diff --git 
a/server/mailet/integration-testing/src/test/java/org/apache/james/mailets/configuration/Constants.java
 
b/server/mailet/integration-testing/src/test/java/org/apache/james/mailets/configuration/Constants.java
index 13522f4..8e18a09 100644
--- 
a/server/mailet/integration-testing/src/test/java/org/apache/james/mailets/configuration/Constants.java
+++ 
b/server/mailet/integration-testing/src/test/java/org/apache/james/mailets/configuration/Constants.java
@@ -45,5 +45,6 @@ public class Constants {
     public static final String PASSWORD = "secret";
     public static final String FROM = "user@" + DEFAULT_DOMAIN;
     public static final String RECIPIENT = "user2@" + DEFAULT_DOMAIN;
+    public static final String ALIAS = "user2alias@" + DEFAULT_DOMAIN;
     public static final String RECIPIENT2 = "user3@" + DEFAULT_DOMAIN;
 }
diff --git 
a/server/mailet/mailetcontainer-camel/src/main/java/org/apache/james/mailetcontainer/impl/JamesMailetContext.java
 
b/server/mailet/mailetcontainer-camel/src/main/java/org/apache/james/mailetcontainer/impl/JamesMailetContext.java
index e1c3483..6309e52 100644
--- 
a/server/mailet/mailetcontainer-camel/src/main/java/org/apache/james/mailetcontainer/impl/JamesMailetContext.java
+++ 
b/server/mailet/mailetcontainer-camel/src/main/java/org/apache/james/mailetcontainer/impl/JamesMailetContext.java
@@ -22,6 +22,7 @@ package org.apache.james.mailetcontainer.impl;
 import java.io.IOException;
 import java.util.Collection;
 import java.util.Date;
+import java.util.EnumSet;
 import java.util.HashSet;
 import java.util.Iterator;
 import java.util.List;
@@ -56,6 +57,10 @@ import org.apache.james.lifecycle.api.Disposable;
 import org.apache.james.lifecycle.api.LifecycleUtil;
 import org.apache.james.queue.api.MailQueue;
 import org.apache.james.queue.api.MailQueueFactory;
+import org.apache.james.rrt.api.RecipientRewriteTable;
+import org.apache.james.rrt.api.RecipientRewriteTable.ErrorMappingException;
+import org.apache.james.rrt.api.RecipientRewriteTableException;
+import org.apache.james.rrt.lib.Mapping;
 import org.apache.james.server.core.MailImpl;
 import org.apache.james.user.api.UsersRepository;
 import org.apache.james.user.api.UsersRepositoryException;
@@ -66,11 +71,13 @@ import org.apache.mailet.base.RFC2822Headers;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
+import com.github.fge.lambdas.Throwing;
 import com.google.common.base.Preconditions;
 import com.google.common.collect.ImmutableSet;
 
 public class JamesMailetContext implements MailetContext, Configurable, 
Disposable {
     private static final Logger LOGGER = 
LoggerFactory.getLogger(JamesMailetContext.class);
+    public static final EnumSet<Mapping.Type> ALIAS_TYPES = 
EnumSet.of(Mapping.Type.Alias, Mapping.Type.DomainAlias);
 
     /**
      * A hash table of server attributes These are the MailetContext attributes
@@ -80,15 +87,17 @@ public class JamesMailetContext implements MailetContext, 
Configurable, Disposab
     protected final DNSService dns;
     private final UsersRepository localusers;
     private final DomainList domains;
+    private final RecipientRewriteTable recipientRewriteTable;
     private final MailQueueFactory<?> mailQueueFactory;
     private MailQueue rootMailQueue;
     private MailAddress postmaster;
 
     @Inject
-    public JamesMailetContext(DNSService dns, UsersRepository localusers, 
DomainList domains, MailQueueFactory<?> mailQueueFactory) {
+    public JamesMailetContext(DNSService dns, UsersRepository localusers, 
DomainList domains, RecipientRewriteTable recipientRewriteTable, 
MailQueueFactory<?> mailQueueFactory) {
         this.dns = dns;
         this.localusers = localusers;
         this.domains = domains;
+        this.recipientRewriteTable = recipientRewriteTable;
         this.mailQueueFactory = mailQueueFactory;
     }
 
@@ -261,14 +270,27 @@ public class JamesMailetContext implements MailetContext, 
Configurable, Disposab
                 return false;
             }
             try {
-                return localusers.contains(localusers.getUser(mailAddress));
-            } catch (UsersRepositoryException e) {
+                return isLocaluser(mailAddress)
+                    || isLocalAlias(mailAddress);
+            } catch (UsersRepositoryException | ErrorMappingException | 
RecipientRewriteTableException e) {
                 LOGGER.error("Unable to access UsersRepository", e);
             }
         }
         return false;
     }
 
+    private boolean isLocaluser(MailAddress mailAddress) throws 
UsersRepositoryException {
+        return localusers.contains(localusers.getUser(mailAddress));
+    }
+
+    private boolean isLocalAlias(MailAddress mailAddress) throws 
UsersRepositoryException, ErrorMappingException, RecipientRewriteTableException 
{
+        return 
recipientRewriteTable.getResolvedMappings(mailAddress.getLocalPart(), 
mailAddress.getDomain(), ALIAS_TYPES)
+            .asStream()
+            .map(mapping -> mapping.asMailAddress()
+                .orElseThrow(() -> new 
IllegalStateException(String.format("Can not compute address for mapping %s", 
mapping.asString()))))
+            .anyMatch(Throwing.predicate(this::isLocaluser).sneakyThrow());
+    }
+
     @Override
     public MailAddress getPostmaster() {
         return postmaster;
diff --git 
a/server/mailet/mailetcontainer-camel/src/test/java/org/apache/james/mailetcontainer/impl/JamesMailetContextTest.java
 
b/server/mailet/mailetcontainer-camel/src/test/java/org/apache/james/mailetcontainer/impl/JamesMailetContextTest.java
index 6dccf9c..b3c8713 100644
--- 
a/server/mailet/mailetcontainer-camel/src/test/java/org/apache/james/mailetcontainer/impl/JamesMailetContextTest.java
+++ 
b/server/mailet/mailetcontainer-camel/src/test/java/org/apache/james/mailetcontainer/impl/JamesMailetContextTest.java
@@ -40,6 +40,7 @@ import 
org.apache.james.domainlist.lib.DomainListConfiguration;
 import org.apache.james.domainlist.memory.MemoryDomainList;
 import org.apache.james.queue.api.MailQueue;
 import org.apache.james.queue.api.MailQueueFactory;
+import org.apache.james.rrt.memory.MemoryRecipientRewriteTable;
 import org.apache.james.server.core.MailImpl;
 import org.apache.james.user.memory.MemoryUsersRepository;
 import org.apache.james.util.MimeMessageUtil;
@@ -80,11 +81,13 @@ public class JamesMailetContextTest {
             .build());
 
         usersRepository = MemoryUsersRepository.withVirtualHosting(domainList);
+        MemoryRecipientRewriteTable recipientRewriteTable = new 
MemoryRecipientRewriteTable();
+        recipientRewriteTable.configure(new BaseHierarchicalConfiguration());
         MailQueueFactory<MailQueue> mailQueueFactory = 
mock(MailQueueFactory.class);
         spoolMailQueue = mock(MailQueue.class);
         
when(mailQueueFactory.createQueue(MailQueueFactory.SPOOL)).thenReturn(spoolMailQueue);
         DNSService dnsService = null;
-        testee = new JamesMailetContext(dnsService, usersRepository, 
domainList, mailQueueFactory);
+        testee = new JamesMailetContext(dnsService, usersRepository, 
domainList, recipientRewriteTable, mailQueueFactory);
         testee.configure(new BaseHierarchicalConfiguration());
         mailAddress = new MailAddress(USERMAIL.asString());
     }


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to