Remove Account.storeUri and Account.transportUri

The URIs are still used as serialization format when saving settings
This commit is contained in:
cketti 2021-01-31 15:21:19 +01:00
parent c35876a3ae
commit de2560b90b
33 changed files with 164 additions and 162 deletions

View file

@ -17,6 +17,7 @@ import android.text.TextUtils;
import com.fsck.k9.backend.api.SyncConfig.ExpungePolicy;
import com.fsck.k9.mail.Address;
import com.fsck.k9.mail.NetworkType;
import com.fsck.k9.mail.ServerSettings;
import com.fsck.k9.mailstore.StorageManager;
import com.fsck.k9.mailstore.StorageManager.StorageProvider;
import org.jetbrains.annotations.NotNull;
@ -101,14 +102,14 @@ public class Account implements BaseAccount {
private DeletePolicy deletePolicy = DeletePolicy.NEVER;
private final String accountUuid;
private String storeUri;
private ServerSettings incomingServerSettings;
private ServerSettings outgoingServerSettings;
/**
* Storage provider ID, used to locate and manage the underlying DB/file
* storage
*/
private String localStorageProviderId;
private String transportUri;
private String description;
private String alwaysBcc;
private int automaticCheckIntervalMinutes;
@ -254,20 +255,20 @@ public class Account implements BaseAccount {
return accountUuid;
}
public synchronized String getStoreUri() {
return storeUri;
public synchronized ServerSettings getIncomingServerSettings() {
return incomingServerSettings;
}
public synchronized void setStoreUri(String storeUri) {
this.storeUri = storeUri;
public synchronized void setIncomingServerSettings(ServerSettings incomingServerSettings) {
this.incomingServerSettings = incomingServerSettings;
}
public synchronized String getTransportUri() {
return transportUri;
public synchronized ServerSettings getOutgoingServerSettings() {
return outgoingServerSettings;
}
public synchronized void setTransportUri(String transportUri) {
this.transportUri = transportUri;
public synchronized void setOutgoingServerSettings(ServerSettings outgoingServerSettings) {
this.outgoingServerSettings = outgoingServerSettings;
}
@Override

View file

@ -16,7 +16,6 @@ import com.fsck.k9.Account.SpecialFolderSelection
import com.fsck.k9.Account.UNASSIGNED_ACCOUNT_NUMBER
import com.fsck.k9.helper.Utility
import com.fsck.k9.mail.NetworkType
import com.fsck.k9.mail.filter.Base64
import com.fsck.k9.mailstore.StorageManager
import com.fsck.k9.preferences.Storage
import com.fsck.k9.preferences.StorageEditor
@ -24,16 +23,17 @@ import timber.log.Timber
class AccountPreferenceSerializer(
private val storageManager: StorageManager,
private val resourceProvider: CoreResourceProvider
private val resourceProvider: CoreResourceProvider,
private val serverSettingsSerializer: ServerSettingsSerializer
) {
@Synchronized
fun loadAccount(account: Account, storage: Storage) {
val accountUuid = account.uuid
with(account) {
storeUri = Base64.decode(storage.getString("$accountUuid.storeUri", null))
incomingServerSettings = serverSettingsSerializer.deserializeIncoming(storage.getString("$accountUuid.storeUri", ""))
outgoingServerSettings = serverSettingsSerializer.deserializeOutgoing(storage.getString("$accountUuid.transportUri", ""))
localStorageProviderId = storage.getString("$accountUuid.localStorageProvider", storageManager.defaultProviderId)
transportUri = Base64.decode(storage.getString("$accountUuid.transportUri", null))
description = storage.getString("$accountUuid.description", null)
alwaysBcc = storage.getString("$accountUuid.alwaysBcc", alwaysBcc)
automaticCheckIntervalMinutes = storage.getInt("$accountUuid.automaticCheckIntervalMinutes", DEFAULT_SYNC_INTERVAL)
@ -244,9 +244,9 @@ class AccountPreferenceSerializer(
}
with(account) {
editor.putString("$accountUuid.storeUri", Base64.encode(storeUri))
editor.putString("$accountUuid.storeUri", serverSettingsSerializer.serializeIncoming(incomingServerSettings))
editor.putString("$accountUuid.transportUri", serverSettingsSerializer.serializeOutgoing(outgoingServerSettings))
editor.putString("$accountUuid.localStorageProvider", localStorageProviderId)
editor.putString("$accountUuid.transportUri", Base64.encode(transportUri))
editor.putString("$accountUuid.description", description)
editor.putString("$accountUuid.alwaysBcc", alwaysBcc)
editor.putInt("$accountUuid.automaticCheckIntervalMinutes", automaticCheckIntervalMinutes)

View file

@ -26,4 +26,5 @@ val mainModule = module {
single { Clock.INSTANCE }
factory { ServerNameSuggester() }
factory { EmailAddressValidator() }
factory { ServerSettingsSerializer() }
}

View file

@ -1,6 +1,5 @@
package com.fsck.k9
import android.net.Uri
import com.fsck.k9.mail.MailServerDirection
import com.fsck.k9.mail.ssl.LocalKeyStore
import java.security.cert.CertificateException
@ -14,12 +13,12 @@ class LocalKeyStoreManager(
*/
@Throws(CertificateException::class)
fun addCertificate(account: Account, direction: MailServerDirection, certificate: X509Certificate) {
val uri = if (direction === MailServerDirection.INCOMING) {
Uri.parse(account.storeUri)
val serverSettings = if (direction === MailServerDirection.INCOMING) {
account.incomingServerSettings
} else {
Uri.parse(account.transportUri)
account.outgoingServerSettings
}
localKeyStore.addCertificate(uri.host, uri.port, certificate)
localKeyStore.addCertificate(serverSettings.host, serverSettings.port, certificate)
}
/**
@ -28,13 +27,13 @@ class LocalKeyStoreManager(
* old host/port.
*/
fun deleteCertificate(account: Account, newHost: String, newPort: Int, direction: MailServerDirection) {
val uri = if (direction === MailServerDirection.INCOMING) {
Uri.parse(account.storeUri)
val serverSettings = if (direction === MailServerDirection.INCOMING) {
account.incomingServerSettings
} else {
Uri.parse(account.transportUri)
account.outgoingServerSettings
}
val oldHost = uri.host
val oldPort = uri.port
val oldHost = serverSettings.host
val oldPort = serverSettings.port
if (oldPort == -1) {
// This occurs when a new account is created
return
@ -49,15 +48,12 @@ class LocalKeyStoreManager(
* certificates for the incoming and outgoing servers.
*/
fun deleteCertificates(account: Account) {
val storeUri = account.storeUri
if (storeUri != null) {
val uri = Uri.parse(storeUri)
localKeyStore.deleteCertificate(uri.host, uri.port)
account.incomingServerSettings?.let { serverSettings ->
localKeyStore.deleteCertificate(serverSettings.host, serverSettings.port)
}
val transportUri = account.transportUri
if (transportUri != null) {
val uri = Uri.parse(transportUri)
localKeyStore.deleteCertificate(uri.host, uri.port)
account.outgoingServerSettings?.let { serverSettings ->
localKeyStore.deleteCertificate(serverSettings.host, serverSettings.port)
}
}
}

View file

@ -0,0 +1,27 @@
package com.fsck.k9
import com.fsck.k9.backend.BackendManager
import com.fsck.k9.mail.ServerSettings
import com.fsck.k9.mail.filter.Base64
import org.koin.core.KoinComponent
import org.koin.core.inject
class ServerSettingsSerializer : KoinComponent {
private val backendManager: BackendManager by inject()
fun serializeIncoming(serverSettings: ServerSettings): String {
return Base64.encode(backendManager.createStoreUri(serverSettings))
}
fun serializeOutgoing(serverSettings: ServerSettings): String {
return Base64.encode(backendManager.createTransportUri(serverSettings))
}
fun deserializeIncoming(uri: String): ServerSettings {
return backendManager.decodeStoreUri(Base64.decode(uri))
}
fun deserializeOutgoing(uri: String): ServerSettings {
return backendManager.decodeTransportUri(Base64.decode(uri))
}
}

View file

@ -14,14 +14,19 @@ class BackendManager(private val backendFactories: Map<String, BackendFactory>)
container.backend
} else {
createBackend(account).also { backend ->
backendCache[account.uuid] = BackendContainer(backend, account.storeUri, account.transportUri)
backendCache[account.uuid] = BackendContainer(
backend,
account.incomingServerSettings,
account.outgoingServerSettings
)
}
}
}
}
private fun isBackendStillValid(container: BackendContainer, account: Account): Boolean {
return container.storeUri == account.storeUri && container.transportUri == account.transportUri
return container.incomingServerSettings == account.incomingServerSettings &&
container.outgoingServerSettings == account.outgoingServerSettings
}
fun removeBackend(account: Account) {
@ -31,14 +36,9 @@ class BackendManager(private val backendFactories: Map<String, BackendFactory>)
}
private fun createBackend(account: Account): Backend {
val storeUri = account.storeUri
backendFactories.forEach { (storeUriPrefix, backendFactory) ->
if (storeUri.startsWith(storeUriPrefix)) {
return backendFactory.createBackend(account)
}
}
throw IllegalArgumentException("Unsupported account type")
val serverType = account.incomingServerSettings.type
val backendFactory = backendFactories[serverType] ?: error("Unsupported account type")
return backendFactory.createBackend(account)
}
fun decodeStoreUri(storeUri: String): ServerSettings {
@ -81,5 +81,9 @@ class BackendManager(private val backendFactories: Map<String, BackendFactory>)
throw IllegalArgumentException("Unsupported ServerSettings type")
}
private data class BackendContainer(val backend: Backend, val storeUri: String, val transportUri: String)
private data class BackendContainer(
val backend: Backend,
val incomingServerSettings: ServerSettings,
val outgoingServerSettings: ServerSettings
)
}

View file

@ -4,6 +4,7 @@ import com.fsck.k9.Account
import com.fsck.k9.Account.SpecialFolderSelection
import com.fsck.k9.Preferences
import com.fsck.k9.mail.FolderClass
import com.fsck.k9.preferences.Protocols
/**
* Updates special folders in [Account] if they are marked as [SpecialFolderSelection.AUTOMATIC] or if they are marked
@ -132,5 +133,5 @@ class SpecialFolderUpdater(
preferences.saveAccount(account)
}
private fun Account.isPop3() = storeUri.startsWith("pop3")
private fun Account.isPop3() = incomingServerSettings.type == Protocols.POP3
}

View file

@ -4,6 +4,7 @@ import com.fsck.k9.Account
import com.fsck.k9.Account.SpecialFolderSelection
import com.fsck.k9.Preferences
import com.fsck.k9.mail.FolderType
import com.fsck.k9.preferences.Protocols
import timber.log.Timber
class SpecialLocalFoldersCreator(
@ -49,7 +50,7 @@ class SpecialLocalFoldersCreator(
preferences.saveAccount(account)
}
private fun Account.isPop3() = storeUri.startsWith("pop3")
private fun Account.isPop3() = incomingServerSettings.type == Protocols.POP3
companion object {
private const val OUTBOX_FOLDER_NAME = Account.OUTBOX_NAME

View file

@ -19,7 +19,13 @@ val coreNotificationModule = module {
get()
)
}
single { AccountPreferenceSerializer(get(), get()) }
single {
AccountPreferenceSerializer(
storageManager = get(),
resourceProvider = get(),
serverSettingsSerializer = get()
)
}
single { CertificateErrorNotifications(get(), get(), get()) }
single { AuthenticationErrorNotifications(get(), get(), get()) }
single { SyncNotifications(get(), get(), get()) }

View file

@ -6,7 +6,6 @@ val preferencesModule = module {
factory {
SettingsExporter(
contentResolver = get(),
backendManager = get(),
preferences = get(),
folderSettingsProvider = get(),
folderRepositoryManager = get()

View file

@ -9,7 +9,6 @@ import com.fsck.k9.AccountPreferenceSerializer.Companion.IDENTITY_DESCRIPTION_KE
import com.fsck.k9.AccountPreferenceSerializer.Companion.IDENTITY_EMAIL_KEY
import com.fsck.k9.AccountPreferenceSerializer.Companion.IDENTITY_NAME_KEY
import com.fsck.k9.Preferences
import com.fsck.k9.backend.BackendManager
import com.fsck.k9.mailstore.FolderRepository
import com.fsck.k9.mailstore.FolderRepositoryManager
import com.fsck.k9.preferences.ServerTypeConverter.fromServerSettingsType
@ -23,7 +22,6 @@ import timber.log.Timber
class SettingsExporter(
private val contentResolver: ContentResolver,
private val backendManager: BackendManager,
private val preferences: Preferences,
private val folderSettingsProvider: FolderSettingsProvider,
private val folderRepositoryManager: FolderRepositoryManager
@ -117,7 +115,7 @@ class SettingsExporter(
}
// Write incoming server settings
val incoming = backendManager.decodeStoreUri(account.storeUri)
val incoming = account.incomingServerSettings
serializer.startTag(null, INCOMING_SERVER_ELEMENT)
serializer.attribute(null, TYPE_ATTRIBUTE, fromServerSettingsType(incoming.type))
@ -125,12 +123,8 @@ class SettingsExporter(
if (incoming.port != -1) {
writeElement(serializer, PORT_ELEMENT, incoming.port.toString())
}
if (incoming.connectionSecurity != null) {
writeElement(serializer, CONNECTION_SECURITY_ELEMENT, incoming.connectionSecurity.name)
}
if (incoming.authenticationType != null) {
writeElement(serializer, AUTHENTICATION_TYPE_ELEMENT, incoming.authenticationType.name)
}
writeElement(serializer, CONNECTION_SECURITY_ELEMENT, incoming.connectionSecurity.name)
writeElement(serializer, AUTHENTICATION_TYPE_ELEMENT, incoming.authenticationType.name)
writeElement(serializer, USERNAME_ELEMENT, incoming.username)
writeElement(serializer, CLIENT_CERTIFICATE_ALIAS_ELEMENT, incoming.clientCertificateAlias)
// XXX For now we don't export the password
@ -147,7 +141,7 @@ class SettingsExporter(
serializer.endTag(null, INCOMING_SERVER_ELEMENT)
// Write outgoing server settings
val outgoing = backendManager.decodeTransportUri(account.transportUri)
val outgoing = account.outgoingServerSettings
serializer.startTag(null, OUTGOING_SERVER_ELEMENT)
serializer.attribute(null, TYPE_ATTRIBUTE, fromServerSettingsType(outgoing.type))
@ -155,12 +149,8 @@ class SettingsExporter(
if (outgoing.port != -1) {
writeElement(serializer, PORT_ELEMENT, outgoing.port.toString())
}
if (outgoing.connectionSecurity != null) {
writeElement(serializer, CONNECTION_SECURITY_ELEMENT, outgoing.connectionSecurity.name)
}
if (outgoing.authenticationType != null) {
writeElement(serializer, AUTHENTICATION_TYPE_ELEMENT, outgoing.authenticationType.name)
}
writeElement(serializer, CONNECTION_SECURITY_ELEMENT, outgoing.connectionSecurity.name)
writeElement(serializer, AUTHENTICATION_TYPE_ELEMENT, outgoing.authenticationType.name)
writeElement(serializer, USERNAME_ELEMENT, outgoing.username)
writeElement(serializer, CLIENT_CERTIFICATE_ALIAS_ELEMENT, outgoing.clientCertificateAlias)
// XXX For now we don't export the password

View file

@ -5,7 +5,6 @@ import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;
@ -14,9 +13,9 @@ import java.util.UUID;
import android.content.Context;
import android.content.SharedPreferences;
import androidx.annotation.VisibleForTesting;
import android.text.TextUtils;
import androidx.annotation.VisibleForTesting;
import com.fsck.k9.Account;
import com.fsck.k9.AccountPreferenceSerializer;
import com.fsck.k9.Core;
@ -24,11 +23,10 @@ import com.fsck.k9.DI;
import com.fsck.k9.Identity;
import com.fsck.k9.K9;
import com.fsck.k9.Preferences;
import com.fsck.k9.backend.BackendManager;
import com.fsck.k9.ServerSettingsSerializer;
import com.fsck.k9.mail.AuthType;
import com.fsck.k9.mail.ConnectionSecurity;
import com.fsck.k9.mail.ServerSettings;
import com.fsck.k9.mail.filter.Base64;
import com.fsck.k9.mailstore.SpecialLocalFoldersCreator;
import com.fsck.k9.preferences.Settings.InvalidSettingValueException;
import org.xmlpull.v1.XmlPullParser;
@ -370,11 +368,11 @@ public class SettingsImporter {
throw new InvalidSettingValueException();
}
// Write incoming server settings (storeUri)
// Write incoming server settings
ServerSettings incoming = createServerSettings(account.incoming);
BackendManager backendManager = DI.get(BackendManager.class);
String storeUri = backendManager.createStoreUri(incoming);
putString(editor, accountKeyPrefix + AccountPreferenceSerializer.STORE_URI_KEY, Base64.encode(storeUri));
ServerSettingsSerializer serverSettingsSerializer = DI.get(ServerSettingsSerializer.class);
String storeUri = serverSettingsSerializer.serializeIncoming(incoming);
putString(editor, accountKeyPrefix + AccountPreferenceSerializer.STORE_URI_KEY, storeUri);
String incomingServerName = incoming.host;
boolean incomingPasswordNeeded = AuthType.EXTERNAL != incoming.authenticationType &&
@ -389,10 +387,10 @@ public class SettingsImporter {
String outgoingServerName = null;
boolean outgoingPasswordNeeded = false;
if (account.outgoing != null) {
// Write outgoing server settings (transportUri)
// Write outgoing server settings
ServerSettings outgoing = createServerSettings(account.outgoing);
String transportUri = backendManager.createTransportUri(outgoing);
putString(editor, accountKeyPrefix + AccountPreferenceSerializer.TRANSPORT_URI_KEY, Base64.encode(transportUri));
String transportUri = serverSettingsSerializer.serializeOutgoing(outgoing);
putString(editor, accountKeyPrefix + AccountPreferenceSerializer.TRANSPORT_URI_KEY, transportUri);
/*
* Mark account as disabled if the settings file contained a username but no password. However, no password
@ -644,7 +642,9 @@ public class SettingsImporter {
private static void putString(StorageEditor editor, String key, String value) {
if (K9.isDebugLoggingEnabled()) {
String outputValue = value;
if (!K9.isSensitiveDebugLoggingEnabled() && (key.endsWith(".transportUri") || key.endsWith(".storeUri"))) {
if (!K9.isSensitiveDebugLoggingEnabled() &&
(key.endsWith("." + AccountPreferenceSerializer.TRANSPORT_URI_KEY) ||
key.endsWith("." + AccountPreferenceSerializer.STORE_URI_KEY))) {
outputValue = "*sensitive*";
}
Timber.v("Setting %s=%s", key, outputValue);

View file

@ -22,7 +22,6 @@ class SettingsExporterTest : K9RobolectricTest() {
private val folderRepositoryManager: FolderRepositoryManager by inject()
private val settingsExporter = SettingsExporter(
contentResolver,
backendManager,
preferences,
folderSettingsProvider,
folderRepositoryManager

View file

@ -9,13 +9,12 @@ import java.util.UUID;
import com.fsck.k9.K9RobolectricTest;
import com.fsck.k9.Preferences;
import com.fsck.k9.mail.AuthType;
import kotlin.text.Charsets;
import okio.Buffer;
import org.junit.Before;
import org.junit.Test;
import org.robolectric.RuntimeEnvironment;
import kotlin.text.Charsets;
import okio.Buffer;
import static com.fsck.k9.preferences.MessagingControllerTestExtra.setUpBackendManager;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;

View file

@ -38,10 +38,9 @@ class ImapBackendFactory(
private fun createImapStore(account: Account): ImapStore {
val oAuth2TokenProvider: OAuth2TokenProvider? = null
val serverSettings = ImapStoreUriDecoder.decode(account.storeUri)
val config = createImapStoreConfig(account)
return ImapStore(
serverSettings,
account.incomingServerSettings,
config,
trustedSocketFactory,
context.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager,
@ -61,7 +60,7 @@ class ImapBackendFactory(
}
private fun createSmtpTransport(account: Account): SmtpTransport {
val serverSettings = decodeTransportUri(account.transportUri)
val serverSettings = account.outgoingServerSettings
val oauth2TokenProvider: OAuth2TokenProvider? = null
return SmtpTransport(serverSettings, trustedSocketFactory, oauth2TokenProvider)
}

View file

@ -23,8 +23,8 @@ class JmapAccountCreator(
val account = preferences.newAccount().apply {
email = emailAddress
description = jmapAccount.name
storeUri = backendManager.createStoreUri(serverSettings)
transportUri = backendManager.createTransportUri(serverSettings)
incomingServerSettings = serverSettings
outgoingServerSettings = serverSettings
chipColor = accountCreator.pickColor()
deletePolicy = Account.DeletePolicy.ON_DELETE

View file

@ -21,7 +21,7 @@ class JmapBackendFactory(
val backendStorage = backendStorageFactory.createBackendStorage(account)
val okHttpClient = okHttpClientProvider.getOkHttpClient()
val serverSettings = decodeStoreUri(account.storeUri)
val serverSettings = account.incomingServerSettings
val jmapConfig = JmapConfig(
username = serverSettings.username,
password = serverSettings.password!!,

View file

@ -30,12 +30,12 @@ class Pop3BackendFactory(
}
private fun createPop3Store(account: Account): Pop3Store {
val serverSettings = decodeStoreUri(account.storeUri)
val serverSettings = account.incomingServerSettings
return Pop3Store(serverSettings, trustedSocketFactory)
}
private fun createSmtpTransport(account: Account): SmtpTransport {
val serverSettings = decodeTransportUri(account.transportUri)
val serverSettings = account.outgoingServerSettings
val oauth2TokenProvider: OAuth2TokenProvider? = null
return SmtpTransport(serverSettings, trustedSocketFactory, oauth2TokenProvider)
}

View file

@ -24,7 +24,7 @@ class WebDavBackendFactory(
override fun createBackend(account: Account): Backend {
val accountName = account.displayName
val backendStorage = backendStorageFactory.createBackendStorage(account)
val serverSettings = WebDavStoreUriDecoder.decode(account.storeUri)
val serverSettings = account.incomingServerSettings
val draftsFolderProvider = createDraftsFolderProvider(account)
val webDavStore = WebDavStore(trustManagerFactory, serverSettings, draftsFolderProvider)
val webDavTransport = WebDavTransport(trustManagerFactory, serverSettings, draftsFolderProvider)

View file

@ -38,10 +38,9 @@ class ImapBackendFactory(
private fun createImapStore(account: Account): ImapStore {
val oAuth2TokenProvider: OAuth2TokenProvider? = null
val serverSettings = ImapStoreUriDecoder.decode(account.storeUri)
val config = createImapStoreConfig(account)
return ImapStore(
serverSettings,
account.incomingServerSettings,
config,
trustedSocketFactory,
context.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager,
@ -61,7 +60,7 @@ class ImapBackendFactory(
}
private fun createSmtpTransport(account: Account): SmtpTransport {
val serverSettings = decodeTransportUri(account.transportUri)
val serverSettings = account.outgoingServerSettings
val oauth2TokenProvider: OAuth2TokenProvider? = null
return SmtpTransport(serverSettings, trustedSocketFactory, oauth2TokenProvider)
}

View file

@ -30,12 +30,12 @@ class Pop3BackendFactory(
}
private fun createPop3Store(account: Account): Pop3Store {
val serverSettings = decodeStoreUri(account.storeUri)
val serverSettings = account.incomingServerSettings
return Pop3Store(serverSettings, trustedSocketFactory)
}
private fun createSmtpTransport(account: Account): SmtpTransport {
val serverSettings = decodeTransportUri(account.transportUri)
val serverSettings = account.outgoingServerSettings
val oauth2TokenProvider: OAuth2TokenProvider? = null
return SmtpTransport(serverSettings, trustedSocketFactory, oauth2TokenProvider)
}

View file

@ -24,7 +24,7 @@ class WebDavBackendFactory(
override fun createBackend(account: Account): Backend {
val accountName = account.displayName
val backendStorage = backendStorageFactory.createBackendStorage(account)
val serverSettings = WebDavStoreUriDecoder.decode(account.storeUri)
val serverSettings = account.incomingServerSettings
val draftsFolderProvider = createDraftsFolderProvider(account)
val webDavStore = WebDavStore(trustManagerFactory, serverSettings, draftsFolderProvider)
val webDavTransport = WebDavTransport(trustManagerFactory, serverSettings, draftsFolderProvider)

View file

@ -2,6 +2,7 @@ package com.fsck.k9.storage.migrations
import android.database.sqlite.SQLiteDatabase
import com.fsck.k9.mailstore.MigrationsHelper
import com.fsck.k9.preferences.Protocols
internal object MigrationTo65 {
@JvmStatic
@ -16,6 +17,6 @@ internal object MigrationTo65 {
}
private fun isPop3Account(migrationsHelper: MigrationsHelper): Boolean {
return migrationsHelper.account.storeUri.startsWith("pop3")
return migrationsHelper.account.incomingServerSettings.type == Protocols.POP3
}
}

View file

@ -5,6 +5,7 @@ import android.database.sqlite.SQLiteDatabase
import com.fsck.k9.Account
import com.fsck.k9.helper.map
import com.fsck.k9.mailstore.MigrationsHelper
import com.fsck.k9.preferences.Protocols
import timber.log.Timber
/**
@ -119,7 +120,7 @@ internal class MigrationTo76(private val db: SQLiteDatabase, private val migrati
db.delete("folders", "id = ?", arrayOf(folderId.toString()))
}
private fun Account.isPop3() = storeUri.startsWith("pop3")
private fun Account.isPop3() = incomingServerSettings.type == Protocols.POP3
companion object {
private const val OUTBOX_FOLDER_TYPE = "outbox"

View file

@ -14,7 +14,10 @@ import android.text.TextUtils;
import com.fsck.k9.Account;
import com.fsck.k9.core.BuildConfig;
import com.fsck.k9.mail.AuthType;
import com.fsck.k9.mail.ConnectionSecurity;
import com.fsck.k9.mail.MessagingException;
import com.fsck.k9.mail.ServerSettings;
import com.fsck.k9.mailstore.LocalStore;
import com.fsck.k9.mailstore.LockableDatabase;
import com.fsck.k9.mailstore.MigrationsHelper;
@ -406,7 +409,10 @@ public class StoreSchemaDefinitionTest extends K9RobolectricTest {
when(account.getImportedSentFolder()).thenReturn("Sent");
when(account.getImportedArchiveFolder()).thenReturn(null);
when(account.getLocalStorageProviderId()).thenReturn(StorageManager.InternalStorageProvider.ID);
when(account.getStoreUri()).thenReturn("dummy://");
ServerSettings incomingServerSettings = new ServerSettings("dummy", "", -1, ConnectionSecurity.NONE,
AuthType.AUTOMATIC, "", "", null);
when(account.getIncomingServerSettings()).thenReturn(incomingServerSettings);
return account;
}

View file

@ -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.backend.BackendManager
import com.fsck.k9.coreModules
import com.fsck.k9.crypto.EncryptionExtractor
import com.fsck.k9.preferences.K9StoragePersister
@ -30,4 +31,5 @@ val testModule = module {
single { mock<CoreResourceProvider>() }
single { mock<EncryptionExtractor>() }
single<StoragePersister> { K9StoragePersister(get()) }
single { mock<BackendManager>() }
}

View file

@ -6,7 +6,6 @@ import android.os.Bundle
import android.view.View
import com.fsck.k9.Account
import com.fsck.k9.Preferences
import com.fsck.k9.backend.BackendManager
import com.fsck.k9.helper.EmailHelper.getDomainFromEmailAddress
import com.fsck.k9.mail.ConnectionSecurity
import com.fsck.k9.mail.ServerSettings
@ -26,7 +25,6 @@ class AccountSetupAccountType : K9Activity() {
private val preferences: Preferences by inject()
private val serverNameSuggester: ServerNameSuggester by inject()
private val localFoldersCreator: SpecialLocalFoldersCreator by inject()
private val backendManager: BackendManager by inject()
private lateinit var account: Account
private var makeDefault = false
@ -67,11 +65,11 @@ class AccountSetupAccountType : K9Activity() {
private fun setupStoreAndSmtpTransport(serverType: String) {
val domainPart = getDomainFromEmailAddress(account.email) ?: error("Couldn't get domain from email address")
setupStoreUri(serverType, domainPart)
setupTransportUri(domainPart)
initializeIncomingServerSettings(serverType, domainPart)
initializeOutgoingServerSettings(domainPart)
}
private fun setupStoreUri(serverType: String, domainPart: String) {
private fun initializeIncomingServerSettings(serverType: String, domainPart: String) {
val suggestedStoreServerName = serverNameSuggester.suggestServerName(serverType, domainPart)
val storeServer = ServerSettings(
serverType,
@ -83,11 +81,10 @@ class AccountSetupAccountType : K9Activity() {
initialAccountSettings.password,
initialAccountSettings.clientCertificateAlias
)
val storeUri = backendManager.createStoreUri(storeServer)
account.storeUri = storeUri
account.incomingServerSettings = storeServer
}
private fun setupTransportUri(domainPart: String) {
private fun initializeOutgoingServerSettings(domainPart: String) {
val suggestedTransportServerName = serverNameSuggester.suggestServerName(Protocols.SMTP, domainPart)
val transportServer = ServerSettings(
Protocols.SMTP,
@ -99,8 +96,7 @@ class AccountSetupAccountType : K9Activity() {
initialAccountSettings.password,
initialAccountSettings.clientCertificateAlias
)
val transportUri = backendManager.createTransportUri(transportServer)
account.transportUri = transportUri
account.outgoingServerSettings = transportServer
}
private fun createSpecialLocalFolders() {

View file

@ -25,7 +25,6 @@ import com.fsck.k9.autodiscovery.api.DiscoveredServerSettings;
import com.fsck.k9.autodiscovery.api.DiscoveryResults;
import com.fsck.k9.autodiscovery.api.DiscoveryTarget;
import com.fsck.k9.autodiscovery.providersxml.ProvidersXmlDiscovery;
import com.fsck.k9.backend.BackendManager;
import com.fsck.k9.helper.Utility;
import com.fsck.k9.mail.AuthType;
import com.fsck.k9.mail.ServerSettings;
@ -50,7 +49,6 @@ public class AccountSetupBasics extends K9Activity
private final static String STATE_KEY_CHECKED_INCOMING = "com.fsck.k9.AccountSetupBasics.checkedIncoming";
private final BackendManager backendManager = DI.get(BackendManager.class);
private final ProvidersXmlDiscovery providersXmlDiscovery = DI.get(ProvidersXmlDiscovery.class);
private final AccountCreator accountCreator = DI.get(AccountCreator.class);
private final SpecialLocalFoldersCreator localFoldersCreator = DI.get(SpecialLocalFoldersCreator.class);
@ -228,12 +226,10 @@ public class AccountSetupBasics extends K9Activity
mAccount.setEmail(email);
ServerSettings incomingServerSettings = connectionSettings.getIncoming().newPassword(password);
String storeUri = backendManager.createStoreUri(incomingServerSettings);
mAccount.setStoreUri(storeUri);
mAccount.setIncomingServerSettings(incomingServerSettings);
ServerSettings outgoingServerSettings = connectionSettings.getOutgoing().newPassword(password);
String transportUri = backendManager.createTransportUri(outgoingServerSettings);
mAccount.setTransportUri(transportUri);
mAccount.setOutgoingServerSettings(outgoingServerSettings);
mAccount.setDeletePolicy(accountCreator.getDefaultDeletePolicy(incomingServerSettings.type));

View file

@ -15,22 +15,20 @@ import android.app.Activity;
import android.app.AlertDialog;
import android.content.DialogInterface;
import android.content.Intent;
import android.net.Uri;
import android.os.AsyncTask;
import android.os.Bundle;
import android.os.Handler;
import androidx.fragment.app.DialogFragment;
import androidx.fragment.app.FragmentTransaction;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.ProgressBar;
import android.widget.TextView;
import androidx.fragment.app.DialogFragment;
import androidx.fragment.app.FragmentTransaction;
import com.fsck.k9.Account;
import com.fsck.k9.DI;
import com.fsck.k9.LocalKeyStoreManager;
import com.fsck.k9.Preferences;
import com.fsck.k9.ui.base.K9Activity;
import com.fsck.k9.controller.MessagingController;
import com.fsck.k9.fragment.ConfirmationDialogFragment;
import com.fsck.k9.fragment.ConfirmationDialogFragment.ConfirmationDialogFragmentListener;
@ -39,7 +37,9 @@ import com.fsck.k9.mail.CertificateValidationException;
import com.fsck.k9.mail.MailServerDirection;
import com.fsck.k9.mail.MessagingException;
import com.fsck.k9.mail.filter.Hex;
import com.fsck.k9.preferences.Protocols;
import com.fsck.k9.ui.R;
import com.fsck.k9.ui.base.K9Activity;
import timber.log.Timber;
@ -187,8 +187,8 @@ public class AccountSetupCheckSettings extends K9Activity implements OnClickList
altNamesText.append("Subject has ").append(subjectAlternativeNames.size()).append(" alternative names\n");
// we need these for matching
String storeURIHost = (Uri.parse(mAccount.getStoreUri())).getHost();
String transportURIHost = (Uri.parse(mAccount.getTransportUri())).getHost();
String incomingServerHost = mAccount.getIncomingServerSettings().host;
String outgoingServerHost = mAccount.getOutgoingServerSettings().host;
for (List<?> subjectAlternativeName : subjectAlternativeNames) {
Integer type = (Integer)subjectAlternativeName.get(0);
@ -226,12 +226,12 @@ public class AccountSetupCheckSettings extends K9Activity implements OnClickList
// if some of the SubjectAltNames match the store or transport -host,
// display them
if (name.equalsIgnoreCase(storeURIHost) || name.equalsIgnoreCase(transportURIHost)) {
if (name.equalsIgnoreCase(incomingServerHost) || name.equalsIgnoreCase(outgoingServerHost)) {
//TODO: localize this string
altNamesText.append("Subject(alt): ").append(name).append(",...\n");
} else if (name.startsWith("*.") && (
storeURIHost.endsWith(name.substring(2)) ||
transportURIHost.endsWith(name.substring(2)))) {
incomingServerHost.endsWith(name.substring(2)) ||
outgoingServerHost.endsWith(name.substring(2)))) {
//TODO: localize this string
altNamesText.append("Subject(alt): ").append(name).append(",...\n");
}
@ -515,7 +515,7 @@ public class AccountSetupCheckSettings extends K9Activity implements OnClickList
}
private boolean isWebDavAccount() {
return account.getStoreUri().startsWith("webdav");
return account.getIncomingServerSettings().type.equals(Protocols.WEBDAV);
}
@Override

View file

@ -31,7 +31,6 @@ import com.fsck.k9.helper.EmailHelper;
import com.fsck.k9.setup.ServerNameSuggester;
import com.fsck.k9.ui.base.K9Activity;
import com.fsck.k9.activity.setup.AccountSetupCheckSettings.CheckDirection;
import com.fsck.k9.backend.BackendManager;
import com.fsck.k9.controller.MessagingController;
import com.fsck.k9.helper.Utility;
import com.fsck.k9.job.K9JobManager;
@ -63,7 +62,6 @@ public class AccountSetupIncoming extends K9Activity implements OnClickListener
private static final String STATE_AUTH_TYPE_POSITION = "authTypePosition";
private final MessagingController messagingController = DI.get(MessagingController.class);
private final BackendManager backendManager = DI.get(BackendManager.class);
private final K9JobManager jobManager = DI.get(K9JobManager.class);
private final AccountCreator accountCreator = DI.get(AccountCreator.class);
private final ServerNameSuggester serverNameSuggester = DI.get(ServerNameSuggester.class);
@ -182,7 +180,7 @@ public class AccountSetupIncoming extends K9Activity implements OnClickListener
boolean editSettings = Intent.ACTION_EDIT.equals(getIntent().getAction());
try {
ServerSettings settings = backendManager.decodeStoreUri(mAccount.getStoreUri());
ServerSettings settings = mAccount.getIncomingServerSettings();
if (savedInstanceState == null) {
// The first item is selected if settings.authenticationType is null or is not in mAuthTypeAdapter
@ -193,9 +191,7 @@ public class AccountSetupIncoming extends K9Activity implements OnClickListener
mAuthTypeView.setSelection(mCurrentAuthTypeViewPosition, false);
updateViewFromAuthType();
if (settings.username != null) {
mUsernameView.setText(settings.username);
}
mUsernameView.setText(settings.username);
if (settings.password != null) {
mPasswordView.setText(settings.password);
@ -264,7 +260,7 @@ public class AccountSetupIncoming extends K9Activity implements OnClickListener
mWebdavMailboxPathView.setText(mailboxPath);
}
} else {
throw new Exception("Unknown account type: " + mAccount.getStoreUri());
throw new Exception("Unknown account type: " + settings.type);
}
if (!editSettings) {
@ -547,8 +543,7 @@ public class AccountSetupIncoming extends K9Activity implements OnClickListener
ServerSettings transportServer = new ServerSettings(Protocols.SMTP, host,
-1, ConnectionSecurity.SSL_TLS_REQUIRED, authType, username, password,
clientCertificateAlias);
String transportUri = backendManager.createTransportUri(transportServer);
mAccount.setTransportUri(transportUri);
mAccount.setOutgoingServerSettings(transportServer);
AccountSetupOutgoing.actionOutgoingSettings(this, mAccount, mMakeDefault);
}
@ -588,7 +583,7 @@ public class AccountSetupIncoming extends K9Activity implements OnClickListener
ServerSettings settings = new ServerSettings(mStoreType, host, port,
connectionSecurity, authType, username, password, clientCertificateAlias, extra);
mAccount.setStoreUri(backendManager.createStoreUri(settings));
mAccount.setIncomingServerSettings(settings);
mAccount.setCompression(NetworkType.MOBILE, mCompressionMobile.isChecked());
mAccount.setCompression(NetworkType.WIFI, mCompressionWifi.isChecked());

View file

@ -2,9 +2,6 @@
package com.fsck.k9.activity.setup;
import java.net.URI;
import java.net.URISyntaxException;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
@ -28,7 +25,6 @@ import com.fsck.k9.Account;
import com.fsck.k9.DI;
import com.fsck.k9.LocalKeyStoreManager;
import com.fsck.k9.Preferences;
import com.fsck.k9.backend.BackendManager;
import com.fsck.k9.preferences.Protocols;
import com.fsck.k9.ui.R;
import com.fsck.k9.account.AccountCreator;
@ -54,7 +50,6 @@ public class AccountSetupOutgoing extends K9Activity implements OnClickListener,
private static final String STATE_AUTH_TYPE_POSITION = "authTypePosition";
private final BackendManager backendManager = DI.get(BackendManager.class);
private final AccountCreator accountCreator = DI.get(AccountCreator.class);
private TextInputEditText mUsernameView;
@ -105,14 +100,10 @@ public class AccountSetupOutgoing extends K9Activity implements OnClickListener,
String accountUuid = getIntent().getStringExtra(EXTRA_ACCOUNT);
mAccount = Preferences.getPreferences(this).getAccount(accountUuid);
try {
if (new URI(mAccount.getStoreUri()).getScheme().startsWith("webdav")) {
mAccount.setTransportUri(mAccount.getStoreUri());
AccountSetupCheckSettings.actionCheckSettings(this, mAccount, CheckDirection.OUTGOING);
}
} catch (URISyntaxException e) {
// TODO Auto-generated catch block
e.printStackTrace();
ServerSettings incomingServerSettings = mAccount.getIncomingServerSettings();
if (incomingServerSettings.type.equals(Protocols.WEBDAV)) {
mAccount.setOutgoingServerSettings(incomingServerSettings);
AccountSetupCheckSettings.actionCheckSettings(this, mAccount, CheckDirection.OUTGOING);
}
@ -156,7 +147,7 @@ public class AccountSetupOutgoing extends K9Activity implements OnClickListener,
}
try {
ServerSettings settings = backendManager.decodeTransportUri(mAccount.getTransportUri());
ServerSettings settings = mAccount.getOutgoingServerSettings();
updateAuthPlainTextFromSecurityType(settings.connectionSecurity);
@ -471,7 +462,6 @@ public class AccountSetupOutgoing extends K9Activity implements OnClickListener,
protected void onNext() {
ConnectionSecurity securityType = getSelectedSecurity();
String uri;
String username = null;
String password = null;
String clientCertificateAlias = null;
@ -491,9 +481,8 @@ public class AccountSetupOutgoing extends K9Activity implements OnClickListener,
int newPort = Integer.parseInt(mPortView.getText().toString());
ServerSettings server = new ServerSettings(Protocols.SMTP, newHost, newPort, securityType, authType, username,
password, clientCertificateAlias);
uri = backendManager.createTransportUri(server);
DI.get(LocalKeyStoreManager.class).deleteCertificate(mAccount, newHost, newPort, MailServerDirection.OUTGOING);
mAccount.setTransportUri(uri);
mAccount.setOutgoingServerSettings(server);
AccountSetupCheckSettings.actionCheckSettings(this, mAccount, CheckDirection.OUTGOING);
}

View file

@ -30,5 +30,5 @@ val settingsUiModule = module {
viewModel { SettingsImportViewModel(get(), get()) }
viewModel { SettingsImportResultViewModel() }
single { AccountActivator(get(), get(), get(), get()) }
single { AccountActivator(get(), get(), get()) }
}

View file

@ -4,7 +4,6 @@ import android.content.Context
import com.fsck.k9.Account
import com.fsck.k9.Core
import com.fsck.k9.Preferences
import com.fsck.k9.backend.BackendManager
import com.fsck.k9.controller.MessagingController
/**
@ -13,8 +12,7 @@ import com.fsck.k9.controller.MessagingController
class AccountActivator(
private val context: Context,
private val preferences: Preferences,
private val messagingController: MessagingController,
private val backendManager: BackendManager
private val messagingController: MessagingController
) {
fun enableAccount(accountUuid: String, incomingServerPassword: String?, outgoingServerPassword: String?) {
val account = preferences.getAccount(accountUuid)
@ -34,15 +32,11 @@ class AccountActivator(
outgoingServerPassword: String?
) {
if (incomingServerPassword != null) {
val incomingServerSettings = backendManager.decodeStoreUri(account.storeUri)
val newIncomingServerSettings = incomingServerSettings.newPassword(incomingServerPassword)
account.storeUri = backendManager.createStoreUri(newIncomingServerSettings)
account.incomingServerSettings = account.incomingServerSettings.newPassword(incomingServerPassword)
}
if (outgoingServerPassword != null) {
val outgoingServerSettings = backendManager.decodeTransportUri(account.transportUri)
val newOutgoingServerSettings = outgoingServerSettings.newPassword(outgoingServerPassword)
account.transportUri = backendManager.createTransportUri(newOutgoingServerSettings)
account.outgoingServerSettings = account.outgoingServerSettings.newPassword(outgoingServerPassword)
}
account.isEnabled = true