From a8f41118e39a802061d6eac23a2545bc88dff68a Mon Sep 17 00:00:00 2001 From: cketti Date: Fri, 31 Aug 2018 02:59:39 +0200 Subject: [PATCH] Add interface for detection of encrypted messages This includes some capabilities that are not currently used by K-9 Mail, e.g. the ability to supply additional data to be inserted into the database. --- .../com/fsck/k9/crypto/EncryptionExtractor.kt | 17 +++++++ .../com/fsck/k9/mailstore/LocalFolder.java | 41 ++++++++++++--- .../message/extractors/AttachmentCounter.java | 14 +---- .../extractors/MessageFulltextCreator.java | 15 +----- .../extractors/MessagePreviewCreator.java | 16 +----- .../k9/message/extractors/TextPartFinder.java | 2 +- app/core/src/test/java/com/fsck/k9/TestApp.kt | 2 + .../extractors/MessagePreviewCreatorTest.java | 23 +-------- app/crypto-openpgp/build.gradle | 33 ++++++++++++ .../src/main/AndroidManifest.xml | 2 + .../crypto/openpgp}/EncryptionDetector.java | 4 +- .../openpgp/OpenPgpEncryptionExtractor.kt | 31 +++++++++++ .../openpgp}/EncryptionDetectorTest.java | 23 +++++---- .../crypto/openpgp/MessageCreationHelper.java | 51 +++++++++++++++++++ app/k9mail/build.gradle | 1 + .../src/main/java/com/fsck/k9/Dependencies.kt | 3 ++ .../k9/storage/StoreSchemaDefinition.java | 5 +- .../k9/storage/migrations/MigrationTo66.kt | 13 +++++ .../k9/storage/migrations/Migrations.java | 2 + .../test/java/com/fsck/k9/storage/TestApp.kt | 2 + settings.gradle | 1 + 21 files changed, 217 insertions(+), 84 deletions(-) create mode 100644 app/core/src/main/java/com/fsck/k9/crypto/EncryptionExtractor.kt create mode 100644 app/crypto-openpgp/build.gradle create mode 100644 app/crypto-openpgp/src/main/AndroidManifest.xml rename app/{core/src/main/java/com/fsck/k9/message/extractors => crypto-openpgp/src/main/java/com/fsck/k9/crypto/openpgp}/EncryptionDetector.java (91%) create mode 100644 app/crypto-openpgp/src/main/java/com/fsck/k9/crypto/openpgp/OpenPgpEncryptionExtractor.kt rename app/{core/src/test/java/com/fsck/k9/message/extractors => crypto-openpgp/src/test/java/com/fsck/k9/crypto/openpgp}/EncryptionDetectorTest.java (82%) create mode 100644 app/crypto-openpgp/src/test/java/com/fsck/k9/crypto/openpgp/MessageCreationHelper.java create mode 100644 app/storage/src/main/java/com/fsck/k9/storage/migrations/MigrationTo66.kt diff --git a/app/core/src/main/java/com/fsck/k9/crypto/EncryptionExtractor.kt b/app/core/src/main/java/com/fsck/k9/crypto/EncryptionExtractor.kt new file mode 100644 index 00000000000..395d7430d1c --- /dev/null +++ b/app/core/src/main/java/com/fsck/k9/crypto/EncryptionExtractor.kt @@ -0,0 +1,17 @@ +package com.fsck.k9.crypto + +import android.content.ContentValues +import com.fsck.k9.mail.Message +import com.fsck.k9.message.extractors.PreviewResult + +interface EncryptionExtractor { + fun extractEncryption(message: Message): EncryptionResult? +} + +data class EncryptionResult( + val encryptionType: String, + val attachmentCount: Int, + val previewResult: PreviewResult = PreviewResult.encrypted(), + val textForSearchIndex: String? = null, + val extraContentValues: ContentValues? = null +) diff --git a/app/core/src/main/java/com/fsck/k9/mailstore/LocalFolder.java b/app/core/src/main/java/com/fsck/k9/mailstore/LocalFolder.java index 801c04f6227..a4c079e26dd 100644 --- a/app/core/src/main/java/com/fsck/k9/mailstore/LocalFolder.java +++ b/app/core/src/main/java/com/fsck/k9/mailstore/LocalFolder.java @@ -31,6 +31,8 @@ import com.fsck.k9.K9; import com.fsck.k9.controller.MessageReference; import com.fsck.k9.backend.api.MessageRemovalListener; +import com.fsck.k9.crypto.EncryptionExtractor; +import com.fsck.k9.crypto.EncryptionResult; import com.fsck.k9.helper.FileHelper; import com.fsck.k9.helper.Utility; import com.fsck.k9.mail.Address; @@ -77,6 +79,7 @@ public class LocalFolder extends Folder { private final SearchStatusManager searchStatusManager = DI.get(SearchStatusManager.class); private final LocalStore localStore; private final AttachmentInfoExtractor attachmentInfoExtractor; + private final EncryptionExtractor encryptionExtractor = DI.get(EncryptionExtractor.class); private String serverId = null; @@ -1379,17 +1382,34 @@ private void saveMessage(SQLiteDatabase db, Message message, boolean copy, Map attachmentParts = new ArrayList<>(); MessageExtractor.findViewablesAndAttachments(message, null, attachmentParts); diff --git a/app/core/src/main/java/com/fsck/k9/message/extractors/MessageFulltextCreator.java b/app/core/src/main/java/com/fsck/k9/message/extractors/MessageFulltextCreator.java index 82dd8e4ed21..c596477d7e4 100644 --- a/app/core/src/main/java/com/fsck/k9/message/extractors/MessageFulltextCreator.java +++ b/app/core/src/main/java/com/fsck/k9/message/extractors/MessageFulltextCreator.java @@ -15,29 +15,18 @@ public class MessageFulltextCreator { private final TextPartFinder textPartFinder; - private final EncryptionDetector encryptionDetector; - MessageFulltextCreator(TextPartFinder textPartFinder, EncryptionDetector encryptionDetector) { + MessageFulltextCreator(TextPartFinder textPartFinder) { this.textPartFinder = textPartFinder; - this.encryptionDetector = encryptionDetector; } public static MessageFulltextCreator newInstance() { TextPartFinder textPartFinder = new TextPartFinder(); - EncryptionDetector encryptionDetector = new EncryptionDetector(textPartFinder); - return new MessageFulltextCreator(textPartFinder, encryptionDetector); + return new MessageFulltextCreator(textPartFinder); } public String createFulltext(@NonNull Message message) { - if (encryptionDetector.isEncrypted(message)) { - return null; - } - - return extractText(message); - } - - private String extractText(Message message) { Part textPart = textPartFinder.findFirstTextPart(message); if (textPart == null || hasEmptyBody(textPart)) { return null; diff --git a/app/core/src/main/java/com/fsck/k9/message/extractors/MessagePreviewCreator.java b/app/core/src/main/java/com/fsck/k9/message/extractors/MessagePreviewCreator.java index 88b2f935369..43cdcaacc82 100644 --- a/app/core/src/main/java/com/fsck/k9/message/extractors/MessagePreviewCreator.java +++ b/app/core/src/main/java/com/fsck/k9/message/extractors/MessagePreviewCreator.java @@ -10,32 +10,20 @@ public class MessagePreviewCreator { private final TextPartFinder textPartFinder; private final PreviewTextExtractor previewTextExtractor; - private final EncryptionDetector encryptionDetector; - MessagePreviewCreator(TextPartFinder textPartFinder, PreviewTextExtractor previewTextExtractor, - EncryptionDetector encryptionDetector) { + MessagePreviewCreator(TextPartFinder textPartFinder, PreviewTextExtractor previewTextExtractor) { this.textPartFinder = textPartFinder; this.previewTextExtractor = previewTextExtractor; - this.encryptionDetector = encryptionDetector; } public static MessagePreviewCreator newInstance() { TextPartFinder textPartFinder = new TextPartFinder(); PreviewTextExtractor previewTextExtractor = new PreviewTextExtractor(); - EncryptionDetector encryptionDetector = new EncryptionDetector(textPartFinder); - return new MessagePreviewCreator(textPartFinder, previewTextExtractor, encryptionDetector); + return new MessagePreviewCreator(textPartFinder, previewTextExtractor); } public PreviewResult createPreview(@NonNull Message message) { - if (encryptionDetector.isEncrypted(message)) { - return PreviewResult.encrypted(); - } - - return extractText(message); - } - - private PreviewResult extractText(Message message) { Part textPart = textPartFinder.findFirstTextPart(message); if (textPart == null || hasEmptyBody(textPart)) { return PreviewResult.none(); diff --git a/app/core/src/main/java/com/fsck/k9/message/extractors/TextPartFinder.java b/app/core/src/main/java/com/fsck/k9/message/extractors/TextPartFinder.java index aa375701566..56548cd16c9 100644 --- a/app/core/src/main/java/com/fsck/k9/message/extractors/TextPartFinder.java +++ b/app/core/src/main/java/com/fsck/k9/message/extractors/TextPartFinder.java @@ -12,7 +12,7 @@ import static com.fsck.k9.mail.internet.MimeUtility.isSameMimeType; -class TextPartFinder { +public class TextPartFinder { @Nullable public Part findFirstTextPart(@NonNull Part part) { String mimeType = part.getMimeType(); diff --git a/app/core/src/test/java/com/fsck/k9/TestApp.kt b/app/core/src/test/java/com/fsck/k9/TestApp.kt index 989e48542d4..b712c1b1ca4 100644 --- a/app/core/src/test/java/com/fsck/k9/TestApp.kt +++ b/app/core/src/test/java/com/fsck/k9/TestApp.kt @@ -1,6 +1,7 @@ package com.fsck.k9 import android.app.Application +import com.fsck.k9.crypto.EncryptionExtractor import com.fsck.k9.storage.storageModule import com.nhaarman.mockito_kotlin.mock import org.koin.dsl.module.applicationContext @@ -20,4 +21,5 @@ class TestApp : Application() { val testModule = applicationContext { bean { AppConfig(emptyList()) } bean { mock() } + bean { mock() } } diff --git a/app/core/src/test/java/com/fsck/k9/message/extractors/MessagePreviewCreatorTest.java b/app/core/src/test/java/com/fsck/k9/message/extractors/MessagePreviewCreatorTest.java index 7bab3f572e5..b1bde33c0b0 100644 --- a/app/core/src/test/java/com/fsck/k9/message/extractors/MessagePreviewCreatorTest.java +++ b/app/core/src/test/java/com/fsck/k9/message/extractors/MessagePreviewCreatorTest.java @@ -21,35 +21,19 @@ public class MessagePreviewCreatorTest { private TextPartFinder textPartFinder; private PreviewTextExtractor previewTextExtractor; - private EncryptionDetector encryptionDetector; private MessagePreviewCreator previewCreator; @Before public void setUp() throws Exception { textPartFinder = mock(TextPartFinder.class); previewTextExtractor = mock(PreviewTextExtractor.class); - encryptionDetector = mock(EncryptionDetector.class); - previewCreator = new MessagePreviewCreator(textPartFinder, previewTextExtractor, encryptionDetector); + previewCreator = new MessagePreviewCreator(textPartFinder, previewTextExtractor); } @Test - public void createPreview_withEncryptedMessage() throws Exception { + public void createPreview_withoutTextPart() { Message message = createDummyMessage(); - when(encryptionDetector.isEncrypted(message)).thenReturn(true); - - PreviewResult result = previewCreator.createPreview(message); - - assertFalse(result.isPreviewTextAvailable()); - assertEquals(PreviewType.ENCRYPTED, result.getPreviewType()); - verifyNoMoreInteractions(textPartFinder); - verifyNoMoreInteractions(previewTextExtractor); - } - - @Test - public void createPreview_withoutTextPart() throws Exception { - Message message = createDummyMessage(); - when(encryptionDetector.isEncrypted(message)).thenReturn(false); when(textPartFinder.findFirstTextPart(message)).thenReturn(null); PreviewResult result = previewCreator.createPreview(message); @@ -63,7 +47,6 @@ public void createPreview_withoutTextPart() throws Exception { public void createPreview_withEmptyTextPart() throws Exception { Message message = createDummyMessage(); Part textPart = createEmptyPart("text/plain"); - when(encryptionDetector.isEncrypted(message)).thenReturn(false); when(textPartFinder.findFirstTextPart(message)).thenReturn(textPart); PreviewResult result = previewCreator.createPreview(message); @@ -77,7 +60,6 @@ public void createPreview_withEmptyTextPart() throws Exception { public void createPreview_withTextPart() throws Exception { Message message = createDummyMessage(); Part textPart = createTextPart("text/plain"); - when(encryptionDetector.isEncrypted(message)).thenReturn(false); when(textPartFinder.findFirstTextPart(message)).thenReturn(textPart); when(previewTextExtractor.extractPreview(textPart)).thenReturn("expected"); @@ -92,7 +74,6 @@ public void createPreview_withTextPart() throws Exception { public void createPreview_withPreviewTextExtractorThrowing() throws Exception { Message message = createDummyMessage(); Part textPart = createTextPart("text/plain"); - when(encryptionDetector.isEncrypted(message)).thenReturn(false); when(textPartFinder.findFirstTextPart(message)).thenReturn(textPart); when(previewTextExtractor.extractPreview(textPart)).thenThrow(new PreviewExtractionException("")); diff --git a/app/crypto-openpgp/build.gradle b/app/crypto-openpgp/build.gradle new file mode 100644 index 00000000000..5175b6fec0e --- /dev/null +++ b/app/crypto-openpgp/build.gradle @@ -0,0 +1,33 @@ +apply plugin: 'com.android.library' +apply plugin: 'org.jetbrains.kotlin.android' + +apply from: "${rootProject.projectDir}/gradle/plugins/checkstyle-android.gradle" +apply from: "${rootProject.projectDir}/gradle/plugins/findbugs-android.gradle" + +dependencies { + implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:${versions.kotlin}" + + implementation project(":app:core") + + testImplementation "junit:junit:${versions.junit}" + testImplementation "org.mockito:mockito-core:${versions.mockito}" +} + +android { + compileSdkVersion buildConfig.compileSdk + buildToolsVersion buildConfig.buildTools + + defaultConfig { + minSdkVersion buildConfig.minSdk + } + + lintOptions { + abortOnError false + lintConfig file("$rootProject.projectDir/config/lint/lint.xml") + } + + compileOptions { + sourceCompatibility JavaVersion.VERSION_1_7 + targetCompatibility JavaVersion.VERSION_1_7 + } +} diff --git a/app/crypto-openpgp/src/main/AndroidManifest.xml b/app/crypto-openpgp/src/main/AndroidManifest.xml new file mode 100644 index 00000000000..2cdc574d919 --- /dev/null +++ b/app/crypto-openpgp/src/main/AndroidManifest.xml @@ -0,0 +1,2 @@ + + diff --git a/app/core/src/main/java/com/fsck/k9/message/extractors/EncryptionDetector.java b/app/crypto-openpgp/src/main/java/com/fsck/k9/crypto/openpgp/EncryptionDetector.java similarity index 91% rename from app/core/src/main/java/com/fsck/k9/message/extractors/EncryptionDetector.java rename to app/crypto-openpgp/src/main/java/com/fsck/k9/crypto/openpgp/EncryptionDetector.java index 084c9c51264..2e0ada8b09b 100644 --- a/app/core/src/main/java/com/fsck/k9/message/extractors/EncryptionDetector.java +++ b/app/crypto-openpgp/src/main/java/com/fsck/k9/crypto/openpgp/EncryptionDetector.java @@ -1,4 +1,4 @@ -package com.fsck.k9.message.extractors; +package com.fsck.k9.crypto.openpgp; import android.support.annotation.NonNull; @@ -9,10 +9,12 @@ import com.fsck.k9.mail.Message; import com.fsck.k9.mail.Multipart; import com.fsck.k9.mail.Part; +import com.fsck.k9.message.extractors.TextPartFinder; import static com.fsck.k9.mail.internet.MimeUtility.isSameMimeType; +//FIXME: Make this only detect OpenPGP messages. Move support for S/MIME messages to separate module. class EncryptionDetector { private final TextPartFinder textPartFinder; diff --git a/app/crypto-openpgp/src/main/java/com/fsck/k9/crypto/openpgp/OpenPgpEncryptionExtractor.kt b/app/crypto-openpgp/src/main/java/com/fsck/k9/crypto/openpgp/OpenPgpEncryptionExtractor.kt new file mode 100644 index 00000000000..64467b34bdb --- /dev/null +++ b/app/crypto-openpgp/src/main/java/com/fsck/k9/crypto/openpgp/OpenPgpEncryptionExtractor.kt @@ -0,0 +1,31 @@ +package com.fsck.k9.crypto.openpgp + +import com.fsck.k9.crypto.EncryptionExtractor +import com.fsck.k9.crypto.EncryptionResult +import com.fsck.k9.mail.Message +import com.fsck.k9.message.extractors.TextPartFinder + +class OpenPgpEncryptionExtractor internal constructor( + private val encryptionDetector: EncryptionDetector +) : EncryptionExtractor { + + override fun extractEncryption(message: Message): EncryptionResult? { + return if (encryptionDetector.isEncrypted(message)) { + EncryptionResult(ENCRYPTION_TYPE, 0) + } else { + null + } + } + + + companion object { + const val ENCRYPTION_TYPE = "openpgp" + + @JvmStatic + fun newInstance(): OpenPgpEncryptionExtractor { + val textPartFinder = TextPartFinder() + val encryptionDetector = EncryptionDetector(textPartFinder) + return OpenPgpEncryptionExtractor(encryptionDetector) + } + } +} diff --git a/app/core/src/test/java/com/fsck/k9/message/extractors/EncryptionDetectorTest.java b/app/crypto-openpgp/src/test/java/com/fsck/k9/crypto/openpgp/EncryptionDetectorTest.java similarity index 82% rename from app/core/src/test/java/com/fsck/k9/message/extractors/EncryptionDetectorTest.java rename to app/crypto-openpgp/src/test/java/com/fsck/k9/crypto/openpgp/EncryptionDetectorTest.java index 9114afc7eda..494ac31947f 100644 --- a/app/core/src/test/java/com/fsck/k9/message/extractors/EncryptionDetectorTest.java +++ b/app/crypto-openpgp/src/test/java/com/fsck/k9/crypto/openpgp/EncryptionDetectorTest.java @@ -1,14 +1,15 @@ -package com.fsck.k9.message.extractors; +package com.fsck.k9.crypto.openpgp; import com.fsck.k9.mail.Message; +import com.fsck.k9.message.extractors.TextPartFinder; import org.junit.Before; import org.junit.Test; -import static com.fsck.k9.message.MessageCreationHelper.createMessage; -import static com.fsck.k9.message.MessageCreationHelper.createMultipartMessage; -import static com.fsck.k9.message.MessageCreationHelper.createPart; -import static com.fsck.k9.message.MessageCreationHelper.createTextMessage; +import static com.fsck.k9.crypto.openpgp.MessageCreationHelper.createMessage; +import static com.fsck.k9.crypto.openpgp.MessageCreationHelper.createMultipartMessage; +import static com.fsck.k9.crypto.openpgp.MessageCreationHelper.createPart; +import static com.fsck.k9.crypto.openpgp.MessageCreationHelper.createTextMessage; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; import static org.mockito.Mockito.mock; @@ -24,14 +25,14 @@ public class EncryptionDetectorTest { @Before - public void setUp() throws Exception { + public void setUp() { textPartFinder = mock(TextPartFinder.class); encryptionDetector = new EncryptionDetector(textPartFinder); } @Test - public void isEncrypted_withTextPlain_shouldReturnFalse() throws Exception { + public void isEncrypted_withTextPlain_shouldReturnFalse() { Message message = createTextMessage("text/plain", "plain text"); boolean encrypted = encryptionDetector.isEncrypted(message); @@ -50,7 +51,7 @@ public void isEncrypted_withMultipartEncrypted_shouldReturnTrue() throws Excepti } @Test - public void isEncrypted_withSMimePart_shouldReturnTrue() throws Exception { + public void isEncrypted_withSMimePart_shouldReturnTrue() { Message message = createMessage("application/pkcs7-mime"); boolean encrypted = encryptionDetector.isEncrypted(message); @@ -69,7 +70,7 @@ public void isEncrypted_withMultipartMixedContainingSMimePart_shouldReturnTrue() } @Test - public void isEncrypted_withInlinePgp_shouldReturnTrue() throws Exception { + public void isEncrypted_withInlinePgp_shouldReturnTrue() { Message message = createTextMessage("text/plain", "" + "-----BEGIN PGP MESSAGE-----" + CRLF + "some encrypted stuff here" + CRLF + @@ -82,7 +83,7 @@ public void isEncrypted_withInlinePgp_shouldReturnTrue() throws Exception { } @Test - public void isEncrypted_withPlainTextAndPreambleWithInlinePgp_shouldReturnFalse() throws Exception { + public void isEncrypted_withPlainTextAndPreambleWithInlinePgp_shouldReturnFalse() { Message message = createTextMessage("text/plain", "" + "preamble" + CRLF + "-----BEGIN PGP MESSAGE-----" + CRLF + @@ -97,7 +98,7 @@ public void isEncrypted_withPlainTextAndPreambleWithInlinePgp_shouldReturnFalse( } @Test - public void isEncrypted_withQuotedInlinePgp_shouldReturnFalse() throws Exception { + public void isEncrypted_withQuotedInlinePgp_shouldReturnFalse() { Message message = createTextMessage("text/plain", "" + "good talk!" + CRLF + CRLF + diff --git a/app/crypto-openpgp/src/test/java/com/fsck/k9/crypto/openpgp/MessageCreationHelper.java b/app/crypto-openpgp/src/test/java/com/fsck/k9/crypto/openpgp/MessageCreationHelper.java new file mode 100644 index 00000000000..c1747182ec8 --- /dev/null +++ b/app/crypto-openpgp/src/test/java/com/fsck/k9/crypto/openpgp/MessageCreationHelper.java @@ -0,0 +1,51 @@ +package com.fsck.k9.crypto.openpgp; + + +import com.fsck.k9.mail.Body; +import com.fsck.k9.mail.BodyPart; +import com.fsck.k9.mail.Message; +import com.fsck.k9.mail.MessagingException; +import com.fsck.k9.mail.internet.MimeBodyPart; +import com.fsck.k9.mail.internet.MimeHeader; +import com.fsck.k9.mail.internet.MimeMessage; +import com.fsck.k9.mail.internet.MimeMultipart; +import com.fsck.k9.mail.internet.TextBody; +import com.fsck.k9.mailstore.BinaryMemoryBody; + + +public class MessageCreationHelper { + public static BodyPart createPart(String mimeType) throws MessagingException { + BinaryMemoryBody body = new BinaryMemoryBody(new byte[0], "utf-8"); + return new MimeBodyPart(body, mimeType); + } + + public static Message createTextMessage(String mimeType, String text) { + TextBody body = new TextBody(text); + return createMessage(mimeType, body); + } + + public static Message createMultipartMessage(String mimeType, BodyPart... parts) { + MimeMultipart body = createMultipartBody(mimeType, parts); + return createMessage(mimeType, body); + } + + public static Message createMessage(String mimeType) { + return createMessage(mimeType, null); + } + + private static Message createMessage(String mimeType, Body body) { + MimeMessage message = new MimeMessage(); + message.setBody(body); + message.setHeader(MimeHeader.HEADER_CONTENT_TYPE, mimeType); + + return message; + } + + private static MimeMultipart createMultipartBody(String mimeType, BodyPart[] parts) { + MimeMultipart multipart = new MimeMultipart(mimeType, "boundary"); + for (BodyPart part : parts) { + multipart.addBodyPart(part); + } + return multipart; + } +} diff --git a/app/k9mail/build.gradle b/app/k9mail/build.gradle index beebfabbcd1..3f3de7da7f9 100644 --- a/app/k9mail/build.gradle +++ b/app/k9mail/build.gradle @@ -15,6 +15,7 @@ dependencies { implementation project(":app:ui") implementation project(":app:core") implementation project(":app:storage") + implementation project(":app:crypto-openpgp") implementation project(":backend:imap") implementation project(":backend:pop3") implementation project(":backend:webdav") diff --git a/app/k9mail/src/main/java/com/fsck/k9/Dependencies.kt b/app/k9mail/src/main/java/com/fsck/k9/Dependencies.kt index d8cccb5fa59..0345fffbe18 100644 --- a/app/k9mail/src/main/java/com/fsck/k9/Dependencies.kt +++ b/app/k9mail/src/main/java/com/fsck/k9/Dependencies.kt @@ -2,6 +2,8 @@ package com.fsck.k9 import com.fsck.k9.backends.backendsModule import com.fsck.k9.controller.ControllerExtension +import com.fsck.k9.crypto.EncryptionExtractor +import com.fsck.k9.crypto.openpgp.OpenPgpEncryptionExtractor import com.fsck.k9.external.BroadcastSenderListener import com.fsck.k9.external.externalModule import com.fsck.k9.notification.notificationModule @@ -23,6 +25,7 @@ private val mainAppModule = applicationContext { )) } bean("controllerExtensions") { emptyList() } + bean { OpenPgpEncryptionExtractor.newInstance() as EncryptionExtractor } } val appModules = listOf( diff --git a/app/storage/src/main/java/com/fsck/k9/storage/StoreSchemaDefinition.java b/app/storage/src/main/java/com/fsck/k9/storage/StoreSchemaDefinition.java index ee1647baff3..4e8be792fbb 100644 --- a/app/storage/src/main/java/com/fsck/k9/storage/StoreSchemaDefinition.java +++ b/app/storage/src/main/java/com/fsck/k9/storage/StoreSchemaDefinition.java @@ -12,7 +12,7 @@ class StoreSchemaDefinition implements SchemaDefinition { - static final int DB_VERSION = 65; + static final int DB_VERSION = 66; private final MigrationsHelper migrationsHelper; @@ -134,7 +134,8 @@ private static void dbCreateDatabaseFromScratch(SQLiteDatabase db) { "flagged INTEGER default 0, " + "answered INTEGER default 0, " + "forwarded INTEGER default 0, " + - "message_part_id INTEGER" + + "message_part_id INTEGER," + + "encryption_type TEXT" + ")"); db.execSQL("DROP TABLE IF EXISTS message_parts"); diff --git a/app/storage/src/main/java/com/fsck/k9/storage/migrations/MigrationTo66.kt b/app/storage/src/main/java/com/fsck/k9/storage/migrations/MigrationTo66.kt new file mode 100644 index 00000000000..998d5e4464f --- /dev/null +++ b/app/storage/src/main/java/com/fsck/k9/storage/migrations/MigrationTo66.kt @@ -0,0 +1,13 @@ +package com.fsck.k9.storage.migrations + +import android.database.sqlite.SQLiteDatabase + + +internal object MigrationTo66 { + @JvmStatic + fun addEncryptionTypeColumnToMessagesTable(db: SQLiteDatabase) { + db.execSQL("ALTER TABLE messages ADD encryption_type TEXT") + + db.execSQL("UPDATE messages SET encryption_type = 'openpgp' WHERE preview_type = 'encrypted'") + } +} diff --git a/app/storage/src/main/java/com/fsck/k9/storage/migrations/Migrations.java b/app/storage/src/main/java/com/fsck/k9/storage/migrations/Migrations.java index d80d429d22b..92575437565 100644 --- a/app/storage/src/main/java/com/fsck/k9/storage/migrations/Migrations.java +++ b/app/storage/src/main/java/com/fsck/k9/storage/migrations/Migrations.java @@ -88,6 +88,8 @@ public static void upgradeDatabase(SQLiteDatabase db, MigrationsHelper migration MigrationTo64.addExtraValuesTables(db); case 64: MigrationTo65.addLocalOnlyColumnToFoldersTable(db, migrationsHelper); + case 65: + MigrationTo66.addEncryptionTypeColumnToMessagesTable(db); } if (shouldBuildFtsTable) { diff --git a/app/storage/src/test/java/com/fsck/k9/storage/TestApp.kt b/app/storage/src/test/java/com/fsck/k9/storage/TestApp.kt index 792b709a8f0..5f90c969f16 100644 --- a/app/storage/src/test/java/com/fsck/k9/storage/TestApp.kt +++ b/app/storage/src/test/java/com/fsck/k9/storage/TestApp.kt @@ -6,6 +6,7 @@ import com.fsck.k9.Core import com.fsck.k9.CoreResourceProvider import com.fsck.k9.DI import com.fsck.k9.K9 +import com.fsck.k9.crypto.EncryptionExtractor import com.nhaarman.mockito_kotlin.mock import org.koin.dsl.module.applicationContext @@ -24,4 +25,5 @@ class TestApp : Application() { val testModule = applicationContext { bean { AppConfig(emptyList()) } bean { mock() } + bean { mock() } } diff --git a/settings.gradle b/settings.gradle index 6b9cbd25a78..45f51551519 100644 --- a/settings.gradle +++ b/settings.gradle @@ -2,6 +2,7 @@ include ':app:k9mail' include ':app:ui' include ':app:core' include ':app:storage' +include ':app:crypto-openpgp' include ':mail:common' include ':mail:testing' include ':mail:protocols:imap'