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 bt...@apache.org on 2018/06/12 00:03:24 UTC

[05/17] james-project git commit: JAMES-2411 EML download should enforce exact raw content

JAMES-2411 EML download should enforce exact raw content


Project: http://git-wip-us.apache.org/repos/asf/james-project/repo
Commit: http://git-wip-us.apache.org/repos/asf/james-project/commit/8b1f6fb5
Tree: http://git-wip-us.apache.org/repos/asf/james-project/tree/8b1f6fb5
Diff: http://git-wip-us.apache.org/repos/asf/james-project/diff/8b1f6fb5

Branch: refs/heads/master
Commit: 8b1f6fb56140c6516e6f6fbe1f182b7812b67a94
Parents: 0d66652
Author: benwa <bt...@linagora.com>
Authored: Thu Jun 7 08:37:39 2018 +0700
Committer: benwa <bt...@linagora.com>
Committed: Tue Jun 12 07:00:47 2018 +0700

----------------------------------------------------------------------
 .../webadmin/routes/MailRepositoriesRoutes.java | 24 ++++++++++------
 .../service/MailRepositoryStoreService.java     |  8 ++----
 .../routes/MailRepositoriesRoutesTest.java      | 15 +++++-----
 .../service/MailRepositoryStoreServiceTest.java | 29 +++++++++++---------
 .../src/test/resources/mail.eml                 | 16 +++++++++++
 5 files changed, 58 insertions(+), 34 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/james-project/blob/8b1f6fb5/server/protocols/webadmin/webadmin-mailrepository/src/main/java/org/apache/james/webadmin/routes/MailRepositoriesRoutes.java
----------------------------------------------------------------------
diff --git a/server/protocols/webadmin/webadmin-mailrepository/src/main/java/org/apache/james/webadmin/routes/MailRepositoriesRoutes.java b/server/protocols/webadmin/webadmin-mailrepository/src/main/java/org/apache/james/webadmin/routes/MailRepositoriesRoutes.java
index 83f035d..9bd7f1d 100644
--- a/server/protocols/webadmin/webadmin-mailrepository/src/main/java/org/apache/james/webadmin/routes/MailRepositoriesRoutes.java
+++ b/server/protocols/webadmin/webadmin-mailrepository/src/main/java/org/apache/james/webadmin/routes/MailRepositoriesRoutes.java
@@ -19,7 +19,7 @@
 
 package org.apache.james.webadmin.routes;
 
-import java.io.InputStream;
+import java.io.IOException;
 import java.io.UnsupportedEncodingException;
 import java.net.URLDecoder;
 import java.nio.charset.StandardCharsets;
@@ -29,6 +29,8 @@ import java.util.function.Supplier;
 
 import javax.inject.Inject;
 import javax.mail.MessagingException;
+import javax.mail.internet.MimeMessage;
+import javax.servlet.http.HttpServletResponse;
 import javax.ws.rs.DELETE;
 import javax.ws.rs.GET;
 import javax.ws.rs.Path;
@@ -187,15 +189,21 @@ public class MailRepositoriesRoutes implements Routes {
         service.get(MAIL_REPOSITORIES + "/:encodedUrl/mails/:mailKey", Constants.JSON_CONTENT_TYPE,
             (request, response) -> getMailAsJson(decodedRepositoryUrl(request), request.params("mailKey")), jsonTransformer);
 
-        service.get(MAIL_REPOSITORIES + "/:encodedUrl/mails/:mailKey", Constants.RFC822_CONTENT_TYPE, (request, response) -> {
-            response.type(Constants.RFC822_CONTENT_TYPE);
-            return getMailAsEml(decodedRepositoryUrl(request), request.params("mailKey"));
-        });
+        service.get(MAIL_REPOSITORIES + "/:encodedUrl/mails/:mailKey", Constants.RFC822_CONTENT_TYPE,
+            (request, response) -> writeMimeMessage(
+                getMailAsMimeMessage(decodedRepositoryUrl(request), request.params("mailKey")),
+                response.raw()));
+    }
+
+    private Object writeMimeMessage(MimeMessage mimeMessage, HttpServletResponse rawResponse) throws MessagingException, IOException {
+        rawResponse.setContentType(Constants.RFC822_CONTENT_TYPE);
+        mimeMessage.writeTo(rawResponse.getOutputStream());
+        return rawResponse;
     }
 
-    private InputStream getMailAsEml(String url, String mailKey) {
+    private MimeMessage getMailAsMimeMessage(String url, String mailKey) {
         try {
-            return repositoryStoreService.downloadMail(url, mailKey)
+            return repositoryStoreService.retrieveMessage(url, mailKey)
                 .orElseThrow(mailNotFoundError(mailKey));
         } catch (MailRepositoryStore.MailRepositoryStoreException | MessagingException e) {
             throw internalServerError(e);
@@ -248,7 +256,7 @@ public class MailRepositoriesRoutes implements Routes {
                             .message("The repository " + encodedUrl + "(decoded value: '" + url + "') does not exist")
                             .haltError());
                 return new ExtendedMailRepositoryResponse(url, size);
-            } catch (MailRepositoryStore.MailRepositoryStoreException | MessagingException e) {
+            } catch (MailRepositoryStore.MailRepositoryStoreException e) {
                 throw ErrorResponder.builder()
                     .statusCode(HttpStatus.INTERNAL_SERVER_ERROR_500)
                     .type(ErrorResponder.ErrorType.SERVER_ERROR)

http://git-wip-us.apache.org/repos/asf/james-project/blob/8b1f6fb5/server/protocols/webadmin/webadmin-mailrepository/src/main/java/org/apache/james/webadmin/service/MailRepositoryStoreService.java
----------------------------------------------------------------------
diff --git a/server/protocols/webadmin/webadmin-mailrepository/src/main/java/org/apache/james/webadmin/service/MailRepositoryStoreService.java b/server/protocols/webadmin/webadmin-mailrepository/src/main/java/org/apache/james/webadmin/service/MailRepositoryStoreService.java
index efc9a75..6f69be3 100644
--- a/server/protocols/webadmin/webadmin-mailrepository/src/main/java/org/apache/james/webadmin/service/MailRepositoryStoreService.java
+++ b/server/protocols/webadmin/webadmin-mailrepository/src/main/java/org/apache/james/webadmin/service/MailRepositoryStoreService.java
@@ -19,7 +19,6 @@
 
 package org.apache.james.webadmin.service;
 
-import java.io.InputStream;
 import java.util.List;
 import java.util.Optional;
 
@@ -74,7 +73,7 @@ public class MailRepositoryStoreService {
                 .collect(Guavate.toImmutableList());
     }
 
-    public Optional<Long> size(String url) throws MailRepositoryStore.MailRepositoryStoreException, MessagingException {
+    public Optional<Long> size(String url) throws MailRepositoryStore.MailRepositoryStoreException {
         Optional<MailRepository> mailRepository = Optional.ofNullable(getRepository(url));
         return mailRepository.map(Throwing.function(MailRepository::size).sneakyThrow());
     }
@@ -86,12 +85,11 @@ public class MailRepositoryStoreService {
             .map(Throwing.function(MailDto::fromMail).sneakyThrow());
     }
 
-    public Optional<InputStream> downloadMail(String url, String mailKey) throws MailRepositoryStore.MailRepositoryStoreException, MessagingException {
+    public Optional<MimeMessage> retrieveMessage(String url, String mailKey) throws MailRepositoryStore.MailRepositoryStoreException, MessagingException {
         MailRepository mailRepository = getRepository(url);
 
         return Optional.ofNullable(mailRepository.retrieve(mailKey))
-            .map(Throwing.function(Mail::getMessage).sneakyThrow())
-            .map(Throwing.function(MimeMessage::getRawInputStream).sneakyThrow());
+            .map(Throwing.function(Mail::getMessage).sneakyThrow());
     }
 
     public void deleteMail(String url, String mailKey) throws MailRepositoryStore.MailRepositoryStoreException, MessagingException {

http://git-wip-us.apache.org/repos/asf/james-project/blob/8b1f6fb5/server/protocols/webadmin/webadmin-mailrepository/src/test/java/org/apache/james/webadmin/routes/MailRepositoriesRoutesTest.java
----------------------------------------------------------------------
diff --git a/server/protocols/webadmin/webadmin-mailrepository/src/test/java/org/apache/james/webadmin/routes/MailRepositoriesRoutesTest.java b/server/protocols/webadmin/webadmin-mailrepository/src/test/java/org/apache/james/webadmin/routes/MailRepositoriesRoutesTest.java
index 308c9de..6e7d6fb 100644
--- a/server/protocols/webadmin/webadmin-mailrepository/src/test/java/org/apache/james/webadmin/routes/MailRepositoriesRoutesTest.java
+++ b/server/protocols/webadmin/webadmin-mailrepository/src/test/java/org/apache/james/webadmin/routes/MailRepositoriesRoutesTest.java
@@ -35,11 +35,9 @@ import static org.hamcrest.Matchers.notNullValue;
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.when;
 
-import java.nio.charset.StandardCharsets;
 import java.util.List;
 import java.util.Optional;
 
-import org.apache.commons.io.IOUtils;
 import org.apache.james.mailrepository.api.MailRepositoryStore;
 import org.apache.james.mailrepository.memory.MemoryMailRepository;
 import org.apache.james.metrics.api.NoopMetricFactory;
@@ -48,6 +46,7 @@ import org.apache.james.queue.api.ManageableMailQueue;
 import org.apache.james.queue.api.RawMailQueueItemDecoratorFactory;
 import org.apache.james.queue.memory.MemoryMailQueueFactory;
 import org.apache.james.task.MemoryTaskManager;
+import org.apache.james.util.ClassLoaderUtils;
 import org.apache.james.webadmin.Constants;
 import org.apache.james.webadmin.WebAdminServer;
 import org.apache.james.webadmin.WebAdminUtils;
@@ -248,7 +247,7 @@ public class MailRepositoriesRoutesTest {
     }
 
     @Test
-    public void listingKeysShouldReturnErrorOnInvalidOffset() throws Exception {
+    public void listingKeysShouldReturnErrorOnInvalidOffset() {
         given()
             .param("offset", "invalid")
         .when()
@@ -261,7 +260,7 @@ public class MailRepositoriesRoutesTest {
     }
 
     @Test
-    public void listingKeysShouldReturnErrorOnNegativeOffset() throws Exception {
+    public void listingKeysShouldReturnErrorOnNegativeOffset() {
         given()
             .param("offset", "-1")
         .when()
@@ -297,7 +296,7 @@ public class MailRepositoriesRoutesTest {
     }
 
     @Test
-    public void listingKeysShouldReturnErrorOnInvalidLimit() throws Exception {
+    public void listingKeysShouldReturnErrorOnInvalidLimit() {
         given()
             .param("limit", "invalid")
         .when()
@@ -310,7 +309,7 @@ public class MailRepositoriesRoutesTest {
     }
 
     @Test
-    public void listingKeysShouldReturnErrorOnNegativeLimit() throws Exception {
+    public void listingKeysShouldReturnErrorOnNegativeLimit() {
         given()
             .param("limit", "-1")
         .when()
@@ -344,7 +343,7 @@ public class MailRepositoriesRoutesTest {
     }
 
     @Test
-    public void zeroLimitShouldNotBeValid() throws Exception {
+    public void zeroLimitShouldNotBeValid() {
         given()
             .param("limit", "0")
         .when()
@@ -485,7 +484,7 @@ public class MailRepositoriesRoutesTest {
             .build();
         mailRepository.store(mail);
 
-        String expectedContent = IOUtils.toString(mail.getMessage().getRawInputStream(), StandardCharsets.UTF_8);
+        String expectedContent = ClassLoaderUtils.getSystemResourceAsString("mail.eml");
         given()
             .accept(Constants.RFC822_CONTENT_TYPE)
         .when()

http://git-wip-us.apache.org/repos/asf/james-project/blob/8b1f6fb5/server/protocols/webadmin/webadmin-mailrepository/src/test/java/org/apache/james/webadmin/service/MailRepositoryStoreServiceTest.java
----------------------------------------------------------------------
diff --git a/server/protocols/webadmin/webadmin-mailrepository/src/test/java/org/apache/james/webadmin/service/MailRepositoryStoreServiceTest.java b/server/protocols/webadmin/webadmin-mailrepository/src/test/java/org/apache/james/webadmin/service/MailRepositoryStoreServiceTest.java
index bd84ae1..100959a 100644
--- a/server/protocols/webadmin/webadmin-mailrepository/src/test/java/org/apache/james/webadmin/service/MailRepositoryStoreServiceTest.java
+++ b/server/protocols/webadmin/webadmin-mailrepository/src/test/java/org/apache/james/webadmin/service/MailRepositoryStoreServiceTest.java
@@ -23,13 +23,16 @@ import static org.assertj.core.api.Assertions.assertThatThrownBy;
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.when;
 
-import java.io.InputStream;
 import java.nio.charset.StandardCharsets;
 import java.util.Optional;
 
+import javax.mail.internet.MimeMessage;
+
 import org.apache.commons.io.IOUtils;
 import org.apache.james.mailrepository.api.MailRepositoryStore;
 import org.apache.james.mailrepository.memory.MemoryMailRepository;
+import org.apache.james.server.core.MimeMessageInputStream;
+import org.apache.james.util.ClassLoaderUtils;
 import org.apache.james.util.streams.Limit;
 import org.apache.james.util.streams.Offset;
 import org.apache.james.webadmin.dto.MailKey;
@@ -131,32 +134,32 @@ public class MailRepositoryStoreServiceTest {
     }
 
     @Test
-    public void downloadMailShouldThrownWhenUnknownRepository() throws Exception {
+    public void retrieveMessageShouldThrownWhenUnknownRepository() throws Exception {
         when(mailRepositoryStore.get("unkown")).thenReturn(Optional.empty());
 
-        assertThatThrownBy(() -> testee.downloadMail(FIRST_REPOSITORY, NAME_1))
+        assertThatThrownBy(() -> testee.retrieveMessage(FIRST_REPOSITORY, NAME_1))
             .isInstanceOf(NullPointerException.class);
     }
 
     @Test
-    public void dowloadMailShouldThrowWhenMailRepositoryStoreThrows() throws Exception {
+    public void retrieveMessageShouldThrowWhenMailRepositoryStoreThrows() throws Exception {
         when(mailRepositoryStore.get(FIRST_REPOSITORY))
             .thenThrow(new MailRepositoryStore.MailRepositoryStoreException("message"));
 
-        assertThatThrownBy(() -> testee.downloadMail(FIRST_REPOSITORY, NAME_1))
+        assertThatThrownBy(() -> testee.retrieveMessage(FIRST_REPOSITORY, NAME_1))
             .isInstanceOf(MailRepositoryStore.MailRepositoryStoreException.class);
     }
 
     @Test
-    public void dowloadMailShouldReturnEmptyWhenMailNotFound() throws Exception {
+    public void retrieveMessageShouldReturnEmptyWhenMailNotFound() throws Exception {
         when(mailRepositoryStore.get(FIRST_REPOSITORY)).thenReturn(Optional.of(repository));
 
-        assertThat(testee.downloadMail(FIRST_REPOSITORY, NAME_1))
+        assertThat(testee.retrieveMessage(FIRST_REPOSITORY, NAME_1))
             .isEmpty();
     }
 
     @Test
-    public void dowloadMailShouldReturnThInputStreamWhenMailExists() throws Exception {
+    public void retrieveMessageShouldReturnTheMessageWhenMailExists() throws Exception {
         when(mailRepositoryStore.get(FIRST_REPOSITORY)).thenReturn(Optional.of(repository));
 
         FakeMail mail = FakeMail.builder()
@@ -165,11 +168,11 @@ public class MailRepositoryStoreServiceTest {
             .build();
         repository.store(mail);
 
-        Optional<InputStream> downloadMail = testee.downloadMail(FIRST_REPOSITORY, NAME_1);
-        assertThat(downloadMail).isNotEmpty();
+        Optional<MimeMessage> mimeMessage = testee.retrieveMessage(FIRST_REPOSITORY, NAME_1);
+        assertThat(mimeMessage).isNotEmpty();
 
-        String eml = IOUtils.toString(downloadMail.get(), StandardCharsets.UTF_8);
-        String expectedContent = IOUtils.toString(mail.getMessage().getRawInputStream(), StandardCharsets.UTF_8);
-        assertThat(eml).isEqualTo(expectedContent);
+        String eml = IOUtils.toString(new MimeMessageInputStream(mimeMessage.get()), StandardCharsets.UTF_8);
+        String expectedContent = ClassLoaderUtils.getSystemResourceAsString("mail.eml");
+        assertThat(eml).isEqualToNormalizingNewlines(expectedContent);
     }
 }

http://git-wip-us.apache.org/repos/asf/james-project/blob/8b1f6fb5/server/protocols/webadmin/webadmin-mailrepository/src/test/resources/mail.eml
----------------------------------------------------------------------
diff --git a/server/protocols/webadmin/webadmin-mailrepository/src/test/resources/mail.eml b/server/protocols/webadmin/webadmin-mailrepository/src/test/resources/mail.eml
new file mode 100644
index 0000000..b732d23
--- /dev/null
+++ b/server/protocols/webadmin/webadmin-mailrepository/src/test/resources/mail.eml
@@ -0,0 +1,16 @@
+Return-Path: <ge...@list.org>
+MIME-Version: 1.0
+From: Hello <he...@gmail.com>
+Date: Thu, 4 Jun 2015 06:08:41 +0200
+Message-ID: <CA...@mail.gmail.com>
+To: General Discussion  <ge...@list.org>
+Content-Type: text/plain; charset=UTF-8
+Subject: [arch-general] Very important topic
+Reply-To: General Discussion <ge...@list.org>
+Sender: "arch-general" <ge...@list.org>
+
+Hi all,
+
+Very important message!!!
+
+Thanks!
\ 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