Repository: james-project
Updated Branches:
  refs/heads/master 46fd66b6e -> 4c27ed7ad


JAMES-2235 Contact Extractor should accept non stritly parsable recipients


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

Branch: refs/heads/master
Commit: bbb1a4c2d0b32d12c2a482d8491f3a63a194e759
Parents: 2249568
Author: Raphael Ouazana <[email protected]>
Authored: Thu Nov 23 14:07:08 2017 +0100
Committer: Matthieu Baechler <[email protected]>
Committed: Wed Nov 29 10:55:57 2017 +0100

----------------------------------------------------------------------
 .../mailet/base/test/MimeMessageBuilder.java    |  4 ++
 .../transport/mailets/ContactExtractor.java     | 55 +++++++++++-----
 .../transport/mailets/ContactExtractorTest.java | 69 ++++++++++++++++++--
 3 files changed, 109 insertions(+), 19 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/james-project/blob/bbb1a4c2/mailet/base/src/test/java/org/apache/mailet/base/test/MimeMessageBuilder.java
----------------------------------------------------------------------
diff --git 
a/mailet/base/src/test/java/org/apache/mailet/base/test/MimeMessageBuilder.java 
b/mailet/base/src/test/java/org/apache/mailet/base/test/MimeMessageBuilder.java
index 91dafc9..498a6ff 100644
--- 
a/mailet/base/src/test/java/org/apache/mailet/base/test/MimeMessageBuilder.java
+++ 
b/mailet/base/src/test/java/org/apache/mailet/base/test/MimeMessageBuilder.java
@@ -192,6 +192,10 @@ public class MimeMessageBuilder {
         return new MimeMessage(Session.getDefaultInstance(new Properties()), 
inputStream);
     }
 
+    public static MimeMessage mimeMessageFromBytes(byte[] bytes) throws 
MessagingException {
+        return mimeMessageFromStream(new ByteArrayInputStream(bytes));
+    }
+
     public static MimeMessageBuilder mimeMessageBuilder() {
         return new MimeMessageBuilder();
     }

http://git-wip-us.apache.org/repos/asf/james-project/blob/bbb1a4c2/mailet/standard/src/main/java/org/apache/james/transport/mailets/ContactExtractor.java
----------------------------------------------------------------------
diff --git 
a/mailet/standard/src/main/java/org/apache/james/transport/mailets/ContactExtractor.java
 
b/mailet/standard/src/main/java/org/apache/james/transport/mailets/ContactExtractor.java
index 6c8f23e..c363f06 100644
--- 
a/mailet/standard/src/main/java/org/apache/james/transport/mailets/ContactExtractor.java
+++ 
b/mailet/standard/src/main/java/org/apache/james/transport/mailets/ContactExtractor.java
@@ -21,13 +21,19 @@ package org.apache.james.transport.mailets;
 import java.io.IOException;
 import java.util.Arrays;
 import java.util.Optional;
+import java.util.function.Function;
+import java.util.stream.Stream;
 
 import javax.mail.Address;
+import javax.mail.Message;
+import javax.mail.Message.RecipientType;
 import javax.mail.MessagingException;
+import javax.mail.internet.InternetAddress;
 import javax.mail.internet.MimeMessage;
 
 import org.apache.james.core.MailAddress;
 import org.apache.james.mime4j.util.MimeUtil;
+import org.apache.james.util.StreamUtils;
 import org.apache.mailet.Mail;
 import org.apache.mailet.Mailet;
 import org.apache.mailet.MailetException;
@@ -95,26 +101,45 @@ public class ContactExtractor extends GenericMailet 
implements Mailet {
         }
     }
 
-    private Optional<String> extractContacts(Mail mail) throws 
MessagingException, IOException {
-        MimeMessage message = mail.getMessage();
+    @VisibleForTesting
+    Optional<String> extractContacts(Mail mail) throws MessagingException, 
IOException {
+        ImmutableList<String> allRecipients = 
getAllRecipients(mail.getMessage());
 
-        return Optional.of(mail.getSender())
-            .map(MailAddress::asString)
-            .filter(Throwing.predicate(sender -> hasRecipients(message)))
-            .map(Throwing.function(sender -> new ExtractedContacts(sender, 
recipients(message))))
-            .map(Throwing.function(extractedContacts -> 
objectMapper.writeValueAsString(extractedContacts)));
+        if (hasRecipient(allRecipients)) {
+            return Optional.of(mail.getSender())
+                .map(MailAddress::asString)
+                .map(sender -> new ExtractedContacts(sender, allRecipients))
+                .map(Throwing.function(extractedContacts -> 
objectMapper.writeValueAsString(extractedContacts)));
+        }
+
+        return Optional.empty();
+    }
+
+    private boolean hasRecipient(ImmutableList<String> allRecipients) {
+        return !allRecipients.isEmpty();
     }
 
-    @VisibleForTesting boolean hasRecipients(MimeMessage mimeMessage) throws 
MessagingException {
-        return mimeMessage.getAllRecipients() != null 
-                && mimeMessage.getAllRecipients().length > 0;
+    private ImmutableList<String> getAllRecipients(MimeMessage mimeMessage) 
throws MessagingException {
+        return StreamUtils
+            .flatten(
+                getRecipients(mimeMessage, Message.RecipientType.TO),
+                getRecipients(mimeMessage, Message.RecipientType.CC),
+                getRecipients(mimeMessage, Message.RecipientType.BCC))
+            .collect(Guavate.toImmutableList());
     }
 
-    private ImmutableList<String> recipients(MimeMessage mimeMessage) throws 
MessagingException {
-        return Arrays.stream(mimeMessage.getAllRecipients())
-                .map(Address::toString)
-                .map(MimeUtil::unscrambleHeaderValue)
-                .collect(Guavate.toImmutableList());
+    private Stream<String> getRecipients(MimeMessage mimeMessage, 
RecipientType recipientType) throws MessagingException {
+        boolean notStrict = false;
+        Function<String, InternetAddress[]> parseRecipient =
+            Throwing
+                .function((String header) -> 
InternetAddress.parseHeader(header, notStrict))
+                .sneakyThrow();
+        return 
Optional.ofNullable(mimeMessage.getHeader(recipientType.toString(), ","))
+            .map(parseRecipient)
+            .map(Arrays::stream)
+            .orElse(Stream.empty())
+            .map(Address::toString)
+            .map(MimeUtil::unscrambleHeaderValue);
     }
 
     public static class ExtractedContacts {

http://git-wip-us.apache.org/repos/asf/james-project/blob/bbb1a4c2/mailet/standard/src/test/java/org/apache/james/transport/mailets/ContactExtractorTest.java
----------------------------------------------------------------------
diff --git 
a/mailet/standard/src/test/java/org/apache/james/transport/mailets/ContactExtractorTest.java
 
b/mailet/standard/src/test/java/org/apache/james/transport/mailets/ContactExtractorTest.java
index ccde3d6..7546025 100644
--- 
a/mailet/standard/src/test/java/org/apache/james/transport/mailets/ContactExtractorTest.java
+++ 
b/mailet/standard/src/test/java/org/apache/james/transport/mailets/ContactExtractorTest.java
@@ -162,6 +162,66 @@ public class ContactExtractorTest {
     }
 
     @Test
+    public void serviceShouldUnscrambleRecipientsWhenNameContainsSuperiors() 
throws Exception {
+        String rawMessage = "From: [email protected]\r\n"
+            + "To: =?UTF-8?Q?recip_>>_Fr=c3=a9d=c3=a9ric_RECIPIENT?= 
<[email protected]>\r\n"
+            + "Subject: extract this recipient please\r\n"
+            + "\r\n"
+            + "Please!";
+        MimeMessage message = 
MimeMessageBuilder.mimeMessageFromBytes(rawMessage.getBytes());
+        FakeMail mail = FakeMail.builder().mimeMessage(message)
+            .sender(new MailAddress(SENDER))
+            .recipient(new MailAddress("[email protected]"))
+            .build();
+        mailet.init(mailetConfig);
+
+        String expectedMessage = "{\"userEmail\" : \"" + SENDER + "\", 
\"emails\" : [ \"\\\"recip >> Frédéric RECIPIENT\\\" 
<[email protected]>\" ]}";
+        mailet.service(mail);
+
+        
assertThatJson(mail.getAttribute(ATTRIBUTE).toString()).isEqualTo(expectedMessage);
+    }
+
+    @Test
+    public void serviceShouldParseMultipleRecipients() throws Exception {
+        String rawMessage = "From: [email protected]\r\n"
+            + "To: User 1 <[email protected]>, 
=?UTF-8?Q?recip_>>_Fr=c3=a9d=c3=a9ric_RECIPIENT?= <[email protected]>\r\n"
+            + "Subject: extract this recipient please\r\n"
+            + "\r\n"
+            + "Please!";
+        MimeMessage message = 
MimeMessageBuilder.mimeMessageFromBytes(rawMessage.getBytes());
+        FakeMail mail = FakeMail.builder().mimeMessage(message)
+            .sender(new MailAddress(SENDER))
+            .recipient(new MailAddress("[email protected]"))
+            .build();
+        mailet.init(mailetConfig);
+
+        String expectedMessage = "{\"userEmail\" : \"" + SENDER + "\", 
\"emails\" : [ \"User 1 <[email protected]>\", \"\\\"recip >> Frédéric 
RECIPIENT\\\" <[email protected]>\" ]}";
+        mailet.service(mail);
+
+        
assertThatJson(mail.getAttribute(ATTRIBUTE).toString()).isEqualTo(expectedMessage);
+    }
+
+    @Test
+    public void serviceShouldParseRecipientWithCommaInName() throws Exception {
+        String rawMessage = "From: [email protected]\r\n"
+            + "To: \"User, the first one\" <[email protected]>\r\n"
+            + "Subject: extract this recipient please\r\n"
+            + "\r\n"
+            + "Please!";
+        MimeMessage message = 
MimeMessageBuilder.mimeMessageFromBytes(rawMessage.getBytes());
+        FakeMail mail = FakeMail.builder().mimeMessage(message)
+            .sender(new MailAddress(SENDER))
+            .recipient(new MailAddress("[email protected]"))
+            .build();
+        mailet.init(mailetConfig);
+
+        String expectedMessage = "{\"userEmail\" : \"" + SENDER + "\", 
\"emails\" : [ \"\\\"User, the first one\\\" <[email protected]>\" ]}";
+        mailet.service(mail);
+
+        
assertThatJson(mail.getAttribute(ATTRIBUTE).toString()).isEqualTo(expectedMessage);
+    }
+
+    @Test
     public void serviceShouldNotOverwriteSenderWhenDifferentFromField() throws 
Exception {
         MimeMessage message = MimeMessageBuilder.mimeMessageBuilder()
             .addFrom("[email protected]")
@@ -236,15 +296,16 @@ public class ContactExtractorTest {
     }
 
     @Test
-    public void hasRecipientsShouldNotThrowWhenNoRecipient() throws Exception {
+    public void extractContactsShouldNotThrowWhenNoRecipient() throws 
Exception {
         MimeMessage message = MimeMessageBuilder.mimeMessageBuilder()
                 .setSender(SENDER)
                 .setSubject("Contact collection Rocks")
                 .setText("This is my email")
                 .build();
+        FakeMail mail = FakeMail.builder().mimeMessage(message)
+            .sender(new MailAddress(SENDER))
+            .build();
 
-        boolean hasRecipients = mailet.hasRecipients(message);
-
-        assertThat(hasRecipients).isFalse();
+        mailet.extractContacts(mail);
     }
 }
\ No newline at end of file


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

Reply via email to