Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Unverified Commit c577c908 authored by cketti's avatar cketti Committed by GitHub
Browse files

Merge pull request #3302 from k9mail/encrypt-drafts-to-self

Encrypt drafts to self
parents 67df4295 213646d5
Loading
Loading
Loading
Loading
+11 −0
Original line number Diff line number Diff line
@@ -216,6 +216,7 @@ public class Account implements BaseAccount, StoreConfig {
    private boolean autocryptPreferEncryptMutual;
    private boolean openPgpHideSignOnly;
    private boolean openPgpEncryptSubject;
    private boolean openPgpEncryptAllDrafts;
    private boolean markMessageAsReadOnView;
    private boolean alwaysShowCcBcc;
    private boolean allowRemoteSearch;
@@ -461,6 +462,7 @@ public class Account implements BaseAccount, StoreConfig {
        openPgpKey = storage.getLong(accountUuid + ".cryptoKey", NO_OPENPGP_KEY);
        openPgpHideSignOnly = storage.getBoolean(accountUuid + ".openPgpHideSignOnly", true);
        openPgpEncryptSubject = storage.getBoolean(accountUuid + ".openPgpEncryptSubject", true);
        openPgpEncryptAllDrafts = storage.getBoolean(accountUuid + ".openPgpEncryptAllDrafts", true);
        autocryptPreferEncryptMutual = storage.getBoolean(accountUuid + ".autocryptMutualMode", false);
        allowRemoteSearch = storage.getBoolean(accountUuid + ".allowRemoteSearch", false);
        remoteSearchFullText = storage.getBoolean(accountUuid + ".remoteSearchFullText", false);
@@ -740,6 +742,7 @@ public class Account implements BaseAccount, StoreConfig {
        editor.putLong(accountUuid + ".cryptoKey", openPgpKey);
        editor.putBoolean(accountUuid + ".openPgpHideSignOnly", openPgpHideSignOnly);
        editor.putBoolean(accountUuid + ".openPgpEncryptSubject", openPgpEncryptSubject);
        editor.putBoolean(accountUuid + ".openPgpEncryptAllDrafts", openPgpEncryptAllDrafts);
        editor.putString(accountUuid + ".openPgpProvider", openPgpProvider);
        editor.putBoolean(accountUuid + ".autocryptMutualMode", autocryptPreferEncryptMutual);
        editor.putBoolean(accountUuid + ".allowRemoteSearch", allowRemoteSearch);
@@ -1591,6 +1594,14 @@ public class Account implements BaseAccount, StoreConfig {
        this.openPgpEncryptSubject = openPgpEncryptSubject;
    }

    public boolean getOpenPgpEncryptAllDrafts() {
        return openPgpEncryptAllDrafts;
    }

    public void setOpenPgpEncryptAllDrafts(boolean openPgpEncryptAllDrafts) {
        this.openPgpEncryptAllDrafts = openPgpEncryptAllDrafts;
    }

    public boolean allowRemoteSearch() {
        return allowRemoteSearch;
    }
+57 −0
Original line number Diff line number Diff line
package com.fsck.k9.autocrypt

import com.fsck.k9.message.CryptoStatus


data class AutocryptDraftStateHeader(val isEncrypt: Boolean,
                                              val isSignOnly: Boolean,
                                              val isReply: Boolean,
                                              val isByChoice: Boolean,
                                              val isPgpInline: Boolean,
                                              val parameters: Map<String, String> = mapOf()) {

    fun toHeaderValue(): String {
        val builder = StringBuilder()

        builder.append(AutocryptDraftStateHeader.PARAM_ENCRYPT)
        builder.append(if (isEncrypt) "=yes; " else "=no; ")

        if (isReply) {
            builder.append(AutocryptDraftStateHeader.PARAM_IS_REPLY).append("=yes; ")
        }
        if (isSignOnly) {
            builder.append(AutocryptDraftStateHeader.PARAM_SIGN_ONLY).append("=yes; ")
        }
        if (isByChoice) {
            builder.append(AutocryptDraftStateHeader.PARAM_BY_CHOICE).append("=yes; ")
        }
        if (isPgpInline) {
            builder.append(AutocryptDraftStateHeader.PARAM_PGP_INLINE).append("=yes; ")
        }

        return builder.toString()
    }

    companion object {
        const val AUTOCRYPT_DRAFT_STATE_HEADER = "Autocrypt-Draft-State"

        const val PARAM_ENCRYPT = "encrypt"

        const val PARAM_IS_REPLY = "_is-reply-to-encrypted"
        const val PARAM_BY_CHOICE = "_by-choice"
        const val PARAM_PGP_INLINE = "_pgp-inline"
        const val PARAM_SIGN_ONLY = "_sign-only"

        const val VALUE_YES = "yes";

        @JvmStatic
        fun fromCryptoStatus(cryptoStatus: CryptoStatus): AutocryptDraftStateHeader {
            if (cryptoStatus.isSignOnly) {
                return AutocryptDraftStateHeader(false, true, cryptoStatus.isReplyToEncrypted,
                        cryptoStatus.isUserChoice(), cryptoStatus.isPgpInlineModeEnabled, mapOf())
            }
            return AutocryptDraftStateHeader(cryptoStatus.isEncryptionEnabled, false, cryptoStatus.isReplyToEncrypted,
                    cryptoStatus.isUserChoice(), cryptoStatus.isPgpInlineModeEnabled, mapOf())
        }
    }
}
+42 −0
Original line number Diff line number Diff line
package com.fsck.k9.autocrypt


import com.fsck.k9.mail.internet.MimeUtility


class AutocryptDraftStateHeaderParser internal constructor() {

    fun parseAutocryptDraftStateHeader(headerValue: String): AutocryptDraftStateHeader? {
        val parameters = MimeUtility.getAllHeaderParameters(headerValue)

        val isEncryptStr = parameters.remove(AutocryptDraftStateHeader.PARAM_ENCRYPT) ?: return null
        val isEncrypt = isEncryptStr == AutocryptDraftStateHeader.VALUE_YES

        val isSignOnlyStr = parameters.remove(AutocryptDraftStateHeader.PARAM_SIGN_ONLY)
        val isSignOnly = isSignOnlyStr == AutocryptDraftStateHeader.VALUE_YES

        val isReplyStr = parameters.remove(AutocryptDraftStateHeader.PARAM_IS_REPLY)
        val isReply = isReplyStr == AutocryptDraftStateHeader.VALUE_YES

        val isByChoiceStr = parameters.remove(AutocryptDraftStateHeader.PARAM_BY_CHOICE)
        val isByChoice = isByChoiceStr == AutocryptDraftStateHeader.VALUE_YES

        val isPgpInlineStr = parameters.remove(AutocryptDraftStateHeader.PARAM_PGP_INLINE)
        val isPgpInline = isPgpInlineStr == AutocryptDraftStateHeader.VALUE_YES

        if (hasCriticalParameters(parameters)) {
            return null
        }

        return AutocryptDraftStateHeader(isEncrypt, isSignOnly, isReply, isByChoice, isPgpInline, parameters)
    }

    private fun hasCriticalParameters(parameters: Map<String, String>): Boolean {
        for (parameterName in parameters.keys) {
            if (!parameterName.startsWith("_")) {
                return true
            }
        }
        return false
    }
}
+1 −0
Original line number Diff line number Diff line
@@ -4,4 +4,5 @@ import org.koin.dsl.module.applicationContext

val autocryptModule = applicationContext {
    bean { AutocryptTransferMessageCreator(get()) }
    bean { AutocryptDraftStateHeaderParser() }
}
 No newline at end of file
+9 −4
Original line number Diff line number Diff line
@@ -1443,14 +1443,16 @@ public class MessagingController {
     */
    public void sendMessage(final Account account,
            final Message message,
            String plaintextSubject,
            MessagingListener listener) {
        try {
            LocalStore localStore = account.getLocalStore();
            LocalFolder localFolder = localStore.getFolder(account.getOutboxFolder());
            localFolder.open(Folder.OPEN_MODE_RW);
            localFolder.appendMessages(Collections.singletonList(message));
            Message localMessage = localFolder.getMessage(message.getUid());
            LocalMessage localMessage = localFolder.getMessage(message.getUid());
            localMessage.setFlag(Flag.X_DOWNLOADED_FULL, true);
            localMessage.setCachedDecryptedSubject(plaintextSubject);
            localFolder.close();
            sendPendingMessages(account, listener);
        } catch (Exception e) {
@@ -1601,7 +1603,7 @@ public class MessagingController {

                    localFolder.fetch(Collections.singletonList(message), fp, null);
                    try {
                        if (message.getHeader(K9.IDENTITY_HEADER).length > 0) {
                        if (message.getHeader(K9.IDENTITY_HEADER).length > 0 || message.isSet(Flag.DRAFT)) {
                            Timber.v("The user has set the Outbox and Drafts folder to the same thing. " +
                                    "This message appears to be a draft, so K-9 will not send it");
                            continue;
@@ -2760,8 +2762,8 @@ public class MessagingController {
     *
     * @return Message representing the entry in the local store.
     */
    public Message saveDraft(final Account account, final Message message, long existingDraftId, boolean saveRemotely) {
        Message localMessage = null;
    public Message saveDraft(final Account account, final Message message, long existingDraftId, String plaintextSubject, boolean saveRemotely) {
        LocalMessage localMessage = null;
        try {
            LocalStore localStore = account.getLocalStore();
            LocalFolder localFolder = localStore.getFolder(account.getDraftsFolder());
@@ -2777,6 +2779,9 @@ public class MessagingController {
            // Fetch the message back from the store.  This is the Message that's returned to the caller.
            localMessage = localFolder.getMessage(message.getUid());
            localMessage.setFlag(Flag.X_DOWNLOADED_FULL, true);
            if (plaintextSubject != null) {
                localMessage.setCachedDecryptedSubject(plaintextSubject);
            }

            if (saveRemotely) {
                PendingCommand command = PendingAppend.create(localFolder.getServerId(), localMessage.getUid());
Loading