Use the SDK Client to check whether a homeserver is compatible (#5664)

* Use the SDK `Client` to check whether a HS is compatible

* Remove usage of unused `WellKnown`, keep `ElementWellKnown`

* Make `HomeServerLoginCompatibilityChecker.check` return `true/false` values to distinguish non-valid homeservers from a failed check

* Use `inMemoryStore` and `serverNameOrHomeserverUrl`

* Do some cleanup of `isValid` and `isWellknownValid`

* Make the debounce for starting the search a bit higher, as checking for the homeservers seems more resource-intensive now
This commit is contained in:
Jorge Martin Espinosa 2025-11-04 15:43:00 +01:00 committed by GitHub
parent 8a4d0c7bee
commit 7aa564e74d
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
27 changed files with 195 additions and 341 deletions

View file

@ -0,0 +1,36 @@
/*
* Copyright 2025 New Vector Ltd.
*
* SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial
* Please see LICENSE files in the repository root for full details.
*/
package io.element.android.libraries.matrix.impl.auth
import dev.zacsweers.metro.AppScope
import dev.zacsweers.metro.ContributesBinding
import dev.zacsweers.metro.Inject
import io.element.android.libraries.core.extensions.runCatchingExceptions
import io.element.android.libraries.matrix.api.auth.HomeServerLoginCompatibilityChecker
import io.element.android.libraries.matrix.impl.ClientBuilderProvider
import timber.log.Timber
@ContributesBinding(AppScope::class)
@Inject
class RustHomeServerLoginCompatibilityChecker(
private val clientBuilderProvider: ClientBuilderProvider,
) : HomeServerLoginCompatibilityChecker {
override suspend fun check(url: String): Result<Boolean> = runCatchingExceptions {
clientBuilderProvider.provide()
.inMemoryStore()
.serverNameOrHomeserverUrl(url)
.build()
.use {
it.homeserverLoginDetails()
}
.use {
Timber.d("Homeserver $url | OIDC: ${it.supportsOidcLogin()} | Password: ${it.supportsPasswordLogin()} | SSO: ${it.supportsSsoLogin()}")
it.supportsOidcLogin() || it.supportsPasswordLogin()
}
}
}

View file

@ -0,0 +1,54 @@
/*
* Copyright 2025 New Vector Ltd.
*
* SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial
* Please see LICENSE files in the repository root for full details.
*/
package io.element.android.libraries.matrix.impl.auth
import com.google.common.truth.Truth.assertThat
import io.element.android.libraries.matrix.impl.FakeClientBuilderProvider
import io.element.android.libraries.matrix.impl.fixtures.fakes.FakeFfiClient
import io.element.android.libraries.matrix.impl.fixtures.fakes.FakeFfiClientBuilder
import io.element.android.libraries.matrix.impl.fixtures.fakes.FakeFfiHomeserverLoginDetails
import kotlinx.coroutines.test.runTest
import org.junit.Ignore
import org.junit.Test
@Ignore("JNA direct mapping has broken unit tests with FFI fakes")
class RustHomeserverLoginCompatibilityCheckerTest {
@Test
fun `check - is valid if it supports OIDC login`() = runTest {
val sut = createChecker { FakeFfiHomeserverLoginDetails(supportsOidcLogin = true) }
assertThat(sut.check("https://matrix.host.org").getOrNull()).isTrue()
}
@Test
fun `check - is valid if it supports password login`() = runTest {
val sut = createChecker { FakeFfiHomeserverLoginDetails(supportsPasswordLogin = true) }
assertThat(sut.check("https://matrix.host.org").getOrNull()).isTrue()
}
@Test
fun `check - is not valid if it only supports SSO login`() = runTest {
val sut = createChecker { FakeFfiHomeserverLoginDetails(supportsSsoLogin = true) }
assertThat(sut.check("https://matrix.host.org").getOrNull()).isFalse()
}
@Test
fun `check - is not valid if fetching the data fails`() = runTest {
val sut = createChecker { error("Unexpected error!") }
assertThat(sut.check("https://matrix.host.org").isFailure).isTrue()
}
private fun createChecker(
result: () -> FakeFfiHomeserverLoginDetails,
) = RustHomeServerLoginCompatibilityChecker(
clientBuilderProvider = FakeClientBuilderProvider {
FakeFfiClientBuilder {
FakeFfiClient(homeserverLoginDetailsResult = result)
}
}
)
}

View file

@ -12,10 +12,12 @@ import org.matrix.rustcomponents.sdk.NoHandle
class FakeFfiHomeserverLoginDetails(
private val url: String = "https://example.org",
private val supportsPasswordLogin: Boolean = true,
private val supportsOidcLogin: Boolean = false
private val supportsPasswordLogin: Boolean = false,
private val supportsOidcLogin: Boolean = false,
private val supportsSsoLogin: Boolean = false,
) : HomeserverLoginDetails(NoHandle) {
override fun url(): String = url
override fun supportsOidcLogin(): Boolean = supportsOidcLogin
override fun supportsPasswordLogin(): Boolean = supportsPasswordLogin
override fun supportsSsoLogin(): Boolean = supportsSsoLogin
}