You are viewing a plain text version of this content. The canonical link for it is here.
Posted to server-dev@james.apache.org by ro...@apache.org on 2020/02/14 10:33:19 UTC

[james-project] 01/02: JAMES-3038 SMTP allow user to send mail using an alias

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

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

commit 052b72ddaac99c721c82bf94b84ca9d84231f40f
Author: RĂ©mi KOWALSKI <rk...@linagora.com>
AuthorDate: Fri Jan 31 14:30:35 2020 +0100

    JAMES-3038 SMTP allow user to send mail using an alias
---
 .../data/CassandraRecipientRewriteTableModule.java |   4 +
 .../data/JPARecipientRewriteTableModule.java       |   4 +
 .../james/modules/data/MemoryDataModule.java       |   5 +
 .../apache/james/jmap/draft/JMAPCommonModule.java  |   4 -
 .../META-INF/org/apache/james/spring-server.xml    |   1 +
 .../SenderAuthIdentifyVerificationRcptHook.java    |   9 +-
 .../apache/james/smtpserver/SMTPServerTest.java    | 222 +++++++++++++++++++--
 7 files changed, 230 insertions(+), 19 deletions(-)

diff --git a/server/container/guice/cassandra-guice/src/main/java/org/apache/james/modules/data/CassandraRecipientRewriteTableModule.java b/server/container/guice/cassandra-guice/src/main/java/org/apache/james/modules/data/CassandraRecipientRewriteTableModule.java
index 939f641..5a1836f 100644
--- a/server/container/guice/cassandra-guice/src/main/java/org/apache/james/modules/data/CassandraRecipientRewriteTableModule.java
+++ b/server/container/guice/cassandra-guice/src/main/java/org/apache/james/modules/data/CassandraRecipientRewriteTableModule.java
@@ -19,11 +19,13 @@
 package org.apache.james.modules.data;
 
 import org.apache.james.backends.cassandra.components.CassandraModule;
+import org.apache.james.rrt.api.CanSendFrom;
 import org.apache.james.rrt.api.RecipientRewriteTable;
 import org.apache.james.rrt.cassandra.CassandraMappingsSourcesDAO;
 import org.apache.james.rrt.cassandra.CassandraRRTModule;
 import org.apache.james.rrt.cassandra.CassandraRecipientRewriteTable;
 import org.apache.james.rrt.cassandra.CassandraRecipientRewriteTableDAO;
+import org.apache.james.rrt.lib.CanSendFromImpl;
 import org.apache.james.server.core.configuration.ConfigurationProvider;
 import org.apache.james.utils.InitializationOperation;
 import org.apache.james.utils.InitilizationOperationBuilder;
@@ -40,6 +42,8 @@ public class CassandraRecipientRewriteTableModule extends AbstractModule {
         bind(CassandraRecipientRewriteTableDAO.class).in(Scopes.SINGLETON);
         bind(CassandraMappingsSourcesDAO.class).in(Scopes.SINGLETON);
         bind(RecipientRewriteTable.class).to(CassandraRecipientRewriteTable.class);
+        bind(CanSendFromImpl.class).in(Scopes.SINGLETON);
+        bind(CanSendFrom.class).to(CanSendFromImpl.class);
         Multibinder<CassandraModule> cassandraDataDefinitions = Multibinder.newSetBinder(binder(), CassandraModule.class);
         cassandraDataDefinitions.addBinding().toInstance(CassandraRRTModule.MODULE);
     }
diff --git a/server/container/guice/jpa-common-guice/src/main/java/org/apache/james/modules/data/JPARecipientRewriteTableModule.java b/server/container/guice/jpa-common-guice/src/main/java/org/apache/james/modules/data/JPARecipientRewriteTableModule.java
index b0456f1..f22eb63 100644
--- a/server/container/guice/jpa-common-guice/src/main/java/org/apache/james/modules/data/JPARecipientRewriteTableModule.java
+++ b/server/container/guice/jpa-common-guice/src/main/java/org/apache/james/modules/data/JPARecipientRewriteTableModule.java
@@ -18,8 +18,10 @@
  ****************************************************************/
 package org.apache.james.modules.data;
 
+import org.apache.james.rrt.api.CanSendFrom;
 import org.apache.james.rrt.api.RecipientRewriteTable;
 import org.apache.james.rrt.jpa.JPARecipientRewriteTable;
+import org.apache.james.rrt.lib.CanSendFromImpl;
 import org.apache.james.server.core.configuration.ConfigurationProvider;
 import org.apache.james.utils.InitializationOperation;
 import org.apache.james.utils.InitilizationOperationBuilder;
@@ -33,6 +35,8 @@ public class JPARecipientRewriteTableModule extends AbstractModule {
     public void configure() {
         bind(JPARecipientRewriteTable.class).in(Scopes.SINGLETON);
         bind(RecipientRewriteTable.class).to(JPARecipientRewriteTable.class);
+        bind(CanSendFromImpl.class).in(Scopes.SINGLETON);
+        bind(CanSendFrom.class).to(CanSendFromImpl.class);
     }
 
     @ProvidesIntoSet
diff --git a/server/container/guice/memory-guice/src/main/java/org/apache/james/modules/data/MemoryDataModule.java b/server/container/guice/memory-guice/src/main/java/org/apache/james/modules/data/MemoryDataModule.java
index 7daf4b5..d78baca 100644
--- a/server/container/guice/memory-guice/src/main/java/org/apache/james/modules/data/MemoryDataModule.java
+++ b/server/container/guice/memory-guice/src/main/java/org/apache/james/modules/data/MemoryDataModule.java
@@ -32,7 +32,9 @@ import org.apache.james.mailrepository.memory.MailRepositoryStoreConfiguration;
 import org.apache.james.mailrepository.memory.MemoryMailRepository;
 import org.apache.james.mailrepository.memory.MemoryMailRepositoryUrlStore;
 import org.apache.james.modules.server.MailStoreRepositoryModule;
+import org.apache.james.rrt.api.CanSendFrom;
 import org.apache.james.rrt.api.RecipientRewriteTable;
+import org.apache.james.rrt.lib.CanSendFromImpl;
 import org.apache.james.rrt.memory.MemoryRecipientRewriteTable;
 import org.apache.james.server.core.configuration.ConfigurationProvider;
 import org.apache.james.user.api.UsersRepository;
@@ -66,6 +68,9 @@ public class MemoryDataModule extends AbstractModule {
         bind(MemoryRecipientRewriteTable.class).in(Scopes.SINGLETON);
         bind(RecipientRewriteTable.class).to(MemoryRecipientRewriteTable.class);
 
+        bind(CanSendFromImpl.class).in(Scopes.SINGLETON);
+        bind(CanSendFrom.class).to(CanSendFromImpl.class);
+
         bind(MemoryMailRepositoryUrlStore.class).in(Scopes.SINGLETON);
         bind(MailRepositoryUrlStore.class).to(MemoryMailRepositoryUrlStore.class);
 
diff --git a/server/container/guice/protocols/jmap-draft/src/main/java/org/apache/james/jmap/draft/JMAPCommonModule.java b/server/container/guice/protocols/jmap-draft/src/main/java/org/apache/james/jmap/draft/JMAPCommonModule.java
index e53b9cd..34184a7 100644
--- a/server/container/guice/protocols/jmap-draft/src/main/java/org/apache/james/jmap/draft/JMAPCommonModule.java
+++ b/server/container/guice/protocols/jmap-draft/src/main/java/org/apache/james/jmap/draft/JMAPCommonModule.java
@@ -43,8 +43,6 @@ import org.apache.james.jmap.draft.utils.HeadersAuthenticationExtractor;
 import org.apache.james.jmap.event.ComputeMessageFastViewProjectionListener;
 import org.apache.james.lifecycle.api.StartUpCheck;
 import org.apache.james.mailbox.events.MailboxListener;
-import org.apache.james.rrt.api.CanSendFrom;
-import org.apache.james.rrt.lib.CanSendFromImpl;
 import org.apache.james.util.date.DefaultZonedDateTimeProvider;
 import org.apache.james.util.date.ZonedDateTimeProvider;
 import org.apache.james.util.mime.MessageContentExtractor;
@@ -80,8 +78,6 @@ public class JMAPCommonModule extends AbstractModule {
         bind(MessageHeaderViewFactory.class).in(Scopes.SINGLETON);
         bind(MessageFastViewFactory.class).in(Scopes.SINGLETON);
 
-        bind(CanSendFrom.class).to(CanSendFromImpl.class).in(Scopes.SINGLETON);
-
         bind(MessageContentExtractor.class).in(Scopes.SINGLETON);
         bind(HeadersAuthenticationExtractor.class).in(Scopes.SINGLETON);
         bind(SecurityKeyLoader.class).in(Scopes.SINGLETON);
diff --git a/server/container/spring/src/main/resources/META-INF/org/apache/james/spring-server.xml b/server/container/spring/src/main/resources/META-INF/org/apache/james/spring-server.xml
index 665e7be..46b1f29 100644
--- a/server/container/spring/src/main/resources/META-INF/org/apache/james/spring-server.xml
+++ b/server/container/spring/src/main/resources/META-INF/org/apache/james/spring-server.xml
@@ -326,4 +326,5 @@
 
     <bean id="jspfLogger" class="org.apache.james.smtpserver.fastfail.SPFHandler.SPFLogger"/>
 
+    <bean id="cansendfrom" class="org.apache.james.rrt.lib.CanSendFromImpl" />
 </beans>
diff --git a/server/protocols/protocols-smtp/src/main/java/org/apache/james/smtpserver/SenderAuthIdentifyVerificationRcptHook.java b/server/protocols/protocols-smtp/src/main/java/org/apache/james/smtpserver/SenderAuthIdentifyVerificationRcptHook.java
index 0faa527..63d98c7 100644
--- a/server/protocols/protocols-smtp/src/main/java/org/apache/james/smtpserver/SenderAuthIdentifyVerificationRcptHook.java
+++ b/server/protocols/protocols-smtp/src/main/java/org/apache/james/smtpserver/SenderAuthIdentifyVerificationRcptHook.java
@@ -29,6 +29,7 @@ import org.apache.james.domainlist.api.DomainListException;
 import org.apache.james.protocols.smtp.SMTPSession;
 import org.apache.james.protocols.smtp.core.AbstractSenderAuthIdentifyVerificationRcptHook;
 import org.apache.james.protocols.smtp.hook.HookResult;
+import org.apache.james.rrt.api.CanSendFrom;
 import org.apache.james.user.api.UsersRepository;
 import org.apache.james.user.api.UsersRepositoryException;
 
@@ -38,11 +39,13 @@ import org.apache.james.user.api.UsersRepositoryException;
 public class SenderAuthIdentifyVerificationRcptHook extends AbstractSenderAuthIdentifyVerificationRcptHook {
     private final DomainList domains;
     private final UsersRepository users;
+    private final CanSendFrom canSendFrom;
 
     @Inject
-    public SenderAuthIdentifyVerificationRcptHook(DomainList domains, UsersRepository users) {
+    public SenderAuthIdentifyVerificationRcptHook(DomainList domains, UsersRepository users, CanSendFrom canSendFrom) {
         this.domains = domains;
         this.users = users;
+        this.canSendFrom = canSendFrom;
     }
 
     @Override
@@ -74,7 +77,7 @@ public class SenderAuthIdentifyVerificationRcptHook extends AbstractSenderAuthId
     }
 
     @Override
-    protected boolean isSenderAllowed(Username user, Username sender) {
-        return user.equals(sender);
+    protected boolean isSenderAllowed(Username connectedUser, Username sender) {
+        return canSendFrom.userCanSendFrom(connectedUser, sender);
     }
 }
diff --git a/server/protocols/protocols-smtp/src/test/java/org/apache/james/smtpserver/SMTPServerTest.java b/server/protocols/protocols-smtp/src/test/java/org/apache/james/smtpserver/SMTPServerTest.java
index 8414b7a..9e5278a 100644
--- a/server/protocols/protocols-smtp/src/test/java/org/apache/james/smtpserver/SMTPServerTest.java
+++ b/server/protocols/protocols-smtp/src/test/java/org/apache/james/smtpserver/SMTPServerTest.java
@@ -50,6 +50,7 @@ import org.apache.james.core.Domain;
 import org.apache.james.core.MailAddress;
 import org.apache.james.core.Username;
 import org.apache.james.dnsservice.api.DNSService;
+import org.apache.james.dnsservice.api.InMemoryDNSService;
 import org.apache.james.domainlist.api.DomainList;
 import org.apache.james.domainlist.memory.MemoryDomainList;
 import org.apache.james.filesystem.api.FileSystem;
@@ -69,7 +70,10 @@ import org.apache.james.protocols.netty.AbstractChannelPipelineFactory;
 import org.apache.james.queue.api.MailQueueFactory;
 import org.apache.james.queue.api.RawMailQueueItemDecoratorFactory;
 import org.apache.james.queue.memory.MemoryMailQueueFactory;
+import org.apache.james.rrt.api.CanSendFrom;
 import org.apache.james.rrt.api.RecipientRewriteTable;
+import org.apache.james.rrt.lib.CanSendFromImpl;
+import org.apache.james.rrt.lib.MappingSource;
 import org.apache.james.rrt.memory.MemoryRecipientRewriteTable;
 import org.apache.james.server.core.configuration.Configuration;
 import org.apache.james.server.core.filesystem.FileSystemImpl;
@@ -91,6 +95,10 @@ import com.google.inject.TypeLiteral;
 
 public class SMTPServerTest {
 
+    public static final String LOCAL_DOMAIN = "example.local";
+    public static final String USER_LOCALHOST = "test_user_smtp@localhost";
+    public static final String USER_LOCAL_DOMAIN = "test_user_smtp@example.local";
+
     final class AlterableDNSServer implements DNSService {
 
         private InetAddress localhostByName = null;
@@ -121,7 +129,7 @@ public class SMTPServerTest {
             }
 
             if ("1.0.0.127.bl.spamcop.net.".equals(host)) {
-                return InetAddress.getByName("localhost");
+                return InetAddress.getByName(Domain.LOCALHOST.asString());
             }
 
             if ("james.apache.org".equals(host)) {
@@ -174,12 +182,14 @@ public class SMTPServerTest {
 
     private static final long HALF_SECOND = 500;
     private static final int MAX_ITERATIONS = 10;
-    private static final DomainList NO_DOMAIN_LIST = null;
+
+
     private static final Logger LOGGER = LoggerFactory.getLogger(SMTPServerTest.class);
 
     protected SMTPTestConfiguration smtpConfiguration;
     protected HashedWheelTimer hashedWheelTimer;
-    protected final MemoryUsersRepository usersRepository = MemoryUsersRepository.withoutVirtualHosting(NO_DOMAIN_LIST);
+    protected MemoryDomainList domainList;
+    protected MemoryUsersRepository usersRepository;
     protected AlterableDNSServer dnsServer;
     protected MemoryMailRepositoryStore mailRepositoryStore;
     protected FileSystemImpl fileSystem;
@@ -187,11 +197,27 @@ public class SMTPServerTest {
     protected MockProtocolHandlerLoader chain;
     protected MemoryMailQueueFactory queueFactory;
     protected MemoryMailQueueFactory.MemoryMailQueue queue;
+    protected MemoryRecipientRewriteTable rewriteTable;
+    protected CanSendFrom canSendFrom;
 
     private SMTPServer smtpServer;
 
     @Before
     public void setUp() throws Exception {
+
+        domainList = new MemoryDomainList(new InMemoryDNSService()
+            .registerMxRecord(Domain.LOCALHOST.asString(), "127.0.0.1")
+            .registerMxRecord(LOCAL_DOMAIN, "127.0.0.1")
+            .registerMxRecord("examplebis.local", "127.0.0.1")
+            .registerMxRecord("127.0.0.1", "127.0.0.1"));
+        domainList.setAutoDetect(false);
+        domainList.setAutoDetectIP(false);
+
+        domainList.addDomain(Domain.LOCALHOST);
+        domainList.addDomain(Domain.of(LOCAL_DOMAIN));
+        domainList.addDomain(Domain.of("examplebis.local"));
+        usersRepository = MemoryUsersRepository.withVirtualHosting(domainList);
+
         createMailRepositoryStore();
 
         setUpFakeLoader();
@@ -248,16 +274,17 @@ public class SMTPServerTest {
 
     protected void setUpFakeLoader() throws Exception {
         dnsServer = new AlterableDNSServer();
-        MemoryRecipientRewriteTable rewriteTable = new MemoryRecipientRewriteTable();
+
+        rewriteTable = new MemoryRecipientRewriteTable();
+        canSendFrom = new CanSendFromImpl(rewriteTable);
         queueFactory = new MemoryMailQueueFactory(new RawMailQueueItemDecoratorFactory());
         queue = queueFactory.createQueue(MailQueueFactory.SPOOL);
-        MemoryDomainList domainList = new MemoryDomainList(mock(DNSService.class));
-        domainList.addDomain(Domain.LOCALHOST);
 
         chain = MockProtocolHandlerLoader.builder()
             .put(binder -> binder.bind(DomainList.class).toInstance(domainList))
             .put(binder -> binder.bind(new TypeLiteral<MailQueueFactory<?>>() {}).toInstance(queueFactory))
             .put(binder -> binder.bind(RecipientRewriteTable.class).toInstance(rewriteTable))
+            .put(binder -> binder.bind(CanSendFrom.class).toInstance(canSendFrom))
             .put(binder -> binder.bind(FileSystem.class).toInstance(fileSystem))
             .put(binder -> binder.bind(MailRepositoryStore.class).toInstance(mailRepositoryStore))
             .put(binder -> binder.bind(DNSService.class).toInstance(dnsServer))
@@ -1266,9 +1293,9 @@ public class SMTPServerTest {
         // assertTrue("anouncing auth required",
         // capabilitieslist.contains("AUTH=LOGIN PLAIN"));
 
-        String userName = "test_user_smtp";
+        String userName = USER_LOCALHOST;
         String noexistUserName = "noexist_test_user_smtp";
-        String sender = "test_user_smtp@localhost";
+        String sender = USER_LOCALHOST;
         smtpProtocol.sendCommand("AUTH FOO", null);
         assertThat(smtpProtocol.getReplyCode())
             .as("expected error: unrecognized authentication type")
@@ -1323,6 +1350,177 @@ public class SMTPServerTest {
     }
 
     @Test
+    public void testAuthSendMail() throws Exception {
+        smtpConfiguration.setAuthorizedAddresses("128.0.0.1/8");
+        smtpConfiguration.setAuthorizingAnnounce();
+        init(smtpConfiguration);
+
+        SMTPClient smtpProtocol = new SMTPClient();
+        InetSocketAddress bindedAddress = new ProtocolServerUtils(smtpServer).retrieveBindedAddress();
+        smtpProtocol.connect(bindedAddress.getAddress().getHostAddress(), bindedAddress.getPort());
+
+        smtpProtocol.sendCommand("ehlo", InetAddress.getLocalHost().toString());
+        String[] capabilityRes = smtpProtocol.getReplyStrings();
+
+        List<String> capabilitieslist = new ArrayList<>();
+        for (int i = 1; i < capabilityRes.length; i++) {
+            capabilitieslist.add(capabilityRes[i].substring(4));
+        }
+
+        String userName = USER_LOCALHOST;
+        String sender = USER_LOCALHOST;
+
+        usersRepository.addUser(Username.of(userName), "pwd");
+
+        smtpProtocol.sendCommand("AUTH PLAIN");
+        smtpProtocol.sendCommand(Base64.getEncoder().encodeToString(("\0" + userName + "\0pwd\0").getBytes(UTF_8)));
+        assertThat(smtpProtocol.getReplyCode())
+            .as("authenticated")
+            .isEqualTo(235);
+
+        smtpProtocol.setSender(sender);
+        smtpProtocol.addRecipient("mail@sample.com");
+        smtpProtocol.sendShortMessageData("Subject: test\r\n\r\nTest body testAuth\r\n");
+
+        smtpProtocol.quit();
+
+        // mail was propagated by SMTPServer
+        assertThat(queue.getLastMail())
+            .as("mail received by mail server")
+            .isNotNull();
+    }
+
+    @Test
+    public void testAuthSendMailFromAlias() throws Exception {
+        smtpConfiguration.setAuthorizedAddresses("128.0.0.1/8");
+        smtpConfiguration.setAuthorizingAnnounce();
+        init(smtpConfiguration);
+
+        SMTPClient smtpProtocol = new SMTPClient();
+        InetSocketAddress bindedAddress = new ProtocolServerUtils(smtpServer).retrieveBindedAddress();
+        smtpProtocol.connect(bindedAddress.getAddress().getHostAddress(), bindedAddress.getPort());
+
+        smtpProtocol.sendCommand("ehlo", InetAddress.getLocalHost().toString());
+        String[] capabilityRes = smtpProtocol.getReplyStrings();
+
+        List<String> capabilitieslist = new ArrayList<>();
+        for (int i = 1; i < capabilityRes.length; i++) {
+            capabilitieslist.add(capabilityRes[i].substring(4));
+        }
+
+        String userName = USER_LOCAL_DOMAIN;
+        String sender = "alias_test_user_smtp@example.local";
+
+        usersRepository.addUser(Username.of(userName), "pwd");
+        rewriteTable.addAliasMapping(MappingSource.fromUser(Username.of(sender)), userName);
+
+        smtpProtocol.sendCommand("AUTH PLAIN");
+        smtpProtocol.sendCommand(Base64.getEncoder().encodeToString(("\0" + userName + "\0pwd\0").getBytes(UTF_8)));
+        assertThat(smtpProtocol.getReplyCode())
+            .as("authenticated")
+            .isEqualTo(235);
+
+        smtpProtocol.setSender(sender);
+        smtpProtocol.addRecipient("mail@sample.com");
+        smtpProtocol.sendShortMessageData("Subject: test\r\n\r\nTest body testAuth\r\n");
+
+        smtpProtocol.quit();
+
+        // mail was propagated by SMTPServer
+        assertThat(queue.getLastMail())
+            .as("mail received by mail server")
+            .isNotNull();
+    }
+
+    @Test
+    public void testAuthSendMailFromDomainAlias() throws Exception {
+        smtpConfiguration.setAuthorizedAddresses("128.0.0.1/8");
+        smtpConfiguration.setAuthorizingAnnounce();
+        init(smtpConfiguration);
+
+        SMTPClient smtpProtocol = new SMTPClient();
+        InetSocketAddress bindedAddress = new ProtocolServerUtils(smtpServer).retrieveBindedAddress();
+        smtpProtocol.connect(bindedAddress.getAddress().getHostAddress(), bindedAddress.getPort());
+
+        smtpProtocol.sendCommand("ehlo", InetAddress.getLocalHost().toString());
+        String[] capabilityRes = smtpProtocol.getReplyStrings();
+
+        List<String> capabilitieslist = new ArrayList<>();
+        for (int i = 1; i < capabilityRes.length; i++) {
+            capabilitieslist.add(capabilityRes[i].substring(4));
+        }
+
+        String userName = USER_LOCAL_DOMAIN;
+        String sender = "test_user_smtp@examplebis.local";
+
+        usersRepository.addUser(Username.of(userName), "pwd");
+        rewriteTable.addAliasDomainMapping(MappingSource.fromDomain(Domain.of("examplebis.local")), Domain.of(LOCAL_DOMAIN));
+
+        smtpProtocol.sendCommand("AUTH PLAIN");
+        smtpProtocol.sendCommand(Base64.getEncoder().encodeToString(("\0" + userName + "\0pwd\0").getBytes(UTF_8)));
+        assertThat(smtpProtocol.getReplyCode())
+            .as("authenticated")
+            .isEqualTo(235);
+
+        smtpProtocol.setSender(sender);
+        smtpProtocol.addRecipient("mail@sample.com");
+        smtpProtocol.sendShortMessageData("Subject: test\r\n\r\nTest body testAuth\r\n");
+
+        smtpProtocol.quit();
+
+        // mail was propagated by SMTPServer
+        assertThat(queue.getLastMail())
+            .as("mail received by mail server")
+            .isNotNull();
+    }
+
+    @Test
+    public void testAuthSendMailFromGroupAlias() throws Exception {
+        smtpConfiguration.setAuthorizedAddresses("128.0.0.1/8");
+        smtpConfiguration.setAuthorizingAnnounce();
+        init(smtpConfiguration);
+
+        SMTPClient smtpProtocol = new SMTPClient();
+        InetSocketAddress bindedAddress = new ProtocolServerUtils(smtpServer).retrieveBindedAddress();
+        smtpProtocol.connect(bindedAddress.getAddress().getHostAddress(), bindedAddress.getPort());
+
+        smtpProtocol.sendCommand("ehlo", InetAddress.getLocalHost().toString());
+        String[] capabilityRes = smtpProtocol.getReplyStrings();
+
+        List<String> capabilitieslist = new ArrayList<>();
+        for (int i = 1; i < capabilityRes.length; i++) {
+            capabilitieslist.add(capabilityRes[i].substring(4));
+        }
+
+        String userName = USER_LOCAL_DOMAIN;
+        String sender = "group@example.local";
+
+        usersRepository.addUser(Username.of(userName), "pwd");
+        rewriteTable.addGroupMapping(MappingSource.fromUser(Username.of(sender)), userName);
+
+        smtpProtocol.sendCommand("AUTH PLAIN");
+        smtpProtocol.sendCommand(Base64.getEncoder().encodeToString(("\0" + userName + "\0pwd\0").getBytes(UTF_8)));
+        assertThat(smtpProtocol.getReplyCode())
+            .as("authenticated")
+            .isEqualTo(235);
+
+        smtpProtocol.setSender(sender);
+        smtpProtocol.addRecipient("mail@sample.com");
+        smtpProtocol.sendShortMessageData("Subject: test\r\n\r\nTest body testAuth\r\n");
+
+        assertThat(smtpProtocol.getReplyCode())
+            .as("expected error")
+            .isEqualTo(503);
+
+        smtpProtocol.quit();
+
+        // mail was not propagated by SMTPServer
+        assertThat(queue.getLastMail())
+            .as("mail received by mail server")
+            .isNull();
+    }
+
+    @Test
     public void testAuthWithEmptySender() throws Exception {
         smtpConfiguration.setAuthorizedAddresses("128.0.0.1/8");
         smtpConfiguration.setAuthorizingAnnounce();
@@ -1334,7 +1532,7 @@ public class SMTPServerTest {
 
         smtpProtocol.sendCommand("ehlo " + InetAddress.getLocalHost());
 
-        String userName = "test_user_smtp";
+        String userName = USER_LOCALHOST;
         usersRepository.addUser(Username.of(userName), "pwd");
 
         smtpProtocol.setSender("");
@@ -1551,8 +1749,8 @@ public class SMTPServerTest {
         // is this required or just for compatibility? assertTrue("anouncing
         // auth required", capabilitieslist.contains("AUTH=LOGIN PLAIN"));
 
-        String userName = "test_user_smtp";
-        String sender = "test_user_smtp@localhost";
+        String userName = USER_LOCALHOST;
+        String sender = USER_LOCALHOST;
 
         smtpProtocol.setSender(sender);
 
@@ -1593,7 +1791,7 @@ public class SMTPServerTest {
 
         smtpProtocol.sendCommand("ehlo", InetAddress.getLocalHost().toString());
 
-        String sender = "test_user_smtp@localhost";
+        String sender = USER_LOCALHOST;
 
         smtpProtocol.setSender(sender);
 


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