From 06e5f790bb11c1f48a75ed0e4f31deef423120dc Mon Sep 17 00:00:00 2001 From: yesalam Date: Tue, 7 Mar 2017 11:03:05 +0530 Subject: [PATCH] Auto select identity based on X-Original-To / Delivered-To / X-Envelope-To / TO / CC --- .../main/java/com/fsck/k9/mail/Message.java | 2 +- .../fsck/k9/mail/internet/MimeMessage.java | 51 +++++++ .../mail/internet/MimeMessageParseTest.java | 61 ++++++++ .../com/fsck/k9/helper/IdentityHelper.java | 34 ++++- .../fsck/k9/helper/IdentityHelperTest.java | 136 ++++++++++++++++++ 5 files changed, 282 insertions(+), 2 deletions(-) create mode 100644 k9mail/src/test/java/com/fsck/k9/helper/IdentityHelperTest.java diff --git a/k9mail-library/src/main/java/com/fsck/k9/mail/Message.java b/k9mail-library/src/main/java/com/fsck/k9/mail/Message.java index 9e9017909..051127f2b 100644 --- a/k9mail-library/src/main/java/com/fsck/k9/mail/Message.java +++ b/k9mail-library/src/main/java/com/fsck/k9/mail/Message.java @@ -17,7 +17,7 @@ import timber.log.Timber; public abstract class Message implements Part, Body { public enum RecipientType { - TO, CC, BCC, + TO, CC, BCC, X_ORIGINAL_TO, DELIVERED_TO, X_ENVELOPE_TO } protected String mUid; diff --git a/k9mail-library/src/main/java/com/fsck/k9/mail/internet/MimeMessage.java b/k9mail-library/src/main/java/com/fsck/k9/mail/internet/MimeMessage.java index 93ee3928c..557927734 100644 --- a/k9mail-library/src/main/java/com/fsck/k9/mail/internet/MimeMessage.java +++ b/k9mail-library/src/main/java/com/fsck/k9/mail/internet/MimeMessage.java @@ -48,6 +48,9 @@ public class MimeMessage extends Message { protected Address[] mCc; protected Address[] mBcc; protected Address[] mReplyTo; + protected Address[] xOriginalTo; + protected Address[] deliveredTo; + protected Address[] xEnvelopeTo; protected String mMessageId; private String[] mReferences; @@ -85,6 +88,9 @@ public class MimeMessage extends Message { mCc = null; mBcc = null; mReplyTo = null; + xOriginalTo = null; + deliveredTo = null; + xEnvelopeTo = null; mMessageId = null; mReferences = null; @@ -212,6 +218,24 @@ public class MimeMessage extends Message { } return mBcc; } + case X_ORIGINAL_TO: { + if (xOriginalTo == null) { + xOriginalTo = Address.parse(MimeUtility.unfold(getFirstHeader("X-Original-To"))); + } + return xOriginalTo; + } + case DELIVERED_TO: { + if (deliveredTo == null) { + deliveredTo = Address.parse(MimeUtility.unfold(getFirstHeader("Delivered-To"))); + } + return deliveredTo; + } + case X_ENVELOPE_TO: { + if (xEnvelopeTo == null) { + xEnvelopeTo = Address.parse(MimeUtility.unfold(getFirstHeader("X-Envelope-To"))); + } + return xEnvelopeTo; + } } throw new IllegalArgumentException("Unrecognized recipient type."); @@ -243,6 +267,30 @@ public class MimeMessage extends Message { setHeader("BCC", Address.toEncodedString(addresses)); this.mBcc = addresses; } + } else if (type == RecipientType.X_ORIGINAL_TO) { + if (addresses == null || addresses.length == 0) { + removeHeader("X-Original-To"); + this.xOriginalTo = null; + } else { + setHeader("X-Original-To", Address.toEncodedString(addresses)); + this.xOriginalTo = addresses; + } + } else if (type == RecipientType.DELIVERED_TO) { + if (addresses == null || addresses.length == 0) { + removeHeader("Delivered-To"); + this.deliveredTo = null; + } else { + setHeader("Delivered-To", Address.toEncodedString(addresses)); + this.deliveredTo = addresses; + } + } else if (type == RecipientType.X_ENVELOPE_TO) { + if (addresses == null || addresses.length == 0) { + removeHeader("X-Envelope-To"); + this.xEnvelopeTo = null; + } else { + setHeader("X-Envelope-To", Address.toEncodedString(addresses)); + this.xEnvelopeTo = addresses; + } } else { throw new IllegalStateException("Unrecognized recipient type."); } @@ -624,6 +672,9 @@ public class MimeMessage extends Message { destination.mReplyTo = mReplyTo; destination.mReferences = mReferences; destination.mInReplyTo = mInReplyTo; + destination.xOriginalTo = xOriginalTo; + destination.deliveredTo = deliveredTo; + destination.xEnvelopeTo = xEnvelopeTo; } @Override diff --git a/k9mail-library/src/test/java/com/fsck/k9/mail/internet/MimeMessageParseTest.java b/k9mail-library/src/test/java/com/fsck/k9/mail/internet/MimeMessageParseTest.java index 6c05f8110..e8f95d218 100644 --- a/k9mail-library/src/test/java/com/fsck/k9/mail/internet/MimeMessageParseTest.java +++ b/k9mail-library/src/test/java/com/fsck/k9/mail/internet/MimeMessageParseTest.java @@ -19,9 +19,11 @@ import com.fsck.k9.mail.BodyPart; import com.fsck.k9.mail.K9LibRobolectricTestRunner; import com.fsck.k9.mail.Message.RecipientType; import com.fsck.k9.mail.Multipart; + import org.junit.runner.RunWith; import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; @RunWith(K9LibRobolectricTestRunner.class) @@ -272,4 +274,63 @@ public class MimeMessageParseTest { } assertEquals(Arrays.asList(expectedParts), actual); } + + @Test + public void getRecipients_withXOriginalTo() throws Exception { + MimeMessage msg = parseWithoutRecurse(toStream( + "From: \r\n" + + "To: \r\n" + + "X-Original-To: \r\n" + + "Subject: Testmail\r\n" + + "MIME-Version: 1.0\r\n" + + "Content-type: text/plain\r\n" + + "Content-Transfer-Encoding: 7bit\r\n" + + "\r\n" + + "this is some test text.")); + + Address[] xOriginalAddresses = msg.getRecipients(RecipientType.X_ORIGINAL_TO); + + assertEquals(1, xOriginalAddresses.length); + assertEquals(new Address(""), xOriginalAddresses[0]); + } + + @Test + public void getRecipients_withDeliveredTo() throws Exception { + MimeMessage msg = parseWithoutRecurse(toStream( + "From: \r\n" + + "To: \r\n" + + "Delivered-To: \r\n" + + "Subject: Testmail\r\n" + + "MIME-Version: 1.0\r\n" + + "Content-type: text/plain\r\n" + + "Content-Transfer-Encoding: 7bit\r\n" + + "\r\n" + + "this is some test text.")); + + Address[] deliveredToAddresses = msg.getRecipients(RecipientType.DELIVERED_TO); + + assertEquals(1, deliveredToAddresses.length); + assertEquals(new Address(""), deliveredToAddresses[0]); + } + + @Test + public void getRecipients_withXEnvelopeTo() throws Exception { + MimeMessage msg = parseWithoutRecurse(toStream( + "From: \r\n" + + "To: \r\n" + + "X-Envelope-To: \r\n" + + "Subject: Testmail\r\n" + + "MIME-Version: 1.0\r\n" + + "Content-type: text/plain\r\n" + + "Content-Transfer-Encoding: 7bit\r\n" + + "\r\n" + + "this is some test text.")); + + Address[] xEnvelopeToAddresses = msg.getRecipients(RecipientType.X_ENVELOPE_TO); + + assertEquals(1, xEnvelopeToAddresses.length); + assertEquals(new Address(""), xEnvelopeToAddresses[0]); + } + + } diff --git a/k9mail/src/main/java/com/fsck/k9/helper/IdentityHelper.java b/k9mail/src/main/java/com/fsck/k9/helper/IdentityHelper.java index ac79c416c..bc54923b8 100644 --- a/k9mail/src/main/java/com/fsck/k9/helper/IdentityHelper.java +++ b/k9mail/src/main/java/com/fsck/k9/helper/IdentityHelper.java @@ -6,6 +6,7 @@ import com.fsck.k9.Identity; import com.fsck.k9.mail.Address; import com.fsck.k9.mail.Message; + public class IdentityHelper { /** @@ -24,13 +25,44 @@ public class IdentityHelper { public static Identity getRecipientIdentityFromMessage(Account account, Message message) { Identity recipient = null; - for (Address address : message.getRecipients(Message.RecipientType.TO)) { + for (Address address : message.getRecipients(Message.RecipientType.X_ORIGINAL_TO)) { Identity identity = account.findIdentity(address); if (identity != null) { recipient = identity; break; } } + + if (recipient == null) { + for (Address address : message.getRecipients(Message.RecipientType.DELIVERED_TO)) { + Identity identity = account.findIdentity(address); + if (identity != null) { + recipient = identity; + break; + } + } + } + + if (recipient == null) { + for (Address address : message.getRecipients(Message.RecipientType.X_ENVELOPE_TO)) { + Identity identity = account.findIdentity(address); + if (identity != null) { + recipient = identity; + break; + } + } + } + + if (recipient == null) { + for (Address address : message.getRecipients(Message.RecipientType.TO)) { + Identity identity = account.findIdentity(address); + if (identity != null) { + recipient = identity; + break; + } + } + } + if (recipient == null) { Address[] ccAddresses = message.getRecipients(Message.RecipientType.CC); if (ccAddresses.length > 0) { diff --git a/k9mail/src/test/java/com/fsck/k9/helper/IdentityHelperTest.java b/k9mail/src/test/java/com/fsck/k9/helper/IdentityHelperTest.java new file mode 100644 index 000000000..c45de73ee --- /dev/null +++ b/k9mail/src/test/java/com/fsck/k9/helper/IdentityHelperTest.java @@ -0,0 +1,136 @@ +package com.fsck.k9.helper; + + +import android.content.Context; + +import com.fsck.k9.Account; +import com.fsck.k9.Identity; +import com.fsck.k9.K9RobolectricTestRunner; +import com.fsck.k9.mail.Message; +import com.fsck.k9.mail.Address; +import com.fsck.k9.mail.internet.MimeMessage; + +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.robolectric.RuntimeEnvironment; +import org.robolectric.annotation.Config; + +import java.io.ByteArrayInputStream; +import java.io.InputStream; +import java.util.ArrayList; +import java.util.List; + +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; + +@RunWith(K9RobolectricTestRunner.class) +public class IdentityHelperTest { + + private Account account; + private MimeMessage msg; + + + @Before + public void setUp() throws Exception { + Context context = RuntimeEnvironment.application; + createDummyAccount(context); + msg = parseWithoutRecurse(toStream( + "From: \r\n" + + "To: \r\n" + + "Subject: Testmail\r\n" + + "MIME-Version: 1.0\r\n" + + "Content-type: text/plain\r\n" + + "Content-Transfer-Encoding: 7bit\r\n" + + "\r\n" + + "this is some test text.")); + } + + + private static MimeMessage parseWithoutRecurse(InputStream data) throws Exception { + return MimeMessage.parseMimeMessage(data, false); + } + + private static ByteArrayInputStream toStream(String rawMailData) throws Exception { + return new ByteArrayInputStream(rawMailData.getBytes("ISO-8859-1")); + } + + private void createDummyAccount(Context context) { + account = new DummyAccount(context); + setIdentity(); + } + + private void setIdentity() { + Identity identity = new Identity(); + identity.setEmail("test@mail.com"); + identity.setName("test"); + Identity identity2 = new Identity(); + identity2.setEmail("test2@mail.com"); + identity2.setName("test2"); + Identity eva = new Identity(); + eva.setEmail("eva@example.org"); + eva.setName("Eva"); + + List identityList = new ArrayList<>(); + identityList.add(identity); + identityList.add(identity2); + identityList.add(eva); + account.setIdentities(identityList); + } + + @Test + public void testXOriginalTo() throws Exception { + Address[] addresses = {new Address("test2@mail.com")}; + msg.setRecipients(Message.RecipientType.X_ORIGINAL_TO, addresses); + + Identity identity = IdentityHelper.getRecipientIdentityFromMessage(account, msg); + assertTrue(identity.getEmail().equalsIgnoreCase("test2@mail.com")); + } + + @Test + public void testTo_withoutXOriginalTo() throws Exception { + Identity eva = IdentityHelper.getRecipientIdentityFromMessage(account, msg); + assertTrue(eva.getEmail().equalsIgnoreCase("eva@example.org")); + } + + @Test + public void testDeliveredTo() throws Exception { + Address[] addresses = {new Address("test2@mail.com")}; + msg.setRecipients(Message.RecipientType.DELIVERED_TO, addresses); + msg.removeHeader("X-Original-To"); + + Identity identity = IdentityHelper.getRecipientIdentityFromMessage(account, msg); + assertTrue(identity.getEmail().equalsIgnoreCase("test2@mail.com")); + + } + + @Test + public void testXEnvelopeTo() throws Exception { + Address[] addresses = {new Address("test@mail.com")}; + msg.setRecipients(Message.RecipientType.X_ENVELOPE_TO, addresses); + msg.removeHeader("X-Original-To"); + msg.removeHeader("Delivered-To"); + + Identity identity = IdentityHelper.getRecipientIdentityFromMessage(account, msg); + assertTrue(identity.getEmail().equalsIgnoreCase("test@mail.com")); + } + + @Test + public void testXEnvelopeTo_withXOriginalTo() throws Exception { + Address[] addresses = {new Address("test@mail.com")}; + Address[] xoriginaltoaddresses = {new Address("test2@mail.com")}; + msg.setRecipients(Message.RecipientType.X_ENVELOPE_TO, addresses); + msg.setRecipients(Message.RecipientType.X_ORIGINAL_TO, xoriginaltoaddresses); + + Identity identity = IdentityHelper.getRecipientIdentityFromMessage(account, msg); + assertTrue(identity.getEmail().equalsIgnoreCase("test2@mail.com")); + } + + + static class DummyAccount extends Account { + + protected DummyAccount(Context context) { + super(context); + } + } +}