Prevent verification while initial sync is in progress (#1138)

* Prevent verification while initial sync is in progress

* Add `canVerifySessionFlow` to simplify the check
This commit is contained in:
Jorge Martin Espinosa 2023-08-24 13:43:36 +02:00 committed by GitHub
parent 9fb0216272
commit c670fc9e9c
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
8 changed files with 38 additions and 26 deletions

View file

@ -16,6 +16,7 @@
package io.element.android.libraries.matrix.api.verification
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.StateFlow
interface SessionVerificationService {
@ -37,6 +38,11 @@ interface SessionVerificationService {
*/
val sessionVerifiedStatus: StateFlow<SessionVerifiedStatus>
/**
* Returns whether the current session needs to be verified and the SDK is ready to start the verification.
*/
val canVerifySessionFlow: Flow<Boolean>
/**
* Request verification of the current session.
*/

View file

@ -35,7 +35,6 @@ import io.element.android.libraries.matrix.api.room.RoomMembershipObserver
import io.element.android.libraries.matrix.api.roomlist.RoomListService
import io.element.android.libraries.matrix.api.roomlist.awaitLoaded
import io.element.android.libraries.matrix.api.sync.SyncService
import io.element.android.libraries.matrix.api.sync.SyncState
import io.element.android.libraries.matrix.api.user.MatrixSearchUserResults
import io.element.android.libraries.matrix.api.user.MatrixUser
import io.element.android.libraries.matrix.api.verification.SessionVerificationService
@ -93,8 +92,8 @@ class RustMatrixClient constructor(
private val innerRoomListService = syncService.roomListService()
private val sessionDispatcher = dispatchers.io.limitedParallelism(64)
private val sessionCoroutineScope = appCoroutineScope.childScope(dispatchers.main, "Session-${sessionId}")
private val verificationService = RustSessionVerificationService()
private val rustSyncService = RustSyncService(syncService, sessionCoroutineScope)
private val verificationService = RustSessionVerificationService(rustSyncService)
private val pushersService = RustPushersService(
client = client,
dispatchers = dispatchers,
@ -149,13 +148,11 @@ class RustMatrixClient constructor(
init {
client.setDelegate(clientDelegate)
rustSyncService.syncState
.onEach { syncState ->
if (syncState == SyncState.Running) {
onSlidingSyncUpdate()
}
roomListService.state.onEach { state ->
if (state == RoomListService.State.Running) {
setupVerificationControllerIfNeeded()
}
.launchIn(sessionCoroutineScope)
}.launchIn(sessionCoroutineScope)
}
override suspend fun getRoom(roomId: RoomId): MatrixRoom? = withContext(sessionDispatcher) {
@ -338,8 +335,8 @@ class RustMatrixClient constructor(
}
}
private fun onSlidingSyncUpdate() {
if (!verificationService.isReady.value) {
private fun setupVerificationControllerIfNeeded() {
if (verificationService.verificationController == null) {
try {
verificationService.verificationController = client.getSessionVerificationController()
} catch (e: Throwable) {

View file

@ -17,20 +17,25 @@
package io.element.android.libraries.matrix.impl.verification
import io.element.android.libraries.core.data.tryOrNull
import io.element.android.libraries.matrix.api.sync.SyncState
import io.element.android.libraries.matrix.api.verification.SessionVerificationService
import io.element.android.libraries.matrix.api.verification.SessionVerifiedStatus
import io.element.android.libraries.matrix.api.verification.VerificationEmoji
import io.element.android.libraries.matrix.api.verification.VerificationFlowState
import io.element.android.libraries.matrix.impl.sync.RustSyncService
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.asStateFlow
import kotlinx.coroutines.flow.combine
import org.matrix.rustcomponents.sdk.SessionVerificationController
import org.matrix.rustcomponents.sdk.SessionVerificationControllerDelegate
import org.matrix.rustcomponents.sdk.SessionVerificationControllerInterface
import org.matrix.rustcomponents.sdk.SessionVerificationEmoji
import javax.inject.Inject
class RustSessionVerificationService @Inject constructor() : SessionVerificationService, SessionVerificationControllerDelegate {
class RustSessionVerificationService @Inject constructor(
private val syncService: RustSyncService,
) : SessionVerificationService, SessionVerificationControllerDelegate {
var verificationController: SessionVerificationControllerInterface? = null
set(value) {
@ -52,6 +57,10 @@ class RustSessionVerificationService @Inject constructor() : SessionVerification
private val _sessionVerifiedStatus = MutableStateFlow<SessionVerifiedStatus>(SessionVerifiedStatus.Unknown)
override val sessionVerifiedStatus: StateFlow<SessionVerifiedStatus> = _sessionVerifiedStatus.asStateFlow()
override val canVerifySessionFlow = combine(sessionVerifiedStatus, syncService.syncState) { verificationStatus, syncState ->
syncState == SyncState.Running && verificationStatus == SessionVerifiedStatus.NotVerified
}
override suspend fun requestVerification() = tryOrFail {
verificationController?.requestVerification()
}

View file

@ -20,6 +20,7 @@ import io.element.android.libraries.matrix.api.verification.SessionVerificationS
import io.element.android.libraries.matrix.api.verification.VerificationFlowState
import io.element.android.libraries.matrix.api.verification.SessionVerifiedStatus
import io.element.android.libraries.matrix.api.verification.VerificationEmoji
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.StateFlow
@ -27,13 +28,13 @@ class FakeSessionVerificationService : SessionVerificationService {
private val _isReady = MutableStateFlow(false)
private val _sessionVerifiedStatus = MutableStateFlow<SessionVerifiedStatus>(SessionVerifiedStatus.Unknown)
private var _verificationFlowState = MutableStateFlow<VerificationFlowState>(VerificationFlowState.Initial)
private var _canVerifySessionFlow = MutableStateFlow(true)
private var emojiList = emptyList<VerificationEmoji>()
var shouldFail = false
override val verificationFlowState: StateFlow<VerificationFlowState>
get() = _verificationFlowState
override val verificationFlowState: StateFlow<VerificationFlowState> =_verificationFlowState
override val sessionVerifiedStatus: StateFlow<SessionVerifiedStatus> = _sessionVerifiedStatus
override val canVerifySessionFlow: Flow<Boolean> = _canVerifySessionFlow
override val isReady: StateFlow<Boolean> = _isReady
@ -77,6 +78,10 @@ class FakeSessionVerificationService : SessionVerificationService {
_verificationFlowState.value = state
}
fun givenCanVerifySession(canVerify: Boolean) {
_canVerifySessionFlow.value = canVerify
}
fun givenIsReady(value: Boolean) {
_isReady.value = value
}