From 1f7311a42802a603db62bf63cdcfccad6eda8711 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Damir=20Jeli=C4=87?= Date: Mon, 28 Jun 2021 14:08:49 +0200 Subject: [PATCH] crypto: Allow verification requests to be canelled --- .../internal/crypto/VerificationRequest.kt | 10 +++++++ .../verification/RustVerificationService.kt | 30 +++++++++++++------ rust-sdk/src/machine.rs | 4 ++- 3 files changed, 34 insertions(+), 10 deletions(-) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/VerificationRequest.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/VerificationRequest.kt index 24edebc085..79feb795f7 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/VerificationRequest.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/VerificationRequest.kt @@ -20,6 +20,7 @@ import android.os.Handler import android.os.Looper import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.withContext +import org.matrix.android.sdk.api.session.crypto.verification.CancelCode import org.matrix.android.sdk.api.session.crypto.verification.PendingVerificationRequest import org.matrix.android.sdk.api.session.crypto.verification.ValidVerificationInfoReady import org.matrix.android.sdk.api.session.crypto.verification.ValidVerificationInfoRequest @@ -108,6 +109,15 @@ internal class VerificationRequest( } } + suspend fun cancel() { + val request = this.machine.cancelVerification(this.inner.otherUserId, this.inner.flowId, CancelCode.User.value) + + if (request != null) { + this.sender.sendVerificationRequest(request) + this.dispatchRequestUpdated() + } + } + fun isCanceled(): Boolean { refreshData() return this.inner.isCancelled diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/verification/RustVerificationService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/verification/RustVerificationService.kt index 26d9fd1ef6..4ccafd3a99 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/verification/RustVerificationService.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/verification/RustVerificationService.kt @@ -33,6 +33,7 @@ import org.matrix.android.sdk.internal.crypto.QrCodeVerification import org.matrix.android.sdk.internal.crypto.RequestSender import org.matrix.android.sdk.internal.crypto.SasVerification import org.matrix.android.sdk.internal.crypto.VerificationRequest +import org.matrix.android.sdk.internal.crypto.model.rest.KeyVerificationCancel import org.matrix.android.sdk.internal.crypto.model.rest.KeyVerificationDone import org.matrix.android.sdk.internal.crypto.model.rest.KeyVerificationKey import org.matrix.android.sdk.internal.crypto.model.rest.KeyVerificationRequest @@ -106,8 +107,10 @@ constructor( } fun onEvent(event: Event) = when (event.getClearType()) { + // TODO most of those methods do the same, we just need to get the + // flow id and the sender from the event, can we add a generic method for this? EventType.KEY_VERIFICATION_START -> onStart(event) - EventType.KEY_VERIFICATION_CANCEL -> {} + EventType.KEY_VERIFICATION_CANCEL -> onCancel(event) EventType.KEY_VERIFICATION_ACCEPT -> {} EventType.KEY_VERIFICATION_KEY -> onKey(event) EventType.KEY_VERIFICATION_MAC -> {} @@ -117,13 +120,24 @@ constructor( else -> {} } + private fun getAndDispatch(sender: String, flowId: String) { + val verification = this.getExistingTransaction(sender, flowId) ?: return + dispatchTxUpdated(verification) + } + + private fun onCancel(event: Event) { + val content = event.getClearContent().toModel() ?: return + val flowId = content.transactionId ?: return + val sender = event.senderId ?: return + + getAndDispatch(sender, flowId) + } private fun onStart(event: Event) { val content = event.getClearContent().toModel() ?: return val flowId = content.transactionId ?: return val sender = event.senderId ?: return - val verification = this.getExistingTransaction(sender, flowId) ?: return - dispatchTxUpdated(verification) + getAndDispatch(sender, flowId) } private fun onDone(event: Event) { @@ -131,8 +145,7 @@ constructor( val flowId = content.transactionId ?: return val sender = event.senderId ?: return - val verification = this.getExistingTransaction(sender, flowId) ?: return - dispatchTxUpdated(verification) + getAndDispatch(sender, flowId) } private fun onKey(event: Event) { @@ -140,8 +153,7 @@ constructor( val flowId = content.transactionId ?: return val sender = event.senderId ?: return - val verification = this.getExistingTransaction(sender, flowId) ?: return - dispatchTxUpdated(verification) + getAndDispatch(sender, flowId) } private fun onRequest(event: Event) { @@ -246,8 +258,8 @@ constructor( } override fun cancelVerificationRequest(request: PendingVerificationRequest) { - // TODO get the request out of the olm machine and cancel here - TODO() + val verificationRequest = request.transactionId?.let { this.getVerificationRequest(request.otherUserId, it) } + runBlocking { verificationRequest?.cancel() } } override fun declineVerificationRequestInDMs( diff --git a/rust-sdk/src/machine.rs b/rust-sdk/src/machine.rs index bbce67d9a7..8affeeca3f 100644 --- a/rust-sdk/src/machine.rs +++ b/rust-sdk/src/machine.rs @@ -797,7 +797,9 @@ impl OlmMachine { ) -> Option { let user_id = UserId::try_from(user_id).ok()?; - if let Some(verification) = self.inner.get_verification(&user_id, flow_id) { + if let Some(request) = self.inner.get_verification_request(&user_id, flow_id) { + request.cancel().map(|r| r.into()) + } else if let Some(verification) = self.inner.get_verification(&user_id, flow_id) { match verification { RustVerification::SasV1(v) => { v.cancel_with_code(cancel_code.into()).map(|r| r.into())