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,
private val sessionVerificationService: SessionVerificationService,
) {
private val resetHandleFlow: MutableStateFlow<AsyncData<IdentityResetHandle>> = MutableStateFlow(AsyncData.Uninitialized)
val currentHandleFlow: StateFlow<AsyncData<IdentityResetHandle>> = resetHandleFlow
private val resetHandleFlow: MutableStateFlow<AsyncData<IdentityResetHandle?>> = MutableStateFlow(AsyncData.Uninitialized)
val currentHandleFlow: StateFlow<AsyncData<IdentityResetHandle?>> = resetHandleFlow
private var whenResetIsDoneWaitingJob: Job? = null
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()) {
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

View File

@@ -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)

View File

@@ -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()
}
}

View File

@@ -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.
*/

View File

@@ -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<IdentityResetHandle?> {
return runCatching {
service.resetIdentity()?.let { handle ->
RustIdentityResetHandleFactory.create(sessionId, handle)
}?.getOrNull()
service.resetIdentity()
}.flatMap { handle ->
RustIdentityResetHandleFactory.create(sessionId, handle)
}
}
}

View File

@@ -27,13 +27,17 @@ import org.matrix.rustcomponents.sdk.CrossSigningResetAuthType
object RustIdentityResetHandleFactory {
fun create(
userId: UserId,
identityResetHandle: org.matrix.rustcomponents.sdk.IdentityResetHandle
): Result<IdentityResetHandle> {
identityResetHandle: org.matrix.rustcomponents.sdk.IdentityResetHandle?
): Result<IdentityResetHandle?> {
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)
}
}
}
}