MAILBOX-321 PGP signature parts SHOULD always be considered as attachment

A specific handling needs to be implemented using ContentType header as, as you 
can see in the added tests, ContentDisposition header is not specified on PGP 
signature.

The new code allow to add ContentTypes that should always be considered as 
attachment (even when no ContentDisposition is attached to them).


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

Branch: refs/heads/master
Commit: 9e3d5dce46e37d374b89cf9b2f01dd4dfd5d6a61
Parents: 1d05817
Author: benwa <[email protected]>
Authored: Tue Nov 28 13:13:59 2017 +0700
Committer: Antoine Duprat <[email protected]>
Committed: Thu Nov 30 14:55:36 2017 +0100

----------------------------------------------------------------------
 .../store/mail/model/impl/MessageParser.java    | 22 ++++-
 .../mail/model/impl/MessageParserTest.java      | 13 +++
 .../src/test/resources/eml/signedMessage.eml    | 84 ++++++++++++++++++++
 3 files changed, 115 insertions(+), 4 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/james-project/blob/9e3d5dce/mailbox/store/src/main/java/org/apache/james/mailbox/store/mail/model/impl/MessageParser.java
----------------------------------------------------------------------
diff --git 
a/mailbox/store/src/main/java/org/apache/james/mailbox/store/mail/model/impl/MessageParser.java
 
b/mailbox/store/src/main/java/org/apache/james/mailbox/store/mail/model/impl/MessageParser.java
index cbde24a..a0273ba 100644
--- 
a/mailbox/store/src/main/java/org/apache/james/mailbox/store/mail/model/impl/MessageParser.java
+++ 
b/mailbox/store/src/main/java/org/apache/james/mailbox/store/mail/model/impl/MessageParser.java
@@ -68,6 +68,7 @@ public class MessageParser {
     private static final List<String> ATTACHMENT_CONTENT_DISPOSITIONS = 
ImmutableList.of(
             
ContentDispositionField.DISPOSITION_TYPE_ATTACHMENT.toLowerCase(Locale.US),
             
ContentDispositionField.DISPOSITION_TYPE_INLINE.toLowerCase(Locale.US));
+    private static final ImmutableList<String> ATTACHMENT_CONTENT_TYPES = 
ImmutableList.of("application/pgp-signature");
     private static final Logger LOGGER = 
LoggerFactory.getLogger(MessageParser.class);
 
     private final Cid.CidParser cidParser;
@@ -192,10 +193,7 @@ public class MessageParser {
         if (context == Context.BODY && isTextPart(part)) {
             return false;
         }
-        return Optional.ofNullable(part.getDispositionType())
-                .map(dispositionType -> 
ATTACHMENT_CONTENT_DISPOSITIONS.contains(
-                    dispositionType.toLowerCase(Locale.US)))
-            .orElse(false);
+        return attachmentDispositionCriterion(part) || 
attachmentContentTypeCriterion(part);
     }
 
     private boolean isTextPart(Entity part) {
@@ -205,6 +203,22 @@ public class MessageParser {
             .orElse(false);
     }
 
+    private Boolean attachmentContentTypeCriterion(Entity part) {
+        return getContentTypeField(part)
+            .map(ContentTypeField::getMimeType)
+            .map(dispositionType -> dispositionType.toLowerCase(Locale.US))
+            .map(ATTACHMENT_CONTENT_TYPES::contains)
+            .orElse(false);
+    }
+
+    private Boolean attachmentDispositionCriterion(Entity part) {
+        return getContentDispositionField(part)
+            .map(ContentDispositionField::getDispositionType)
+            .map(dispositionType -> dispositionType.toLowerCase(Locale.US))
+            .map(ATTACHMENT_CONTENT_DISPOSITIONS::contains)
+            .orElse(false);
+    }
+
     private byte[] getBytes(Body body) throws IOException {
         DefaultMessageWriter messageWriter = new DefaultMessageWriter();
         ByteArrayOutputStream out = new ByteArrayOutputStream();

http://git-wip-us.apache.org/repos/asf/james-project/blob/9e3d5dce/mailbox/store/src/test/java/org/apache/james/mailbox/store/mail/model/impl/MessageParserTest.java
----------------------------------------------------------------------
diff --git 
a/mailbox/store/src/test/java/org/apache/james/mailbox/store/mail/model/impl/MessageParserTest.java
 
b/mailbox/store/src/test/java/org/apache/james/mailbox/store/mail/model/impl/MessageParserTest.java
index 581a2df..61df5a9 100644
--- 
a/mailbox/store/src/test/java/org/apache/james/mailbox/store/mail/model/impl/MessageParserTest.java
+++ 
b/mailbox/store/src/test/java/org/apache/james/mailbox/store/mail/model/impl/MessageParserTest.java
@@ -20,6 +20,7 @@
 package org.apache.james.mailbox.store.mail.model.impl;
 
 import static org.assertj.core.api.Assertions.assertThat;
+
 import java.util.List;
 import java.util.Optional;
 
@@ -253,4 +254,16 @@ public class MessageParserTest {
 
         assertThat(attachments).hasSize(1);
     }
+
+    @Test
+    public void gpgSignatureShouldBeConsideredAsAnAttachment() throws 
Exception {
+        List<MessageAttachment> attachments = testee.retrieveAttachments(
+            ClassLoader.getSystemResourceAsStream("eml/signedMessage.eml"));
+
+        assertThat(attachments).hasSize(2)
+            .extracting(MessageAttachment::getName)
+            .allMatch(Optional::isPresent)
+            .extracting(Optional::get)
+            .containsOnly("message suivi", "signature.asc");
+    }
 }

http://git-wip-us.apache.org/repos/asf/james-project/blob/9e3d5dce/mailbox/store/src/test/resources/eml/signedMessage.eml
----------------------------------------------------------------------
diff --git a/mailbox/store/src/test/resources/eml/signedMessage.eml 
b/mailbox/store/src/test/resources/eml/signedMessage.eml
new file mode 100644
index 0000000..e8c33b8
--- /dev/null
+++ b/mailbox/store/src/test/resources/eml/signedMessage.eml
@@ -0,0 +1,84 @@
+Return-Path: <[email protected]>
+From: Important Client <[email protected]>
+To: Big Boss <[email protected]>, Big big boss <[email protected]>
+Subject: Fwd: Re: Deploying production instances of James
+Date: Fri, 17 Nov 2017 11:50:12 +0100
+Message-ID: <[email protected]>
+Organization: Linagora
+MIME-Version: 1.0
+Content-Type: multipart/signed; boundary="nextPart2399737.qbvXs1L0ps"; 
micalg="pgp-sha1"; protocol="application/pgp-signature"
+
+--nextPart2399737.qbvXs1L0ps
+Content-Type: multipart/mixed; boundary="nextPart3147505.khcI58SeaZ"
+Content-Transfer-Encoding: 7Bit
+
+This is a multi-part message in MIME format.
+
+--nextPart3147505.khcI58SeaZ
+Content-Transfer-Encoding: quoted-printable
+Content-Type: text/plain; charset="iso-8859-1"
+
+For your information,
+
+--nextPart3147505.khcI58SeaZ
+Content-Type: message/rfc822
+Content-Disposition: inline; filename="message suivi"
+Content-Description: Harold Goguelin <[email protected]>: Re: La Cerise - 
certificat =?UTF-8?B?RXhwaXLDqQ==?=
+
+Return-Path: <[email protected]>
+Subject: Re: Deploying production instances of James
+To: Important Client <[email protected]>
+From: Project manager <[email protected]>
+Organization: Linagora
+Message-ID: <[email protected]>
+Date: Fri, 17 Nov 2017 11:39:27 +0100
+MIME-Version: 1.0
+Content-Type: multipart/alternative; 
boundary="------------51EED611A8498A33106C3AAD"
+Content-Language: fr
+
+ This is a multi-part message in MIME format.
+--------------51EED611A8498A33106C3AAD
+Content-Type: text/plain; charset="utf-8"; format="flowed"
+Content-Transfer-Encoding: 8bit
+
+Message envoyé grâce à OBM <http://obm.org>, la Communication Libre par 
+Linagora <http://www.linagora.com/>
+
+--------------51EED611A8498A33106C3AAD
+Content-Type: text/html; charset="utf-8"
+Content-Transfer-Encoding: 8bit
+
+<html>
+  <head>
+    <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+  </head>
+
+    <div><div>--</div><div>Message envoyé grâce à
+        <a href="http://obm.org";>OBM</a>, la Communication Libre par
+        <a href="http://www.linagora.com/";>Linagora</a></div></div>
+  </body>
+</html>
+
+--------------51EED611A8498A33106C3AAD--
+
+--nextPart3147505.khcI58SeaZ--
+
+--nextPart2399737.qbvXs1L0ps
+Content-Type: application/pgp-signature; name="signature.asc"
+Content-Description: This is a digitally signed message part.
+Content-Transfer-Encoding: 7Bit
+
+-----BEGIN PGP SIGNATURE-----
+Version: GnuPG v2
+
+iQEcBAABAgAGBQJaDr7mAAoJEG2idAxkrRbwU/AIAMdFxvcR0CkhBJcNJq3Y3acR
+hfrQEO25N7lKpqKgcOZ8q3oh6yUXoSTECSdXDZqOeFLg2lWcP30HxE+imU/7BMbq
+p0ODuTHGBm0jLlXHdgLSsmjgSsZ5QqLJNxuSlJ/S+eG1tREuxVMLw01vVvIOIH4f
+aUmaYmUbFrSzNV6AWbhvifgnzCiPfp6/Q/HorvTngE6LSvmwGUvcghxrlq5+98Ow
+AbWAdSeE1M1IArPKspUydVygD4WnfFnOurcITgka7jTS67MW/VYolwfiZYSX0ao+
+wOTkyd0HKWYU+WsCn/nXKa8+dlYxFdohjDx0UqoX9wagpZt9bgjdGpj7j6jhv/c=
+=rzKZ
+-----END PGP SIGNATURE-----
+
+--nextPart2399737.qbvXs1L0ps--
+


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to