From 87c1d69e2673b3485c9c791145771c36ac8f4ebb Mon Sep 17 00:00:00 2001 From: ganfra Date: Thu, 9 Jun 2022 10:56:41 +0200 Subject: [PATCH] Cancel verification flow if request sending fails (after retry) --- .../android/sdk/internal/crypto/Device.kt | 22 +++++++---- .../crypto/verification/SasVerification.kt | 31 ++++++++------- .../verification/VerificationRequest.kt | 39 +++++++++++-------- .../verification/qrcode/QrCodeVerification.kt | 22 ++++++----- 4 files changed, 68 insertions(+), 46 deletions(-) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/Device.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/Device.kt index dbd7903056..42c2d58240 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/Device.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/Device.kt @@ -24,6 +24,7 @@ import org.matrix.android.sdk.api.MatrixCoroutineDispatchers import org.matrix.android.sdk.api.session.crypto.crosssigning.DeviceTrustLevel import org.matrix.android.sdk.api.session.crypto.model.CryptoDeviceInfo import org.matrix.android.sdk.api.session.crypto.model.UnsignedDeviceInfo +import org.matrix.android.sdk.api.session.crypto.verification.CancelCode import org.matrix.android.sdk.api.session.crypto.verification.VerificationMethod import org.matrix.android.sdk.internal.crypto.network.RequestSender import org.matrix.android.sdk.internal.crypto.verification.SasVerification @@ -83,8 +84,13 @@ internal class Device @AssistedInject constructor( innerMachine.requestVerificationWithDevice(innerDevice.userId, innerDevice.deviceId, stringMethods) } return if (result != null) { - requestSender.sendVerificationRequest(result.request) - verificationRequestFactory.create(result.verification) + try { + requestSender.sendVerificationRequest(result.request) + verificationRequestFactory.create(result.verification) + } catch (failure: Throwable) { + innerMachine.cancelVerification(result.verification.otherUserId, result.verification.flowId, CancelCode.UserError.value) + null + } } else { null } @@ -104,10 +110,14 @@ internal class Device @AssistedInject constructor( val result = withContext(coroutineDispatchers.io) { innerMachine.startSasWithDevice(innerDevice.userId, innerDevice.deviceId) } - return if (result != null) { - requestSender.sendVerificationRequest(result.request) - sasVerificationFactory.create(result.sas) + try { + requestSender.sendVerificationRequest(result.request) + sasVerificationFactory.create(result.sas) + }catch (failure: Throwable){ + innerMachine.cancelVerification(result.sas.otherUserId, result.sas.flowId, CancelCode.UserError.value) + null + } } else { null } @@ -140,9 +150,7 @@ internal class Device @AssistedInject constructor( val request = withContext(coroutineDispatchers.io) { innerMachine.verifyDevice(innerDevice.userId, innerDevice.deviceId) } - requestSender.sendSignatureUpload(request) - return true } diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/verification/SasVerification.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/verification/SasVerification.kt index d3113f5d57..07c4c77201 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/verification/SasVerification.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/verification/SasVerification.kt @@ -19,8 +19,10 @@ package org.matrix.android.sdk.internal.crypto.verification import dagger.assisted.Assisted import dagger.assisted.AssistedFactory import dagger.assisted.AssistedInject +import kotlinx.coroutines.NonCancellable import kotlinx.coroutines.withContext import org.matrix.android.sdk.api.MatrixCoroutineDispatchers +import org.matrix.android.sdk.api.extensions.tryOrNull import org.matrix.android.sdk.api.session.crypto.verification.CancelCode import org.matrix.android.sdk.api.session.crypto.verification.EmojiRepresentation import org.matrix.android.sdk.api.session.crypto.verification.SasVerificationTransaction @@ -193,11 +195,12 @@ internal class SasVerification @AssistedInject constructor( } internal suspend fun accept() { - val request = innerMachine.acceptSasVerification(inner.otherUserId, inner.flowId) - - if (request != null) { + val request = innerMachine.acceptSasVerification(inner.otherUserId, inner.flowId) ?: return + dispatchTxUpdated() + try { sender.sendVerificationRequest(request) - dispatchTxUpdated() + } catch (failure: Throwable) { + cancelHelper(CancelCode.UserError) } } @@ -205,8 +208,10 @@ internal class SasVerification @AssistedInject constructor( private suspend fun confirm() { val result = withContext(coroutineDispatchers.io) { innerMachine.confirmVerification(inner.otherUserId, inner.flowId) - } - if (result != null) { + } ?: return + + dispatchTxUpdated() + try { for (verificationRequest in result.requests) { sender.sendVerificationRequest(verificationRequest) } @@ -214,16 +219,16 @@ internal class SasVerification @AssistedInject constructor( if (signatureRequest != null) { sender.sendSignatureUpload(signatureRequest) } - dispatchTxUpdated() + } catch (failure: Throwable) { + cancelHelper(CancelCode.UserError) } } - private suspend fun cancelHelper(code: CancelCode) { - val request = innerMachine.cancelVerification(inner.otherUserId, inner.flowId, code.value) - - if (request != null) { - sender.sendVerificationRequest(request) - dispatchTxUpdated() + private suspend fun cancelHelper(code: CancelCode) = withContext(NonCancellable) { + val request = innerMachine.cancelVerification(inner.otherUserId, inner.flowId, code.value) ?: return@withContext + dispatchTxUpdated() + tryOrNull("Fail to send cancel request") { + sender.sendVerificationRequest(request, retryCount = Int.MAX_VALUE) } } diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/verification/VerificationRequest.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/verification/VerificationRequest.kt index 6fb5f1287c..996c6fdee0 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/verification/VerificationRequest.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/verification/VerificationRequest.kt @@ -19,8 +19,10 @@ package org.matrix.android.sdk.internal.crypto.verification import dagger.assisted.Assisted import dagger.assisted.AssistedFactory import dagger.assisted.AssistedInject +import kotlinx.coroutines.NonCancellable import kotlinx.coroutines.withContext import org.matrix.android.sdk.api.MatrixCoroutineDispatchers +import org.matrix.android.sdk.api.extensions.tryOrNull 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 @@ -140,11 +142,13 @@ internal class VerificationRequest @AssistedInject constructor( innerVerificationRequest.otherUserId, innerVerificationRequest.flowId, stringMethods - ) + ) ?: return - if (request != null) { - requestSender.sendVerificationRequest(request) + try { dispatchRequestUpdated() + requestSender.sendVerificationRequest(request) + } catch (failure: Throwable) { + cancel(CancelCode.UserError) } } @@ -163,12 +167,12 @@ internal class VerificationRequest @AssistedInject constructor( */ internal suspend fun startSasVerification(): SasVerification? { return withContext(coroutineDispatchers.io) { - val result = innerOlmMachine.startSasVerification(innerVerificationRequest.otherUserId, innerVerificationRequest.flowId) - - if (result != null) { + val result = innerOlmMachine.startSasVerification(innerVerificationRequest.otherUserId, innerVerificationRequest.flowId) ?: return@withContext null + try { requestSender.sendVerificationRequest(result.request) sasVerificationFactory.create(result.sas) - } else { + } catch (failure: Throwable) { + cancel(CancelCode.UserError) null } } @@ -192,8 +196,12 @@ internal class VerificationRequest @AssistedInject constructor( val byteArray = data.toByteArray(Charsets.ISO_8859_1) val encodedData = byteArray.toBase64NoPadding() val result = innerOlmMachine.scanQrCode(otherUser(), flowId(), encodedData) ?: return null - - requestSender.sendVerificationRequest(result.request) + try { + requestSender.sendVerificationRequest(result.request) + } catch (failure: Throwable) { + cancel(CancelCode.UserError) + return null + } return qrCodeVerificationFactory.create(this, result.qr) } @@ -233,16 +241,15 @@ internal class VerificationRequest @AssistedInject constructor( * * The method turns into a noop, if the verification flow has already been cancelled. */ - internal suspend fun cancel() { + internal suspend fun cancel(cancelCode: CancelCode = CancelCode.User) = withContext(NonCancellable) { val request = innerOlmMachine.cancelVerification( innerVerificationRequest.otherUserId, innerVerificationRequest.flowId, - CancelCode.User.value - ) - - if (request != null) { - requestSender.sendVerificationRequest(request) - dispatchRequestUpdated() + cancelCode.value + ) ?: return@withContext + dispatchRequestUpdated() + tryOrNull("Fail to send cancel request") { + requestSender.sendVerificationRequest(request, retryCount = Int.MAX_VALUE) } } diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/verification/qrcode/QrCodeVerification.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/verification/qrcode/QrCodeVerification.kt index 912172e60a..d96ed74d93 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/verification/qrcode/QrCodeVerification.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/verification/qrcode/QrCodeVerification.kt @@ -19,8 +19,10 @@ package org.matrix.android.sdk.internal.crypto.verification.qrcode import dagger.assisted.Assisted import dagger.assisted.AssistedFactory import dagger.assisted.AssistedInject +import kotlinx.coroutines.NonCancellable import kotlinx.coroutines.withContext import org.matrix.android.sdk.api.MatrixCoroutineDispatchers +import org.matrix.android.sdk.api.extensions.tryOrNull import org.matrix.android.sdk.api.session.crypto.verification.CancelCode import org.matrix.android.sdk.api.session.crypto.verification.QrCodeVerificationTransaction import org.matrix.android.sdk.api.session.crypto.verification.VerificationTxState @@ -184,9 +186,9 @@ internal class QrCodeVerification @AssistedInject constructor( private suspend fun confirm() { val result = withContext(coroutineDispatchers.io) { innerMachine.confirmVerification(request.otherUser(), request.flowId()) - } - - if (result != null) { + } ?: return + dispatchTxUpdated() + try { for (verificationRequest in result.requests) { sender.sendVerificationRequest(verificationRequest) } @@ -194,16 +196,16 @@ internal class QrCodeVerification @AssistedInject constructor( if (signatureRequest != null) { sender.sendSignatureUpload(signatureRequest) } - dispatchTxUpdated() + } catch (failure: Throwable) { + cancelHelper(CancelCode.UserError) } } - private suspend fun cancelHelper(code: CancelCode) { - val request = innerMachine.cancelVerification(request.otherUser(), request.flowId(), code.value) - - if (request != null) { - sender.sendVerificationRequest(request) - dispatchTxUpdated() + private suspend fun cancelHelper(code: CancelCode) = withContext(NonCancellable) { + val request = innerMachine.cancelVerification(request.otherUser(), request.flowId(), code.value) ?: return@withContext + dispatchTxUpdated() + tryOrNull("Fail to send cancel verification request") { + sender.sendVerificationRequest(request, retryCount = Int.MAX_VALUE) } }