mirror of
https://github.com/element-hq/element-android
synced 2024-11-27 11:59:12 +03:00
rust sas state mapping
This commit is contained in:
parent
fb1995e9c9
commit
f8d6511c59
8 changed files with 67 additions and 24 deletions
|
@ -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))
|
||||||
}
|
}
|
||||||
|
|
|
@ -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()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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 {
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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()
|
||||||
}
|
}
|
||||||
|
|
|
@ -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)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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(
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue