crypto: Move the sendToDevice logic to a common class and use it for verifications

This commit is contained in:
Damir Jelić 2021-06-24 13:58:59 +02:00
parent 6a79d022c3
commit aad18ebec7
4 changed files with 272 additions and 244 deletions

View file

@ -20,25 +20,16 @@ import android.content.Context
import androidx.annotation.VisibleForTesting
import androidx.lifecycle.LiveData
import androidx.paging.PagedList
import com.squareup.moshi.Types
import dagger.Lazy
import java.io.File
import java.util.concurrent.atomic.AtomicBoolean
import java.util.concurrent.ConcurrentHashMap
import javax.inject.Inject
import kotlin.jvm.Throws
import kotlin.math.max
import kotlinx.coroutines.async
import kotlinx.coroutines.CancellationException
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.coroutineScope
import kotlinx.coroutines.async
import kotlinx.coroutines.cancelChildren
import kotlinx.coroutines.coroutineScope
import kotlinx.coroutines.joinAll
import kotlinx.coroutines.launch
import kotlinx.coroutines.runBlocking
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.NoOpMatrixCallback
import org.matrix.android.sdk.api.auth.UserInteractiveAuthInterceptor
@ -59,14 +50,11 @@ import org.matrix.android.sdk.api.session.room.model.RoomHistoryVisibility
import org.matrix.android.sdk.api.session.room.model.RoomHistoryVisibilityContent
import org.matrix.android.sdk.api.session.room.model.RoomMemberContent
import org.matrix.android.sdk.api.util.JsonDict
import org.matrix.android.sdk.internal.crypto.OlmMachine
import org.matrix.android.sdk.internal.crypto.setRustLogger
import org.matrix.android.sdk.internal.crypto.crosssigning.DefaultCrossSigningService
import org.matrix.android.sdk.internal.crypto.crosssigning.DeviceTrustLevel
import org.matrix.android.sdk.internal.crypto.keysbackup.DefaultKeysBackupService
import org.matrix.android.sdk.internal.crypto.model.CryptoDeviceInfo
import org.matrix.android.sdk.internal.crypto.model.ImportRoomKeysResult
import org.matrix.android.sdk.internal.crypto.model.MXDeviceInfo
import org.matrix.android.sdk.internal.crypto.model.MXEncryptEventContentResult
import org.matrix.android.sdk.internal.crypto.model.MXUsersDevicesMap
import org.matrix.android.sdk.internal.crypto.model.event.RoomKeyContent
@ -74,19 +62,19 @@ import org.matrix.android.sdk.internal.crypto.model.event.RoomKeyWithHeldContent
import org.matrix.android.sdk.internal.crypto.model.rest.DeviceInfo
import org.matrix.android.sdk.internal.crypto.model.rest.DevicesListResponse
import org.matrix.android.sdk.internal.crypto.model.rest.ForwardedRoomKeyContent
import org.matrix.android.sdk.internal.crypto.model.rest.KeysUploadResponse
import org.matrix.android.sdk.internal.crypto.model.rest.KeysClaimResponse
import org.matrix.android.sdk.internal.crypto.model.rest.KeysQueryResponse
import org.matrix.android.sdk.internal.crypto.model.rest.KeysUploadResponse
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.ClaimOneTimeKeysForUsersDeviceTask
import org.matrix.android.sdk.internal.crypto.tasks.DeleteDeviceTask
import org.matrix.android.sdk.internal.crypto.tasks.DownloadKeysForUsersTask
import org.matrix.android.sdk.internal.crypto.tasks.GetDeviceInfoTask
import org.matrix.android.sdk.internal.crypto.tasks.GetDevicesTask
import org.matrix.android.sdk.internal.crypto.tasks.UploadKeysTask
import org.matrix.android.sdk.internal.crypto.tasks.SetDeviceNameTask
import org.matrix.android.sdk.internal.crypto.tasks.SendToDeviceTask
import org.matrix.android.sdk.internal.crypto.tasks.ClaimOneTimeKeysForUsersDeviceTask
import org.matrix.android.sdk.internal.crypto.tasks.SetDeviceNameTask
import org.matrix.android.sdk.internal.crypto.tasks.UploadKeysTask
import org.matrix.android.sdk.internal.crypto.verification.RustVerificationService
import org.matrix.android.sdk.internal.di.DeviceId
import org.matrix.android.sdk.internal.di.MoshiProvider
@ -95,7 +83,6 @@ import org.matrix.android.sdk.internal.di.UserId
import org.matrix.android.sdk.internal.extensions.foldToCallback
import org.matrix.android.sdk.internal.session.SessionScope
import org.matrix.android.sdk.internal.session.room.membership.LoadRoomMembersTask
import org.matrix.android.sdk.internal.session.sync.model.SyncResponse
import org.matrix.android.sdk.internal.session.sync.model.DeviceListResponse
import org.matrix.android.sdk.internal.session.sync.model.DeviceOneTimeKeysCountSyncResponse
import org.matrix.android.sdk.internal.session.sync.model.ToDeviceSyncResponse
@ -107,6 +94,30 @@ import org.matrix.android.sdk.internal.util.MatrixCoroutineDispatchers
import timber.log.Timber
import uniffi.olm.Request
import uniffi.olm.RequestType
import java.io.File
import java.util.concurrent.ConcurrentHashMap
import java.util.concurrent.atomic.AtomicBoolean
import javax.inject.Inject
import kotlin.math.max
internal class RequestSender(
private val sendToDeviceTask: SendToDeviceTask,
) {
suspend fun sendToDevice(eventType: String, body: String) {
// TODO this produces floats for the Olm type fields, which
// are integers originally.
val adapter = MoshiProvider
.providesMoshi()
.adapter<Map<String, HashMap<String, Any>>>(Map::class.java)
val jsonBody = adapter.fromJson(body)!!
val userMap = MXUsersDevicesMap<Any>()
userMap.join(jsonBody)
val sendToDeviceParams = SendToDeviceTask.Params(eventType, userMap)
sendToDeviceTask.execute(sendToDeviceParams)
}
}
/**
* A `CryptoService` class instance manages the end-to-end crypto for a session.
@ -153,6 +164,8 @@ internal class DefaultCryptoService @Inject constructor(
private val isStarting = AtomicBoolean(false)
private val isStarted = AtomicBoolean(false)
private val sender = RequestSender(this.sendToDeviceTask)
private var olmMachine: OlmMachine? = null
// The verification service.
private var verificationService: RustVerificationService? = null
@ -320,7 +333,7 @@ internal class DefaultCryptoService @Inject constructor(
val machine = OlmMachine(userId, deviceId!!, dataDir, deviceObserver)
this.olmMachine = machine
this.verificationService =
RustVerificationService(this.taskExecutor, machine, this.sendToDeviceTask)
RustVerificationService(machine, this.sender)
Timber.v(
"## CRYPTO | Successfully started up an Olm machine for " +
"${userId}, ${deviceId}, identity keys: ${this.olmMachine?.identityKeys()}")
@ -373,7 +386,7 @@ internal class DefaultCryptoService @Inject constructor(
// `ActiveSessionHolder` class in the `setActiveSession()` method. In
// the `setActiveSession()` method we call the `start()` method of the
// handlers without first calling the `start()` method of the
// `DefaultCrytpoService`.
// `DefaultCryptoService`.
//
// The start method of the crypto service isn't part of the
// `CryptoService` interface so it currently can't be called there. I'm
@ -666,7 +679,7 @@ internal class DefaultCryptoService @Inject constructor(
}
}
private fun notifyRoomKeyReceival(
private fun notifyRoomKeyReceived(
roomId: String,
sessionId: String,
) {
@ -791,18 +804,7 @@ internal class DefaultCryptoService @Inject constructor(
}
private suspend fun sendToDevice(request: Request.ToDevice) {
// TODO this produces floats for the Olm type fields, which
// are integers originally.
val adapter = MoshiProvider
.providesMoshi()
.adapter<Map<String, HashMap<String, Any>>>(Map::class.java)
val body = adapter.fromJson(request.body)!!
val userMap = MXUsersDevicesMap<Any>()
userMap.join(body)
val sendToDeviceParams = SendToDeviceTask.Params(request.eventType, userMap)
sendToDeviceTask.execute(sendToDeviceParams)
this.sender.sendToDevice(request.eventType, request.body)
olmMachine!!.markRequestAsSent(request.requestId, RequestType.TO_DEVICE, "{}")
}

View file

@ -27,13 +27,10 @@ import kotlinx.coroutines.withContext
import org.matrix.android.sdk.api.listeners.ProgressListener
import org.matrix.android.sdk.api.session.crypto.MXCryptoError
import org.matrix.android.sdk.api.session.crypto.verification.CancelCode
import org.matrix.android.sdk.api.session.crypto.verification.EmojiRepresentation
import org.matrix.android.sdk.api.session.crypto.verification.PendingVerificationRequest
import org.matrix.android.sdk.api.session.crypto.verification.SasVerificationTransaction
import org.matrix.android.sdk.api.session.crypto.verification.ValidVerificationInfoReady
import org.matrix.android.sdk.api.session.crypto.verification.ValidVerificationInfoRequest
import org.matrix.android.sdk.api.session.crypto.verification.VerificationMethod
import org.matrix.android.sdk.api.session.crypto.verification.VerificationTxState
import org.matrix.android.sdk.api.session.events.model.Content
import org.matrix.android.sdk.api.session.events.model.Event
import org.matrix.android.sdk.api.util.JsonDict
@ -46,7 +43,6 @@ import org.matrix.android.sdk.internal.crypto.model.rest.VERIFICATION_METHOD_QR_
import org.matrix.android.sdk.internal.crypto.model.rest.VERIFICATION_METHOD_QR_CODE_SHOW
import org.matrix.android.sdk.internal.crypto.model.rest.VERIFICATION_METHOD_RECIPROCATE
import org.matrix.android.sdk.internal.crypto.model.rest.VERIFICATION_METHOD_SAS
import org.matrix.android.sdk.internal.crypto.verification.getEmojiForCode
import org.matrix.android.sdk.internal.di.MoshiProvider
import org.matrix.android.sdk.internal.session.sync.model.DeviceListResponse
import org.matrix.android.sdk.internal.session.sync.model.DeviceOneTimeKeysCountSyncResponse
@ -64,7 +60,7 @@ import uniffi.olm.OutgoingVerificationRequest
import uniffi.olm.ProgressListener as RustProgressListener
import uniffi.olm.Request
import uniffi.olm.RequestType
import uniffi.olm.Sas as InnerSas
import uniffi.olm.Sas
import uniffi.olm.StartSasResult
import uniffi.olm.VerificationRequest as InnerRequest
import uniffi.olm.setLogger
@ -149,7 +145,7 @@ internal class VerificationRequest(
return
}
fun accept_with_methods(methods: List<VerificationMethod>): OutgoingVerificationRequest? {
fun acceptWithMethods(methods: List<VerificationMethod>): OutgoingVerificationRequest? {
val stringMethods: MutableList<String> =
methods
.map {
@ -185,17 +181,11 @@ internal class VerificationRequest(
return this.inner.isReady
}
suspend fun startSasVerification(): Pair<OutgoingVerificationRequest, SasVerification>? {
suspend fun startSasVerification(): StartSasResult? {
refreshData()
return withContext(Dispatchers.IO) {
val response = machine.startSasVerification(inner.otherUserId, inner.flowId)
if (response != null) {
Pair(response.request, SasVerification(machine, response.sas))
} else {
null
}
machine.startSasVerification(inner.otherUserId, inner.flowId)
}
}
@ -280,7 +270,7 @@ internal class VerificationRequest(
}
}
private fun toCancelCode(cancelCode: RustCancelCode): CancelCode {
internal fun toCancelCode(cancelCode: RustCancelCode): CancelCode {
return when (cancelCode) {
RustCancelCode.USER -> CancelCode.User
RustCancelCode.TIMEOUT -> CancelCode.Timeout
@ -290,162 +280,11 @@ private fun toCancelCode(cancelCode: RustCancelCode): CancelCode {
RustCancelCode.KEY_MISMATCH -> CancelCode.MismatchedKeys
RustCancelCode.USER_MISMATCH -> CancelCode.MismatchedKeys
RustCancelCode.INVALID_MESSAGE -> CancelCode.InvalidMessage
// TODO why don't the ruma codes match what's in EA?
// TODO why don't the Ruma codes match what's in EA?
RustCancelCode.ACCEPTED -> CancelCode.User
}
}
public class SasVerification(private val machine: InnerMachine, private var inner: InnerSas) :
SasVerificationTransaction {
private var stateField: VerificationTxState = VerificationTxState.OnStarted
private fun refreshData() {
val sas = this.machine.getVerification(this.inner.otherUserId, this.inner.flowId)
if (sas != null) {
this.inner = sas
}
return
}
override val isIncoming: Boolean
get() {
return false
}
override var otherDeviceId: String?
get() {
return this.inner.otherDeviceId
}
set(value) {
if (value != null) {
this.inner.otherDeviceId = value
}
}
override val otherUserId: String
get() {
return this.inner.otherUserId
}
override var state: VerificationTxState
get() {
refreshData()
return when {
this.inner.canBePresented -> {
VerificationTxState.ShortCodeReady
}
this.inner.isCancelled -> {
// TODO fetch the cancel code from the rust side
VerificationTxState.Cancelled(CancelCode.User, false)
}
this.inner.isDone -> {
VerificationTxState.Verified
}
else -> {
VerificationTxState.Started
}
}
}
set(v) {
this.stateField = v
}
override val transactionId: String
get() {
return this.inner.flowId
}
override fun cancel() {
TODO()
}
override fun cancel(code: CancelCode) {
TODO()
}
override fun shortCodeDoesNotMatch() {
TODO()
}
override fun isToDeviceTransport(): Boolean {
return false
}
override fun supportsDecimal(): Boolean {
// This is ignored anyways, throw it away?
// The spec also mandates that devices support
// at least decimal and the rust-sdk cancels if
// devices don't support it
return true
}
override fun supportsEmoji(): Boolean {
refreshData()
return this.inner.supportsEmoji
}
override fun userHasVerifiedShortCode() {
// This is confirm
TODO()
}
fun isCanceled(): Boolean {
refreshData()
return this.inner.isCancelled
}
fun isDone(): Boolean {
refreshData()
return this.inner.isDone
}
fun timedOut(): Boolean {
refreshData()
return this.inner.timedOut
}
fun canBePresented(): Boolean {
refreshData()
return this.inner.canBePresented
}
fun accept(): OutgoingVerificationRequest? {
return this.machine.acceptSasVerification(this.inner.otherUserId, inner.flowId)
}
@Throws(CryptoStoreErrorException::class)
suspend fun confirm(): OutgoingVerificationRequest? =
withContext(Dispatchers.IO) {
machine.confirmVerification(inner.otherUserId, inner.flowId)
}
fun cancelHelper(): OutgoingVerificationRequest? {
return this.machine.cancelVerification(this.inner.otherUserId, inner.flowId)
}
override fun getEmojiCodeRepresentation(): List<EmojiRepresentation> {
val emojiIndex = this.machine.getEmojiIndex(this.inner.otherUserId, this.inner.flowId)
return if (emojiIndex != null) {
emojiIndex.map { getEmojiForCode(it) }
} else {
listOf()
}
}
override fun getDecimalCodeRepresentation(): String {
val decimals = this.machine.getDecimals(this.inner.otherUserId, this.inner.flowId)
return if (decimals != null) {
decimals.joinToString(" ")
} else {
""
}
}
}
internal class OlmMachine(
user_id: String,
device_id: String,
@ -470,6 +309,10 @@ internal class OlmMachine(
return this.inner.identityKeys()
}
fun inner(): InnerMachine {
return this.inner
}
fun ownDevice(): CryptoDeviceInfo {
val deviceId = this.deviceId()
@ -528,7 +371,7 @@ internal class OlmMachine(
* This needs to be called after every sync, ideally before processing any other sync changes.
*
* @param toDevice A serialized array of to-device events we received in the current sync
* resposne.
* response.
*
* @param deviceChanges The list of devices that have changed in some way since the previous
* sync.
@ -613,7 +456,7 @@ internal class OlmMachine(
* **Note**: A room key needs to be shared with the group of users that are members in the given
* room. If this is not done this method will panic.
*
* The usual flow to encrypt an evnet using this state machine is as follows:
* The usual flow to encrypt an event using this state machine is as follows:
*
* 1. Get the one-time key claim request to establish 1:1 Olm sessions for
* ```
@ -629,7 +472,7 @@ internal class OlmMachine(
*
* 4. Send the encrypted event to the server.
*
* After the room key is shared steps 1 and 2 will become noops, unless there's some changes in
* After the room key is shared steps 1 and 2 will become no-ops, unless there's some changes in
* the room membership or in the list of devices a member has.
*
* @param roomId the ID of the room where the encrypted event will be sent to
@ -865,13 +708,7 @@ internal class OlmMachine(
}
/** Get an active verification */
fun getVerification(userId: String, flowId: String): SasVerification? {
val sas = this.inner.getVerification(userId, flowId)
return if (sas == null) {
null
} else {
SasVerification(this.inner, sas)
}
fun getVerification(userId: String, flowId: String): Sas? {
return this.inner.getVerification(userId, flowId)
}
}

View file

@ -1,2 +1,208 @@
/*
* Copyright (c) 2021 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
import android.os.Handler
import android.os.Looper
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.runBlocking
import kotlinx.coroutines.withContext
import org.matrix.android.sdk.api.session.crypto.verification.CancelCode
import org.matrix.android.sdk.api.session.crypto.verification.EmojiRepresentation
import org.matrix.android.sdk.api.session.crypto.verification.SasVerificationTransaction
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.internal.crypto.verification.getEmojiForCode
import timber.log.Timber
import uniffi.olm.CryptoStoreErrorException
import uniffi.olm.OlmMachine
import uniffi.olm.OutgoingVerificationRequest
import uniffi.olm.Sas
internal class SasVerification(
private val machine: OlmMachine,
private var inner: Sas,
private val sender: RequestSender,
private val listeners: ArrayList<VerificationService.Listener>,
) :
SasVerificationTransaction {
private val uiHandler = Handler(Looper.getMainLooper())
private var stateField: VerificationTxState = VerificationTxState.OnStarted
private fun dispatchTxUpdated() {
uiHandler.post {
listeners.forEach {
try {
it.transactionUpdated(this)
} catch (e: Throwable) {
Timber.e(e, "## Error while notifying listeners")
}
}
}
}
private fun refreshData() {
val sas = this.machine.getVerification(this.inner.otherUserId, this.inner.flowId)
if (sas != null) {
this.inner = sas
}
return
}
override val isIncoming: Boolean
get() {
return false
}
override var otherDeviceId: String?
get() {
return this.inner.otherDeviceId
}
set(value) {
if (value != null) {
this.inner.otherDeviceId = value
}
}
override val otherUserId: String
get() {
return this.inner.otherUserId
}
override var state: VerificationTxState
get() {
refreshData()
return when {
this.inner.isDone -> VerificationTxState.Verified
this.inner.haveWeConfirmed -> VerificationTxState.ShortCodeAccepted
this.inner.canBePresented -> VerificationTxState.ShortCodeReady
this.inner.isCancelled -> {
val rustCancelCode = this.inner.cancelCode
val cancelCode =
if (rustCancelCode != null) {
toCancelCode(rustCancelCode)
} else {
CancelCode.UnexpectedMessage
}
// TODO get byMe from the rust side
VerificationTxState.Cancelled(cancelCode, false)
}
else -> {
VerificationTxState.Started
}
}
}
set(v) {
this.stateField = v
}
override val transactionId: String
get() {
return this.inner.flowId
}
override fun cancel() {
TODO()
}
override fun cancel(code: CancelCode) {
TODO()
}
override fun shortCodeDoesNotMatch() {
TODO()
}
override fun isToDeviceTransport(): Boolean {
return false
}
override fun supportsDecimal(): Boolean {
// This is ignored anyways, throw it away?
// The spec also mandates that devices support
// at least decimal and the rust-sdk cancels if
// devices don't support it
return true
}
override fun supportsEmoji(): Boolean {
refreshData()
return this.inner.supportsEmoji
}
override fun userHasVerifiedShortCode() {
runBlocking {
when (val request = confirm()) {
is OutgoingVerificationRequest.ToDevice -> {
sender.sendToDevice(request.eventType, request.body)
}
else -> {}
}
}
refreshData()
dispatchTxUpdated()
}
fun isCanceled(): Boolean {
refreshData()
return this.inner.isCancelled
}
fun isDone(): Boolean {
refreshData()
return this.inner.isDone
}
fun timedOut(): Boolean {
refreshData()
return this.inner.timedOut
}
fun canBePresented(): Boolean {
refreshData()
return this.inner.canBePresented
}
fun accept(): OutgoingVerificationRequest? {
return this.machine.acceptSasVerification(this.inner.otherUserId, inner.flowId)
}
@Throws(CryptoStoreErrorException::class)
suspend fun confirm(): OutgoingVerificationRequest? =
withContext(Dispatchers.IO) {
machine.confirmVerification(inner.otherUserId, inner.flowId)
}
fun cancelHelper(): OutgoingVerificationRequest? {
return this.machine.cancelVerification(this.inner.otherUserId, inner.flowId)
}
override fun getEmojiCodeRepresentation(): List<EmojiRepresentation> {
val emojiIndex = this.machine.getEmojiIndex(this.inner.otherUserId, this.inner.flowId)
return emojiIndex?.map { getEmojiForCode(it) } ?: listOf()
}
override fun getDecimalCodeRepresentation(): String {
val decimals = this.machine.getDecimals(this.inner.otherUserId, this.inner.flowId)
return decimals?.joinToString(" ") ?: ""
}
}

View file

@ -18,9 +18,7 @@ package org.matrix.android.sdk.internal.crypto.verification
import android.os.Handler
import android.os.Looper
import kotlinx.coroutines.flow.flow
import javax.inject.Inject
import kotlin.collections.set
import kotlinx.coroutines.runBlocking
import org.matrix.android.sdk.api.session.crypto.verification.PendingVerificationRequest
import org.matrix.android.sdk.api.session.crypto.verification.VerificationMethod
@ -31,14 +29,12 @@ import org.matrix.android.sdk.api.session.events.model.EventType
import org.matrix.android.sdk.api.session.events.model.toModel
import org.matrix.android.sdk.api.session.room.model.message.MessageType
import org.matrix.android.sdk.internal.crypto.OlmMachine
import org.matrix.android.sdk.internal.crypto.model.MXUsersDevicesMap
import org.matrix.android.sdk.internal.crypto.RequestSender
import org.matrix.android.sdk.internal.crypto.SasVerification
import org.matrix.android.sdk.internal.crypto.model.rest.KeyVerificationDone
import org.matrix.android.sdk.internal.crypto.model.rest.KeyVerificationKey
import org.matrix.android.sdk.internal.crypto.model.rest.KeyVerificationRequest
import org.matrix.android.sdk.internal.crypto.tasks.SendToDeviceTask
import org.matrix.android.sdk.internal.di.MoshiProvider
import org.matrix.android.sdk.internal.session.SessionScope
import org.matrix.android.sdk.internal.task.TaskExecutor
import timber.log.Timber
import uniffi.olm.OutgoingVerificationRequest
@ -46,9 +42,8 @@ import uniffi.olm.OutgoingVerificationRequest
internal class RustVerificationService
@Inject
constructor(
private val taskExecutor: TaskExecutor,
private val olmMachine: OlmMachine,
private val sendToDeviceTask: SendToDeviceTask,
private val requestSender: RequestSender,
) : DefaultVerificationTransaction.Listener, VerificationService {
private val uiHandler = Handler(Looper.getMainLooper())
@ -91,7 +86,7 @@ constructor(
}
private fun dispatchRequestAdded(tx: PendingVerificationRequest) {
Timber.v("## SAS dispatchRequestAdded txId:${tx.transactionId} ${tx}")
Timber.v("## SAS dispatchRequestAdded txId:${tx.transactionId} $tx")
uiHandler.post {
listeners.forEach {
try {
@ -188,7 +183,9 @@ constructor(
otherUserId: String,
tid: String,
): VerificationTransaction? {
return this.olmMachine.getVerification(otherUserId, tid)
val verification = this.olmMachine.getVerification(otherUserId, tid) ?: return null
return SasVerification(this.olmMachine.inner(), verification, this.requestSender, this.listeners)
}
override fun getExistingVerificationRequests(
@ -204,13 +201,7 @@ constructor(
tid: String?
): PendingVerificationRequest? {
return if (tid != null) {
val request = this.olmMachine.getVerificationRequest(otherUserId, tid)
if (request != null) {
request.toPendingVerificationRequest()
} else {
null
}
olmMachine.getVerificationRequest(otherUserId, tid)?.toPendingVerificationRequest()
} else {
null
}
@ -236,9 +227,10 @@ constructor(
runBlocking {
val response = request?.startSasVerification()
if (response != null) {
sendRequest(response.first)
dispatchTxAdded(response.second)
response.second.transactionId
sendRequest(response.request)
val sas = SasVerification(olmMachine.inner(), response.sas, requestSender, listeners)
dispatchTxAdded(sas)
sas.transactionId
} else {
null
}
@ -315,7 +307,7 @@ constructor(
val request = this.olmMachine.getVerificationRequest(otherUserId, transactionId)
return if (request != null) {
val outgoingRequest = request.accept_with_methods(methods)
val outgoingRequest = request.acceptWithMethods(methods)
if (outgoingRequest != null) {
runBlocking { sendRequest(outgoingRequest) }
@ -335,16 +327,7 @@ constructor(
suspend fun sendRequest(request: OutgoingVerificationRequest) {
when (request) {
is OutgoingVerificationRequest.ToDevice -> {
val adapter =
MoshiProvider.providesMoshi()
.adapter<Map<String, HashMap<String, Any>>>(Map::class.java)
val body = adapter.fromJson(request.body)!!
val userMap = MXUsersDevicesMap<Any>()
userMap.join(body)
val sendToDeviceParams = SendToDeviceTask.Params(request.eventType, userMap)
sendToDeviceTask.execute(sendToDeviceParams)
this.requestSender.sendToDevice(request.eventType, request.body)
}
else -> {}
}