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 2019/05/10 03:27:01 UTC

[james-project] branch master updated (d7adf18 -> e7d5585)

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

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


    from d7adf18  JAMES-2717 CassandraLinshareBlobExportMechanismIntegrationTest needs to rely on DockerElasticSearchExtension
     new 4f6eafb  JAMES-2233 Adding more context to WebAdmin audit logs
     new 5e0baaa  JAMES-2233 Correlate request and response logging using a requestId
     new 5439fd0  JAMES-2743 HeaderCollectionTest JUNIT 5 migration
     new 1b19a73  JAMES-2743 JMAP Search Doesn't support From field with UTF8 characters
     new 4b3d611  JAMES-2743 Need HeaderCollection to use encoded(raw) value when parsing
     new 7457846  JAMES-2744 James download currently doesn't provide Content-Type header
     new e7d5585  JAMES-2744 James download should provide Content-Type header

The 7 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:
 mailbox/elasticsearch/pom.xml                      |  5 ++
 .../elasticsearch/json/HeaderCollection.java       | 13 +--
 .../elasticsearch/json/HeaderCollectionTest.java   | 93 +++++++++++++---------
 .../org/apache/james/util/InputStreamUtils.java    | 20 ++---
 .../apache/james/util/InputStreamUtilsTest.java}   | 33 +++++---
 .../integration/GetMessageListMethodTest.java      | 78 ++++++++++++++++++
 .../integration/cucumber/DownloadStepdefs.java     | 21 +++++
 .../test/resources/cucumber/DownloadGet.feature    |  6 ++
 .../src/test/resources/eml/oneAttachment-part1.eml | 69 +++++++---------
 .../src/test/resources/eml/oneAttachment-part2.eml | 46 +++--------
 .../memory/MemoryGetMessageListMethodTest.java     |  7 ++
 .../org/apache/james/jmap/DownloadServlet.java     |  1 +
 .../james/webadmin/mdc/LoggingRequestFilter.java   | 23 +++++-
 .../james/webadmin/mdc/LoggingResponseFilter.java  | 19 ++++-
 .../org/apache/james/webadmin/mdc/RequestId.java}  | 52 ++++++------
 .../apache/james/webadmin/mdc/RequestIdTest.java   |  9 +--
 16 files changed, 322 insertions(+), 173 deletions(-)
 copy mailbox/api/src/main/java/org/apache/james/mailbox/exception/AnnotationException.java => server/container/util/src/main/java/org/apache/james/util/InputStreamUtils.java (74%)
 copy server/{blob/blob-objectstorage/src/test/java/org/apache/james/blob/objectstorage/PayloadCodecContract.java => container/util/src/test/java/org/apache/james/util/InputStreamUtilsTest.java} (56%)
 copy mailbox/store/src/test/resources/eml/oneHtmlAttachmentAndSomeTextInlined.eml => server/protocols/jmap-integration-testing/jmap-integration-testing-common/src/test/resources/eml/oneAttachment-part1.eml (75%)
 copy mailbox/store/src/test/resources/eml/oneAttachmentWithoutContentType.eml => server/protocols/jmap-integration-testing/jmap-integration-testing-common/src/test/resources/eml/oneAttachment-part2.eml (85%)
 copy server/{mailrepository/mailrepository-api/src/main/java/org/apache/james/mailrepository/api/MailKey.java => protocols/webadmin/webadmin-core/src/main/java/org/apache/james/webadmin/mdc/RequestId.java} (63%)
 copy protocols/smtp/src/test/java/org/apache/james/protocols/smtp/hook/HookResultTest.java => server/protocols/webadmin/webadmin-core/src/test/java/org/apache/james/webadmin/mdc/RequestIdTest.java (89%)


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


[james-project] 02/07: JAMES-2233 Correlate request and response logging using a requestId

Posted by bt...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

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

commit 5e0baaa48b351594b65bfd635a9d38c401483fa5
Author: Benoit Tellier <bt...@linagora.com>
AuthorDate: Tue May 7 10:38:04 2019 +0700

    JAMES-2233 Correlate request and response logging using a requestId
---
 .../james/webadmin/mdc/LoggingRequestFilter.java   |  6 ++
 .../james/webadmin/mdc/LoggingResponseFilter.java  |  4 ++
 .../{LoggingRequestFilter.java => RequestId.java}  | 67 ++++++++++++++--------
 .../apache/james/webadmin/mdc/RequestIdTest.java}  | 36 +++---------
 4 files changed, 60 insertions(+), 53 deletions(-)

diff --git a/server/protocols/webadmin/webadmin-core/src/main/java/org/apache/james/webadmin/mdc/LoggingRequestFilter.java b/server/protocols/webadmin/webadmin-core/src/main/java/org/apache/james/webadmin/mdc/LoggingRequestFilter.java
index fac1e90..32ef13e 100644
--- a/server/protocols/webadmin/webadmin-core/src/main/java/org/apache/james/webadmin/mdc/LoggingRequestFilter.java
+++ b/server/protocols/webadmin/webadmin-core/src/main/java/org/apache/james/webadmin/mdc/LoggingRequestFilter.java
@@ -38,10 +38,16 @@ public class LoggingRequestFilter implements Filter {
     static final String ENDPOINT = "endpoint";
     static final String QUERY_PARAMETERS = "queryParameters";
     static final String IP = "ip";
+    static final String REQUEST_ID = "requestId";
 
     @Override
     public void handle(Request request, Response response) {
+        RequestId requestId = RequestId.random();
+
+        request.attribute(REQUEST_ID, requestId);
+
         MDCStructuredLogger.forLogger(LOGGER)
+            .addField(REQUEST_ID, requestId.asString())
             .addField(IP, request.ip())
             .addField(ENDPOINT, request.url())
             .addField(METHOD, request.requestMethod())
diff --git a/server/protocols/webadmin/webadmin-core/src/main/java/org/apache/james/webadmin/mdc/LoggingResponseFilter.java b/server/protocols/webadmin/webadmin-core/src/main/java/org/apache/james/webadmin/mdc/LoggingResponseFilter.java
index cffc7a5..39b99a9 100644
--- a/server/protocols/webadmin/webadmin-core/src/main/java/org/apache/james/webadmin/mdc/LoggingResponseFilter.java
+++ b/server/protocols/webadmin/webadmin-core/src/main/java/org/apache/james/webadmin/mdc/LoggingResponseFilter.java
@@ -24,6 +24,7 @@ import static org.apache.james.webadmin.mdc.LoggingRequestFilter.ENDPOINT;
 import static org.apache.james.webadmin.mdc.LoggingRequestFilter.IP;
 import static org.apache.james.webadmin.mdc.LoggingRequestFilter.METHOD;
 import static org.apache.james.webadmin.mdc.LoggingRequestFilter.QUERY_PARAMETERS;
+import static org.apache.james.webadmin.mdc.LoggingRequestFilter.REQUEST_ID;
 
 import org.apache.james.util.MDCStructuredLogger;
 import org.slf4j.Logger;
@@ -42,7 +43,10 @@ public class LoggingResponseFilter implements Filter {
 
     @Override
     public void handle(Request request, Response response) {
+        RequestId requestId = request.attribute(REQUEST_ID);
+
         MDCStructuredLogger.forLogger(LOGGER)
+            .addField(REQUEST_ID, requestId.asString())
             .addField(IP, request.ip())
             .addField(ENDPOINT, request.url())
             .addField(METHOD, request.requestMethod())
diff --git a/server/protocols/webadmin/webadmin-core/src/main/java/org/apache/james/webadmin/mdc/LoggingRequestFilter.java b/server/protocols/webadmin/webadmin-core/src/main/java/org/apache/james/webadmin/mdc/RequestId.java
similarity index 51%
copy from server/protocols/webadmin/webadmin-core/src/main/java/org/apache/james/webadmin/mdc/LoggingRequestFilter.java
copy to server/protocols/webadmin/webadmin-core/src/main/java/org/apache/james/webadmin/mdc/RequestId.java
index fac1e90..e85e130 100644
--- a/server/protocols/webadmin/webadmin-core/src/main/java/org/apache/james/webadmin/mdc/LoggingRequestFilter.java
+++ b/server/protocols/webadmin/webadmin-core/src/main/java/org/apache/james/webadmin/mdc/RequestId.java
@@ -19,35 +19,54 @@
 
 package org.apache.james.webadmin.mdc;
 
-import static org.apache.james.webadmin.authentication.AuthenticationFilter.LOGIN;
+import java.util.Objects;
+import java.util.UUID;
 
-import org.apache.james.util.MDCStructuredLogger;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
+import com.google.common.base.Preconditions;
 
-import com.google.common.collect.ImmutableSet;
+public class RequestId {
+    public static RequestId random() {
+        return of(UUID.randomUUID());
+    }
+
+    public static RequestId of(UUID uuid) {
+        Preconditions.checkNotNull(uuid, "'uuid' can not be null");
+
+        return new RequestId(uuid);
+    }
+
+    public static RequestId of(String uuid) {
+        Preconditions.checkNotNull(uuid, "'uuid' can not be null");
+
+        return new RequestId(UUID.fromString(uuid));
+    }
+
+    private final UUID uuid;
 
-import spark.Filter;
-import spark.Request;
-import spark.Response;
+    private RequestId(UUID uuid) {
+        this.uuid = uuid;
+    }
+
+    public UUID getUuid() {
+        return uuid;
+    }
+
+    public String asString() {
+        return uuid.toString();
+    }
+
+    @Override
+    public final boolean equals(Object o) {
+        if (o instanceof RequestId) {
+            RequestId requestId = (RequestId) o;
 
-public class LoggingRequestFilter implements Filter {
-    private static final Logger LOGGER = LoggerFactory.getLogger(LoggingRequestFilter.class);
-    static final String REQUEST_BODY = "request-body";
-    static final String METHOD = "method";
-    static final String ENDPOINT = "endpoint";
-    static final String QUERY_PARAMETERS = "queryParameters";
-    static final String IP = "ip";
+            return Objects.equals(this.uuid, requestId.uuid);
+        }
+        return false;
+    }
 
     @Override
-    public void handle(Request request, Response response) {
-        MDCStructuredLogger.forLogger(LOGGER)
-            .addField(IP, request.ip())
-            .addField(ENDPOINT, request.url())
-            .addField(METHOD, request.requestMethod())
-            .addField(LOGIN, request.attribute(LOGIN))
-            .addField(QUERY_PARAMETERS, ImmutableSet.copyOf(request.queryParams()))
-            .addField(REQUEST_BODY, request.body())
-            .log(logger -> logger.info("WebAdmin request received"));
+    public final int hashCode() {
+        return Objects.hash(uuid);
     }
 }
diff --git a/server/protocols/webadmin/webadmin-core/src/main/java/org/apache/james/webadmin/mdc/LoggingRequestFilter.java b/server/protocols/webadmin/webadmin-core/src/test/java/org/apache/james/webadmin/mdc/RequestIdTest.java
similarity index 50%
copy from server/protocols/webadmin/webadmin-core/src/main/java/org/apache/james/webadmin/mdc/LoggingRequestFilter.java
copy to server/protocols/webadmin/webadmin-core/src/test/java/org/apache/james/webadmin/mdc/RequestIdTest.java
index fac1e90..0eaad31 100644
--- a/server/protocols/webadmin/webadmin-core/src/main/java/org/apache/james/webadmin/mdc/LoggingRequestFilter.java
+++ b/server/protocols/webadmin/webadmin-core/src/test/java/org/apache/james/webadmin/mdc/RequestIdTest.java
@@ -19,35 +19,13 @@
 
 package org.apache.james.webadmin.mdc;
 
-import static org.apache.james.webadmin.authentication.AuthenticationFilter.LOGIN;
+import org.junit.Test;
 
-import org.apache.james.util.MDCStructuredLogger;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
+import nl.jqno.equalsverifier.EqualsVerifier;
 
-import com.google.common.collect.ImmutableSet;
-
-import spark.Filter;
-import spark.Request;
-import spark.Response;
-
-public class LoggingRequestFilter implements Filter {
-    private static final Logger LOGGER = LoggerFactory.getLogger(LoggingRequestFilter.class);
-    static final String REQUEST_BODY = "request-body";
-    static final String METHOD = "method";
-    static final String ENDPOINT = "endpoint";
-    static final String QUERY_PARAMETERS = "queryParameters";
-    static final String IP = "ip";
-
-    @Override
-    public void handle(Request request, Response response) {
-        MDCStructuredLogger.forLogger(LOGGER)
-            .addField(IP, request.ip())
-            .addField(ENDPOINT, request.url())
-            .addField(METHOD, request.requestMethod())
-            .addField(LOGIN, request.attribute(LOGIN))
-            .addField(QUERY_PARAMETERS, ImmutableSet.copyOf(request.queryParams()))
-            .addField(REQUEST_BODY, request.body())
-            .log(logger -> logger.info("WebAdmin request received"));
+public class RequestIdTest {
+    @Test
+    public void shouldMatchBeanContract() {
+        EqualsVerifier.forClass(RequestId.class).verify();
     }
-}
+}
\ 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] 04/07: JAMES-2743 JMAP Search Doesn't support From field with UTF8 characters

Posted by bt...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

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

commit 1b19a733a9c7f2720a9b9d949ee1461c6fc5e9c6
Author: Tran Tien Duc <dt...@linagora.com>
AuthorDate: Fri Apr 26 17:47:25 2019 +0700

    JAMES-2743 JMAP Search Doesn't support From field with UTF8 characters
---
 .../elasticsearch/json/HeaderCollectionTest.java   | 29 ++++++--
 .../integration/GetMessageListMethodTest.java      | 78 ++++++++++++++++++++++
 2 files changed, 103 insertions(+), 4 deletions(-)

diff --git a/mailbox/elasticsearch/src/test/java/org/apache/james/mailbox/elasticsearch/json/HeaderCollectionTest.java b/mailbox/elasticsearch/src/test/java/org/apache/james/mailbox/elasticsearch/json/HeaderCollectionTest.java
index 586ab14..db73f08 100644
--- a/mailbox/elasticsearch/src/test/java/org/apache/james/mailbox/elasticsearch/json/HeaderCollectionTest.java
+++ b/mailbox/elasticsearch/src/test/java/org/apache/james/mailbox/elasticsearch/json/HeaderCollectionTest.java
@@ -23,11 +23,30 @@ import static org.assertj.core.api.Assertions.assertThat;
 import static org.assertj.core.api.Assertions.assertThatThrownBy;
 
 import java.time.format.DateTimeFormatter;
+import java.util.stream.Stream;
 
+import org.junit.jupiter.api.Disabled;
 import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.ExtensionContext;
+import org.junit.jupiter.params.ParameterizedTest;
+import org.junit.jupiter.params.provider.Arguments;
+import org.junit.jupiter.params.provider.ArgumentsProvider;
+import org.junit.jupiter.params.provider.ArgumentsSource;
 
 class HeaderCollectionTest {
 
+    static class UTF8FromHeaderTestSource implements ArgumentsProvider {
+
+        @Override
+        public Stream<? extends Arguments> provideArguments(ExtensionContext context) throws Exception {
+            return Stream.of(
+                Arguments.of("=?UTF-8?B?RnLDqWTDqXJpYyBNQVJUSU4=?= <fm...@linagora.com>, Graham CROSMARIE <gc...@linagora.com>", "Frédéric MARTIN"),
+                Arguments.of("=?UTF-8?Q?=C3=9Csteli=C4=9Fhan_Ma=C5=9Frapa?= <us...@domain.tld>", "Üsteliğhan Maşrapa"),
+                Arguments.of("=?UTF-8?Q?Ke=C5=9Ffet_Turizm?= <ke...@domain.tld>", "Keşfet Turizm"),
+                Arguments.of("=?UTF-8?Q?MODAL=C4=B0F?= <mo...@domain.tld>", "MODALİF"));
+        }
+    }
+
     private static final DateTimeFormatter DATE_TIME_FORMATTER = DateTimeFormatter.ofPattern("yyyy/MM/dd HH:mm:ss");
 
     @Test
@@ -75,15 +94,17 @@ class HeaderCollectionTest {
             .containsOnly(new EMailer("Christophe Hamerling", "chri.hamerling@linagora.com"));
     }
 
-    @Test
-    void displayNamesShouldBeRetrievedWhenEncodedWord() {
+    @Disabled("JAMES-2743 HeaderCollection doesn't support Q encoding")
+    @ParameterizedTest
+    @ArgumentsSource(UTF8FromHeaderTestSource.class)
+    void displayNamesShouldBeRetrievedWhenEncodedWord(String encodedFromHeader, String nameOfFromAddress) {
         HeaderCollection headerCollection = HeaderCollection.builder()
-            .add(new FieldImpl("From", "=?UTF-8?B?RnLDqWTDqXJpYyBNQVJUSU4=?= <fr...@linagora.com>, Graham CROSMARIE <gr...@linagora.com>"))
+            .add(new FieldImpl("From", encodedFromHeader))
             .build();
 
         assertThat(headerCollection.getFromAddressSet())
             .extracting(EMailer::getName)
-            .contains("Frédéric MARTIN");
+            .contains(nameOfFromAddress);
     }
 
     @Test
diff --git a/server/protocols/jmap-integration-testing/jmap-integration-testing-common/src/test/java/org/apache/james/jmap/methods/integration/GetMessageListMethodTest.java b/server/protocols/jmap-integration-testing/jmap-integration-testing-common/src/test/java/org/apache/james/jmap/methods/integration/GetMessageListMethodTest.java
index 640d893..ce45654 100644
--- a/server/protocols/jmap-integration-testing/jmap-integration-testing-common/src/test/java/org/apache/james/jmap/methods/integration/GetMessageListMethodTest.java
+++ b/server/protocols/jmap-integration-testing/jmap-integration-testing-common/src/test/java/org/apache/james/jmap/methods/integration/GetMessageListMethodTest.java
@@ -22,6 +22,7 @@ package org.apache.james.jmap.methods.integration;
 import static io.restassured.RestAssured.given;
 import static io.restassured.RestAssured.with;
 import static org.apache.james.jmap.HttpJmapAuthentication.authenticateJamesUser;
+import static org.apache.james.jmap.JmapCommonRequests.getOutboxId;
 import static org.apache.james.jmap.JmapURIBuilder.baseUri;
 import static org.apache.james.jmap.TestingConstants.ALICE;
 import static org.apache.james.jmap.TestingConstants.ALICE_PASSWORD;
@@ -33,6 +34,7 @@ import static org.apache.james.jmap.TestingConstants.NAME;
 import static org.apache.james.jmap.TestingConstants.calmlyAwait;
 import static org.apache.james.jmap.TestingConstants.jmapRequestSpecBuilder;
 import static org.apache.james.transport.mailets.remote.delivery.HeloNameProvider.LOCALHOST;
+import static org.assertj.core.api.Assertions.assertThat;
 import static org.hamcrest.Matchers.allOf;
 import static org.hamcrest.Matchers.contains;
 import static org.hamcrest.Matchers.containsInAnyOrder;
@@ -57,6 +59,7 @@ import org.apache.james.jmap.api.access.AccessToken;
 import org.apache.james.jmap.categories.BasicFeature;
 import org.apache.james.jmap.categories.CassandraAndElasticSearchCategory;
 import org.apache.james.jmap.model.Number;
+import org.apache.james.mailbox.DefaultMailboxes;
 import org.apache.james.mailbox.FlagsBuilder;
 import org.apache.james.mailbox.MessageManager;
 import org.apache.james.mailbox.model.ComposedMessageId;
@@ -80,6 +83,8 @@ import org.apache.james.util.date.ImapDateTimeFormatter;
 import org.apache.james.utils.DataProbeImpl;
 import org.apache.james.utils.IMAPMessageReader;
 import org.apache.james.utils.JmapGuiceProbe;
+import org.awaitility.Duration;
+import org.hamcrest.Matchers;
 import org.junit.After;
 import org.junit.Before;
 import org.junit.Test;
@@ -206,6 +211,79 @@ public abstract class GetMessageListMethodTest {
             .body(ARGUMENTS + ".messageIds", contains(messageId));
     }
 
+    @Category(BasicFeature.class)
+    @Test
+    public void searchByFromFieldDoesntSupportUTF8FromName() throws Exception {
+        String toUsername = "username1@" + DOMAIN;
+        String password = "password";
+        dataProbe.addUser(toUsername, password);
+        mailboxProbe.createMailbox(MailboxConstants.USER_NAMESPACE, toUsername, DefaultMailboxes.INBOX);
+
+        String messageCreationId = "creationId1337";
+        String fromName = "Üsteliğhan Maşrapa";
+        String fromAddress = ALICE;
+        String requestBody = "[" +
+            "  [" +
+            "    \"setMessages\"," +
+            "    {" +
+            "      \"create\": { \"" + messageCreationId  + "\" : {" +
+            "        \"from\": { \"name\": \"" + fromName + "\", \"email\": \"" + fromAddress + "\"}," +
+            "        \"to\": [{ \"name\": \"BOB\", \"email\": \"" + BOB + "\"}]," +
+            "        \"subject\": \"Thank you for joining example.com!\"," +
+            "        \"textBody\": \"Hello someone, and thank you for joining example.com!\"," +
+            "        \"mailboxIds\": [\"" + getOutboxId(aliceAccessToken) + "\"]" +
+            "      }}" +
+            "    }," +
+            "    \"#0\"" +
+            "  ]" +
+            "]";
+
+        String messageId = with()
+            .header("Authorization", aliceAccessToken.serialize())
+            .body(requestBody)
+            .post("/jmap")
+        .then()
+            .extract()
+            .body()
+            .path(ARGUMENTS + ".created." + messageCreationId + ".id");
+
+        calmlyAwait.atMost(Duration.TEN_SECONDS)
+            .until(() -> searchFirstMessageByFromField(fromAddress), Matchers.notNullValue());
+
+        assertThat(searchFirstMessageByFromField(fromName))
+            .isNull();
+    }
+
+    private String searchFirstMessageByFromField(String from) {
+        String searchRequest = "[" +
+            "  [" +
+            "    \"getMessageList\"," +
+            "    {" +
+            "      \"filter\": {" +
+            "        \"from\": \"" + from + "\"" +
+            "      }," +
+            "      \"sort\": [" +
+            "        \"date desc\"" +
+            "      ]," +
+            "      \"collapseThreads\": false," +
+            "      \"fetchMessages\": false," +
+            "      \"position\": 0," +
+            "      \"limit\": 1" +
+            "    }," +
+            "    \"#0\"" +
+            "  ]" +
+            "]";
+
+        return with()
+            .header("Authorization", aliceAccessToken.serialize())
+            .body(searchRequest)
+            .post("/jmap")
+        .then()
+            .statusCode(200)
+            .extract()
+            .path(ARGUMENTS + ".messageIds[0]");
+    }
+
     @Test
     public void getMessageListShouldListMessageThatHasBeenMovedInAMailboxWhereTheUserHasOnlyReadRight() throws Exception {
         MailboxId delegatedMailboxId = mailboxProbe.createMailbox(MailboxConstants.USER_NAMESPACE, BOB, "delegated");


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


[james-project] 01/07: JAMES-2233 Adding more context to WebAdmin audit logs

Posted by bt...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

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

commit 4f6eafb5d0415cbfae4649058ac364439aa3dfdd
Author: Benoit Tellier <bt...@linagora.com>
AuthorDate: Tue May 7 10:29:16 2019 +0700

    JAMES-2233 Adding more context to WebAdmin audit logs
---
 .../apache/james/webadmin/mdc/LoggingRequestFilter.java | 17 +++++++++++++++--
 .../james/webadmin/mdc/LoggingResponseFilter.java       | 15 ++++++++++++++-
 2 files changed, 29 insertions(+), 3 deletions(-)

diff --git a/server/protocols/webadmin/webadmin-core/src/main/java/org/apache/james/webadmin/mdc/LoggingRequestFilter.java b/server/protocols/webadmin/webadmin-core/src/main/java/org/apache/james/webadmin/mdc/LoggingRequestFilter.java
index 08a6e5e..fac1e90 100644
--- a/server/protocols/webadmin/webadmin-core/src/main/java/org/apache/james/webadmin/mdc/LoggingRequestFilter.java
+++ b/server/protocols/webadmin/webadmin-core/src/main/java/org/apache/james/webadmin/mdc/LoggingRequestFilter.java
@@ -19,21 +19,34 @@
 
 package org.apache.james.webadmin.mdc;
 
+import static org.apache.james.webadmin.authentication.AuthenticationFilter.LOGIN;
+
 import org.apache.james.util.MDCStructuredLogger;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
+import com.google.common.collect.ImmutableSet;
+
 import spark.Filter;
 import spark.Request;
 import spark.Response;
 
 public class LoggingRequestFilter implements Filter {
     private static final Logger LOGGER = LoggerFactory.getLogger(LoggingRequestFilter.class);
-    private static final String REQUEST_BODY = "request-body";
+    static final String REQUEST_BODY = "request-body";
+    static final String METHOD = "method";
+    static final String ENDPOINT = "endpoint";
+    static final String QUERY_PARAMETERS = "queryParameters";
+    static final String IP = "ip";
 
     @Override
-    public void handle(Request request, Response response) throws Exception {
+    public void handle(Request request, Response response) {
         MDCStructuredLogger.forLogger(LOGGER)
+            .addField(IP, request.ip())
+            .addField(ENDPOINT, request.url())
+            .addField(METHOD, request.requestMethod())
+            .addField(LOGIN, request.attribute(LOGIN))
+            .addField(QUERY_PARAMETERS, ImmutableSet.copyOf(request.queryParams()))
             .addField(REQUEST_BODY, request.body())
             .log(logger -> logger.info("WebAdmin request received"));
     }
diff --git a/server/protocols/webadmin/webadmin-core/src/main/java/org/apache/james/webadmin/mdc/LoggingResponseFilter.java b/server/protocols/webadmin/webadmin-core/src/main/java/org/apache/james/webadmin/mdc/LoggingResponseFilter.java
index ebe4ff5..cffc7a5 100644
--- a/server/protocols/webadmin/webadmin-core/src/main/java/org/apache/james/webadmin/mdc/LoggingResponseFilter.java
+++ b/server/protocols/webadmin/webadmin-core/src/main/java/org/apache/james/webadmin/mdc/LoggingResponseFilter.java
@@ -19,10 +19,18 @@
 
 package org.apache.james.webadmin.mdc;
 
+import static org.apache.james.webadmin.authentication.AuthenticationFilter.LOGIN;
+import static org.apache.james.webadmin.mdc.LoggingRequestFilter.ENDPOINT;
+import static org.apache.james.webadmin.mdc.LoggingRequestFilter.IP;
+import static org.apache.james.webadmin.mdc.LoggingRequestFilter.METHOD;
+import static org.apache.james.webadmin.mdc.LoggingRequestFilter.QUERY_PARAMETERS;
+
 import org.apache.james.util.MDCStructuredLogger;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
+import com.google.common.collect.ImmutableSet;
+
 import spark.Filter;
 import spark.Request;
 import spark.Response;
@@ -33,8 +41,13 @@ public class LoggingResponseFilter implements Filter {
     private static final String RESPONSE_BODY = "response-body";
 
     @Override
-    public void handle(Request request, Response response) throws Exception {
+    public void handle(Request request, Response response) {
         MDCStructuredLogger.forLogger(LOGGER)
+            .addField(IP, request.ip())
+            .addField(ENDPOINT, request.url())
+            .addField(METHOD, request.requestMethod())
+            .addField(LOGIN, request.attribute(LOGIN))
+            .addField(QUERY_PARAMETERS, ImmutableSet.copyOf(request.queryParams()))
             .addField(STATUS, response.status())
             .addField(RESPONSE_BODY, response.body())
             .log(logger -> logger.info("WebAdmin response received"));


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


[james-project] 07/07: JAMES-2744 James download should provide Content-Type header

Posted by bt...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

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

commit e7d55850526ca94f6a86b63fd47dd2aad7518108
Author: Tran Tien Duc <dt...@linagora.com>
AuthorDate: Thu May 2 17:26:33 2019 +0700

    JAMES-2744 James download should provide Content-Type header
---
 .../org/apache/james/util/InputStreamUtils.java    | 34 ++++++++++++++
 .../apache/james/util/InputStreamUtilsTest.java    | 53 ++++++++++++++++++++++
 .../integration/cucumber/DownloadStepdefs.java     | 22 ++++++---
 .../test/resources/cucumber/DownloadGet.feature    |  4 +-
 .../src/test/resources/eml/oneAttachment-part1.eml | 30 ++++++++++++
 .../src/test/resources/eml/oneAttachment-part2.eml |  9 ++++
 .../org/apache/james/jmap/DownloadServlet.java     |  1 +
 7 files changed, 145 insertions(+), 8 deletions(-)

diff --git a/server/container/util/src/main/java/org/apache/james/util/InputStreamUtils.java b/server/container/util/src/main/java/org/apache/james/util/InputStreamUtils.java
new file mode 100644
index 0000000..d522965
--- /dev/null
+++ b/server/container/util/src/main/java/org/apache/james/util/InputStreamUtils.java
@@ -0,0 +1,34 @@
+/****************************************************************
+ * 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.util;
+
+import java.io.InputStream;
+import java.io.SequenceInputStream;
+import java.util.Arrays;
+import java.util.stream.Stream;
+
+public class InputStreamUtils {
+    public static InputStream concat(InputStream inputStream, InputStream... additionalInputStreams) {
+        Stream<InputStream> inputStreams = Stream.concat(Stream.of(inputStream), Arrays.stream(additionalInputStreams));
+
+        return inputStreams.reduce(SequenceInputStream::new)
+            .get();
+    }
+}
diff --git a/server/container/util/src/test/java/org/apache/james/util/InputStreamUtilsTest.java b/server/container/util/src/test/java/org/apache/james/util/InputStreamUtilsTest.java
new file mode 100644
index 0000000..7ed1f97
--- /dev/null
+++ b/server/container/util/src/test/java/org/apache/james/util/InputStreamUtilsTest.java
@@ -0,0 +1,53 @@
+/****************************************************************
+ * 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.util;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+import java.io.ByteArrayInputStream;
+import java.nio.charset.StandardCharsets;
+
+import org.junit.jupiter.api.Test;
+
+import com.google.common.primitives.Bytes;
+
+class InputStreamUtilsTest {
+    private static final byte[] CONTENT_1 = "content1".getBytes(StandardCharsets.UTF_8);
+    private static final byte[] CONTENT_2 = "content2".getBytes(StandardCharsets.UTF_8);
+    private static final byte[] EMPTY = "".getBytes(StandardCharsets.UTF_8);
+
+    @Test
+    void concatShouldNoopWhenSingleArgument() {
+        assertThat(InputStreamUtils.concat(new ByteArrayInputStream(CONTENT_1)))
+            .hasSameContentAs(new ByteArrayInputStream(CONTENT_1));
+    }
+
+    @Test
+    void concatShouldReturnConcatenatedStreams() {
+        assertThat(InputStreamUtils.concat(new ByteArrayInputStream(CONTENT_1), new ByteArrayInputStream(CONTENT_2)))
+            .hasSameContentAs(new ByteArrayInputStream(Bytes.concat(CONTENT_1, CONTENT_2)));
+    }
+
+    @Test
+    void concatShouldNoopWhenEmpty() {
+        assertThat(InputStreamUtils.concat(new ByteArrayInputStream(CONTENT_1), new ByteArrayInputStream(EMPTY)))
+            .hasSameContentAs(new ByteArrayInputStream(CONTENT_1));
+    }
+}
\ No newline at end of file
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 b1450a0..8abff9d 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
@@ -24,6 +24,7 @@ import static org.assertj.core.api.Assertions.assertThat;
 
 import java.io.ByteArrayInputStream;
 import java.io.IOException;
+import java.io.InputStream;
 import java.net.URI;
 import java.net.URISyntaxException;
 import java.nio.charset.StandardCharsets;
@@ -49,6 +50,7 @@ import org.apache.james.mailbox.model.MailboxConstants;
 import org.apache.james.mailbox.model.MailboxPath;
 import org.apache.james.mailbox.model.MessageId;
 import org.apache.james.mime4j.codec.DecoderUtil;
+import org.apache.james.util.InputStreamUtils;
 
 import com.google.common.base.CharMatcher;
 import com.google.common.base.MoreObjects;
@@ -126,6 +128,20 @@ public class DownloadStepdefs {
         retrieveAndSaveAttachmentDetails(user, messageId, attachmentId, composedMessageId);
     }
 
+    @Given("^\"([^\"]*)\" mailbox \"([^\"]*)\" contains a message \"([^\"]*)\" with an attachment \"([^\"]*)\" having \"([^\"]*)\" contentType$")
+    public void appendMessageWithAttachmentToMailbox(String user, String mailbox, String messageId, String attachmentId, String contentType) throws Throwable {
+        MailboxPath mailboxPath = MailboxPath.forUser(user, mailbox);
+
+        InputStream message = InputStreamUtils.concat(
+            ClassLoader.getSystemResourceAsStream("eml/oneAttachment-part1.eml"),
+            new ByteArrayInputStream(contentType.getBytes(StandardCharsets.UTF_8)),
+            ClassLoader.getSystemResourceAsStream("eml/oneAttachment-part2.eml"));
+
+        ComposedMessageId composedMessageId = mainStepdefs.mailboxProbe.appendMessage(user, mailboxPath, AppendCommand.from(message));
+
+        retrieveAndSaveAttachmentDetails(user, messageId, attachmentId, composedMessageId);
+    }
+
     @Given("^\"([^\"]*)\" mailbox \"([^\"]*)\" contains a message \"([^\"]*)\" with an inlined attachment \"([^\"]*)\"$")
     public void appendMessageWithInlinedAttachmentToMailbox(String user, String mailbox, String messageId, String attachmentId) throws Throwable {
         MailboxPath mailboxPath = MailboxPath.forUser(user, mailbox);
@@ -456,12 +472,6 @@ public class DownloadStepdefs {
         assertThat(response.getFirstHeader("Content-Length").getValue()).isEqualTo(String.valueOf(size));
     }
 
-    @Then("^there is no Content-Type$")
-    public void assertNoContentType() {
-        assertThat(response.getFirstHeader("Content-Type"))
-            .isNull();
-    }
-
     @Then("^the Content-Type is \"([^\"]*)\"$")
     public void assertContentType(String contentType) {
         assertThat(response.getFirstHeader("Content-Type").getValue()).isEqualTo(contentType);
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
index 4b7c889..2639d86 100644
--- 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
@@ -51,10 +51,10 @@ Feature: Download GET
     And the attachment is named "ديناصور.odt"
 
   Scenario: Getting an attachment with a specified Content-Type
-    Given "alice@domain.tld" mailbox "INBOX" contains a message "1" with an attachment "2"
+    Given "alice@domain.tld" mailbox "INBOX" contains a message "1" with an attachment "2" having "application/pdf" contentType
     When "alice@domain.tld" downloads "2" with "myFileName.txt" name
     Then she can read that blob
-    And there is no Content-Type
+    And the Content-Type is "application/pdf"
 
   @BasicFeature
   Scenario: Getting a message blob previously stored
diff --git a/server/protocols/jmap-integration-testing/jmap-integration-testing-common/src/test/resources/eml/oneAttachment-part1.eml b/server/protocols/jmap-integration-testing/jmap-integration-testing-common/src/test/resources/eml/oneAttachment-part1.eml
new file mode 100644
index 0000000..1c7df76
--- /dev/null
+++ b/server/protocols/jmap-integration-testing/jmap-integration-testing-common/src/test/resources/eml/oneAttachment-part1.eml
@@ -0,0 +1,30 @@
+Mail content:
+To: "=?utf-8?B?UmFuaSBBc3NhZg==?=" <ra...@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:
\ No newline at end of file
diff --git a/server/protocols/jmap-integration-testing/jmap-integration-testing-common/src/test/resources/eml/oneAttachment-part2.eml b/server/protocols/jmap-integration-testing/jmap-integration-testing-common/src/test/resources/eml/oneAttachment-part2.eml
new file mode 100644
index 0000000..2e81c80
--- /dev/null
+++ b/server/protocols/jmap-integration-testing/jmap-integration-testing-common/src/test/resources/eml/oneAttachment-part2.eml
@@ -0,0 +1,9 @@
+
+Content-Transfer-Encoding: base64
+Content-Disposition: attachment;
+	filename="gimp.png"
+
+iVBORw0KGgoAAAANSUhEUgAAADAAAAAwCAYAAABXAvmHAAALxklEQVR4Ae2Xe0xUZ97H5X4RiyAXEARURBSYCzNnLjMwwAx3huGOIBcUFJERAUVRq+KlwHABFdu+b9+0766x1W21ttnUtE3rul6aGNtm3XbdWncjaa3VXrZRK6IgfPd3Tp6wOGmyo0v/cOMknxwy5xzO7/P8LueZaWlpaU80TwWeCvy3CcRwXJlUqp39RApIOE4i5hQPxBz30hMpIJIrjktkseMimfzPUyoglilTf/XVl8u1Ik4xrOJEEMu4wSkVEMmVZ6VSTeivFXy0TDZfIlfc0qil0KpIQM59P6UCUk71lVShPD1t2jT7qQ4+Sq32prq/GhfHjSXFSxGvEfMCQ1MsoLzOadT3pArFwBQ3LSdRqK4mJyfcz0xRwaCLRVKcBDEybmxqBRTKH8uXpEOj0/1MD3wuMTHR8T9adY4LoOD3KuPj7xYVGlGYo0e6 [...]
+
+------=_Part_0_1330682067197--
+
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 6e2b272..ca317fd 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
@@ -127,6 +127,7 @@ public class DownloadServlet extends HttpServlet {
 
             addContentDispositionHeader(downloadPath.getName(), resp);
             resp.setHeader("Content-Length", String.valueOf(blob.getSize()));
+            resp.setHeader("Content-Type", blob.getContentType());
             resp.setStatus(SC_OK);
             IOUtils.copy(blob.getStream(), resp.getOutputStream());
         } catch (BlobNotFoundException e) {


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


[james-project] 05/07: JAMES-2743 Need HeaderCollection to use encoded(raw) value when parsing

Posted by bt...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

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

commit 4b3d611e7c71af3ddc0ce790e5cfa070dc06ba33
Author: Tran Tien Duc <dt...@linagora.com>
AuthorDate: Fri Apr 26 18:54:47 2019 +0700

    JAMES-2743 Need HeaderCollection to use encoded(raw) value when parsing
---
 .../james/mailbox/elasticsearch/json/HeaderCollection.java  | 13 +++++++------
 .../mailbox/elasticsearch/json/HeaderCollectionTest.java    |  2 --
 .../jmap/methods/integration/GetMessageListMethodTest.java  | 10 +++++-----
 .../james/jmap/memory/MemoryGetMessageListMethodTest.java   |  7 +++++++
 4 files changed, 19 insertions(+), 13 deletions(-)

diff --git a/mailbox/elasticsearch/src/main/java/org/apache/james/mailbox/elasticsearch/json/HeaderCollection.java b/mailbox/elasticsearch/src/main/java/org/apache/james/mailbox/elasticsearch/json/HeaderCollection.java
index 4782f74..f007e69 100644
--- a/mailbox/elasticsearch/src/main/java/org/apache/james/mailbox/elasticsearch/json/HeaderCollection.java
+++ b/mailbox/elasticsearch/src/main/java/org/apache/james/mailbox/elasticsearch/json/HeaderCollection.java
@@ -71,12 +71,13 @@ public class HeaderCollection {
         public Builder add(Field field) {
             Preconditions.checkNotNull(field);
             String headerName = field.getName().toLowerCase(Locale.US);
-            String sanitizedValue = MimeUtil.unscrambleHeaderValue(field.getBody());
+            String rawHeaderValue = field.getBody();
+            String sanitizedValue = MimeUtil.unscrambleHeaderValue(rawHeaderValue);
 
             if (!headerName.contains(".")) {
                 headers.put(headerName, sanitizedValue);
             }
-            handleSpecificHeader(headerName, sanitizedValue);
+            handleSpecificHeader(headerName, sanitizedValue, rawHeaderValue);
             return this;
         }
 
@@ -92,14 +93,14 @@ public class HeaderCollection {
                 sentDate, messageID);
         }
 
-        private void handleSpecificHeader(String headerName, String headerValue) {
+        private void handleSpecificHeader(String headerName, String headerValue, String rawHeaderValue) {
             switch (headerName) {
                 case TO:
                 case FROM:
                 case CC:
                 case BCC:
                 case REPLY_TO:
-                    manageAddressField(headerName, headerValue);
+                    manageAddressField(headerName, rawHeaderValue);
                     break;
                 case SUBJECT:
                     subjectSet.add(headerValue);
@@ -113,9 +114,9 @@ public class HeaderCollection {
             }
         }
 
-        private void manageAddressField(String headerName, String headerValue) {
+        private void manageAddressField(String headerName, String rawHeaderValue) {
             LenientAddressParser.DEFAULT
-                .parseAddressList(headerValue)
+                .parseAddressList(rawHeaderValue)
                 .stream()
                 .flatMap(this::convertAddressToMailboxStream)
                 .map((mailbox) -> new EMailer(SearchUtil.getDisplayAddress(mailbox), mailbox.getAddress()))
diff --git a/mailbox/elasticsearch/src/test/java/org/apache/james/mailbox/elasticsearch/json/HeaderCollectionTest.java b/mailbox/elasticsearch/src/test/java/org/apache/james/mailbox/elasticsearch/json/HeaderCollectionTest.java
index db73f08..647bdf8 100644
--- a/mailbox/elasticsearch/src/test/java/org/apache/james/mailbox/elasticsearch/json/HeaderCollectionTest.java
+++ b/mailbox/elasticsearch/src/test/java/org/apache/james/mailbox/elasticsearch/json/HeaderCollectionTest.java
@@ -25,7 +25,6 @@ import static org.assertj.core.api.Assertions.assertThatThrownBy;
 import java.time.format.DateTimeFormatter;
 import java.util.stream.Stream;
 
-import org.junit.jupiter.api.Disabled;
 import org.junit.jupiter.api.Test;
 import org.junit.jupiter.api.extension.ExtensionContext;
 import org.junit.jupiter.params.ParameterizedTest;
@@ -94,7 +93,6 @@ class HeaderCollectionTest {
             .containsOnly(new EMailer("Christophe Hamerling", "chri.hamerling@linagora.com"));
     }
 
-    @Disabled("JAMES-2743 HeaderCollection doesn't support Q encoding")
     @ParameterizedTest
     @ArgumentsSource(UTF8FromHeaderTestSource.class)
     void displayNamesShouldBeRetrievedWhenEncodedWord(String encodedFromHeader, String nameOfFromAddress) {
diff --git a/server/protocols/jmap-integration-testing/jmap-integration-testing-common/src/test/java/org/apache/james/jmap/methods/integration/GetMessageListMethodTest.java b/server/protocols/jmap-integration-testing/jmap-integration-testing-common/src/test/java/org/apache/james/jmap/methods/integration/GetMessageListMethodTest.java
index ce45654..1ac3d65 100644
--- a/server/protocols/jmap-integration-testing/jmap-integration-testing-common/src/test/java/org/apache/james/jmap/methods/integration/GetMessageListMethodTest.java
+++ b/server/protocols/jmap-integration-testing/jmap-integration-testing-common/src/test/java/org/apache/james/jmap/methods/integration/GetMessageListMethodTest.java
@@ -213,7 +213,7 @@ public abstract class GetMessageListMethodTest {
 
     @Category(BasicFeature.class)
     @Test
-    public void searchByFromFieldDoesntSupportUTF8FromName() throws Exception {
+    public void searchByFromFieldShouldSupportUTF8FromName() throws Exception {
         String toUsername = "username1@" + DOMAIN;
         String password = "password";
         dataProbe.addUser(toUsername, password);
@@ -247,11 +247,11 @@ public abstract class GetMessageListMethodTest {
             .body()
             .path(ARGUMENTS + ".created." + messageCreationId + ".id");
 
-        calmlyAwait.atMost(Duration.TEN_SECONDS)
-            .until(() -> searchFirstMessageByFromField(fromAddress), Matchers.notNullValue());
+        String searchedMessageId = calmlyAwait.atMost(Duration.TEN_SECONDS)
+            .until(() -> searchFirstMessageByFromField(fromName), Matchers.notNullValue());
 
-        assertThat(searchFirstMessageByFromField(fromName))
-            .isNull();
+        assertThat(searchedMessageId)
+            .isEqualTo(messageId);
     }
 
     private String searchFirstMessageByFromField(String from) {
diff --git a/server/protocols/jmap-integration-testing/memory-jmap-integration-testing/src/test/java/org/apache/james/jmap/memory/MemoryGetMessageListMethodTest.java b/server/protocols/jmap-integration-testing/memory-jmap-integration-testing/src/test/java/org/apache/james/jmap/memory/MemoryGetMessageListMethodTest.java
index 5871e88..589b007 100644
--- a/server/protocols/jmap-integration-testing/memory-jmap-integration-testing/src/test/java/org/apache/james/jmap/memory/MemoryGetMessageListMethodTest.java
+++ b/server/protocols/jmap-integration-testing/memory-jmap-integration-testing/src/test/java/org/apache/james/jmap/memory/MemoryGetMessageListMethodTest.java
@@ -49,4 +49,11 @@ public class MemoryGetMessageListMethodTest extends GetMessageListMethodTest {
     @Test
     public void getMessageListShouldIncludeMessagesWhenTextFilterMatchesBodyWithStemming() {
     }
+
+    @Override
+    @Ignore("JAMES-2756 Memory James Server uses the SimpleMessageSearchIndex, " +
+        "it doesn't support to search on the encoded header value's names")
+    @Test
+    public void searchByFromFieldShouldSupportUTF8FromName() {
+    }
 }


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


[james-project] 06/07: JAMES-2744 James download currently doesn't provide Content-Type header

Posted by bt...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

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

commit 7457846990213ef722f6a2447294714df101e1cb
Author: Tran Tien Duc <dt...@linagora.com>
AuthorDate: Thu May 2 17:24:50 2019 +0700

    JAMES-2744 James download currently doesn't provide Content-Type header
---
 .../jmap/methods/integration/cucumber/DownloadStepdefs.java   | 11 +++++++++++
 .../src/test/resources/cucumber/DownloadGet.feature           |  6 ++++++
 2 files changed, 17 insertions(+)

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 fefe803..b1450a0 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
@@ -456,6 +456,17 @@ public class DownloadStepdefs {
         assertThat(response.getFirstHeader("Content-Length").getValue()).isEqualTo(String.valueOf(size));
     }
 
+    @Then("^there is no Content-Type$")
+    public void assertNoContentType() {
+        assertThat(response.getFirstHeader("Content-Type"))
+            .isNull();
+    }
+
+    @Then("^the Content-Type is \"([^\"]*)\"$")
+    public void assertContentType(String contentType) {
+        assertThat(response.getFirstHeader("Content-Type").getValue()).isEqualTo(contentType);
+    }
+
     private void assertEncodedFilenameMatches(String name) {
         String contentDispositionHeader = response.getHeaders("Content-Disposition")[0].toString();
         assertThat(contentDispositionHeader).startsWith(UTF8_CONTENT_DIPOSITION_START);
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
index 2c225c7..4b7c889 100644
--- 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
@@ -50,6 +50,12 @@ Feature: Download GET
     Then she can read that blob
     And the attachment is named "ديناصور.odt"
 
+  Scenario: Getting an attachment with a specified Content-Type
+    Given "alice@domain.tld" mailbox "INBOX" contains a message "1" with an attachment "2"
+    When "alice@domain.tld" downloads "2" with "myFileName.txt" name
+    Then she can read that blob
+    And there is no Content-Type
+
   @BasicFeature
   Scenario: Getting a message blob previously stored
     Given "alice@domain.tld" mailbox "INBOX" contains a message "1"


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


[james-project] 03/07: JAMES-2743 HeaderCollectionTest JUNIT 5 migration

Posted by bt...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

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

commit 5439fd02fca8357af3734048e5b65b5510db0bb7
Author: Tran Tien Duc <dt...@linagora.com>
AuthorDate: Thu May 2 15:16:02 2019 +0700

    JAMES-2743 HeaderCollectionTest JUNIT 5 migration
---
 mailbox/elasticsearch/pom.xml                      |  5 ++
 .../elasticsearch/json/HeaderCollectionTest.java   | 64 +++++++++++-----------
 2 files changed, 38 insertions(+), 31 deletions(-)

diff --git a/mailbox/elasticsearch/pom.xml b/mailbox/elasticsearch/pom.xml
index b47a071..ba50010 100644
--- a/mailbox/elasticsearch/pom.xml
+++ b/mailbox/elasticsearch/pom.xml
@@ -166,6 +166,11 @@
             <scope>test</scope>
         </dependency>
         <dependency>
+            <groupId>org.junit.jupiter</groupId>
+            <artifactId>junit-jupiter-params</artifactId>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
             <groupId>org.mockito</groupId>
             <artifactId>mockito-core</artifactId>
             <scope>test</scope>
diff --git a/mailbox/elasticsearch/src/test/java/org/apache/james/mailbox/elasticsearch/json/HeaderCollectionTest.java b/mailbox/elasticsearch/src/test/java/org/apache/james/mailbox/elasticsearch/json/HeaderCollectionTest.java
index 9d10e7a..586ab14 100644
--- a/mailbox/elasticsearch/src/test/java/org/apache/james/mailbox/elasticsearch/json/HeaderCollectionTest.java
+++ b/mailbox/elasticsearch/src/test/java/org/apache/james/mailbox/elasticsearch/json/HeaderCollectionTest.java
@@ -20,17 +20,18 @@
 package org.apache.james.mailbox.elasticsearch.json;
 
 import static org.assertj.core.api.Assertions.assertThat;
+import static org.assertj.core.api.Assertions.assertThatThrownBy;
 
 import java.time.format.DateTimeFormatter;
 
-import org.junit.Test;
+import org.junit.jupiter.api.Test;
 
-public class HeaderCollectionTest {
+class HeaderCollectionTest {
 
     private static final DateTimeFormatter DATE_TIME_FORMATTER = DateTimeFormatter.ofPattern("yyyy/MM/dd HH:mm:ss");
 
     @Test
-    public void simpleValueAddressHeaderShouldBeAddedToTheAddressSet() {
+    void simpleValueAddressHeaderShouldBeAddedToTheAddressSet() {
         HeaderCollection headerCollection = HeaderCollection.builder()
             .add(new FieldImpl("To", "ben.tellier@linagora.com"))
             .build();
@@ -40,7 +41,7 @@ public class HeaderCollectionTest {
     }
 
     @Test
-    public void comaSeparatedAddressShouldBeBothAddedToTheAddressSet() {
+    void comaSeparatedAddressShouldBeBothAddedToTheAddressSet() {
         HeaderCollection headerCollection = HeaderCollection.builder()
             .add(new FieldImpl("To", "ben.tellier@linagora.com, btellier@minet.net"))
             .build();
@@ -52,7 +53,7 @@ public class HeaderCollectionTest {
     }
 
     @Test
-    public void addressesOfTwoFieldsHavingTheSameNameShouldBeMerged() {
+    void addressesOfTwoFieldsHavingTheSameNameShouldBeMerged() {
         HeaderCollection headerCollection = HeaderCollection.builder()
             .add(new FieldImpl("To", "ben.tellier@linagora.com"))
             .add(new FieldImpl("To", "ben.tellier@linagora.com, btellier@minet.net"))
@@ -65,7 +66,7 @@ public class HeaderCollectionTest {
     }
 
     @Test
-    public void displayNamesShouldBeRetreived() {
+    void displayNamesShouldBeRetreived() {
         HeaderCollection headerCollection = HeaderCollection.builder()
             .add(new FieldImpl("To", "Christophe Hamerling <ch...@linagora.com>"))
             .build();
@@ -75,7 +76,7 @@ public class HeaderCollectionTest {
     }
 
     @Test
-    public void displayNamesShouldBeRetrievedWhenEncodedWord() {
+    void displayNamesShouldBeRetrievedWhenEncodedWord() {
         HeaderCollection headerCollection = HeaderCollection.builder()
             .add(new FieldImpl("From", "=?UTF-8?B?RnLDqWTDqXJpYyBNQVJUSU4=?= <fr...@linagora.com>, Graham CROSMARIE <gr...@linagora.com>"))
             .build();
@@ -86,7 +87,7 @@ public class HeaderCollectionTest {
     }
 
     @Test
-    public void getHeadersShouldDecodeValues() {
+    void getHeadersShouldDecodeValues() {
         HeaderCollection headerCollection = HeaderCollection.builder()
             .add(new FieldImpl("From", "=?UTF-8?B?RnLDqWTDqXJpYyBNQVJUSU4=?= <fm...@linagora.com>, Graham CROSMARIE <gc...@linagora.com>"))
             .build();
@@ -96,7 +97,7 @@ public class HeaderCollectionTest {
     }
 
     @Test
-    public void getHeadersShouldIgnoreHeadersWithDots() {
+    void getHeadersShouldIgnoreHeadersWithDots() {
         HeaderCollection headerCollection = HeaderCollection.builder()
             .add(new FieldImpl("a.b.c", "value"))
             .build();
@@ -106,7 +107,7 @@ public class HeaderCollectionTest {
     }
 
     @Test
-    public void addressWithTwoDisplayNamesOnTheSameFieldShouldBeRetrieved() {
+    void addressWithTwoDisplayNamesOnTheSameFieldShouldBeRetrieved() {
         HeaderCollection headerCollection = HeaderCollection.builder()
             .add(new FieldImpl("From", "Christophe Hamerling <ch...@linagora.com>, Graham CROSMARIE <gr...@linagora.com>"))
             .build();
@@ -117,7 +118,7 @@ public class HeaderCollectionTest {
     }
 
     @Test
-    public void foldedFromHeaderShouldBeSupported() {
+    void foldedFromHeaderShouldBeSupported() {
         HeaderCollection headerCollection = HeaderCollection.builder()
             .add(new FieldImpl("From", "Christophe Hamerling <ch...@linagora.com>,\r\n" +
                 " Graham CROSMARIE <gr...@linagora.com>"))
@@ -129,7 +130,7 @@ public class HeaderCollectionTest {
     }
 
     @Test
-    public void foldedHeaderShouldBeSupported() {
+    void foldedHeaderShouldBeSupported() {
         HeaderCollection headerCollection = HeaderCollection.builder()
             .add(new FieldImpl("From", "Christophe Hamerling <ch...@linagora.com>,\r\n" +
                 " Graham CROSMARIE <gr...@linagora.com>"))
@@ -140,7 +141,7 @@ public class HeaderCollectionTest {
     }
 
     @Test
-    public void mixingAddressWithDisplayNamesWithOthersShouldBeAllowed() {
+    void mixingAddressWithDisplayNamesWithOthersShouldBeAllowed() {
         HeaderCollection headerCollection = HeaderCollection.builder()
             .add(new FieldImpl("To", "Christophe Hamerling <ch...@linagora.com>, grah.crosmarie@linagora.com"))
             .build();
@@ -151,7 +152,7 @@ public class HeaderCollectionTest {
     }
 
     @Test
-    public void displayNamesShouldBeRetreivedOnCc() {
+    void displayNamesShouldBeRetreivedOnCc() {
         HeaderCollection headerCollection = HeaderCollection.builder()
             .add(new FieldImpl("Cc", "Christophe Hamerling <ch...@linagora.com>"))
             .build();
@@ -161,7 +162,7 @@ public class HeaderCollectionTest {
     }
 
     @Test
-    public void displayNamesShouldBeRetreivedOnReplyTo() {
+    void displayNamesShouldBeRetreivedOnReplyTo() {
         HeaderCollection headerCollection = HeaderCollection.builder()
             .add(new FieldImpl("Reply-To", "Christophe Hamerling <ch...@linagora.com>"))
             .build();
@@ -171,7 +172,7 @@ public class HeaderCollectionTest {
     }
 
     @Test
-    public void displayNamesShouldBeRetreivedOnBcc() {
+    void displayNamesShouldBeRetreivedOnBcc() {
         HeaderCollection headerCollection = HeaderCollection.builder()
             .add(new FieldImpl("Bcc", "Christophe Hamerling <ch...@linagora.com>"))
             .build();
@@ -181,7 +182,7 @@ public class HeaderCollectionTest {
     }
 
     @Test
-    public void headerContaingNoAddressShouldBeConsideredBothAsNameAndAddress() {
+    void headerContaingNoAddressShouldBeConsideredBothAsNameAndAddress() {
         HeaderCollection headerCollection = HeaderCollection.builder()
             .add(new FieldImpl("Bcc", "Not an address"))
             .build();
@@ -191,7 +192,7 @@ public class HeaderCollectionTest {
     }
 
     @Test
-    public void unclosedAddressSubpartShouldBeWellHandled() {
+    void unclosedAddressSubpartShouldBeWellHandled() {
         HeaderCollection headerCollection = HeaderCollection.builder()
             .add(new FieldImpl("Bcc", "Mickey <tricky@mouse.com"))
             .build();
@@ -201,7 +202,7 @@ public class HeaderCollectionTest {
     }
 
     @Test
-    public void notComaSeparatedAddressSubpartShouldBeWellHandled() {
+    void notComaSeparatedAddressSubpartShouldBeWellHandled() {
         HeaderCollection headerCollection = HeaderCollection.builder()
             .add(new FieldImpl("Bcc", "Mickey <tr...@mouse.com> Miny<he...@polo.com>"))
             .build();
@@ -212,7 +213,7 @@ public class HeaderCollectionTest {
     }
 
     @Test
-    public void notSeparatedAddressSubpartShouldBeWellHandled() {
+    void notSeparatedAddressSubpartShouldBeWellHandled() {
         HeaderCollection headerCollection = HeaderCollection.builder()
             .add(new FieldImpl("Bcc", "Mickey <tr...@polo.com>"))
             .build();
@@ -223,7 +224,7 @@ public class HeaderCollectionTest {
     }
 
     @Test
-    public void dateShouldBeRetreived() {
+    void dateShouldBeRetreived() {
         HeaderCollection headerCollection = HeaderCollection.builder()
             .add(new FieldImpl("Date", "Thu, 4 Jun 2015 06:08:41 +0200"))
             .build();
@@ -233,7 +234,7 @@ public class HeaderCollectionTest {
     }
 
     @Test
-    public void partialYearShouldBeCompleted() {
+    void partialYearShouldBeCompleted() {
         HeaderCollection headerCollection = HeaderCollection.builder()
             .add(new FieldImpl("Date", "Thu, 4 Jun 15 06:08:41 +0200"))
             .build();
@@ -243,7 +244,7 @@ public class HeaderCollectionTest {
     }
 
     @Test
-    public void nonStandardDatesShouldBeRetreived() {
+    void nonStandardDatesShouldBeRetreived() {
         HeaderCollection headerCollection = HeaderCollection.builder()
             .add(new FieldImpl("Date", "Thu, 4 Jun 2015 06:08:41 +0200 (UTC)"))
             .build();
@@ -253,7 +254,7 @@ public class HeaderCollectionTest {
     }
 
     @Test
-    public void dateShouldBeAbsentOnInvalidHeader() {
+    void dateShouldBeAbsentOnInvalidHeader() {
         HeaderCollection headerCollection = HeaderCollection.builder()
             .add(new FieldImpl("Date", "Not a date"))
             .build();
@@ -263,7 +264,7 @@ public class HeaderCollectionTest {
     }
 
     @Test
-    public void subjectsShouldBeWellRetrieved() {
+    void subjectsShouldBeWellRetrieved() {
         String subject = "A fantastic ElasticSearch module will be available soon for JAMES";
         HeaderCollection headerCollection = HeaderCollection.builder()
             .add(new FieldImpl("Subject", subject))
@@ -273,7 +274,7 @@ public class HeaderCollectionTest {
     }
 
     @Test
-    public void getMessageIDShouldReturnMessageIdValue() {
+    void getMessageIDShouldReturnMessageIdValue() {
         String messageID = "<ab...@123>";
         HeaderCollection headerCollection = HeaderCollection.builder()
             .add(new FieldImpl("Message-ID", messageID))
@@ -284,7 +285,7 @@ public class HeaderCollectionTest {
     }
 
     @Test
-    public void getMessageIDShouldReturnLatestEncounteredMessageIdValue() {
+    void getMessageIDShouldReturnLatestEncounteredMessageIdValue() {
         String messageID = "<ab...@123>";
         HeaderCollection headerCollection = HeaderCollection.builder()
             .add(new FieldImpl("Message-ID", "<ot...@toto.com>"))
@@ -296,7 +297,7 @@ public class HeaderCollectionTest {
     }
 
     @Test
-    public void getMessageIDShouldReturnEmptyWhenNoMessageId() {
+    void getMessageIDShouldReturnEmptyWhenNoMessageId() {
         HeaderCollection headerCollection = HeaderCollection.builder()
             .add(new FieldImpl("Other", "value"))
             .build();
@@ -305,9 +306,10 @@ public class HeaderCollectionTest {
             .isEmpty();
     }
 
-    @Test(expected = NullPointerException.class)
-    public void nullFieldShouldThrow() {
-        HeaderCollection.builder().add(null).build();
+    @Test
+    void nullFieldShouldThrow() {
+        assertThatThrownBy(() -> HeaderCollection.builder().add(null).build())
+            .isInstanceOf(NullPointerException.class);
     }
 
 }


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