diff --git a/CHANGES.md b/CHANGES.md index e05c52c835..e09aa3fed3 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -10,6 +10,7 @@ Improvements 🙌: Bugfix 🐛: - Fix crash by removing all notifications after clearing cache (#878) + - Fix issue with verification when other client declares it can only show QR code (#988) Translations 🗣: - diff --git a/matrix-sdk-android/src/androidTest/java/im/vector/matrix/android/internal/crypto/verification/SASTest.kt b/matrix-sdk-android/src/androidTest/java/im/vector/matrix/android/internal/crypto/verification/SASTest.kt index 6ae2489993..79670bb21e 100644 --- a/matrix-sdk-android/src/androidTest/java/im/vector/matrix/android/internal/crypto/verification/SASTest.kt +++ b/matrix-sdk-android/src/androidTest/java/im/vector/matrix/android/internal/crypto/verification/SASTest.kt @@ -66,14 +66,10 @@ class SASTest : InstrumentedTest { val bobVerificationService = bobSession!!.getVerificationService() val bobTxCreatedLatch = CountDownLatch(1) - val bobListener = object : VerificationService.VerificationListener { - override fun transactionCreated(tx: VerificationTransaction) {} - + val bobListener = object : VerificationService.Listener { override fun transactionUpdated(tx: VerificationTransaction) { bobTxCreatedLatch.countDown() } - - override fun markedAsManuallyVerified(userId: String, deviceId: String) {} } bobVerificationService.addListener(bobListener) @@ -106,9 +102,7 @@ class SASTest : InstrumentedTest { // Let's cancel from alice side val cancelLatch = CountDownLatch(1) - val bobListener2 = object : VerificationService.VerificationListener { - override fun transactionCreated(tx: VerificationTransaction) {} - + val bobListener2 = object : VerificationService.Listener { override fun transactionUpdated(tx: VerificationTransaction) { if (tx.transactionId == txID) { val immutableState = (tx as SASDefaultVerificationTransaction).state @@ -117,8 +111,6 @@ class SASTest : InstrumentedTest { } } } - - override fun markedAsManuallyVerified(userId: String, deviceId: String) {} } bobVerificationService.addListener(bobListener2) @@ -157,17 +149,13 @@ class SASTest : InstrumentedTest { var cancelReason: CancelCode? = null val cancelLatch = CountDownLatch(1) - val bobListener = object : VerificationService.VerificationListener { - override fun transactionCreated(tx: VerificationTransaction) {} - + val bobListener = object : VerificationService.Listener { override fun transactionUpdated(tx: VerificationTransaction) { if (tx.transactionId == tid && tx.state is VerificationTxState.Cancelled) { cancelReason = (tx.state as VerificationTxState.Cancelled).cancelCode cancelLatch.countDown() } } - - override fun markedAsManuallyVerified(userId: String, deviceId: String) {} } bobSession.getVerificationService().addListener(bobListener) @@ -186,16 +174,12 @@ class SASTest : InstrumentedTest { val aliceUserID = aliceSession.myUserId val aliceDevice = aliceSession.getMyDevice().deviceId - val aliceListener = object : VerificationService.VerificationListener { - override fun transactionCreated(tx: VerificationTransaction) {} - + val aliceListener = object : VerificationService.Listener { override fun transactionUpdated(tx: VerificationTransaction) { if ((tx as IncomingSasVerificationTransaction).uxState === IncomingSasVerificationTransaction.UxState.SHOW_ACCEPT) { (tx as IncomingSasVerificationTransaction).performAccept() } } - - override fun markedAsManuallyVerified(userId: String, deviceId: String) {} } aliceSession.getVerificationService().addListener(aliceListener) @@ -328,7 +312,7 @@ class SASTest : InstrumentedTest { val aliceCreatedLatch = CountDownLatch(2) val aliceCancelledLatch = CountDownLatch(2) val createdTx = mutableListOf() - val aliceListener = object : VerificationService.VerificationListener { + val aliceListener = object : VerificationService.Listener { override fun transactionCreated(tx: VerificationTransaction) { createdTx.add(tx as SASDefaultVerificationTransaction) aliceCreatedLatch.countDown() @@ -339,8 +323,6 @@ class SASTest : InstrumentedTest { aliceCancelledLatch.countDown() } } - - override fun markedAsManuallyVerified(userId: String, deviceId: String) {} } aliceVerificationService.addListener(aliceListener) @@ -372,11 +354,7 @@ class SASTest : InstrumentedTest { var startReq: KeyVerificationStart? = null val aliceAcceptedLatch = CountDownLatch(1) - val aliceListener = object : VerificationService.VerificationListener { - override fun markedAsManuallyVerified(userId: String, deviceId: String) {} - - override fun transactionCreated(tx: VerificationTransaction) {} - + val aliceListener = object : VerificationService.Listener { override fun transactionUpdated(tx: VerificationTransaction) { if ((tx as SASDefaultVerificationTransaction).state === VerificationTxState.OnAccepted) { val at = tx as SASDefaultVerificationTransaction @@ -388,17 +366,13 @@ class SASTest : InstrumentedTest { } aliceVerificationService.addListener(aliceListener) - val bobListener = object : VerificationService.VerificationListener { - override fun transactionCreated(tx: VerificationTransaction) {} - + val bobListener = object : VerificationService.Listener { override fun transactionUpdated(tx: VerificationTransaction) { if ((tx as IncomingSasVerificationTransaction).uxState === IncomingSasVerificationTransaction.UxState.SHOW_ACCEPT) { val at = tx as IncomingSasVerificationTransaction at.performAccept() } } - - override fun markedAsManuallyVerified(userId: String, deviceId: String) {} } bobVerificationService.addListener(bobListener) @@ -433,9 +407,7 @@ class SASTest : InstrumentedTest { val bobVerificationService = bobSession!!.getVerificationService() val aliceSASLatch = CountDownLatch(1) - val aliceListener = object : VerificationService.VerificationListener { - override fun transactionCreated(tx: VerificationTransaction) {} - + val aliceListener = object : VerificationService.Listener { override fun transactionUpdated(tx: VerificationTransaction) { val uxState = (tx as OutgoingSasVerificationTransaction).uxState when (uxState) { @@ -445,15 +417,11 @@ class SASTest : InstrumentedTest { else -> Unit } } - - override fun markedAsManuallyVerified(userId: String, deviceId: String) {} } aliceVerificationService.addListener(aliceListener) val bobSASLatch = CountDownLatch(1) - val bobListener = object : VerificationService.VerificationListener { - override fun transactionCreated(tx: VerificationTransaction) {} - + val bobListener = object : VerificationService.Listener { override fun transactionUpdated(tx: VerificationTransaction) { val uxState = (tx as IncomingSasVerificationTransaction).uxState when (uxState) { @@ -466,8 +434,6 @@ class SASTest : InstrumentedTest { bobSASLatch.countDown() } } - - override fun markedAsManuallyVerified(userId: String, deviceId: String) {} } bobVerificationService.addListener(bobListener) @@ -497,9 +463,7 @@ class SASTest : InstrumentedTest { val bobVerificationService = bobSession!!.getVerificationService() val aliceSASLatch = CountDownLatch(1) - val aliceListener = object : VerificationService.VerificationListener { - override fun transactionCreated(tx: VerificationTransaction) {} - + val aliceListener = object : VerificationService.Listener { override fun transactionUpdated(tx: VerificationTransaction) { val uxState = (tx as OutgoingSasVerificationTransaction).uxState when (uxState) { @@ -512,15 +476,11 @@ class SASTest : InstrumentedTest { else -> Unit } } - - override fun markedAsManuallyVerified(userId: String, deviceId: String) {} } aliceVerificationService.addListener(aliceListener) val bobSASLatch = CountDownLatch(1) - val bobListener = object : VerificationService.VerificationListener { - override fun transactionCreated(tx: VerificationTransaction) {} - + val bobListener = object : VerificationService.Listener { override fun transactionUpdated(tx: VerificationTransaction) { val uxState = (tx as IncomingSasVerificationTransaction).uxState when (uxState) { @@ -536,8 +496,6 @@ class SASTest : InstrumentedTest { else -> Unit } } - - override fun markedAsManuallyVerified(userId: String, deviceId: String) {} } bobVerificationService.addListener(bobListener) diff --git a/matrix-sdk-android/src/androidTest/java/im/vector/matrix/android/internal/crypto/verification/qrcode/VerificationTest.kt b/matrix-sdk-android/src/androidTest/java/im/vector/matrix/android/internal/crypto/verification/qrcode/VerificationTest.kt new file mode 100644 index 0000000000..61ea0f35b4 --- /dev/null +++ b/matrix-sdk-android/src/androidTest/java/im/vector/matrix/android/internal/crypto/verification/qrcode/VerificationTest.kt @@ -0,0 +1,232 @@ +/* + * Copyright (c) 2020 New Vector Ltd + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package im.vector.matrix.android.internal.crypto.verification.qrcode + +import androidx.test.ext.junit.runners.AndroidJUnit4 +import im.vector.matrix.android.InstrumentedTest +import im.vector.matrix.android.api.session.crypto.sas.VerificationMethod +import im.vector.matrix.android.api.session.crypto.sas.VerificationService +import im.vector.matrix.android.common.CommonTestHelper +import im.vector.matrix.android.common.CryptoTestHelper +import im.vector.matrix.android.common.TestConstants +import im.vector.matrix.android.internal.crypto.model.rest.UserPasswordAuth +import im.vector.matrix.android.internal.crypto.verification.PendingVerificationRequest +import org.amshove.kluent.shouldBe +import org.junit.FixMethodOrder +import org.junit.Test +import org.junit.runner.RunWith +import org.junit.runners.MethodSorters +import java.util.concurrent.CountDownLatch + +@RunWith(AndroidJUnit4::class) +@FixMethodOrder(MethodSorters.JVM) +class VerificationTest : InstrumentedTest { + private val mTestHelper = CommonTestHelper(context()) + private val mCryptoTestHelper = CryptoTestHelper(mTestHelper) + + data class ExpectedResult( + val sasIsSupported: Boolean = false, + val otherCanScanQrCode: Boolean = false, + val otherCanShowQrCode: Boolean = false + ) + + private val sas = listOf( + VerificationMethod.SAS + ) + + private val sasShow = listOf( + VerificationMethod.SAS, + VerificationMethod.QR_CODE_SHOW + ) + + private val sasScan = listOf( + VerificationMethod.SAS, + VerificationMethod.QR_CODE_SCAN + ) + + private val sasShowScan = listOf( + VerificationMethod.SAS, + VerificationMethod.QR_CODE_SHOW, + VerificationMethod.QR_CODE_SCAN + ) + + @Test + fun test_aliceAndBob_sas_sas() = doTest( + sas, + sas, + ExpectedResult(sasIsSupported = true), + ExpectedResult(sasIsSupported = true) + ) + + @Test + fun test_aliceAndBob_sas_show() = doTest( + sas, + sasShow, + ExpectedResult(sasIsSupported = true), + ExpectedResult(sasIsSupported = true) + ) + + @Test + fun test_aliceAndBob_show_sas() = doTest( + sasShow, + sas, + ExpectedResult(sasIsSupported = true), + ExpectedResult(sasIsSupported = true) + ) + + @Test + fun test_aliceAndBob_sas_scan() = doTest( + sas, + sasScan, + ExpectedResult(sasIsSupported = true), + ExpectedResult(sasIsSupported = true) + ) + + @Test + fun test_aliceAndBob_scan_sas() = doTest( + sasScan, + sas, + ExpectedResult(sasIsSupported = true), + ExpectedResult(sasIsSupported = true) + ) + + @Test + fun test_aliceAndBob_scan_scan() = doTest( + sasScan, + sasScan, + ExpectedResult(sasIsSupported = true), + ExpectedResult(sasIsSupported = true) + ) + + @Test + fun test_aliceAndBob_show_show() = doTest( + sasShow, + sasShow, + ExpectedResult(sasIsSupported = true), + ExpectedResult(sasIsSupported = true) + ) + + @Test + fun test_aliceAndBob_show_scan() = doTest( + sasShow, + sasScan, + ExpectedResult(sasIsSupported = true, otherCanScanQrCode = true), + ExpectedResult(sasIsSupported = true, otherCanShowQrCode = true) + ) + + @Test + fun test_aliceAndBob_scan_show() = doTest( + sasScan, + sasShow, + ExpectedResult(sasIsSupported = true, otherCanShowQrCode = true), + ExpectedResult(sasIsSupported = true, otherCanScanQrCode = true) + ) + + @Test + fun test_aliceAndBob_all_all() = doTest( + sasShowScan, + sasShowScan, + ExpectedResult(sasIsSupported = true, otherCanShowQrCode = true, otherCanScanQrCode = true), + ExpectedResult(sasIsSupported = true, otherCanShowQrCode = true, otherCanScanQrCode = true) + ) + + // TODO Add tests without SAS + + private fun doTest(aliceSupportedMethods: List, + bobSupportedMethods: List, + expectedResultForAlice: ExpectedResult, + expectedResultForBob: ExpectedResult) { + val cryptoTestData = mCryptoTestHelper.doE2ETestWithAliceAndBobInARoom() + + val aliceSession = cryptoTestData.firstSession + val bobSession = cryptoTestData.secondSession!! + + mTestHelper.doSync { callback -> + aliceSession.getCrossSigningService() + .initializeCrossSigning(UserPasswordAuth( + user = aliceSession.myUserId, + password = TestConstants.PASSWORD + ), callback) + } + + mTestHelper.doSync { callback -> + bobSession.getCrossSigningService() + .initializeCrossSigning(UserPasswordAuth( + user = bobSession.myUserId, + password = TestConstants.PASSWORD + ), callback) + } + + val aliceVerificationService = aliceSession.getVerificationService() + val bobVerificationService = bobSession.getVerificationService() + + var aliceReadyPendingVerificationRequest: PendingVerificationRequest? = null + var bobReadyPendingVerificationRequest: PendingVerificationRequest? = null + + val latch = CountDownLatch(2) + val aliceListener = object : VerificationService.Listener { + override fun verificationRequestUpdated(pr: PendingVerificationRequest) { + // Step 4: Alice receive the ready request + if (pr.isReady) { + aliceReadyPendingVerificationRequest = pr + latch.countDown() + } + } + } + aliceVerificationService.addListener(aliceListener) + + val bobListener = object : VerificationService.Listener { + override fun verificationRequestCreated(pr: PendingVerificationRequest) { + // Step 2: Bob accepts the verification request + bobVerificationService.readyPendingVerificationInDMs( + bobSupportedMethods, + aliceSession.myUserId, + cryptoTestData.roomId, + pr.transactionId!! + ) + } + + override fun verificationRequestUpdated(pr: PendingVerificationRequest) { + // Step 3: Bob is ready + if (pr.isReady) { + bobReadyPendingVerificationRequest = pr + latch.countDown() + } + } + } + bobVerificationService.addListener(bobListener) + + val bobUserId = bobSession.myUserId + // Step 1: Alice starts a verification request + aliceVerificationService.requestKeyVerificationInDMs(aliceSupportedMethods, bobUserId, cryptoTestData.roomId) + mTestHelper.await(latch) + + aliceReadyPendingVerificationRequest!!.let { pr -> + pr.isSasSupported() shouldBe expectedResultForAlice.sasIsSupported + pr.otherCanShowQrCode() shouldBe expectedResultForAlice.otherCanShowQrCode + pr.otherCanScanQrCode() shouldBe expectedResultForAlice.otherCanScanQrCode + } + + bobReadyPendingVerificationRequest!!.let { pr -> + pr.isSasSupported() shouldBe expectedResultForBob.sasIsSupported + pr.otherCanShowQrCode() shouldBe expectedResultForBob.otherCanShowQrCode + pr.otherCanScanQrCode() shouldBe expectedResultForBob.otherCanScanQrCode + } + + cryptoTestData.close() + } +} diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/crypto/sas/VerificationService.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/crypto/sas/VerificationService.kt index 0dd143f792..1b5f5d3dd6 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/crypto/sas/VerificationService.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/crypto/sas/VerificationService.kt @@ -30,9 +30,9 @@ import im.vector.matrix.android.internal.crypto.verification.PendingVerification */ interface VerificationService { - fun addListener(listener: VerificationListener) + fun addListener(listener: Listener) - fun removeListener(listener: VerificationListener) + fun removeListener(listener: Listener) /** * Mark this device as verified manually @@ -68,11 +68,11 @@ interface VerificationService { otherDevices: List?): PendingVerificationRequest fun declineVerificationRequestInDMs(otherUserId: String, - otherDeviceId: String, transactionId: String, roomId: String) // Only SAS method is supported for the moment + // TODO Parameter otherDeviceId should be removed in this case fun beginKeyVerificationInDMs(method: VerificationMethod, transactionId: String, roomId: String, @@ -95,15 +95,33 @@ interface VerificationService { otherUserId: String, transactionId: String): Boolean - // fun transactionUpdated(tx: SasVerificationTransaction) - - interface VerificationListener { - fun transactionCreated(tx: VerificationTransaction) - fun transactionUpdated(tx: VerificationTransaction) - fun markedAsManuallyVerified(userId: String, deviceId: String) {} - + interface Listener { + /** + * Called when a verification request is created either by the user, or by the other user. + */ fun verificationRequestCreated(pr: PendingVerificationRequest) {} + + /** + * Called when a verification request is updated. + */ fun verificationRequestUpdated(pr: PendingVerificationRequest) {} + + /** + * Called when a transaction is created, either by the user or initiated by the other user. + */ + fun transactionCreated(tx: VerificationTransaction) {} + + /** + * Called when a transaction is updated. You may be interested to track the state of the VerificationTransaction. + */ + fun transactionUpdated(tx: VerificationTransaction) {} + + /** + * Inform the the deviceId of the userId has been marked as manually verified by the SDK. + * It will be called after VerificationService.markedLocallyAsManuallyVerified() is called. + * + */ + fun markedAsManuallyVerified(userId: String, deviceId: String) {} } companion object { diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/verification/DefaultVerificationService.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/verification/DefaultVerificationService.kt index fc14b0a23a..00ac4a6986 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/verification/DefaultVerificationService.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/verification/DefaultVerificationService.kt @@ -176,9 +176,9 @@ internal class DefaultVerificationService @Inject constructor( } } - private var listeners = ArrayList() + private var listeners = ArrayList() - override fun addListener(listener: VerificationService.VerificationListener) { + override fun addListener(listener: VerificationService.Listener) { uiHandler.post { if (!listeners.contains(listener)) { listeners.add(listener) @@ -186,7 +186,7 @@ internal class DefaultVerificationService @Inject constructor( } } - override fun removeListener(listener: VerificationService.VerificationListener) { + override fun removeListener(listener: VerificationService.Listener) { uiHandler.post { listeners.remove(listener) } @@ -1151,9 +1151,9 @@ internal class DefaultVerificationService @Inject constructor( return verificationRequest } - override fun declineVerificationRequestInDMs(otherUserId: String, otherDeviceId: String, transactionId: String, roomId: String) { + override fun declineVerificationRequestInDMs(otherUserId: String, transactionId: String, roomId: String) { verificationTransportRoomMessageFactory.createTransport(roomId, null) - .cancelTransaction(transactionId, otherUserId, otherDeviceId, CancelCode.User) + .cancelTransaction(transactionId, otherUserId, null, CancelCode.User) getExistingVerificationRequest(otherUserId, transactionId)?.let { updatePendingRequest(it.copy( diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/verification/PendingVerificationRequest.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/verification/PendingVerificationRequest.kt index 3379ddd2ed..fe5f9dadb9 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/verification/PendingVerificationRequest.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/verification/PendingVerificationRequest.kt @@ -15,8 +15,8 @@ */ package im.vector.matrix.android.internal.crypto.verification +import im.vector.matrix.android.api.extensions.orFalse import im.vector.matrix.android.api.session.crypto.sas.CancelCode -import im.vector.matrix.android.api.session.crypto.sas.VerificationMethod import im.vector.matrix.android.internal.crypto.model.rest.VERIFICATION_METHOD_QR_CODE_SCAN import im.vector.matrix.android.internal.crypto.model.rest.VERIFICATION_METHOD_QR_CODE_SHOW import im.vector.matrix.android.internal.crypto.model.rest.VERIFICATION_METHOD_SAS @@ -46,11 +46,37 @@ data class PendingVerificationRequest( val isFinished: Boolean = isSuccessful || cancelConclusion != null - fun hasMethod(method: VerificationMethod): Boolean? { - return when (method) { - VerificationMethod.SAS -> readyInfo?.methods?.contains(VERIFICATION_METHOD_SAS) - VerificationMethod.QR_CODE_SHOW -> readyInfo?.methods?.contains(VERIFICATION_METHOD_QR_CODE_SHOW) - VerificationMethod.QR_CODE_SCAN -> readyInfo?.methods?.contains(VERIFICATION_METHOD_QR_CODE_SCAN) + /** + * SAS is supported if I support it and the other party support it + */ + fun isSasSupported(): Boolean { + return requestInfo?.methods?.contains(VERIFICATION_METHOD_SAS).orFalse() + && readyInfo?.methods?.contains(VERIFICATION_METHOD_SAS).orFalse() + } + + /** + * Other can show QR code if I can scan QR code and other can show QR code + */ + fun otherCanShowQrCode(): Boolean { + return if (isIncoming) { + requestInfo?.methods?.contains(VERIFICATION_METHOD_QR_CODE_SHOW).orFalse() + && readyInfo?.methods?.contains(VERIFICATION_METHOD_QR_CODE_SCAN).orFalse() + } else { + requestInfo?.methods?.contains(VERIFICATION_METHOD_QR_CODE_SCAN).orFalse() + && readyInfo?.methods?.contains(VERIFICATION_METHOD_QR_CODE_SHOW).orFalse() + } + } + + /** + * Other can scan QR code if I can show QR code and other can scan QR code + */ + fun otherCanScanQrCode(): Boolean { + return if (isIncoming) { + requestInfo?.methods?.contains(VERIFICATION_METHOD_QR_CODE_SCAN).orFalse() + && readyInfo?.methods?.contains(VERIFICATION_METHOD_QR_CODE_SHOW).orFalse() + } else { + requestInfo?.methods?.contains(VERIFICATION_METHOD_QR_CODE_SHOW).orFalse() + && readyInfo?.methods?.contains(VERIFICATION_METHOD_QR_CODE_SCAN).orFalse() } } } diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/verification/VerificationTransport.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/verification/VerificationTransport.kt index bc85cddf26..ee0e66959d 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/verification/VerificationTransport.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/verification/VerificationTransport.kt @@ -42,7 +42,7 @@ internal interface VerificationTransport { fun cancelTransaction(transactionId: String, otherUserId: String, - otherUserDeviceId: String, + otherUserDeviceId: String?, code: CancelCode) fun done(transactionId: String) @@ -79,11 +79,13 @@ internal interface VerificationTransport { fun createMac(tid: String, mac: Map, keys: String): VerificationInfoMac - fun createReady(tid: String, fromDevice: String, methods: List): VerificationInfoReady + fun createReady(tid: String, + fromDevice: String, + methods: List): VerificationInfoReady // TODO Refactor fun sendVerificationReady(keyReq: VerificationInfoReady, otherUserId: String, - otherDeviceId: String, + otherDeviceId: String?, callback: (() -> Unit)?) } diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/verification/VerificationTransportRoomMessage.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/verification/VerificationTransportRoomMessage.kt index 30d94c52d9..11093ca3ba 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/verification/VerificationTransportRoomMessage.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/verification/VerificationTransportRoomMessage.kt @@ -208,7 +208,7 @@ internal class VerificationTransportRoomMessage( } } - override fun cancelTransaction(transactionId: String, otherUserId: String, otherUserDeviceId: String, code: CancelCode) { + override fun cancelTransaction(transactionId: String, otherUserId: String, otherUserDeviceId: String?, code: CancelCode) { Timber.d("## SAS canceling transaction $transactionId for reason $code") val event = createEventAndLocalEcho( type = EventType.KEY_VERIFICATION_CANCEL, @@ -337,7 +337,7 @@ internal class VerificationTransportRoomMessage( override fun sendVerificationReady(keyReq: VerificationInfoReady, otherUserId: String, - otherDeviceId: String, + otherDeviceId: String?, callback: (() -> Unit)?) { // Not applicable (send event is called directly) Timber.w("## SAS ignored verification ready with methods: ${keyReq.methods}") diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/verification/VerificationTransportToDevice.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/verification/VerificationTransportToDevice.kt index f76f8331bc..1dae8fba68 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/verification/VerificationTransportToDevice.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/verification/VerificationTransportToDevice.kt @@ -80,7 +80,7 @@ internal class VerificationTransportToDevice( override fun sendVerificationReady(keyReq: VerificationInfoReady, otherUserId: String, - otherDeviceId: String, + otherDeviceId: String?, callback: (() -> Unit)?) { Timber.d("## SAS sending verification ready with methods: ${keyReq.methods}") val contentMap = MXUsersDevicesMap() @@ -159,7 +159,7 @@ internal class VerificationTransportToDevice( .executeBy(taskExecutor) } - override fun cancelTransaction(transactionId: String, otherUserId: String, otherUserDeviceId: String, code: CancelCode) { + override fun cancelTransaction(transactionId: String, otherUserId: String, otherUserDeviceId: String?, code: CancelCode) { Timber.d("## SAS canceling transaction $transactionId for reason $code") val cancelMessage = KeyVerificationCancel.create(transactionId, code) val contentMap = MXUsersDevicesMap() diff --git a/vector/src/main/java/im/vector/riotx/features/crypto/keysrequest/KeyRequestHandler.kt b/vector/src/main/java/im/vector/riotx/features/crypto/keysrequest/KeyRequestHandler.kt index 856c71f888..f890aef91b 100644 --- a/vector/src/main/java/im/vector/riotx/features/crypto/keysrequest/KeyRequestHandler.kt +++ b/vector/src/main/java/im/vector/riotx/features/crypto/keysrequest/KeyRequestHandler.kt @@ -56,7 +56,7 @@ import kotlin.collections.HashMap @Singleton class KeyRequestHandler @Inject constructor(private val context: Context) : RoomKeysRequestListener, - VerificationService.VerificationListener { + VerificationService.Listener { private val alertsToRequests = HashMap>() @@ -262,9 +262,6 @@ class KeyRequestHandler @Inject constructor(private val context: Context) } } - override fun transactionCreated(tx: VerificationTransaction) { - } - override fun transactionUpdated(tx: VerificationTransaction) { if (tx is SasVerificationTransaction) { val state = tx.state diff --git a/vector/src/main/java/im/vector/riotx/features/crypto/verification/IncomingVerificationRequestHandler.kt b/vector/src/main/java/im/vector/riotx/features/crypto/verification/IncomingVerificationRequestHandler.kt index 0fbbccee8a..8765dbc0d9 100644 --- a/vector/src/main/java/im/vector/riotx/features/crypto/verification/IncomingVerificationRequestHandler.kt +++ b/vector/src/main/java/im/vector/riotx/features/crypto/verification/IncomingVerificationRequestHandler.kt @@ -34,7 +34,7 @@ import javax.inject.Singleton * Listens to the VerificationManager and add a new notification when an incoming request is detected. */ @Singleton -class IncomingVerificationRequestHandler @Inject constructor(private val context: Context) : VerificationService.VerificationListener { +class IncomingVerificationRequestHandler @Inject constructor(private val context: Context) : VerificationService.Listener { private var session: Session? = null @@ -48,8 +48,6 @@ class IncomingVerificationRequestHandler @Inject constructor(private val context this.session = null } - override fun transactionCreated(tx: VerificationTransaction) {} - override fun transactionUpdated(tx: VerificationTransaction) { if (!tx.isToDeviceTransport()) return // TODO maybe check also if @@ -111,9 +109,6 @@ class IncomingVerificationRequestHandler @Inject constructor(private val context } } - override fun markedAsManuallyVerified(userId: String, deviceId: String) { - } - override fun verificationRequestCreated(pr: PendingVerificationRequest) { // For incoming request we should prompt (if not in activity where this request apply) if (pr.isIncoming) { @@ -145,7 +140,6 @@ class IncomingVerificationRequestHandler @Inject constructor(private val context } dismissedAction = Runnable { session?.getVerificationService()?.declineVerificationRequestInDMs(pr.otherUserId, - pr.requestInfo?.fromDevice ?: "", pr.transactionId ?: "", pr.roomId ?: "" ) @@ -163,7 +157,6 @@ class IncomingVerificationRequestHandler @Inject constructor(private val context if (pr.isIncoming && (pr.isReady || pr.handledByOtherSession)) { PopupAlertManager.cancelAlert(uniqueIdForVerificationRequest(pr)) } - super.verificationRequestUpdated(pr) } private fun uniqueIdForVerificationRequest(pr: PendingVerificationRequest) = diff --git a/vector/src/main/java/im/vector/riotx/features/crypto/verification/VerificationBottomSheetViewModel.kt b/vector/src/main/java/im/vector/riotx/features/crypto/verification/VerificationBottomSheetViewModel.kt index a9f9987c7f..85b878fe16 100644 --- a/vector/src/main/java/im/vector/riotx/features/crypto/verification/VerificationBottomSheetViewModel.kt +++ b/vector/src/main/java/im/vector/riotx/features/crypto/verification/VerificationBottomSheetViewModel.kt @@ -60,7 +60,7 @@ class VerificationBottomSheetViewModel @AssistedInject constructor(@Assisted ini @Assisted args: VerificationBottomSheet.VerificationArgs, private val session: Session) : VectorViewModel(initialState), - VerificationService.VerificationListener { + VerificationService.Listener { init { session.getVerificationService().addListener(this) diff --git a/vector/src/main/java/im/vector/riotx/features/crypto/verification/choose/VerificationChooseMethodViewModel.kt b/vector/src/main/java/im/vector/riotx/features/crypto/verification/choose/VerificationChooseMethodViewModel.kt index 75c1b69058..bdb07ed0dc 100644 --- a/vector/src/main/java/im/vector/riotx/features/crypto/verification/choose/VerificationChooseMethodViewModel.kt +++ b/vector/src/main/java/im/vector/riotx/features/crypto/verification/choose/VerificationChooseMethodViewModel.kt @@ -21,9 +21,9 @@ import com.airbnb.mvrx.MvRxViewModelFactory import com.airbnb.mvrx.ViewModelContext import com.squareup.inject.assisted.Assisted import com.squareup.inject.assisted.AssistedInject +import im.vector.matrix.android.api.extensions.orFalse import im.vector.matrix.android.api.session.Session import im.vector.matrix.android.api.session.crypto.sas.QrCodeVerificationTransaction -import im.vector.matrix.android.api.session.crypto.sas.VerificationMethod import im.vector.matrix.android.api.session.crypto.sas.VerificationService import im.vector.matrix.android.api.session.crypto.sas.VerificationTransaction import im.vector.matrix.android.internal.crypto.verification.PendingVerificationRequest @@ -45,7 +45,7 @@ data class VerificationChooseMethodViewState( class VerificationChooseMethodViewModel @AssistedInject constructor( @Assisted initialState: VerificationChooseMethodViewState, private val session: Session -) : VectorViewModel(initialState), VerificationService.VerificationListener { +) : VectorViewModel(initialState), VerificationService.Listener { override fun transactionCreated(tx: VerificationTransaction) { transactionUpdated(tx) @@ -66,9 +66,9 @@ class VerificationChooseMethodViewModel @AssistedInject constructor( setState { copy( - otherCanShowQrCode = pvr?.hasMethod(VerificationMethod.QR_CODE_SHOW) ?: false, - otherCanScanQrCode = pvr?.hasMethod(VerificationMethod.QR_CODE_SCAN) ?: false, - SASModeAvailable = pvr?.hasMethod(VerificationMethod.SAS) ?: false + otherCanShowQrCode = pvr?.otherCanShowQrCode().orFalse(), + otherCanScanQrCode = pvr?.otherCanScanQrCode().orFalse(), + SASModeAvailable = pvr?.isSasSupported().orFalse() ) } } @@ -103,10 +103,10 @@ class VerificationChooseMethodViewModel @AssistedInject constructor( return VerificationChooseMethodViewState(otherUserId = args.otherUserId, transactionId = args.verificationId ?: "", - otherCanShowQrCode = pvr?.hasMethod(VerificationMethod.QR_CODE_SHOW) ?: false, - otherCanScanQrCode = pvr?.hasMethod(VerificationMethod.QR_CODE_SCAN) ?: false, + otherCanShowQrCode = pvr?.otherCanShowQrCode().orFalse(), + otherCanScanQrCode = pvr?.otherCanScanQrCode().orFalse(), qrCodeText = (qrCodeVerificationTransaction as? QrCodeVerificationTransaction)?.qrCodeText, - SASModeAvailable = pvr?.hasMethod(VerificationMethod.SAS) ?: false + SASModeAvailable = pvr?.isSasSupported().orFalse() ) } } diff --git a/vector/src/main/java/im/vector/riotx/features/crypto/verification/emoji/VerificationEmojiCodeViewModel.kt b/vector/src/main/java/im/vector/riotx/features/crypto/verification/emoji/VerificationEmojiCodeViewModel.kt index 69d106a4b4..637b7d7cc9 100644 --- a/vector/src/main/java/im/vector/riotx/features/crypto/verification/emoji/VerificationEmojiCodeViewModel.kt +++ b/vector/src/main/java/im/vector/riotx/features/crypto/verification/emoji/VerificationEmojiCodeViewModel.kt @@ -52,7 +52,7 @@ data class VerificationEmojiCodeViewState( class VerificationEmojiCodeViewModel @AssistedInject constructor( @Assisted initialState: VerificationEmojiCodeViewState, private val session: Session -) : VectorViewModel(initialState), VerificationService.VerificationListener { +) : VectorViewModel(initialState), VerificationService.Listener { init { withState { state -> diff --git a/vector/src/main/java/im/vector/riotx/features/home/room/detail/RoomDetailAction.kt b/vector/src/main/java/im/vector/riotx/features/home/room/detail/RoomDetailAction.kt index eff34ed764..3061c5c9e2 100644 --- a/vector/src/main/java/im/vector/riotx/features/home/room/detail/RoomDetailAction.kt +++ b/vector/src/main/java/im/vector/riotx/features/home/room/detail/RoomDetailAction.kt @@ -67,8 +67,8 @@ sealed class RoomDetailAction : VectorViewModelAction { object ClearSendQueue : RoomDetailAction() object ResendAll : RoomDetailAction() - data class AcceptVerificationRequest(val transactionId: String, val otherUserId: String, val otherdDeviceId: String) : RoomDetailAction() - data class DeclineVerificationRequest(val transactionId: String, val otherUserId: String, val otherdDeviceId: String) : RoomDetailAction() + data class AcceptVerificationRequest(val transactionId: String, val otherUserId: String) : RoomDetailAction() + data class DeclineVerificationRequest(val transactionId: String, val otherUserId: String) : RoomDetailAction() data class RequestVerification(val userId: String) : RoomDetailAction() - data class ResumeVerification(val transactionId: String, val otherUserId: String? = null, val otherdDeviceId: String? = null) : RoomDetailAction() + data class ResumeVerification(val transactionId: String, val otherUserId: String?) : RoomDetailAction() } diff --git a/vector/src/main/java/im/vector/riotx/features/home/room/detail/RoomDetailFragment.kt b/vector/src/main/java/im/vector/riotx/features/home/room/detail/RoomDetailFragment.kt index 2fa2243060..5cb3024712 100644 --- a/vector/src/main/java/im/vector/riotx/features/home/room/detail/RoomDetailFragment.kt +++ b/vector/src/main/java/im/vector/riotx/features/home/room/detail/RoomDetailFragment.kt @@ -1028,7 +1028,7 @@ class RoomDetailFragment @Inject constructor( override fun onEventCellClicked(informationData: MessageInformationData, messageContent: MessageContent?, view: View) { if (messageContent is MessageVerificationRequestContent) { - roomDetailViewModel.handle(RoomDetailAction.ResumeVerification(informationData.eventId)) + roomDetailViewModel.handle(RoomDetailAction.ResumeVerification(informationData.eventId, null)) } } diff --git a/vector/src/main/java/im/vector/riotx/features/home/room/detail/RoomDetailViewModel.kt b/vector/src/main/java/im/vector/riotx/features/home/room/detail/RoomDetailViewModel.kt index e5f4576cd1..2ca372707f 100644 --- a/vector/src/main/java/im/vector/riotx/features/home/room/detail/RoomDetailViewModel.kt +++ b/vector/src/main/java/im/vector/riotx/features/home/room/detail/RoomDetailViewModel.kt @@ -840,7 +840,6 @@ class RoomDetailViewModel @AssistedInject constructor(@Assisted initialState: Ro private fun handleDeclineVerification(action: RoomDetailAction.DeclineVerificationRequest) { session.getVerificationService().declineVerificationRequestInDMs( action.otherUserId, - action.otherdDeviceId, action.transactionId, room.roomId) } diff --git a/vector/src/main/java/im/vector/riotx/features/home/room/detail/timeline/factory/MessageItemFactory.kt b/vector/src/main/java/im/vector/riotx/features/home/room/detail/timeline/factory/MessageItemFactory.kt index ef4f66fe5d..83f0c63147 100644 --- a/vector/src/main/java/im/vector/riotx/features/home/room/detail/timeline/factory/MessageItemFactory.kt +++ b/vector/src/main/java/im/vector/riotx/features/home/room/detail/timeline/factory/MessageItemFactory.kt @@ -219,7 +219,6 @@ class MessageItemFactory @Inject constructor( VerificationRequestItem.Attributes( otherUserId = otherUserId, otherUserName = otherUserName.toString(), - fromDevide = messageContent.fromDevice ?: "", referenceId = informationData.eventId, informationData = informationData, avatarRenderer = attributes.avatarRenderer, diff --git a/vector/src/main/java/im/vector/riotx/features/home/room/detail/timeline/item/VerificationRequestItem.kt b/vector/src/main/java/im/vector/riotx/features/home/room/detail/timeline/item/VerificationRequestItem.kt index 24f992a001..853e40c516 100644 --- a/vector/src/main/java/im/vector/riotx/features/home/room/detail/timeline/item/VerificationRequestItem.kt +++ b/vector/src/main/java/im/vector/riotx/features/home/room/detail/timeline/item/VerificationRequestItem.kt @@ -134,12 +134,9 @@ abstract class VerificationRequestItem : AbsBaseMessageItem(initialState), VerificationService.VerificationListener { + : VectorViewModel(initialState), VerificationService.Listener { @AssistedInject.Factory interface Factory { @@ -89,7 +89,6 @@ class DevicesViewModel @AssistedInject constructor(@Assisted initialState: Devic super.onCleared() } - override fun transactionCreated(tx: VerificationTransaction) {} override fun transactionUpdated(tx: VerificationTransaction) { if (tx.state == VerificationTxState.Verified) { refreshDevicesList()