mirror of
https://github.com/SchildiChat/SchildiChat-android.git
synced 2024-12-09 08:06:05 +01:00
Continue cleaning up/adding suspend
This commit is contained in:
parent
69ede523b6
commit
b4bc56ff5c
@ -125,9 +125,9 @@ class FlowSession(private val session: Session) {
|
||||
}
|
||||
|
||||
fun liveUserCryptoDevices(userId: String): Flow<List<CryptoDeviceInfo>> {
|
||||
return session.cryptoService().getLiveCryptoDeviceInfo(userId)
|
||||
return session.cryptoService().getLiveCryptoDeviceInfoList(userId)
|
||||
.startWith(session.coroutineDispatchers.io) {
|
||||
session.cryptoService().getCryptoDeviceInfo(userId)
|
||||
session.cryptoService().getCryptoDeviceInfoList(userId)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -301,12 +301,10 @@ class CryptoTestHelper(private val testHelper: CommonTestHelper) {
|
||||
val bobVerificationService = bob.cryptoService().verificationService()
|
||||
|
||||
runBlocking {
|
||||
aliceVerificationService.beginKeyVerificationInDMs(
|
||||
aliceVerificationService.beginKeyVerification(
|
||||
VerificationMethod.SAS,
|
||||
requestID,
|
||||
roomId,
|
||||
bob.myUserId,
|
||||
bob.sessionParams.credentials.deviceId!!)
|
||||
bob.myUserId, )
|
||||
}
|
||||
|
||||
// we should reach SHOW SAS on both
|
||||
|
@ -145,7 +145,7 @@ class UnwedgingTest : InstrumentedTest {
|
||||
// Let us pickle our session with bob here so we can later unpickle it
|
||||
// and wedge our session.
|
||||
var myDevice = testHelper.runBlockingTest {
|
||||
bobSession.cryptoService().getMyDevice()
|
||||
bobSession.cryptoService().getMyCryptoDevice()
|
||||
}
|
||||
val sessionIdsForBob = aliceCryptoStore.getDeviceSessionIds(myDevice.identityKey()!!)
|
||||
sessionIdsForBob!!.size shouldBe 1
|
||||
@ -178,7 +178,7 @@ class UnwedgingTest : InstrumentedTest {
|
||||
Timber.i("## CRYPTO | testUnwedging: wedge the session now. Set crypto state like after the first message")
|
||||
|
||||
myDevice = testHelper.runBlockingTest {
|
||||
bobSession.cryptoService().getMyDevice()
|
||||
bobSession.cryptoService().getMyCryptoDevice()
|
||||
}
|
||||
aliceCryptoStore.storeSession(OlmSessionWrapper(deserializeFromRealm<OlmSession>(oldSession)!!), myDevice.identityKey()!!)
|
||||
Thread.sleep(6_000)
|
||||
|
@ -203,7 +203,7 @@ class XSigningTest : InstrumentedTest {
|
||||
}
|
||||
|
||||
val bobSecondDevicePOVFirstDevice = runBlocking {
|
||||
bobSession.cryptoService().getDeviceInfo(bobUserId, bobSecondDeviceId)
|
||||
bobSession.cryptoService().getCryptoDeviceInfo(bobUserId, bobSecondDeviceId)
|
||||
}
|
||||
assertNotNull("Bob Second device should be known and persisted from first", bobSecondDevicePOVFirstDevice)
|
||||
|
||||
|
@ -50,7 +50,6 @@ import org.matrix.android.sdk.common.SessionTestParams
|
||||
import org.matrix.android.sdk.common.TestConstants
|
||||
import org.matrix.android.sdk.internal.crypto.GossipingRequestState
|
||||
import org.matrix.android.sdk.internal.crypto.OutgoingGossipingRequestState
|
||||
import org.matrix.android.sdk.internal.crypto.crosssigning.DeviceTrustLevel
|
||||
import org.matrix.android.sdk.internal.crypto.model.event.EncryptedEventContent
|
||||
import kotlin.coroutines.Continuation
|
||||
import kotlin.coroutines.resume
|
||||
@ -158,8 +157,9 @@ class KeyShareTests : InstrumentedTest {
|
||||
}
|
||||
|
||||
// Mark the device as trusted
|
||||
aliceSession.cryptoService().setDeviceVerification(DeviceTrustLevel(crossSigningVerified = false, locallyVerified = true), aliceSession.myUserId,
|
||||
aliceSession2.sessionParams.deviceId ?: "")
|
||||
commonTestHelper.runBlockingTest {
|
||||
aliceSession.cryptoService().verificationService().markedLocallyAsManuallyVerified(aliceSession.myUserId, aliceSession2.sessionParams.deviceId ?: "")
|
||||
}
|
||||
|
||||
// Re request
|
||||
aliceSession2.cryptoService().reRequestRoomKeyForEvent(receivedEvent.root)
|
||||
@ -280,13 +280,12 @@ class KeyShareTests : InstrumentedTest {
|
||||
|
||||
val txId = "m.testVerif12"
|
||||
commonTestHelper.runBlockingTest {
|
||||
aliceVerificationService2.beginKeyVerification(VerificationMethod.SAS, aliceSession1.myUserId, aliceSession1.sessionParams.deviceId
|
||||
?: "", txId)
|
||||
aliceVerificationService2.beginKeyVerification(VerificationMethod.SAS, aliceSession1.myUserId, txId)
|
||||
}
|
||||
|
||||
commonTestHelper.waitWithLatch { latch ->
|
||||
commonTestHelper.retryPeriodicallyWithLatch(latch) {
|
||||
aliceSession1.cryptoService().getDeviceInfo(aliceSession1.myUserId, aliceSession2.sessionParams.deviceId ?: "")?.isVerified == true
|
||||
aliceSession1.cryptoService().getCryptoDeviceInfo(aliceSession1.myUserId, aliceSession2.sessionParams.deviceId ?: "")?.isVerified == true
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -39,7 +39,6 @@ import org.matrix.android.sdk.common.CommonTestHelper
|
||||
import org.matrix.android.sdk.common.CryptoTestHelper
|
||||
import org.matrix.android.sdk.common.TestConstants
|
||||
import org.matrix.android.sdk.internal.crypto.MXCRYPTO_ALGORITHM_MEGOLM_BACKUP
|
||||
import org.matrix.android.sdk.internal.crypto.crosssigning.DeviceTrustLevel
|
||||
import org.matrix.android.sdk.internal.crypto.model.ImportRoomKeysResult
|
||||
import java.util.concurrent.CountDownLatch
|
||||
|
||||
@ -840,7 +839,7 @@ class KeysBackupTest : InstrumentedTest {
|
||||
|
||||
val signature = keysBackupVersionTrust.signatures[0]
|
||||
val device = runBlocking {
|
||||
cryptoTestData.firstSession.cryptoService().getMyDevice()
|
||||
cryptoTestData.firstSession.cryptoService().getMyCryptoDevice()
|
||||
}
|
||||
assertTrue(signature.valid)
|
||||
assertNotNull(signature.device)
|
||||
@ -1065,7 +1064,9 @@ class KeysBackupTest : InstrumentedTest {
|
||||
assertFalse(keysBackup2.isEnabled)
|
||||
|
||||
// - Validate the old device from the new one
|
||||
aliceSession2.cryptoService().setDeviceVerification(DeviceTrustLevel(crossSigningVerified = false, locallyVerified = true), aliceSession2.myUserId, oldDeviceId)
|
||||
testHelper.runBlockingTest {
|
||||
aliceSession2.cryptoService().verificationService().markedLocallyAsManuallyVerified(aliceSession2.myUserId, oldDeviceId)
|
||||
}
|
||||
|
||||
// -> Backup should automatically enable on the new device
|
||||
val latch4 = CountDownLatch(1)
|
||||
|
@ -22,7 +22,6 @@ import kotlinx.coroutines.runBlocking
|
||||
import org.junit.Assert.assertEquals
|
||||
import org.junit.Assert.assertFalse
|
||||
import org.junit.Assert.assertNotNull
|
||||
import org.junit.Assert.assertNull
|
||||
import org.junit.Assert.assertTrue
|
||||
import org.junit.Assert.fail
|
||||
import org.junit.FixMethodOrder
|
||||
@ -49,7 +48,6 @@ import org.matrix.android.sdk.internal.crypto.model.rest.KeyVerificationCancel
|
||||
import org.matrix.android.sdk.internal.crypto.model.rest.KeyVerificationStart
|
||||
import org.matrix.android.sdk.internal.crypto.model.rest.toValue
|
||||
import timber.log.Timber
|
||||
import java.util.UUID
|
||||
import java.util.concurrent.CountDownLatch
|
||||
|
||||
@RunWith(AndroidJUnit4::class)
|
||||
@ -76,14 +74,12 @@ class SASTest : InstrumentedTest {
|
||||
}
|
||||
bobVerificationService.addListener(bobListener)
|
||||
|
||||
val myDevice = testHelper.runBlockingTest {
|
||||
bobSession.cryptoService().getMyDevice()
|
||||
val bobDevice = testHelper.runBlockingTest {
|
||||
bobSession.cryptoService().getMyCryptoDevice()
|
||||
}
|
||||
val txID = testHelper.runBlockingTest {
|
||||
aliceVerificationService.beginKeyVerification(VerificationMethod.SAS,
|
||||
bobSession.myUserId,
|
||||
myDevice.deviceId,
|
||||
null)
|
||||
aliceSession.cryptoService().downloadKeys(listOf(bobSession.myUserId), forceDownload = true)
|
||||
aliceVerificationService.beginDeviceVerification(bobSession.myUserId, bobDevice.deviceId)
|
||||
}
|
||||
assertNotNull("Alice should have a started transaction", txID)
|
||||
|
||||
@ -102,7 +98,7 @@ class SASTest : InstrumentedTest {
|
||||
assertEquals("Alice and Bob have same transaction id", aliceKeyTx!!.transactionId, bobKeyTx!!.transactionId)
|
||||
|
||||
|
||||
assertEquals("Alice state should be started", VerificationTxState.Started, aliceKeyTx.state)
|
||||
assertEquals("Alice state should be started", VerificationTxState.OnStarted, aliceKeyTx.state)
|
||||
assertEquals("Bob state should be started by alice", VerificationTxState.OnStarted, bobKeyTx.state)
|
||||
|
||||
// Let's cancel from alice side
|
||||
@ -137,9 +133,6 @@ class SASTest : InstrumentedTest {
|
||||
assertEquals("Should be User cancelled on alice side", CancelCode.User, aliceCancelState.cancelCode)
|
||||
assertEquals("Should be User cancelled on bob side", CancelCode.User, bobCancelState.cancelCode)
|
||||
|
||||
assertNull(bobVerificationService.getExistingTransaction(aliceSession.myUserId, txID))
|
||||
assertNull(aliceVerificationService.getExistingTransaction(bobSession.myUserId, txID))
|
||||
|
||||
cryptoTestData.cleanUp(testHelper)
|
||||
}
|
||||
|
||||
@ -184,7 +177,7 @@ class SASTest : InstrumentedTest {
|
||||
val aliceSession = cryptoTestData.firstSession
|
||||
val aliceUserID = aliceSession.myUserId
|
||||
val aliceDevice = testHelper.runBlockingTest {
|
||||
aliceSession.cryptoService().getMyDevice().deviceId
|
||||
aliceSession.cryptoService().getMyCryptoDevice().deviceId
|
||||
}
|
||||
|
||||
val aliceListener = object : VerificationService.Listener {
|
||||
@ -237,7 +230,7 @@ class SASTest : InstrumentedTest {
|
||||
val aliceSession = cryptoTestData.firstSession
|
||||
val aliceUserID = aliceSession.myUserId
|
||||
val aliceDevice = testHelper.runBlockingTest {
|
||||
aliceSession.cryptoService().getMyDevice().deviceId
|
||||
aliceSession.cryptoService().getMyCryptoDevice().deviceId
|
||||
}
|
||||
|
||||
fakeBobStart(bobSession, aliceUserID, aliceDevice, tid, mac = mac)
|
||||
@ -280,7 +273,7 @@ class SASTest : InstrumentedTest {
|
||||
val aliceSession = cryptoTestData.firstSession
|
||||
val aliceUserID = aliceSession.myUserId
|
||||
val aliceDevice = testHelper.runBlockingTest {
|
||||
aliceSession.cryptoService().getMyDevice().deviceId
|
||||
aliceSession.cryptoService().getMyCryptoDevice().deviceId
|
||||
}
|
||||
|
||||
fakeBobStart(bobSession, aliceUserID, aliceDevice, tid, codes = codes)
|
||||
@ -302,7 +295,7 @@ class SASTest : InstrumentedTest {
|
||||
mac: List<String> = emptyList(),
|
||||
codes: List<String> = emptyList()) {
|
||||
val deviceId = runBlocking {
|
||||
bobSession.cryptoService().getMyDevice().deviceId
|
||||
bobSession.cryptoService().getMyCryptoDevice().deviceId
|
||||
}
|
||||
val startMessage = KeyVerificationStart(
|
||||
fromDevice = deviceId,
|
||||
@ -340,7 +333,7 @@ class SASTest : InstrumentedTest {
|
||||
val aliceVerificationService = aliceSession.cryptoService().verificationService()
|
||||
|
||||
val aliceCreatedLatch = CountDownLatch(2)
|
||||
val aliceCancelledLatch = CountDownLatch(2)
|
||||
val aliceCancelledLatch = CountDownLatch(1)
|
||||
val createdTx = mutableListOf<VerificationTransaction>()
|
||||
val aliceListener = object : VerificationService.Listener {
|
||||
override fun transactionCreated(tx: VerificationTransaction) {
|
||||
@ -358,11 +351,12 @@ class SASTest : InstrumentedTest {
|
||||
|
||||
val bobUserId = bobSession!!.myUserId
|
||||
val bobDeviceId = testHelper.runBlockingTest {
|
||||
bobSession.cryptoService().getMyDevice().deviceId
|
||||
bobSession.cryptoService().getMyCryptoDevice().deviceId
|
||||
}
|
||||
testHelper.runBlockingTest {
|
||||
aliceVerificationService.beginKeyVerification(VerificationMethod.SAS, bobUserId, bobDeviceId, null)
|
||||
aliceVerificationService.beginKeyVerification(VerificationMethod.SAS, bobUserId, bobDeviceId, null)
|
||||
aliceSession.cryptoService().downloadKeys(listOf(bobUserId), forceDownload = true)
|
||||
aliceVerificationService.beginDeviceVerification(bobUserId, bobDeviceId)
|
||||
aliceVerificationService.beginDeviceVerification(bobUserId, bobDeviceId)
|
||||
}
|
||||
testHelper.await(aliceCreatedLatch)
|
||||
testHelper.await(aliceCancelledLatch)
|
||||
@ -410,10 +404,10 @@ class SASTest : InstrumentedTest {
|
||||
|
||||
val bobUserId = bobSession.myUserId
|
||||
val bobDeviceId = runBlocking {
|
||||
bobSession.cryptoService().getMyDevice().deviceId
|
||||
bobSession.cryptoService().getMyCryptoDevice().deviceId
|
||||
}
|
||||
testHelper.runBlockingTest {
|
||||
aliceVerificationService.beginKeyVerification(VerificationMethod.SAS, bobUserId, bobDeviceId, null)
|
||||
//aliceVerificationService.beginKeyVerification(VerificationMethod.SAS, bobUserId, bobDeviceId, null)
|
||||
}
|
||||
testHelper.await(aliceAcceptedLatch)
|
||||
|
||||
@ -422,71 +416,40 @@ class SASTest : InstrumentedTest {
|
||||
|
||||
@Test
|
||||
fun test_aliceAndBobSASCode() {
|
||||
val supportedMethods = listOf(VerificationMethod.SAS)
|
||||
val testHelper = CommonTestHelper(context())
|
||||
val cryptoTestHelper = CryptoTestHelper(testHelper)
|
||||
val cryptoTestData = cryptoTestHelper.doE2ETestWithAliceAndBobInARoom()
|
||||
|
||||
val sasTestHelper = SasVerificationTestHelper(testHelper, cryptoTestHelper)
|
||||
val aliceSession = cryptoTestData.firstSession
|
||||
val bobSession = cryptoTestData.secondSession!!
|
||||
val transactionId = sasTestHelper.requestVerificationAndWaitForReadyState(cryptoTestData, supportedMethods)
|
||||
|
||||
cryptoTestHelper.initializeCrossSigning(aliceSession)
|
||||
cryptoTestHelper.initializeCrossSigning(bobSession)
|
||||
|
||||
val aliceVerificationService = aliceSession.cryptoService().verificationService()
|
||||
val bobVerificationService = bobSession.cryptoService().verificationService()
|
||||
|
||||
val aliceSASLatch = CountDownLatch(1)
|
||||
val latch = CountDownLatch(2)
|
||||
val aliceListener = object : VerificationService.Listener {
|
||||
override fun transactionUpdated(tx: VerificationTransaction) {
|
||||
when (tx.state) {
|
||||
VerificationTxState.ShortCodeReady -> {
|
||||
aliceSASLatch.countDown()
|
||||
}
|
||||
else -> Unit
|
||||
}
|
||||
Timber.v("Alice transactionUpdated: ${tx.state}")
|
||||
latch.countDown()
|
||||
}
|
||||
}
|
||||
aliceVerificationService.addListener(aliceListener)
|
||||
|
||||
val bobSASLatch = CountDownLatch(1)
|
||||
}
|
||||
aliceSession.cryptoService().verificationService().addListener(aliceListener)
|
||||
val bobListener = object : VerificationService.Listener {
|
||||
|
||||
override fun verificationRequestCreated(pr: PendingVerificationRequest) {
|
||||
|
||||
}
|
||||
|
||||
override fun transactionUpdated(tx: VerificationTransaction) {
|
||||
val sasVerification = tx as SasVerificationTransaction
|
||||
when (tx.state) {
|
||||
VerificationTxState.OnStarted -> testHelper.runBlockingTest {
|
||||
sasVerification.acceptVerification()
|
||||
}
|
||||
VerificationTxState.ShortCodeReady -> {
|
||||
bobSASLatch.countDown()
|
||||
}
|
||||
else -> Unit
|
||||
}
|
||||
Timber.v("Bob transactionUpdated: ${tx.state}")
|
||||
latch.countDown()
|
||||
}
|
||||
}
|
||||
bobVerificationService.addListener(bobListener)
|
||||
|
||||
val bobUserId = bobSession.myUserId
|
||||
bobSession.cryptoService().verificationService().addListener(bobListener)
|
||||
testHelper.runBlockingTest {
|
||||
aliceSession.cryptoService().downloadKeys(listOf(bobUserId), forceDownload = true)
|
||||
aliceVerificationService.requestKeyVerificationInDMs(listOf(VerificationMethod.SAS),bobUserId, cryptoTestData.roomId)
|
||||
aliceSession.cryptoService().verificationService().beginKeyVerification(VerificationMethod.SAS, bobSession.myUserId, transactionId)
|
||||
}
|
||||
testHelper.await(aliceSASLatch)
|
||||
testHelper.await(bobSASLatch)
|
||||
|
||||
/*
|
||||
val aliceTx = aliceVerificationService.getExistingTransaction(bobUserId, verificationSAS!!) as SasVerificationTransaction
|
||||
val bobTx = bobVerificationService.getExistingTransaction(aliceSession.myUserId, verificationSAS) as SasVerificationTransaction
|
||||
|
||||
testHelper.await(latch)
|
||||
val aliceTx = aliceSession.cryptoService().verificationService().getExistingTransaction(bobSession.myUserId, transactionId) as SasVerificationTransaction
|
||||
val bobTx = bobSession.cryptoService().verificationService().getExistingTransaction(aliceSession.myUserId, transactionId) as SasVerificationTransaction
|
||||
|
||||
assertEquals("Should have same SAS", aliceTx.getDecimalCodeRepresentation(), bobTx.getDecimalCodeRepresentation())
|
||||
|
||||
*/
|
||||
|
||||
cryptoTestData.cleanUp(testHelper)
|
||||
}
|
||||
|
||||
@ -495,7 +458,8 @@ class SASTest : InstrumentedTest {
|
||||
val testHelper = CommonTestHelper(context())
|
||||
val cryptoTestHelper = CryptoTestHelper(testHelper)
|
||||
val cryptoTestData = cryptoTestHelper.doE2ETestWithAliceAndBobInARoom()
|
||||
|
||||
val sasVerificationTestHelper = SasVerificationTestHelper(testHelper, cryptoTestHelper)
|
||||
val transactionId = sasVerificationTestHelper.requestVerificationAndWaitForReadyState(cryptoTestData, listOf(VerificationMethod.SAS))
|
||||
val aliceSession = cryptoTestData.firstSession
|
||||
val bobSession = cryptoTestData.secondSession
|
||||
|
||||
@ -504,8 +468,14 @@ class SASTest : InstrumentedTest {
|
||||
|
||||
val aliceSASLatch = CountDownLatch(1)
|
||||
val aliceListener = object : VerificationService.Listener {
|
||||
|
||||
override fun verificationRequestUpdated(pr: PendingVerificationRequest) {
|
||||
Timber.v("RequestUpdated pr=$pr")
|
||||
}
|
||||
|
||||
var matchOnce = true
|
||||
override fun transactionUpdated(tx: VerificationTransaction) {
|
||||
Timber.v("Alice transactionUpdated: ${tx.state}")
|
||||
if (tx !is SasVerificationTransaction) return
|
||||
when (tx.state) {
|
||||
VerificationTxState.ShortCodeReady -> testHelper.runBlockingTest {
|
||||
@ -527,7 +497,13 @@ class SASTest : InstrumentedTest {
|
||||
val bobListener = object : VerificationService.Listener {
|
||||
var acceptOnce = true
|
||||
var matchOnce = true
|
||||
|
||||
override fun verificationRequestUpdated(pr: PendingVerificationRequest) {
|
||||
Timber.v("RequestUpdated: pr=$pr")
|
||||
}
|
||||
|
||||
override fun transactionUpdated(tx: VerificationTransaction) {
|
||||
Timber.v("Bob transactionUpdated: ${tx.state}")
|
||||
if (tx !is SasVerificationTransaction) return
|
||||
when (tx.state) {
|
||||
VerificationTxState.OnStarted -> testHelper.runBlockingTest {
|
||||
@ -542,7 +518,7 @@ class SASTest : InstrumentedTest {
|
||||
tx.userHasVerifiedShortCode()
|
||||
}
|
||||
}
|
||||
VerificationTxState.Verified -> {
|
||||
VerificationTxState.ShortCodeAccepted -> {
|
||||
bobSASLatch.countDown()
|
||||
}
|
||||
else -> Unit
|
||||
@ -553,20 +529,20 @@ class SASTest : InstrumentedTest {
|
||||
|
||||
val bobUserId = bobSession.myUserId
|
||||
val bobDeviceId = runBlocking {
|
||||
bobSession.cryptoService().getMyDevice().deviceId
|
||||
bobSession.cryptoService().getMyCryptoDevice().deviceId
|
||||
}
|
||||
testHelper.runBlockingTest {
|
||||
aliceVerificationService.beginKeyVerification(VerificationMethod.SAS, bobUserId, bobDeviceId, null)
|
||||
aliceVerificationService.beginKeyVerification(VerificationMethod.SAS, bobUserId, transactionId)
|
||||
}
|
||||
testHelper.await(aliceSASLatch)
|
||||
testHelper.await(bobSASLatch)
|
||||
|
||||
// Assert that devices are verified
|
||||
val bobDeviceInfoFromAlicePOV: CryptoDeviceInfo? = testHelper.runBlockingTest {
|
||||
aliceSession.cryptoService().getDeviceInfo(bobUserId, bobDeviceId)
|
||||
aliceSession.cryptoService().getCryptoDeviceInfo(bobUserId, bobDeviceId)
|
||||
}
|
||||
val aliceDeviceInfoFromBobPOV: CryptoDeviceInfo? = testHelper.runBlockingTest {
|
||||
bobSession.cryptoService().getDeviceInfo(aliceSession.myUserId, aliceSession.cryptoService().getMyDevice().deviceId)
|
||||
bobSession.cryptoService().getCryptoDeviceInfo(aliceSession.myUserId, aliceSession.cryptoService().getMyCryptoDevice().deviceId)
|
||||
}
|
||||
assertTrue("alice device should be verified from bob point of view", aliceDeviceInfoFromBobPOV!!.isVerified)
|
||||
assertTrue("bob device should be verified from alice point of view", bobDeviceInfoFromAlicePOV!!.isVerified)
|
||||
@ -633,19 +609,17 @@ class SASTest : InstrumentedTest {
|
||||
|
||||
// Start concurrent!
|
||||
testHelper.runBlockingTest {
|
||||
aliceVerificationService.beginKeyVerificationInDMs(
|
||||
VerificationMethod.SAS,
|
||||
requestID!!,
|
||||
cryptoTestData.roomId,
|
||||
bobSession.myUserId,
|
||||
bobSession.sessionParams.deviceId!!)
|
||||
aliceVerificationService.requestKeyVerificationInDMs(
|
||||
methods = listOf(VerificationMethod.SAS),
|
||||
otherUserId = bobSession.myUserId,
|
||||
roomId = cryptoTestData.roomId
|
||||
)
|
||||
|
||||
bobVerificationService.beginKeyVerificationInDMs(
|
||||
VerificationMethod.SAS,
|
||||
requestID!!,
|
||||
cryptoTestData.roomId,
|
||||
aliceSession.myUserId,
|
||||
aliceSession.sessionParams.deviceId!!)
|
||||
bobVerificationService.requestKeyVerificationInDMs(
|
||||
methods = listOf(VerificationMethod.SAS),
|
||||
otherUserId = aliceSession.myUserId,
|
||||
roomId = cryptoTestData.roomId
|
||||
)
|
||||
|
||||
}
|
||||
|
||||
|
@ -0,0 +1,88 @@
|
||||
/*
|
||||
* Copyright (c) 2022 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 org.matrix.android.sdk.internal.crypto.verification
|
||||
|
||||
import org.matrix.android.sdk.api.session.crypto.verification.PendingVerificationRequest
|
||||
import org.matrix.android.sdk.api.session.crypto.verification.VerificationMethod
|
||||
import org.matrix.android.sdk.api.session.crypto.verification.VerificationService
|
||||
import org.matrix.android.sdk.common.CommonTestHelper
|
||||
import org.matrix.android.sdk.common.CryptoTestData
|
||||
import org.matrix.android.sdk.common.CryptoTestHelper
|
||||
import timber.log.Timber
|
||||
import java.util.concurrent.CountDownLatch
|
||||
|
||||
class SasVerificationTestHelper (private val testHelper: CommonTestHelper, private val cryptoTestHelper: CryptoTestHelper){
|
||||
fun requestVerificationAndWaitForReadyState(cryptoTestData: CryptoTestData, supportedMethods: List<VerificationMethod>): String {
|
||||
val aliceSession = cryptoTestData.firstSession
|
||||
val bobSession = cryptoTestData.secondSession!!
|
||||
cryptoTestHelper.initializeCrossSigning(aliceSession)
|
||||
cryptoTestHelper.initializeCrossSigning(bobSession)
|
||||
|
||||
val aliceVerificationService = aliceSession.cryptoService().verificationService()
|
||||
val bobVerificationService = bobSession.cryptoService().verificationService()
|
||||
|
||||
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
|
||||
Timber.v("Alice request updated: $pr")
|
||||
if (pr.isReady) {
|
||||
latch.countDown()
|
||||
}
|
||||
}
|
||||
}
|
||||
aliceVerificationService.addListener(aliceListener)
|
||||
|
||||
val bobListener = object : VerificationService.Listener {
|
||||
override fun verificationRequestCreated(pr: PendingVerificationRequest) {
|
||||
// Step 2: Bob accepts the verification request
|
||||
Timber.v("Bob accepts the verification request")
|
||||
testHelper.runBlockingTest {
|
||||
bobVerificationService.readyPendingVerification(
|
||||
supportedMethods,
|
||||
aliceSession.myUserId,
|
||||
pr.transactionId!!
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
override fun verificationRequestUpdated(pr: PendingVerificationRequest) {
|
||||
// Step 3: Bob is ready
|
||||
Timber.v("Bob request updated $pr")
|
||||
if (pr.isReady) {
|
||||
bobReadyPendingVerificationRequest = pr
|
||||
latch.countDown()
|
||||
}
|
||||
}
|
||||
}
|
||||
bobVerificationService.addListener(bobListener)
|
||||
|
||||
val bobUserId = bobSession.myUserId
|
||||
// Step 1: Alice starts a verification request
|
||||
testHelper.runBlockingTest {
|
||||
aliceVerificationService.requestKeyVerificationInDMs(supportedMethods, bobUserId, cryptoTestData.roomId)
|
||||
}
|
||||
testHelper.await(latch)
|
||||
bobVerificationService.removeListener(bobListener)
|
||||
aliceVerificationService.removeListener(aliceListener)
|
||||
return bobReadyPendingVerificationRequest?.transactionId!!
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -50,9 +50,9 @@ interface CryptoService {
|
||||
|
||||
fun keysBackupService(): KeysBackupService
|
||||
|
||||
fun setDeviceName(deviceId: String, deviceName: String, callback: MatrixCallback<Unit>)
|
||||
suspend fun setDeviceName(deviceId: String, deviceName: String)
|
||||
|
||||
fun deleteDevice(deviceId: String, userInteractiveAuthInterceptor: UserInteractiveAuthInterceptor, callback: MatrixCallback<Unit>)
|
||||
suspend fun deleteDevice(deviceId: String, userInteractiveAuthInterceptor: UserInteractiveAuthInterceptor)
|
||||
|
||||
fun getCryptoVersion(context: Context, longFormat: Boolean): String
|
||||
|
||||
@ -62,11 +62,9 @@ interface CryptoService {
|
||||
|
||||
fun setWarnOnUnknownDevices(warn: Boolean)
|
||||
|
||||
fun setDeviceVerification(trustLevel: DeviceTrustLevel, userId: String, deviceId: String)
|
||||
|
||||
suspend fun getUserDevices(userId: String): MutableList<CryptoDeviceInfo>
|
||||
|
||||
suspend fun getMyDevice(): CryptoDeviceInfo
|
||||
suspend fun getMyCryptoDevice(): CryptoDeviceInfo
|
||||
|
||||
fun getGlobalBlacklistUnverifiedDevices(): Boolean
|
||||
|
||||
@ -74,8 +72,6 @@ interface CryptoService {
|
||||
|
||||
fun setRoomUnBlacklistUnverifiedDevices(roomId: String)
|
||||
|
||||
fun getDeviceTrackingStatus(userId: String): Int
|
||||
|
||||
suspend fun importRoomKeys(roomKeysAsArray: ByteArray,
|
||||
password: String,
|
||||
progressListener: ProgressListener?): ImportRoomKeysResult
|
||||
@ -84,7 +80,7 @@ interface CryptoService {
|
||||
|
||||
fun setRoomBlacklistUnverifiedDevices(roomId: String)
|
||||
|
||||
suspend fun getDeviceInfo(userId: String, deviceId: String?): CryptoDeviceInfo?
|
||||
suspend fun getCryptoDeviceInfo(userId: String, deviceId: String?): CryptoDeviceInfo?
|
||||
|
||||
fun reRequestRoomKeyForEvent(event: Event)
|
||||
|
||||
@ -98,7 +94,7 @@ interface CryptoService {
|
||||
|
||||
fun getLiveMyDevicesInfo(): LiveData<List<DeviceInfo>>
|
||||
|
||||
fun getDeviceInfo(deviceId: String, callback: MatrixCallback<DeviceInfo>)
|
||||
suspend fun fetchDeviceInfo(deviceId: String): DeviceInfo
|
||||
|
||||
suspend fun inboundGroupSessionsCount(onlyBackedUp: Boolean): Int
|
||||
|
||||
@ -113,19 +109,17 @@ interface CryptoService {
|
||||
@Throws(MXCryptoError::class)
|
||||
suspend fun decryptEvent(event: Event, timeline: String): MXEventDecryptionResult
|
||||
|
||||
fun decryptEventAsync(event: Event, timeline: String, callback: MatrixCallback<MXEventDecryptionResult>)
|
||||
|
||||
fun getEncryptionAlgorithm(roomId: String): String?
|
||||
|
||||
fun shouldEncryptForInvitedMembers(roomId: String): Boolean
|
||||
|
||||
suspend fun downloadKeys(userIds: List<String>, forceDownload: Boolean = false): MXUsersDevicesMap<CryptoDeviceInfo>
|
||||
|
||||
suspend fun getCryptoDeviceInfo(userId: String): List<CryptoDeviceInfo>
|
||||
suspend fun getCryptoDeviceInfoList(userId: String): List<CryptoDeviceInfo>
|
||||
|
||||
fun getLiveCryptoDeviceInfo(userId: String): Flow<List<CryptoDeviceInfo>>
|
||||
fun getLiveCryptoDeviceInfoList(userId: String): Flow<List<CryptoDeviceInfo>>
|
||||
|
||||
fun getLiveCryptoDeviceInfo(userIds: List<String>): Flow<List<CryptoDeviceInfo>>
|
||||
fun getLiveCryptoDeviceInfoList(userIds: List<String>): Flow<List<CryptoDeviceInfo>>
|
||||
|
||||
fun addNewSessionListener(newSessionListener: NewSessionListener)
|
||||
|
||||
|
@ -121,5 +121,4 @@ interface VerificationService {
|
||||
}
|
||||
}
|
||||
|
||||
fun onPotentiallyInterestingEventRoomFailToDecrypt(event: Event)
|
||||
}
|
||||
|
@ -32,9 +32,7 @@ import kotlinx.coroutines.launch
|
||||
import kotlinx.coroutines.sync.Mutex
|
||||
import kotlinx.coroutines.sync.withLock
|
||||
import kotlinx.coroutines.withContext
|
||||
import org.matrix.android.sdk.api.MatrixCallback
|
||||
import org.matrix.android.sdk.api.MatrixCoroutineDispatchers
|
||||
import org.matrix.android.sdk.api.NoOpMatrixCallback
|
||||
import org.matrix.android.sdk.api.auth.UserInteractiveAuthInterceptor
|
||||
import org.matrix.android.sdk.api.crypto.MXCryptoConfig
|
||||
import org.matrix.android.sdk.api.extensions.tryOrNull
|
||||
@ -56,7 +54,6 @@ import org.matrix.android.sdk.api.session.room.model.RoomMemberContent
|
||||
import org.matrix.android.sdk.api.session.sync.model.DeviceListResponse
|
||||
import org.matrix.android.sdk.api.session.sync.model.DeviceOneTimeKeysCountSyncResponse
|
||||
import org.matrix.android.sdk.api.session.sync.model.ToDeviceSyncResponse
|
||||
import org.matrix.android.sdk.internal.crypto.crosssigning.DeviceTrustLevel
|
||||
import org.matrix.android.sdk.internal.crypto.keysbackup.RustKeyBackupService
|
||||
import org.matrix.android.sdk.internal.crypto.model.CryptoDeviceInfo
|
||||
import org.matrix.android.sdk.internal.crypto.model.ImportRoomKeysResult
|
||||
@ -67,6 +64,8 @@ import org.matrix.android.sdk.internal.crypto.model.event.RoomKeyWithHeldContent
|
||||
import org.matrix.android.sdk.internal.crypto.model.event.SecretSendEventContent
|
||||
import org.matrix.android.sdk.internal.crypto.model.rest.DeviceInfo
|
||||
import org.matrix.android.sdk.internal.crypto.model.rest.ForwardedRoomKeyContent
|
||||
import org.matrix.android.sdk.internal.crypto.network.OutgoingRequestsProcessor
|
||||
import org.matrix.android.sdk.internal.crypto.network.RequestSender
|
||||
import org.matrix.android.sdk.internal.crypto.repository.WarnOnUnknownDeviceRepository
|
||||
import org.matrix.android.sdk.internal.crypto.store.IMXCryptoStore
|
||||
import org.matrix.android.sdk.internal.crypto.tasks.DeleteDeviceTask
|
||||
@ -79,10 +78,6 @@ import org.matrix.android.sdk.internal.di.UserId
|
||||
import org.matrix.android.sdk.internal.session.SessionScope
|
||||
import org.matrix.android.sdk.internal.session.StreamEventsManager
|
||||
import org.matrix.android.sdk.internal.session.room.membership.LoadRoomMembersTask
|
||||
import org.matrix.android.sdk.internal.task.TaskExecutor
|
||||
import org.matrix.android.sdk.internal.task.TaskThread
|
||||
import org.matrix.android.sdk.internal.task.configureWith
|
||||
import org.matrix.android.sdk.internal.task.launchToCallback
|
||||
import timber.log.Timber
|
||||
import uniffi.olm.Request
|
||||
import uniffi.olm.RequestType
|
||||
@ -129,7 +124,6 @@ internal class DefaultCryptoService @Inject constructor(
|
||||
private val loadRoomMembersTask: LoadRoomMembersTask,
|
||||
private val cryptoSessionInfoProvider: CryptoSessionInfoProvider,
|
||||
private val coroutineDispatchers: MatrixCoroutineDispatchers,
|
||||
private val taskExecutor: TaskExecutor,
|
||||
private val cryptoCoroutineScope: CoroutineScope,
|
||||
private val requestSender: RequestSender,
|
||||
private val crossSigningService: CrossSigningService,
|
||||
@ -152,7 +146,7 @@ internal class DefaultCryptoService @Inject constructor(
|
||||
|
||||
// Locks for some of our operations
|
||||
private val keyClaimLock: Mutex = Mutex()
|
||||
private val outgoingRequestsLock: Mutex = Mutex()
|
||||
private val outgoingRequestsProcessor = OutgoingRequestsProcessor(requestSender, cryptoCoroutineScope, cryptoSessionInfoProvider, crossSigningService::shieldForGroup)
|
||||
private val roomKeyShareLocks: ConcurrentHashMap<String, Mutex> = ConcurrentHashMap()
|
||||
|
||||
fun onStateEvent(roomId: String, event: Event) {
|
||||
@ -179,38 +173,19 @@ internal class DefaultCryptoService @Inject constructor(
|
||||
|
||||
private val gossipingBuffer = mutableListOf<Event>()
|
||||
|
||||
override fun setDeviceName(deviceId: String, deviceName: String, callback: MatrixCallback<Unit>) {
|
||||
setDeviceNameTask
|
||||
.configureWith(SetDeviceNameTask.Params(deviceId, deviceName)) {
|
||||
this.executionThread = TaskThread.CRYPTO
|
||||
this.callback = object : MatrixCallback<Unit> {
|
||||
override fun onSuccess(data: Unit) {
|
||||
// bg refresh of crypto device
|
||||
cryptoCoroutineScope.launch {
|
||||
try {
|
||||
downloadKeys(listOf(userId), true)
|
||||
} catch (failure: Throwable) {
|
||||
Timber.tag(loggerTag.value).w(failure, "setDeviceName: Failed to refresh of crypto device")
|
||||
}
|
||||
}
|
||||
callback.onSuccess(data)
|
||||
}
|
||||
|
||||
override fun onFailure(failure: Throwable) {
|
||||
callback.onFailure(failure)
|
||||
}
|
||||
}
|
||||
}
|
||||
.executeBy(taskExecutor)
|
||||
override suspend fun setDeviceName(deviceId: String, deviceName: String) {
|
||||
val params = SetDeviceNameTask.Params(deviceId, deviceName)
|
||||
setDeviceNameTask.execute(params)
|
||||
try {
|
||||
downloadKeys(listOf(userId), true)
|
||||
} catch (failure: Throwable) {
|
||||
Timber.tag(loggerTag.value).w(failure, "setDeviceName: Failed to refresh of crypto device")
|
||||
}
|
||||
}
|
||||
|
||||
override fun deleteDevice(deviceId: String, userInteractiveAuthInterceptor: UserInteractiveAuthInterceptor, callback: MatrixCallback<Unit>) {
|
||||
deleteDeviceTask
|
||||
.configureWith(DeleteDeviceTask.Params(deviceId, userInteractiveAuthInterceptor, null)) {
|
||||
this.executionThread = TaskThread.CRYPTO
|
||||
this.callback = callback
|
||||
}
|
||||
.executeBy(taskExecutor)
|
||||
override suspend fun deleteDevice(deviceId: String, userInteractiveAuthInterceptor: UserInteractiveAuthInterceptor) {
|
||||
val params = DeleteDeviceTask.Params(deviceId, userInteractiveAuthInterceptor, null)
|
||||
deleteDeviceTask.execute(params)
|
||||
}
|
||||
|
||||
override fun getCryptoVersion(context: Context, longFormat: Boolean): String {
|
||||
@ -218,7 +193,7 @@ internal class DefaultCryptoService @Inject constructor(
|
||||
return if (longFormat) "Rust SDK 0.3" else "0.3"
|
||||
}
|
||||
|
||||
override suspend fun getMyDevice(): CryptoDeviceInfo {
|
||||
override suspend fun getMyCryptoDevice(): CryptoDeviceInfo {
|
||||
return olmMachine.ownDevice()
|
||||
}
|
||||
|
||||
@ -238,13 +213,9 @@ internal class DefaultCryptoService @Inject constructor(
|
||||
return cryptoStore.getMyDevicesInfo()
|
||||
}
|
||||
|
||||
override fun getDeviceInfo(deviceId: String, callback: MatrixCallback<DeviceInfo>) {
|
||||
getDeviceInfoTask
|
||||
.configureWith(GetDeviceInfoTask.Params(deviceId)) {
|
||||
this.executionThread = TaskThread.CRYPTO
|
||||
this.callback = callback
|
||||
}
|
||||
.executeBy(taskExecutor)
|
||||
override suspend fun fetchDeviceInfo(deviceId: String): DeviceInfo {
|
||||
val params = GetDeviceInfoTask.Params(deviceId)
|
||||
return getDeviceInfoTask.execute(params)
|
||||
}
|
||||
|
||||
override suspend fun inboundGroupSessionsCount(onlyBackedUp: Boolean): Int {
|
||||
@ -256,20 +227,6 @@ internal class DefaultCryptoService @Inject constructor(
|
||||
// return cryptoStore.inboundGroupSessionsCount(onlyBackedUp)
|
||||
}
|
||||
|
||||
/**
|
||||
* Provides the tracking status
|
||||
*
|
||||
* @param userId the user id
|
||||
* @return the tracking status
|
||||
*/
|
||||
override fun getDeviceTrackingStatus(userId: String): Int {
|
||||
return if (olmMachine.isUserTracked(userId)) {
|
||||
3
|
||||
} else {
|
||||
-1
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Tell if the MXCrypto is started
|
||||
*
|
||||
@ -288,28 +245,13 @@ internal class DefaultCryptoService @Inject constructor(
|
||||
*/
|
||||
fun start() {
|
||||
internalStart()
|
||||
cryptoCoroutineScope.launch(coroutineDispatchers.crypto) {
|
||||
cryptoCoroutineScope.launch {
|
||||
// Just update
|
||||
fetchDevicesList()
|
||||
cryptoStore.tidyUpDataBase()
|
||||
}
|
||||
}
|
||||
|
||||
fun ensureDevice() {
|
||||
cryptoCoroutineScope.launchToCallback(coroutineDispatchers.crypto, NoOpMatrixCallback()) {
|
||||
// Open the store
|
||||
cryptoStore.open()
|
||||
|
||||
// this can throw if no backup
|
||||
/*
|
||||
TODO
|
||||
tryOrNull {
|
||||
keysBackupService.checkAndStartKeysBackup()
|
||||
}
|
||||
*/
|
||||
}
|
||||
}
|
||||
|
||||
private fun internalStart() {
|
||||
if (isStarted.get() || isStarting.get()) {
|
||||
return
|
||||
@ -372,7 +314,7 @@ internal class DefaultCryptoService @Inject constructor(
|
||||
*/
|
||||
suspend fun onSyncCompleted() {
|
||||
if (isStarted()) {
|
||||
sendOutgoingRequests()
|
||||
outgoingRequestsProcessor.process(olmMachine)
|
||||
// This isn't a copy paste error. Sending the outgoing requests may
|
||||
// claim one-time keys and establish 1-to-1 Olm sessions with devices, while some
|
||||
// outgoing requests are waiting for an Olm session to be established (e.g. forwarding
|
||||
@ -381,7 +323,7 @@ internal class DefaultCryptoService @Inject constructor(
|
||||
// The second call sends out those requests that are waiting for the
|
||||
// keys claim request to be sent out.
|
||||
// This could be omitted but then devices might be waiting for the next
|
||||
sendOutgoingRequests()
|
||||
outgoingRequestsProcessor.process(olmMachine)
|
||||
|
||||
keysBackupService.maybeBackupKeys()
|
||||
}
|
||||
@ -402,34 +344,21 @@ internal class DefaultCryptoService @Inject constructor(
|
||||
* @param userId the user id
|
||||
* @param deviceId the device id
|
||||
*/
|
||||
override suspend fun getDeviceInfo(userId: String, deviceId: String?): CryptoDeviceInfo? {
|
||||
override suspend fun getCryptoDeviceInfo(userId: String, deviceId: String?): CryptoDeviceInfo? {
|
||||
if (userId.isEmpty() || deviceId.isNullOrEmpty()) return null
|
||||
return olmMachine.getCryptoDeviceInfo(userId, deviceId)
|
||||
}
|
||||
|
||||
override suspend fun getCryptoDeviceInfo(userId: String): List<CryptoDeviceInfo> {
|
||||
override suspend fun getCryptoDeviceInfoList(userId: String): List<CryptoDeviceInfo> {
|
||||
return olmMachine.getCryptoDeviceInfo(userId)
|
||||
}
|
||||
|
||||
override fun getLiveCryptoDeviceInfo(userId: String): Flow<List<CryptoDeviceInfo>> {
|
||||
return getLiveCryptoDeviceInfo(listOf(userId))
|
||||
}
|
||||
override fun getLiveCryptoDeviceInfoList(userId: String) = getLiveCryptoDeviceInfoList(listOf(userId))
|
||||
|
||||
override fun getLiveCryptoDeviceInfo(userIds: List<String>): Flow<List<CryptoDeviceInfo>> {
|
||||
override fun getLiveCryptoDeviceInfoList(userIds: List<String>): Flow<List<CryptoDeviceInfo>> {
|
||||
return olmMachine.getLiveDevices(userIds)
|
||||
}
|
||||
|
||||
/**
|
||||
* Update the blocked/verified state of the given device.
|
||||
*
|
||||
* @param trustLevel the new trust level
|
||||
* @param userId the owner of the device
|
||||
* @param deviceId the unique identifier for the device.
|
||||
*/
|
||||
override fun setDeviceVerification(trustLevel: DeviceTrustLevel, userId: String, deviceId: String) {
|
||||
// TODO
|
||||
}
|
||||
|
||||
/**
|
||||
* Configure a room to use encryption.
|
||||
*
|
||||
@ -487,7 +416,7 @@ internal class DefaultCryptoService @Inject constructor(
|
||||
* @return the stored device keys for a user.
|
||||
*/
|
||||
override suspend fun getUserDevices(userId: String): MutableList<CryptoDeviceInfo> {
|
||||
return this.getCryptoDeviceInfo(userId).toMutableList()
|
||||
return this.getCryptoDeviceInfoList(userId).toMutableList()
|
||||
}
|
||||
|
||||
private fun isEncryptionEnabledForInvitedUser(): Boolean {
|
||||
@ -559,18 +488,6 @@ internal class DefaultCryptoService @Inject constructor(
|
||||
return olmMachine.decryptRoomEvent(event)
|
||||
}
|
||||
|
||||
/**
|
||||
* Decrypt an event asynchronously
|
||||
*
|
||||
* @param event the raw event.
|
||||
* @param timeline the id of the timeline where the event is decrypted. It is used to prevent replay attack.
|
||||
* @param callback the callback to return data or null
|
||||
*/
|
||||
override fun decryptEventAsync(event: Event, timeline: String, callback: MatrixCallback<MXEventDecryptionResult>) {
|
||||
// This isn't really used anywhere, maybe just remove it?
|
||||
// TODO
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle an m.room.encryption event.
|
||||
*
|
||||
@ -816,54 +733,6 @@ internal class DefaultCryptoService @Inject constructor(
|
||||
}
|
||||
}
|
||||
|
||||
private suspend fun sendOutgoingRequests() {
|
||||
outgoingRequestsLock.withLock {
|
||||
coroutineScope {
|
||||
Timber.v("OutgoingRequests: ${olmMachine.outgoingRequests()}")
|
||||
olmMachine.outgoingRequests().map {
|
||||
when (it) {
|
||||
is Request.KeysUpload -> {
|
||||
async {
|
||||
uploadKeys(it)
|
||||
}
|
||||
}
|
||||
is Request.KeysQuery -> {
|
||||
async {
|
||||
queryKeys(it)
|
||||
}
|
||||
}
|
||||
is Request.ToDevice -> {
|
||||
async {
|
||||
sendToDevice(it)
|
||||
}
|
||||
}
|
||||
is Request.KeysClaim -> {
|
||||
async {
|
||||
claimKeys(it)
|
||||
}
|
||||
}
|
||||
is Request.RoomMessage -> {
|
||||
async {
|
||||
sendRoomMessage(it)
|
||||
}
|
||||
}
|
||||
is Request.SignatureUpload -> {
|
||||
async {
|
||||
signatureUpload(it)
|
||||
}
|
||||
}
|
||||
is Request.KeysBackup -> {
|
||||
async {
|
||||
// The rust-sdk won't ever produce KeysBackup requests here,
|
||||
// those only get explicitly created.
|
||||
}
|
||||
}
|
||||
}
|
||||
}.joinAll()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Export the crypto keys
|
||||
*
|
||||
|
@ -23,6 +23,7 @@ import org.matrix.android.sdk.api.session.crypto.verification.VerificationServic
|
||||
import org.matrix.android.sdk.internal.crypto.crosssigning.DeviceTrustLevel
|
||||
import org.matrix.android.sdk.internal.crypto.model.CryptoDeviceInfo
|
||||
import org.matrix.android.sdk.internal.crypto.model.rest.UnsignedDeviceInfo
|
||||
import org.matrix.android.sdk.internal.crypto.network.RequestSender
|
||||
import org.matrix.android.sdk.internal.crypto.verification.prepareMethods
|
||||
import uniffi.olm.CryptoStoreException
|
||||
import uniffi.olm.OlmMachine
|
||||
|
@ -47,6 +47,7 @@ import org.matrix.android.sdk.internal.crypto.model.ImportRoomKeysResult
|
||||
import org.matrix.android.sdk.internal.crypto.model.MXUsersDevicesMap
|
||||
import org.matrix.android.sdk.internal.crypto.model.rest.RestKeyInfo
|
||||
import org.matrix.android.sdk.internal.crypto.model.rest.UnsignedDeviceInfo
|
||||
import org.matrix.android.sdk.internal.crypto.network.RequestSender
|
||||
import org.matrix.android.sdk.internal.crypto.store.PrivateKeysInfo
|
||||
import org.matrix.android.sdk.internal.network.parsing.CheckNumberType
|
||||
import timber.log.Timber
|
||||
@ -549,13 +550,7 @@ internal class OlmMachine(
|
||||
*/
|
||||
@Throws(CryptoStoreException::class)
|
||||
suspend fun getCryptoDeviceInfo(userId: String, deviceId: String): CryptoDeviceInfo? {
|
||||
return if (userId == userId() && deviceId == deviceId()) {
|
||||
// Our own device isn't part of our store on the Rust side, return it
|
||||
// using our ownDevice method
|
||||
ownDevice()
|
||||
} else {
|
||||
getDevice(userId, deviceId)?.toCryptoDeviceInfo()
|
||||
}
|
||||
return getDevice(userId, deviceId)?.toCryptoDeviceInfo()
|
||||
}
|
||||
|
||||
@Throws(CryptoStoreException::class)
|
||||
@ -596,8 +591,8 @@ internal class OlmMachine(
|
||||
*/
|
||||
@Throws(CryptoStoreException::class)
|
||||
suspend fun getCryptoDeviceInfo(userId: String): List<CryptoDeviceInfo> {
|
||||
val devices = getUserDevices(userId).map { it.toCryptoDeviceInfo() }.toMutableList()
|
||||
|
||||
return getUserDevices(userId).map { it.toCryptoDeviceInfo() }
|
||||
/*
|
||||
// EA doesn't differentiate much between our own and other devices of
|
||||
// while the rust-sdk does, append our own device here.
|
||||
if (userId == userId()) {
|
||||
@ -605,6 +600,8 @@ internal class OlmMachine(
|
||||
}
|
||||
|
||||
return devices
|
||||
|
||||
*/
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -18,6 +18,7 @@ package org.matrix.android.sdk.internal.crypto
|
||||
|
||||
import com.squareup.moshi.Moshi
|
||||
import org.matrix.android.sdk.api.MatrixCoroutineDispatchers
|
||||
import org.matrix.android.sdk.internal.crypto.network.RequestSender
|
||||
import org.matrix.android.sdk.internal.di.DeviceId
|
||||
import org.matrix.android.sdk.internal.di.SessionFilesDirectory
|
||||
import org.matrix.android.sdk.internal.di.UserId
|
||||
|
@ -24,6 +24,7 @@ import org.matrix.android.sdk.api.session.crypto.verification.VerificationServic
|
||||
import org.matrix.android.sdk.api.session.crypto.verification.VerificationTxState
|
||||
import org.matrix.android.sdk.api.session.crypto.verification.safeValueOf
|
||||
import org.matrix.android.sdk.internal.crypto.crosssigning.fromBase64
|
||||
import org.matrix.android.sdk.internal.crypto.network.RequestSender
|
||||
import org.matrix.android.sdk.internal.crypto.verification.UpdateDispatcher
|
||||
import uniffi.olm.CryptoStoreException
|
||||
import uniffi.olm.OlmMachine
|
||||
|
@ -24,6 +24,7 @@ import org.matrix.android.sdk.api.session.crypto.verification.SasVerificationTra
|
||||
import org.matrix.android.sdk.api.session.crypto.verification.VerificationService
|
||||
import org.matrix.android.sdk.api.session.crypto.verification.VerificationTxState
|
||||
import org.matrix.android.sdk.api.session.crypto.verification.safeValueOf
|
||||
import org.matrix.android.sdk.internal.crypto.network.RequestSender
|
||||
import org.matrix.android.sdk.internal.crypto.verification.UpdateDispatcher
|
||||
import org.matrix.android.sdk.internal.crypto.verification.getEmojiForCode
|
||||
import uniffi.olm.CryptoStoreException
|
||||
|
@ -23,6 +23,7 @@ import org.matrix.android.sdk.api.session.crypto.verification.VerificationMethod
|
||||
import org.matrix.android.sdk.api.session.events.model.EventType
|
||||
import org.matrix.android.sdk.internal.crypto.crosssigning.DeviceTrustLevel
|
||||
import org.matrix.android.sdk.internal.crypto.model.CryptoCrossSigningKey
|
||||
import org.matrix.android.sdk.internal.crypto.network.RequestSender
|
||||
import org.matrix.android.sdk.internal.crypto.verification.prepareMethods
|
||||
import uniffi.olm.CryptoStoreException
|
||||
import uniffi.olm.SignatureException
|
||||
|
@ -18,7 +18,6 @@ package org.matrix.android.sdk.internal.crypto
|
||||
|
||||
import android.os.Handler
|
||||
import android.os.Looper
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.withContext
|
||||
import org.matrix.android.sdk.api.MatrixCoroutineDispatchers
|
||||
import org.matrix.android.sdk.api.session.crypto.verification.CancelCode
|
||||
@ -30,6 +29,7 @@ import org.matrix.android.sdk.api.session.crypto.verification.VerificationServic
|
||||
import org.matrix.android.sdk.api.session.crypto.verification.safeValueOf
|
||||
import org.matrix.android.sdk.internal.crypto.crosssigning.toBase64NoPadding
|
||||
import org.matrix.android.sdk.internal.crypto.model.rest.VERIFICATION_METHOD_QR_CODE_SCAN
|
||||
import org.matrix.android.sdk.internal.crypto.network.RequestSender
|
||||
import org.matrix.android.sdk.internal.crypto.verification.prepareMethods
|
||||
import timber.log.Timber
|
||||
import uniffi.olm.OlmMachine
|
||||
|
@ -40,7 +40,7 @@ import org.matrix.android.sdk.internal.crypto.MXCRYPTO_ALGORITHM_MEGOLM_BACKUP
|
||||
import org.matrix.android.sdk.internal.crypto.MegolmSessionData
|
||||
import org.matrix.android.sdk.internal.crypto.MegolmSessionImportManager
|
||||
import org.matrix.android.sdk.internal.crypto.OlmMachineProvider
|
||||
import org.matrix.android.sdk.internal.crypto.RequestSender
|
||||
import org.matrix.android.sdk.internal.crypto.network.RequestSender
|
||||
import org.matrix.android.sdk.internal.crypto.keysbackup.model.KeysBackupVersionTrust
|
||||
import org.matrix.android.sdk.internal.crypto.keysbackup.model.MegolmBackupAuthData
|
||||
import org.matrix.android.sdk.internal.crypto.keysbackup.model.MegolmBackupCreationInfo
|
||||
@ -580,16 +580,12 @@ internal class RustKeyBackupService @Inject constructor(
|
||||
}
|
||||
|
||||
override suspend fun getVersion(version: String): KeysVersionResult? {
|
||||
return withContext(coroutineDispatchers.io) {
|
||||
sender.getKeyBackupVersion(version)
|
||||
}
|
||||
return sender.getKeyBackupVersion(version)
|
||||
}
|
||||
|
||||
@Throws
|
||||
override suspend fun getCurrentVersion(): KeysVersionResult? {
|
||||
return withContext(coroutineDispatchers.io) {
|
||||
sender.getKeyBackupVersion()
|
||||
}
|
||||
return sender.getKeyBackupVersion()
|
||||
}
|
||||
|
||||
override suspend fun forceUsingLastVersion(): Boolean {
|
||||
@ -645,18 +641,16 @@ internal class RustKeyBackupService @Inject constructor(
|
||||
Timber.w("checkAndStartKeysBackup: invalid state: $state")
|
||||
return@withContext
|
||||
}
|
||||
|
||||
keysBackupVersion = null
|
||||
keysBackupStateManager.state = KeysBackupState.CheckingBackUpOnHomeserver
|
||||
|
||||
withContext(coroutineDispatchers.io) {
|
||||
try {
|
||||
val data = getCurrentVersion()
|
||||
withContext(coroutineDispatchers.crypto) {
|
||||
checkAndStartWithKeysBackupVersion(data)
|
||||
}
|
||||
} catch (failure: Throwable) {
|
||||
Timber.e(failure, "checkAndStartKeysBackup: Failed to get current version")
|
||||
try {
|
||||
val data = getCurrentVersion()
|
||||
withContext(coroutineDispatchers.crypto) {
|
||||
checkAndStartWithKeysBackupVersion(data)
|
||||
}
|
||||
} catch (failure: Throwable) {
|
||||
Timber.e(failure, "checkAndStartKeysBackup: Failed to get current version")
|
||||
withContext(coroutineDispatchers.crypto) {
|
||||
keysBackupStateManager.state = KeysBackupState.Unknown
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,157 @@
|
||||
/*
|
||||
* Copyright (c) 2022 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 org.matrix.android.sdk.internal.crypto.network
|
||||
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.async
|
||||
import kotlinx.coroutines.coroutineScope
|
||||
import kotlinx.coroutines.joinAll
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlinx.coroutines.sync.Mutex
|
||||
import kotlinx.coroutines.sync.withLock
|
||||
import org.matrix.android.sdk.api.crypto.RoomEncryptionTrustLevel
|
||||
import org.matrix.android.sdk.api.logger.LoggerTag
|
||||
import org.matrix.android.sdk.internal.crypto.CryptoSessionInfoProvider
|
||||
import org.matrix.android.sdk.internal.crypto.OlmMachine
|
||||
import timber.log.Timber
|
||||
import uniffi.olm.Request
|
||||
import uniffi.olm.RequestType
|
||||
|
||||
private val loggerTag = LoggerTag("OutgoingRequestsProcessor", LoggerTag.CRYPTO)
|
||||
|
||||
internal class OutgoingRequestsProcessor(private val requestSender: RequestSender,
|
||||
private val coroutineScope: CoroutineScope,
|
||||
private val cryptoSessionInfoProvider: CryptoSessionInfoProvider,
|
||||
private val shieldComputer: ShieldComputer) {
|
||||
|
||||
fun interface ShieldComputer {
|
||||
suspend fun compute(userIds: List<String>): RoomEncryptionTrustLevel
|
||||
}
|
||||
|
||||
private val lock: Mutex = Mutex()
|
||||
|
||||
suspend fun process(olmMachine: OlmMachine) {
|
||||
lock.withLock {
|
||||
coroutineScope {
|
||||
Timber.v("OutgoingRequests: ${olmMachine.outgoingRequests()}")
|
||||
olmMachine.outgoingRequests().map {
|
||||
when (it) {
|
||||
is Request.KeysUpload -> {
|
||||
async {
|
||||
uploadKeys(olmMachine, it)
|
||||
}
|
||||
}
|
||||
is Request.KeysQuery -> {
|
||||
async {
|
||||
queryKeys(olmMachine, it)
|
||||
}
|
||||
}
|
||||
is Request.ToDevice -> {
|
||||
async {
|
||||
sendToDevice(olmMachine, it)
|
||||
}
|
||||
}
|
||||
is Request.KeysClaim -> {
|
||||
async {
|
||||
claimKeys(olmMachine, it)
|
||||
}
|
||||
}
|
||||
is Request.RoomMessage -> {
|
||||
async {
|
||||
sendRoomMessage(olmMachine, it)
|
||||
}
|
||||
}
|
||||
is Request.SignatureUpload -> {
|
||||
async {
|
||||
signatureUpload(olmMachine, it)
|
||||
}
|
||||
}
|
||||
is Request.KeysBackup -> {
|
||||
async {
|
||||
// The rust-sdk won't ever produce KeysBackup requests here,
|
||||
// those only get explicitly created.
|
||||
}
|
||||
}
|
||||
}
|
||||
}.joinAll()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private suspend fun uploadKeys(olmMachine: OlmMachine, request: Request.KeysUpload) {
|
||||
try {
|
||||
val response = requestSender.uploadKeys(request)
|
||||
olmMachine.markRequestAsSent(request.requestId, RequestType.KEYS_UPLOAD, response)
|
||||
} catch (throwable: Throwable) {
|
||||
Timber.tag(loggerTag.value).e(throwable, "## uploadKeys(): error")
|
||||
}
|
||||
}
|
||||
|
||||
private suspend fun queryKeys(olmMachine: OlmMachine, request: Request.KeysQuery) {
|
||||
try {
|
||||
val response = requestSender.queryKeys(request)
|
||||
olmMachine.markRequestAsSent(request.requestId, RequestType.KEYS_QUERY, response)
|
||||
coroutineScope.updateShields(request.users)
|
||||
} catch (throwable: Throwable) {
|
||||
Timber.tag(loggerTag.value).e(throwable, "## queryKeys(): error")
|
||||
}
|
||||
}
|
||||
|
||||
private fun CoroutineScope.updateShields(userIds: List<String>) = launch {
|
||||
cryptoSessionInfoProvider.getRoomsWhereUsersAreParticipating(userIds).forEach { roomId ->
|
||||
val userGroup = cryptoSessionInfoProvider.getUserListForShieldComputation(roomId)
|
||||
val shield = shieldComputer.compute(userGroup)
|
||||
cryptoSessionInfoProvider.updateShieldForRoom(roomId, shield)
|
||||
}
|
||||
}
|
||||
|
||||
private suspend fun sendToDevice(olmMachine: OlmMachine, request: Request.ToDevice) {
|
||||
try {
|
||||
requestSender.sendToDevice(request)
|
||||
olmMachine.markRequestAsSent(request.requestId, RequestType.TO_DEVICE, "{}")
|
||||
} catch (throwable: Throwable) {
|
||||
Timber.tag(loggerTag.value).e(throwable, "## sendToDevice(): error")
|
||||
}
|
||||
}
|
||||
|
||||
private suspend fun claimKeys(olmMachine: OlmMachine, request: Request.KeysClaim) {
|
||||
try {
|
||||
val response = requestSender.claimKeys(request)
|
||||
olmMachine.markRequestAsSent(request.requestId, RequestType.KEYS_CLAIM, response)
|
||||
} catch (throwable: Throwable) {
|
||||
Timber.tag(loggerTag.value).e(throwable, "## claimKeys(): error")
|
||||
}
|
||||
}
|
||||
|
||||
private suspend fun signatureUpload(olmMachine: OlmMachine, request: Request.SignatureUpload) {
|
||||
try {
|
||||
val response = requestSender.sendSignatureUpload(request)
|
||||
olmMachine.markRequestAsSent(request.requestId, RequestType.SIGNATURE_UPLOAD, response)
|
||||
} catch (throwable: Throwable) {
|
||||
Timber.tag(loggerTag.value).e(throwable, "## signatureUpload(): error")
|
||||
}
|
||||
}
|
||||
|
||||
private suspend fun sendRoomMessage(olmMachine: OlmMachine, request: Request.RoomMessage) {
|
||||
try {
|
||||
val response = requestSender.sendRoomMessage(request)
|
||||
olmMachine.markRequestAsSent(request.requestId, RequestType.ROOM_MESSAGE, response)
|
||||
} catch (throwable: Throwable) {
|
||||
Timber.tag(loggerTag.value).e(throwable, "## sendRoomMessage(): error")
|
||||
}
|
||||
}
|
||||
}
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2021 The Matrix.org Foundation C.I.C.
|
||||
* Copyright (c) 2022 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.
|
||||
@ -14,7 +14,7 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.matrix.android.sdk.internal.crypto
|
||||
package org.matrix.android.sdk.internal.crypto.network
|
||||
|
||||
import com.squareup.moshi.Moshi
|
||||
import com.squareup.moshi.Types
|
||||
@ -59,7 +59,6 @@ import org.matrix.android.sdk.internal.crypto.tasks.UploadSigningKeysTask
|
||||
import org.matrix.android.sdk.internal.di.MoshiProvider
|
||||
import org.matrix.android.sdk.internal.network.parsing.CheckNumberType
|
||||
import org.matrix.android.sdk.internal.session.room.send.SendResponse
|
||||
import org.matrix.android.sdk.internal.session.room.send.queue.EventSenderProcessor
|
||||
import timber.log.Timber
|
||||
import uniffi.olm.OutgoingVerificationRequest
|
||||
import uniffi.olm.Request
|
@ -60,7 +60,7 @@ internal class DefaultEncryptEventTask @Inject constructor(
|
||||
).toContent(),
|
||||
forwardingCurve25519KeyChain = emptyList(),
|
||||
senderCurve25519Key = result.eventContent["sender_key"] as? String,
|
||||
claimedEd25519Key = cryptoService.getMyDevice().fingerprint()
|
||||
claimedEd25519Key = cryptoService.getMyCryptoDevice().fingerprint()
|
||||
)
|
||||
} else {
|
||||
null
|
||||
|
@ -176,13 +176,7 @@ internal class RustVerificationService @Inject constructor(private val olmMachin
|
||||
}
|
||||
|
||||
override suspend fun markedLocallyAsManuallyVerified(userId: String, deviceID: String) {
|
||||
// TODO this doesn't seem to be used anymore?
|
||||
val device = olmMachine.getDevice(userId, deviceID)
|
||||
device?.markAsTrusted()
|
||||
}
|
||||
|
||||
override fun onPotentiallyInterestingEventRoomFailToDecrypt(event: Event) {
|
||||
// TODO This should be handled inside the rust-sdk decryption method
|
||||
olmMachine.getDevice(userId, deviceID)?.markAsTrusted()
|
||||
}
|
||||
|
||||
override fun getExistingTransaction(
|
||||
|
@ -177,7 +177,6 @@ internal class DefaultSession @Inject constructor(
|
||||
assert(!isOpen)
|
||||
isOpen = true
|
||||
globalErrorHandler.listener = this
|
||||
cryptoService.get().ensureDevice()
|
||||
uiHandler.post {
|
||||
lifecycleObservers.forEach {
|
||||
it.onSessionStarted(this)
|
||||
|
@ -128,7 +128,7 @@ class KeyRequestHandler @Inject constructor(
|
||||
}
|
||||
|
||||
if (deviceInfo.isUnknown) {
|
||||
session?.cryptoService()?.setDeviceVerification(DeviceTrustLevel(crossSigningVerified = false, locallyVerified = false), userId, deviceId)
|
||||
session?.cryptoService()?.verificationService()?.markedLocallyAsManuallyVerified(userId, deviceId)
|
||||
|
||||
deviceInfo.trustLevel = DeviceTrustLevel(crossSigningVerified = false, locallyVerified = false)
|
||||
|
||||
|
@ -132,7 +132,7 @@ class VerificationBottomSheetViewModel @AssistedInject constructor(
|
||||
viewModelScope.launch {
|
||||
|
||||
val hasAnyOtherSession = session.cryptoService()
|
||||
.getCryptoDeviceInfo(session.myUserId)
|
||||
.getCryptoDeviceInfoList(session.myUserId)
|
||||
.any {
|
||||
it.deviceId != session.sessionParams.deviceId
|
||||
}
|
||||
|
@ -155,7 +155,7 @@ class UnknownDeviceDetectorSharedViewModel @AssistedInject constructor(@Assisted
|
||||
}
|
||||
|
||||
private fun Session.firstTimeDeviceSeen() = flow {
|
||||
val value = cryptoService().getCryptoDeviceInfo(myUserId)
|
||||
val value = cryptoService().getCryptoDeviceInfoList(myUserId)
|
||||
.firstOrNull { it.deviceId == sessionParams.deviceId }
|
||||
?.firstTimeSeenLocalTs
|
||||
?: System.currentTimeMillis()
|
||||
|
@ -401,7 +401,7 @@ class MessageActionsViewModel @AssistedInject constructor(@Assisted
|
||||
) {
|
||||
add(EventSharedAction.UseKeyBackup)
|
||||
}
|
||||
if (session.cryptoService().getCryptoDeviceInfo(session.myUserId).size > 1 ||
|
||||
if (session.cryptoService().getCryptoDeviceInfoList(session.myUserId).size > 1 ||
|
||||
timelineEvent.senderInfo.userId != session.myUserId) {
|
||||
add(EventSharedAction.ReRequestKey(timelineEvent.eventId))
|
||||
}
|
||||
|
@ -159,7 +159,7 @@ class MessageInformationDataFactory @Inject constructor(private val session: Ses
|
||||
.toModel<EncryptedEventContent>()
|
||||
?.deviceId
|
||||
?.let { deviceId ->
|
||||
session.cryptoService().getDeviceInfo(event.root.senderId ?: "", deviceId)
|
||||
session.cryptoService().getCryptoDeviceInfo(event.root.senderId ?: "", deviceId)
|
||||
}
|
||||
when {
|
||||
sendingDevice == null -> {
|
||||
|
@ -234,7 +234,7 @@ class DefaultNavigator @Inject constructor(
|
||||
coroutineScope.launch {
|
||||
val session = sessionHolder.getSafeActiveSession() ?: return@launch
|
||||
val otherSessions = session.cryptoService()
|
||||
.getCryptoDeviceInfo(session.myUserId)
|
||||
.getCryptoDeviceInfoList(session.myUserId)
|
||||
.filter { it.deviceId != session.sessionParams.deviceId }
|
||||
.map { it.deviceId }
|
||||
if (context is AppCompatActivity) {
|
||||
|
@ -16,7 +16,6 @@
|
||||
|
||||
package im.vector.app.features.roomprofile.members
|
||||
|
||||
import androidx.lifecycle.asFlow
|
||||
import com.airbnb.mvrx.MavericksViewModelFactory
|
||||
import dagger.assisted.Assisted
|
||||
import dagger.assisted.AssistedFactory
|
||||
@ -94,7 +93,7 @@ class RoomMemberListViewModel @AssistedInject constructor(@Assisted initialState
|
||||
if (room.isEncrypted()) {
|
||||
room.flow().liveRoomMembers(roomMemberQueryParams)
|
||||
.flatMapLatest { membersSummary ->
|
||||
session.cryptoService().getLiveCryptoDeviceInfo(membersSummary.map { it.userId })
|
||||
session.cryptoService().getLiveCryptoDeviceInfoList(membersSummary.map { it.userId })
|
||||
.catch { Timber.e(it) }
|
||||
.map { deviceList ->
|
||||
// If any key change, emit the userIds list
|
||||
|
@ -552,7 +552,7 @@ class VectorSettingsSecurityPrivacyFragment @Inject constructor(
|
||||
}
|
||||
|
||||
// crypto section: device key (fingerprint)
|
||||
val deviceInfo = session.cryptoService().getDeviceInfo(userId, deviceId)
|
||||
val deviceInfo = session.cryptoService().getCryptoDeviceInfo(userId, deviceId)
|
||||
|
||||
val fingerprint = deviceInfo?.fingerprint()
|
||||
if (fingerprint?.isNotEmpty() == true) {
|
||||
|
@ -131,7 +131,7 @@ class CrossSigningSettingsViewModel @AssistedInject constructor(
|
||||
|
||||
private fun observeCrossSigning() {
|
||||
combine(
|
||||
session.flow().liveMyDevicesInfo(),
|
||||
session.flow().liveUserCryptoDevices(session.myUserId),
|
||||
session.flow().liveCrossSigningInfo(session.myUserId)
|
||||
) { myDevicesInfo, mxCrossSigningInfo ->
|
||||
myDevicesInfo to mxCrossSigningInfo
|
||||
|
@ -35,7 +35,6 @@ import im.vector.app.core.utils.PublishDataSource
|
||||
import im.vector.app.features.auth.ReAuthActivity
|
||||
import im.vector.app.features.login.ReAuthHelper
|
||||
import im.vector.lib.core.utils.flow.throttleFirst
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.flow.combine
|
||||
import kotlinx.coroutines.flow.distinctUntilChanged
|
||||
import kotlinx.coroutines.flow.launchIn
|
||||
@ -43,8 +42,6 @@ import kotlinx.coroutines.flow.map
|
||||
import kotlinx.coroutines.flow.onEach
|
||||
import kotlinx.coroutines.flow.sample
|
||||
import kotlinx.coroutines.launch
|
||||
import org.matrix.android.sdk.api.MatrixCallback
|
||||
import org.matrix.android.sdk.api.NoOpMatrixCallback
|
||||
import org.matrix.android.sdk.api.auth.UIABaseAuth
|
||||
import org.matrix.android.sdk.api.auth.UserInteractiveAuthInterceptor
|
||||
import org.matrix.android.sdk.api.auth.UserPasswordAuth
|
||||
@ -53,17 +50,14 @@ import org.matrix.android.sdk.api.auth.registration.RegistrationFlowResponse
|
||||
import org.matrix.android.sdk.api.auth.registration.nextUncompletedStage
|
||||
import org.matrix.android.sdk.api.failure.Failure
|
||||
import org.matrix.android.sdk.api.session.Session
|
||||
import org.matrix.android.sdk.api.session.crypto.verification.VerificationMethod
|
||||
import org.matrix.android.sdk.api.session.crypto.verification.VerificationService
|
||||
import org.matrix.android.sdk.api.session.crypto.verification.VerificationTransaction
|
||||
import org.matrix.android.sdk.api.session.crypto.verification.VerificationTxState
|
||||
import org.matrix.android.sdk.flow.flow
|
||||
import org.matrix.android.sdk.internal.crypto.crosssigning.DeviceTrustLevel
|
||||
import org.matrix.android.sdk.internal.crypto.crosssigning.fromBase64
|
||||
import org.matrix.android.sdk.internal.crypto.model.CryptoDeviceInfo
|
||||
import org.matrix.android.sdk.internal.crypto.model.rest.DefaultBaseAuth
|
||||
import org.matrix.android.sdk.internal.crypto.model.rest.DeviceInfo
|
||||
import org.matrix.android.sdk.internal.util.awaitCallback
|
||||
import timber.log.Timber
|
||||
import javax.net.ssl.HttpsURLConnection
|
||||
import kotlin.coroutines.Continuation
|
||||
@ -277,8 +271,7 @@ class DevicesViewModel @AssistedInject constructor(
|
||||
}
|
||||
} else {
|
||||
// legacy
|
||||
session.cryptoService().setDeviceVerification(
|
||||
DeviceTrustLevel(crossSigningVerified = false, locallyVerified = true),
|
||||
session.cryptoService().verificationService().markedLocallyAsManuallyVerified(
|
||||
action.cryptoDeviceInfo.userId,
|
||||
action.cryptoDeviceInfo.deviceId)
|
||||
}
|
||||
@ -297,27 +290,21 @@ class DevicesViewModel @AssistedInject constructor(
|
||||
}
|
||||
|
||||
private fun handleRename(action: DevicesAction.Rename) {
|
||||
session.cryptoService().setDeviceName(action.deviceId, action.newName, object : MatrixCallback<Unit> {
|
||||
override fun onSuccess(data: Unit) {
|
||||
viewModelScope.launch {
|
||||
try {
|
||||
session.cryptoService().setDeviceName(action.deviceId, action.newName)
|
||||
setState {
|
||||
copy(
|
||||
request = Success(data)
|
||||
)
|
||||
copy(request = Success(Unit))
|
||||
}
|
||||
// force settings update
|
||||
queryRefreshDevicesList()
|
||||
}
|
||||
|
||||
override fun onFailure(failure: Throwable) {
|
||||
} catch (failure: Throwable) {
|
||||
setState {
|
||||
copy(
|
||||
request = Fail(failure)
|
||||
)
|
||||
copy(request = Fail(failure))
|
||||
}
|
||||
|
||||
_viewEvents.post(DevicesViewEvents.Failure(failure))
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@ -332,39 +319,32 @@ class DevicesViewModel @AssistedInject constructor(
|
||||
)
|
||||
}
|
||||
|
||||
viewModelScope.launch(Dispatchers.IO) {
|
||||
viewModelScope.launch {
|
||||
try {
|
||||
awaitCallback<Unit> {
|
||||
session.cryptoService().deleteDevice(deviceId, object : UserInteractiveAuthInterceptor {
|
||||
override fun performStage(flowResponse: RegistrationFlowResponse, errCode: String?, promise: Continuation<UIABaseAuth>) {
|
||||
Timber.d("## UIA : deleteDevice UIA")
|
||||
if (flowResponse.nextUncompletedStage() == LoginFlowTypes.PASSWORD && reAuthHelper.data != null && errCode == null) {
|
||||
UserPasswordAuth(
|
||||
session = null,
|
||||
user = session.myUserId,
|
||||
password = reAuthHelper.data
|
||||
).let { promise.resume(it) }
|
||||
} else {
|
||||
Timber.d("## UIA : deleteDevice UIA > start reauth activity")
|
||||
_viewEvents.post(DevicesViewEvents.RequestReAuth(flowResponse, errCode))
|
||||
pendingAuth = DefaultBaseAuth(session = flowResponse.session)
|
||||
uiaContinuation = promise
|
||||
}
|
||||
session.cryptoService().deleteDevice(deviceId, object : UserInteractiveAuthInterceptor {
|
||||
override fun performStage(flowResponse: RegistrationFlowResponse, errCode: String?, promise: Continuation<UIABaseAuth>) {
|
||||
Timber.d("## UIA : deleteDevice UIA")
|
||||
if (flowResponse.nextUncompletedStage() == LoginFlowTypes.PASSWORD && reAuthHelper.data != null && errCode == null) {
|
||||
UserPasswordAuth(
|
||||
session = null,
|
||||
user = session.myUserId,
|
||||
password = reAuthHelper.data
|
||||
).let { promise.resume(it) }
|
||||
} else {
|
||||
Timber.d("## UIA : deleteDevice UIA > start reauth activity")
|
||||
_viewEvents.post(DevicesViewEvents.RequestReAuth(flowResponse, errCode))
|
||||
pendingAuth = DefaultBaseAuth(session = flowResponse.session)
|
||||
uiaContinuation = promise
|
||||
}
|
||||
}, it)
|
||||
}
|
||||
}
|
||||
})
|
||||
setState {
|
||||
copy(
|
||||
request = Success(Unit)
|
||||
)
|
||||
copy(request = Success(Unit))
|
||||
}
|
||||
// force settings update
|
||||
queryRefreshDevicesList()
|
||||
} catch (failure: Throwable) {
|
||||
setState {
|
||||
copy(
|
||||
request = Fail(failure)
|
||||
)
|
||||
copy(request = Fail(failure))
|
||||
}
|
||||
if (failure is Failure.OtherServerError && failure.httpCode == HttpsURLConnection.HTTP_UNAUTHORIZED) {
|
||||
_viewEvents.post(DevicesViewEvents.Failure(Exception(stringProvider.getString(R.string.authentication_error))))
|
||||
|
@ -30,9 +30,9 @@ class FakeCryptoService : CryptoService by mockk() {
|
||||
|
||||
override fun getLiveCryptoDeviceInfo() = MutableLiveData(cryptoDeviceInfos.values.toList())
|
||||
|
||||
override fun getLiveCryptoDeviceInfo(userId: String) = getLiveCryptoDeviceInfo(listOf(userId))
|
||||
override fun getLiveCryptoDeviceInfoList(userId: String) = getLiveCryptoDeviceInfo(listOf(userId))
|
||||
|
||||
override fun getLiveCryptoDeviceInfo(userIds: List<String>) = MutableLiveData(
|
||||
override fun getLiveCryptoDeviceInfoList(userIds: List<String>) = MutableLiveData(
|
||||
cryptoDeviceInfos.filterKeys { userIds.contains(it) }.values.toList()
|
||||
)
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user