-
-
Notifications
You must be signed in to change notification settings - Fork 2.5k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #7956 from thunderbird/validate_server_settings_on…
…_import Add `ServerSettingsDescriptions` to validate and upgrade server settings
- Loading branch information
Showing
16 changed files
with
589 additions
and
86 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
12 changes: 12 additions & 0 deletions
12
app/core/src/main/java/com/fsck/k9/preferences/NoDefaultStringEnumSetting.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
package com.fsck.k9.preferences | ||
|
||
import com.fsck.k9.preferences.Settings.InvalidSettingValueException | ||
import com.fsck.k9.preferences.Settings.StringSetting | ||
|
||
internal class NoDefaultStringEnumSetting( | ||
private val values: Set<String>, | ||
) : StringSetting(null) { | ||
override fun fromString(value: String?): String { | ||
return value?.takeIf { it in values } ?: throw InvalidSettingValueException("Unsupported value: $value") | ||
} | ||
} |
86 changes: 86 additions & 0 deletions
86
app/core/src/main/java/com/fsck/k9/preferences/ServerSettingsDescriptions.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,86 @@ | ||
package com.fsck.k9.preferences | ||
|
||
import com.fsck.k9.preferences.Settings.IntegerRangeSetting | ||
import com.fsck.k9.preferences.Settings.SettingsDescription | ||
import com.fsck.k9.preferences.Settings.SettingsUpgrader | ||
import com.fsck.k9.preferences.Settings.StringSetting | ||
import com.fsck.k9.preferences.upgrader.ServerSettingsUpgraderTo92 | ||
import java.util.TreeMap | ||
|
||
/** | ||
* Contains information to validate imported server settings with a given content version, and to upgrade those server | ||
* settings to the latest content version. | ||
*/ | ||
@Suppress("MagicNumber") | ||
internal class ServerSettingsDescriptions { | ||
val settings: Map<String, TreeMap<Int, SettingsDescription<*>>> by lazy { | ||
mapOf( | ||
HOST to versions( | ||
1 to StringSetting(null), | ||
), | ||
PORT to versions( | ||
1 to IntegerRangeSetting(1, 65535, -1), | ||
), | ||
CONNECTION_SECURITY to versions( | ||
1 to StringEnumSetting( | ||
defaultValue = "SSL_TLS_REQUIRED", | ||
values = setOf( | ||
"NONE", | ||
"STARTTLS_OPTIONAL", | ||
"STARTTLS_REQUIRED", | ||
"SSL_TLS_OPTIONAL", | ||
"SSL_TLS_REQUIRED", | ||
), | ||
), | ||
92 to NoDefaultStringEnumSetting( | ||
values = setOf( | ||
"NONE", | ||
"STARTTLS_REQUIRED", | ||
"SSL_TLS_REQUIRED", | ||
), | ||
), | ||
), | ||
AUTHENTICATION_TYPE to versions( | ||
1 to NoDefaultStringEnumSetting( | ||
values = setOf( | ||
"PLAIN", | ||
"CRAM_MD5", | ||
"EXTERNAL", | ||
"XOAUTH2", | ||
"AUTOMATIC", | ||
"LOGIN", | ||
), | ||
), | ||
), | ||
USERNAME to versions( | ||
1 to StringSetting(""), | ||
), | ||
PASSWORD to versions( | ||
1 to StringSetting(null), | ||
), | ||
CLIENT_CERTIFICATE_ALIAS to versions( | ||
1 to StringSetting(null), | ||
), | ||
) | ||
} | ||
|
||
val upgraders: Map<Int, SettingsUpgrader> by lazy { | ||
mapOf( | ||
92 to ServerSettingsUpgraderTo92(), | ||
) | ||
} | ||
|
||
companion object { | ||
const val HOST = "host" | ||
const val PORT = "port" | ||
const val CONNECTION_SECURITY = "connectionSecurity" | ||
const val AUTHENTICATION_TYPE = "authenticationType" | ||
const val USERNAME = "username" | ||
const val PASSWORD = "password" | ||
const val CLIENT_CERTIFICATE_ALIAS = "clientCertificateAlias" | ||
} | ||
} | ||
|
||
private fun versions(vararg versions: Pair<Int, SettingsDescription<*>>): TreeMap<Int, SettingsDescription<*>> { | ||
return TreeMap(versions.toMap()) | ||
} |
22 changes: 22 additions & 0 deletions
22
app/core/src/main/java/com/fsck/k9/preferences/ServerSettingsUpgrader.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
package com.fsck.k9.preferences | ||
|
||
internal class ServerSettingsUpgrader( | ||
private val serverSettingsDescriptions: ServerSettingsDescriptions = ServerSettingsDescriptions(), | ||
) { | ||
fun upgrade(contentVersion: Int, server: ValidatedSettings.Server): ValidatedSettings.Server { | ||
if (contentVersion == Settings.VERSION) { | ||
return server | ||
} | ||
|
||
val settings = server.settings.toMutableMap() | ||
|
||
Settings.upgrade( | ||
contentVersion, | ||
serverSettingsDescriptions.upgraders, | ||
serverSettingsDescriptions.settings, | ||
settings, | ||
) | ||
|
||
return server.copy(settings = settings.toMap()) | ||
} | ||
} |
49 changes: 49 additions & 0 deletions
49
app/core/src/main/java/com/fsck/k9/preferences/ServerSettingsValidator.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,49 @@ | ||
package com.fsck.k9.preferences | ||
|
||
import com.fsck.k9.preferences.ServerSettingsDescriptions.Companion.AUTHENTICATION_TYPE | ||
import com.fsck.k9.preferences.ServerSettingsDescriptions.Companion.CLIENT_CERTIFICATE_ALIAS | ||
import com.fsck.k9.preferences.ServerSettingsDescriptions.Companion.CONNECTION_SECURITY | ||
import com.fsck.k9.preferences.ServerSettingsDescriptions.Companion.HOST | ||
import com.fsck.k9.preferences.ServerSettingsDescriptions.Companion.PASSWORD | ||
import com.fsck.k9.preferences.ServerSettingsDescriptions.Companion.PORT | ||
import com.fsck.k9.preferences.ServerSettingsDescriptions.Companion.USERNAME | ||
import com.fsck.k9.preferences.ServerTypeConverter.toServerSettingsType | ||
import com.fsck.k9.preferences.Settings.InvalidSettingValueException | ||
|
||
internal class ServerSettingsValidator( | ||
private val serverSettingsDescriptions: ServerSettingsDescriptions = ServerSettingsDescriptions(), | ||
) { | ||
fun validate(contentVersion: Int, server: SettingsFile.Server): ValidatedSettings.Server { | ||
val settings = convertServerSettingsToMap(server) | ||
|
||
val validatedSettings = Settings.validate(contentVersion, serverSettingsDescriptions.settings, settings, true) | ||
|
||
if (validatedSettings[AUTHENTICATION_TYPE] !is String) { | ||
throw InvalidSettingValueException("Missing '$AUTHENTICATION_TYPE' value") | ||
} | ||
|
||
if (validatedSettings[CONNECTION_SECURITY] !is String) { | ||
throw InvalidSettingValueException("Missing '$CONNECTION_SECURITY' value") | ||
} | ||
|
||
return ValidatedSettings.Server( | ||
type = toServerSettingsType(server.type!!), | ||
settings = validatedSettings, | ||
extras = server.extras.orEmpty(), | ||
) | ||
} | ||
|
||
private fun convertServerSettingsToMap(server: SettingsFile.Server): SettingsMap { | ||
return buildMap { | ||
server.host?.let { host -> put(HOST, host) } | ||
server.port?.let { port -> put(PORT, port) } | ||
server.connectionSecurity?.let { connectionSecurity -> put(CONNECTION_SECURITY, connectionSecurity) } | ||
server.authenticationType?.let { authenticationType -> put(AUTHENTICATION_TYPE, authenticationType) } | ||
server.username?.let { username -> put(USERNAME, username) } | ||
server.password?.let { password -> put(PASSWORD, password) } | ||
server.clientCertificateAlias?.let { clientCertificateAlias -> | ||
put(CLIENT_CERTIFICATE_ALIAS, clientCertificateAlias) | ||
} | ||
} | ||
} | ||
} |
52 changes: 52 additions & 0 deletions
52
app/core/src/main/java/com/fsck/k9/preferences/ServerSettingsWriter.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,52 @@ | ||
package com.fsck.k9.preferences | ||
|
||
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.preferences.ServerSettingsDescriptions.Companion.AUTHENTICATION_TYPE | ||
import com.fsck.k9.preferences.ServerSettingsDescriptions.Companion.CLIENT_CERTIFICATE_ALIAS | ||
import com.fsck.k9.preferences.ServerSettingsDescriptions.Companion.CONNECTION_SECURITY | ||
import com.fsck.k9.preferences.ServerSettingsDescriptions.Companion.HOST | ||
import com.fsck.k9.preferences.ServerSettingsDescriptions.Companion.PASSWORD | ||
import com.fsck.k9.preferences.ServerSettingsDescriptions.Companion.PORT | ||
import com.fsck.k9.preferences.ServerSettingsDescriptions.Companion.USERNAME | ||
|
||
internal class ServerSettingsWriter( | ||
private val serverSettingsSerializer: ServerSettingsSerializer, | ||
) { | ||
fun writeServerSettings( | ||
editor: StorageEditor, | ||
key: String, | ||
server: ValidatedSettings.Server, | ||
) { | ||
val serverSettings = createServerSettings(server) | ||
val serverSettingsJson = serverSettingsSerializer.serialize(serverSettings) | ||
editor.putStringWithLogging(key, serverSettingsJson) | ||
} | ||
|
||
private fun createServerSettings(server: ValidatedSettings.Server): ServerSettings { | ||
val validatedSettings = server.settings | ||
|
||
val host = validatedSettings[HOST] as? String | ||
val port = validatedSettings[PORT] as Int | ||
val connectionSecurity = ConnectionSecurity.valueOf(validatedSettings[CONNECTION_SECURITY] as String) | ||
val authenticationType = AuthType.valueOf(validatedSettings[AUTHENTICATION_TYPE] as String) | ||
val username = validatedSettings[USERNAME] as String | ||
val rawPassword = validatedSettings[PASSWORD] as? String | ||
val password = if (authenticationType == AuthType.XOAUTH2) "" else rawPassword | ||
val clientCertificateAlias = validatedSettings[CLIENT_CERTIFICATE_ALIAS] as? String | ||
|
||
return ServerSettings( | ||
server.type, | ||
host, | ||
port, | ||
connectionSecurity, | ||
authenticationType, | ||
username, | ||
password, | ||
clientCertificateAlias, | ||
server.extras, | ||
) | ||
} | ||
} |
Oops, something went wrong.