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 rc...@apache.org on 2020/02/10 03:54:15 UTC

[james-project] branch master updated (4c3654d -> da7e48a)

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

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


    from 4c3654d  JAMES-3028 rename IOObjectStoreException to ObjectStoreIOException
     new ba68ead  JAMES-1824 Test to prove James SMTP & IMAP can handle UTF-8 mail body
     new 277dd46  JAMES-3034 SMTPMessageSender cannot handle UTF-8 characters in body
     new c171f20  JAMES-3034 Switch to use James SMTPMessageSender
     new c456920  JAMES-3034 Fix IMAPMessageReader to read correctly UTF-8 emails
     new ea6a901  JAMES-3016 Extract MockSMTPServer image name to Images class
     new f7e83f4  JAMES-3016 Extract new DKIMVerifier to be using in integration test
     new 4c25836  JAMES-3016 Broken DKIMSign + RemoteDelivery integration tests
     new 6d2e138  JAMES-3016 Drop allow8bitmime option in remote delivery
     new da7e48a  JAMES-3016 Use Junit5 in integration tests

The 9 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.


Summary of changes:
 CHANGELOG.md                                       |   6 +-
 pom.xml                                            |   5 +
 .../apache/james/MailsShouldBeWellReceived.java    |  61 +++++
 .../eml/mail-containing-unicode-characters.eml     |   3 +-
 .../apache/james/jdkim/mailets/DKIMVerifier.java   |  74 ++++++
 .../org/apache/james/jdkim/mailets/DKIMVerify.java |  38 +--
 .../apache/james/jdkim/mailets/DKIMSignTest.java   |   8 +-
 .../mailets/RemoteDeliveryDKIMIntegrationTest.java | 279 +++++++++++++++++++++
 .../james/mailets/RemoteDeliveryErrorTest.java     |   5 +-
 .../test/resources/eml/message-multipart-7bit.eml  |   2 +-
 .../test/resources/eml/message-multipart-8bit.eml  |   0
 .../test/resources/eml/message-text-only-7bit.eml  |   2 +-
 .../test/resources/eml/message-text-only-8bit.eml  |   3 +-
 .../delivery/RemoteDeliveryConfiguration.java      |   3 -
 .../delivery/RemoteDeliveryConfigurationTest.java  |   3 -
 server/mailet/mock-smtp-server/pom.xml             |   3 -
 .../server/testing/MockSmtpServerExtension.java    |  82 +++---
 .../test/resources/cucumber/GetMessages.feature    |   2 +-
 server/testing/pom.xml                             |   5 +
 .../java/org/apache/james/util/docker/Images.java  |   1 +
 .../org/apache/james/utils/IMAPMessageReader.java  |  22 +-
 .../org/apache/james/utils/SMTPMessageSender.java  |  13 +-
 .../james/utils/SMTPMessageSenderExtension.java}   |  27 +-
 .../apache/james/utils/IMAPMessageReaderTest.java  |  18 +-
 .../apache/james/utils/SMTPMessageSenderTest.java  |  94 +++++++
 25 files changed, 624 insertions(+), 135 deletions(-)
 copy mailet/base/src/test/resources/eml/text-only-8bit.eml => server/container/guice/guice-common/src/test/resources/eml/mail-containing-unicode-characters.eml (94%)
 create mode 100644 server/mailet/dkim/src/main/java/org/apache/james/jdkim/mailets/DKIMVerifier.java
 create mode 100644 server/mailet/integration-testing/src/test/java/org/apache/james/mailets/RemoteDeliveryDKIMIntegrationTest.java
 copy mailet/base/src/test/resources/eml/multipart-7bit.eml => server/mailet/integration-testing/src/test/resources/eml/message-multipart-7bit.eml (97%)
 copy mailet/base/src/test/resources/eml/multipart-8bit.eml => server/mailet/integration-testing/src/test/resources/eml/message-multipart-8bit.eml (100%)
 copy mailet/base/src/test/resources/eml/text-only-7bit.eml => server/mailet/integration-testing/src/test/resources/eml/message-text-only-7bit.eml (93%)
 copy mailet/base/src/test/resources/eml/text-only-8bit.eml => server/mailet/integration-testing/src/test/resources/eml/message-text-only-8bit.eml (94%)
 copy backends-common/elasticsearch/src/test/java/org/apache/james/backends/es/ElasticSearchClusterExtension.java => server/mailet/mock-smtp-server/src/main/java/org/apache/james/mock/smtp/server/testing/MockSmtpServerExtension.java (56%)
 copy server/{task/task-memory/src/test/java/org/apache/james/task/CountDownLatchExtension.java => testing/src/main/java/org/apache/james/utils/SMTPMessageSenderExtension.java} (71%)
 create mode 100644 server/testing/src/test/java/org/apache/james/utils/SMTPMessageSenderTest.java


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


[james-project] 07/09: JAMES-3016 Broken DKIMSign + RemoteDelivery integration tests

Posted by rc...@apache.org.
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

commit 4c25836aa75d4b38f8df53bd736132bf82bff241
Author: Tran Tien Duc <dt...@linagora.com>
AuthorDate: Wed Jan 22 13:37:43 2020 +0700

    JAMES-3016 Broken DKIMSign + RemoteDelivery integration tests
---
 .../mailets/RemoteDeliveryDKIMIntegrationTest.java | 438 +++++++++++++++++++++
 .../test/resources/eml/message-multipart-7bit.eml  | 142 +++++++
 .../test/resources/eml/message-multipart-8bit.eml  | 128 ++++++
 .../test/resources/eml/message-text-only-7bit.eml  |  27 ++
 .../test/resources/eml/message-text-only-8bit.eml  |  28 ++
 5 files changed, 763 insertions(+)

diff --git a/server/mailet/integration-testing/src/test/java/org/apache/james/mailets/RemoteDeliveryDKIMIntegrationTest.java b/server/mailet/integration-testing/src/test/java/org/apache/james/mailets/RemoteDeliveryDKIMIntegrationTest.java
new file mode 100644
index 0000000..3a991b0
--- /dev/null
+++ b/server/mailet/integration-testing/src/test/java/org/apache/james/mailets/RemoteDeliveryDKIMIntegrationTest.java
@@ -0,0 +1,438 @@
+/****************************************************************
+ * 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.MemoryJamesServerMain.SMTP_ONLY_MODULE;
+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.awaitAtMostOneMinute;
+import static org.apache.james.util.docker.Images.MOCK_SMTP_SERVER;
+import static org.assertj.core.api.Assertions.assertThat;
+
+import java.util.Optional;
+
+import javax.mail.MessagingException;
+import javax.mail.internet.MimeMessage;
+
+import org.apache.james.core.MailAddress;
+import org.apache.james.dnsservice.api.DNSService;
+import org.apache.james.dnsservice.api.InMemoryDNSService;
+import org.apache.james.jdkim.api.PublicKeyRecordRetriever;
+import org.apache.james.jdkim.mailets.ConvertTo7Bit;
+import org.apache.james.jdkim.mailets.DKIMSign;
+import org.apache.james.jdkim.mailets.DKIMVerifier;
+import org.apache.james.jdkim.mailets.MockPublicKeyRecordRetriever;
+import org.apache.james.mailets.configuration.CommonProcessors;
+import org.apache.james.mailets.configuration.MailetConfiguration;
+import org.apache.james.mailets.configuration.ProcessorConfiguration;
+import org.apache.james.mock.smtp.server.ConfigurationClient;
+import org.apache.james.mock.smtp.server.model.Mail;
+import org.apache.james.modules.protocols.SmtpGuiceProbe;
+import org.apache.james.probe.DataProbe;
+import org.apache.james.transport.matchers.All;
+import org.apache.james.util.Host;
+import org.apache.james.util.MimeMessageUtil;
+import org.apache.james.util.docker.DockerContainer;
+import org.apache.james.utils.DataProbeImpl;
+import org.apache.james.utils.IMAPMessageReader;
+import org.apache.james.utils.SMTPMessageSender;
+import org.apache.mailet.base.test.FakeMail;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.ClassRule;
+import org.junit.Ignore;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.TemporaryFolder;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class RemoteDeliveryDKIMIntegrationTest {
+
+    private static final Logger LOGGER = LoggerFactory.getLogger(RemoteDeliveryDKIMIntegrationTest.class);
+
+    private static final String JAMES_ANOTHER_DOMAIN = "james.com";
+    private static final String FROM = "from@" + DEFAULT_DOMAIN;
+    private static final String RECIPIENT = "touser@" + JAMES_ANOTHER_DOMAIN;
+
+    private static final String TESTING_PEM = "-----BEGIN RSA PRIVATE KEY-----\r\n" +
+        "MIICXAIBAAKBgQDYDaYKXzwVYwqWbLhmuJ66aTAN8wmDR+rfHE8HfnkSOax0oIoT\r\n" +
+        "M5zquZrTLo30870YMfYzxwfB6j/Nz3QdwrUD/t0YMYJiUKyWJnCKfZXHJBJ+yfRH\r\n" +
+        "r7oW+UW3cVo9CG2bBfIxsInwYe175g9UjyntJpWueqdEIo1c2bhv9Mp66QIDAQAB\r\n" +
+        "AoGBAI8XcwnZi0Sq5N89wF+gFNhnREFo3rsJDaCY8iqHdA5DDlnr3abb/yhipw0I\r\n" +
+        "/1HlgC6fIG2oexXOXFWl+USgqRt1kTt9jXhVFExg8mNko2UelAwFtsl8CRjVcYQO\r\n" +
+        "cedeH/WM/mXjg2wUqqZenBmlKlD6vNb70jFJeVaDJ/7n7j8BAkEA9NkH2D4Zgj/I\r\n" +
+        "OAVYccZYH74+VgO0e7VkUjQk9wtJ2j6cGqJ6Pfj0roVIMUWzoBb8YfErR8l6JnVQ\r\n" +
+        "bfy83gJeiQJBAOHk3ow7JjAn8XuOyZx24KcTaYWKUkAQfRWYDFFOYQF4KV9xLSEt\r\n" +
+        "ycY0kjsdxGKDudWcsATllFzXDCQF6DTNIWECQEA52ePwTjKrVnLTfCLEG4OgHKvl\r\n" +
+        "Zud4amthwDyJWoMEH2ChNB2je1N4JLrABOE+hk+OuoKnKAKEjWd8f3Jg/rkCQHj8\r\n" +
+        "mQmogHqYWikgP/FSZl518jV48Tao3iXbqvU9Mo2T6yzYNCCqIoDLFWseNVnCTZ0Q\r\n" +
+        "b+IfiEf1UeZVV5o4J+ECQDatNnS3V9qYUKjj/krNRD/U0+7eh8S2ylLqD3RlSn9K\r\n" +
+        "tYGRMgAtUXtiOEizBH6bd/orzI9V9sw8yBz+ZqIH25Q=\r\n" +
+        "-----END RSA PRIVATE KEY-----\r\n";
+    private static final MailetConfiguration DKIMSIGN_MAILET = MailetConfiguration.builder()
+        .matcher(All.class)
+        .mailet(DKIMSign.class)
+        .addProperty(
+            "signatureTemplate",
+            "v=1; s=selector; d=example.com; h=from:to:received:received; a=rsa-sha256; bh=; b=;")
+        .addProperty("privateKey", TESTING_PEM)
+        .build();
+    private static final MailetConfiguration CONVERT_TO_7BIT_MAILET = MailetConfiguration.builder()
+        .matcher(All.class)
+        .mailet(ConvertTo7Bit.class)
+        .build();
+    private static final PublicKeyRecordRetriever MOCK_PUBLIC_KEY_RECORD_RETRIEVER = new MockPublicKeyRecordRetriever(
+        "v=DKIM1; k=rsa; p=MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDYDaYKXzwVYwqWbLhmuJ66aTAN8wmDR+rfHE8HfnkSOax0oIoTM5zquZrTLo30870YMfYzxwfB6j/Nz3QdwrUD/t0YMYJiUKyWJnCKfZXHJBJ+yfRHr7oW+UW3cVo9CG2bBfIxsInwYe175g9UjyntJpWueqdEIo1c2bhv9Mp66QIDAQAB;",
+        "selector", "example.com");
+
+    @ClassRule
+    public static DockerContainer mockSmtp = DockerContainer.fromName(MOCK_SMTP_SERVER)
+        .withLogConsumer(outputFrame -> LOGGER.debug("MockSMTP: " + outputFrame.getUtf8String()));
+    @Rule
+    public TemporaryFolder temporaryFolder = new TemporaryFolder();
+    @Rule
+    public IMAPMessageReader imapMessageReader = new IMAPMessageReader();
+    @Rule
+    public SMTPMessageSender messageSender = new SMTPMessageSender(DEFAULT_DOMAIN);
+
+    private TemporaryJamesServer jamesServer;
+    private ConfigurationClient mockSMTPConfiguration;
+    private DataProbe dataProbe;
+    private DKIMVerifier dkimVerifier;
+
+    @Before
+    public void setUp() {
+        mockSMTPConfiguration = configurationClient(mockSmtp);
+        dkimVerifier = new DKIMVerifier(MOCK_PUBLIC_KEY_RECORD_RETRIEVER);
+    }
+
+    @After
+    public void tearDown() {
+        mockSMTPConfiguration.cleanServer();
+        if (jamesServer != null) {
+            jamesServer.shutdown();
+        }
+    }
+
+    @Ignore("assertion failed:" +
+        "org.apache.james.jdkim.exceptions.PermFailException: Computed bodyhash is different from the expected one")
+    @Test
+    public void remoteDeliveryShouldNotBreakDKIMSignWhen7BitMessageAndAllowing8BitMime() throws Exception {
+        InMemoryDNSService inMemoryDNSService = new InMemoryDNSService()
+            .registerMxRecord(JAMES_ANOTHER_DOMAIN, mockSmtp.getContainerIp());
+
+        jamesServer = TemporaryJamesServer.builder()
+            .withBase(SMTP_ONLY_MODULE)
+            .withOverrides(binder -> binder.bind(DNSService.class).toInstance(inMemoryDNSService))
+            .withMailetContainer(TemporaryJamesServer.SIMPLE_MAILET_CONTAINER_CONFIGURATION
+                .putProcessor(directResolutionTransport(MailetConfiguration.remoteDeliveryBuilder()))
+                .putProcessor(CommonProcessors.bounces()))
+            .build(temporaryFolder.newFolder());
+
+        dataProbe = jamesServer.getProbe(DataProbeImpl.class);
+        dataProbe.addDomain(DEFAULT_DOMAIN);
+        dataProbe.addUser(FROM, PASSWORD);
+
+        FakeMail mail = FakeMail.builder()
+            .name("a-mail-with-7bit-encoding")
+            .sender(new MailAddress(FROM))
+            .recipient(new MailAddress(RECIPIENT))
+            .mimeMessage(MimeMessageUtil.mimeMessageFromStream(
+                ClassLoader.getSystemResourceAsStream(("eml/message-text-only-7bit.eml"))))
+            .build();
+        messageSender.connect(LOCALHOST_IP, jamesServer.getProbe(SmtpGuiceProbe.class).getSmtpPort())
+            .sendMessage(mail);
+
+        MimeMessage sendMessage = toMimeMessage(getFirstRecivedMail());
+
+        assertThat(dkimVerifier.verifyUsingCRLF(sendMessage))
+            .isNotEmpty();
+    }
+
+    @Test
+    public void remoteDeliveryShouldNotBreakDKIMSignWhen7BitAndBase64MessageAndAllowing8BitMime() throws Exception {
+        InMemoryDNSService inMemoryDNSService = new InMemoryDNSService()
+            .registerMxRecord(JAMES_ANOTHER_DOMAIN, mockSmtp.getContainerIp());
+
+        jamesServer = TemporaryJamesServer.builder()
+            .withBase(SMTP_ONLY_MODULE)
+            .withOverrides(binder -> binder.bind(DNSService.class).toInstance(inMemoryDNSService))
+            .withMailetContainer(TemporaryJamesServer.SIMPLE_MAILET_CONTAINER_CONFIGURATION
+                .putProcessor(directResolutionTransport(MailetConfiguration.remoteDeliveryBuilder()))
+                .putProcessor(CommonProcessors.bounces()))
+            .build(temporaryFolder.newFolder());
+
+        dataProbe = jamesServer.getProbe(DataProbeImpl.class);
+        dataProbe.addDomain(DEFAULT_DOMAIN);
+        dataProbe.addUser(FROM, PASSWORD);
+
+        FakeMail mail = FakeMail.builder()
+            .name("a-mail-with-7bit-base64-encoding")
+            .sender(new MailAddress(FROM))
+            .recipient(new MailAddress(RECIPIENT))
+            .mimeMessage(MimeMessageUtil.mimeMessageFromStream(
+                ClassLoader.getSystemResourceAsStream(("eml/message-multipart-7bit.eml"))))
+            .build();
+        messageSender.connect(LOCALHOST_IP, jamesServer.getProbe(SmtpGuiceProbe.class).getSmtpPort())
+            .sendMessage(mail);
+
+        MimeMessage sendMessage = toMimeMessage(getFirstRecivedMail());
+
+        assertThat(dkimVerifier.verifyUsingCRLF(sendMessage))
+            .isNotEmpty();
+    }
+
+    @Test
+    public void remoteDeliveryShouldNotBreakDKIMSignWhen7BitMessageAndDisable8BitMime() throws Exception {
+        InMemoryDNSService inMemoryDNSService = new InMemoryDNSService()
+            .registerMxRecord(JAMES_ANOTHER_DOMAIN, mockSmtp.getContainerIp());
+
+        jamesServer = TemporaryJamesServer.builder()
+            .withBase(SMTP_ONLY_MODULE)
+            .withOverrides(binder -> binder.bind(DNSService.class).toInstance(inMemoryDNSService))
+            .withMailetContainer(TemporaryJamesServer.SIMPLE_MAILET_CONTAINER_CONFIGURATION
+                .putProcessor(directResolutionTransport(MailetConfiguration.remoteDeliveryBuilder()
+                    .addProperty("mail.smtp.allow8bitmime", "false")))
+                .putProcessor(CommonProcessors.bounces()))
+            .build(temporaryFolder.newFolder());
+
+        dataProbe = jamesServer.getProbe(DataProbeImpl.class);
+        dataProbe.addDomain(DEFAULT_DOMAIN);
+        dataProbe.addUser(FROM, PASSWORD);
+
+        FakeMail mail = FakeMail.builder()
+            .name("a-mail-with-7bit-encoding")
+            .sender(new MailAddress(FROM))
+            .recipient(new MailAddress(RECIPIENT))
+            .mimeMessage(MimeMessageUtil.mimeMessageFromStream(
+                ClassLoader.getSystemResourceAsStream(("eml/message-text-only-7bit.eml"))))
+            .build();
+        messageSender.connect(LOCALHOST_IP, jamesServer.getProbe(SmtpGuiceProbe.class).getSmtpPort())
+            .sendMessage(mail);
+
+        MimeMessage sendMessage = toMimeMessage(getFirstRecivedMail());
+
+        assertThat(dkimVerifier.verifyUsingCRLF(sendMessage))
+            .isNotEmpty();
+    }
+
+    @Test
+    public void remoteDeliveryShouldNotBreakDKIMSignWhen7BitAndBase64MessageAndDisable8BitMime() throws Exception {
+        InMemoryDNSService inMemoryDNSService = new InMemoryDNSService()
+            .registerMxRecord(JAMES_ANOTHER_DOMAIN, mockSmtp.getContainerIp());
+
+        jamesServer = TemporaryJamesServer.builder()
+            .withBase(SMTP_ONLY_MODULE)
+            .withOverrides(binder -> binder.bind(DNSService.class).toInstance(inMemoryDNSService))
+            .withMailetContainer(TemporaryJamesServer.SIMPLE_MAILET_CONTAINER_CONFIGURATION
+                .putProcessor(directResolutionTransport(MailetConfiguration.remoteDeliveryBuilder()
+                    .addProperty("mail.smtp.allow8bitmime", "false")))
+                .putProcessor(CommonProcessors.bounces()))
+            .build(temporaryFolder.newFolder());
+
+        dataProbe = jamesServer.getProbe(DataProbeImpl.class);
+        dataProbe.addDomain(DEFAULT_DOMAIN);
+        dataProbe.addUser(FROM, PASSWORD);
+
+        FakeMail mail = FakeMail.builder()
+            .name("a-mail-with-7bit-base64-encoding")
+            .sender(new MailAddress(FROM))
+            .recipient(new MailAddress(RECIPIENT))
+            .mimeMessage(MimeMessageUtil.mimeMessageFromStream(
+                ClassLoader.getSystemResourceAsStream(("eml/message-multipart-7bit.eml"))))
+            .build();
+        messageSender.connect(LOCALHOST_IP, jamesServer.getProbe(SmtpGuiceProbe.class).getSmtpPort())
+            .sendMessage(mail);
+
+        MimeMessage sendMessage = toMimeMessage(getFirstRecivedMail());
+
+        assertThat(dkimVerifier.verifyUsingCRLF(sendMessage))
+            .isNotEmpty();
+    }
+
+    @Ignore("assertion failed:" +
+        "org.apache.james.jdkim.exceptions.PermFailException: Computed bodyhash is different from the expected one")
+    @Test
+    public void remoteDeliveryShouldNotBreakDKIMSignWhen8BitMessageAndAllowing8BitMime() throws Exception {
+        InMemoryDNSService inMemoryDNSService = new InMemoryDNSService()
+            .registerMxRecord(JAMES_ANOTHER_DOMAIN, mockSmtp.getContainerIp());
+
+        jamesServer = TemporaryJamesServer.builder()
+            .withBase(SMTP_ONLY_MODULE)
+            .withOverrides(binder -> binder.bind(DNSService.class).toInstance(inMemoryDNSService))
+            .withMailetContainer(TemporaryJamesServer.SIMPLE_MAILET_CONTAINER_CONFIGURATION
+                .putProcessor(directResolutionTransport(MailetConfiguration.remoteDeliveryBuilder()))
+                .putProcessor(CommonProcessors.bounces()))
+            .build(temporaryFolder.newFolder());
+
+        dataProbe = jamesServer.getProbe(DataProbeImpl.class);
+        dataProbe.addDomain(DEFAULT_DOMAIN);
+        dataProbe.addUser(FROM, PASSWORD);
+
+        FakeMail mail = FakeMail.builder()
+            .name("a-mail-with-8bit-encoding")
+            .sender(new MailAddress(FROM))
+            .recipient(new MailAddress(RECIPIENT))
+            .mimeMessage(MimeMessageUtil.mimeMessageFromStream(
+                ClassLoader.getSystemResourceAsStream(("eml/message-text-only-7bit.eml"))))
+            .build();
+        messageSender.connect(LOCALHOST_IP, jamesServer.getProbe(SmtpGuiceProbe.class).getSmtpPort())
+            .sendMessage(mail);
+
+        MimeMessage sendMessage = toMimeMessage(getFirstRecivedMail());
+
+        assertThat(dkimVerifier.verifyUsingCRLF(sendMessage))
+            .isNotEmpty();
+    }
+
+    @Test
+    public void remoteDeliveryShouldNotBreakDKIMSignWhen8BitAndBase64MessageAndAllowing8BitMime() throws Exception {
+        InMemoryDNSService inMemoryDNSService = new InMemoryDNSService()
+            .registerMxRecord(JAMES_ANOTHER_DOMAIN, mockSmtp.getContainerIp());
+
+        jamesServer = TemporaryJamesServer.builder()
+            .withBase(SMTP_ONLY_MODULE)
+            .withOverrides(binder -> binder.bind(DNSService.class).toInstance(inMemoryDNSService))
+            .withMailetContainer(TemporaryJamesServer.SIMPLE_MAILET_CONTAINER_CONFIGURATION
+                .putProcessor(directResolutionTransport(MailetConfiguration.remoteDeliveryBuilder()))
+                .putProcessor(CommonProcessors.bounces()))
+            .build(temporaryFolder.newFolder());
+
+        dataProbe = jamesServer.getProbe(DataProbeImpl.class);
+        dataProbe.addDomain(DEFAULT_DOMAIN);
+        dataProbe.addUser(FROM, PASSWORD);
+
+        FakeMail mail = FakeMail.builder()
+            .name("a-mail-with-8bit-base64-encoding")
+            .sender(new MailAddress(FROM))
+            .recipient(new MailAddress(RECIPIENT))
+            .mimeMessage(MimeMessageUtil.mimeMessageFromStream(
+                ClassLoader.getSystemResourceAsStream(("eml/message-multipart-8bit.eml"))))
+            .build();
+        messageSender.connect(LOCALHOST_IP, jamesServer.getProbe(SmtpGuiceProbe.class).getSmtpPort())
+            .sendMessage(mail);
+
+        MimeMessage sendMessage = toMimeMessage(getFirstRecivedMail());
+
+        assertThat(dkimVerifier.verifyUsingCRLF(sendMessage))
+            .isNotEmpty();
+    }
+
+    @Test
+    public void remoteDeliveryShouldNotBreakDKIMSignWhen8BitMessageAndDisable8BitMime() throws Exception {
+        InMemoryDNSService inMemoryDNSService = new InMemoryDNSService()
+            .registerMxRecord(JAMES_ANOTHER_DOMAIN, mockSmtp.getContainerIp());
+
+        jamesServer = TemporaryJamesServer.builder()
+            .withBase(SMTP_ONLY_MODULE)
+            .withOverrides(binder -> binder.bind(DNSService.class).toInstance(inMemoryDNSService))
+            .withMailetContainer(TemporaryJamesServer.SIMPLE_MAILET_CONTAINER_CONFIGURATION
+                .putProcessor(directResolutionTransport(MailetConfiguration.remoteDeliveryBuilder()
+                    .addProperty("mail.smtp.allow8bitmime", "false")))
+                .putProcessor(CommonProcessors.bounces()))
+            .build(temporaryFolder.newFolder());
+
+        dataProbe = jamesServer.getProbe(DataProbeImpl.class);
+        dataProbe.addDomain(DEFAULT_DOMAIN);
+        dataProbe.addUser(FROM, PASSWORD);
+
+        FakeMail mail = FakeMail.builder()
+            .name("a-mail-with-8bit-encoding")
+            .sender(new MailAddress(FROM))
+            .recipient(new MailAddress(RECIPIENT))
+            .mimeMessage(MimeMessageUtil.mimeMessageFromStream(
+                ClassLoader.getSystemResourceAsStream(("eml/message-text-only-8bit.eml"))))
+            .build();
+        messageSender.connect(LOCALHOST_IP, jamesServer.getProbe(SmtpGuiceProbe.class).getSmtpPort())
+            .sendMessage(mail);
+
+        MimeMessage sendMessage = toMimeMessage(getFirstRecivedMail());
+
+        assertThat(dkimVerifier.verifyUsingCRLF(sendMessage))
+            .isNotEmpty();
+    }
+
+    @Test
+    public void remoteDeliveryShouldNotBreakDKIMSignWhen8BitAndBase64MessageAndDisable8BitMime() throws Exception {
+        InMemoryDNSService inMemoryDNSService = new InMemoryDNSService()
+            .registerMxRecord(JAMES_ANOTHER_DOMAIN, mockSmtp.getContainerIp());
+
+        jamesServer = TemporaryJamesServer.builder()
+            .withBase(SMTP_ONLY_MODULE)
+            .withOverrides(binder -> binder.bind(DNSService.class).toInstance(inMemoryDNSService))
+            .withMailetContainer(TemporaryJamesServer.SIMPLE_MAILET_CONTAINER_CONFIGURATION
+                .putProcessor(directResolutionTransport(MailetConfiguration.remoteDeliveryBuilder()
+                    .addProperty("mail.smtp.allow8bitmime", "false")))
+                .putProcessor(CommonProcessors.bounces()))
+            .build(temporaryFolder.newFolder());
+
+        dataProbe = jamesServer.getProbe(DataProbeImpl.class);
+        dataProbe.addDomain(DEFAULT_DOMAIN);
+        dataProbe.addUser(FROM, PASSWORD);
+
+        FakeMail mail = FakeMail.builder()
+            .name("a-mail-with-8bit-base64-encoding")
+            .sender(new MailAddress(FROM))
+            .recipient(new MailAddress(RECIPIENT))
+            .mimeMessage(MimeMessageUtil.mimeMessageFromStream(
+                ClassLoader.getSystemResourceAsStream(("eml/message-multipart-8bit.eml"))))
+            .build();
+        messageSender.connect(LOCALHOST_IP, jamesServer.getProbe(SmtpGuiceProbe.class).getSmtpPort())
+            .sendMessage(mail);
+
+        MimeMessage sendMessage = toMimeMessage(getFirstRecivedMail());
+
+        assertThat(dkimVerifier.verifyUsingCRLF(sendMessage))
+            .isNotEmpty();
+    }
+
+    private MimeMessage toMimeMessage(Mail mail) {
+        try {
+            return MimeMessageUtil.mimeMessageFromString(mail.getMessage());
+        } catch (MessagingException e) {
+            throw new RuntimeException(e);
+        }
+    }
+
+    private Mail getFirstRecivedMail() {
+        return awaitAtMostOneMinute
+            .until(() -> mockSMTPConfiguration.listMails()
+                .stream()
+                .findFirst(), Optional::isPresent)
+            .get();
+    }
+
+    private ProcessorConfiguration.Builder directResolutionTransport(MailetConfiguration.Builder remoteDeliveryConfiguration) {
+        return ProcessorConfiguration.transport()
+            .addMailet(MailetConfiguration.BCC_STRIPPER)
+            .addMailet(CONVERT_TO_7BIT_MAILET)
+            .addMailet(DKIMSIGN_MAILET)
+            .addMailet(remoteDeliveryConfiguration
+                .matcher(All.class));
+    }
+
+    private ConfigurationClient configurationClient(DockerContainer mockSmtp) {
+        return ConfigurationClient.from(
+            Host.from(mockSmtp.getHostIp(),
+                mockSmtp.getMappedPort(8000)));
+    }
+}
diff --git a/server/mailet/integration-testing/src/test/resources/eml/message-multipart-7bit.eml b/server/mailet/integration-testing/src/test/resources/eml/message-multipart-7bit.eml
new file mode 100644
index 0000000..ca97347
--- /dev/null
+++ b/server/mailet/integration-testing/src/test/resources/eml/message-multipart-7bit.eml
@@ -0,0 +1,142 @@
+Return-Path: <bo...@james.org>
+MIME-Version: 1.0
+Delivered-To: bob@james.org
+Received: from 10.233.68.83 (EHLO incoming.james.org) ([10.233.68.83])
+          by james-0 (JAMES SMTP Server ) with ESMTP ID -973333758
+          for <bo...@james.james.org>;
+          Wed, 22 Jan 2020 03:47:32 +0000 (UTC)
+Received: from smtp.james.org (unknown [10.233.65.0])
+	by incoming.james.org (Postfix) with ESMTPS id 8151D43
+	for <bo...@james.james.org>; Wed, 22 Jan 2020 03:47:32 +0000 (UTC)
+Received: from [10.116.29.102] (unknown [1.54.162.156])
+	(using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits))
+	(No client certificate requested)
+	by smtp.james.org (Postfix) with ESMTPSA id D6C653F38C
+	for <bo...@james.org>; Wed, 22 Jan 2020 04:47:31 +0100 (CET)
+To: bob@james.org
+X-LINAGORA-Copy-Delivery-Done: 1
+From: Uncle Bob <bo...@james.org>
+Subject: multipart
+Message-ID: <69...@james.org>
+Date: Wed, 22 Jan 2020 10:47:17 +0700
+User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:60.0) Gecko/20100101
+ Thunderbird/60.2.1
+Content-Type: multipart/mixed;
+ boundary="------------C3FD44EAF9B6A93E163D9176"
+Content-Language: en-US
+
+This is a multi-part message in MIME format.
+--------------C3FD44EAF9B6A93E163D9176
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: quoted-printable
+
+A quoted-printable encoded body with =E2=82=ACuro symbol.
+
+
+
+--------------C3FD44EAF9B6A93E163D9176
+Content-Type: image/png;
+ name="james-logo.png"
+Content-Transfer-Encoding: base64
+Content-Disposition: attachment;
+ filename="james-logo.png"
+
+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
+RK5CYII=
+--------------C3FD44EAF9B6A93E163D9176--
diff --git a/server/mailet/integration-testing/src/test/resources/eml/message-multipart-8bit.eml b/server/mailet/integration-testing/src/test/resources/eml/message-multipart-8bit.eml
new file mode 100644
index 0000000..3c8c8f4
--- /dev/null
+++ b/server/mailet/integration-testing/src/test/resources/eml/message-multipart-8bit.eml
@@ -0,0 +1,128 @@
+Return-Path: <bo...@james.org>
+MIME-Version: 1.0
+Delivered-To: bob@james.org
+Received: from 10.233.68.83 (EHLO incoming.james.org) ([10.233.68.83])
+          by james-0 (JAMES SMTP Server ) with ESMTP ID 926590876
+          for <bo...@james.james.org>;
+          Tue, 21 Jan 2020 07:12:56 +0000 (UTC)
+Received: from smtp.james.org (unknown [10.233.68.1])
+	by incoming.james.org (Postfix) with ESMTPS id B39A643
+	for <bo...@james.james.org>; Tue, 21 Jan 2020 07:12:56 +0000 (UTC)
+Received: from duc-HP-ProBook-450-G4 (unknown [1.54.162.156])
+	(using TLSv1.2 with cipher ECDHE-RSA-AES256-SHA384 (256/256 bits))
+	(No client certificate requested)
+	by smtp.james.org (Postfix) with ESMTPSA id F11B13F386
+	for <bo...@james.org>; Tue, 21 Jan 2020 08:12:55 +0100 (CET)
+Date: Tue, 21 Jan 2020 14:12:39 +0700 (ICT)
+X-LINAGORA-Copy-Delivery-Done: 1
+From: bob@james.org
+To: bob@james.org
+Message-ID: <42...@duc-HP-ProBook-450-G4>
+Subject: UTF-8 8bit multipart
+Content-Type: multipart/mixed; 
+	boundary="----=_Part_0_238762799.1579590759052"
+
+------=_Part_0_238762799.1579590759052
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+A 8bit encoded body with €uro symbol.
+------=_Part_0_238762799.1579590759052
+Content-Type: application/octet-stream; name=james-logo.png
+Content-Transfer-Encoding: base64
+Content-Disposition: attachment; filename=james-logo.png
+
+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
+
+------=_Part_0_238762799.1579590759052--
diff --git a/server/mailet/integration-testing/src/test/resources/eml/message-text-only-7bit.eml b/server/mailet/integration-testing/src/test/resources/eml/message-text-only-7bit.eml
new file mode 100644
index 0000000..7e010ba
--- /dev/null
+++ b/server/mailet/integration-testing/src/test/resources/eml/message-text-only-7bit.eml
@@ -0,0 +1,27 @@
+Return-Path: <bo...@james.org>
+MIME-Version: 1.0
+Delivered-To: bob@james.org
+Received: from 10.233.68.83 (EHLO incoming.james.org) ([10.233.68.83])
+          by james-0 (JAMES SMTP Server ) with ESMTP ID -1705393842
+          for <bo...@james.james.org>;
+          Wed, 22 Jan 2020 04:11:54 +0000 (UTC)
+Received: from smtp.james.org (unknown [10.233.65.0])
+	by incoming.james.org (Postfix) with ESMTPS id CCCA943
+	for <bo...@james.james.org>; Wed, 22 Jan 2020 04:11:54 +0000 (UTC)
+Received: from [10.116.29.102] (unknown [1.54.162.156])
+	(using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits))
+	(No client certificate requested)
+	by smtp.james.org (Postfix) with ESMTPSA id 2B7D13F393
+	for <bo...@james.org>; Wed, 22 Jan 2020 05:11:53 +0100 (CET)
+To: bob@james.org
+X-LINAGORA-Copy-Delivery-Done: 1
+From: Uncle Bob <bo...@james.org>
+Subject: quoted
+Message-ID: <f4...@james.org>
+Date: Wed, 22 Jan 2020 11:11:38 +0700
+User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:60.0) Gecko/20100101
+ Thunderbird/60.2.1
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: quoted-printable
+
+A quoted-printable encoded body with =E2=82=ACuro symbol.
\ No newline at end of file
diff --git a/server/mailet/integration-testing/src/test/resources/eml/message-text-only-8bit.eml b/server/mailet/integration-testing/src/test/resources/eml/message-text-only-8bit.eml
new file mode 100644
index 0000000..96ed638
--- /dev/null
+++ b/server/mailet/integration-testing/src/test/resources/eml/message-text-only-8bit.eml
@@ -0,0 +1,28 @@
+Return-Path: <bo...@james.org>
+MIME-Version: 1.0
+Delivered-To: bob@james.org
+Received: from 10.233.68.83 (EHLO incoming.james.org) ([10.233.68.83])
+          by james-0 (JAMES SMTP Server ) with ESMTP ID -1705393842
+          for <bo...@james.james.org>;
+          Wed, 22 Jan 2020 04:11:54 +0000 (UTC)
+Received: from smtp.james.org (unknown [10.233.65.0])
+	by incoming.james.org (Postfix) with ESMTPS id CCCA943
+	for <bo...@james.james.org>; Wed, 22 Jan 2020 04:11:54 +0000 (UTC)
+Received: from [10.116.29.102] (unknown [1.54.162.156])
+	(using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits))
+	(No client certificate requested)
+	by smtp.james.org (Postfix) with ESMTPSA id 2B7D13F393
+	for <bo...@james.org>; Wed, 22 Jan 2020 05:11:53 +0100 (CET)
+To: bob@james.org
+X-LINAGORA-Copy-Delivery-Done: 1
+From: Uncle Bob <bo...@james.org>
+Subject: quoted
+Message-ID: <f4...@james.org>
+Date: Wed, 22 Jan 2020 11:11:38 +0700
+User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:60.0) Gecko/20100101
+ Thunderbird/60.2.1
+Content-Type: text/plain; charset=utf-8; format=flowed
+Content-Transfer-Encoding: 8bit
+Content-Language: en-US
+
+A 8bit encoded body with €uro symbol.
\ No newline at end of file


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


[james-project] 08/09: JAMES-3016 Drop allow8bitmime option in remote delivery

Posted by rc...@apache.org.
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

commit 6d2e138119a54b354314586b94e6aecbe7be79a1
Author: Tran Tien Duc <dt...@linagora.com>
AuthorDate: Thu Jan 30 13:58:19 2020 +0700

    JAMES-3016 Drop allow8bitmime option in remote delivery
---
 CHANGELOG.md                                           |  6 +++++-
 .../mailets/RemoteDeliveryDKIMIntegrationTest.java     | 18 ++++++++----------
 .../remote/delivery/RemoteDeliveryConfiguration.java   |  3 ---
 .../delivery/RemoteDeliveryConfigurationTest.java      |  3 ---
 4 files changed, 13 insertions(+), 17 deletions(-)

diff --git a/CHANGELOG.md b/CHANGELOG.md
index 5df9c24..205ce27 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -54,7 +54,11 @@ of tasks being currently executed.
   - MailboxQuotaFixed matcher. Please use IsOverQuota instead.
 - UsersFileRepository, which was marked as deprecated for years
   - We accordingly removed deprecated methods within UsersRepositoryManagementMBean exposed over JMX (unsetAlias, getAlias, unsetForwardAddress, getForwardAddress). RecipientRewriteTables should be used instead.
-
+- JAMES-3016 RemoteDelivery now doesn't enable `allow8bitmime` property by default. 
+This parameter could cause body content alteration leading to DKIM invalid DKIM signatures to be positioned. 
+Thanks to Sergey B. for the report. 
+More details about the property is at [java mail doc](https://javaee.github.io/javamail/docs/api/com/sun/mail/smtp/package-summary.html) 
+ 
 ### Third party softwares
  - The distributed James server product (relying on Guice, Cassandra, ElasticSearch, RabbitMQ and optionally Swift) now needs at least RabbitMQ 3.8.
  - Tika prior 1.22 is subject to multiple CVEs. We recommend the upgrade.
diff --git a/server/mailet/integration-testing/src/test/java/org/apache/james/mailets/RemoteDeliveryDKIMIntegrationTest.java b/server/mailet/integration-testing/src/test/java/org/apache/james/mailets/RemoteDeliveryDKIMIntegrationTest.java
index 3a991b0..3efb1ad 100644
--- a/server/mailet/integration-testing/src/test/java/org/apache/james/mailets/RemoteDeliveryDKIMIntegrationTest.java
+++ b/server/mailet/integration-testing/src/test/java/org/apache/james/mailets/RemoteDeliveryDKIMIntegrationTest.java
@@ -144,7 +144,8 @@ public class RemoteDeliveryDKIMIntegrationTest {
             .withBase(SMTP_ONLY_MODULE)
             .withOverrides(binder -> binder.bind(DNSService.class).toInstance(inMemoryDNSService))
             .withMailetContainer(TemporaryJamesServer.SIMPLE_MAILET_CONTAINER_CONFIGURATION
-                .putProcessor(directResolutionTransport(MailetConfiguration.remoteDeliveryBuilder()))
+                .putProcessor(directResolutionTransport(MailetConfiguration.remoteDeliveryBuilder()
+                    .addProperty("mail.smtp.allow8bitmime", "true")))
                 .putProcessor(CommonProcessors.bounces()))
             .build(temporaryFolder.newFolder());
 
@@ -210,8 +211,7 @@ public class RemoteDeliveryDKIMIntegrationTest {
             .withBase(SMTP_ONLY_MODULE)
             .withOverrides(binder -> binder.bind(DNSService.class).toInstance(inMemoryDNSService))
             .withMailetContainer(TemporaryJamesServer.SIMPLE_MAILET_CONTAINER_CONFIGURATION
-                .putProcessor(directResolutionTransport(MailetConfiguration.remoteDeliveryBuilder()
-                    .addProperty("mail.smtp.allow8bitmime", "false")))
+                .putProcessor(directResolutionTransport(MailetConfiguration.remoteDeliveryBuilder()))
                 .putProcessor(CommonProcessors.bounces()))
             .build(temporaryFolder.newFolder());
 
@@ -244,8 +244,7 @@ public class RemoteDeliveryDKIMIntegrationTest {
             .withBase(SMTP_ONLY_MODULE)
             .withOverrides(binder -> binder.bind(DNSService.class).toInstance(inMemoryDNSService))
             .withMailetContainer(TemporaryJamesServer.SIMPLE_MAILET_CONTAINER_CONFIGURATION
-                .putProcessor(directResolutionTransport(MailetConfiguration.remoteDeliveryBuilder()
-                    .addProperty("mail.smtp.allow8bitmime", "false")))
+                .putProcessor(directResolutionTransport(MailetConfiguration.remoteDeliveryBuilder()))
                 .putProcessor(CommonProcessors.bounces()))
             .build(temporaryFolder.newFolder());
 
@@ -280,7 +279,8 @@ public class RemoteDeliveryDKIMIntegrationTest {
             .withBase(SMTP_ONLY_MODULE)
             .withOverrides(binder -> binder.bind(DNSService.class).toInstance(inMemoryDNSService))
             .withMailetContainer(TemporaryJamesServer.SIMPLE_MAILET_CONTAINER_CONFIGURATION
-                .putProcessor(directResolutionTransport(MailetConfiguration.remoteDeliveryBuilder()))
+                .putProcessor(directResolutionTransport(MailetConfiguration.remoteDeliveryBuilder()
+                    .addProperty("mail.smtp.allow8bitmime", "true")))
                 .putProcessor(CommonProcessors.bounces()))
             .build(temporaryFolder.newFolder());
 
@@ -346,8 +346,7 @@ public class RemoteDeliveryDKIMIntegrationTest {
             .withBase(SMTP_ONLY_MODULE)
             .withOverrides(binder -> binder.bind(DNSService.class).toInstance(inMemoryDNSService))
             .withMailetContainer(TemporaryJamesServer.SIMPLE_MAILET_CONTAINER_CONFIGURATION
-                .putProcessor(directResolutionTransport(MailetConfiguration.remoteDeliveryBuilder()
-                    .addProperty("mail.smtp.allow8bitmime", "false")))
+                .putProcessor(directResolutionTransport(MailetConfiguration.remoteDeliveryBuilder()))
                 .putProcessor(CommonProcessors.bounces()))
             .build(temporaryFolder.newFolder());
 
@@ -380,8 +379,7 @@ public class RemoteDeliveryDKIMIntegrationTest {
             .withBase(SMTP_ONLY_MODULE)
             .withOverrides(binder -> binder.bind(DNSService.class).toInstance(inMemoryDNSService))
             .withMailetContainer(TemporaryJamesServer.SIMPLE_MAILET_CONTAINER_CONFIGURATION
-                .putProcessor(directResolutionTransport(MailetConfiguration.remoteDeliveryBuilder()
-                    .addProperty("mail.smtp.allow8bitmime", "false")))
+                .putProcessor(directResolutionTransport(MailetConfiguration.remoteDeliveryBuilder()))
                 .putProcessor(CommonProcessors.bounces()))
             .build(temporaryFolder.newFolder());
 
diff --git a/server/mailet/mailets/src/main/java/org/apache/james/transport/mailets/remote/delivery/RemoteDeliveryConfiguration.java b/server/mailet/mailets/src/main/java/org/apache/james/transport/mailets/remote/delivery/RemoteDeliveryConfiguration.java
index 7bf937f..fbe60fa 100644
--- a/server/mailet/mailets/src/main/java/org/apache/james/transport/mailets/remote/delivery/RemoteDeliveryConfiguration.java
+++ b/server/mailet/mailets/src/main/java/org/apache/james/transport/mailets/remote/delivery/RemoteDeliveryConfiguration.java
@@ -213,9 +213,6 @@ public class RemoteDeliveryConfiguration {
         // Reactivated: javamail 1.3.2 should no more have problems with "250 OK" messages
         // (WAS "false": Prevents problems encountered with 250 OK Messages)
         props.put("mail.smtp.ehlo", "true");
-        // By setting this property to true the transport is allowed to send 8 bit data to the server (if it supports
-        // the 8bitmime extension).
-        props.setProperty("mail.smtp.allow8bitmime", "true");
         props.put("mail.smtp.timeout", String.valueOf(smtpTimeout));
         props.put("mail.smtp.connectiontimeout", String.valueOf(connectionTimeout));
         props.put("mail.smtp.sendpartial", String.valueOf(sendPartial));
diff --git a/server/mailet/mailets/src/test/java/org/apache/james/transport/mailets/remote/delivery/RemoteDeliveryConfigurationTest.java b/server/mailet/mailets/src/test/java/org/apache/james/transport/mailets/remote/delivery/RemoteDeliveryConfigurationTest.java
index 99abe13..cd70d4c 100644
--- a/server/mailet/mailets/src/test/java/org/apache/james/transport/mailets/remote/delivery/RemoteDeliveryConfigurationTest.java
+++ b/server/mailet/mailets/src/test/java/org/apache/james/transport/mailets/remote/delivery/RemoteDeliveryConfigurationTest.java
@@ -766,7 +766,6 @@ public class RemoteDeliveryConfigurationTest {
         assertThat(properties)
             .containsOnly(MapEntry.entry("mail.smtp.ssl.enable", "false"),
                 MapEntry.entry("mail.smtp.sendpartial", "false"),
-                MapEntry.entry("mail.smtp.allow8bitmime", "true"),
                 MapEntry.entry("mail.smtp.ehlo", "true"),
                 MapEntry.entry("mail.smtp.connectiontimeout", "60000"),
                 MapEntry.entry("mail.smtp.localhost", helo),
@@ -793,7 +792,6 @@ public class RemoteDeliveryConfigurationTest {
         assertThat(properties)
             .containsOnly(MapEntry.entry("mail.smtp.ssl.enable", "true"),
                 MapEntry.entry("mail.smtp.sendpartial", "true"),
-                MapEntry.entry("mail.smtp.allow8bitmime", "true"),
                 MapEntry.entry("mail.smtp.ehlo", "true"),
                 MapEntry.entry("mail.smtp.connectiontimeout", String.valueOf(connectionTimeout)),
                 MapEntry.entry("mail.smtp.localhost", helo),
@@ -823,7 +821,6 @@ public class RemoteDeliveryConfigurationTest {
         assertThat(properties)
             .containsOnly(MapEntry.entry("mail.smtp.ssl.enable", "true"),
                 MapEntry.entry("mail.smtp.sendpartial", "true"),
-                MapEntry.entry("mail.smtp.allow8bitmime", "true"),
                 MapEntry.entry("mail.smtp.ehlo", "true"),
                 MapEntry.entry("mail.smtp.connectiontimeout", String.valueOf(connectionTimeout)),
                 MapEntry.entry("mail.smtp.localhost", helo),


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


[james-project] 03/09: JAMES-3034 Switch to use James SMTPMessageSender

Posted by rc...@apache.org.
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

commit c171f206ac367ddd47be58463160d3bb56b7386c
Author: Tran Tien Duc <dt...@linagora.com>
AuthorDate: Tue Feb 4 14:03:04 2020 +0700

    JAMES-3034 Switch to use James SMTPMessageSender
---
 .../apache/james/MailsShouldBeWellReceived.java    | 86 ++++++++++------------
 .../eml/mail-containing-unicode-characters.eml     | 28 +++++++
 2 files changed, 68 insertions(+), 46 deletions(-)

diff --git a/server/container/guice/guice-common/src/test/java/org/apache/james/MailsShouldBeWellReceived.java b/server/container/guice/guice-common/src/test/java/org/apache/james/MailsShouldBeWellReceived.java
index 3fa2d00..ff443ab 100644
--- a/server/container/guice/guice-common/src/test/java/org/apache/james/MailsShouldBeWellReceived.java
+++ b/server/container/guice/guice-common/src/test/java/org/apache/james/MailsShouldBeWellReceived.java
@@ -22,33 +22,33 @@ package org.apache.james;
 import static org.assertj.core.api.Assertions.assertThat;
 
 import java.io.IOException;
+import java.io.InputStream;
 import java.nio.charset.StandardCharsets;
 import java.util.Properties;
 import java.util.UUID;
 
-import javax.mail.Authenticator;
 import javax.mail.Flags;
 import javax.mail.Folder;
 import javax.mail.Message;
 import javax.mail.MessagingException;
-import javax.mail.PasswordAuthentication;
 import javax.mail.Session;
 import javax.mail.Store;
-import javax.mail.Transport;
-import javax.mail.internet.InternetAddress;
 import javax.mail.internet.MimeMessage;
 import javax.mail.search.FlagTerm;
 
+import org.apache.commons.io.IOUtils;
 import org.apache.james.core.Domain;
 import org.apache.james.mailbox.DefaultMailboxes;
 import org.apache.james.modules.MailboxProbeImpl;
 import org.apache.james.modules.protocols.ImapGuiceProbe;
 import org.apache.james.modules.protocols.SmtpGuiceProbe;
+import org.apache.james.util.MimeMessageUtil;
 import org.apache.james.util.Port;
 import org.apache.james.utils.DataProbeImpl;
 import org.apache.james.utils.IMAPMessageReader;
 import org.apache.james.utils.SMTPMessageSender;
 import org.apache.james.utils.SpoolerProbe;
+import org.apache.mailet.base.test.FakeMail;
 import org.awaitility.Awaitility;
 import org.awaitility.Duration;
 import org.awaitility.core.ConditionFactory;
@@ -73,49 +73,29 @@ interface MailsShouldBeWellReceived {
 
     ConditionFactory CALMLY_AWAIT_FIVE_MINUTE = CALMLY_AWAIT.timeout(Duration.FIVE_MINUTES);
     String SENDER = "bob@apache.org";
-    String UNICODE_BODY = "unicode character 'Ð'";
+    String UNICODE_BODY = "Unicode €uro symbol.";
 
 
-    static Message readFirstMessageJavax(int imapPort) throws MessagingException {
+    static String readFirstMessageJavax(int imapPort) throws Exception {
         Session imapSession = Session.getDefaultInstance(new Properties());
-        Store store = imapSession.getStore("imap");
-        store.connect("localhost", imapPort, JAMES_USER, PASSWORD);
-        Folder inbox = store.getFolder(IMAPMessageReader.INBOX);
-        inbox.open(Folder.READ_ONLY);
-
-        CALMLY_AWAIT.untilAsserted(() ->
-            assertThat(searchForUnSeen(inbox))
-                .hasSize(1));
-
-        return searchForUnSeen(inbox)[0];
-    }
-
-    static Message[] searchForUnSeen(Folder inbox) throws MessagingException {
-        return inbox.search(new FlagTerm(new Flags(Flags.Flag.SEEN), false));
-    }
-
-    static void sendMessageJavax(GuiceJamesServer server) throws MessagingException {
-        Port smtpPort = server.getProbe(SmtpGuiceProbe.class).getSmtpPort();
-
-        Properties props = new Properties();
-        props.put("mail.smtp.host", "localhost");
-        props.put("mail.smtp.port", smtpPort.getValue() + "");
-        props.put("mail.smtp.auth", "true");
-        props.put("mail.smtp.allow8bitmime", "true"); //force to use 8bit(UTF-8), otherwise, it automatically converts into 7bit
-
-        Authenticator auth = new Authenticator() {
-            protected PasswordAuthentication getPasswordAuthentication() {
-                return new PasswordAuthentication(SENDER, PASSWORD);
+        try (Store store = imapSession.getStore("imap")) {
+            store.connect("localhost", imapPort, JAMES_USER, PASSWORD);
+            Folder inbox = store.getFolder(IMAPMessageReader.INBOX);
+            inbox.open(Folder.READ_ONLY);
+
+            CALMLY_AWAIT.untilAsserted(() ->
+                assertThat(searchForAll(inbox))
+                    .hasSize(1));
+
+            try (InputStream inputStream = searchForAll(inbox)[0].getInputStream()) {
+                return MimeMessageUtil.asString(
+                    MimeMessageUtil.mimeMessageFromStream(inputStream));
             }
-        };
-
-        Session session = Session.getInstance(props, auth);
-        Message message = new MimeMessage(session);
-        message.setFrom(new InternetAddress(SENDER));
-        message.setRecipients(Message.RecipientType.TO, InternetAddress.parse(JAMES_USER));
-        message.setText(UNICODE_BODY);
+        }
+    }
 
-        Transport.send(message);
+    static Message[] searchForAll(Folder inbox) throws MessagingException {
+        return inbox.search(new FlagTerm(new Flags(), false));
     }
 
     @Test
@@ -127,7 +107,20 @@ interface MailsShouldBeWellReceived {
         MailboxProbeImpl mailboxProbe = server.getProbe(MailboxProbeImpl.class);
         mailboxProbe.createMailbox("#private", JAMES_USER, DefaultMailboxes.INBOX);
 
-        sendMessageJavax(server);
+        Port smtpPort = server.getProbe(SmtpGuiceProbe.class).getSmtpPort();
+        try (SMTPMessageSender sender = new SMTPMessageSender(Domain.LOCALHOST.asString())) {
+            sender.connect(JAMES_SERVER_HOST, smtpPort);
+            MimeMessage mimeMessage = MimeMessageUtil.mimeMessageFromStream(
+                ClassLoader.getSystemResourceAsStream("eml/mail-containing-unicode-characters.eml"));
+
+            FakeMail.Builder mail = FakeMail.builder()
+                .name("test-unicode-body")
+                .sender(SENDER)
+                .recipient(JAMES_USER)
+                .mimeMessage(mimeMessage);
+
+            sender.sendMessage(mail);
+        }
 
         CALMLY_AWAIT.until(() -> server.getProbe(SpoolerProbe.class).processingFinished());
 
@@ -135,10 +128,11 @@ interface MailsShouldBeWellReceived {
             int imapPort = server.getProbe(ImapGuiceProbe.class).getImapPort();
             reader.connect(JAMES_SERVER_HOST, imapPort)
                 .login(JAMES_USER, PASSWORD)
-                .select(IMAPMessageReader.INBOX);
+                .select(IMAPMessageReader.INBOX)
+                .awaitMessageCount(CALMLY_AWAIT, 1);
 
-            assertThat(readFirstMessageJavax(imapPort).getInputStream())
-                .hasContent(UNICODE_BODY);
+            assertThat(readFirstMessageJavax(imapPort))
+                .contains(UNICODE_BODY);
         }
     }
 
diff --git a/server/container/guice/guice-common/src/test/resources/eml/mail-containing-unicode-characters.eml b/server/container/guice/guice-common/src/test/resources/eml/mail-containing-unicode-characters.eml
new file mode 100644
index 0000000..54e04b1
--- /dev/null
+++ b/server/container/guice/guice-common/src/test/resources/eml/mail-containing-unicode-characters.eml
@@ -0,0 +1,28 @@
+Return-Path: <bo...@james.org>
+MIME-Version: 1.0
+Delivered-To: bob@james.org
+Received: from 10.233.68.83 (EHLO incoming.james.org) ([10.233.68.83])
+          by james-0 (JAMES SMTP Server ) with ESMTP ID -1705393842
+          for <bo...@james.james.org>;
+          Wed, 22 Jan 2020 04:11:54 +0000 (UTC)
+Received: from smtp.james.org (unknown [10.233.65.0])
+	by incoming.james.org (Postfix) with ESMTPS id CCCA943
+	for <bo...@james.james.org>; Wed, 22 Jan 2020 04:11:54 +0000 (UTC)
+Received: from [10.116.29.102] (unknown [1.54.162.156])
+	(using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits))
+	(No client certificate requested)
+	by smtp.james.org (Postfix) with ESMTPSA id 2B7D13F393
+	for <bo...@james.org>; Wed, 22 Jan 2020 05:11:53 +0100 (CET)
+To: bob@james.org
+X-LINAGORA-Copy-Delivery-Done: 1
+From: Uncle Bob <bo...@james.org>
+Subject: quoted
+Message-ID: <f4...@james.org>
+Date: Wed, 22 Jan 2020 11:11:38 +0700
+User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:60.0) Gecko/20100101
+ Thunderbird/60.2.1
+Content-Type: text/plain; charset=utf-8; format=flowed
+Content-Transfer-Encoding: 8bit
+Content-Language: en-US
+
+Unicode €uro symbol.


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


[james-project] 04/09: JAMES-3034 Fix IMAPMessageReader to read correctly UTF-8 emails

Posted by rc...@apache.org.
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

commit c456920bdd378d5ed65e9d06a06e31a1b326a023
Author: Raphael Ouazana <ra...@linagora.com>
AuthorDate: Thu Feb 6 10:20:10 2020 +0100

    JAMES-3034 Fix IMAPMessageReader to read correctly UTF-8 emails
---
 .../apache/james/MailsShouldBeWellReceived.java    | 21 +--------------------
 .../org/apache/james/utils/IMAPMessageReader.java  | 22 +++++++++++++++++++---
 .../apache/james/utils/IMAPMessageReaderTest.java  | 18 +++++++++---------
 3 files changed, 29 insertions(+), 32 deletions(-)

diff --git a/server/container/guice/guice-common/src/test/java/org/apache/james/MailsShouldBeWellReceived.java b/server/container/guice/guice-common/src/test/java/org/apache/james/MailsShouldBeWellReceived.java
index ff443ab..e34fb46 100644
--- a/server/container/guice/guice-common/src/test/java/org/apache/james/MailsShouldBeWellReceived.java
+++ b/server/container/guice/guice-common/src/test/java/org/apache/james/MailsShouldBeWellReceived.java
@@ -75,25 +75,6 @@ interface MailsShouldBeWellReceived {
     String SENDER = "bob@apache.org";
     String UNICODE_BODY = "Unicode €uro symbol.";
 
-
-    static String readFirstMessageJavax(int imapPort) throws Exception {
-        Session imapSession = Session.getDefaultInstance(new Properties());
-        try (Store store = imapSession.getStore("imap")) {
-            store.connect("localhost", imapPort, JAMES_USER, PASSWORD);
-            Folder inbox = store.getFolder(IMAPMessageReader.INBOX);
-            inbox.open(Folder.READ_ONLY);
-
-            CALMLY_AWAIT.untilAsserted(() ->
-                assertThat(searchForAll(inbox))
-                    .hasSize(1));
-
-            try (InputStream inputStream = searchForAll(inbox)[0].getInputStream()) {
-                return MimeMessageUtil.asString(
-                    MimeMessageUtil.mimeMessageFromStream(inputStream));
-            }
-        }
-    }
-
     static Message[] searchForAll(Folder inbox) throws MessagingException {
         return inbox.search(new FlagTerm(new Flags(), false));
     }
@@ -131,7 +112,7 @@ interface MailsShouldBeWellReceived {
                 .select(IMAPMessageReader.INBOX)
                 .awaitMessageCount(CALMLY_AWAIT, 1);
 
-            assertThat(readFirstMessageJavax(imapPort))
+            assertThat(reader.readFirstMessage())
                 .contains(UNICODE_BODY);
         }
     }
diff --git a/server/testing/src/main/java/org/apache/james/utils/IMAPMessageReader.java b/server/testing/src/main/java/org/apache/james/utils/IMAPMessageReader.java
index c9f841e..36a57e0 100644
--- a/server/testing/src/main/java/org/apache/james/utils/IMAPMessageReader.java
+++ b/server/testing/src/main/java/org/apache/james/utils/IMAPMessageReader.java
@@ -19,14 +19,18 @@
 
 package org.apache.james.utils;
 
+import java.io.BufferedWriter;
 import java.io.Closeable;
 import java.io.IOException;
+import java.io.InputStreamReader;
+import java.io.OutputStreamWriter;
 import java.util.List;
 import java.util.regex.Matcher;
 import java.util.regex.Pattern;
 import java.util.stream.Stream;
 
 import org.apache.commons.net.imap.IMAPClient;
+import org.apache.commons.net.io.CRLFLineReader;
 import org.apache.james.core.Username;
 import org.assertj.core.api.Assertions;
 import org.awaitility.core.ConditionFactory;
@@ -39,19 +43,31 @@ import com.google.common.base.Splitter;
 
 public class IMAPMessageReader extends ExternalResource implements Closeable, AfterEachCallback {
 
+    public static class Utf8IMAPClient extends IMAPClient {
+        private static String UTF8_ENCODING = "UTF-8";
+
+        @Override
+        protected void _connectAction_() throws IOException {
+            super._connectAction_();
+            _reader = new CRLFLineReader(new InputStreamReader(_input_, UTF8_ENCODING));
+            __writer = new BufferedWriter(new OutputStreamWriter(_output_, UTF8_ENCODING));
+        }
+    }
+
     private static final Pattern EXAMINE_EXISTS = Pattern.compile("^\\* (\\d+) EXISTS$");
     private static final int MESSAGE_NUMBER_MATCHING_GROUP = 1;
     public static final String INBOX = "INBOX";
 
-    private final IMAPClient imapClient;
+    private final Utf8IMAPClient imapClient;
+
 
     @VisibleForTesting
-    IMAPMessageReader(IMAPClient imapClient) {
+    IMAPMessageReader(Utf8IMAPClient imapClient) {
         this.imapClient = imapClient;
     }
 
     public IMAPMessageReader() {
-        this(new IMAPClient());
+        this(new Utf8IMAPClient());
     }
 
     public IMAPMessageReader connect(String host, int port) throws IOException {
diff --git a/server/testing/src/test/java/org/apache/james/utils/IMAPMessageReaderTest.java b/server/testing/src/test/java/org/apache/james/utils/IMAPMessageReaderTest.java
index 797e92f..8d8051c 100644
--- a/server/testing/src/test/java/org/apache/james/utils/IMAPMessageReaderTest.java
+++ b/server/testing/src/test/java/org/apache/james/utils/IMAPMessageReaderTest.java
@@ -21,15 +21,15 @@ package org.apache.james.utils;
 
 import static org.assertj.core.api.Assertions.assertThat;
 
-import org.apache.commons.net.imap.IMAPClient;
-import org.junit.Test;
+import org.apache.james.utils.IMAPMessageReader.Utf8IMAPClient;
+import org.junit.jupiter.api.Test;
 
-public class IMAPMessageReaderTest {
-    private static final IMAPClient NULL_IMAP_CLIENT = null;
-    private IMAPMessageReader testee = new IMAPMessageReader(NULL_IMAP_CLIENT);
+class IMAPMessageReaderTest {
+    static final Utf8IMAPClient NULL_IMAP_CLIENT = null;
+    IMAPMessageReader testee = new IMAPMessageReader(NULL_IMAP_CLIENT);
 
     @Test
-    public void userReceivedMessageWithFlagsInMailboxShouldReturnTrueWhenSingleFlag() throws Exception {
+    void userReceivedMessageWithFlagsInMailboxShouldReturnTrueWhenSingleFlag() throws Exception {
         String replyString = "* 1 FETCH (FLAGS (\\Flagged) )\n" +
             "AAAC OK FETCH completed.";
 
@@ -38,7 +38,7 @@ public class IMAPMessageReaderTest {
     }
 
     @Test
-    public void userReceivedMessageWithFlagsInMailboxShouldReturnFalseWhenCompletedButNoFlag() throws Exception {
+    void userReceivedMessageWithFlagsInMailboxShouldReturnFalseWhenCompletedButNoFlag() throws Exception {
         String replyString = "* 1 FETCH (FLAGS (\\Seen) )\n" +
             "AAAC OK FETCH completed.";
 
@@ -47,7 +47,7 @@ public class IMAPMessageReaderTest {
     }
 
     @Test
-    public void userReceivedMessageWithFlagsInMailboxShouldReturnTrueWhenSeveralFlags() throws Exception {
+    void userReceivedMessageWithFlagsInMailboxShouldReturnTrueWhenSeveralFlags() throws Exception {
         String replyString = "* 1 FETCH (FLAGS (\\Flagged \\Seen) )\n" +
             "AAAC OK FETCH completed.";
 
@@ -56,7 +56,7 @@ public class IMAPMessageReaderTest {
     }
 
     @Test
-    public void userReceivedMessageWithFlagsInMailboxShouldReturnTrueWhenSeveralFlagsInAnyOrder() throws Exception {
+    void userReceivedMessageWithFlagsInMailboxShouldReturnTrueWhenSeveralFlagsInAnyOrder() throws Exception {
         String replyString = "* 1 FETCH (FLAGS (\\Flagged \\Seen) )\n" +
             "AAAC OK FETCH completed.";
 


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


[james-project] 01/09: JAMES-1824 Test to prove James SMTP & IMAP can handle UTF-8 mail body

Posted by rc...@apache.org.
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

commit ba68ead4f53cdba420ba312ddcda75495101c64d
Author: Tran Tien Duc <dt...@linagora.com>
AuthorDate: Thu Jan 30 17:26:22 2020 +0700

    JAMES-1824 Test to prove James SMTP & IMAP can handle UTF-8 mail body
    
    But something is wrong in SMTPMessageSender and ImapMessageReader which
    are relying on the apache commons net mail clients
---
 .../apache/james/MailsShouldBeWellReceived.java    | 86 ++++++++++++++++++++++
 1 file changed, 86 insertions(+)

diff --git a/server/container/guice/guice-common/src/test/java/org/apache/james/MailsShouldBeWellReceived.java b/server/container/guice/guice-common/src/test/java/org/apache/james/MailsShouldBeWellReceived.java
index 45f71fc..3fa2d00 100644
--- a/server/container/guice/guice-common/src/test/java/org/apache/james/MailsShouldBeWellReceived.java
+++ b/server/container/guice/guice-common/src/test/java/org/apache/james/MailsShouldBeWellReceived.java
@@ -19,10 +19,26 @@
 
 package org.apache.james;
 
+import static org.assertj.core.api.Assertions.assertThat;
+
 import java.io.IOException;
 import java.nio.charset.StandardCharsets;
+import java.util.Properties;
 import java.util.UUID;
 
+import javax.mail.Authenticator;
+import javax.mail.Flags;
+import javax.mail.Folder;
+import javax.mail.Message;
+import javax.mail.MessagingException;
+import javax.mail.PasswordAuthentication;
+import javax.mail.Session;
+import javax.mail.Store;
+import javax.mail.Transport;
+import javax.mail.internet.InternetAddress;
+import javax.mail.internet.MimeMessage;
+import javax.mail.search.FlagTerm;
+
 import org.apache.james.core.Domain;
 import org.apache.james.mailbox.DefaultMailboxes;
 import org.apache.james.modules.MailboxProbeImpl;
@@ -40,6 +56,7 @@ import org.junit.jupiter.api.Test;
 
 import com.github.fge.lambdas.Throwing;
 import com.google.common.io.Resources;
+
 import reactor.core.publisher.Mono;
 import reactor.core.scheduler.Schedulers;
 
@@ -55,6 +72,75 @@ interface MailsShouldBeWellReceived {
         .await();
 
     ConditionFactory CALMLY_AWAIT_FIVE_MINUTE = CALMLY_AWAIT.timeout(Duration.FIVE_MINUTES);
+    String SENDER = "bob@apache.org";
+    String UNICODE_BODY = "unicode character 'Ð'";
+
+
+    static Message readFirstMessageJavax(int imapPort) throws MessagingException {
+        Session imapSession = Session.getDefaultInstance(new Properties());
+        Store store = imapSession.getStore("imap");
+        store.connect("localhost", imapPort, JAMES_USER, PASSWORD);
+        Folder inbox = store.getFolder(IMAPMessageReader.INBOX);
+        inbox.open(Folder.READ_ONLY);
+
+        CALMLY_AWAIT.untilAsserted(() ->
+            assertThat(searchForUnSeen(inbox))
+                .hasSize(1));
+
+        return searchForUnSeen(inbox)[0];
+    }
+
+    static Message[] searchForUnSeen(Folder inbox) throws MessagingException {
+        return inbox.search(new FlagTerm(new Flags(Flags.Flag.SEEN), false));
+    }
+
+    static void sendMessageJavax(GuiceJamesServer server) throws MessagingException {
+        Port smtpPort = server.getProbe(SmtpGuiceProbe.class).getSmtpPort();
+
+        Properties props = new Properties();
+        props.put("mail.smtp.host", "localhost");
+        props.put("mail.smtp.port", smtpPort.getValue() + "");
+        props.put("mail.smtp.auth", "true");
+        props.put("mail.smtp.allow8bitmime", "true"); //force to use 8bit(UTF-8), otherwise, it automatically converts into 7bit
+
+        Authenticator auth = new Authenticator() {
+            protected PasswordAuthentication getPasswordAuthentication() {
+                return new PasswordAuthentication(SENDER, PASSWORD);
+            }
+        };
+
+        Session session = Session.getInstance(props, auth);
+        Message message = new MimeMessage(session);
+        message.setFrom(new InternetAddress(SENDER));
+        message.setRecipients(Message.RecipientType.TO, InternetAddress.parse(JAMES_USER));
+        message.setText(UNICODE_BODY);
+
+        Transport.send(message);
+    }
+
+    @Test
+    default void mailsContentWithUnicodeCharactersShouldBeKeptUnChanged(GuiceJamesServer server) throws Exception {
+        server.getProbe(DataProbeImpl.class).fluent()
+            .addDomain(DOMAIN)
+            .addUser(JAMES_USER, PASSWORD);
+
+        MailboxProbeImpl mailboxProbe = server.getProbe(MailboxProbeImpl.class);
+        mailboxProbe.createMailbox("#private", JAMES_USER, DefaultMailboxes.INBOX);
+
+        sendMessageJavax(server);
+
+        CALMLY_AWAIT.until(() -> server.getProbe(SpoolerProbe.class).processingFinished());
+
+        try (IMAPMessageReader reader = new IMAPMessageReader()) {
+            int imapPort = server.getProbe(ImapGuiceProbe.class).getImapPort();
+            reader.connect(JAMES_SERVER_HOST, imapPort)
+                .login(JAMES_USER, PASSWORD)
+                .select(IMAPMessageReader.INBOX);
+
+            assertThat(readFirstMessageJavax(imapPort).getInputStream())
+                .hasContent(UNICODE_BODY);
+        }
+    }
 
     @Test
     default void mailsShouldBeWellReceived(GuiceJamesServer server) throws Exception {


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


[james-project] 09/09: JAMES-3016 Use Junit5 in integration tests

Posted by rc...@apache.org.
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

commit da7e48a1456bdd53ca07190bfa03b9c3722aaf41
Author: Tran Tien Duc <dt...@linagora.com>
AuthorDate: Thu Jan 30 15:05:31 2020 +0700

    JAMES-3016 Use Junit5 in integration tests
---
 .../mailets/RemoteDeliveryDKIMIntegrationTest.java | 455 +++++++--------------
 server/mailet/mock-smtp-server/pom.xml             |   2 -
 .../server/testing/MockSmtpServerExtension.java    |  99 +++++
 .../james/utils/SMTPMessageSenderExtension.java    |  58 +++
 4 files changed, 306 insertions(+), 308 deletions(-)

diff --git a/server/mailet/integration-testing/src/test/java/org/apache/james/mailets/RemoteDeliveryDKIMIntegrationTest.java b/server/mailet/integration-testing/src/test/java/org/apache/james/mailets/RemoteDeliveryDKIMIntegrationTest.java
index 3efb1ad..02faba5 100644
--- a/server/mailet/integration-testing/src/test/java/org/apache/james/mailets/RemoteDeliveryDKIMIntegrationTest.java
+++ b/server/mailet/integration-testing/src/test/java/org/apache/james/mailets/RemoteDeliveryDKIMIntegrationTest.java
@@ -24,14 +24,15 @@ 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.awaitAtMostOneMinute;
-import static org.apache.james.util.docker.Images.MOCK_SMTP_SERVER;
 import static org.assertj.core.api.Assertions.assertThat;
 
+import java.io.File;
 import java.util.Optional;
 
 import javax.mail.MessagingException;
 import javax.mail.internet.MimeMessage;
 
+import org.apache.james.core.Domain;
 import org.apache.james.core.MailAddress;
 import org.apache.james.dnsservice.api.DNSService;
 import org.apache.james.dnsservice.api.InMemoryDNSService;
@@ -43,31 +44,28 @@ import org.apache.james.jdkim.mailets.MockPublicKeyRecordRetriever;
 import org.apache.james.mailets.configuration.CommonProcessors;
 import org.apache.james.mailets.configuration.MailetConfiguration;
 import org.apache.james.mailets.configuration.ProcessorConfiguration;
-import org.apache.james.mock.smtp.server.ConfigurationClient;
 import org.apache.james.mock.smtp.server.model.Mail;
+import org.apache.james.mock.smtp.server.testing.MockSmtpServerExtension;
+import org.apache.james.mock.smtp.server.testing.MockSmtpServerExtension.DockerMockSmtp;
 import org.apache.james.modules.protocols.SmtpGuiceProbe;
 import org.apache.james.probe.DataProbe;
 import org.apache.james.transport.matchers.All;
-import org.apache.james.util.Host;
 import org.apache.james.util.MimeMessageUtil;
-import org.apache.james.util.docker.DockerContainer;
 import org.apache.james.utils.DataProbeImpl;
-import org.apache.james.utils.IMAPMessageReader;
 import org.apache.james.utils.SMTPMessageSender;
+import org.apache.james.utils.SMTPMessageSenderExtension;
 import org.apache.mailet.base.test.FakeMail;
-import org.junit.After;
-import org.junit.Before;
-import org.junit.ClassRule;
-import org.junit.Ignore;
-import org.junit.Rule;
-import org.junit.Test;
-import org.junit.rules.TemporaryFolder;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-public class RemoteDeliveryDKIMIntegrationTest {
-
-    private static final Logger LOGGER = LoggerFactory.getLogger(RemoteDeliveryDKIMIntegrationTest.class);
+import org.junit.jupiter.api.AfterEach;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Disabled;
+import org.junit.jupiter.api.Nested;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.RegisterExtension;
+import org.junit.jupiter.api.io.TempDir;
+import org.junit.jupiter.params.ParameterizedTest;
+import org.junit.jupiter.params.provider.CsvSource;
+
+class RemoteDeliveryDKIMIntegrationTest {
 
     private static final String JAMES_ANOTHER_DOMAIN = "james.com";
     private static final String FROM = "from@" + DEFAULT_DOMAIN;
@@ -104,303 +102,154 @@ public class RemoteDeliveryDKIMIntegrationTest {
         "v=DKIM1; k=rsa; p=MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDYDaYKXzwVYwqWbLhmuJ66aTAN8wmDR+rfHE8HfnkSOax0oIoTM5zquZrTLo30870YMfYzxwfB6j/Nz3QdwrUD/t0YMYJiUKyWJnCKfZXHJBJ+yfRHr7oW+UW3cVo9CG2bBfIxsInwYe175g9UjyntJpWueqdEIo1c2bhv9Mp66QIDAQAB;",
         "selector", "example.com");
 
-    @ClassRule
-    public static DockerContainer mockSmtp = DockerContainer.fromName(MOCK_SMTP_SERVER)
-        .withLogConsumer(outputFrame -> LOGGER.debug("MockSMTP: " + outputFrame.getUtf8String()));
-    @Rule
-    public TemporaryFolder temporaryFolder = new TemporaryFolder();
-    @Rule
-    public IMAPMessageReader imapMessageReader = new IMAPMessageReader();
-    @Rule
-    public SMTPMessageSender messageSender = new SMTPMessageSender(DEFAULT_DOMAIN);
+    @RegisterExtension
+    static MockSmtpServerExtension mockSmtpServerExtension = new MockSmtpServerExtension();
+    @TempDir
+    static File tempDir;
+
+    @RegisterExtension
+    SMTPMessageSenderExtension smtpSenderExtension = new SMTPMessageSenderExtension(Domain.of(DEFAULT_DOMAIN));
 
     private TemporaryJamesServer jamesServer;
-    private ConfigurationClient mockSMTPConfiguration;
     private DataProbe dataProbe;
     private DKIMVerifier dkimVerifier;
 
-    @Before
-    public void setUp() {
-        mockSMTPConfiguration = configurationClient(mockSmtp);
+    @BeforeEach
+    void setUp() {
         dkimVerifier = new DKIMVerifier(MOCK_PUBLIC_KEY_RECORD_RETRIEVER);
     }
 
-    @After
-    public void tearDown() {
-        mockSMTPConfiguration.cleanServer();
+    @AfterEach
+    void tearDown() {
         if (jamesServer != null) {
             jamesServer.shutdown();
         }
     }
 
-    @Ignore("assertion failed:" +
-        "org.apache.james.jdkim.exceptions.PermFailException: Computed bodyhash is different from the expected one")
-    @Test
-    public void remoteDeliveryShouldNotBreakDKIMSignWhen7BitMessageAndAllowing8BitMime() throws Exception {
-        InMemoryDNSService inMemoryDNSService = new InMemoryDNSService()
-            .registerMxRecord(JAMES_ANOTHER_DOMAIN, mockSmtp.getContainerIp());
-
-        jamesServer = TemporaryJamesServer.builder()
-            .withBase(SMTP_ONLY_MODULE)
-            .withOverrides(binder -> binder.bind(DNSService.class).toInstance(inMemoryDNSService))
-            .withMailetContainer(TemporaryJamesServer.SIMPLE_MAILET_CONTAINER_CONFIGURATION
-                .putProcessor(directResolutionTransport(MailetConfiguration.remoteDeliveryBuilder()
-                    .addProperty("mail.smtp.allow8bitmime", "true")))
-                .putProcessor(CommonProcessors.bounces()))
-            .build(temporaryFolder.newFolder());
-
-        dataProbe = jamesServer.getProbe(DataProbeImpl.class);
-        dataProbe.addDomain(DEFAULT_DOMAIN);
-        dataProbe.addUser(FROM, PASSWORD);
-
-        FakeMail mail = FakeMail.builder()
-            .name("a-mail-with-7bit-encoding")
-            .sender(new MailAddress(FROM))
-            .recipient(new MailAddress(RECIPIENT))
-            .mimeMessage(MimeMessageUtil.mimeMessageFromStream(
-                ClassLoader.getSystemResourceAsStream(("eml/message-text-only-7bit.eml"))))
-            .build();
-        messageSender.connect(LOCALHOST_IP, jamesServer.getProbe(SmtpGuiceProbe.class).getSmtpPort())
-            .sendMessage(mail);
-
-        MimeMessage sendMessage = toMimeMessage(getFirstRecivedMail());
-
-        assertThat(dkimVerifier.verifyUsingCRLF(sendMessage))
-            .isNotEmpty();
-    }
-
-    @Test
-    public void remoteDeliveryShouldNotBreakDKIMSignWhen7BitAndBase64MessageAndAllowing8BitMime() throws Exception {
-        InMemoryDNSService inMemoryDNSService = new InMemoryDNSService()
-            .registerMxRecord(JAMES_ANOTHER_DOMAIN, mockSmtp.getContainerIp());
-
-        jamesServer = TemporaryJamesServer.builder()
-            .withBase(SMTP_ONLY_MODULE)
-            .withOverrides(binder -> binder.bind(DNSService.class).toInstance(inMemoryDNSService))
-            .withMailetContainer(TemporaryJamesServer.SIMPLE_MAILET_CONTAINER_CONFIGURATION
-                .putProcessor(directResolutionTransport(MailetConfiguration.remoteDeliveryBuilder()))
-                .putProcessor(CommonProcessors.bounces()))
-            .build(temporaryFolder.newFolder());
-
-        dataProbe = jamesServer.getProbe(DataProbeImpl.class);
-        dataProbe.addDomain(DEFAULT_DOMAIN);
-        dataProbe.addUser(FROM, PASSWORD);
-
-        FakeMail mail = FakeMail.builder()
-            .name("a-mail-with-7bit-base64-encoding")
-            .sender(new MailAddress(FROM))
-            .recipient(new MailAddress(RECIPIENT))
-            .mimeMessage(MimeMessageUtil.mimeMessageFromStream(
-                ClassLoader.getSystemResourceAsStream(("eml/message-multipart-7bit.eml"))))
-            .build();
-        messageSender.connect(LOCALHOST_IP, jamesServer.getProbe(SmtpGuiceProbe.class).getSmtpPort())
-            .sendMessage(mail);
-
-        MimeMessage sendMessage = toMimeMessage(getFirstRecivedMail());
-
-        assertThat(dkimVerifier.verifyUsingCRLF(sendMessage))
-            .isNotEmpty();
-    }
-
-    @Test
-    public void remoteDeliveryShouldNotBreakDKIMSignWhen7BitMessageAndDisable8BitMime() throws Exception {
-        InMemoryDNSService inMemoryDNSService = new InMemoryDNSService()
-            .registerMxRecord(JAMES_ANOTHER_DOMAIN, mockSmtp.getContainerIp());
-
-        jamesServer = TemporaryJamesServer.builder()
-            .withBase(SMTP_ONLY_MODULE)
-            .withOverrides(binder -> binder.bind(DNSService.class).toInstance(inMemoryDNSService))
-            .withMailetContainer(TemporaryJamesServer.SIMPLE_MAILET_CONTAINER_CONFIGURATION
-                .putProcessor(directResolutionTransport(MailetConfiguration.remoteDeliveryBuilder()))
-                .putProcessor(CommonProcessors.bounces()))
-            .build(temporaryFolder.newFolder());
-
-        dataProbe = jamesServer.getProbe(DataProbeImpl.class);
-        dataProbe.addDomain(DEFAULT_DOMAIN);
-        dataProbe.addUser(FROM, PASSWORD);
-
-        FakeMail mail = FakeMail.builder()
-            .name("a-mail-with-7bit-encoding")
-            .sender(new MailAddress(FROM))
-            .recipient(new MailAddress(RECIPIENT))
-            .mimeMessage(MimeMessageUtil.mimeMessageFromStream(
-                ClassLoader.getSystemResourceAsStream(("eml/message-text-only-7bit.eml"))))
-            .build();
-        messageSender.connect(LOCALHOST_IP, jamesServer.getProbe(SmtpGuiceProbe.class).getSmtpPort())
-            .sendMessage(mail);
-
-        MimeMessage sendMessage = toMimeMessage(getFirstRecivedMail());
-
-        assertThat(dkimVerifier.verifyUsingCRLF(sendMessage))
-            .isNotEmpty();
-    }
-
-    @Test
-    public void remoteDeliveryShouldNotBreakDKIMSignWhen7BitAndBase64MessageAndDisable8BitMime() throws Exception {
-        InMemoryDNSService inMemoryDNSService = new InMemoryDNSService()
-            .registerMxRecord(JAMES_ANOTHER_DOMAIN, mockSmtp.getContainerIp());
-
-        jamesServer = TemporaryJamesServer.builder()
-            .withBase(SMTP_ONLY_MODULE)
-            .withOverrides(binder -> binder.bind(DNSService.class).toInstance(inMemoryDNSService))
-            .withMailetContainer(TemporaryJamesServer.SIMPLE_MAILET_CONTAINER_CONFIGURATION
-                .putProcessor(directResolutionTransport(MailetConfiguration.remoteDeliveryBuilder()))
-                .putProcessor(CommonProcessors.bounces()))
-            .build(temporaryFolder.newFolder());
-
-        dataProbe = jamesServer.getProbe(DataProbeImpl.class);
-        dataProbe.addDomain(DEFAULT_DOMAIN);
-        dataProbe.addUser(FROM, PASSWORD);
-
-        FakeMail mail = FakeMail.builder()
-            .name("a-mail-with-7bit-base64-encoding")
-            .sender(new MailAddress(FROM))
-            .recipient(new MailAddress(RECIPIENT))
-            .mimeMessage(MimeMessageUtil.mimeMessageFromStream(
-                ClassLoader.getSystemResourceAsStream(("eml/message-multipart-7bit.eml"))))
-            .build();
-        messageSender.connect(LOCALHOST_IP, jamesServer.getProbe(SmtpGuiceProbe.class).getSmtpPort())
-            .sendMessage(mail);
-
-        MimeMessage sendMessage = toMimeMessage(getFirstRecivedMail());
-
-        assertThat(dkimVerifier.verifyUsingCRLF(sendMessage))
-            .isNotEmpty();
-    }
-
-    @Ignore("assertion failed:" +
-        "org.apache.james.jdkim.exceptions.PermFailException: Computed bodyhash is different from the expected one")
-    @Test
-    public void remoteDeliveryShouldNotBreakDKIMSignWhen8BitMessageAndAllowing8BitMime() throws Exception {
-        InMemoryDNSService inMemoryDNSService = new InMemoryDNSService()
-            .registerMxRecord(JAMES_ANOTHER_DOMAIN, mockSmtp.getContainerIp());
-
-        jamesServer = TemporaryJamesServer.builder()
-            .withBase(SMTP_ONLY_MODULE)
-            .withOverrides(binder -> binder.bind(DNSService.class).toInstance(inMemoryDNSService))
-            .withMailetContainer(TemporaryJamesServer.SIMPLE_MAILET_CONTAINER_CONFIGURATION
-                .putProcessor(directResolutionTransport(MailetConfiguration.remoteDeliveryBuilder()
-                    .addProperty("mail.smtp.allow8bitmime", "true")))
-                .putProcessor(CommonProcessors.bounces()))
-            .build(temporaryFolder.newFolder());
-
-        dataProbe = jamesServer.getProbe(DataProbeImpl.class);
-        dataProbe.addDomain(DEFAULT_DOMAIN);
-        dataProbe.addUser(FROM, PASSWORD);
-
-        FakeMail mail = FakeMail.builder()
-            .name("a-mail-with-8bit-encoding")
-            .sender(new MailAddress(FROM))
-            .recipient(new MailAddress(RECIPIENT))
-            .mimeMessage(MimeMessageUtil.mimeMessageFromStream(
-                ClassLoader.getSystemResourceAsStream(("eml/message-text-only-7bit.eml"))))
-            .build();
-        messageSender.connect(LOCALHOST_IP, jamesServer.getProbe(SmtpGuiceProbe.class).getSmtpPort())
-            .sendMessage(mail);
-
-        MimeMessage sendMessage = toMimeMessage(getFirstRecivedMail());
-
-        assertThat(dkimVerifier.verifyUsingCRLF(sendMessage))
-            .isNotEmpty();
-    }
+    @Nested
+    class WhenEnable8BitMime {
+        @Disabled("JAMES-3016 assertion failed:" +
+            "org.apache.james.jdkim.exceptions.PermFailException: Computed bodyhash is different from the expected one")
+        @Test
+        void remoteDeliveryShouldNotBreakDKIMSignWhen7BitTextMessage(SMTPMessageSender messageSender, DockerMockSmtp dockerMockSmtp) throws Exception {
+
+            InMemoryDNSService inMemoryDNSService = new InMemoryDNSService()
+                .registerMxRecord(JAMES_ANOTHER_DOMAIN, dockerMockSmtp.getIPAddress());
+
+            jamesServer = TemporaryJamesServer.builder()
+                .withBase(SMTP_ONLY_MODULE)
+                .withOverrides(binder -> binder.bind(DNSService.class).toInstance(inMemoryDNSService))
+                .withMailetContainer(TemporaryJamesServer.SIMPLE_MAILET_CONTAINER_CONFIGURATION
+                    .putProcessor(directResolutionTransport(MailetConfiguration.remoteDeliveryBuilder()
+                        .addProperty("mail.smtp.allow8bitmime", "true")))
+                    .putProcessor(CommonProcessors.bounces()))
+                .build(tempDir);
+
+            dataProbe = jamesServer.getProbe(DataProbeImpl.class);
+            dataProbe.addDomain(DEFAULT_DOMAIN);
+            dataProbe.addUser(FROM, PASSWORD);
+
+            FakeMail mail = FakeMail.builder()
+                .name("a-mail-with-7bit-encoding")
+                .sender(new MailAddress(FROM))
+                .recipient(new MailAddress(RECIPIENT))
+                .mimeMessage(MimeMessageUtil.mimeMessageFromStream(
+                    ClassLoader.getSystemResourceAsStream("eml/message-text-only-7bit.eml")))
+                .build();
+            messageSender.connect(LOCALHOST_IP, jamesServer.getProbe(SmtpGuiceProbe.class).getSmtpPort())
+                .sendMessage(mail);
+
+            MimeMessage sendMessage = toMimeMessage(getFirstRecivedMail(dockerMockSmtp));
+
+            assertThat(dkimVerifier.verifyUsingCRLF(sendMessage))
+                .isNotEmpty();
+        }
 
-    @Test
-    public void remoteDeliveryShouldNotBreakDKIMSignWhen8BitAndBase64MessageAndAllowing8BitMime() throws Exception {
-        InMemoryDNSService inMemoryDNSService = new InMemoryDNSService()
-            .registerMxRecord(JAMES_ANOTHER_DOMAIN, mockSmtp.getContainerIp());
-
-        jamesServer = TemporaryJamesServer.builder()
-            .withBase(SMTP_ONLY_MODULE)
-            .withOverrides(binder -> binder.bind(DNSService.class).toInstance(inMemoryDNSService))
-            .withMailetContainer(TemporaryJamesServer.SIMPLE_MAILET_CONTAINER_CONFIGURATION
-                .putProcessor(directResolutionTransport(MailetConfiguration.remoteDeliveryBuilder()))
-                .putProcessor(CommonProcessors.bounces()))
-            .build(temporaryFolder.newFolder());
-
-        dataProbe = jamesServer.getProbe(DataProbeImpl.class);
-        dataProbe.addDomain(DEFAULT_DOMAIN);
-        dataProbe.addUser(FROM, PASSWORD);
-
-        FakeMail mail = FakeMail.builder()
-            .name("a-mail-with-8bit-base64-encoding")
-            .sender(new MailAddress(FROM))
-            .recipient(new MailAddress(RECIPIENT))
-            .mimeMessage(MimeMessageUtil.mimeMessageFromStream(
-                ClassLoader.getSystemResourceAsStream(("eml/message-multipart-8bit.eml"))))
-            .build();
-        messageSender.connect(LOCALHOST_IP, jamesServer.getProbe(SmtpGuiceProbe.class).getSmtpPort())
-            .sendMessage(mail);
-
-        MimeMessage sendMessage = toMimeMessage(getFirstRecivedMail());
-
-        assertThat(dkimVerifier.verifyUsingCRLF(sendMessage))
-            .isNotEmpty();
+        @CsvSource({
+            "a-mail-with-7bit-base64-encoding, eml/message-multipart-7bit.eml",
+            "a-mail-with-8bit-encoding, eml/message-text-only-8bit.eml",
+            "a-mail-with-8bit-base64-encoding, eml/message-multipart-8bit.eml"
+        })
+        @ParameterizedTest
+        void remoteDeliveryShouldNotBreakDKIMSign(String mailName, String emlPath,
+                                                  SMTPMessageSender messageSender, DockerMockSmtp dockerMockSmtp) throws Exception {
+
+            InMemoryDNSService inMemoryDNSService = new InMemoryDNSService()
+                .registerMxRecord(JAMES_ANOTHER_DOMAIN, dockerMockSmtp.getIPAddress());
+
+            jamesServer = TemporaryJamesServer.builder()
+                .withBase(SMTP_ONLY_MODULE)
+                .withOverrides(binder -> binder.bind(DNSService.class).toInstance(inMemoryDNSService))
+                .withMailetContainer(TemporaryJamesServer.SIMPLE_MAILET_CONTAINER_CONFIGURATION
+                    .putProcessor(directResolutionTransport(MailetConfiguration.remoteDeliveryBuilder()
+                        .addProperty("mail.smtp.allow8bitmime", "true")))
+                    .putProcessor(CommonProcessors.bounces()))
+                .build(tempDir);
+
+            dataProbe = jamesServer.getProbe(DataProbeImpl.class);
+            dataProbe.addDomain(DEFAULT_DOMAIN);
+            dataProbe.addUser(FROM, PASSWORD);
+
+            FakeMail mail = FakeMail.builder()
+                .name(mailName)
+                .sender(new MailAddress(FROM))
+                .recipient(new MailAddress(RECIPIENT))
+                .mimeMessage(MimeMessageUtil.mimeMessageFromStream(
+                    ClassLoader.getSystemResourceAsStream(emlPath)))
+                .build();
+            messageSender.connect(LOCALHOST_IP, jamesServer.getProbe(SmtpGuiceProbe.class).getSmtpPort())
+                .sendMessage(mail);
+
+            MimeMessage sendMessage = toMimeMessage(getFirstRecivedMail(dockerMockSmtp));
+
+            assertThat(dkimVerifier.verifyUsingCRLF(sendMessage))
+                .isNotEmpty();
+        }
     }
 
-    @Test
-    public void remoteDeliveryShouldNotBreakDKIMSignWhen8BitMessageAndDisable8BitMime() throws Exception {
-        InMemoryDNSService inMemoryDNSService = new InMemoryDNSService()
-            .registerMxRecord(JAMES_ANOTHER_DOMAIN, mockSmtp.getContainerIp());
-
-        jamesServer = TemporaryJamesServer.builder()
-            .withBase(SMTP_ONLY_MODULE)
-            .withOverrides(binder -> binder.bind(DNSService.class).toInstance(inMemoryDNSService))
-            .withMailetContainer(TemporaryJamesServer.SIMPLE_MAILET_CONTAINER_CONFIGURATION
-                .putProcessor(directResolutionTransport(MailetConfiguration.remoteDeliveryBuilder()))
-                .putProcessor(CommonProcessors.bounces()))
-            .build(temporaryFolder.newFolder());
-
-        dataProbe = jamesServer.getProbe(DataProbeImpl.class);
-        dataProbe.addDomain(DEFAULT_DOMAIN);
-        dataProbe.addUser(FROM, PASSWORD);
-
-        FakeMail mail = FakeMail.builder()
-            .name("a-mail-with-8bit-encoding")
-            .sender(new MailAddress(FROM))
-            .recipient(new MailAddress(RECIPIENT))
-            .mimeMessage(MimeMessageUtil.mimeMessageFromStream(
-                ClassLoader.getSystemResourceAsStream(("eml/message-text-only-8bit.eml"))))
-            .build();
-        messageSender.connect(LOCALHOST_IP, jamesServer.getProbe(SmtpGuiceProbe.class).getSmtpPort())
-            .sendMessage(mail);
-
-        MimeMessage sendMessage = toMimeMessage(getFirstRecivedMail());
-
-        assertThat(dkimVerifier.verifyUsingCRLF(sendMessage))
-            .isNotEmpty();
-    }
+    @Nested
+    class WhenDisable8BitMime {
+
+        @CsvSource({
+            "a-mail-with-7bit-encoding, eml/message-text-only-7bit.eml",
+            "a-mail-with-7bit-base64-encoding, eml/message-multipart-7bit.eml",
+            "a-mail-with-8bit-encoding, eml/message-text-only-8bit.eml",
+            "a-mail-with-8bit-base64-encoding, eml/message-multipart-8bit.eml"
+        })
+        @ParameterizedTest
+        void remoteDeliveryShouldNotBreakDKIMSign(String mailName, String emlPath,
+                                                  SMTPMessageSender messageSender, DockerMockSmtp dockerMockSmtp) throws Exception {
+            InMemoryDNSService inMemoryDNSService = new InMemoryDNSService()
+                .registerMxRecord(JAMES_ANOTHER_DOMAIN, dockerMockSmtp.getIPAddress());
+
+            jamesServer = TemporaryJamesServer.builder()
+                .withBase(SMTP_ONLY_MODULE)
+                .withOverrides(binder -> binder.bind(DNSService.class).toInstance(inMemoryDNSService))
+                .withMailetContainer(TemporaryJamesServer.SIMPLE_MAILET_CONTAINER_CONFIGURATION
+                    .putProcessor(directResolutionTransport(MailetConfiguration.remoteDeliveryBuilder()))
+                    .putProcessor(CommonProcessors.bounces()))
+                .build(tempDir);
+
+            dataProbe = jamesServer.getProbe(DataProbeImpl.class);
+            dataProbe.addDomain(DEFAULT_DOMAIN);
+            dataProbe.addUser(FROM, PASSWORD);
+
+            FakeMail mail = FakeMail.builder()
+                .name(mailName)
+                .sender(new MailAddress(FROM))
+                .recipient(new MailAddress(RECIPIENT))
+                .mimeMessage(MimeMessageUtil.mimeMessageFromStream(
+                    ClassLoader.getSystemResourceAsStream(emlPath)))
+                .build();
+            messageSender.connect(LOCALHOST_IP, jamesServer.getProbe(SmtpGuiceProbe.class).getSmtpPort())
+                .sendMessage(mail);
+
+            MimeMessage sendMessage = toMimeMessage(getFirstRecivedMail(dockerMockSmtp));
+
+            assertThat(dkimVerifier.verifyUsingCRLF(sendMessage))
+                .isNotEmpty();
+        }
 
-    @Test
-    public void remoteDeliveryShouldNotBreakDKIMSignWhen8BitAndBase64MessageAndDisable8BitMime() throws Exception {
-        InMemoryDNSService inMemoryDNSService = new InMemoryDNSService()
-            .registerMxRecord(JAMES_ANOTHER_DOMAIN, mockSmtp.getContainerIp());
-
-        jamesServer = TemporaryJamesServer.builder()
-            .withBase(SMTP_ONLY_MODULE)
-            .withOverrides(binder -> binder.bind(DNSService.class).toInstance(inMemoryDNSService))
-            .withMailetContainer(TemporaryJamesServer.SIMPLE_MAILET_CONTAINER_CONFIGURATION
-                .putProcessor(directResolutionTransport(MailetConfiguration.remoteDeliveryBuilder()))
-                .putProcessor(CommonProcessors.bounces()))
-            .build(temporaryFolder.newFolder());
-
-        dataProbe = jamesServer.getProbe(DataProbeImpl.class);
-        dataProbe.addDomain(DEFAULT_DOMAIN);
-        dataProbe.addUser(FROM, PASSWORD);
-
-        FakeMail mail = FakeMail.builder()
-            .name("a-mail-with-8bit-base64-encoding")
-            .sender(new MailAddress(FROM))
-            .recipient(new MailAddress(RECIPIENT))
-            .mimeMessage(MimeMessageUtil.mimeMessageFromStream(
-                ClassLoader.getSystemResourceAsStream(("eml/message-multipart-8bit.eml"))))
-            .build();
-        messageSender.connect(LOCALHOST_IP, jamesServer.getProbe(SmtpGuiceProbe.class).getSmtpPort())
-            .sendMessage(mail);
-
-        MimeMessage sendMessage = toMimeMessage(getFirstRecivedMail());
-
-        assertThat(dkimVerifier.verifyUsingCRLF(sendMessage))
-            .isNotEmpty();
     }
 
     private MimeMessage toMimeMessage(Mail mail) {
@@ -411,9 +260,9 @@ public class RemoteDeliveryDKIMIntegrationTest {
         }
     }
 
-    private Mail getFirstRecivedMail() {
+    private Mail getFirstRecivedMail(DockerMockSmtp dockerMockSmtp) {
         return awaitAtMostOneMinute
-            .until(() -> mockSMTPConfiguration.listMails()
+            .until(() -> dockerMockSmtp.getConfigurationClient().listMails()
                 .stream()
                 .findFirst(), Optional::isPresent)
             .get();
@@ -427,10 +276,4 @@ public class RemoteDeliveryDKIMIntegrationTest {
             .addMailet(remoteDeliveryConfiguration
                 .matcher(All.class));
     }
-
-    private ConfigurationClient configurationClient(DockerContainer mockSmtp) {
-        return ConfigurationClient.from(
-            Host.from(mockSmtp.getHostIp(),
-                mockSmtp.getMappedPort(8000)));
-    }
 }
diff --git a/server/mailet/mock-smtp-server/pom.xml b/server/mailet/mock-smtp-server/pom.xml
index 4f7f78c..14c00b3 100644
--- a/server/mailet/mock-smtp-server/pom.xml
+++ b/server/mailet/mock-smtp-server/pom.xml
@@ -52,12 +52,10 @@
         <dependency>
             <groupId>${james.groupId}</groupId>
             <artifactId>james-server-testing</artifactId>
-            <scope>test</scope>
         </dependency>
         <dependency>
             <groupId>${james.groupId}</groupId>
             <artifactId>testing-base</artifactId>
-            <scope>test</scope>
         </dependency>
         <dependency>
             <groupId>com.fasterxml.jackson.core</groupId>
diff --git a/server/mailet/mock-smtp-server/src/main/java/org/apache/james/mock/smtp/server/testing/MockSmtpServerExtension.java b/server/mailet/mock-smtp-server/src/main/java/org/apache/james/mock/smtp/server/testing/MockSmtpServerExtension.java
new file mode 100644
index 0000000..8095c06
--- /dev/null
+++ b/server/mailet/mock-smtp-server/src/main/java/org/apache/james/mock/smtp/server/testing/MockSmtpServerExtension.java
@@ -0,0 +1,99 @@
+/****************************************************************
+ * 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.mock.smtp.server.testing;
+
+import org.apache.james.mock.smtp.server.ConfigurationClient;
+import org.apache.james.util.Host;
+import org.apache.james.util.docker.DockerContainer;
+import org.apache.james.util.docker.Images;
+import org.junit.jupiter.api.extension.AfterAllCallback;
+import org.junit.jupiter.api.extension.AfterEachCallback;
+import org.junit.jupiter.api.extension.BeforeAllCallback;
+import org.junit.jupiter.api.extension.ExtensionContext;
+import org.junit.jupiter.api.extension.ParameterContext;
+import org.junit.jupiter.api.extension.ParameterResolutionException;
+import org.junit.jupiter.api.extension.ParameterResolver;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class MockSmtpServerExtension implements AfterEachCallback, BeforeAllCallback,
+    AfterAllCallback, ParameterResolver {
+
+    public static class DockerMockSmtp {
+        private static final Logger LOGGER = LoggerFactory.getLogger(DockerMockSmtp.class);
+
+        private final DockerContainer mockSmtpServer;
+
+        DockerMockSmtp() {
+            mockSmtpServer = DockerContainer.fromName(Images.MOCK_SMTP_SERVER)
+                .withLogConsumer(outputFrame -> LOGGER.debug("MockSMTP: " + outputFrame.getUtf8String()));
+        }
+
+        void start() {
+            mockSmtpServer.start();
+        }
+
+        void stop() {
+            mockSmtpServer.stop();
+        }
+
+        public ConfigurationClient getConfigurationClient() {
+            return ConfigurationClient.from(Host.from(
+                mockSmtpServer.getHostIp(),
+                mockSmtpServer.getMappedPort(8000)));
+        }
+
+        public String getIPAddress() {
+            return mockSmtpServer.getContainerIp();
+        }
+    }
+
+    private final DockerMockSmtp dockerMockSmtp;
+
+    public MockSmtpServerExtension() {
+        this.dockerMockSmtp = new DockerMockSmtp();
+    }
+
+    @Override
+    public void beforeAll(ExtensionContext extensionContext) throws Exception {
+        dockerMockSmtp.start();
+    }
+
+    @Override
+    public void afterEach(ExtensionContext extensionContext) throws Exception {
+        dockerMockSmtp.getConfigurationClient()
+            .cleanServer();
+    }
+
+    @Override
+    public void afterAll(ExtensionContext extensionContext) throws Exception {
+        dockerMockSmtp.stop();
+    }
+
+    @Override
+    public boolean supportsParameter(ParameterContext parameterContext, ExtensionContext extensionContext) throws ParameterResolutionException {
+        return parameterContext.getParameter().getType() == DockerMockSmtp.class;
+    }
+
+    @Override
+    public Object resolveParameter(ParameterContext parameterContext, ExtensionContext extensionContext) throws ParameterResolutionException {
+        return dockerMockSmtp;
+    }
+}
diff --git a/server/testing/src/main/java/org/apache/james/utils/SMTPMessageSenderExtension.java b/server/testing/src/main/java/org/apache/james/utils/SMTPMessageSenderExtension.java
new file mode 100644
index 0000000..2e8993f
--- /dev/null
+++ b/server/testing/src/main/java/org/apache/james/utils/SMTPMessageSenderExtension.java
@@ -0,0 +1,58 @@
+/****************************************************************
+ * 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.utils;
+
+import org.apache.james.core.Domain;
+import org.junit.jupiter.api.extension.AfterEachCallback;
+import org.junit.jupiter.api.extension.BeforeEachCallback;
+import org.junit.jupiter.api.extension.ExtensionContext;
+import org.junit.jupiter.api.extension.ParameterContext;
+import org.junit.jupiter.api.extension.ParameterResolutionException;
+import org.junit.jupiter.api.extension.ParameterResolver;
+
+public class SMTPMessageSenderExtension implements ParameterResolver, BeforeEachCallback, AfterEachCallback {
+
+    private final Domain senderDomain;
+    private SMTPMessageSender messageSender;
+
+    public SMTPMessageSenderExtension(Domain senderDomain) {
+        this.senderDomain = senderDomain;
+    }
+
+    @Override
+    public void beforeEach(ExtensionContext extensionContext) throws Exception {
+        messageSender = new SMTPMessageSender(senderDomain.asString());
+    }
+
+    @Override
+    public void afterEach(ExtensionContext extensionContext) throws Exception {
+        messageSender.close();
+    }
+
+    @Override
+    public boolean supportsParameter(ParameterContext parameterContext, ExtensionContext extensionContext) throws ParameterResolutionException {
+        return parameterContext.getParameter().getType() == SMTPMessageSender.class;
+    }
+
+    @Override
+    public Object resolveParameter(ParameterContext parameterContext, ExtensionContext extensionContext) throws ParameterResolutionException {
+        return messageSender;
+    }
+}


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


[james-project] 06/09: JAMES-3016 Extract new DKIMVerifier to be using in integration test

Posted by rc...@apache.org.
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

commit f7e83f4ee11d0d2e6a34844fd6b692335c7ab742
Author: Tran Tien Duc <dt...@linagora.com>
AuthorDate: Wed Jan 22 13:20:03 2020 +0700

    JAMES-3016 Extract new DKIMVerifier to be using in integration test
---
 .../apache/james/jdkim/mailets/DKIMVerifier.java   | 74 ++++++++++++++++++++++
 .../org/apache/james/jdkim/mailets/DKIMVerify.java | 38 +----------
 .../apache/james/jdkim/mailets/DKIMSignTest.java   |  8 ++-
 3 files changed, 80 insertions(+), 40 deletions(-)

diff --git a/server/mailet/dkim/src/main/java/org/apache/james/jdkim/mailets/DKIMVerifier.java b/server/mailet/dkim/src/main/java/org/apache/james/jdkim/mailets/DKIMVerifier.java
new file mode 100644
index 0000000..0699402
--- /dev/null
+++ b/server/mailet/dkim/src/main/java/org/apache/james/jdkim/mailets/DKIMVerifier.java
@@ -0,0 +1,74 @@
+/****************************************************************
+ * 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.jdkim.mailets;
+
+import java.io.IOException;
+import java.io.OutputStream;
+import java.util.List;
+
+import javax.mail.MessagingException;
+import javax.mail.internet.MimeMessage;
+
+import org.apache.james.jdkim.api.BodyHasher;
+import org.apache.james.jdkim.api.Headers;
+import org.apache.james.jdkim.api.PublicKeyRecordRetriever;
+import org.apache.james.jdkim.api.SignatureRecord;
+import org.apache.james.jdkim.exceptions.FailException;
+
+public class DKIMVerifier {
+    private final org.apache.james.jdkim.DKIMVerifier originalVerifier;
+
+    public DKIMVerifier(PublicKeyRecordRetriever publicKeyRecordRetriever) {
+        this.originalVerifier = new org.apache.james.jdkim.DKIMVerifier(publicKeyRecordRetriever);
+    }
+
+    public List<SignatureRecord> verifyUsingCRLF(MimeMessage message) throws MessagingException, FailException {
+        return verify(message, true);
+    }
+
+    public List<SignatureRecord> verify(MimeMessage message, boolean forceCRLF) throws MessagingException, FailException {
+        Headers headers = new MimeMessageHeaders(message);
+        BodyHasher bh = originalVerifier.newBodyHasher(headers);
+        try {
+            if (bh != null) {
+                OutputStream os = new HeaderSkippingOutputStream(bh
+                    .getOutputStream());
+                if (forceCRLF) {
+                    os = new CRLFOutputStream(os);
+                }
+                message.writeTo(os);
+            }
+
+        } catch (IOException e) {
+            throw new MessagingException("Exception calculating bodyhash: "
+                    + e.getMessage(), e);
+        } finally {
+            try {
+                if (bh != null) {
+                    bh.getOutputStream().close();
+                }
+            } catch (IOException e) {
+                throw new MessagingException("Exception calculating bodyhash: "
+                        + e.getMessage(), e);
+            }
+        }
+        return originalVerifier.verify(bh);
+    }
+}
diff --git a/server/mailet/dkim/src/main/java/org/apache/james/jdkim/mailets/DKIMVerify.java b/server/mailet/dkim/src/main/java/org/apache/james/jdkim/mailets/DKIMVerify.java
index 2a2b11a..37eee98 100644
--- a/server/mailet/dkim/src/main/java/org/apache/james/jdkim/mailets/DKIMVerify.java
+++ b/server/mailet/dkim/src/main/java/org/apache/james/jdkim/mailets/DKIMVerify.java
@@ -19,8 +19,6 @@
 
 package org.apache.james.jdkim.mailets;
 
-import java.io.IOException;
-import java.io.OutputStream;
 import java.util.List;
 import java.util.Optional;
 
@@ -28,9 +26,6 @@ import javax.inject.Inject;
 import javax.mail.MessagingException;
 import javax.mail.internet.MimeMessage;
 
-import org.apache.james.jdkim.DKIMVerifier;
-import org.apache.james.jdkim.api.BodyHasher;
-import org.apache.james.jdkim.api.Headers;
 import org.apache.james.jdkim.api.PublicKeyRecordRetriever;
 import org.apache.james.jdkim.api.SignatureRecord;
 import org.apache.james.jdkim.exceptions.FailException;
@@ -77,7 +72,7 @@ public class DKIMVerify extends GenericMailet {
     public void service(Mail mail) throws MessagingException {
         try {
             MimeMessage message = mail.getMessage();
-            List<SignatureRecord> res = verify(verifier, message, forceCRLF);
+            List<SignatureRecord> res = verifier.verify(message, forceCRLF);
             if (res == null || res.isEmpty()) {
                 // neutral
                 mail.setAttribute(new Attribute(DKIM_AUTH_RESULT, AttributeValue.of("neutral (no signatures)")));
@@ -101,35 +96,4 @@ public class DKIMVerify extends GenericMailet {
             mail.setAttribute(new Attribute(DKIM_AUTH_RESULT, AttributeValue.of("fail (" + relatedRecordIdentity + e.getMessage() + ")")));
         }
     }
-
-    @VisibleForTesting
-    static List<SignatureRecord> verify(DKIMVerifier verifier, MimeMessage message, boolean forceCRLF)
-        throws MessagingException, FailException {
-        Headers headers = new MimeMessageHeaders(message);
-        BodyHasher bh = verifier.newBodyHasher(headers);
-        try {
-            if (bh != null) {
-                OutputStream os = new HeaderSkippingOutputStream(bh
-                    .getOutputStream());
-                if (forceCRLF) {
-                    os = new CRLFOutputStream(os);
-                }
-                message.writeTo(os);
-            }
-
-        } catch (IOException e) {
-            throw new MessagingException("Exception calculating bodyhash: "
-                    + e.getMessage(), e);
-        } finally {
-            try {
-                if (bh != null) {
-                    bh.getOutputStream().close();
-                }
-            } catch (IOException e) {
-                throw new MessagingException("Exception calculating bodyhash: "
-                        + e.getMessage(), e);
-            }
-        }
-        return verifier.verify(bh);
-    }
 }
diff --git a/server/mailet/dkim/src/test/java/org/apache/james/jdkim/mailets/DKIMSignTest.java b/server/mailet/dkim/src/test/java/org/apache/james/jdkim/mailets/DKIMSignTest.java
index 4a1c992..bd9fac9 100644
--- a/server/mailet/dkim/src/test/java/org/apache/james/jdkim/mailets/DKIMSignTest.java
+++ b/server/mailet/dkim/src/test/java/org/apache/james/jdkim/mailets/DKIMSignTest.java
@@ -35,10 +35,10 @@ import javax.mail.internet.InternetAddress;
 import javax.mail.internet.MimeMessage;
 import javax.mail.internet.MimeMessage.RecipientType;
 
-import org.apache.james.jdkim.DKIMVerifier;
 import org.apache.james.jdkim.api.SignatureRecord;
 import org.apache.james.jdkim.exceptions.FailException;
 import org.apache.james.jdkim.exceptions.PermFailException;
+import org.apache.james.util.MimeMessageUtil;
 import org.apache.mailet.Mail;
 import org.apache.mailet.Mailet;
 import org.apache.mailet.base.test.FakeMail;
@@ -47,7 +47,7 @@ import org.apache.mailet.base.test.FakeMailetConfig;
 import org.junit.jupiter.params.ParameterizedTest;
 import org.junit.jupiter.params.provider.ValueSource;
 
-public class DKIMSignTest {
+class DKIMSignTest {
 
     private static final String PKCS1_PEM_FILE = "test-dkim-pkcs1.pem";
     private static final String PKCS8_PEM_FILE = "test-dkim-pkcs8.pem";
@@ -97,7 +97,9 @@ public class DKIMSignTest {
     private List<SignatureRecord> verify(ByteArrayOutputStream rawMessage,
                                          MockPublicKeyRecordRetriever mockPublicKeyRecordRetriever)
             throws MessagingException, FailException {
-        List<SignatureRecord> signs = DKIMVerify.verify(new DKIMVerifier(mockPublicKeyRecordRetriever), new MimeMessage(Session.getDefaultInstance(new Properties()), new ByteArrayInputStream(rawMessage.toByteArray())), true);
+        List<SignatureRecord> signs = new DKIMVerifier(mockPublicKeyRecordRetriever)
+            .verifyUsingCRLF(MimeMessageUtil.mimeMessageFromStream(
+                new ByteArrayInputStream(rawMessage.toByteArray())));
         assertThat(signs).hasSize(1);
 
         return signs;


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


[james-project] 05/09: JAMES-3016 Extract MockSMTPServer image name to Images class

Posted by rc...@apache.org.
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

commit ea6a9018081057c76afa14d8d192bb21911d90ff
Author: Tran Tien Duc <dt...@linagora.com>
AuthorDate: Wed Jan 22 11:45:36 2020 +0700

    JAMES-3016 Extract MockSMTPServer image name to Images class
---
 .../test/java/org/apache/james/mailets/RemoteDeliveryErrorTest.java  | 5 +++--
 .../testing/src/main/java/org/apache/james/util/docker/Images.java   | 1 +
 2 files changed, 4 insertions(+), 2 deletions(-)

diff --git a/server/mailet/integration-testing/src/test/java/org/apache/james/mailets/RemoteDeliveryErrorTest.java b/server/mailet/integration-testing/src/test/java/org/apache/james/mailets/RemoteDeliveryErrorTest.java
index 493e976..7e6adeb 100644
--- a/server/mailet/integration-testing/src/test/java/org/apache/james/mailets/RemoteDeliveryErrorTest.java
+++ b/server/mailet/integration-testing/src/test/java/org/apache/james/mailets/RemoteDeliveryErrorTest.java
@@ -28,6 +28,7 @@ import static org.apache.james.mock.smtp.server.ConfigurationClient.BehaviorsPar
 import static org.apache.james.mock.smtp.server.ConfigurationClient.BehaviorsParamsBuilder.ConditionStep.inputContaining;
 import static org.apache.james.mock.smtp.server.ConfigurationClient.BehaviorsParamsBuilder.ResponseStep.doesNotAcceptAnyMail;
 import static org.apache.james.mock.smtp.server.ConfigurationClient.BehaviorsParamsBuilder.ResponseStep.serviceNotAvailable;
+import static org.apache.james.util.docker.Images.MOCK_SMTP_SERVER;
 import static org.assertj.core.api.Assertions.assertThat;
 
 import java.net.InetAddress;
@@ -108,10 +109,10 @@ public class RemoteDeliveryErrorTest {
     @Rule
     public SMTPMessageSender messageSender = new SMTPMessageSender(DEFAULT_DOMAIN);
     @ClassRule
-    public static DockerContainer mockSmtp = DockerContainer.fromName("linagora/mock-smtp-server")
+    public static DockerContainer mockSmtp = DockerContainer.fromName(MOCK_SMTP_SERVER)
         .withLogConsumer(outputFrame -> LOGGER.debug("MockSMTP 1: " + outputFrame.getUtf8String()));
     @ClassRule
-    public static DockerContainer mockSmtp2 = DockerContainer.fromName("linagora/mock-smtp-server")
+    public static DockerContainer mockSmtp2 = DockerContainer.fromName(MOCK_SMTP_SERVER)
         .withLogConsumer(outputFrame -> LOGGER.debug("MockSMTP 2: " + outputFrame.getUtf8String()));
 
     private TemporaryJamesServer jamesServer;
diff --git a/server/testing/src/main/java/org/apache/james/util/docker/Images.java b/server/testing/src/main/java/org/apache/james/util/docker/Images.java
index f880197..bd2f2e1 100644
--- a/server/testing/src/main/java/org/apache/james/util/docker/Images.java
+++ b/server/testing/src/main/java/org/apache/james/util/docker/Images.java
@@ -27,4 +27,5 @@ public interface Images {
     String NGINX = "nginx:1.15.1";
     String TIKA = "apache/tika:1.22";
     String SPAMASSASSIN = "dinkel/spamassassin:3.4.0";
+    String MOCK_SMTP_SERVER = "linagora/mock-smtp-server";
 }


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


[james-project] 02/09: JAMES-3034 SMTPMessageSender cannot handle UTF-8 characters in body

Posted by rc...@apache.org.
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

commit 277dd466796cb1d1fd29c45c0ccc9f86741cfe2b
Author: Tran Tien Duc <dt...@linagora.com>
AuthorDate: Mon Feb 3 15:35:17 2020 +0700

    JAMES-3034 SMTPMessageSender cannot handle UTF-8 characters in body
---
 pom.xml                                            |  5 ++
 server/mailet/mock-smtp-server/pom.xml             |  1 -
 .../test/resources/cucumber/GetMessages.feature    |  2 +-
 server/testing/pom.xml                             |  5 ++
 .../org/apache/james/utils/SMTPMessageSender.java  | 13 ++-
 .../apache/james/utils/SMTPMessageSenderTest.java  | 94 ++++++++++++++++++++++
 6 files changed, 115 insertions(+), 5 deletions(-)

diff --git a/pom.xml b/pom.xml
index c491d1b..1b387a6 100644
--- a/pom.xml
+++ b/pom.xml
@@ -2672,6 +2672,11 @@
                 </exclusions>
             </dependency>
             <dependency>
+                <groupId>org.subethamail</groupId>
+                <artifactId>subethasmtp</artifactId>
+                <version>3.1.7</version>
+            </dependency>
+            <dependency>
                 <groupId>org.testcontainers</groupId>
                 <artifactId>testcontainers</artifactId>
                 <version>${testcontainers.version}</version>
diff --git a/server/mailet/mock-smtp-server/pom.xml b/server/mailet/mock-smtp-server/pom.xml
index 0f81583..4f7f78c 100644
--- a/server/mailet/mock-smtp-server/pom.xml
+++ b/server/mailet/mock-smtp-server/pom.xml
@@ -113,7 +113,6 @@
         <dependency>
             <groupId>org.subethamail</groupId>
             <artifactId>subethasmtp</artifactId>
-            <version>3.1.7</version>
         </dependency>
     </dependencies>
 
diff --git a/server/protocols/jmap-draft-integration-testing/jmap-draft-integration-testing-common/src/test/resources/cucumber/GetMessages.feature b/server/protocols/jmap-draft-integration-testing/jmap-draft-integration-testing-common/src/test/resources/cucumber/GetMessages.feature
index a497504..d58c6a1 100644
--- a/server/protocols/jmap-draft-integration-testing/jmap-draft-integration-testing-common/src/test/resources/cucumber/GetMessages.feature
+++ b/server/protocols/jmap-draft-integration-testing/jmap-draft-integration-testing-common/src/test/resources/cucumber/GetMessages.feature
@@ -447,6 +447,6 @@ Feature: GetMessages method
     And the first attachment is:
     |key      | value                        |
     |type     |"text/calendar"               |
-    |size     |1056                          |
+    |size     |1096                          |
     |name     |"event.ics"                   |
     |isInline |false                         |
diff --git a/server/testing/pom.xml b/server/testing/pom.xml
index d981af7..20fc034 100644
--- a/server/testing/pom.xml
+++ b/server/testing/pom.xml
@@ -74,6 +74,11 @@
             <artifactId>awaitility</artifactId>
         </dependency>
         <dependency>
+            <groupId>org.subethamail</groupId>
+            <artifactId>subethasmtp</artifactId>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
             <groupId>org.testcontainers</groupId>
             <artifactId>testcontainers</artifactId>
         </dependency>
diff --git a/server/testing/src/main/java/org/apache/james/utils/SMTPMessageSender.java b/server/testing/src/main/java/org/apache/james/utils/SMTPMessageSender.java
index cdae5c8..7563db1 100644
--- a/server/testing/src/main/java/org/apache/james/utils/SMTPMessageSender.java
+++ b/server/testing/src/main/java/org/apache/james/utils/SMTPMessageSender.java
@@ -41,15 +41,18 @@ import com.github.fge.lambdas.Throwing;
 
 public class SMTPMessageSender extends ExternalResource implements Closeable {
 
+    private static final String DEFAULT_PROTOCOL = "TLS";
+    private static final String UTF_8_ENCODING = "UTF-8";
+
     public static SMTPMessageSender noAuthentication(String ip, int port, String senderDomain) throws IOException {
-        AuthenticatingSMTPClient smtpClient = new AuthenticatingSMTPClient();
+        AuthenticatingSMTPClient smtpClient = newUtf8AuthenticatingClient();
         smtpClient.connect(ip, port);
         return new SMTPMessageSender(smtpClient, senderDomain);
     }
 
     public static SMTPMessageSender authentication(String ip, int port, String senderDomain, String username, String password)
         throws NoSuchAlgorithmException, IOException, InvalidKeySpecException, InvalidKeyException {
-        AuthenticatingSMTPClient smtpClient = new AuthenticatingSMTPClient();
+        AuthenticatingSMTPClient smtpClient = newUtf8AuthenticatingClient();
         smtpClient.connect(ip, port);
         if (!smtpClient.auth(AuthenticatingSMTPClient.AUTH_METHOD.PLAIN, username, password)) {
             throw new RuntimeException("auth failed");
@@ -57,6 +60,10 @@ public class SMTPMessageSender extends ExternalResource implements Closeable {
         return new SMTPMessageSender(smtpClient, senderDomain);
     }
 
+    private static AuthenticatingSMTPClient newUtf8AuthenticatingClient() {
+        return new AuthenticatingSMTPClient(DEFAULT_PROTOCOL, UTF_8_ENCODING);
+    }
+
     private final AuthenticatingSMTPClient smtpClient;
     private final String senderDomain;
 
@@ -66,7 +73,7 @@ public class SMTPMessageSender extends ExternalResource implements Closeable {
     }
 
     public SMTPMessageSender(String senderDomain) {
-        this(new AuthenticatingSMTPClient(), senderDomain);
+        this(newUtf8AuthenticatingClient(), senderDomain);
     }
 
     public SMTPMessageSender connect(String ip, Port port) throws IOException {
diff --git a/server/testing/src/test/java/org/apache/james/utils/SMTPMessageSenderTest.java b/server/testing/src/test/java/org/apache/james/utils/SMTPMessageSenderTest.java
new file mode 100644
index 0000000..08565be
--- /dev/null
+++ b/server/testing/src/test/java/org/apache/james/utils/SMTPMessageSenderTest.java
@@ -0,0 +1,94 @@
+/****************************************************************
+ * 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.utils;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+import java.io.IOException;
+import java.nio.charset.StandardCharsets;
+
+import org.apache.james.core.Domain;
+import org.apache.james.util.Port;
+import org.junit.jupiter.api.AfterEach;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+import org.subethamail.wiser.Wiser;
+
+class SMTPMessageSenderTest {
+
+    private static final int RANDOM_PORT = 0;
+    private static final String LOCALHOST = "localhost";
+    private static final String SENDER = "sender@localhost";
+    private static final String RECIPIENT = "receiver@localhost";
+    private static final String UNICODE_BODY = "Unicode characters Ê Â á tiếng việt";
+    private static final String ASCII_BODY = "ASCII characters E A A tieng viet";
+
+    private Wiser testingSMTPServer;
+    private SMTPMessageSender testee;
+
+    @BeforeEach
+    void setUp() throws IOException {
+        testingSMTPServer = new Wiser(RANDOM_PORT);
+        testingSMTPServer.start();
+
+        testee = new SMTPMessageSender(Domain.LOCALHOST.asString())
+            .connect(LOCALHOST, Port.of(testingSMTPServer.getServer().getPort()));
+    }
+
+    @AfterEach
+    void teardown() {
+        testingSMTPServer.stop();
+    }
+
+    @Test
+    void sendMessageWithHeadersShouldDeliverUnicodeBodyCharacters() throws IOException {
+        testee.sendMessageWithHeaders(SENDER, RECIPIENT, UNICODE_BODY);
+
+        assertThat(testingSMTPServer.getMessages())
+            .extracting(message -> new String(message.getData(), StandardCharsets.UTF_8))
+            .hasOnlyOneElementSatisfying(messageContent ->
+                assertThat(messageContent)
+                    .contains(UNICODE_BODY));
+    }
+
+    @Test
+    void sendMessageWithHeadersShouldDeliverASCIIBodyCharacters() throws IOException {
+        testee.sendMessageWithHeaders(SENDER, RECIPIENT, ASCII_BODY);
+
+        assertThat(testingSMTPServer.getMessages())
+            .extracting(message -> new String(message.getData(), StandardCharsets.UTF_8))
+            .hasOnlyOneElementSatisfying(messageContent ->
+                assertThat(messageContent)
+                    .contains(ASCII_BODY));
+    }
+
+    @Test
+    void sendMessageWithHeadersShouldPreserveRightEnvelop() throws IOException {
+        testee.sendMessageWithHeaders(SENDER, RECIPIENT, ASCII_BODY);
+
+        assertThat(testingSMTPServer.getMessages())
+            .hasOnlyOneElementSatisfying(message -> {
+                assertThat(message.getEnvelopeReceiver())
+                    .isEqualTo(RECIPIENT);
+                assertThat(message.getEnvelopeSender())
+                    .isEqualTo(SENDER);
+            });
+    }
+}
\ No newline at end of file


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