From b4e9799fecf9e2b1a1d4a0b80eb82d644376d07a Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Tue, 27 Aug 2024 16:43:05 +0200 Subject: [PATCH] Better handling on null reset handler. This is not an error, but in this case, the reset identity is successful. --- .../impl/reset/ResetIdentityFlowManager.kt | 16 +++++++--------- .../impl/reset/ResetIdentityFlowNode.kt | 3 +++ .../impl/reset/ResetIdentityFlowManagerTest.kt | 4 +++- .../matrix/api/encryption/EncryptionService.kt | 2 +- .../impl/encryption/RustEncryptionService.kt | 7 ++++--- .../impl/encryption/RustIdentityResetHandle.kt | 16 ++++++++++------ 6 files changed, 28 insertions(+), 20 deletions(-) diff --git a/features/securebackup/impl/src/main/kotlin/io/element/android/features/securebackup/impl/reset/ResetIdentityFlowManager.kt b/features/securebackup/impl/src/main/kotlin/io/element/android/features/securebackup/impl/reset/ResetIdentityFlowManager.kt index 16850890a7..22e1bec945 100644 --- a/features/securebackup/impl/src/main/kotlin/io/element/android/features/securebackup/impl/reset/ResetIdentityFlowManager.kt +++ b/features/securebackup/impl/src/main/kotlin/io/element/android/features/securebackup/impl/reset/ResetIdentityFlowManager.kt @@ -36,8 +36,8 @@ class ResetIdentityFlowManager @Inject constructor( @SessionCoroutineScope private val sessionCoroutineScope: CoroutineScope, private val sessionVerificationService: SessionVerificationService, ) { - private val resetHandleFlow: MutableStateFlow> = MutableStateFlow(AsyncData.Uninitialized) - val currentHandleFlow: StateFlow> = resetHandleFlow + private val resetHandleFlow: MutableStateFlow> = MutableStateFlow(AsyncData.Uninitialized) + val currentHandleFlow: StateFlow> = resetHandleFlow private var whenResetIsDoneWaitingJob: Job? = null fun whenResetIsDone(block: () -> Unit) { @@ -47,7 +47,7 @@ class ResetIdentityFlowManager @Inject constructor( } } - fun getResetHandle(): StateFlow> { + fun getResetHandle(): StateFlow> { return if (resetHandleFlow.value.isLoading() || resetHandleFlow.value.isSuccess()) { resetHandleFlow } else { @@ -56,13 +56,11 @@ class ResetIdentityFlowManager @Inject constructor( sessionCoroutineScope.launch { matrixClient.encryptionService().startIdentityReset() .onSuccess { handle -> - resetHandleFlow.value = if (handle != null) { - AsyncData.Success(handle) - } else { - AsyncData.Failure(IllegalStateException("Could not get a reset identity handle")) - } + resetHandleFlow.value = AsyncData.Success(handle) + } + .onFailure { + resetHandleFlow.value = AsyncData.Failure(it) } - .onFailure { resetHandleFlow.value = AsyncData.Failure(it) } } resetHandleFlow diff --git a/features/securebackup/impl/src/main/kotlin/io/element/android/features/securebackup/impl/reset/ResetIdentityFlowNode.kt b/features/securebackup/impl/src/main/kotlin/io/element/android/features/securebackup/impl/reset/ResetIdentityFlowNode.kt index 9bd8aeff03..7900cf858d 100644 --- a/features/securebackup/impl/src/main/kotlin/io/element/android/features/securebackup/impl/reset/ResetIdentityFlowNode.kt +++ b/features/securebackup/impl/src/main/kotlin/io/element/android/features/securebackup/impl/reset/ResetIdentityFlowNode.kt @@ -140,6 +140,9 @@ class ResetIdentityFlowNode @AssistedInject constructor( } is AsyncData.Success -> { when (val handle = state.data) { + null -> { + Timber.d("No reset handle return, the reset is done.") + } is IdentityOidcResetHandle -> { if (oidcEntryPoint.canUseCustomTab()) { activity.openUrlInChromeCustomTab(null, false, handle.url) diff --git a/features/securebackup/impl/src/test/kotlin/io/element/android/features/securebackup/impl/reset/ResetIdentityFlowManagerTest.kt b/features/securebackup/impl/src/test/kotlin/io/element/android/features/securebackup/impl/reset/ResetIdentityFlowManagerTest.kt index eb33fe5c36..2e03db7e36 100644 --- a/features/securebackup/impl/src/test/kotlin/io/element/android/features/securebackup/impl/reset/ResetIdentityFlowManagerTest.kt +++ b/features/securebackup/impl/src/test/kotlin/io/element/android/features/securebackup/impl/reset/ResetIdentityFlowManagerTest.kt @@ -73,7 +73,9 @@ class ResetIdentityFlowManagerTest { flowManager.getResetHandle().test { assertThat(awaitItem().isLoading()).isTrue() - assertThat(awaitItem().isFailure()).isTrue() + val finalItem = awaitItem() + assertThat(finalItem.isSuccess()).isTrue() + assertThat(finalItem.dataOrNull()).isNull() startResetLambda.assertions().isCalledOnce() } } diff --git a/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/encryption/EncryptionService.kt b/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/encryption/EncryptionService.kt index 5afb81648b..ac5431a965 100644 --- a/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/encryption/EncryptionService.kt +++ b/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/encryption/EncryptionService.kt @@ -72,7 +72,7 @@ interface EncryptionService { /** * A handle to reset the user's identity. */ -interface IdentityResetHandle { +sealed interface IdentityResetHandle { /** * Cancel the reset process and drops the existing handle in the SDK. */ diff --git a/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/encryption/RustEncryptionService.kt b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/encryption/RustEncryptionService.kt index ae681b2771..2040c772d6 100644 --- a/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/encryption/RustEncryptionService.kt +++ b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/encryption/RustEncryptionService.kt @@ -17,6 +17,7 @@ package io.element.android.libraries.matrix.impl.encryption import io.element.android.libraries.core.coroutine.CoroutineDispatchers +import io.element.android.libraries.core.extensions.flatMap import io.element.android.libraries.core.extensions.mapFailure import io.element.android.libraries.matrix.api.core.SessionId import io.element.android.libraries.matrix.api.encryption.BackupState @@ -204,9 +205,9 @@ internal class RustEncryptionService( override suspend fun startIdentityReset(): Result { return runCatching { - service.resetIdentity()?.let { handle -> - RustIdentityResetHandleFactory.create(sessionId, handle) - }?.getOrNull() + service.resetIdentity() + }.flatMap { handle -> + RustIdentityResetHandleFactory.create(sessionId, handle) } } } diff --git a/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/encryption/RustIdentityResetHandle.kt b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/encryption/RustIdentityResetHandle.kt index c4c20eb7d6..e6428d7fe8 100644 --- a/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/encryption/RustIdentityResetHandle.kt +++ b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/encryption/RustIdentityResetHandle.kt @@ -27,13 +27,17 @@ import org.matrix.rustcomponents.sdk.CrossSigningResetAuthType object RustIdentityResetHandleFactory { fun create( userId: UserId, - identityResetHandle: org.matrix.rustcomponents.sdk.IdentityResetHandle - ): Result { + identityResetHandle: org.matrix.rustcomponents.sdk.IdentityResetHandle? + ): Result { return runCatching { - when (val authType = identityResetHandle.authType()) { - is CrossSigningResetAuthType.Oidc -> RustOidcIdentityResetHandle(identityResetHandle, authType.info.approvalUrl) - // User interactive authentication (user + password) - CrossSigningResetAuthType.Uiaa -> RustPasswordIdentityResetHandle(userId, identityResetHandle) + if (identityResetHandle == null) { + null + } else { + when (val authType = identityResetHandle.authType()) { + is CrossSigningResetAuthType.Oidc -> RustOidcIdentityResetHandle(identityResetHandle, authType.info.approvalUrl) + // User interactive authentication (user + password) + CrossSigningResetAuthType.Uiaa -> RustPasswordIdentityResetHandle(userId, identityResetHandle) + } } } }