From 9e739cda732f6743a72d926ae7f8c1607634fd72 Mon Sep 17 00:00:00 2001 From: bbottema Date: Tue, 7 Jan 2020 20:28:00 +0100 Subject: [PATCH] #241: distinguish properly between TO, CC and BCC recipients when converting from Outlook messages --- angular-app | 2 +- .../converter/OutlookEmailConverter.java | 16 ++++++-- .../converter/EmailConverter.java | 26 ++++++------- .../converter/EmailConverterTest.java | 36 ++++++++++++++++++ .../simple email with TO and CC.msg | Bin 0 -> 36864 bytes 5 files changed, 63 insertions(+), 17 deletions(-) create mode 100644 modules/simple-java-mail/src/test/java/org/simplejavamail/converter/EmailConverterTest.java create mode 100644 modules/simple-java-mail/src/test/resources/test-messages/simple email with TO and CC.msg diff --git a/angular-app b/angular-app index 980d1f815..7e80429e7 160000 --- a/angular-app +++ b/angular-app @@ -1 +1 @@ -Subproject commit 980d1f815b291a36a8474d34726512f326ce6135 +Subproject commit 7e80429e7557ad826ced0e9aeee78c24b70de73b diff --git a/modules/outlook-module/src/main/java/org/simplejavamail/internal/outlooksupport/converter/OutlookEmailConverter.java b/modules/outlook-module/src/main/java/org/simplejavamail/internal/outlooksupport/converter/OutlookEmailConverter.java index b27c88275..0d3daecb3 100644 --- a/modules/outlook-module/src/main/java/org/simplejavamail/internal/outlooksupport/converter/OutlookEmailConverter.java +++ b/modules/outlook-module/src/main/java/org/simplejavamail/internal/outlooksupport/converter/OutlookEmailConverter.java @@ -2,6 +2,7 @@ import org.simplejavamail.api.email.EmailPopulatingBuilder; import org.simplejavamail.api.email.EmailStartingBuilder; +import org.simplejavamail.api.email.Recipient; import org.simplejavamail.api.internal.outlooksupport.model.EmailFromOutlookMessage; import org.simplejavamail.internal.modules.OutlookModule; import org.simplejavamail.internal.outlooksupport.internal.model.OutlookMessageProxy; @@ -15,6 +16,7 @@ import java.io.IOException; import java.io.InputStream; import java.util.Map; +import java.util.Objects; import static org.simplejavamail.internal.util.MiscUtil.extractCID; import static org.simplejavamail.internal.util.Preconditions.assumeNonNull; @@ -75,9 +77,6 @@ private static EmailFromOutlookMessage buildEmailFromOutlookMessage( } private static void copyReceiversFromOutlookMessage(@NotNull EmailPopulatingBuilder builder, @NotNull OutlookMessage outlookMessage) { - for (final OutlookRecipient to : outlookMessage.getRecipients()) { - builder.to(to.getName(), to.getAddress()); - } //noinspection QuestionableName for (final OutlookRecipient cc : outlookMessage.getCcRecipients()) { builder.cc(cc.getName(), cc.getAddress()); @@ -85,6 +84,17 @@ private static void copyReceiversFromOutlookMessage(@NotNull EmailPopulatingBuil for (final OutlookRecipient bcc : outlookMessage.getBccRecipients()) { builder.bcc(bcc.getName(), bcc.getAddress()); } + // only add remaining recipients... + outerloop: + for (final OutlookRecipient to : outlookMessage.getRecipients()) { + for (final Recipient recipient : builder.getRecipients()) { + if (Objects.equals(recipient.getName(), to.getName()) && + Objects.equals(recipient.getAddress(), to.getAddress())) { + continue outerloop; + } + } + builder.to(to.getName(), to.getAddress()); + } } @NotNull diff --git a/modules/simple-java-mail/src/main/java/org/simplejavamail/converter/EmailConverter.java b/modules/simple-java-mail/src/main/java/org/simplejavamail/converter/EmailConverter.java index f1520588c..2f54e7af7 100644 --- a/modules/simple-java-mail/src/main/java/org/simplejavamail/converter/EmailConverter.java +++ b/modules/simple-java-mail/src/main/java/org/simplejavamail/converter/EmailConverter.java @@ -107,24 +107,24 @@ public static EmailPopulatingBuilder mimeMessageToEmailBuilder(@NotNull final Mi /** * Delegates to {@link #outlookMsgToEmail(String, Pkcs12Config)}. * - * @param msgFile The content of an Outlook (.msg) message from which to create the {@link Email}. + * @param msgData The content of an Outlook (.msg) message from which to create the {@link Email}. */ @SuppressWarnings("unused") @NotNull - public static Email outlookMsgToEmail(@NotNull final String msgFile) { - return outlookMsgToEmail(msgFile, null); + public static Email outlookMsgToEmail(@NotNull final String msgData) { + return outlookMsgToEmail(msgData, null); } /** - * @param msgFile The content of an Outlook (.msg) message from which to create the {@link Email}. + * @param msgData The content of an Outlook (.msg) message from which to create the {@link Email}. * @param pkcs12Config Private key store for decrypting S/MIME encrypted attachments * (only needed when the message is encrypted rather than just signed). */ @SuppressWarnings("deprecation") @NotNull - public static Email outlookMsgToEmail(@NotNull final String msgFile, @Nullable final Pkcs12Config pkcs12Config) { - checkNonEmptyArgument(msgFile, "msgFile"); - EmailFromOutlookMessage result = ModuleLoader.loadOutlookModule().outlookMsgToEmailBuilder(msgFile, new EmailStartingBuilderImpl()); + public static Email outlookMsgToEmail(@NotNull final String msgData, @Nullable final Pkcs12Config pkcs12Config) { + checkNonEmptyArgument(msgData, "msgFile"); + EmailFromOutlookMessage result = ModuleLoader.loadOutlookModule().outlookMsgToEmailBuilder(msgData, new EmailStartingBuilderImpl()); return decryptAttachments(result.getEmailBuilder(), result.getOutlookMessage(), pkcs12Config) .buildEmail(); } @@ -372,9 +372,9 @@ public static MimeMessage outlookMsgToMimeMessage(@NotNull final String msgFile) * @return Result of {@link #outlookMsgToEmail(String, Pkcs12Config)} and {@link #emailToMimeMessage(Email)}. */ @NotNull - public static MimeMessage outlookMsgToMimeMessage(@NotNull final String msgFile, @Nullable final Pkcs12Config pkcs12Config) { - checkNonEmptyArgument(msgFile, "outlookMsgData"); - return emailToMimeMessage(outlookMsgToEmail(msgFile, pkcs12Config)); + public static MimeMessage outlookMsgToMimeMessage(@NotNull final String msgData, @Nullable final Pkcs12Config pkcs12Config) { + checkNonEmptyArgument(msgData, "outlookMsgData"); + return emailToMimeMessage(outlookMsgToEmail(msgData, pkcs12Config)); } /** @@ -535,9 +535,9 @@ public static String outlookMsgToEML(@NotNull final String msgFile) { * @return Result of {@link #outlookMsgToEmail(String, Pkcs12Config)} and {@link #emailToEML(Email)} */ @NotNull - public static String outlookMsgToEML(@NotNull final String msgFile, @Nullable final Pkcs12Config pkcs12Config) { - checkNonEmptyArgument(msgFile, "outlookMsgData"); - return emailToEML(outlookMsgToEmail(msgFile, pkcs12Config)); + public static String outlookMsgToEML(@NotNull final String msgData, @Nullable final Pkcs12Config pkcs12Config) { + checkNonEmptyArgument(msgData, "outlookMsgData"); + return emailToEML(outlookMsgToEmail(msgData, pkcs12Config)); } /** diff --git a/modules/simple-java-mail/src/test/java/org/simplejavamail/converter/EmailConverterTest.java b/modules/simple-java-mail/src/test/java/org/simplejavamail/converter/EmailConverterTest.java new file mode 100644 index 000000000..e18b13cc8 --- /dev/null +++ b/modules/simple-java-mail/src/test/java/org/simplejavamail/converter/EmailConverterTest.java @@ -0,0 +1,36 @@ +package org.simplejavamail.converter; + +import org.jetbrains.annotations.NotNull; +import org.junit.Test; +import org.simplejavamail.api.email.Email; +import org.simplejavamail.api.email.EmailAssert; +import org.simplejavamail.api.email.Recipient; + +import java.io.File; + +import static demo.ResourceFolderHelper.determineResourceFolder; +import static javax.mail.Message.RecipientType.CC; +import static javax.mail.Message.RecipientType.TO; +import static org.assertj.core.api.Assertions.assertThat; +import static org.simplejavamail.internal.util.MiscUtil.normalizeNewlines; + +public class EmailConverterTest { + + private static final String RESOURCE_FOLDER = determineResourceFolder("simple-java-mail") + "/test/resources/test-messages"; + + @Test + public void testOutlookBasicConversions() { + final Recipient elias = new Recipient("Elias Laugher", "elias.laugher@gmail.com", null); + final Recipient sven = new Recipient("Sven Sielenkemper", "sielenkemper@otris.de", TO); + final Recipient niklas = new Recipient("niklas.lindson@gmail.com", "niklas.lindson@gmail.com", CC); + + @NotNull Email msg = EmailConverter.outlookMsgToEmail(new File(RESOURCE_FOLDER + "/simple email with TO and CC.msg")); + EmailAssert.assertThat(msg).hasFromRecipient(elias); + EmailAssert.assertThat(msg).hasSubject("Test E-Mail"); + EmailAssert.assertThat(msg).hasOnlyRecipients(sven, niklas); + EmailAssert.assertThat(msg).hasNoAttachments(); + assertThat(msg.getPlainText()).isNotEmpty(); + assertThat(normalizeNewlines(msg.getHTMLText())).isEqualTo("
Just a test to get an email with one cc recipient.
\n"); + assertThat(normalizeNewlines(msg.getPlainText())).isEqualTo("Just a test to get an email with one cc recipient.\n"); + } +} \ No newline at end of file diff --git a/modules/simple-java-mail/src/test/resources/test-messages/simple email with TO and CC.msg b/modules/simple-java-mail/src/test/resources/test-messages/simple email with TO and CC.msg new file mode 100644 index 0000000000000000000000000000000000000000..f374a1b91374e9e619d5eacb2762bf32d7d4a9db GIT binary patch literal 36864 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 HN#Oqhne|QX literal 0 HcmV?d00001