Better handling on null reset handler.

This is not an error, but in this case, the reset identity is successful.
This commit is contained in:
Benoit Marty 2024-08-27 16:43:05 +02:00 committed by Benoit Marty
parent 8408c7db2d
commit b4e9799fec
6 changed files with 28 additions and 20 deletions

View file

@ -36,8 +36,8 @@ class ResetIdentityFlowManager @Inject constructor(
@SessionCoroutineScope private val sessionCoroutineScope: CoroutineScope, @SessionCoroutineScope private val sessionCoroutineScope: CoroutineScope,
private val sessionVerificationService: SessionVerificationService, private val sessionVerificationService: SessionVerificationService,
) { ) {
private val resetHandleFlow: MutableStateFlow<AsyncData<IdentityResetHandle>> = MutableStateFlow(AsyncData.Uninitialized) private val resetHandleFlow: MutableStateFlow<AsyncData<IdentityResetHandle?>> = MutableStateFlow(AsyncData.Uninitialized)
val currentHandleFlow: StateFlow<AsyncData<IdentityResetHandle>> = resetHandleFlow val currentHandleFlow: StateFlow<AsyncData<IdentityResetHandle?>> = resetHandleFlow
private var whenResetIsDoneWaitingJob: Job? = null private var whenResetIsDoneWaitingJob: Job? = null
fun whenResetIsDone(block: () -> Unit) { fun whenResetIsDone(block: () -> Unit) {
@ -47,7 +47,7 @@ class ResetIdentityFlowManager @Inject constructor(
} }
} }
fun getResetHandle(): StateFlow<AsyncData<IdentityResetHandle>> { fun getResetHandle(): StateFlow<AsyncData<IdentityResetHandle?>> {
return if (resetHandleFlow.value.isLoading() || resetHandleFlow.value.isSuccess()) { return if (resetHandleFlow.value.isLoading() || resetHandleFlow.value.isSuccess()) {
resetHandleFlow resetHandleFlow
} else { } else {
@ -56,13 +56,11 @@ class ResetIdentityFlowManager @Inject constructor(
sessionCoroutineScope.launch { sessionCoroutineScope.launch {
matrixClient.encryptionService().startIdentityReset() matrixClient.encryptionService().startIdentityReset()
.onSuccess { handle -> .onSuccess { handle ->
resetHandleFlow.value = if (handle != null) { resetHandleFlow.value = AsyncData.Success(handle)
AsyncData.Success(handle) }
} else { .onFailure {
AsyncData.Failure(IllegalStateException("Could not get a reset identity handle")) resetHandleFlow.value = AsyncData.Failure(it)
}
} }
.onFailure { resetHandleFlow.value = AsyncData.Failure(it) }
} }
resetHandleFlow resetHandleFlow

View file

@ -140,6 +140,9 @@ class ResetIdentityFlowNode @AssistedInject constructor(
} }
is AsyncData.Success -> { is AsyncData.Success -> {
when (val handle = state.data) { when (val handle = state.data) {
null -> {
Timber.d("No reset handle return, the reset is done.")
}
is IdentityOidcResetHandle -> { is IdentityOidcResetHandle -> {
if (oidcEntryPoint.canUseCustomTab()) { if (oidcEntryPoint.canUseCustomTab()) {
activity.openUrlInChromeCustomTab(null, false, handle.url) activity.openUrlInChromeCustomTab(null, false, handle.url)

View file

@ -73,7 +73,9 @@ class ResetIdentityFlowManagerTest {
flowManager.getResetHandle().test { flowManager.getResetHandle().test {
assertThat(awaitItem().isLoading()).isTrue() assertThat(awaitItem().isLoading()).isTrue()
assertThat(awaitItem().isFailure()).isTrue() val finalItem = awaitItem()
assertThat(finalItem.isSuccess()).isTrue()
assertThat(finalItem.dataOrNull()).isNull()
startResetLambda.assertions().isCalledOnce() startResetLambda.assertions().isCalledOnce()
} }
} }

View file

@ -72,7 +72,7 @@ interface EncryptionService {
/** /**
* A handle to reset the user's identity. * 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. * Cancel the reset process and drops the existing handle in the SDK.
*/ */

View file

@ -17,6 +17,7 @@
package io.element.android.libraries.matrix.impl.encryption package io.element.android.libraries.matrix.impl.encryption
import io.element.android.libraries.core.coroutine.CoroutineDispatchers 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.core.extensions.mapFailure
import io.element.android.libraries.matrix.api.core.SessionId import io.element.android.libraries.matrix.api.core.SessionId
import io.element.android.libraries.matrix.api.encryption.BackupState import io.element.android.libraries.matrix.api.encryption.BackupState
@ -204,9 +205,9 @@ internal class RustEncryptionService(
override suspend fun startIdentityReset(): Result<IdentityResetHandle?> { override suspend fun startIdentityReset(): Result<IdentityResetHandle?> {
return runCatching { return runCatching {
service.resetIdentity()?.let { handle -> service.resetIdentity()
RustIdentityResetHandleFactory.create(sessionId, handle) }.flatMap { handle ->
}?.getOrNull() RustIdentityResetHandleFactory.create(sessionId, handle)
} }
} }
} }

View file

@ -27,13 +27,17 @@ import org.matrix.rustcomponents.sdk.CrossSigningResetAuthType
object RustIdentityResetHandleFactory { object RustIdentityResetHandleFactory {
fun create( fun create(
userId: UserId, userId: UserId,
identityResetHandle: org.matrix.rustcomponents.sdk.IdentityResetHandle identityResetHandle: org.matrix.rustcomponents.sdk.IdentityResetHandle?
): Result<IdentityResetHandle> { ): Result<IdentityResetHandle?> {
return runCatching { return runCatching {
when (val authType = identityResetHandle.authType()) { if (identityResetHandle == null) {
is CrossSigningResetAuthType.Oidc -> RustOidcIdentityResetHandle(identityResetHandle, authType.info.approvalUrl) null
// User interactive authentication (user + password) } else {
CrossSigningResetAuthType.Uiaa -> RustPasswordIdentityResetHandle(userId, identityResetHandle) when (val authType = identityResetHandle.authType()) {
is CrossSigningResetAuthType.Oidc -> RustOidcIdentityResetHandle(identityResetHandle, authType.info.approvalUrl)
// User interactive authentication (user + password)
CrossSigningResetAuthType.Uiaa -> RustPasswordIdentityResetHandle(userId, identityResetHandle)
}
} }
} }
} }