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 <[email protected]> Authored: Thu Jun 7 08:37:39 2018 +0700 Committer: benwa <[email protected]> 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: <[email protected]> +MIME-Version: 1.0 +From: Hello <[email protected]> +Date: Thu, 4 Jun 2015 06:08:41 +0200 +Message-ID: <can1zdnw5pw7z5msm-tjupouygxwy6z-25a3wcb-c5bvqdup...@mail.gmail.com> +To: General Discussion <[email protected]> +Content-Type: text/plain; charset=UTF-8 +Subject: [arch-general] Very important topic +Reply-To: General Discussion <[email protected]> +Sender: "arch-general" <[email protected]> + +Hi all, + +Very important message!!! + +Thanks! \ No newline at end of file --------------------------------------------------------------------- To unsubscribe, e-mail: [email protected] For additional commands, e-mail: [email protected]
