Add new AutoDiscovery API
This commit is contained in:
parent
3e5b7b1772
commit
f948fad797
14 changed files with 198 additions and 1 deletions
|
@ -0,0 +1,13 @@
|
|||
package app.k9mail.core.common.net
|
||||
|
||||
/**
|
||||
* Represents a hostname, IPv4, or IPv6 address.
|
||||
*/
|
||||
@JvmInline
|
||||
value class Hostname(val value: String) {
|
||||
init {
|
||||
requireNotNull(HostNameUtils.isLegalHostNameOrIP(value)) { "Not a valid domain or IP: '$value'" }
|
||||
}
|
||||
}
|
||||
|
||||
fun String.toHostname() = Hostname(this)
|
|
@ -0,0 +1,11 @@
|
|||
package app.k9mail.core.common.net
|
||||
|
||||
@Suppress("MagicNumber")
|
||||
@JvmInline
|
||||
value class Port(val value: Int) {
|
||||
init {
|
||||
require(value in 0..65535) { "Not a valid port number: $value" }
|
||||
}
|
||||
}
|
||||
|
||||
fun Int.toPort() = Port(this)
|
|
@ -0,0 +1,47 @@
|
|||
package app.k9mail.core.common.net
|
||||
|
||||
import assertk.assertFailure
|
||||
import assertk.assertThat
|
||||
import assertk.assertions.hasMessage
|
||||
import assertk.assertions.isEqualTo
|
||||
import assertk.assertions.isInstanceOf
|
||||
import kotlin.test.Test
|
||||
|
||||
class HostnameTest {
|
||||
@Test
|
||||
fun `valid domain`() {
|
||||
val hostname = Hostname("domain.example")
|
||||
|
||||
assertThat(hostname.value).isEqualTo("domain.example")
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `valid IPv4`() {
|
||||
val hostname = Hostname("127.0.0.1")
|
||||
|
||||
assertThat(hostname.value).isEqualTo("127.0.0.1")
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `valid IPv6`() {
|
||||
val hostname = Hostname("fc00::1")
|
||||
|
||||
assertThat(hostname.value).isEqualTo("fc00::1")
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `invalid domain should throw`() {
|
||||
assertFailure {
|
||||
Hostname("invalid domain")
|
||||
}.isInstanceOf<IllegalArgumentException>()
|
||||
.hasMessage("Not a valid domain or IP: 'invalid domain'")
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `invalid IPv6 should throw`() {
|
||||
assertFailure {
|
||||
Hostname("fc00:1")
|
||||
}.isInstanceOf<IllegalArgumentException>()
|
||||
.hasMessage("Not a valid domain or IP: 'fc00:1'")
|
||||
}
|
||||
}
|
|
@ -0,0 +1,33 @@
|
|||
package app.k9mail.core.common.net
|
||||
|
||||
import assertk.assertFailure
|
||||
import assertk.assertThat
|
||||
import assertk.assertions.hasMessage
|
||||
import assertk.assertions.isEqualTo
|
||||
import assertk.assertions.isInstanceOf
|
||||
import kotlin.test.Test
|
||||
|
||||
class PortTest {
|
||||
@Test
|
||||
fun `valid port number`() {
|
||||
val port = Port(993)
|
||||
|
||||
assertThat(port.value).isEqualTo(993)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `negative port number should throw`() {
|
||||
assertFailure {
|
||||
Port(-1)
|
||||
}.isInstanceOf<IllegalArgumentException>()
|
||||
.hasMessage("Not a valid port number: -1")
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `port number exceeding valid range should throw`() {
|
||||
assertFailure {
|
||||
Port(65536)
|
||||
}.isInstanceOf<IllegalArgumentException>()
|
||||
.hasMessage("Not a valid port number: 65536")
|
||||
}
|
||||
}
|
|
@ -5,4 +5,5 @@ plugins {
|
|||
|
||||
dependencies {
|
||||
api(projects.mail.common)
|
||||
api(projects.core.common)
|
||||
}
|
||||
|
|
|
@ -0,0 +1,13 @@
|
|||
package app.k9mail.autodiscovery.api
|
||||
|
||||
/**
|
||||
* The authentication types supported when using the [AutoDiscovery] mechanism.
|
||||
*
|
||||
* Note: Currently we support the same set of values in [ImapServerSettings] and [SmtpServerSettings]. As soon as this
|
||||
* changes, this type should be replaced with `ImapAuthenticationType` and `SmtpAuthenticationType`.
|
||||
*/
|
||||
enum class AuthenticationType {
|
||||
PasswordCleartext,
|
||||
PasswordEncrypted,
|
||||
OAuth2,
|
||||
}
|
|
@ -0,0 +1,13 @@
|
|||
package app.k9mail.autodiscovery.api
|
||||
|
||||
import app.k9mail.core.common.mail.EmailAddress
|
||||
|
||||
/**
|
||||
* Provides a mechanism to find mail server settings for a given email address.
|
||||
*/
|
||||
interface AutoDiscovery {
|
||||
/**
|
||||
* Returns a list of [AutoDiscoveryRunnable]s that perform the actual mail server settings discovery.
|
||||
*/
|
||||
fun initDiscovery(email: EmailAddress): List<AutoDiscoveryRunnable>
|
||||
}
|
|
@ -0,0 +1,23 @@
|
|||
package app.k9mail.autodiscovery.api
|
||||
|
||||
/**
|
||||
* Results of a mail server settings lookup.
|
||||
*/
|
||||
data class AutoDiscoveryResult(
|
||||
val incomingServerSettings: IncomingServerSettings,
|
||||
val outgoingServerSettings: OutgoingServerSettings,
|
||||
)
|
||||
|
||||
/**
|
||||
* Incoming mail server settings.
|
||||
*
|
||||
* Implementations contain protocol-specific properties.
|
||||
*/
|
||||
interface IncomingServerSettings
|
||||
|
||||
/**
|
||||
* Outgoing mail server settings.
|
||||
*
|
||||
* Implementations contain protocol-specific properties.
|
||||
*/
|
||||
interface OutgoingServerSettings
|
|
@ -0,0 +1,10 @@
|
|||
package app.k9mail.autodiscovery.api
|
||||
|
||||
/**
|
||||
* Performs a mail server settings lookup.
|
||||
*
|
||||
* This is an abstraction that allows us to run multiple lookups in parallel.
|
||||
*/
|
||||
fun interface AutoDiscoveryRunnable {
|
||||
suspend fun run(): AutoDiscoveryResult?
|
||||
}
|
|
@ -0,0 +1,9 @@
|
|||
package app.k9mail.autodiscovery.api
|
||||
|
||||
/**
|
||||
* The connection security methods supported when using the [AutoDiscovery] mechanism.
|
||||
*/
|
||||
enum class ConnectionSecurity {
|
||||
StartTLS,
|
||||
TLS,
|
||||
}
|
|
@ -3,6 +3,7 @@ package app.k9mail.autodiscovery.api
|
|||
import com.fsck.k9.mail.AuthType
|
||||
import com.fsck.k9.mail.ConnectionSecurity
|
||||
|
||||
@Deprecated("New code should use app.k9mail.autodiscovery.api.AutoDiscovery")
|
||||
interface ConnectionSettingsDiscovery {
|
||||
fun discover(email: String): DiscoveryResults?
|
||||
}
|
||||
|
|
|
@ -0,0 +1,12 @@
|
|||
package app.k9mail.autodiscovery.api
|
||||
|
||||
import app.k9mail.core.common.net.Hostname
|
||||
import app.k9mail.core.common.net.Port
|
||||
|
||||
data class ImapServerSettings(
|
||||
val hostname: Hostname,
|
||||
val port: Port,
|
||||
val connectionSecurity: ConnectionSecurity,
|
||||
val authenticationType: AuthenticationType,
|
||||
val username: String,
|
||||
) : IncomingServerSettings
|
|
@ -0,0 +1,12 @@
|
|||
package app.k9mail.autodiscovery.api
|
||||
|
||||
import app.k9mail.core.common.net.Hostname
|
||||
import app.k9mail.core.common.net.Port
|
||||
|
||||
data class SmtpServerSettings(
|
||||
val hostname: Hostname,
|
||||
val port: Port,
|
||||
val connectionSecurity: ConnectionSecurity,
|
||||
val authenticationType: AuthenticationType,
|
||||
val username: String,
|
||||
) : OutgoingServerSettings
|
|
@ -7,7 +7,6 @@ dependencies {
|
|||
api(projects.feature.autodiscovery.api)
|
||||
|
||||
compileOnly(libs.xmlpull)
|
||||
implementation(projects.core.common)
|
||||
implementation(libs.okhttp)
|
||||
implementation(libs.minidns.hla)
|
||||
|
||||
|
|
Loading…
Reference in a new issue