Skip to content

Commit

Permalink
Add DemoAutoDiscovery
Browse files Browse the repository at this point in the history
  • Loading branch information
wmontwe committed May 29, 2024
1 parent 685dd91 commit 8902b9b
Show file tree
Hide file tree
Showing 12 changed files with 124 additions and 12 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ class ValidateServerSettings(
"imap" -> imapValidator.checkServerSettings(settings, authStateStorage)
"pop3" -> pop3Validator.checkServerSettings(settings, authStateStorage)
"smtp" -> smtpValidator.checkServerSettings(settings, authStateStorage)
"demo" -> ServerSettingsValidationResult.Success
else -> {
throw IllegalArgumentException("Unsupported server type: ${settings.type}")
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -100,11 +100,36 @@ class ValidateServerSettingsTest {
assertThat(result).isEqualTo(failure)
}

@Test
fun `should validate successfully for demo settings`() = runTest {
val testSubject = ValidateServerSettings(
authStateStorage = authStateStorage,
imapValidator = { _, _ -> ServerSettingsValidationResult.NetworkError(IOException("Failed IMAP")) },
pop3Validator = { _, _ -> ServerSettingsValidationResult.NetworkError(IOException("Failed POP3")) },
smtpValidator = { _, _ -> ServerSettingsValidationResult.NetworkError(IOException("Failed SMTP")) },
)

val result = testSubject.execute(
ServerSettings(
type = "demo",
host = "demo.example.com",
port = 993,
connectionSecurity = ConnectionSecurity.SSL_TLS_REQUIRED,
authenticationType = AuthType.PLAIN,
username = "user",
password = "password",
clientCertificateAlias = null,
),
)

assertThat(result).isEqualTo(ServerSettingsValidationResult.Success)
}

private companion object {

val IMAP_SERVER_SETTINGS = ServerSettings(
type = "imap",
host = "imap.example.org",
host = "imap.example.com",
port = 993,
connectionSecurity = ConnectionSecurity.SSL_TLS_REQUIRED,
authenticationType = AuthType.PLAIN,
Expand All @@ -115,7 +140,7 @@ class ValidateServerSettingsTest {

val POP3_SERVER_SETTINGS = ServerSettings(
type = "pop3",
host = "pop3.example.org",
host = "pop3.example.com",
port = 993,
connectionSecurity = ConnectionSecurity.SSL_TLS_REQUIRED,
authenticationType = AuthType.PLAIN,
Expand All @@ -126,7 +151,7 @@ class ValidateServerSettingsTest {

val SMTP_SERVER_SETTINGS = ServerSettings(
type = "smtp",
host = "smtp.example.org",
host = "smtp.example.com",
port = 993,
connectionSecurity = ConnectionSecurity.SSL_TLS_REQUIRED,
authenticationType = AuthType.PLAIN,
Expand Down
1 change: 1 addition & 0 deletions feature/account/setup/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ dependencies {
implementation(projects.mail.protocols.smtp)

implementation(projects.feature.autodiscovery.service)
implementation(projects.feature.autodiscovery.demo)

api(projects.feature.account.common)
implementation(projects.feature.account.oauth)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package app.k9mail.feature.account.setup

import app.k9mail.autodiscovery.api.AutoDiscovery
import app.k9mail.autodiscovery.api.AutoDiscoveryRegistry
import app.k9mail.autodiscovery.api.AutoDiscoveryService
import app.k9mail.autodiscovery.service.RealAutoDiscoveryRegistry
Expand Down Expand Up @@ -45,8 +46,11 @@ val featureAccountSetupModule: Module = module {
}

single<AutoDiscoveryRegistry> {
RealAutoDiscoveryRegistry.createDefault(
okHttpClient = get(),
val extraAutoDiscoveries = get<List<AutoDiscovery>>(named("extraAutoDiscoveries"))
RealAutoDiscoveryRegistry(
autoDiscoveries = RealAutoDiscoveryRegistry.createDefaultAutoDiscoveries(
okHttpClient = get(),
) + extraAutoDiscoveries,
)
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import app.k9mail.autodiscovery.api.ImapServerSettings
import app.k9mail.autodiscovery.api.IncomingServerSettings
import app.k9mail.autodiscovery.api.OutgoingServerSettings
import app.k9mail.autodiscovery.api.SmtpServerSettings
import app.k9mail.autodiscovery.demo.DemoServerSettings
import app.k9mail.feature.account.common.domain.entity.toAuthType
import app.k9mail.feature.account.common.domain.entity.toMailConnectionSecurity
import app.k9mail.feature.account.setup.domain.entity.toAuthenticationType
Expand All @@ -14,6 +15,8 @@ import com.fsck.k9.mail.store.imap.ImapStoreSettings
internal fun IncomingServerSettings.toServerSettings(password: String?): ServerSettings {
return when (this) {
is ImapServerSettings -> this.toImapServerSettings(password)
is DemoServerSettings -> this.serverSettings

else -> throw IllegalArgumentException("Unknown server settings type: $this")
}
}
Expand Down Expand Up @@ -45,6 +48,8 @@ private fun ImapServerSettings.toImapServerSettings(password: String?): ServerSe
internal fun OutgoingServerSettings.toServerSettings(password: String?): ServerSettings {
return when (this) {
is SmtpServerSettings -> this.toSmtpServerSettings(password)
is DemoServerSettings -> this.serverSettings

else -> throw IllegalArgumentException("Unknown server settings type: $this")
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import app.k9mail.autodiscovery.api.AutoDiscoveryResult
import app.k9mail.autodiscovery.api.AutoDiscoveryService
import app.k9mail.autodiscovery.api.ImapServerSettings
import app.k9mail.autodiscovery.api.SmtpServerSettings
import app.k9mail.autodiscovery.demo.DemoServerSettings
import app.k9mail.core.common.mail.toUserEmailAddress
import app.k9mail.core.common.oauth.OAuthConfigurationProvider
import app.k9mail.feature.account.setup.domain.DomainContract
Expand All @@ -19,7 +20,11 @@ internal class GetAutoDiscovery(
val result = service.discover(email)

return if (result is AutoDiscoveryResult.Settings) {
validateOAuthSupport(result)
if (result.incomingServerSettings is DemoServerSettings) {
return result
} else {
validateOAuthSupport(result)
}
} else {
result
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import androidx.lifecycle.viewModelScope
import app.k9mail.autodiscovery.api.AutoDiscoveryResult
import app.k9mail.autodiscovery.api.ImapServerSettings
import app.k9mail.autodiscovery.api.IncomingServerSettings
import app.k9mail.autodiscovery.demo.DemoServerSettings
import app.k9mail.core.common.domain.usecase.validation.ValidationResult
import app.k9mail.core.ui.compose.common.mvi.BaseViewModel
import app.k9mail.feature.account.common.domain.AccountDomainContract
Expand Down Expand Up @@ -152,6 +153,18 @@ internal class AccountAutoDiscoveryViewModel(
}

private fun updateAutoDiscoverySettings(settings: AutoDiscoveryResult.Settings) {
if (settings.incomingServerSettings is DemoServerSettings) {
updateState {
it.copy(
isLoading = false,
autoDiscoverySettings = settings,
configStep = ConfigStep.PASSWORD,
isNextButtonVisible = true,
)
}
return
}

val imapServerSettings = settings.incomingServerSettings as ImapServerSettings
val isOAuth = imapServerSettings.authenticationTypes.first() == AutoDiscoveryAuthenticationType.OAuth2

Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package app.k9mail.feature.account.setup

import android.content.Context
import app.k9mail.autodiscovery.api.AutoDiscovery
import app.k9mail.core.common.oauth.OAuthConfigurationFactory
import app.k9mail.feature.account.common.AccountCommonExternalContract
import app.k9mail.feature.account.common.domain.entity.AccountState
Expand Down Expand Up @@ -28,6 +29,7 @@ import org.junit.runner.RunWith
import org.koin.android.ext.koin.androidContext
import org.koin.core.annotation.KoinExperimentalAPI
import org.koin.core.module.Module
import org.koin.core.qualifier.named
import org.koin.dsl.koinApplication
import org.koin.dsl.module
import org.koin.test.KoinTest
Expand Down Expand Up @@ -61,6 +63,7 @@ class AccountSetupModuleKtTest : KoinTest {
single<LocalKeyStore> { mock() }
single<AccountCommonExternalContract.AccountStateLoader> { mock() }
factory<AccountSetupExternalContract.AccountOwnerNameProvider> { mock() }
single<List<AutoDiscovery>>(named("extraAutoDiscoveries")) { emptyList() }
}

@Test
Expand Down
8 changes: 8 additions & 0 deletions feature/autodiscovery/demo/build.gradle.kts
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
plugins {
id(ThunderbirdPlugins.Library.jvm)
alias(libs.plugins.android.lint)
}

dependencies {
api(projects.feature.autodiscovery.api)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
package app.k9mail.autodiscovery.demo

import app.k9mail.autodiscovery.api.AutoDiscovery
import app.k9mail.autodiscovery.api.AutoDiscoveryResult
import app.k9mail.autodiscovery.api.AutoDiscoveryRunnable
import app.k9mail.autodiscovery.api.IncomingServerSettings
import app.k9mail.autodiscovery.api.OutgoingServerSettings
import app.k9mail.core.common.mail.EmailAddress
import app.k9mail.core.common.mail.toDomain
import com.fsck.k9.mail.AuthType
import com.fsck.k9.mail.ConnectionSecurity
import com.fsck.k9.mail.ServerSettings

class DemoAutoDiscovery : AutoDiscovery {
override fun initDiscovery(email: EmailAddress): List<AutoDiscoveryRunnable> {
val domain = email.domain.toDomain()

return listOf(
AutoDiscoveryRunnable {
if (domain.value == "example.com") {
AutoDiscoveryResult.Settings(
incomingServerSettings = DemoServerSettings,
outgoingServerSettings = DemoServerSettings,
isTrusted = true,
source = "DemoAutoDiscovery",
)
} else {
AutoDiscoveryResult.NoUsableSettingsFound
}
},
)
}
}

object DemoServerSettings : IncomingServerSettings, OutgoingServerSettings {
val serverSettings = ServerSettings(
type = "demo",
host = "irrelevant",
port = 23,
connectionSecurity = ConnectionSecurity.SSL_TLS_REQUIRED,
authenticationType = AuthType.AUTOMATIC,
username = "irrelevant",
password = "irrelevant",
clientCertificateAlias = null,
)
}
Original file line number Diff line number Diff line change
Expand Up @@ -15,16 +15,16 @@ class RealAutoDiscoveryRegistry(
override fun getAutoDiscoveries(): List<AutoDiscovery> = autoDiscoveries

companion object {
val defaultAutoconfigUrlConfig = AutoconfigUrlConfig(
private val defaultAutoconfigUrlConfig = AutoconfigUrlConfig(
httpsOnly = false,
includeEmailAddress = false,
)

fun createDefault(
fun createDefaultAutoDiscoveries(
okHttpClient: OkHttpClient,
autoconfigUrlConfig: AutoconfigUrlConfig = defaultAutoconfigUrlConfig,
): RealAutoDiscoveryRegistry = RealAutoDiscoveryRegistry(
autoDiscoveries = listOf(
): List<AutoDiscovery> {
return listOf(
createProviderAutoconfigDiscovery(
okHttpClient = okHttpClient,
config = autoconfigUrlConfig,
Expand All @@ -35,7 +35,7 @@ class RealAutoDiscoveryRegistry(
createMxLookupAutoconfigDiscovery(
okHttpClient = okHttpClient,
),
),
)
)
}
}
}
1 change: 1 addition & 0 deletions settings.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@ include(
":feature:autodiscovery:api",
":feature:autodiscovery:autoconfig",
":feature:autodiscovery:service",
":feature:autodiscovery:demo",
)

include(
Expand Down

0 comments on commit 8902b9b

Please sign in to comment.