Repository: james-project Updated Branches: refs/heads/master 74fd6c223 -> 81d88bf73
JAMES-1742 Retrieve attachment in download endpoint Project: http://git-wip-us.apache.org/repos/asf/james-project/repo Commit: http://git-wip-us.apache.org/repos/asf/james-project/commit/81d88bf7 Tree: http://git-wip-us.apache.org/repos/asf/james-project/tree/81d88bf7 Diff: http://git-wip-us.apache.org/repos/asf/james-project/diff/81d88bf7 Branch: refs/heads/master Commit: 81d88bf73d655e698afb7ba436649a5d273a03ab Parents: 4df388b Author: Antoine Duprat <adup...@linagora.com> Authored: Wed Jun 1 12:46:37 2016 +0200 Committer: Antoine Duprat <adup...@linagora.com> Committed: Mon Jun 6 13:05:37 2016 +0200 ---------------------------------------------------------------------- .../inmemory/mail/InMemoryAttachmentMapper.java | 3 ++ .../cucumber/CassandraDownloadCucumberTest.java | 2 +- .../cassandra/cucumber/CassandraStepdefs.java | 21 +++++--- .../integration/cucumber/DownloadStepdefs.java | 53 ++++++++++++++++-- .../resources/cucumber/DownloadEndpoint.feature | 6 +-- .../test/resources/cucumber/DownloadGet.feature | 16 ++++++ .../src/test/resources/eml/oneAttachment.eml | 38 +++++++++++++ .../cucumber/MemoryDownloadCucumberTest.java | 2 +- .../org/apache/james/jmap/DownloadServlet.java | 48 +++++++++++++++++ .../apache/james/jmap/DownloadServletTest.java | 57 ++++++++++++++++++++ 10 files changed, 229 insertions(+), 17 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/james-project/blob/81d88bf7/mailbox/memory/src/main/java/org/apache/james/mailbox/inmemory/mail/InMemoryAttachmentMapper.java ---------------------------------------------------------------------- diff --git a/mailbox/memory/src/main/java/org/apache/james/mailbox/inmemory/mail/InMemoryAttachmentMapper.java b/mailbox/memory/src/main/java/org/apache/james/mailbox/inmemory/mail/InMemoryAttachmentMapper.java index d4decc9..126fc61 100644 --- a/mailbox/memory/src/main/java/org/apache/james/mailbox/inmemory/mail/InMemoryAttachmentMapper.java +++ b/mailbox/memory/src/main/java/org/apache/james/mailbox/inmemory/mail/InMemoryAttachmentMapper.java @@ -39,6 +39,9 @@ public class InMemoryAttachmentMapper implements AttachmentMapper { @Override public Attachment getAttachment(AttachmentId attachmentId) throws AttachmentNotFoundException { + if (!attachmentsById.containsKey(attachmentId)) { + throw new AttachmentNotFoundException(attachmentId.getId()); + } return attachmentsById.get(attachmentId); } http://git-wip-us.apache.org/repos/asf/james-project/blob/81d88bf7/server/protocols/jmap-integration-testing/cassandra-jmap-integration-testing/src/test/java/org/apache/james/jmap/cassandra/cucumber/CassandraDownloadCucumberTest.java ---------------------------------------------------------------------- diff --git a/server/protocols/jmap-integration-testing/cassandra-jmap-integration-testing/src/test/java/org/apache/james/jmap/cassandra/cucumber/CassandraDownloadCucumberTest.java b/server/protocols/jmap-integration-testing/cassandra-jmap-integration-testing/src/test/java/org/apache/james/jmap/cassandra/cucumber/CassandraDownloadCucumberTest.java index 1ad24f8..428d9df 100644 --- a/server/protocols/jmap-integration-testing/cassandra-jmap-integration-testing/src/test/java/org/apache/james/jmap/cassandra/cucumber/CassandraDownloadCucumberTest.java +++ b/server/protocols/jmap-integration-testing/cassandra-jmap-integration-testing/src/test/java/org/apache/james/jmap/cassandra/cucumber/CassandraDownloadCucumberTest.java @@ -25,7 +25,7 @@ import cucumber.api.CucumberOptions; import cucumber.api.junit.Cucumber; @RunWith(Cucumber.class) -@CucumberOptions(features="classpath:cucumber/DownloadEndpoint.feature", +@CucumberOptions(features={"classpath:cucumber/DownloadEndpoint.feature", "classpath:cucumber/DownloadGet.feature"}, glue={"org.apache.james.jmap.methods.integration", "org.apache.james.jmap.cassandra.cucumber"}) public class CassandraDownloadCucumberTest { } http://git-wip-us.apache.org/repos/asf/james-project/blob/81d88bf7/server/protocols/jmap-integration-testing/cassandra-jmap-integration-testing/src/test/java/org/apache/james/jmap/cassandra/cucumber/CassandraStepdefs.java ---------------------------------------------------------------------- diff --git a/server/protocols/jmap-integration-testing/cassandra-jmap-integration-testing/src/test/java/org/apache/james/jmap/cassandra/cucumber/CassandraStepdefs.java b/server/protocols/jmap-integration-testing/cassandra-jmap-integration-testing/src/test/java/org/apache/james/jmap/cassandra/cucumber/CassandraStepdefs.java index fa2f77a..0ba38d1 100644 --- a/server/protocols/jmap-integration-testing/cassandra-jmap-integration-testing/src/test/java/org/apache/james/jmap/cassandra/cucumber/CassandraStepdefs.java +++ b/server/protocols/jmap-integration-testing/cassandra-jmap-integration-testing/src/test/java/org/apache/james/jmap/cassandra/cucumber/CassandraStepdefs.java @@ -19,6 +19,8 @@ package org.apache.james.jmap.cassandra.cucumber; +import java.util.Arrays; + import javax.inject.Inject; import org.apache.james.CassandraJamesServerMain; @@ -29,6 +31,8 @@ import org.apache.james.mailbox.elasticsearch.EmbeddedElasticSearch; import org.apache.james.modules.CassandraJmapServerModule; import org.junit.rules.TemporaryFolder; +import com.github.fge.lambdas.runnable.ThrowingRunnable; + import cucumber.api.java.After; import cucumber.api.java.Before; import cucumber.runtime.java.guice.ScenarioScoped; @@ -59,16 +63,21 @@ public class CassandraStepdefs { @After public void tearDown() { - tearDown(() -> mainStepdefs.tearDown()); - tearDown(() -> embeddedElasticSearch.after()); - tearDown(() -> temporaryFolder.delete()); + ignoreFailures(() -> mainStepdefs.tearDown(), + () -> embeddedElasticSearch.after(), + () -> temporaryFolder.delete()); } - private void tearDown(Runnable cleaningFunction) { + private void ignoreFailures(ThrowingRunnable... cleaners) { + Arrays.stream(cleaners) + .forEach(this::runSwallowingException); + } + + private void runSwallowingException(Runnable run) { try { - cleaningFunction.run(); + run.run(); } catch (Exception e) { - e.printStackTrace(); + // ignore } } } http://git-wip-us.apache.org/repos/asf/james-project/blob/81d88bf7/server/protocols/jmap-integration-testing/jmap-integration-testing-common/src/test/java/org/apache/james/jmap/methods/integration/cucumber/DownloadStepdefs.java ---------------------------------------------------------------------- diff --git a/server/protocols/jmap-integration-testing/jmap-integration-testing-common/src/test/java/org/apache/james/jmap/methods/integration/cucumber/DownloadStepdefs.java b/server/protocols/jmap-integration-testing/jmap-integration-testing-common/src/test/java/org/apache/james/jmap/methods/integration/cucumber/DownloadStepdefs.java index e703f23..8b0ce48 100644 --- a/server/protocols/jmap-integration-testing/jmap-integration-testing-common/src/test/java/org/apache/james/jmap/methods/integration/cucumber/DownloadStepdefs.java +++ b/server/protocols/jmap-integration-testing/jmap-integration-testing-common/src/test/java/org/apache/james/jmap/methods/integration/cucumber/DownloadStepdefs.java @@ -20,8 +20,16 @@ package org.apache.james.jmap.methods.integration.cucumber; import static com.jayway.restassured.RestAssured.with; +import static org.hamcrest.Matchers.not; +import static org.hamcrest.Matchers.notNullValue; + +import java.util.Date; import javax.inject.Inject; +import javax.mail.Flags; + +import org.apache.james.mailbox.model.MailboxConstants; +import org.apache.james.mailbox.model.MailboxPath; import com.jayway.restassured.http.ContentType; import com.jayway.restassured.response.Response; @@ -45,9 +53,13 @@ public class DownloadStepdefs { this.userStepdefs = userStepdefs; } - @Given("^an unknown current user with username \"([^\"]*)\" and password \"([^\"]*)\"$") - public void createUserWithPassword(String username, String password) throws Exception { - mainStepdefs.jmapServer.serverProbe().addUser(username, password); + @Given("^a message containing an attachment$") + public void appendMessageWithAttachment() throws Exception { + mainStepdefs.jmapServer.serverProbe().createMailbox(MailboxConstants.USER_NAMESPACE, userStepdefs.username, "INBOX"); + MailboxPath mailboxPath = new MailboxPath(MailboxConstants.USER_NAMESPACE, userStepdefs.username, "INBOX"); + + mainStepdefs.jmapServer.serverProbe().appendMessage(userStepdefs.username, mailboxPath, + ClassLoader.getSystemResourceAsStream("eml/oneAttachment.eml"), new Date(), false, new Flags()); } @When("^checking for the availability of the attachment endpoint$") @@ -85,10 +97,28 @@ public class DownloadStepdefs { .get("/download/"); } + @When("^getting the attachment with its correct blobId$") + public void getDownloadWithKnownBlobId() throws Throwable { + response = with() + .accept(ContentType.JSON) + .contentType(ContentType.JSON) + .header("Authorization", userStepdefs.accessToken.serialize()) + .get("/download/4000c5145f633410b80be368c44e1c394bff9437"); + } + + @When("^getting the attachment with an unknown blobId$") + public void getDownloadWithUnknownBlobId() throws Throwable { + response = with() + .accept(ContentType.JSON) + .contentType(ContentType.JSON) + .header("Authorization", userStepdefs.accessToken.serialize()) + .get("/download/badbadbadbadbadbadbadbadbadbadbadbadbadb"); + } + @Then("^the user should be authorized$") - public void httpOkStatus() throws Exception { + public void httpStatusDifferentFromUnauthorized() throws Exception { response.then() - .statusCode(200); + .statusCode(not(401)); } @Then("^the user should not be authorized$") @@ -102,4 +132,17 @@ public class DownloadStepdefs { response.then() .statusCode(400); } + + @Then("^the user should receive that attachment$") + public void httpOkStatusAndExpectedContent() throws Throwable { + response.then() + .statusCode(200) + .content(notNullValue()); + } + + @Then("^the user should receive a not found response$") + public void httpNotFoundStatus() throws Throwable { + response.then() + .statusCode(404); + } } http://git-wip-us.apache.org/repos/asf/james-project/blob/81d88bf7/server/protocols/jmap-integration-testing/jmap-integration-testing-common/src/test/resources/cucumber/DownloadEndpoint.feature ---------------------------------------------------------------------- diff --git a/server/protocols/jmap-integration-testing/jmap-integration-testing-common/src/test/resources/cucumber/DownloadEndpoint.feature b/server/protocols/jmap-integration-testing/jmap-integration-testing-common/src/test/resources/cucumber/DownloadEndpoint.feature index a483d8e..b5f9d3b 100644 --- a/server/protocols/jmap-integration-testing/jmap-integration-testing-common/src/test/resources/cucumber/DownloadEndpoint.feature +++ b/server/protocols/jmap-integration-testing/jmap-integration-testing-common/src/test/resources/cucumber/DownloadEndpoint.feature @@ -10,8 +10,7 @@ Feature: Download endpoint When checking for the availability of the attachment endpoint Then the user should be authorized - Scenario: An unknown user should initiate the access to the download endpoint - Given an unknown current user with username "unkn...@domain.tld" and password "secret" + Scenario: An unauthenticated user should initiate the access to the download endpoint When checking for the availability of the attachment endpoint Then the user should be authorized @@ -20,8 +19,7 @@ Feature: Download endpoint When asking for an attachment Then the user should be authorized - Scenario: An unknown user should not have access to the download endpoint - Given an unknown current user with username "unkn...@domain.tld" and password "secret" + Scenario: An unauthenticated user should not have access to the download endpoint When asking for an attachment Then the user should not be authorized http://git-wip-us.apache.org/repos/asf/james-project/blob/81d88bf7/server/protocols/jmap-integration-testing/jmap-integration-testing-common/src/test/resources/cucumber/DownloadGet.feature ---------------------------------------------------------------------- diff --git a/server/protocols/jmap-integration-testing/jmap-integration-testing-common/src/test/resources/cucumber/DownloadGet.feature b/server/protocols/jmap-integration-testing/jmap-integration-testing-common/src/test/resources/cucumber/DownloadGet.feature new file mode 100644 index 0000000..cd92d8a --- /dev/null +++ b/server/protocols/jmap-integration-testing/jmap-integration-testing-common/src/test/resources/cucumber/DownloadGet.feature @@ -0,0 +1,16 @@ +Feature: Download GET + As a James user + I want to retrieve my attachments + + Background: + Given a domain named "domain.tld" + And a current user with username "usern...@domain.tld" and password "secret" + + Scenario: Getting an attachment previously stored + Given a message containing an attachment + When getting the attachment with its correct blobId + Then the user should receive that attachment + + Scenario: Getting an attachment with an unknown blobId + When getting the attachment with an unknown blobId + Then the user should receive a not found response http://git-wip-us.apache.org/repos/asf/james-project/blob/81d88bf7/server/protocols/jmap-integration-testing/jmap-integration-testing-common/src/test/resources/eml/oneAttachment.eml ---------------------------------------------------------------------- diff --git a/server/protocols/jmap-integration-testing/jmap-integration-testing-common/src/test/resources/eml/oneAttachment.eml b/server/protocols/jmap-integration-testing/jmap-integration-testing-common/src/test/resources/eml/oneAttachment.eml new file mode 100644 index 0000000..ca0abe7 --- /dev/null +++ b/server/protocols/jmap-integration-testing/jmap-integration-testing-common/src/test/resources/eml/oneAttachment.eml @@ -0,0 +1,38 @@ +Mail content: +To: "=?utf-8?B?UmFuaSBBc3NhZg==?=" <rani.as...@jri.obm.lng.org> +Subject: =?utf-8?B?VHIuIDogUGhvdG9zICE=?= +Importance: Normal +MIME-Version: 1.0 +Content-Type: multipart/mixed; + boundary="----=_Part_0_1330682067197" + +------=_Part_0_1330682067197 +Content-Type: multipart/alternative; + boundary="----=_Part_2_1330682067197" + +------=_Part_2_1330682067197 +Content-Type: text/plain; + charset= utf-8 +Content-Transfer-Encoding: 8bit +Content-Disposition: inline + +Content of part 1-1 +------=_Part_2_1330682067197 +Content-Type: text/html; + charset= utf-8 +Content-Transfer-Encoding: 8bit +Content-Disposition: inline + +<b>Content of part 1-2</b> +------=_Part_2_1330682067197-- + +------=_Part_0_1330682067197 +Content-Type: application/octet-stream +Content-Transfer-Encoding: base64 +Content-Disposition: attachment; + filename="gimp.png" + +iVBORw0KGgoAAAANSUhEUgAAADAAAAAwCAYAAABXAvmHAAALxklEQVR4Ae2Xe0xUZ97H5X4RiyAXEARURBSYCzNnLjMwwAx3huGOIBcUFJERAUVRq+KlwHABFdu+b9+0766x1W21ttnUtE3rul6aGNtm3XbdWncjaa3VXrZRK6IgfPd3Tp6wOGmyo0v/cOMknxwy5xzO7/P8LueZaWlpaU80TwWeCvy3CcRwXJlUqp39RApIOE4i5hQPxBz30hMpIJIrjktkseMimfzPUyoglilTf/XVl8u1Ik4xrOJEEMu4wSkVEMmVZ6VSTeivFXy0TDZfIlfc0qil0KpIQM59P6UCUk71lVShPD1t2jT7qQ4+Sq32prq/GhfHjSXFSxGvEfMCQ1MsoLzOadT3pArFwBQ3LSdRqK4mJyfcz0xRwaCLRVKcBDEybmxqBRTKH8uXpEOj0/1MD3wuMTHR8T9adY4LoOD3KuPj7xYVGlGYo0e6gUNKoowkpKBmHpXJZO5TKXCrpjwT5pWFSM1IvROrVH0hksujf+laAHYWi8XT+nsKyIlvVKlSeVSu0twtXpI/Yq4rR2lBKoxpamQmK5Gm55CcIAP1wxAvOWUCEk4xVLvchIaVedi8rgq1NSXjqnjdHcrGayK5yhStVPpbLLvE/Xt6Tnf3Wu529XSM9fZ13Wzbse2kJiGhK1ap/ETCqe5lGLNum+trxnZsbca6tcuwJM+AvKw4mNI1yEpVURYUSE2S8wJ3RSKN35QJUJPdM6/IQ8vaCmzdZMbObU2w7G7BhhbzeEFR4e2SsrIRChqnz5zE999/h9HREXz19SDefOt1dPW0Y8e2Frywtx0vDnRg57NrUVdTgJJ8PYpyEpBvjEdOhvahLIg55YOioiKHRxKgjwPBEaHEQzfz/3DH9mb07+nGsbeO4MjRw+jts8DS3or/GdiNnr4ufP6XC/jhh+9w587PuHdvGLdv38SNG9fwwYfvon9vN3Zvb0Td8 lxUlqSirCgZpSRQnJuIgmwdcikL2elqZKUwAbni0aaQvb19M3HT2dnlloODw5Cdnd0d+rKVRFz48xkm0+i+gX5cv34NP/30I86fP4ePPjqL3n4LOjq24O2338CVK1/i22+v4ssvL+HTTz+B2WzGqlUrcfr0HzCwvw9Na8pRXZaBqtI0VBSnYGmBgUooEYUmHYQyyhDKCClJCl7gus0C9DE5OjkNpefkoXvPPugzjIiMEcN9+vQ7JHKFzvs1tzTdO3P2lBD8wYMHce3aNVBTYk1DPXp62/HHUx/g0qXPSOIyBgcHwX/u37+PiMhIiCViHP7dAbRuqAc/CJbxAktIoJAXSEKRiZURCRhJwJCoAPXcRZsF7B0dL8cq1RgeHgb/+fziX6E1pPCjDJ5e3iOUmcHWzRvHz398ThAoKSnB5b/9HYbUdMwJmUPl04GTJ9/DhQvn8cYbh/D++++D/1y/cYOvZbi6uWHvvj48u7kRgsDSdEGgjARKSOChPiCBpAQFpBx3ymYBWuXR9Zu2gH0wPj6O7KISyNRxiBJLMeMZz/GcXOP4a4cOCAJ5eXmY5eMDL29v6PUJ6O7aQX1xGOfOncLx429h5syZMDc2I05vQJQ0Fq6uriTZifWNy60yYCXAMqDVcmMiTtlrswAZPMgtLsXY2Jgg8PXVb5CYngWpSoMFi6MRsTAS7rSKnZZdeP3IIarv89ixow21tTXoaN9KE6kefdQLJ04cx5kzH0Cp5OA9axYCgoIx08sLCQlxsHS3o646F9XlGSQwuQeSJveAICBTKm49yuaRb+Drco0W6zdTM75zHJW1dVAlGvjXOULDF2ABCQQFz4FcEomdbc3o7qGpQ+za3oQtzWXY3LwUHc9twfPP9+Gd40ephN5GW9tmJCXpsHnLBrq+HS1N1VhRkYnlZemooilUzk+hgokpNPEuyExWUdlx99lb2GaBV+eGh48kJKciVq0VSofqX1j9wDkhCA4Ng0gihb+vF5 pXF2K9uQgta4qxoWEJNq4l6LihoQRtW5vQRSu9d6AH//vSAI1cCzq7dmNdQxVWVmahhq3+RP3n/6t8cjO1yE5TQ59EDaxQsN8Ctk+hUH50JhqSESONFQKfF0GrToH7+AfAf3YQdIlJcHNzwdrafDTWFaCJRJqJdfVFAvzfTfR9c30xrfYytLbUotlchtXVOULwND6FICuXPLz61uWj1iruUePv4gvbZgGWhv2+fn5DesrCXCob34BAPniBoJBQJOj18KMM1NfkYM2KXGFL0VCbxwsJ0N/Cd2Y6x1+zmrYdq5YZJ1Z+OU2ejGTK6rwg4QX20Phkq59mUPLz/264SBRMAva2Sky8hWka/T4gMPBuVnY2OJUaIXPnYU7YXCQlJ0MsFkMaE05BZdPbNJtW1iRQTytMCH9T0MK5VVVC4ELN8ytPZSNsG6IjQ5C4wAkVWl+UZsYiP1sonYl9kIpWPzpW9gLFMp1wJhyYhM1bCUfqh5dp7A3J5PIHqWnpyDQaIZFKMMvbU3iD0hikwLKEAGt5KFhCWGUKlk2ZdGGrUEQlkqaXC+LBgV4ok7tik8Edr1fOwKbkGajXeaBcH4aclFik6hXC9sE7ICCK4vAhZhAutkj8UlMsopL6jZ2d/acOjo7fBAbPuW/Qax7QHkYoBZIQgqUjQ5guQm3nG3VCqeg0IsSKFmDRwlBERYZBHDUPxvhICvoZdGR54IudEfisg8Nva+aiQTcDpVq/B4qY8Ffo2QuIYCsJVk62C9gRTiyVPkFhYSqxnLuk0qqH83P0FGwmVi3PpbLJp2MeZSSbxGjlSa6yRJjxgsxSNmmWUCZo2gjjMj9LgwpDGMzxbji20h9Xu6JxpV+FI+aF4016z/u1atcPq/P1DTqdOoae7U24E46PI+DMVsCfCHN2do6OWBzdS9vqf3Bq1bAxM4FKJZMalqbQmkq00N6+eU0FGlaV0gurgErJiPLiNHpZJfN7fiqnJNawwrYZJoMYtfF eVErT8fG6WbjaGYHBPg6v1EWNdXa2Yeuz6w75+PgEshicHkfAhXiGCCDmEosJGaELCgnpiJJIByUK5YjBED++tDANtctoGq0uw4amGmxaX0vHFSRUhfqVJVhRlYeK0iwSSSaBeCoxJTQablwk40aTYvwvrta6DL9c7DF6eYsPeixtOPjqAbzw4v6hrp7OC+XV5QsfV8CJ2fsRIUQkISXURCpR6enl1b1g0eLP+d8KsQrlqEqjGtHr48ezMmhMFmWiqsyEylIjivNSKPBEJBu0UKoVD0Qy+djC6Oir7h4eA/R/mvw87FdXK13PbsyPHOnt7aAtyQmBQ4dfHe3p7by187ntOXTdPCKDcLZVwIFwI7yIQGLepCxomUQ50Ui0UTD/5+Pr925waOifFi6OuiaKlQ1JOOUYMU6CozGx8uHIqJjr/kFBJ11cXJ6ne7YSZmIpkUJoWxqXv2fp2n133/49d44de1OQOHr0CAIC/Meio6MhkUhA110jNhL21gLWEvaTGtmbmM0kFk3KRCKRRZQR9cQGoo3oIHppJPfTsY/oJtqJbUQLUUeUshVNIJSExMvLK9rT03P+upbGVd09nZfo9/XPJlM2/P390dnZKRAWFsZL8JT+OwG7SRLuxEzCn5VTOBHFRJREPKEn0ggTUcRWtoJRyr4zscwlEXHsXinLbDgbn37sWW7bdm2L9/Pzu+nu7o6NGzeitbWVshEAlokvCPsJARskXFlPeDORYJaRCCYjZuWlYNnREFqGhlCxczJ27WJ279xJgXsRHmyAOLJnnyTAQxkVjvPnz4evry94eWuBX5RgOEwSmU54ErOYzGxiDhHGpMKJCCvC2bkwFvBsFrQ3m3bTWeBO7Fl2jPUErKFy44/p1gK2ijgSzkzGnfBgQcxkAfkwfBk+DG9iJrvWg93ryoJ2nBy41bMPWQvQ7pk/LrMSeCQRe8JhkpATk3JhQblZ4crOOVsFLGwTrAOfDLv3AAErWq0FHldm ktQEDlbYM+yseYTnLSOGCDD6H1/ARilrpuD/LyYuMoFDVgJPBqx3/p84YS3wpInonmQBxlOBpwJPBf4JszXhha5WvGwAAAAASUVORK5CYII= + +------=_Part_0_1330682067197-- + http://git-wip-us.apache.org/repos/asf/james-project/blob/81d88bf7/server/protocols/jmap-integration-testing/memory-jmap-integration-testing/src/test/java/org/apache/james/jmap/memory/cucumber/MemoryDownloadCucumberTest.java ---------------------------------------------------------------------- diff --git a/server/protocols/jmap-integration-testing/memory-jmap-integration-testing/src/test/java/org/apache/james/jmap/memory/cucumber/MemoryDownloadCucumberTest.java b/server/protocols/jmap-integration-testing/memory-jmap-integration-testing/src/test/java/org/apache/james/jmap/memory/cucumber/MemoryDownloadCucumberTest.java index b6a0f3e..3784393 100644 --- a/server/protocols/jmap-integration-testing/memory-jmap-integration-testing/src/test/java/org/apache/james/jmap/memory/cucumber/MemoryDownloadCucumberTest.java +++ b/server/protocols/jmap-integration-testing/memory-jmap-integration-testing/src/test/java/org/apache/james/jmap/memory/cucumber/MemoryDownloadCucumberTest.java @@ -25,7 +25,7 @@ import cucumber.api.CucumberOptions; import cucumber.api.junit.Cucumber; @RunWith(Cucumber.class) -@CucumberOptions(features="classpath:cucumber/DownloadEndpoint.feature", +@CucumberOptions(features={"classpath:cucumber/DownloadEndpoint.feature", "classpath:cucumber/DownloadGet.feature"}, glue={"org.apache.james.jmap.methods.integration", "org.apache.james.jmap.memory.cucumber"}) public class MemoryDownloadCucumberTest { } http://git-wip-us.apache.org/repos/asf/james-project/blob/81d88bf7/server/protocols/jmap/src/main/java/org/apache/james/jmap/DownloadServlet.java ---------------------------------------------------------------------- diff --git a/server/protocols/jmap/src/main/java/org/apache/james/jmap/DownloadServlet.java b/server/protocols/jmap/src/main/java/org/apache/james/jmap/DownloadServlet.java index d4a7597..e0c1e98 100644 --- a/server/protocols/jmap/src/main/java/org/apache/james/jmap/DownloadServlet.java +++ b/server/protocols/jmap/src/main/java/org/apache/james/jmap/DownloadServlet.java @@ -19,18 +19,43 @@ package org.apache.james.jmap; import static javax.servlet.http.HttpServletResponse.SC_BAD_REQUEST; +import static javax.servlet.http.HttpServletResponse.SC_INTERNAL_SERVER_ERROR; +import static javax.servlet.http.HttpServletResponse.SC_NOT_FOUND; import static javax.servlet.http.HttpServletResponse.SC_OK; +import java.io.IOException; + +import javax.inject.Inject; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; +import org.apache.commons.io.IOUtils; +import org.apache.james.mailbox.MailboxSession; +import org.apache.james.mailbox.exception.AttachmentNotFoundException; +import org.apache.james.mailbox.exception.MailboxException; +import org.apache.james.mailbox.store.MailboxSessionMapperFactory; +import org.apache.james.mailbox.store.mail.AttachmentMapper; +import org.apache.james.mailbox.store.mail.model.Attachment; +import org.apache.james.mailbox.store.mail.model.AttachmentId; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.google.common.annotations.VisibleForTesting; import com.google.common.base.Strings; public class DownloadServlet extends HttpServlet { private static final String ROOT_URL = "/"; + private static final Logger LOGGER = LoggerFactory.getLogger(DownloadServlet.class); + + private final MailboxSessionMapperFactory mailboxSessionMapperFactory; + + @Inject + @VisibleForTesting DownloadServlet(MailboxSessionMapperFactory mailboxSessionMapperFactory) { + this.mailboxSessionMapperFactory = mailboxSessionMapperFactory; + } @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException { @@ -38,7 +63,30 @@ public class DownloadServlet extends HttpServlet { if (Strings.isNullOrEmpty(pathInfo) || pathInfo.equals(ROOT_URL)) { resp.setStatus(SC_BAD_REQUEST); } else { + download(getMailboxSession(req), blobIdFrom(pathInfo), resp); + } + } + + @VisibleForTesting String blobIdFrom(String pathInfo) { + return pathInfo.substring(1); + } + + @VisibleForTesting void download(MailboxSession mailboxSession, String blobId, HttpServletResponse resp) { + try { + AttachmentMapper attachmentMapper = mailboxSessionMapperFactory.createAttachmentMapper(mailboxSession); + Attachment attachment = attachmentMapper.getAttachment(AttachmentId.from(blobId)); + IOUtils.copy(attachment.getStream(), resp.getOutputStream()); resp.setStatus(SC_OK); + } catch (AttachmentNotFoundException e) { + LOGGER.info(String.format("Attachment '%s' not found", blobId), e); + resp.setStatus(SC_NOT_FOUND); + } catch (MailboxException | IOException e) { + LOGGER.error("Error while downloading", e); + resp.setStatus(SC_INTERNAL_SERVER_ERROR); } } + + private MailboxSession getMailboxSession(HttpServletRequest req) { + return (MailboxSession) req.getAttribute(AuthenticationFilter.MAILBOX_SESSION); + } } http://git-wip-us.apache.org/repos/asf/james-project/blob/81d88bf7/server/protocols/jmap/src/test/java/org/apache/james/jmap/DownloadServletTest.java ---------------------------------------------------------------------- diff --git a/server/protocols/jmap/src/test/java/org/apache/james/jmap/DownloadServletTest.java b/server/protocols/jmap/src/test/java/org/apache/james/jmap/DownloadServletTest.java new file mode 100644 index 0000000..ccf4992 --- /dev/null +++ b/server/protocols/jmap/src/test/java/org/apache/james/jmap/DownloadServletTest.java @@ -0,0 +1,57 @@ +/**************************************************************** + * 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.jmap; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + +import javax.servlet.http.HttpServletResponse; + +import org.apache.james.mailbox.MailboxSession; +import org.apache.james.mailbox.exception.MailboxException; +import org.apache.james.mailbox.store.MailboxSessionMapperFactory; +import org.junit.Test; + +public class DownloadServletTest { + + @Test + public void blobIdFromShouldSkipTheFirstCharacter() { + String blobId = new DownloadServlet(null).blobIdFrom("1234"); + assertThat(blobId).isEqualTo("234"); + } + + @Test + public void downloadMayFailWhenUnableToCreateAttachmentMapper() throws Exception { + MailboxSession mailboxSession = mock(MailboxSession.class); + MailboxSessionMapperFactory mailboxSessionMapperFactory = mock(MailboxSessionMapperFactory.class); + when(mailboxSessionMapperFactory.createAttachmentMapper(mailboxSession)) + .thenThrow(new MailboxException()); + + DownloadServlet testee = new DownloadServlet(mailboxSessionMapperFactory); + + String blobId = null; + HttpServletResponse resp = mock(HttpServletResponse.class); + testee.download(mailboxSession, blobId, resp); + + verify(resp).setStatus(500); + } +} --------------------------------------------------------------------- To unsubscribe, e-mail: server-dev-unsubscr...@james.apache.org For additional commands, e-mail: server-dev-h...@james.apache.org