crypto: Allow verification requests to be canelled

This commit is contained in:
Damir Jelić 2021-06-28 14:08:49 +02:00
parent 05119bcf90
commit 1f7311a428
3 changed files with 34 additions and 10 deletions

View file

@ -20,6 +20,7 @@ import android.os.Handler
import android.os.Looper import android.os.Looper
import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.withContext 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.PendingVerificationRequest
import org.matrix.android.sdk.api.session.crypto.verification.ValidVerificationInfoReady import org.matrix.android.sdk.api.session.crypto.verification.ValidVerificationInfoReady
import org.matrix.android.sdk.api.session.crypto.verification.ValidVerificationInfoRequest 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 { fun isCanceled(): Boolean {
refreshData() refreshData()
return this.inner.isCancelled return this.inner.isCancelled

View file

@ -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.RequestSender
import org.matrix.android.sdk.internal.crypto.SasVerification import org.matrix.android.sdk.internal.crypto.SasVerification
import org.matrix.android.sdk.internal.crypto.VerificationRequest 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.KeyVerificationDone
import org.matrix.android.sdk.internal.crypto.model.rest.KeyVerificationKey import org.matrix.android.sdk.internal.crypto.model.rest.KeyVerificationKey
import org.matrix.android.sdk.internal.crypto.model.rest.KeyVerificationRequest import org.matrix.android.sdk.internal.crypto.model.rest.KeyVerificationRequest
@ -106,8 +107,10 @@ constructor(
} }
fun onEvent(event: Event) = when (event.getClearType()) { 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_START -> onStart(event)
EventType.KEY_VERIFICATION_CANCEL -> {} EventType.KEY_VERIFICATION_CANCEL -> onCancel(event)
EventType.KEY_VERIFICATION_ACCEPT -> {} EventType.KEY_VERIFICATION_ACCEPT -> {}
EventType.KEY_VERIFICATION_KEY -> onKey(event) EventType.KEY_VERIFICATION_KEY -> onKey(event)
EventType.KEY_VERIFICATION_MAC -> {} EventType.KEY_VERIFICATION_MAC -> {}
@ -117,13 +120,24 @@ constructor(
else -> {} 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<KeyVerificationCancel>() ?: return
val flowId = content.transactionId ?: return
val sender = event.senderId ?: return
getAndDispatch(sender, flowId)
}
private fun onStart(event: Event) { private fun onStart(event: Event) {
val content = event.getClearContent().toModel<KeyVerificationStart>() ?: return val content = event.getClearContent().toModel<KeyVerificationStart>() ?: return
val flowId = content.transactionId ?: return val flowId = content.transactionId ?: return
val sender = event.senderId ?: return val sender = event.senderId ?: return
val verification = this.getExistingTransaction(sender, flowId) ?: return getAndDispatch(sender, flowId)
dispatchTxUpdated(verification)
} }
private fun onDone(event: Event) { private fun onDone(event: Event) {
@ -131,8 +145,7 @@ constructor(
val flowId = content.transactionId ?: return val flowId = content.transactionId ?: return
val sender = event.senderId ?: return val sender = event.senderId ?: return
val verification = this.getExistingTransaction(sender, flowId) ?: return getAndDispatch(sender, flowId)
dispatchTxUpdated(verification)
} }
private fun onKey(event: Event) { private fun onKey(event: Event) {
@ -140,8 +153,7 @@ constructor(
val flowId = content.transactionId ?: return val flowId = content.transactionId ?: return
val sender = event.senderId ?: return val sender = event.senderId ?: return
val verification = this.getExistingTransaction(sender, flowId) ?: return getAndDispatch(sender, flowId)
dispatchTxUpdated(verification)
} }
private fun onRequest(event: Event) { private fun onRequest(event: Event) {
@ -246,8 +258,8 @@ constructor(
} }
override fun cancelVerificationRequest(request: PendingVerificationRequest) { override fun cancelVerificationRequest(request: PendingVerificationRequest) {
// TODO get the request out of the olm machine and cancel here val verificationRequest = request.transactionId?.let { this.getVerificationRequest(request.otherUserId, it) }
TODO() runBlocking { verificationRequest?.cancel() }
} }
override fun declineVerificationRequestInDMs( override fun declineVerificationRequestInDMs(

View file

@ -797,7 +797,9 @@ impl OlmMachine {
) -> Option<OutgoingVerificationRequest> { ) -> Option<OutgoingVerificationRequest> {
let user_id = UserId::try_from(user_id).ok()?; 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 { match verification {
RustVerification::SasV1(v) => { RustVerification::SasV1(v) => {
v.cancel_with_code(cancel_code.into()).map(|r| r.into()) v.cancel_with_code(cancel_code.into()).map(|r| r.into())