Restore OIDC support.

This commit is contained in:
Benoit Marty 2023-08-23 11:55:05 +02:00
parent 7df985baed
commit 6928dc6e44
23 changed files with 164 additions and 87 deletions

View file

@ -119,6 +119,11 @@ class RustMatrixClient constructor(
Timber.v("didReceiveAuthError -> already cleaning up")
}
}
override fun didRefreshTokens() {
Timber.w("didRefreshTokens()")
// TODO handle refresh token
}
}
private val rustRoomListService: RoomListService =
@ -287,19 +292,23 @@ class RustMatrixClient constructor(
baseDirectory.deleteSessionDirectory(userID = sessionId.value, deleteCryptoDb = false)
}
override suspend fun logout() = doLogout(doRequest = true)
override suspend fun logout(): String? = doLogout(doRequest = true)
private suspend fun doLogout(doRequest: Boolean) = withContext(sessionDispatcher) {
if (doRequest) {
try {
client.logout()
} catch (failure: Throwable) {
Timber.e(failure, "Fail to call logout on HS. Still delete local files.")
private suspend fun doLogout(doRequest: Boolean): String? {
var result: String? = null
withContext(sessionDispatcher) {
if (doRequest) {
try {
result = client.logout()
} catch (failure: Throwable) {
Timber.e(failure, "Fail to call logout on HS. Still delete local files.")
}
}
close()
baseDirectory.deleteSessionDirectory(userID = sessionId.value, deleteCryptoDb = true)
sessionStore.removeSession(sessionId.value)
}
close()
baseDirectory.deleteSessionDirectory(userID = sessionId.value, deleteCryptoDb = true)
sessionStore.removeSession(sessionId.value)
return result
}
override suspend fun loadUserDisplayName(): Result<String> = withContext(sessionDispatcher) {

View file

@ -75,4 +75,5 @@ private fun SessionData.toSession() = Session(
deviceId = deviceId,
homeserverUrl = homeserverUrl,
slidingSyncProxy = slidingSyncProxy,
oidcData = oidcData,
)

View file

@ -26,15 +26,12 @@ fun Throwable.mapAuthenticationException(): AuthenticationException {
is RustAuthenticationException.InvalidServerName -> AuthenticationException.InvalidServerName(this.message!!)
is RustAuthenticationException.SessionMissing -> AuthenticationException.SessionMissing(this.message!!)
is RustAuthenticationException.SlidingSyncNotAvailable -> AuthenticationException.SlidingSyncNotAvailable(this.message!!)
/* TODO Oidc
is RustAuthenticationException.OidcException -> AuthenticationException.OidcError("OidcException", message!!)
is RustAuthenticationException.OidcMetadataInvalid -> AuthenticationException.OidcError("OidcMetadataInvalid", message!!)
is RustAuthenticationException.OidcMetadataMissing -> AuthenticationException.OidcError("OidcMetadataMissing", message!!)
is RustAuthenticationException.OidcNotStarted -> AuthenticationException.OidcError("OidcNotStarted", message!!)
is RustAuthenticationException.OidcNotSupported -> AuthenticationException.OidcError("OidcNotSupported", message!!)
*/
is RustAuthenticationException.OidcCancelled -> AuthenticationException.OidcError("OidcCancelled", message!!)
is RustAuthenticationException.OidcCallbackUrlInvalid -> AuthenticationException.OidcError("OidcCallbackUrlInvalid", message!!)
else -> AuthenticationException.Generic(this.message ?: "Unknown error")
}
}

View file

@ -23,6 +23,6 @@ fun HomeserverLoginDetails.map(): MatrixHomeServerDetails = use {
MatrixHomeServerDetails(
url = url(),
supportsPasswordLogin = supportsPasswordLogin(),
supportsOidcLogin = false // TODO Oidc supportsOidcLogin(),
supportsOidcLogin = supportsOidcLogin(),
)
}

View file

@ -16,17 +16,19 @@
package io.element.android.libraries.matrix.impl.auth
// TODO Oidc
// import io.element.android.libraries.matrix.api.auth.OidcConfig
// import org.matrix.rustcomponents.sdk.OidcClientMetadata
import io.element.android.libraries.matrix.api.auth.OidcConfig
import org.matrix.rustcomponents.sdk.OidcConfiguration
/*
val oidcClientMetadata: OidcClientMetadata = OidcClientMetadata(
val oidcConfiguration: OidcConfiguration = OidcConfiguration(
clientName = "Element",
redirectUri = OidcConfig.redirectUri,
clientUri = "https://element.io",
tosUri = "https://element.io/user-terms-of-service",
policyUri = "https://element.io/privacy"
policyUri = "https://element.io/privacy",
/**
* Some homeservers/auth issuers don't support dynamic client registration, and have to be registered manually
*/
staticRegistrations = mapOf(
"https://id.thirdroom.io/realms/thirdroom" to "elementx",
),
)
*/

View file

@ -16,8 +16,6 @@
package io.element.android.libraries.matrix.impl.auth
// TODO Oidc
// import org.matrix.rustcomponents.sdk.OidcAuthenticationUrl
import com.squareup.anvil.annotations.ContributesBinding
import io.element.android.libraries.core.coroutine.CoroutineDispatchers
import io.element.android.libraries.core.extensions.mapFailure
@ -37,6 +35,7 @@ import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.withContext
import org.matrix.rustcomponents.sdk.OidcAuthenticationData
import org.matrix.rustcomponents.sdk.Session
import org.matrix.rustcomponents.sdk.use
import java.io.File
@ -57,9 +56,8 @@ class RustMatrixAuthenticationService @Inject constructor(
private val authService: RustAuthenticationService = RustAuthenticationService(
basePath = baseDirectory.absolutePath,
passphrase = null,
// TODO Oidc
// oidcClientMetadata = oidcClientMetadata,
userAgent = userAgentProvider.provide(),
oidcConfiguration = oidcConfiguration,
customSlidingSyncProxy = null,
)
private var currentHomeserver = MutableStateFlow<MatrixHomeServerDetails?>(null)
@ -112,60 +110,50 @@ class RustMatrixAuthenticationService @Inject constructor(
}
}
// TODO Oidc
// private var pendingUrlForOidcLogin: OidcAuthenticationUrl? = null
private var pendingOidcAuthenticationData: OidcAuthenticationData? = null
override suspend fun getOidcUrl(): Result<OidcDetails> {
TODO("Oidc")
/*
return withContext(coroutineDispatchers.io) {
runCatching {
val urlForOidcLogin = authService.urlForOidcLogin()
val url = urlForOidcLogin.loginUrl()
pendingUrlForOidcLogin = urlForOidcLogin
val oidcAuthenticationData = authService.urlForOidcLogin()
val url = oidcAuthenticationData.loginUrl()
pendingOidcAuthenticationData = oidcAuthenticationData
OidcDetails(url)
}.mapFailure { failure ->
failure.mapAuthenticationException()
}
}
*/
}
override suspend fun cancelOidcLogin(): Result<Unit> {
TODO("Oidc")
/*
return withContext(coroutineDispatchers.io) {
runCatching {
pendingUrlForOidcLogin?.close()
pendingUrlForOidcLogin = null
pendingOidcAuthenticationData?.close()
pendingOidcAuthenticationData = null
}.mapFailure { failure ->
failure.mapAuthenticationException()
}
}
*/
}
/**
* callbackUrl should be the uriRedirect from OidcClientMetadata (with all the parameters).
*/
override suspend fun loginWithOidc(callbackUrl: String): Result<SessionId> {
TODO("Oidc")
/*
return withContext(coroutineDispatchers.io) {
runCatching {
val urlForOidcLogin = pendingUrlForOidcLogin ?: error("You need to call `getOidcUrl()` first")
val urlForOidcLogin = pendingOidcAuthenticationData ?: error("You need to call `getOidcUrl()` first")
val client = authService.loginWithOidcCallback(urlForOidcLogin, callbackUrl)
val sessionData = client.use { it.session().toSessionData() }
pendingUrlForOidcLogin = null
pendingOidcAuthenticationData?.close()
pendingOidcAuthenticationData = null
sessionStore.storeData(sessionData)
SessionId(sessionData.userId)
}.mapFailure { failure ->
failure.mapAuthenticationException()
}
}
*/
}
}
private fun Session.toSessionData() = SessionData(
@ -174,6 +162,7 @@ private fun Session.toSessionData() = SessionData(
accessToken = accessToken,
refreshToken = refreshToken,
homeserverUrl = homeserverUrl,
oidcData = oidcData,
slidingSyncProxy = slidingSyncProxy,
loginTimestamp = Date(),
)