From 6a1ef6d6f7cf1bee84fac62740af435d692b1a56 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Wed, 16 Oct 2024 14:39:20 +0200 Subject: [PATCH] Fix API update regrading OidcPrompt. --- .../ConfirmAccountProviderPresenter.kt | 3 +- .../api/auth/MatrixAuthenticationService.kt | 2 +- .../libraries/matrix/api/auth/OidcPrompt.kt | 51 +++++++++++++++++++ .../libraries/matrix/impl/auth/OidcPrompt.kt | 22 ++++++++ .../auth/RustMatrixAuthenticationService.kt | 8 ++- .../auth/FakeMatrixAuthenticationService.kt | 3 +- 6 files changed, 84 insertions(+), 5 deletions(-) create mode 100644 libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/auth/OidcPrompt.kt create mode 100644 libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/auth/OidcPrompt.kt diff --git a/features/login/impl/src/main/kotlin/io/element/android/features/login/impl/screens/confirmaccountprovider/ConfirmAccountProviderPresenter.kt b/features/login/impl/src/main/kotlin/io/element/android/features/login/impl/screens/confirmaccountprovider/ConfirmAccountProviderPresenter.kt index c15c84744f..63720a613b 100644 --- a/features/login/impl/src/main/kotlin/io/element/android/features/login/impl/screens/confirmaccountprovider/ConfirmAccountProviderPresenter.kt +++ b/features/login/impl/src/main/kotlin/io/element/android/features/login/impl/screens/confirmaccountprovider/ConfirmAccountProviderPresenter.kt @@ -27,6 +27,7 @@ import io.element.android.libraries.architecture.AsyncData import io.element.android.libraries.architecture.Presenter import io.element.android.libraries.architecture.runCatchingUpdatingState import io.element.android.libraries.matrix.api.auth.MatrixAuthenticationService +import io.element.android.libraries.matrix.api.auth.OidcPrompt import io.element.android.libraries.oidc.api.OidcAction import io.element.android.libraries.oidc.api.OidcActionFlow import kotlinx.coroutines.CoroutineScope @@ -92,7 +93,7 @@ class ConfirmAccountProviderPresenter @AssistedInject constructor( val matrixHomeServerDetails = authenticationService.getHomeserverDetails().value!! if (matrixHomeServerDetails.supportsOidcLogin) { // Retrieve the details right now - LoginFlow.OidcFlow(authenticationService.getOidcUrl().getOrThrow()) + LoginFlow.OidcFlow(authenticationService.getOidcUrl(OidcPrompt.Consent).getOrThrow()) } else if (params.isAccountCreation) { val url = webClientUrlForAuthenticationRetriever.retrieve(homeserverUrl) LoginFlow.AccountCreationFlow(url) diff --git a/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/auth/MatrixAuthenticationService.kt b/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/auth/MatrixAuthenticationService.kt index bb3d396202..b7b44ba45e 100644 --- a/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/auth/MatrixAuthenticationService.kt +++ b/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/auth/MatrixAuthenticationService.kt @@ -43,7 +43,7 @@ interface MatrixAuthenticationService { /** * Get the Oidc url to display to the user. */ - suspend fun getOidcUrl(): Result + suspend fun getOidcUrl(prompt: OidcPrompt): Result /** * Cancel Oidc login sequence. diff --git a/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/auth/OidcPrompt.kt b/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/auth/OidcPrompt.kt new file mode 100644 index 0000000000..2444425f3a --- /dev/null +++ b/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/auth/OidcPrompt.kt @@ -0,0 +1,51 @@ +/* + * Copyright 2024 New Vector Ltd. + * + * SPDX-License-Identifier: AGPL-3.0-only + * Please see LICENSE in the repository root for full details. + */ + +package io.element.android.libraries.matrix.api.auth + +sealed interface OidcPrompt { + /** + * The Authorization Server must not display any authentication or consent + * user interface pages. + */ + data object None : OidcPrompt + + /** + * The Authorization Server should prompt the End-User for + * reauthentication. + */ + data object Login : OidcPrompt + + /** + * The Authorization Server should prompt the End-User for consent before + * returning information to the Client. + */ + data object Consent : OidcPrompt + + /** + * The Authorization Server should prompt the End-User to select a user + * account. + * + * This enables an End-User who has multiple accounts at the Authorization + * Server to select amongst the multiple accounts that they might have + * current sessions for. + */ + data object SelectAccount : OidcPrompt + + /** + * The Authorization Server should prompt the End-User to create a user + * account. + * + * Defined in [Initiating User Registration via OpenID Connect](https://openid.net/specs/openid-connect-prompt-create-1_0.html). + */ + data object Create : OidcPrompt + + /** + * An unknown value. + */ + data class Unknown(val value: String) : OidcPrompt +} diff --git a/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/auth/OidcPrompt.kt b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/auth/OidcPrompt.kt new file mode 100644 index 0000000000..a5b9e4d28f --- /dev/null +++ b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/auth/OidcPrompt.kt @@ -0,0 +1,22 @@ +/* + * Copyright 2024 New Vector Ltd. + * + * SPDX-License-Identifier: AGPL-3.0-only + * Please see LICENSE in the repository root for full details. + */ + +package io.element.android.libraries.matrix.impl.auth + +import io.element.android.libraries.matrix.api.auth.OidcPrompt +import org.matrix.rustcomponents.sdk.OidcPrompt as RustOidcPrompt + +internal fun OidcPrompt.toRustPrompt(): RustOidcPrompt { + return when (this) { + OidcPrompt.None -> RustOidcPrompt.None + OidcPrompt.Login -> RustOidcPrompt.Login + OidcPrompt.Consent -> RustOidcPrompt.Consent + OidcPrompt.SelectAccount -> RustOidcPrompt.SelectAccount + OidcPrompt.Create -> RustOidcPrompt.Create + is OidcPrompt.Unknown -> RustOidcPrompt.Unknown(value) + } +} diff --git a/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/auth/RustMatrixAuthenticationService.kt b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/auth/RustMatrixAuthenticationService.kt index 47a81e9f65..434b0b2aef 100644 --- a/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/auth/RustMatrixAuthenticationService.kt +++ b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/auth/RustMatrixAuthenticationService.kt @@ -17,6 +17,7 @@ import io.element.android.libraries.matrix.api.MatrixClient import io.element.android.libraries.matrix.api.auth.MatrixAuthenticationService import io.element.android.libraries.matrix.api.auth.MatrixHomeServerDetails import io.element.android.libraries.matrix.api.auth.OidcDetails +import io.element.android.libraries.matrix.api.auth.OidcPrompt import io.element.android.libraries.matrix.api.auth.external.ExternalSession import io.element.android.libraries.matrix.api.auth.qrlogin.MatrixQrCodeLoginData import io.element.android.libraries.matrix.api.auth.qrlogin.QrCodeLoginStep @@ -181,11 +182,14 @@ class RustMatrixAuthenticationService @Inject constructor( private var pendingOidcAuthorizationData: OidcAuthorizationData? = null - override suspend fun getOidcUrl(): Result { + override suspend fun getOidcUrl(prompt: OidcPrompt): Result { return withContext(coroutineDispatchers.io) { runCatching { val client = currentClient ?: error("You need to call `setHomeserver()` first") - val oidcAuthenticationData = client.urlForOidcLogin(oidcConfigurationProvider.get()) + val oidcAuthenticationData = client.urlForOidc( + oidcConfiguration = oidcConfigurationProvider.get(), + prompt = prompt.toRustPrompt(), + ) val url = oidcAuthenticationData.loginUrl() pendingOidcAuthorizationData = oidcAuthenticationData OidcDetails(url) diff --git a/libraries/matrix/test/src/main/kotlin/io/element/android/libraries/matrix/test/auth/FakeMatrixAuthenticationService.kt b/libraries/matrix/test/src/main/kotlin/io/element/android/libraries/matrix/test/auth/FakeMatrixAuthenticationService.kt index 8c18629817..2846542890 100644 --- a/libraries/matrix/test/src/main/kotlin/io/element/android/libraries/matrix/test/auth/FakeMatrixAuthenticationService.kt +++ b/libraries/matrix/test/src/main/kotlin/io/element/android/libraries/matrix/test/auth/FakeMatrixAuthenticationService.kt @@ -11,6 +11,7 @@ import io.element.android.libraries.matrix.api.MatrixClient import io.element.android.libraries.matrix.api.auth.MatrixAuthenticationService import io.element.android.libraries.matrix.api.auth.MatrixHomeServerDetails import io.element.android.libraries.matrix.api.auth.OidcDetails +import io.element.android.libraries.matrix.api.auth.OidcPrompt import io.element.android.libraries.matrix.api.auth.external.ExternalSession import io.element.android.libraries.matrix.api.auth.qrlogin.MatrixQrCodeLoginData import io.element.android.libraries.matrix.api.auth.qrlogin.QrCodeLoginStep @@ -80,7 +81,7 @@ class FakeMatrixAuthenticationService( return importCreatedSessionLambda(externalSession) } - override suspend fun getOidcUrl(): Result = simulateLongTask { + override suspend fun getOidcUrl(prompt: OidcPrompt): Result = simulateLongTask { oidcError?.let { Result.failure(it) } ?: Result.success(A_OIDC_DATA) }