Add authentication type to outgoing server settings screen

This commit is contained in:
cketti 2023-06-29 17:41:29 +02:00
parent 7156b92187
commit 176a1e5bb7
10 changed files with 49 additions and 1 deletions

View file

@ -3,6 +3,7 @@ package app.k9mail.feature.account.setup.domain.entity
import kotlinx.collections.immutable.toImmutableList
enum class AuthenticationType {
None,
PasswordCleartext,
PasswordEncrypted,
ClientCertificate,
@ -12,5 +13,14 @@ enum class AuthenticationType {
companion object {
val DEFAULT = PasswordCleartext
fun all() = values().toList().toImmutableList()
fun incoming() = listOf(
PasswordCleartext,
PasswordEncrypted,
ClientCertificate,
OAuth2,
).toImmutableList()
fun outgoing() = all()
}
}

View file

@ -6,6 +6,9 @@ import app.k9mail.feature.account.setup.domain.entity.AuthenticationType
internal fun AuthenticationType.toResourceString(resources: Resources): String {
return when (this) {
AuthenticationType.None -> {
resources.getString(R.string.account_setup_authentication_none)
}
AuthenticationType.PasswordCleartext -> {
resources.getString(R.string.account_setup_authentication_password_cleartext)
}

View file

@ -136,7 +136,7 @@ internal fun AccountIncomingConfigContent(
item {
SelectInput(
options = AuthenticationType.all(),
options = AuthenticationType.incoming(),
optionToStringTransformation = { it.toResourceString(resources) },
selectedOption = state.authenticationType,
onOptionChange = { onEvent(Event.AuthenticationTypeChanged(it)) },

View file

@ -25,11 +25,13 @@ import app.k9mail.core.ui.compose.theme.K9Theme
import app.k9mail.core.ui.compose.theme.MainTheme
import app.k9mail.core.ui.compose.theme.ThunderbirdTheme
import app.k9mail.feature.account.setup.R
import app.k9mail.feature.account.setup.domain.entity.AuthenticationType
import app.k9mail.feature.account.setup.domain.entity.ConnectionSecurity
import app.k9mail.feature.account.setup.ui.common.item.ErrorItem
import app.k9mail.feature.account.setup.ui.common.item.LoadingItem
import app.k9mail.feature.account.setup.ui.common.item.SuccessItem
import app.k9mail.feature.account.setup.ui.common.item.defaultItemPadding
import app.k9mail.feature.account.setup.ui.common.mapper.toResourceString
import app.k9mail.feature.account.setup.ui.common.toResourceString
import app.k9mail.feature.account.setup.ui.outgoing.AccountOutgoingConfigContract.Event
import app.k9mail.feature.account.setup.ui.outgoing.AccountOutgoingConfigContract.State
@ -121,6 +123,17 @@ internal fun AccountOutgoingConfigContent(
)
}
item {
SelectInput(
options = AuthenticationType.outgoing(),
optionToStringTransformation = { it.toResourceString(resources) },
selectedOption = state.authenticationType,
onOptionChange = { onEvent(Event.AuthenticationTypeChanged(it)) },
label = stringResource(id = R.string.account_setup_outgoing_config_authentication_label),
contentPadding = defaultItemPadding(),
)
}
item {
TextInput(
text = state.username.value,

View file

@ -2,6 +2,7 @@ package app.k9mail.feature.account.setup.ui.outgoing
import app.k9mail.core.common.domain.usecase.validation.ValidationResult
import app.k9mail.core.ui.compose.common.mvi.UnidirectionalViewModel
import app.k9mail.feature.account.setup.domain.entity.AuthenticationType
import app.k9mail.feature.account.setup.domain.entity.ConnectionSecurity
import app.k9mail.feature.account.setup.domain.entity.toSmtpDefaultPort
import app.k9mail.feature.account.setup.domain.input.NumberInputField
@ -19,6 +20,7 @@ interface AccountOutgoingConfigContract {
val server: StringInputField = StringInputField(),
val security: ConnectionSecurity = ConnectionSecurity.DEFAULT,
val port: NumberInputField = NumberInputField(ConnectionSecurity.DEFAULT.toSmtpDefaultPort()),
val authenticationType: AuthenticationType = AuthenticationType.PasswordCleartext,
val username: StringInputField = StringInputField(),
val password: StringInputField = StringInputField(),
val clientCertificate: String = "",
@ -32,6 +34,7 @@ interface AccountOutgoingConfigContract {
data class ServerChanged(val server: String) : Event()
data class SecurityChanged(val security: ConnectionSecurity) : Event()
data class PortChanged(val port: Long?) : Event()
data class AuthenticationTypeChanged(val authenticationType: AuthenticationType) : Event()
data class UsernameChanged(val username: String) : Event()
data class PasswordChanged(val password: String) : Event()
data class ClientCertificateChanged(val clientCertificate: String) : Event()

View file

@ -36,6 +36,7 @@ internal class AccountOutgoingConfigViewModel(
is Event.ServerChanged -> updateState { it.copy(server = it.server.updateValue(event.server)) }
is Event.SecurityChanged -> updateSecurity(event.security)
is Event.PortChanged -> updateState { it.copy(port = it.port.updateValue(event.port)) }
is Event.AuthenticationTypeChanged -> updateState { it.copy(authenticationType = event.authenticationType) }
is Event.UsernameChanged -> updateState { it.copy(username = it.username.updateValue(event.username)) }
is Event.PasswordChanged -> updateState { it.copy(password = it.password.updateValue(event.password)) }
is Event.ClientCertificateChanged -> updateState { it.copy(clientCertificate = event.clientCertificate) }

View file

@ -7,6 +7,7 @@
<string name="account_setup_connection_security_none">None</string>
<string name="account_setup_connection_security_ssl">SSL/TLS</string>
<string name="account_setup_connection_security_start_tls">StartTLS</string>
<string name="account_setup_authentication_none">None</string>
<string name="account_setup_authentication_password_cleartext">Normal password</string>
<string name="account_setup_authentication_password_encrypted">Encrypted password</string>
<string name="account_setup_authentication_client_certificate">Client certificate</string>
@ -59,6 +60,7 @@
<string name="account_setup_outgoing_config_server_label">Server</string>
<string name="account_setup_outgoing_config_security_label">Security</string>
<string name="account_setup_outgoing_config_port_label">Port</string>
<string name="account_setup_outgoing_config_authentication_label">Authentication</string>
<string name="account_setup_outgoing_config_username_label">Username</string>
<string name="account_setup_outgoing_config_client_certificate_label">Client certificate</string>
<string name="account_setup_outgoing_config_loading_message">Checking outgoing server settings…</string>

View file

@ -1,5 +1,6 @@
package app.k9mail.feature.account.setup.ui.outgoing
import app.k9mail.feature.account.setup.domain.entity.AuthenticationType
import app.k9mail.feature.account.setup.domain.entity.ConnectionSecurity
import app.k9mail.feature.account.setup.domain.entity.MailConnectionSecurity
import app.k9mail.feature.account.setup.domain.input.NumberInputField
@ -19,6 +20,7 @@ class AccountOutgoingConfigStateMapperKtTest {
server = StringInputField(value = "smtp.example.org"),
port = NumberInputField(value = 587),
security = ConnectionSecurity.TLS,
authenticationType = AuthenticationType.PasswordCleartext,
username = StringInputField(value = "user"),
password = StringInputField(value = "password"),
clientCertificate = "",

View file

@ -1,5 +1,6 @@
package app.k9mail.feature.account.setup.ui.outgoing
import app.k9mail.feature.account.setup.domain.entity.AuthenticationType
import app.k9mail.feature.account.setup.domain.entity.ConnectionSecurity
import app.k9mail.feature.account.setup.domain.entity.toSmtpDefaultPort
import app.k9mail.feature.account.setup.domain.input.NumberInputField
@ -20,6 +21,7 @@ class AccountOutgoingConfigStateTest {
server = StringInputField(),
security = ConnectionSecurity.DEFAULT,
port = NumberInputField(value = ConnectionSecurity.DEFAULT.toSmtpDefaultPort()),
authenticationType = AuthenticationType.PasswordCleartext,
username = StringInputField(),
password = StringInputField(),
clientCertificate = "",

View file

@ -4,6 +4,7 @@ import app.cash.turbine.testIn
import app.k9mail.core.common.domain.usecase.validation.ValidationError
import app.k9mail.core.common.domain.usecase.validation.ValidationResult
import app.k9mail.core.ui.compose.testing.MainDispatcherRule
import app.k9mail.feature.account.setup.domain.entity.AuthenticationType
import app.k9mail.feature.account.setup.domain.entity.ConnectionSecurity
import app.k9mail.feature.account.setup.domain.entity.toSmtpDefaultPort
import app.k9mail.feature.account.setup.domain.input.NumberInputField
@ -72,6 +73,17 @@ class AccountOutgoingConfigViewModelTest {
)
}
@Test
fun `should change state when AuthenticationTypeChanged event is received`() = runTest {
eventStateTest(
viewModel = testSubject,
initialState = State(),
event = Event.AuthenticationTypeChanged(AuthenticationType.PasswordEncrypted),
expectedState = State(authenticationType = AuthenticationType.PasswordEncrypted),
coroutineScope = backgroundScope,
)
}
@Test
fun `should change state when UsernameChanged event is received`() = runTest {
eventStateTest(