rust sas state mapping

This commit is contained in:
valere 2022-11-29 11:22:21 +01:00
parent fb1995e9c9
commit f8d6511c59
8 changed files with 67 additions and 24 deletions

View file

@ -44,6 +44,7 @@ internal class VerificationListenersHolder @Inject constructor(
} }
fun dispatchTxUpdated(tx: VerificationTransaction) { fun dispatchTxUpdated(tx: VerificationTransaction) {
Timber.v("## SAS dispatchRequestAdded txId:${tx.transactionId} $tx")
scope.launch { scope.launch {
eventFlow.emit(VerificationEvent.TransactionUpdated(tx)) eventFlow.emit(VerificationEvent.TransactionUpdated(tx))
} }
@ -57,6 +58,7 @@ internal class VerificationListenersHolder @Inject constructor(
} }
fun dispatchRequestUpdated(verificationRequest: PendingVerificationRequest) { fun dispatchRequestUpdated(verificationRequest: PendingVerificationRequest) {
Timber.v("## SAS dispatchRequestUpdated txId:${verificationRequest.transactionId} $verificationRequest")
scope.launch { scope.launch {
eventFlow.emit(VerificationEvent.RequestUpdated(verificationRequest)) eventFlow.emit(VerificationEvent.RequestUpdated(verificationRequest))
} }

View file

@ -24,9 +24,9 @@ import org.matrix.android.sdk.api.session.crypto.verification.VerificationServic
import org.matrix.android.sdk.api.session.crypto.verification.VerificationTransaction import org.matrix.android.sdk.api.session.crypto.verification.VerificationTransaction
import org.matrix.android.sdk.api.session.events.model.Event import org.matrix.android.sdk.api.session.events.model.Event
import org.matrix.android.sdk.api.session.events.model.EventType import org.matrix.android.sdk.api.session.events.model.EventType
import org.matrix.android.sdk.api.session.events.model.getRelationContent
import org.matrix.android.sdk.api.session.events.model.toModel import org.matrix.android.sdk.api.session.events.model.toModel
import org.matrix.android.sdk.api.session.room.model.message.MessageContent import org.matrix.android.sdk.api.session.room.model.message.MessageContent
import org.matrix.android.sdk.api.session.room.model.message.MessageRelationContent
import org.matrix.android.sdk.api.session.room.model.message.MessageType import org.matrix.android.sdk.api.session.room.model.message.MessageType
import org.matrix.android.sdk.internal.crypto.OlmMachine import org.matrix.android.sdk.internal.crypto.OlmMachine
import org.matrix.android.sdk.internal.crypto.OwnUserIdentity import org.matrix.android.sdk.internal.crypto.OwnUserIdentity
@ -49,8 +49,7 @@ internal data class ToDeviceVerificationEvent(
/** Helper method to fetch the unique ID of the verification event */ /** Helper method to fetch the unique ID of the verification event */
private fun getFlowId(event: Event): String? { private fun getFlowId(event: Event): String? {
return if (event.eventId != null) { return if (event.eventId != null) {
val relatesTo = event.content.toModel<MessageRelationContent>()?.relatesTo event.getRelationContent()?.eventId
relatesTo?.eventId
} else { } else {
val content = event.getClearContent().toModel<ToDeviceVerificationEvent>() ?: return null val content = event.getClearContent().toModel<ToDeviceVerificationEvent>() ?: return null
content.transactionId content.transactionId
@ -124,30 +123,32 @@ internal class RustVerificationService @Inject constructor(
/** Check if the start event created new verification objects and dispatch updates */ /** Check if the start event created new verification objects and dispatch updates */
private suspend fun onStart(event: Event) { private suspend fun onStart(event: Event) {
Timber.w("VALR onStart $event")
val sender = event.senderId ?: return val sender = event.senderId ?: return
val flowId = getFlowId(event) ?: return val flowId = getFlowId(event) ?: return
val verification = getExistingTransaction(sender, flowId) ?: return val transaction = getExistingTransaction(sender, flowId) ?: return
val request = olmMachine.getVerificationRequest(sender, flowId) val request = olmMachine.getVerificationRequest(sender, flowId)
if (request != null && request.isReady()) { if (request != null && request.isReady()) {
// If this is a SAS verification originating from a `m.key.verification.request` // If this is a SAS verification originating from a `m.key.verification.request`
// event, we auto-accept here considering that we either initiated the request or // event, we auto-accept here considering that we either initiated the request or
// accepted the request. If it's a QR code verification, just dispatch an update. // accepted the request. If it's a QR code verification, just dispatch an update.
if (verification is SasVerification) { if (transaction is SasVerification) {
// accept() will dispatch an update, no need to do it twice. // accept() will dispatch an update, no need to do it twice.
Timber.d("## Verification: Auto accepting SAS verification with $sender") Timber.d("## Verification: Auto accepting SAS verification with $sender")
verification.accept() transaction.accept()
} else { } else {
verificationListenersHolder.dispatchTxUpdated(verification) verificationListenersHolder.dispatchTxUpdated(transaction)
} }
} else { } else {
// This didn't originate from a request, so tell our listeners that // This didn't originate from a request, so tell our listeners that
// this is a new verification. // this is a new verification.
verificationListenersHolder.dispatchTxAdded(verification) verificationListenersHolder.dispatchTxAdded(transaction)
// The IncomingVerificationRequestHandler seems to only listen to updates // The IncomingVerificationRequestHandler seems to only listen to updates
// so let's trigger an update after the addition as well. // so let's trigger an update after the addition as well.
verificationListenersHolder.dispatchTxUpdated(verification) verificationListenersHolder.dispatchTxUpdated(transaction)
} }
} }
@ -248,6 +249,7 @@ internal class RustVerificationService @Inject constructor(
null -> throw IllegalArgumentException("The user that we wish to verify doesn't support cross signing") null -> throw IllegalArgumentException("The user that we wish to verify doesn't support cross signing")
} }
Timber.w("##VALR requestKeyVerificationInDMs $verification")
return verification.toPendingVerificationRequest() return verification.toPendingVerificationRequest()
} }

View file

@ -81,7 +81,7 @@ internal class SasVerification @AssistedInject constructor(
SasTransactionState.SasShortCodeReady SasTransactionState.SasShortCodeReady
} }
SasState.Confirmed -> SasTransactionState.SasMacSent SasState.Confirmed -> SasTransactionState.SasMacSent
SasState.Done -> SasTransactionState.Done(false) SasState.Done -> SasTransactionState.Done(true)
is SasState.Cancelled -> SasTransactionState.Cancelled(safeValueOf(state.cancelInfo.cancelCode), state.cancelInfo.cancelledByUs) is SasState.Cancelled -> SasTransactionState.Cancelled(safeValueOf(state.cancelInfo.cancelCode), state.cancelInfo.cancelledByUs)
} }
// refreshData() // refreshData()
@ -220,6 +220,7 @@ internal class SasVerification @AssistedInject constructor(
try { try {
for (verificationRequest in result.requests) { for (verificationRequest in result.requests) {
sender.sendVerificationRequest(verificationRequest) sender.sendVerificationRequest(verificationRequest)
verificationListenersHolder.dispatchTxUpdated(this)
} }
val signatureRequest = result.signatureRequest val signatureRequest = result.signatureRequest
if (signatureRequest != null) { if (signatureRequest != null) {
@ -235,6 +236,7 @@ internal class SasVerification @AssistedInject constructor(
tryOrNull("Fail to send cancel request") { tryOrNull("Fail to send cancel request") {
sender.sendVerificationRequest(request, retryCount = Int.MAX_VALUE) sender.sendVerificationRequest(request, retryCount = Int.MAX_VALUE)
} }
verificationListenersHolder.dispatchTxUpdated(this@SasVerification)
} }
/** Fetch fresh data from the Rust side for our verification flow */ /** Fetch fresh data from the Rust side for our verification flow */
@ -252,7 +254,6 @@ internal class SasVerification @AssistedInject constructor(
override fun onChange(state: SasState) { override fun onChange(state: SasState) {
innerState = state innerState = state
verificationListenersHolder.dispatchTxUpdated(this)
} }
override fun toString(): String { override fun toString(): String {

View file

@ -40,6 +40,19 @@ import org.matrix.android.sdk.internal.util.time.Clock
import org.matrix.rustcomponents.sdk.crypto.QrCode import org.matrix.rustcomponents.sdk.crypto.QrCode
import org.matrix.rustcomponents.sdk.crypto.VerificationRequest as InnerVerificationRequest import org.matrix.rustcomponents.sdk.crypto.VerificationRequest as InnerVerificationRequest
fun InnerVerificationRequest.dbgString(): String {
val that = this
return buildString {
append("InnerVerificationRequest(")
append("isDone=${that.isDone()},")
append("isReady=${that.isReady()},")
append("isPassive=${that.isPassive()},")
append("weStarted=${that.weStarted()},")
append("isCancelled=${that.isCancelled()}")
append(")")
}
}
/** A verification request object /** A verification request object
* *
* This represents a verification flow that starts with a m.key.verification.request event * This represents a verification flow that starts with a m.key.verification.request event
@ -283,14 +296,36 @@ internal class VerificationRequest @AssistedInject constructor(
} }
private fun state(): EVerificationState { private fun state(): EVerificationState {
when { if (innerVerificationRequest.isCancelled()) {
innerVerificationRequest.weStarted() -> EVerificationState.WaitingForReady return EVerificationState.Cancelled
innerVerificationRequest.isDone() -> EVerificationState.Done }
innerVerificationRequest.isCancelled() -> EVerificationState.Cancelled if (innerVerificationRequest.isPassive()) {
innerVerificationRequest.isReady() -> EVerificationState.Ready return EVerificationState.HandledByOtherSession
innerVerificationRequest.isPassive() -> EVerificationState.HandledByOtherSession }
if (innerVerificationRequest.isDone()) {
return EVerificationState.Done
}
val started = innerOlmMachine.getVerification(otherUser(), flowId())
if (started != null) {
val asSas = started.asSas()
if (asSas != null) {
return if (asSas.weStarted()) {
EVerificationState.WeStarted
} else {
EVerificationState.Started
}
}
// TODO QR??
}
if (innerVerificationRequest.isReady()) {
return EVerificationState.Ready
}
return if (weStarted()) {
EVerificationState.WaitingForReady
} else {
EVerificationState.Requested
} }
return EVerificationState.Requested
} }
/** Convert the VerificationRequest into a PendingVerificationRequest /** Convert the VerificationRequest into a PendingVerificationRequest
@ -384,6 +419,10 @@ internal class VerificationRequest @AssistedInject constructor(
) )
} }
override fun toString(): String {
return super.toString() + "\n${innerVerificationRequest.dbgString()}"
}
private fun List<String>?.canSas() = orEmpty().contains(VERIFICATION_METHOD_SAS) private fun List<String>?.canSas() = orEmpty().contains(VERIFICATION_METHOD_SAS)
private fun List<String>?.canShowQR() = orEmpty().contains(VERIFICATION_METHOD_RECIPROCATE) && orEmpty().contains(VERIFICATION_METHOD_QR_CODE_SHOW) private fun List<String>?.canShowQR() = orEmpty().contains(VERIFICATION_METHOD_RECIPROCATE) && orEmpty().contains(VERIFICATION_METHOD_QR_CODE_SHOW)
private fun List<String>?.canScanQR() = orEmpty().contains(VERIFICATION_METHOD_RECIPROCATE) && orEmpty().contains(VERIFICATION_METHOD_QR_CODE_SCAN) private fun List<String>?.canScanQR() = orEmpty().contains(VERIFICATION_METHOD_RECIPROCATE) && orEmpty().contains(VERIFICATION_METHOD_QR_CODE_SCAN)

View file

@ -68,7 +68,7 @@ class SelfVerificationFragment : VectorBaseFragment<BottomSheetVerificationChil
} }
override fun invalidate() = withState(viewModel) { state -> override fun invalidate() = withState(viewModel) { state ->
Timber.w("VALR: invalidate with State: ${state.pendingRequest}") // Timber.w("VALR: invalidate with State: ${state.pendingRequest}")
controller.update(state) controller.update(state)
} }

View file

@ -39,7 +39,6 @@ import org.matrix.android.sdk.api.session.crypto.verification.CancelCode
import org.matrix.android.sdk.api.session.crypto.verification.EVerificationState import org.matrix.android.sdk.api.session.crypto.verification.EVerificationState
import org.matrix.android.sdk.api.session.crypto.verification.QRCodeVerificationState import org.matrix.android.sdk.api.session.crypto.verification.QRCodeVerificationState
import org.matrix.android.sdk.api.util.MatrixItem import org.matrix.android.sdk.api.util.MatrixItem
import timber.log.Timber
import javax.inject.Inject import javax.inject.Inject
abstract class BaseEpoxyVerificationController( abstract class BaseEpoxyVerificationController(
@ -78,7 +77,7 @@ class UserVerificationController @Inject constructor(
var state: UserVerificationViewState? = null var state: UserVerificationViewState? = null
fun update(state: UserVerificationViewState) { fun update(state: UserVerificationViewState) {
Timber.w("VALR controller updated $state") // Timber.w("VALR controller updated $state")
this.state = state this.state = state
requestModelBuild() requestModelBuild()
} }

View file

@ -68,7 +68,7 @@ class UserVerificationFragment : VectorBaseFragment<BottomSheetVerificationChild
} }
override fun invalidate() = withState(viewModel) { state -> override fun invalidate() = withState(viewModel) { state ->
Timber.w("VALR: invalidate with State: ${state.pendingRequest}") // Timber.w("VALR: invalidate with State: ${state.pendingRequest}")
controller.update(state) controller.update(state)
} }

View file

@ -158,7 +158,7 @@ class UserVerificationViewModel @AssistedInject constructor(
.onEach { .onEach {
Timber.w("VALR update event ${it.getRequest()} ") Timber.w("VALR update event ${it.getRequest()} ")
it.getRequest()?.let { it.getRequest()?.let {
Timber.w("VALR state updated request to $it") // Timber.w("VALR state updated request to $it")
setState { setState {
copy( copy(
pendingRequest = Success(it), pendingRequest = Success(it),
@ -231,7 +231,7 @@ class UserVerificationViewModel @AssistedInject constructor(
} }
} else { } else {
// This request is ok for us // This request is ok for us
Timber.w("VALR state updated request to $request") // Timber.w("VALR state updated request to $request")
setState { setState {
copy( copy(