From d9ee8b5cf0e8f51c3be2e4578ac2f2b9aa60e738 Mon Sep 17 00:00:00 2001 From: Vincent Breitmoser Date: Mon, 18 Sep 2017 01:41:21 +0200 Subject: [PATCH] Simplify message extraction logic, fix #2776 --- .../fsck/k9/mailstore/MessageViewInfo.java | 27 +++---- .../mailstore/MessageViewInfoExtractor.java | 75 ++++++++++++------- .../k9/ui/crypto/MessageCryptoSplitter.java | 60 --------------- 3 files changed, 60 insertions(+), 102 deletions(-) delete mode 100644 k9mail/src/main/java/com/fsck/k9/ui/crypto/MessageCryptoSplitter.java diff --git a/k9mail/src/main/java/com/fsck/k9/mailstore/MessageViewInfo.java b/k9mail/src/main/java/com/fsck/k9/mailstore/MessageViewInfo.java index f89ff127c..9934447f9 100644 --- a/k9mail/src/main/java/com/fsck/k9/mailstore/MessageViewInfo.java +++ b/k9mail/src/main/java/com/fsck/k9/mailstore/MessageViewInfo.java @@ -1,6 +1,7 @@ package com.fsck.k9.mailstore; +import java.util.Collections; import java.util.List; import com.fsck.k9.mail.Message; @@ -36,24 +37,24 @@ public class MessageViewInfo { this.extraAttachments = extraAttachments; } - public static MessageViewInfo createWithExtractedContent( - Message message, boolean isMessageIncomplete, Part rootPart, - String text, List attachments, - CryptoResultAnnotation cryptoResultAnnotation, - AttachmentResolver attachmentResolver, - String extraText, List extraAttachments - ) { + static MessageViewInfo createWithExtractedContent(Message message, boolean isMessageIncomplete, + String text, List attachments, AttachmentResolver attachmentResolver) { return new MessageViewInfo( - message, isMessageIncomplete, rootPart, - text, attachments, - cryptoResultAnnotation, - attachmentResolver, - extraText, extraAttachments - ); + message, isMessageIncomplete, message, text, attachments, null, attachmentResolver, null, + Collections.emptyList()); } public static MessageViewInfo createWithErrorState(Message message, boolean isMessageIncomplete) { return new MessageViewInfo(message, isMessageIncomplete, null, null, null, null, null, null, null); } + MessageViewInfo withCryptoData(CryptoResultAnnotation rootPartAnnotation, String extraViewableText, + List extraAttachmentInfos) { + return new MessageViewInfo( + message, isMessageIncomplete, rootPart, text, attachments, + rootPartAnnotation, + attachmentResolver, + extraViewableText, extraAttachmentInfos + ); + } } diff --git a/k9mail/src/main/java/com/fsck/k9/mailstore/MessageViewInfoExtractor.java b/k9mail/src/main/java/com/fsck/k9/mailstore/MessageViewInfoExtractor.java index 8d318ca69..c6944e246 100644 --- a/k9mail/src/main/java/com/fsck/k9/mailstore/MessageViewInfoExtractor.java +++ b/k9mail/src/main/java/com/fsck/k9/mailstore/MessageViewInfoExtractor.java @@ -12,22 +12,24 @@ import android.support.annotation.VisibleForTesting; import android.support.annotation.WorkerThread; import com.fsck.k9.Globals; +import com.fsck.k9.K9; import com.fsck.k9.R; +import com.fsck.k9.crypto.MessageCryptoStructureDetector; import com.fsck.k9.mail.Address; import com.fsck.k9.mail.Flag; import com.fsck.k9.mail.Message; import com.fsck.k9.mail.MessagingException; import com.fsck.k9.mail.Part; import com.fsck.k9.mail.internet.MessageExtractor; +import com.fsck.k9.mail.internet.MimeUtility; import com.fsck.k9.mail.internet.Viewable; import com.fsck.k9.mail.internet.Viewable.Flowed; +import com.fsck.k9.mailstore.CryptoResultAnnotation.CryptoError; import com.fsck.k9.mailstore.util.FlowedMessageUtils; import com.fsck.k9.message.extractors.AttachmentInfoExtractor; import com.fsck.k9.message.html.HtmlConverter; import com.fsck.k9.message.html.HtmlProcessor; import com.fsck.k9.ui.crypto.MessageCryptoAnnotations; -import com.fsck.k9.ui.crypto.MessageCryptoSplitter; -import com.fsck.k9.ui.crypto.MessageCryptoSplitter.CryptoMessageParts; import org.openintents.openpgp.util.OpenPgpUtils; import timber.log.Timber; @@ -71,43 +73,58 @@ public class MessageViewInfoExtractor { @WorkerThread public MessageViewInfo extractMessageForView(Message message, @Nullable MessageCryptoAnnotations annotations) throws MessagingException { - Part rootPart; - CryptoResultAnnotation cryptoResultAnnotation; - List extraParts; + ArrayList extraParts = new ArrayList<>(); + Part cryptoContentPart = MessageCryptoStructureDetector.findPrimaryEncryptedOrSignedPart(message, extraParts); - CryptoMessageParts cryptoMessageParts = MessageCryptoSplitter.split(message, annotations); - if (cryptoMessageParts != null) { - rootPart = cryptoMessageParts.contentPart; - cryptoResultAnnotation = cryptoMessageParts.contentCryptoAnnotation; - extraParts = cryptoMessageParts.extraParts; - } else { + if (cryptoContentPart == null) { if (annotations != null && !annotations.isEmpty()) { - Timber.e("Got message annotations but no crypto root part!"); + Timber.e("Got crypto message annotations but no crypto root part!"); } - rootPart = message; - cryptoResultAnnotation = null; - extraParts = null; + return extractSimpleMessageForView(message, message); } - List attachmentInfos = new ArrayList<>(); - ViewableExtractedText viewable = extractViewableAndAttachments( - Collections.singletonList(rootPart), attachmentInfos); + boolean isOpenPgpEncrypted = + MimeUtility.isSameMimeType(cryptoContentPart.getMimeType(), "multipart/encrypted") && + MimeUtility.isSameMimeType(getHeaderParameter(cryptoContentPart.getContentType(), "protocol"), + "application/pgp-encrypted"); + if (!K9.isOpenPgpProviderConfigured() && isOpenPgpEncrypted) { + CryptoResultAnnotation noProviderAnnotation = CryptoResultAnnotation.createErrorAnnotation( + CryptoError.OPENPGP_ENCRYPTED_NO_PROVIDER, null); + return MessageViewInfo.createWithErrorState(message, false).withCryptoData(noProviderAnnotation, null, null); + } + + CryptoResultAnnotation cryptoContentPartAnnotation = annotations != null ? annotations.get(cryptoContentPart) : null; + if (cryptoContentPartAnnotation != null) { + return extractCryptoMessageForView(message, extraParts, cryptoContentPart, cryptoContentPartAnnotation); + } + + return extractSimpleMessageForView(message, message); + } + + private MessageViewInfo extractCryptoMessageForView(Message message, + ArrayList extraParts, Part cryptoContentPart, CryptoResultAnnotation cryptoContentPartAnnotation) + throws MessagingException { + if (cryptoContentPartAnnotation != null && cryptoContentPartAnnotation.hasReplacementData()) { + cryptoContentPart = cryptoContentPartAnnotation.getReplacementData(); + } List extraAttachmentInfos = new ArrayList<>(); - String extraViewableText = null; - if (extraParts != null) { - ViewableExtractedText extraViewable = - extractViewableAndAttachments(extraParts, extraAttachmentInfos); - extraViewableText = extraViewable.text; - } + ViewableExtractedText extraViewable = extractViewableAndAttachments(extraParts, extraAttachmentInfos); - AttachmentResolver attachmentResolver = AttachmentResolver.createFromPart(rootPart); + MessageViewInfo messageViewInfo = extractSimpleMessageForView(message, cryptoContentPart); + return messageViewInfo.withCryptoData(cryptoContentPartAnnotation, extraViewable.text, extraAttachmentInfos); + } - boolean isMessageIncomplete = !message.isSet(Flag.X_DOWNLOADED_FULL) || - MessageExtractor.hasMissingParts(message); + private MessageViewInfo extractSimpleMessageForView(Message message, Part contentPart) throws MessagingException { + List attachmentInfos = new ArrayList<>(); + ViewableExtractedText viewable = extractViewableAndAttachments( + Collections.singletonList(contentPart), attachmentInfos); + AttachmentResolver attachmentResolver = AttachmentResolver.createFromPart(contentPart); + boolean isMessageIncomplete = + !message.isSet(Flag.X_DOWNLOADED_FULL) || MessageExtractor.hasMissingParts(message); - return MessageViewInfo.createWithExtractedContent(message, isMessageIncomplete, rootPart, viewable.html, - attachmentInfos, cryptoResultAnnotation, attachmentResolver, extraViewableText, extraAttachmentInfos); + return MessageViewInfo.createWithExtractedContent( + message, isMessageIncomplete, viewable.html, attachmentInfos, attachmentResolver); } private ViewableExtractedText extractViewableAndAttachments(List parts, diff --git a/k9mail/src/main/java/com/fsck/k9/ui/crypto/MessageCryptoSplitter.java b/k9mail/src/main/java/com/fsck/k9/ui/crypto/MessageCryptoSplitter.java deleted file mode 100644 index 02c439eff..000000000 --- a/k9mail/src/main/java/com/fsck/k9/ui/crypto/MessageCryptoSplitter.java +++ /dev/null @@ -1,60 +0,0 @@ -package com.fsck.k9.ui.crypto; - - -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; - -import android.support.annotation.NonNull; -import android.support.annotation.Nullable; - -import com.fsck.k9.crypto.MessageCryptoStructureDetector; -import com.fsck.k9.mail.Message; -import com.fsck.k9.mail.Part; -import com.fsck.k9.mailstore.CryptoResultAnnotation; -import com.fsck.k9.mailstore.CryptoResultAnnotation.CryptoError; - - -public class MessageCryptoSplitter { - private MessageCryptoSplitter() { } - - @Nullable - public static CryptoMessageParts split(@NonNull Message message, @Nullable MessageCryptoAnnotations annotations) { - ArrayList extraParts = new ArrayList<>(); - Part primaryPart = MessageCryptoStructureDetector.findPrimaryEncryptedOrSignedPart(message, extraParts); - if (primaryPart == null) { - return null; - } - - if (annotations == null) { - CryptoResultAnnotation rootPartAnnotation = - CryptoResultAnnotation.createErrorAnnotation(CryptoError.OPENPGP_ENCRYPTED_NO_PROVIDER, null); - return new CryptoMessageParts(primaryPart, rootPartAnnotation, extraParts); - } - - CryptoResultAnnotation rootPartAnnotation = annotations.get(primaryPart); - Part rootPart; - if (rootPartAnnotation != null && rootPartAnnotation.hasReplacementData()) { - rootPart = rootPartAnnotation.getReplacementData(); - } else { - rootPart = primaryPart; - } - - return new CryptoMessageParts(rootPart, rootPartAnnotation, extraParts); - } - - public static class CryptoMessageParts { - public final Part contentPart; - @Nullable - public final CryptoResultAnnotation contentCryptoAnnotation; - - public final List extraParts; - - CryptoMessageParts(Part contentPart, @Nullable CryptoResultAnnotation contentCryptoAnnotation, List extraParts) { - this.contentPart = contentPart; - this.contentCryptoAnnotation = contentCryptoAnnotation; - this.extraParts = Collections.unmodifiableList(extraParts); - } - } - -}