diff --git a/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/internal/crypto/E2eeSanityTests.kt b/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/internal/crypto/E2eeSanityTests.kt index fb98ebe182..14b75e14bf 100644 --- a/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/internal/crypto/E2eeSanityTests.kt +++ b/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/internal/crypto/E2eeSanityTests.kt @@ -546,7 +546,6 @@ class E2eeSanityTests : InstrumentedTest { // now let new session request newBobSession.cryptoService().reRequestRoomKeyForEvent(firstEventNewBobPov.root) - } // We need to wait for the key request to be sent out and then a reply to be received diff --git a/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/internal/crypto/gossiping/KeyShareTests.kt b/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/internal/crypto/gossiping/KeyShareTests.kt index 15b830823e..e5a9092511 100644 --- a/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/internal/crypto/gossiping/KeyShareTests.kt +++ b/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/internal/crypto/gossiping/KeyShareTests.kt @@ -140,13 +140,13 @@ class KeyShareTests : InstrumentedTest { Log.v("TEST", "Incoming request Session 1 (looking for $outGoingRequestId)") Log.v("TEST", "=========================") it.forEach { keyRequest -> - //Log.v("TEST", "[ts${keyRequest.localCreationTimestamp}] requestId ${keyRequest.requestId}, for sessionId ${keyRequest.requestBody?.sessionId} is ${keyRequest.state}") + // Log.v("TEST", "[ts${keyRequest.localCreationTimestamp}] requestId ${keyRequest.requestId}, for sessionId ${keyRequest.requestBody?.sessionId} is ${keyRequest.state}") } Log.v("TEST", "=========================") } - //val incoming = aliceSession.cryptoService().getIncomingRoomKeyRequests().firstOrNull { it.requestId == outGoingRequestId } - //incoming?.state == GossipingRequestState.REJECTED + // val incoming = aliceSession.cryptoService().getIncomingRoomKeyRequests().firstOrNull { it.requestId == outGoingRequestId } + // incoming?.state == GossipingRequestState.REJECTED true } } @@ -175,7 +175,7 @@ class KeyShareTests : InstrumentedTest { Log.v("TEST", "Incoming request Session 1") Log.v("TEST", "=========================") it.forEach { - //Log.v("TEST", "requestId ${it.requestId}, for sessionId ${it.requestBody?.sessionId} is ${it.state}") + // Log.v("TEST", "requestId ${it.requestId}, for sessionId ${it.requestBody?.sessionId} is ${it.state}") } Log.v("TEST", "=========================") @@ -189,7 +189,7 @@ class KeyShareTests : InstrumentedTest { commonTestHelper.waitWithLatch { latch -> commonTestHelper.retryPeriodicallyWithLatch(latch) { aliceSession2.cryptoService().getOutgoingRoomKeyRequests().let { - true//it.any { it.requestBody?.sessionId == eventMegolmSessionId && it.state == OutgoingGossipingRequestState.CANCELLED } + true // it.any { it.requestBody?.sessionId == eventMegolmSessionId && it.state == OutgoingGossipingRequestState.CANCELLED } } } } diff --git a/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/internal/crypto/gossiping/WithHeldTests.kt b/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/internal/crypto/gossiping/WithHeldTests.kt index 01acf3c47e..146ef4806d 100644 --- a/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/internal/crypto/gossiping/WithHeldTests.kt +++ b/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/internal/crypto/gossiping/WithHeldTests.kt @@ -140,7 +140,7 @@ class WithHeldTests : InstrumentedTest { @Test @Ignore("This test will be ignored until it is fixed") - fun test_WithHeldNoOlm() { + fun test_WithHeldNoOlm() { val testData = cryptoTestHelper.doE2ETestWithAliceAndBobInARoom() val aliceSession = testData.firstSession val bobSession = testData.secondSession!! diff --git a/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/internal/crypto/verification/SASTest.kt b/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/internal/crypto/verification/SASTest.kt index 97a9cf7238..bcdbef98c0 100644 --- a/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/internal/crypto/verification/SASTest.kt +++ b/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/internal/crypto/verification/SASTest.kt @@ -40,10 +40,8 @@ import org.matrix.android.sdk.api.session.crypto.verification.VerificationServic 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.api.session.events.model.Event -import org.matrix.android.sdk.api.session.events.model.toModel import org.matrix.android.sdk.common.CommonTestHelper import org.matrix.android.sdk.common.CryptoTestHelper -import org.matrix.android.sdk.internal.crypto.model.rest.toValue import timber.log.Timber import java.util.concurrent.CountDownLatch @@ -322,8 +320,6 @@ class SASTest : InstrumentedTest { */ } - - // any two devices may only have at most one key verification in flight at a time. // If a device has two verifications in progress with the same device, then it should cancel both verifications. @Test diff --git a/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/internal/crypto/verification/SasVerificationTestHelper.kt b/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/internal/crypto/verification/SasVerificationTestHelper.kt index eed502aad0..0077f7386c 100644 --- a/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/internal/crypto/verification/SasVerificationTestHelper.kt +++ b/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/internal/crypto/verification/SasVerificationTestHelper.kt @@ -86,7 +86,6 @@ class SasVerificationTestHelper(private val testHelper: CommonTestHelper, privat } fun requestSelfKeyAndWaitForReadyState(session1: Session, session2: Session, supportedMethods: List): String { - val session1VerificationService = session1.cryptoService().verificationService() val session2VerificationService = session2.cryptoService().verificationService() var bobReadyPendingVerificationRequest: PendingVerificationRequest? = null diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/crypto/model/MXUsersDevicesMap.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/crypto/model/MXUsersDevicesMap.kt index 02f05e6b01..dff4a9e470 100755 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/crypto/model/MXUsersDevicesMap.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/crypto/model/MXUsersDevicesMap.kt @@ -108,7 +108,6 @@ class MXUsersDevicesMap { map.putAll(other) } - /** * Add entries from another MXUsersDevicesMap * diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/crypto/verification/VerificationService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/crypto/verification/VerificationService.kt index 000dd17916..073c7f3352 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/crypto/verification/VerificationService.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/crypto/verification/VerificationService.kt @@ -45,7 +45,6 @@ interface VerificationService { fun getExistingVerificationRequestInRoom(roomId: String, tid: String?): PendingVerificationRequest? - /** * Request an interactive verification to begin * diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/model/message/MessageVerificationAcceptContent.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/model/message/MessageVerificationAcceptContent.kt index d7c9eaabee..21c2f923c4 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/model/message/MessageVerificationAcceptContent.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/model/message/MessageVerificationAcceptContent.kt @@ -30,5 +30,4 @@ internal data class MessageVerificationAcceptContent( ) { val transactionId: String? = relatesTo?.eventId - } diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/model/message/MessageVerificationRequestContent.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/model/message/MessageVerificationRequestContent.kt index 891b6218c8..7752fac1a2 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/model/message/MessageVerificationRequestContent.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/model/message/MessageVerificationRequestContent.kt @@ -18,7 +18,6 @@ package org.matrix.android.sdk.api.session.room.model.message import com.squareup.moshi.Json import com.squareup.moshi.JsonClass import org.matrix.android.sdk.api.session.events.model.Content -import org.matrix.android.sdk.api.session.events.model.toContent import org.matrix.android.sdk.api.session.room.model.relation.RelationDefaultContent @JsonClass(generateAdapter = true) @@ -36,4 +35,3 @@ data class MessageVerificationRequestContent( // Not parsed, but set after, using the eventId val transactionId: String? = null ) : MessageContent - diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/DecryptRoomEventUseCase.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/DecryptRoomEventUseCase.kt index 6d5b7ca884..9b6c8ff576 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/DecryptRoomEventUseCase.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/DecryptRoomEventUseCase.kt @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022 New Vector Ltd + * Copyright (c) 2022 The Matrix.org Foundation C.I.C. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/DefaultCryptoService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/DefaultCryptoService.kt index 5b0483203d..f936af539b 100755 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/DefaultCryptoService.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/DefaultCryptoService.kt @@ -759,7 +759,7 @@ internal class DefaultCryptoService @Inject constructor( } override suspend fun manuallyAcceptRoomKeyRequest(request: IncomingRoomKeyRequest) { - //TODO rust? + // TODO rust? } override fun getIncomingRoomKeyRequests(): List { diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/Device.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/Device.kt index e248d11360..68dd16a369 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/Device.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/Device.kt @@ -24,6 +24,9 @@ import org.matrix.android.sdk.api.session.crypto.model.UnsignedDeviceInfo 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.internal.crypto.network.RequestSender +import org.matrix.android.sdk.internal.crypto.verification.SasVerification +import org.matrix.android.sdk.internal.crypto.verification.VerificationRequest +import org.matrix.android.sdk.internal.crypto.verification.VerificationRequestFactory import org.matrix.android.sdk.internal.crypto.verification.prepareMethods import uniffi.olm.CryptoStoreException import uniffi.olm.OlmMachine @@ -36,20 +39,21 @@ import uniffi.olm.Device as InnerDevice * or to manually verify the device. */ internal class Device( - private val machine: OlmMachine, - private var inner: InnerDevice, - private val sender: RequestSender, + private val innerMachine: OlmMachine, + private var innerDevice: InnerDevice, + private val requestSender: RequestSender, private val coroutineDispatchers: MatrixCoroutineDispatchers, - private val listeners: ArrayList + private val listeners: ArrayList, + private val verificationRequestFactory: VerificationRequestFactory, ) { @Throws(CryptoStoreException::class) private suspend fun refreshData() { val device = withContext(coroutineDispatchers.io) { - machine.getDevice(inner.userId, inner.deviceId) + innerMachine.getDevice(innerDevice.userId, innerDevice.deviceId) } if (device != null) { - inner = device + innerDevice = device } } @@ -68,17 +72,11 @@ internal class Device( suspend fun requestVerification(methods: List): VerificationRequest? { val stringMethods = prepareMethods(methods) val result = withContext(coroutineDispatchers.io) { - machine.requestVerificationWithDevice(inner.userId, inner.deviceId, stringMethods) + innerMachine.requestVerificationWithDevice(innerDevice.userId, innerDevice.deviceId, stringMethods) } return if (result != null) { - sender.sendVerificationRequest(result.request) - VerificationRequest( - machine = machine, - inner = result.verification, - sender = sender, - coroutineDispatchers = coroutineDispatchers, - listeners = listeners - ) + requestSender.sendVerificationRequest(result.request) + verificationRequestFactory.create(result.verification) } else { null } @@ -96,15 +94,15 @@ internal class Device( @Throws(CryptoStoreException::class) suspend fun startVerification(): SasVerification? { val result = withContext(coroutineDispatchers.io) { - machine.startSasWithDevice(inner.userId, inner.deviceId) + innerMachine.startSasWithDevice(innerDevice.userId, innerDevice.deviceId) } return if (result != null) { - sender.sendVerificationRequest(result.request) + requestSender.sendVerificationRequest(result.request) SasVerification( - machine = machine, + machine = innerMachine, inner = result.sas, - sender = sender, + sender = requestSender, coroutineDispatchers = coroutineDispatchers, listeners = listeners ) @@ -122,7 +120,7 @@ internal class Device( @Throws(CryptoStoreException::class) suspend fun markAsTrusted() { withContext(coroutineDispatchers.io) { - machine.markDeviceAsTrusted(inner.userId, inner.deviceId) + innerMachine.markDeviceAsTrusted(innerDevice.userId, innerDevice.deviceId) } } @@ -138,10 +136,10 @@ internal class Device( @Throws(SignatureException::class) suspend fun verify(): Boolean { val request = withContext(coroutineDispatchers.io) { - machine.verifyDevice(inner.userId, inner.deviceId) + innerMachine.verifyDevice(innerDevice.userId, innerDevice.deviceId) } - sender.sendSignatureUpload(request) + requestSender.sendSignatureUpload(request) return true } @@ -152,7 +150,7 @@ internal class Device( @Throws(CryptoStoreException::class) suspend fun trustLevel(): DeviceTrustLevel { refreshData() - return DeviceTrustLevel(crossSigningVerified = inner.crossSigningTrusted, locallyVerified = inner.locallyTrusted) + return DeviceTrustLevel(crossSigningVerified = innerDevice.crossSigningTrusted, locallyVerified = innerDevice.locallyTrusted) } /** @@ -161,19 +159,19 @@ internal class Device( * This will not fetch out fresh data from the Rust side. **/ internal fun toCryptoDeviceInfo(): CryptoDeviceInfo { - val keys = inner.keys.map { (keyId, key) -> "$keyId:$inner.deviceId" to key }.toMap() + val keys = innerDevice.keys.map { (keyId, key) -> "$keyId:$innerDevice.deviceId" to key }.toMap() return CryptoDeviceInfo( - deviceId = inner.deviceId, - userId = inner.userId, - algorithms = inner.algorithms, + deviceId = innerDevice.deviceId, + userId = innerDevice.userId, + algorithms = innerDevice.algorithms, keys = keys, // The Kotlin side doesn't need to care about signatures, // so we're not filling this out signatures = mapOf(), - unsigned = UnsignedDeviceInfo(inner.displayName), - trustLevel = DeviceTrustLevel(crossSigningVerified = inner.crossSigningTrusted, locallyVerified = inner.locallyTrusted), - isBlocked = inner.isBlocked, + unsigned = UnsignedDeviceInfo(innerDevice.displayName), + trustLevel = DeviceTrustLevel(crossSigningVerified = innerDevice.crossSigningTrusted, locallyVerified = innerDevice.locallyTrusted), + isBlocked = innerDevice.isBlocked, // TODO firstTimeSeenLocalTs = null) } diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/EncryptEventContentUseCase.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/EncryptEventContentUseCase.kt index db5168d31c..3ed5f52173 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/EncryptEventContentUseCase.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/EncryptEventContentUseCase.kt @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022 New Vector Ltd + * Copyright (c) 2022 The Matrix.org Foundation C.I.C. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/GetRoomUserIdsUseCase.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/GetRoomUserIdsUseCase.kt index 75d3e8b0bb..a12bf2eb80 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/GetRoomUserIdsUseCase.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/GetRoomUserIdsUseCase.kt @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022 New Vector Ltd + * Copyright (c) 2022 The Matrix.org Foundation C.I.C. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/GetUserIdentityUseCase.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/GetUserIdentityUseCase.kt new file mode 100644 index 0000000000..53e370f1ba --- /dev/null +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/GetUserIdentityUseCase.kt @@ -0,0 +1,89 @@ +/* + * Copyright (c) 2022 The Matrix.org Foundation C.I.C. + * + * 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 + +import com.squareup.moshi.Moshi +import kotlinx.coroutines.withContext +import org.matrix.android.sdk.api.MatrixCoroutineDispatchers +import org.matrix.android.sdk.api.session.crypto.crosssigning.DeviceTrustLevel +import org.matrix.android.sdk.internal.crypto.model.rest.RestKeyInfo +import org.matrix.android.sdk.internal.crypto.network.RequestSender +import org.matrix.android.sdk.internal.crypto.verification.VerificationRequestFactory +import uniffi.olm.CryptoStoreException +import uniffi.olm.OlmMachine + +internal class GetUserIdentityUseCase( + private val innerMachine: OlmMachine, + private val requestSender: RequestSender, + private val coroutineDispatchers: MatrixCoroutineDispatchers, + private val moshi: Moshi, + private val verificationRequestFactory: VerificationRequestFactory +) { + + @Throws(CryptoStoreException::class) + suspend operator fun invoke(userId: String): UserIdentities? { + val identity = withContext(coroutineDispatchers.io) { + innerMachine.getIdentity(userId) + } + val adapter = moshi.adapter(RestKeyInfo::class.java) + + return when (identity) { + is uniffi.olm.UserIdentity.Other -> { + val verified = innerMachine.isIdentityVerified(userId) + val masterKey = adapter.fromJson(identity.masterKey)!!.toCryptoModel().apply { + trustLevel = DeviceTrustLevel(verified, verified) + } + val selfSigningKey = adapter.fromJson(identity.selfSigningKey)!!.toCryptoModel().apply { + trustLevel = DeviceTrustLevel(verified, verified) + } + UserIdentity( + userId = identity.userId, + masterKey = masterKey, + selfSigningKey = selfSigningKey, + innerMachine = innerMachine, + requestSender = requestSender, + coroutineDispatchers = coroutineDispatchers, + verificationRequestFactory = verificationRequestFactory + ) + } + is uniffi.olm.UserIdentity.Own -> { + val verified = innerMachine.isIdentityVerified(userId) + + val masterKey = adapter.fromJson(identity.masterKey)!!.toCryptoModel().apply { + trustLevel = DeviceTrustLevel(verified, verified) + } + val selfSigningKey = adapter.fromJson(identity.selfSigningKey)!!.toCryptoModel().apply { + trustLevel = DeviceTrustLevel(verified, verified) + } + val userSigningKey = adapter.fromJson(identity.userSigningKey)!!.toCryptoModel() + + OwnUserIdentity( + userId = identity.userId, + masterKey = masterKey, + selfSigningKey = selfSigningKey, + userSigningKey = userSigningKey, + trustsOurOwnDevice = identity.trustsOurOwnDevice, + innerMachine = innerMachine, + requestSender = requestSender, + coroutineDispatchers = coroutineDispatchers, + verificationRequestFactory = verificationRequestFactory + ) + } + null -> null + } + } +} diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/OlmMachine.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/OlmMachine.kt index f2dcd3a76f..f45d236d54 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/OlmMachine.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/OlmMachine.kt @@ -49,9 +49,13 @@ import org.matrix.android.sdk.api.util.JsonDict import org.matrix.android.sdk.api.util.Optional import org.matrix.android.sdk.api.util.toOptional import org.matrix.android.sdk.internal.coroutines.builder.safeInvokeOnClose -import org.matrix.android.sdk.internal.crypto.model.rest.RestKeyInfo import org.matrix.android.sdk.internal.crypto.network.RequestSender +import org.matrix.android.sdk.internal.crypto.verification.SasVerification +import org.matrix.android.sdk.internal.crypto.verification.VerificationRequest +import org.matrix.android.sdk.internal.crypto.verification.VerificationRequestFactory +import org.matrix.android.sdk.internal.crypto.verification.qrcode.QrCodeVerification import org.matrix.android.sdk.internal.network.parsing.CheckNumberType +import org.matrix.android.sdk.internal.util.time.Clock import timber.log.Timber import uniffi.olm.BackupKeys import uniffi.olm.CrossSigningKeyExport @@ -71,7 +75,6 @@ import java.nio.charset.Charset import java.util.UUID import uniffi.olm.OlmMachine as InnerMachine import uniffi.olm.ProgressListener as RustProgressListener -import uniffi.olm.UserIdentity as RustUserIdentity class CryptoLogger : Logger { override fun log(logLine: String) { @@ -85,10 +88,11 @@ private class CryptoProgressListener(private val listener: ProgressListener?) : } } -private data class UserIdentityCollector(val userId: String, val collector: SendChannel>) - : SendChannel> by collector -private data class DevicesCollector(val userIds: List, val collector: SendChannel>) - : SendChannel> by collector +private data class UserIdentityCollector(val userId: String, val collector: SendChannel>) : + SendChannel> by collector + +private data class DevicesCollector(val userIds: List, val collector: SendChannel>) : + SendChannel> by collector private typealias PrivateKeysCollector = SendChannel> private class FlowCollectors { @@ -105,12 +109,16 @@ internal class OlmMachine( user_id: String, device_id: String, path: File, + clock: Clock, private val requestSender: RequestSender, private val coroutineDispatchers: MatrixCoroutineDispatchers, - private val moshi: Moshi + private val moshi: Moshi, ) { + private val inner: InnerMachine = InnerMachine(user_id, device_id, path.toString(), null) - internal val verificationListeners = ArrayList() + val verificationListeners = ArrayList() + private val verificationRequestFactory = VerificationRequestFactory(inner, requestSender, coroutineDispatchers, verificationListeners, clock) + private val getUserIdentity = GetUserIdentityUseCase(inner, requestSender, coroutineDispatchers, moshi, verificationRequestFactory) private val flowCollectors = FlowCollectors() /** Get our own user ID. */ @@ -176,7 +184,8 @@ internal class OlmMachine( UnsignedDeviceInfo(), DeviceTrustLevel(crossSigningVerified, locallyVerified = true), false, - null) + null + ) } /** @@ -389,13 +398,15 @@ internal class OlmMachine( clearEvent, decrypted.senderCurve25519Key, decrypted.claimedEd25519Key, - decrypted.forwardingCurve25519Chain) + decrypted.forwardingCurve25519Chain + ) } catch (throwable: Throwable) { val reason = String.format( MXCryptoError.UNABLE_TO_DECRYPT_REASON, throwable.message, - "m.megolm.v1.aes-sha2") + "m.megolm.v1.aes-sha2" + ) throw MXCryptoError.Base(MXCryptoError.ErrorType.UNABLE_TO_DECRYPT, reason) } } @@ -491,55 +502,7 @@ internal class OlmMachine( } @Throws(CryptoStoreException::class) - suspend fun getIdentity(userId: String): UserIdentities? { - val identity = withContext(coroutineDispatchers.io) { - inner.getIdentity(userId) - } - val adapter = moshi.adapter(RestKeyInfo::class.java) - - return when (identity) { - is RustUserIdentity.Other -> { - val verified = inner().isIdentityVerified(userId) - val masterKey = adapter.fromJson(identity.masterKey)!!.toCryptoModel().apply { - trustLevel = DeviceTrustLevel(verified, verified) - } - val selfSigningKey = adapter.fromJson(identity.selfSigningKey)!!.toCryptoModel().apply { - trustLevel = DeviceTrustLevel(verified, verified) - } - UserIdentity( - userId = identity.userId, - masterKey = masterKey, - selfSigningKey = selfSigningKey, - olmMachine = this, - requestSender = requestSender, - coroutineDispatchers = coroutineDispatchers - ) - } - is RustUserIdentity.Own -> { - val verified = inner().isIdentityVerified(userId) - - val masterKey = adapter.fromJson(identity.masterKey)!!.toCryptoModel().apply { - trustLevel = DeviceTrustLevel(verified, verified) - } - val selfSigningKey = adapter.fromJson(identity.selfSigningKey)!!.toCryptoModel().apply { - trustLevel = DeviceTrustLevel(verified, verified) - } - val userSigningKey = adapter.fromJson(identity.userSigningKey)!!.toCryptoModel() - - OwnUserIdentity( - userId = identity.userId, - masterKey = masterKey, - selfSigningKey = selfSigningKey, - userSigningKey = userSigningKey, - trustsOurOwnDevice = identity.trustsOurOwnDevice, - olmMachine = this, - requestSender = requestSender, - coroutineDispatchers = coroutineDispatchers - ) - } - null -> null - } - } + suspend fun getIdentity(userId: String): UserIdentities? = getUserIdentity(userId) /** * Get a `Device` from the store. @@ -559,30 +522,16 @@ internal class OlmMachine( @Throws(CryptoStoreException::class) suspend fun getDevice(userId: String, deviceId: String): Device? { - val device = withContext(coroutineDispatchers.io) { + val innerDevice = withContext(coroutineDispatchers.io) { inner.getDevice(userId, deviceId) } ?: return null - return Device( - machine = inner, - inner = device, - sender = requestSender, - coroutineDispatchers = coroutineDispatchers, - listeners = verificationListeners - ) + return innerDevice.wrap() } suspend fun getUserDevices(userId: String): List { return withContext(coroutineDispatchers.io) { - inner.getUserDevices(userId).map { - Device( - machine = inner, - inner = it, - sender = requestSender, - coroutineDispatchers = coroutineDispatchers, - listeners = verificationListeners - ) - } + inner.getUserDevices(userId).map { innerDevice -> innerDevice.wrap() } } } @@ -743,30 +692,13 @@ internal class OlmMachine( * @return The list of [VerificationRequest] that we share with the given user */ fun getVerificationRequests(userId: String): List { - return inner.getVerificationRequests(userId).map { - VerificationRequest( - machine = inner, - inner = it, - sender = requestSender, - coroutineDispatchers = coroutineDispatchers, - listeners = verificationListeners, - ) - } + return inner.getVerificationRequests(userId).map(verificationRequestFactory::create) } /** Get a verification request for the given user with the given flow ID */ fun getVerificationRequest(userId: String, flowId: String): VerificationRequest? { - val request = inner.getVerificationRequest(userId, flowId) - return if (request != null) { - VerificationRequest( - machine = inner, - inner = request, - sender = requestSender, - coroutineDispatchers = coroutineDispatchers, - listeners = verificationListeners, - ) - } else { - null + return inner.getVerificationRequest(userId, flowId)?.let { innerVerificationRequest -> + verificationRequestFactory.create(innerVerificationRequest) } } @@ -936,4 +868,13 @@ internal class OlmMachine( inner.verifyBackup(serializedAuthData) } } + + private fun uniffi.olm.Device.wrap() = Device( + innerMachine = inner, + innerDevice = this, + requestSender = requestSender, + coroutineDispatchers = coroutineDispatchers, + listeners = verificationListeners, + verificationRequestFactory = verificationRequestFactory + ) } diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/OlmMachineProvider.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/OlmMachineProvider.kt index a46fcddcaf..c3c835ad22 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/OlmMachineProvider.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/OlmMachineProvider.kt @@ -23,24 +23,30 @@ import org.matrix.android.sdk.internal.di.DeviceId import org.matrix.android.sdk.internal.di.SessionFilesDirectory import org.matrix.android.sdk.internal.di.UserId import org.matrix.android.sdk.internal.session.SessionScope +import org.matrix.android.sdk.internal.util.time.Clock import java.io.File import javax.inject.Inject @SessionScope internal class OlmMachineProvider @Inject constructor( - @UserId private val userId: String, - @DeviceId private val deviceId: String?, - @SessionFilesDirectory private val dataDir: File, + @UserId userId: String, + @DeviceId deviceId: String?, + @SessionFilesDirectory dataDir: File, requestSender: RequestSender, coroutineDispatchers: MatrixCoroutineDispatchers, - moshi: Moshi + moshi: Moshi, + clock: Clock ) { - var olmMachine: OlmMachine = OlmMachine( - user_id = userId, - device_id = deviceId!!, - path = dataDir, - requestSender = requestSender, - coroutineDispatchers = coroutineDispatchers, - moshi = moshi) + val olmMachine: OlmMachine by lazy { + OlmMachine( + user_id = userId, + device_id = deviceId!!, + path = dataDir, + clock = clock, + requestSender = requestSender, + coroutineDispatchers = coroutineDispatchers, + moshi = moshi + ) + } } diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/PerSessionBackupQueryRateLimiter.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/PerSessionBackupQueryRateLimiter.kt index 8fcdb4168b..ecbaad20ee 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/PerSessionBackupQueryRateLimiter.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/PerSessionBackupQueryRateLimiter.kt @@ -22,8 +22,6 @@ import org.matrix.android.sdk.api.MatrixCoroutineDispatchers import org.matrix.android.sdk.api.logger.LoggerTag import org.matrix.android.sdk.api.session.crypto.keysbackup.KeysVersionResult import org.matrix.android.sdk.api.session.crypto.keysbackup.SavedKeyBackupKeyInfo -import org.matrix.android.sdk.api.session.crypto.model.ImportRoomKeysResult -import org.matrix.android.sdk.api.util.awaitCallback import org.matrix.android.sdk.internal.crypto.keysbackup.RustKeyBackupService import org.matrix.android.sdk.internal.crypto.store.IMXCryptoStore import org.matrix.android.sdk.internal.util.time.Clock diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/PrepareToEncryptUseCase.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/PrepareToEncryptUseCase.kt index e2245a6e40..806921781e 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/PrepareToEncryptUseCase.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/PrepareToEncryptUseCase.kt @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022 New Vector Ltd + * Copyright (c) 2022 The Matrix.org Foundation C.I.C. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/RustCrossSigningService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/RustCrossSigningService.kt index 68ec92ab98..d3b9b61b8d 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/RustCrossSigningService.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/RustCrossSigningService.kt @@ -207,7 +207,7 @@ internal class RustCrossSigningService @Inject constructor( } override fun onSecretUSKGossip(uskPrivateKey: String) { - // And + // And } override suspend fun shieldForGroup(userIds: List): RoomEncryptionTrustLevel { diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/ShouldEncryptForInvitedMembersUseCase.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/ShouldEncryptForInvitedMembersUseCase.kt index 51e373b1d9..29a550aad3 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/ShouldEncryptForInvitedMembersUseCase.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/ShouldEncryptForInvitedMembersUseCase.kt @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022 New Vector Ltd + * Copyright (c) 2022 The Matrix.org Foundation C.I.C. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/UserIdentities.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/UserIdentities.kt index 3d0c42b878..abfe7263ff 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/UserIdentities.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/UserIdentities.kt @@ -24,8 +24,11 @@ import org.matrix.android.sdk.api.session.crypto.crosssigning.MXCrossSigningInfo 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.network.RequestSender +import org.matrix.android.sdk.internal.crypto.verification.VerificationRequest +import org.matrix.android.sdk.internal.crypto.verification.VerificationRequestFactory import org.matrix.android.sdk.internal.crypto.verification.prepareMethods import uniffi.olm.CryptoStoreException +import uniffi.olm.OlmMachine import uniffi.olm.SignatureException /** @@ -79,9 +82,11 @@ internal class OwnUserIdentity( private val selfSigningKey: CryptoCrossSigningKey, private val userSigningKey: CryptoCrossSigningKey, private val trustsOurOwnDevice: Boolean, - private val olmMachine: OlmMachine, + private val innerMachine: OlmMachine, private val requestSender: RequestSender, - private val coroutineDispatchers: MatrixCoroutineDispatchers) : UserIdentities() { + private val coroutineDispatchers: MatrixCoroutineDispatchers, + private val verificationRequestFactory: VerificationRequestFactory, +) : UserIdentities() { /** * Our own user id. */ @@ -96,7 +101,7 @@ internal class OwnUserIdentity( */ @Throws(SignatureException::class) override suspend fun verify() { - val request = withContext(coroutineDispatchers.computation) { olmMachine.inner().verifyIdentity(userId) } + val request = withContext(coroutineDispatchers.computation) { innerMachine.verifyIdentity(userId) } requestSender.sendSignatureUpload(request) } @@ -107,7 +112,7 @@ internal class OwnUserIdentity( */ @Throws(CryptoStoreException::class) override suspend fun verified(): Boolean { - return withContext(coroutineDispatchers.io) { olmMachine.inner().isIdentityVerified(userId) } + return withContext(coroutineDispatchers.io) { innerMachine.isIdentityVerified(userId) } } /** @@ -134,16 +139,9 @@ internal class OwnUserIdentity( @Throws(CryptoStoreException::class) suspend fun requestVerification(methods: List): VerificationRequest { val stringMethods = prepareMethods(methods) - val result = olmMachine.inner().requestSelfVerification(stringMethods) + val result = innerMachine.requestSelfVerification(stringMethods) requestSender.sendVerificationRequest(result!!.request) - - return VerificationRequest( - machine = olmMachine.inner(), - inner = result.verification, - sender = requestSender, - coroutineDispatchers = coroutineDispatchers, - listeners = olmMachine.verificationListeners - ) + return verificationRequestFactory.create(result.verification) } /** @@ -173,9 +171,11 @@ internal class UserIdentity( private val userId: String, private val masterKey: CryptoCrossSigningKey, private val selfSigningKey: CryptoCrossSigningKey, - private val olmMachine: OlmMachine, + private val innerMachine: OlmMachine, private val requestSender: RequestSender, - private val coroutineDispatchers: MatrixCoroutineDispatchers) : UserIdentities() { + private val coroutineDispatchers: MatrixCoroutineDispatchers, + private val verificationRequestFactory: VerificationRequestFactory, +) : UserIdentities() { /** * The unique ID of the user that this identity belongs to. */ @@ -192,7 +192,7 @@ internal class UserIdentity( */ @Throws(SignatureException::class) override suspend fun verify() { - val request = withContext(coroutineDispatchers.computation) { olmMachine.inner().verifyIdentity(userId) } + val request = withContext(coroutineDispatchers.computation) { innerMachine.verifyIdentity(userId) } requestSender.sendSignatureUpload(request) } @@ -202,7 +202,7 @@ internal class UserIdentity( * @return True if the identity is considered to be verified and trusted, false otherwise. */ override suspend fun verified(): Boolean { - return withContext(coroutineDispatchers.io) { olmMachine.inner().isIdentityVerified(userId) } + return withContext(coroutineDispatchers.io) { innerMachine.isIdentityVerified(userId) } } /** @@ -235,19 +235,10 @@ internal class UserIdentity( transactionId: String ): VerificationRequest { val stringMethods = prepareMethods(methods) - val content = olmMachine.inner().verificationRequestContent(userId, stringMethods)!! - + val content = innerMachine.verificationRequestContent(userId, stringMethods)!! val eventID = requestSender.sendRoomMessage(EventType.MESSAGE, roomId, content, transactionId).eventId - - val innerRequest = olmMachine.inner().requestVerification(userId, roomId, eventID, stringMethods)!! - - return VerificationRequest( - machine = olmMachine.inner(), - inner = innerRequest, - sender = requestSender, - coroutineDispatchers = coroutineDispatchers, - listeners = olmMachine.verificationListeners - ) + val innerRequest = innerMachine.requestVerification(userId, roomId, eventID, stringMethods)!! + return verificationRequestFactory.create(innerRequest) } /** diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/api/CryptoApi.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/api/CryptoApi.kt index b1c6bfbb04..e0e2ba8543 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/api/CryptoApi.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/api/CryptoApi.kt @@ -15,9 +15,9 @@ */ package org.matrix.android.sdk.internal.crypto.api -import org.matrix.android.sdk.api.util.JsonDict import org.matrix.android.sdk.api.session.crypto.model.DeviceInfo import org.matrix.android.sdk.api.session.crypto.model.DevicesListResponse +import org.matrix.android.sdk.api.util.JsonDict import org.matrix.android.sdk.internal.crypto.model.rest.DeleteDeviceParams import org.matrix.android.sdk.internal.crypto.model.rest.KeyChangesResponse import org.matrix.android.sdk.internal.crypto.model.rest.KeysClaimBody diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/network/RequestSender.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/network/RequestSender.kt index 1a480830ce..2b7a1fdff1 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/network/RequestSender.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/network/RequestSender.kt @@ -227,7 +227,7 @@ internal class RequestSender @Inject constructor( getKeysBackupLastVersionTask.executeRetry(Unit, 3) } - private inline fun getKeyBackupVersion(block: ()-> T?): T?{ + private inline fun getKeyBackupVersion(block: () -> T?): T? { return try { block() } catch (failure: Throwable) { diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/verification/RustVerificationService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/verification/RustVerificationService.kt index dd0d526055..6453eba07a 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/verification/RustVerificationService.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/verification/RustVerificationService.kt @@ -30,7 +30,6 @@ import org.matrix.android.sdk.api.session.room.model.message.MessageRelationCont import org.matrix.android.sdk.api.session.room.model.message.MessageType import org.matrix.android.sdk.internal.crypto.OlmMachineProvider import org.matrix.android.sdk.internal.crypto.OwnUserIdentity -import org.matrix.android.sdk.internal.crypto.SasVerification import org.matrix.android.sdk.internal.crypto.UserIdentity import org.matrix.android.sdk.internal.crypto.model.rest.VERIFICATION_METHOD_QR_CODE_SCAN import org.matrix.android.sdk.internal.crypto.model.rest.VERIFICATION_METHOD_QR_CODE_SHOW @@ -254,8 +253,9 @@ internal class RustVerificationService @Inject constructor(private val olmMachin return verification.toPendingVerificationRequest() } - - override suspend fun requestDeviceVerification(methods: List, otherUserId: String, otherDeviceId: String): PendingVerificationRequest? { + override suspend fun requestDeviceVerification(methods: List, + otherUserId: String, + otherDeviceId: String): PendingVerificationRequest? { olmMachine.ensureUsersKeys(listOf(otherUserId)) val otherDevice = olmMachine.getDevice(otherUserId, otherDeviceId) val verificationRequest = otherDevice?.requestVerification(methods) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/SasVerification.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/verification/SasVerification.kt similarity index 95% rename from matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/SasVerification.kt rename to matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/verification/SasVerification.kt index 731e85d01e..c863895d79 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/SasVerification.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/verification/SasVerification.kt @@ -1,5 +1,5 @@ /* - * Copyright 2021 The Matrix.org Foundation C.I.C. + * Copyright (c) 2022 The Matrix.org Foundation C.I.C. * * 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.verification import kotlinx.coroutines.withContext import org.matrix.android.sdk.api.MatrixCoroutineDispatchers @@ -25,8 +25,6 @@ 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.network.RequestSender -import org.matrix.android.sdk.internal.crypto.verification.UpdateDispatcher -import org.matrix.android.sdk.internal.crypto.verification.getEmojiForCode import uniffi.olm.CryptoStoreException import uniffi.olm.OlmMachine import uniffi.olm.Sas @@ -235,6 +233,11 @@ internal class SasVerification( } override fun toString(): String { - return "SasVerification(otherUserId='$otherUserId', otherDeviceId=$otherDeviceId, isIncoming=$isIncoming, state=$state, transactionId='$transactionId')" + return "SasVerification(" + + "otherUserId='$otherUserId', " + + "otherDeviceId=$otherDeviceId, " + + "isIncoming=$isIncoming, " + + "state=$state, " + + "transactionId='$transactionId')" } } diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/VerificationRequest.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/verification/VerificationRequest.kt similarity index 74% rename from matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/VerificationRequest.kt rename to matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/verification/VerificationRequest.kt index aec2495fc7..cda683a4f2 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/VerificationRequest.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/verification/VerificationRequest.kt @@ -1,5 +1,5 @@ /* - * Copyright 2021 The Matrix.org Foundation C.I.C. + * Copyright (c) 2022 The Matrix.org Foundation C.I.C. * * 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.verification import android.os.Handler import android.os.Looper @@ -30,7 +30,8 @@ import org.matrix.android.sdk.api.session.crypto.verification.safeValueOf import org.matrix.android.sdk.api.util.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 org.matrix.android.sdk.internal.crypto.verification.qrcode.QrCodeVerification +import org.matrix.android.sdk.internal.util.time.Clock import timber.log.Timber import uniffi.olm.OlmMachine import uniffi.olm.VerificationRequest @@ -43,11 +44,12 @@ import uniffi.olm.VerificationRequest * concrete verification flows. */ internal class VerificationRequest( - private val machine: OlmMachine, - private var inner: VerificationRequest, - private val sender: RequestSender, + private val innerOlmMachine: OlmMachine, + private var innerVerificationRequest: VerificationRequest, + private val requestSender: RequestSender, private val coroutineDispatchers: MatrixCoroutineDispatchers, - private val listeners: ArrayList + private val listeners: ArrayList, + private val clock: Clock, ) { private val uiHandler = Handler(Looper.getMainLooper()) @@ -70,12 +72,12 @@ internal class VerificationRequest( * event that initiated the flow. */ internal fun flowId(): String { - return inner.flowId + return innerVerificationRequest.flowId } /** The user ID of the other user that is participating in this verification flow */ internal fun otherUser(): String { - return inner.otherUserId + return innerVerificationRequest.otherUserId } /** The device ID of the other user's device that is participating in this verification flow @@ -85,12 +87,12 @@ internal class VerificationRequest( * */ internal fun otherDeviceId(): String? { refreshData() - return inner.otherDeviceId + return innerVerificationRequest.otherDeviceId } /** Did we initiate this verification flow */ internal fun weStarted(): Boolean { - return inner.weStarted + return innerVerificationRequest.weStarted } /** Get the id of the room where this verification is happening @@ -98,7 +100,7 @@ internal class VerificationRequest( * Will be null if the verification is not happening inside a room. */ internal fun roomId(): String? { - return inner.roomId + return innerVerificationRequest.roomId } /** Did the non-initiating side respond with a m.key.verification.read event @@ -109,13 +111,13 @@ internal class VerificationRequest( */ internal fun isReady(): Boolean { refreshData() - return inner.isReady + return innerVerificationRequest.isReady } /** Did we advertise that we're able to scan QR codes */ internal fun canScanQrCodes(): Boolean { refreshData() - return inner.ourMethods?.contains(VERIFICATION_METHOD_QR_CODE_SCAN) ?: false + return innerVerificationRequest.ourMethods?.contains(VERIFICATION_METHOD_QR_CODE_SCAN) ?: false } /** Accept the verification request advertising the given methods as supported @@ -134,14 +136,14 @@ internal class VerificationRequest( suspend fun acceptWithMethods(methods: List) { val stringMethods = prepareMethods(methods) - val request = machine.acceptVerificationRequest( - inner.otherUserId, - inner.flowId, + val request = innerOlmMachine.acceptVerificationRequest( + innerVerificationRequest.otherUserId, + innerVerificationRequest.flowId, stringMethods ) if (request != null) { - sender.sendVerificationRequest(request) + requestSender.sendVerificationRequest(request) dispatchRequestUpdated() } } @@ -161,11 +163,11 @@ internal class VerificationRequest( */ internal suspend fun startSasVerification(): SasVerification? { return withContext(coroutineDispatchers.io) { - val result = machine.startSasVerification(inner.otherUserId, inner.flowId) + val result = innerOlmMachine.startSasVerification(innerVerificationRequest.otherUserId, innerVerificationRequest.flowId) if (result != null) { - sender.sendVerificationRequest(result.request) - SasVerification(machine, result.sas, sender, coroutineDispatchers, listeners) + requestSender.sendVerificationRequest(result.request) + SasVerification(innerOlmMachine, result.sas, requestSender, coroutineDispatchers, listeners) } else { null } @@ -189,10 +191,10 @@ internal class VerificationRequest( // TODO again, what's the deal with ISO_8859_1? val byteArray = data.toByteArray(Charsets.ISO_8859_1) val encodedData = byteArray.toBase64NoPadding() - val result = machine.scanQrCode(otherUser(), flowId(), encodedData) ?: return null + val result = innerOlmMachine.scanQrCode(otherUser(), flowId(), encodedData) ?: return null - sender.sendVerificationRequest(result.request) - return QrCodeVerification(machine, this, result.qr, sender, coroutineDispatchers, listeners) + requestSender.sendVerificationRequest(result.request) + return QrCodeVerification(innerOlmMachine, this, result.qr, requestSender, coroutineDispatchers, listeners) } /** Transition into a QR code verification to display a QR code @@ -213,14 +215,14 @@ internal class VerificationRequest( * QR code verification, or null if we can't yet transition into QR code verification. */ internal fun startQrVerification(): QrCodeVerification? { - val qrcode = machine.startQrVerification(inner.otherUserId, inner.flowId) + val qrcode = innerOlmMachine.startQrVerification(innerVerificationRequest.otherUserId, innerVerificationRequest.flowId) return if (qrcode != null) { QrCodeVerification( - machine = machine, + machine = innerOlmMachine, request = this, inner = qrcode, - sender = sender, + sender = requestSender, coroutineDispatchers = coroutineDispatchers, listeners = listeners, ) @@ -240,24 +242,24 @@ internal class VerificationRequest( * The method turns into a noop, if the verification flow has already been cancelled. */ internal suspend fun cancel() { - val request = machine.cancelVerification( - inner.otherUserId, - inner.flowId, + val request = innerOlmMachine.cancelVerification( + innerVerificationRequest.otherUserId, + innerVerificationRequest.flowId, CancelCode.User.value ) if (request != null) { - sender.sendVerificationRequest(request) + requestSender.sendVerificationRequest(request) dispatchRequestUpdated() } } /** Fetch fresh data from the Rust side for our verification flow */ private fun refreshData() { - val request = machine.getVerificationRequest(inner.otherUserId, inner.flowId) + val request = innerOlmMachine.getVerificationRequest(innerVerificationRequest.otherUserId, innerVerificationRequest.flowId) if (request != null) { - inner = request + innerVerificationRequest = request } } @@ -272,7 +274,7 @@ internal class VerificationRequest( */ internal fun toPendingVerificationRequest(): PendingVerificationRequest { refreshData() - val cancelInfo = inner.cancelInfo + val cancelInfo = innerVerificationRequest.cancelInfo val cancelCode = if (cancelInfo != null) { safeValueOf(cancelInfo.cancelCode) @@ -280,60 +282,60 @@ internal class VerificationRequest( null } - val ourMethods = inner.ourMethods - val theirMethods = inner.theirMethods - val otherDeviceId = inner.otherDeviceId + val ourMethods = innerVerificationRequest.ourMethods + val theirMethods = innerVerificationRequest.theirMethods + val otherDeviceId = innerVerificationRequest.otherDeviceId var requestInfo: ValidVerificationInfoRequest? = null var readyInfo: ValidVerificationInfoReady? = null - if (inner.weStarted && ourMethods != null) { + if (innerVerificationRequest.weStarted && ourMethods != null) { requestInfo = ValidVerificationInfoRequest( - transactionId = inner.flowId, - fromDevice = machine.deviceId(), + transactionId = innerVerificationRequest.flowId, + fromDevice = innerOlmMachine.deviceId(), methods = ourMethods, timestamp = null, ) - } else if (!inner.weStarted && ourMethods != null) { + } else if (!innerVerificationRequest.weStarted && ourMethods != null) { readyInfo = ValidVerificationInfoReady( - transactionId = inner.flowId, - fromDevice = machine.deviceId(), + transactionId = innerVerificationRequest.flowId, + fromDevice = innerOlmMachine.deviceId(), methods = ourMethods, ) } - if (inner.weStarted && theirMethods != null && otherDeviceId != null) { + if (innerVerificationRequest.weStarted && theirMethods != null && otherDeviceId != null) { readyInfo = ValidVerificationInfoReady( - transactionId = inner.flowId, + transactionId = innerVerificationRequest.flowId, fromDevice = otherDeviceId, methods = theirMethods, ) - } else if (!inner.weStarted && theirMethods != null && otherDeviceId != null) { + } else if (!innerVerificationRequest.weStarted && theirMethods != null && otherDeviceId != null) { requestInfo = ValidVerificationInfoRequest( - transactionId = inner.flowId, + transactionId = innerVerificationRequest.flowId, fromDevice = otherDeviceId, methods = theirMethods, - timestamp = System.currentTimeMillis(), + timestamp = clock.epochMillis(), ) } return PendingVerificationRequest( // Creation time - ageLocalTs = System.currentTimeMillis(), + ageLocalTs = clock.epochMillis(), // Who initiated the request - isIncoming = !inner.weStarted, + isIncoming = !innerVerificationRequest.weStarted, // Local echo id, what to do here? - localId = inner.flowId, + localId = innerVerificationRequest.flowId, // other user - otherUserId = inner.otherUserId, + otherUserId = innerVerificationRequest.otherUserId, // room id - roomId = inner.roomId, + roomId = innerVerificationRequest.roomId, // transaction id - transactionId = inner.flowId, + transactionId = innerVerificationRequest.flowId, // val requestInfo: ValidVerificationInfoRequest? = null, requestInfo = requestInfo, // val readyInfo: ValidVerificationInfoReady? = null, @@ -341,9 +343,9 @@ internal class VerificationRequest( // cancel code if there is one cancelConclusion = cancelCode, // are we done/successful - isSuccessful = inner.isDone, + isSuccessful = innerVerificationRequest.isDone, // did another device answer the request - handledByOtherSession = inner.isPassive, + handledByOtherSession = innerVerificationRequest.isPassive, // devices that should receive the events we send out targetDevices = null ) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/verification/VerificationRequestFactory.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/verification/VerificationRequestFactory.kt new file mode 100644 index 0000000000..3826b23d9e --- /dev/null +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/verification/VerificationRequestFactory.kt @@ -0,0 +1,43 @@ +/* + * Copyright (c) 2022 The Matrix.org Foundation C.I.C. + * + * 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.MatrixCoroutineDispatchers +import org.matrix.android.sdk.api.session.crypto.verification.VerificationService +import org.matrix.android.sdk.internal.crypto.network.RequestSender +import org.matrix.android.sdk.internal.util.time.Clock +import uniffi.olm.OlmMachine + +internal class VerificationRequestFactory( + private val innerOlmMachine: OlmMachine, + private val requestSender: RequestSender, + private val coroutineDispatchers: MatrixCoroutineDispatchers, + private val listeners: ArrayList, + private val clock: Clock, +) { + + fun create(inner: uniffi.olm.VerificationRequest): VerificationRequest { + return VerificationRequest( + innerOlmMachine = innerOlmMachine, + innerVerificationRequest = inner, + requestSender = requestSender, + coroutineDispatchers = coroutineDispatchers, + listeners = listeners, + clock = clock + ) + } +} diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/QrCodeVerification.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/verification/qrcode/QrCodeVerification.kt similarity index 94% rename from matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/QrCodeVerification.kt rename to matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/verification/qrcode/QrCodeVerification.kt index a81f4a1bd1..ad9922504c 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/QrCodeVerification.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/verification/qrcode/QrCodeVerification.kt @@ -1,5 +1,5 @@ /* - * Copyright 2021 The Matrix.org Foundation C.I.C. + * Copyright (c) 2022 The Matrix.org Foundation C.I.C. * * 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.verification.qrcode import kotlinx.coroutines.withContext import org.matrix.android.sdk.api.MatrixCoroutineDispatchers @@ -26,6 +26,7 @@ import org.matrix.android.sdk.api.session.crypto.verification.safeValueOf import org.matrix.android.sdk.api.util.fromBase64 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.VerificationRequest import uniffi.olm.CryptoStoreException import uniffi.olm.OlmMachine import uniffi.olm.QrCode @@ -213,6 +214,12 @@ internal class QrCodeVerification( } override fun toString(): String { - return "QrCodeVerification(qrCodeText=$qrCodeText, state=$state, transactionId='$transactionId', otherUserId='$otherUserId', otherDeviceId=$otherDeviceId, isIncoming=$isIncoming)" + return "QrCodeVerification(" + + "qrCodeText=$qrCodeText, " + + "state=$state, " + + "transactionId='$transactionId', " + + "otherUserId='$otherUserId', " + + "otherDeviceId=$otherDeviceId, " + + "isIncoming=$isIncoming)" } } diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/DefaultToDeviceService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/DefaultToDeviceService.kt index f61d444925..1b6883f38a 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/DefaultToDeviceService.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/DefaultToDeviceService.kt @@ -19,10 +19,6 @@ package org.matrix.android.sdk.internal.session import org.matrix.android.sdk.api.session.ToDeviceService import org.matrix.android.sdk.api.session.crypto.model.MXUsersDevicesMap import org.matrix.android.sdk.api.session.events.model.Content -import org.matrix.android.sdk.api.session.events.model.EventType -import org.matrix.android.sdk.internal.crypto.EncryptEventContentUseCase -import org.matrix.android.sdk.internal.crypto.OlmMachineProvider -import org.matrix.android.sdk.internal.crypto.store.IMXCryptoStore import org.matrix.android.sdk.internal.crypto.tasks.SendToDeviceTask import javax.inject.Inject @@ -52,7 +48,7 @@ internal class DefaultToDeviceService @Inject constructor( } override suspend fun sendEncryptedToDevice(eventType: String, targets: Map>, content: Content, txnId: String?) { - //TODO: add to rust-ffi + // TODO: add to rust-ffi /* val payloadJson = mapOf( "type" to eventType, diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/DefaultRoom.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/DefaultRoom.kt index 796906b81e..7326adee4c 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/DefaultRoom.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/DefaultRoom.kt @@ -45,7 +45,6 @@ import org.matrix.android.sdk.api.util.Optional import org.matrix.android.sdk.internal.session.permalinks.ViaParameterFinder import org.matrix.android.sdk.internal.session.room.summary.RoomSummaryDataSource import org.matrix.android.sdk.internal.session.space.DefaultSpace -import java.security.InvalidParameterException internal class DefaultRoom( override val roomId: String, @@ -81,7 +80,6 @@ internal class DefaultRoom( return roomSummaryDataSource.getRoomSummary(roomId) } - override fun asSpace(): Space? { if (roomSummary()?.roomType != RoomType.SPACE) return null return DefaultSpace(this, roomSummaryDataSource, viaParameterFinder) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/summary/RoomSummaryUpdater.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/summary/RoomSummaryUpdater.kt index 22f0647a28..7e54af3cf2 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/summary/RoomSummaryUpdater.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/summary/RoomSummaryUpdater.kt @@ -21,7 +21,6 @@ import io.realm.kotlin.createObject import kotlinx.coroutines.runBlocking import org.matrix.android.sdk.api.extensions.orFalse import org.matrix.android.sdk.api.extensions.tryOrNull -import org.matrix.android.sdk.api.session.crypto.crosssigning.CrossSigningService import org.matrix.android.sdk.api.session.events.model.EventType import org.matrix.android.sdk.api.session.events.model.content.EncryptionEventContent import org.matrix.android.sdk.api.session.events.model.toModel diff --git a/vector/src/main/java/im/vector/app/features/crypto/keysbackup/settings/KeysBackupSettingsViewModel.kt b/vector/src/main/java/im/vector/app/features/crypto/keysbackup/settings/KeysBackupSettingsViewModel.kt index 1554b8cb0b..8ca14e562a 100644 --- a/vector/src/main/java/im/vector/app/features/crypto/keysbackup/settings/KeysBackupSettingsViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/crypto/keysbackup/settings/KeysBackupSettingsViewModel.kt @@ -31,7 +31,6 @@ import org.matrix.android.sdk.api.session.Session import org.matrix.android.sdk.api.session.crypto.keysbackup.KeysBackupService import org.matrix.android.sdk.api.session.crypto.keysbackup.KeysBackupState import org.matrix.android.sdk.api.session.crypto.keysbackup.KeysBackupStateListener -import org.matrix.android.sdk.api.session.crypto.keysbackup.KeysBackupVersionTrust class KeysBackupSettingsViewModel @AssistedInject constructor(@Assisted initialState: KeysBackupSettingViewState, session: Session diff --git a/vector/src/main/java/im/vector/app/features/crypto/keysrequest/KeyRequestHandler.kt b/vector/src/main/java/im/vector/app/features/crypto/keysrequest/KeyRequestHandler.kt index 92cb47105c..55bb0edae5 100644 --- a/vector/src/main/java/im/vector/app/features/crypto/keysrequest/KeyRequestHandler.kt +++ b/vector/src/main/java/im/vector/app/features/crypto/keysrequest/KeyRequestHandler.kt @@ -66,6 +66,7 @@ class KeyRequestHandler @Inject constructor( var session: Session? = null var scope: CoroutineScope? = null + // This functionality is disabled in element for now. As it could be prone to social attacks var enablePromptingForRequest = false diff --git a/vector/src/main/java/im/vector/app/features/crypto/recover/BootstrapSharedViewModel.kt b/vector/src/main/java/im/vector/app/features/crypto/recover/BootstrapSharedViewModel.kt index da8d2466c4..710a9363b0 100644 --- a/vector/src/main/java/im/vector/app/features/crypto/recover/BootstrapSharedViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/crypto/recover/BootstrapSharedViewModel.kt @@ -44,12 +44,10 @@ import org.matrix.android.sdk.api.auth.registration.nextUncompletedStage import org.matrix.android.sdk.api.extensions.tryOrNull import org.matrix.android.sdk.api.failure.Failure import org.matrix.android.sdk.api.session.Session -import org.matrix.android.sdk.api.session.crypto.keysbackup.KeysBackupLastVersionResult import org.matrix.android.sdk.api.session.crypto.keysbackup.extractCurveKeyFromRecoveryKey import org.matrix.android.sdk.api.session.crypto.keysbackup.toKeysVersionResult import org.matrix.android.sdk.api.session.securestorage.RawBytesKeySpec import org.matrix.android.sdk.api.session.uia.DefaultBaseAuth -import org.matrix.android.sdk.api.util.awaitCallback import org.matrix.android.sdk.api.util.fromBase64 import java.io.OutputStream import kotlin.coroutines.Continuation diff --git a/vector/src/main/java/im/vector/app/features/crypto/verification/VerificationBottomSheetViewModel.kt b/vector/src/main/java/im/vector/app/features/crypto/verification/VerificationBottomSheetViewModel.kt index 4910c74e59..e8247c96c5 100644 --- a/vector/src/main/java/im/vector/app/features/crypto/verification/VerificationBottomSheetViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/crypto/verification/VerificationBottomSheetViewModel.kt @@ -460,7 +460,7 @@ class VerificationBottomSheetViewModel @AssistedInject constructor( tx.performAccept() } } - */ + */ // Use this one! setState { copy( diff --git a/vector/src/main/java/im/vector/app/features/home/HomeActivityViewModel.kt b/vector/src/main/java/im/vector/app/features/home/HomeActivityViewModel.kt index 0b7a70699c..90f861cd7d 100644 --- a/vector/src/main/java/im/vector/app/features/home/HomeActivityViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/home/HomeActivityViewModel.kt @@ -42,15 +42,12 @@ import org.matrix.android.sdk.api.auth.data.LoginFlowTypes import org.matrix.android.sdk.api.auth.registration.RegistrationFlowResponse import org.matrix.android.sdk.api.auth.registration.nextUncompletedStage import org.matrix.android.sdk.api.extensions.tryOrNull -import org.matrix.android.sdk.api.session.crypto.model.CryptoDeviceInfo -import org.matrix.android.sdk.api.session.crypto.model.MXUsersDevicesMap import org.matrix.android.sdk.api.session.getUser import org.matrix.android.sdk.api.session.initsync.SyncStatusService import org.matrix.android.sdk.api.session.pushrules.RuleIds import org.matrix.android.sdk.api.session.room.model.Membership import org.matrix.android.sdk.api.session.room.roomSummaryQueryParams import org.matrix.android.sdk.api.settings.LightweightSettingsStorage -import org.matrix.android.sdk.api.util.awaitCallback import org.matrix.android.sdk.api.util.toMatrixItem import org.matrix.android.sdk.flow.flow import timber.log.Timber diff --git a/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/action/MessageActionsViewModel.kt b/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/action/MessageActionsViewModel.kt index 54dad2aef7..af6df377df 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/action/MessageActionsViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/action/MessageActionsViewModel.kt @@ -250,7 +250,7 @@ class MessageActionsViewModel @AssistedInject constructor( } } - private suspend fun actionsForEvent(timelineEvent: TimelineEvent, actionPermissions: ActionPermissions): List { + private suspend fun actionsForEvent(timelineEvent: TimelineEvent, actionPermissions: ActionPermissions): List { val messageContent = timelineEvent.getLastMessageContent() val msgType = messageContent?.msgType