mirror of
https://github.com/element-hq/element-android
synced 2024-12-22 09:14:58 +03:00
crypto: Move the sendToDevice logic to a common class and use it for verifications
This commit is contained in:
parent
6a79d022c3
commit
aad18ebec7
4 changed files with 272 additions and 244 deletions
|
@ -20,25 +20,16 @@ import android.content.Context
|
||||||
import androidx.annotation.VisibleForTesting
|
import androidx.annotation.VisibleForTesting
|
||||||
import androidx.lifecycle.LiveData
|
import androidx.lifecycle.LiveData
|
||||||
import androidx.paging.PagedList
|
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.CancellationException
|
||||||
import kotlinx.coroutines.CoroutineScope
|
import kotlinx.coroutines.CoroutineScope
|
||||||
import kotlinx.coroutines.coroutineScope
|
import kotlinx.coroutines.async
|
||||||
import kotlinx.coroutines.cancelChildren
|
import kotlinx.coroutines.cancelChildren
|
||||||
|
import kotlinx.coroutines.coroutineScope
|
||||||
import kotlinx.coroutines.joinAll
|
import kotlinx.coroutines.joinAll
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
import kotlinx.coroutines.runBlocking
|
import kotlinx.coroutines.runBlocking
|
||||||
import kotlinx.coroutines.sync.Mutex
|
import kotlinx.coroutines.sync.Mutex
|
||||||
import kotlinx.coroutines.sync.withLock
|
import kotlinx.coroutines.sync.withLock
|
||||||
import kotlinx.coroutines.withContext
|
|
||||||
import org.matrix.android.sdk.api.MatrixCallback
|
import org.matrix.android.sdk.api.MatrixCallback
|
||||||
import org.matrix.android.sdk.api.NoOpMatrixCallback
|
import org.matrix.android.sdk.api.NoOpMatrixCallback
|
||||||
import org.matrix.android.sdk.api.auth.UserInteractiveAuthInterceptor
|
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.RoomHistoryVisibilityContent
|
||||||
import org.matrix.android.sdk.api.session.room.model.RoomMemberContent
|
import org.matrix.android.sdk.api.session.room.model.RoomMemberContent
|
||||||
import org.matrix.android.sdk.api.util.JsonDict
|
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.DefaultCrossSigningService
|
||||||
import org.matrix.android.sdk.internal.crypto.crosssigning.DeviceTrustLevel
|
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.keysbackup.DefaultKeysBackupService
|
||||||
import org.matrix.android.sdk.internal.crypto.model.CryptoDeviceInfo
|
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.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.MXEncryptEventContentResult
|
||||||
import org.matrix.android.sdk.internal.crypto.model.MXUsersDevicesMap
|
import org.matrix.android.sdk.internal.crypto.model.MXUsersDevicesMap
|
||||||
import org.matrix.android.sdk.internal.crypto.model.event.RoomKeyContent
|
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.DeviceInfo
|
||||||
import org.matrix.android.sdk.internal.crypto.model.rest.DevicesListResponse
|
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.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.KeysClaimResponse
|
||||||
import org.matrix.android.sdk.internal.crypto.model.rest.KeysQueryResponse
|
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.repository.WarnOnUnknownDeviceRepository
|
||||||
import org.matrix.android.sdk.internal.crypto.store.IMXCryptoStore
|
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.DeleteDeviceTask
|
||||||
import org.matrix.android.sdk.internal.crypto.tasks.DownloadKeysForUsersTask
|
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.GetDeviceInfoTask
|
||||||
import org.matrix.android.sdk.internal.crypto.tasks.GetDevicesTask
|
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.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.crypto.verification.RustVerificationService
|
||||||
import org.matrix.android.sdk.internal.di.DeviceId
|
import org.matrix.android.sdk.internal.di.DeviceId
|
||||||
import org.matrix.android.sdk.internal.di.MoshiProvider
|
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.extensions.foldToCallback
|
||||||
import org.matrix.android.sdk.internal.session.SessionScope
|
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.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.DeviceListResponse
|
||||||
import org.matrix.android.sdk.internal.session.sync.model.DeviceOneTimeKeysCountSyncResponse
|
import org.matrix.android.sdk.internal.session.sync.model.DeviceOneTimeKeysCountSyncResponse
|
||||||
import org.matrix.android.sdk.internal.session.sync.model.ToDeviceSyncResponse
|
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 timber.log.Timber
|
||||||
import uniffi.olm.Request
|
import uniffi.olm.Request
|
||||||
import uniffi.olm.RequestType
|
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.
|
* 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 isStarting = AtomicBoolean(false)
|
||||||
private val isStarted = AtomicBoolean(false)
|
private val isStarted = AtomicBoolean(false)
|
||||||
|
private val sender = RequestSender(this.sendToDeviceTask)
|
||||||
|
|
||||||
private var olmMachine: OlmMachine? = null
|
private var olmMachine: OlmMachine? = null
|
||||||
// The verification service.
|
// The verification service.
|
||||||
private var verificationService: RustVerificationService? = null
|
private var verificationService: RustVerificationService? = null
|
||||||
|
@ -320,7 +333,7 @@ internal class DefaultCryptoService @Inject constructor(
|
||||||
val machine = OlmMachine(userId, deviceId!!, dataDir, deviceObserver)
|
val machine = OlmMachine(userId, deviceId!!, dataDir, deviceObserver)
|
||||||
this.olmMachine = machine
|
this.olmMachine = machine
|
||||||
this.verificationService =
|
this.verificationService =
|
||||||
RustVerificationService(this.taskExecutor, machine, this.sendToDeviceTask)
|
RustVerificationService(machine, this.sender)
|
||||||
Timber.v(
|
Timber.v(
|
||||||
"## CRYPTO | Successfully started up an Olm machine for " +
|
"## CRYPTO | Successfully started up an Olm machine for " +
|
||||||
"${userId}, ${deviceId}, identity keys: ${this.olmMachine?.identityKeys()}")
|
"${userId}, ${deviceId}, identity keys: ${this.olmMachine?.identityKeys()}")
|
||||||
|
@ -373,7 +386,7 @@ internal class DefaultCryptoService @Inject constructor(
|
||||||
// `ActiveSessionHolder` class in the `setActiveSession()` method. In
|
// `ActiveSessionHolder` class in the `setActiveSession()` method. In
|
||||||
// the `setActiveSession()` method we call the `start()` method of the
|
// the `setActiveSession()` method we call the `start()` method of the
|
||||||
// handlers without first calling 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
|
// The start method of the crypto service isn't part of the
|
||||||
// `CryptoService` interface so it currently can't be called there. I'm
|
// `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,
|
roomId: String,
|
||||||
sessionId: String,
|
sessionId: String,
|
||||||
) {
|
) {
|
||||||
|
@ -791,18 +804,7 @@ internal class DefaultCryptoService @Inject constructor(
|
||||||
}
|
}
|
||||||
|
|
||||||
private suspend fun sendToDevice(request: Request.ToDevice) {
|
private suspend fun sendToDevice(request: Request.ToDevice) {
|
||||||
// TODO this produces floats for the Olm type fields, which
|
this.sender.sendToDevice(request.eventType, request.body)
|
||||||
// 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)
|
|
||||||
olmMachine!!.markRequestAsSent(request.requestId, RequestType.TO_DEVICE, "{}")
|
olmMachine!!.markRequestAsSent(request.requestId, RequestType.TO_DEVICE, "{}")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -27,13 +27,10 @@ import kotlinx.coroutines.withContext
|
||||||
import org.matrix.android.sdk.api.listeners.ProgressListener
|
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.MXCryptoError
|
||||||
import org.matrix.android.sdk.api.session.crypto.verification.CancelCode
|
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.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.ValidVerificationInfoReady
|
||||||
import org.matrix.android.sdk.api.session.crypto.verification.ValidVerificationInfoRequest
|
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.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.Content
|
||||||
import org.matrix.android.sdk.api.session.events.model.Event
|
import org.matrix.android.sdk.api.session.events.model.Event
|
||||||
import org.matrix.android.sdk.api.util.JsonDict
|
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_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_RECIPROCATE
|
||||||
import org.matrix.android.sdk.internal.crypto.model.rest.VERIFICATION_METHOD_SAS
|
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.di.MoshiProvider
|
||||||
import org.matrix.android.sdk.internal.session.sync.model.DeviceListResponse
|
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.DeviceOneTimeKeysCountSyncResponse
|
||||||
|
@ -64,7 +60,7 @@ import uniffi.olm.OutgoingVerificationRequest
|
||||||
import uniffi.olm.ProgressListener as RustProgressListener
|
import uniffi.olm.ProgressListener as RustProgressListener
|
||||||
import uniffi.olm.Request
|
import uniffi.olm.Request
|
||||||
import uniffi.olm.RequestType
|
import uniffi.olm.RequestType
|
||||||
import uniffi.olm.Sas as InnerSas
|
import uniffi.olm.Sas
|
||||||
import uniffi.olm.StartSasResult
|
import uniffi.olm.StartSasResult
|
||||||
import uniffi.olm.VerificationRequest as InnerRequest
|
import uniffi.olm.VerificationRequest as InnerRequest
|
||||||
import uniffi.olm.setLogger
|
import uniffi.olm.setLogger
|
||||||
|
@ -149,7 +145,7 @@ internal class VerificationRequest(
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
fun accept_with_methods(methods: List<VerificationMethod>): OutgoingVerificationRequest? {
|
fun acceptWithMethods(methods: List<VerificationMethod>): OutgoingVerificationRequest? {
|
||||||
val stringMethods: MutableList<String> =
|
val stringMethods: MutableList<String> =
|
||||||
methods
|
methods
|
||||||
.map {
|
.map {
|
||||||
|
@ -185,17 +181,11 @@ internal class VerificationRequest(
|
||||||
return this.inner.isReady
|
return this.inner.isReady
|
||||||
}
|
}
|
||||||
|
|
||||||
suspend fun startSasVerification(): Pair<OutgoingVerificationRequest, SasVerification>? {
|
suspend fun startSasVerification(): StartSasResult? {
|
||||||
refreshData()
|
refreshData()
|
||||||
|
|
||||||
return withContext(Dispatchers.IO) {
|
return withContext(Dispatchers.IO) {
|
||||||
val response = machine.startSasVerification(inner.otherUserId, inner.flowId)
|
machine.startSasVerification(inner.otherUserId, inner.flowId)
|
||||||
|
|
||||||
if (response != null) {
|
|
||||||
Pair(response.request, SasVerification(machine, response.sas))
|
|
||||||
} else {
|
|
||||||
null
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -280,7 +270,7 @@ internal class VerificationRequest(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun toCancelCode(cancelCode: RustCancelCode): CancelCode {
|
internal fun toCancelCode(cancelCode: RustCancelCode): CancelCode {
|
||||||
return when (cancelCode) {
|
return when (cancelCode) {
|
||||||
RustCancelCode.USER -> CancelCode.User
|
RustCancelCode.USER -> CancelCode.User
|
||||||
RustCancelCode.TIMEOUT -> CancelCode.Timeout
|
RustCancelCode.TIMEOUT -> CancelCode.Timeout
|
||||||
|
@ -290,162 +280,11 @@ private fun toCancelCode(cancelCode: RustCancelCode): CancelCode {
|
||||||
RustCancelCode.KEY_MISMATCH -> CancelCode.MismatchedKeys
|
RustCancelCode.KEY_MISMATCH -> CancelCode.MismatchedKeys
|
||||||
RustCancelCode.USER_MISMATCH -> CancelCode.MismatchedKeys
|
RustCancelCode.USER_MISMATCH -> CancelCode.MismatchedKeys
|
||||||
RustCancelCode.INVALID_MESSAGE -> CancelCode.InvalidMessage
|
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
|
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(
|
internal class OlmMachine(
|
||||||
user_id: String,
|
user_id: String,
|
||||||
device_id: String,
|
device_id: String,
|
||||||
|
@ -470,6 +309,10 @@ internal class OlmMachine(
|
||||||
return this.inner.identityKeys()
|
return this.inner.identityKeys()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun inner(): InnerMachine {
|
||||||
|
return this.inner
|
||||||
|
}
|
||||||
|
|
||||||
fun ownDevice(): CryptoDeviceInfo {
|
fun ownDevice(): CryptoDeviceInfo {
|
||||||
val deviceId = this.deviceId()
|
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.
|
* 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
|
* @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
|
* @param deviceChanges The list of devices that have changed in some way since the previous
|
||||||
* sync.
|
* 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
|
* **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.
|
* 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
|
* 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.
|
* 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.
|
* 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
|
* @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 */
|
/** Get an active verification */
|
||||||
fun getVerification(userId: String, flowId: String): SasVerification? {
|
fun getVerification(userId: String, flowId: String): Sas? {
|
||||||
val sas = this.inner.getVerification(userId, flowId)
|
return this.inner.getVerification(userId, flowId)
|
||||||
|
|
||||||
return if (sas == null) {
|
|
||||||
null
|
|
||||||
} else {
|
|
||||||
SasVerification(this.inner, sas)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
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(" ") ?: ""
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -18,9 +18,7 @@ package org.matrix.android.sdk.internal.crypto.verification
|
||||||
|
|
||||||
import android.os.Handler
|
import android.os.Handler
|
||||||
import android.os.Looper
|
import android.os.Looper
|
||||||
import kotlinx.coroutines.flow.flow
|
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
import kotlin.collections.set
|
|
||||||
import kotlinx.coroutines.runBlocking
|
import kotlinx.coroutines.runBlocking
|
||||||
import org.matrix.android.sdk.api.session.crypto.verification.PendingVerificationRequest
|
import org.matrix.android.sdk.api.session.crypto.verification.PendingVerificationRequest
|
||||||
import org.matrix.android.sdk.api.session.crypto.verification.VerificationMethod
|
import org.matrix.android.sdk.api.session.crypto.verification.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.events.model.toModel
|
||||||
import org.matrix.android.sdk.api.session.room.model.message.MessageType
|
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.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.KeyVerificationDone
|
||||||
import org.matrix.android.sdk.internal.crypto.model.rest.KeyVerificationKey
|
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.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.session.SessionScope
|
||||||
import org.matrix.android.sdk.internal.task.TaskExecutor
|
|
||||||
import timber.log.Timber
|
import timber.log.Timber
|
||||||
import uniffi.olm.OutgoingVerificationRequest
|
import uniffi.olm.OutgoingVerificationRequest
|
||||||
|
|
||||||
|
@ -46,9 +42,8 @@ import uniffi.olm.OutgoingVerificationRequest
|
||||||
internal class RustVerificationService
|
internal class RustVerificationService
|
||||||
@Inject
|
@Inject
|
||||||
constructor(
|
constructor(
|
||||||
private val taskExecutor: TaskExecutor,
|
|
||||||
private val olmMachine: OlmMachine,
|
private val olmMachine: OlmMachine,
|
||||||
private val sendToDeviceTask: SendToDeviceTask,
|
private val requestSender: RequestSender,
|
||||||
) : DefaultVerificationTransaction.Listener, VerificationService {
|
) : DefaultVerificationTransaction.Listener, VerificationService {
|
||||||
|
|
||||||
private val uiHandler = Handler(Looper.getMainLooper())
|
private val uiHandler = Handler(Looper.getMainLooper())
|
||||||
|
@ -91,7 +86,7 @@ constructor(
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun dispatchRequestAdded(tx: PendingVerificationRequest) {
|
private fun dispatchRequestAdded(tx: PendingVerificationRequest) {
|
||||||
Timber.v("## SAS dispatchRequestAdded txId:${tx.transactionId} ${tx}")
|
Timber.v("## SAS dispatchRequestAdded txId:${tx.transactionId} $tx")
|
||||||
uiHandler.post {
|
uiHandler.post {
|
||||||
listeners.forEach {
|
listeners.forEach {
|
||||||
try {
|
try {
|
||||||
|
@ -188,7 +183,9 @@ constructor(
|
||||||
otherUserId: String,
|
otherUserId: String,
|
||||||
tid: String,
|
tid: String,
|
||||||
): VerificationTransaction? {
|
): 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(
|
override fun getExistingVerificationRequests(
|
||||||
|
@ -204,13 +201,7 @@ constructor(
|
||||||
tid: String?
|
tid: String?
|
||||||
): PendingVerificationRequest? {
|
): PendingVerificationRequest? {
|
||||||
return if (tid != null) {
|
return if (tid != null) {
|
||||||
val request = this.olmMachine.getVerificationRequest(otherUserId, tid)
|
olmMachine.getVerificationRequest(otherUserId, tid)?.toPendingVerificationRequest()
|
||||||
|
|
||||||
if (request != null) {
|
|
||||||
request.toPendingVerificationRequest()
|
|
||||||
} else {
|
|
||||||
null
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
null
|
null
|
||||||
}
|
}
|
||||||
|
@ -236,9 +227,10 @@ constructor(
|
||||||
runBlocking {
|
runBlocking {
|
||||||
val response = request?.startSasVerification()
|
val response = request?.startSasVerification()
|
||||||
if (response != null) {
|
if (response != null) {
|
||||||
sendRequest(response.first)
|
sendRequest(response.request)
|
||||||
dispatchTxAdded(response.second)
|
val sas = SasVerification(olmMachine.inner(), response.sas, requestSender, listeners)
|
||||||
response.second.transactionId
|
dispatchTxAdded(sas)
|
||||||
|
sas.transactionId
|
||||||
} else {
|
} else {
|
||||||
null
|
null
|
||||||
}
|
}
|
||||||
|
@ -315,7 +307,7 @@ constructor(
|
||||||
val request = this.olmMachine.getVerificationRequest(otherUserId, transactionId)
|
val request = this.olmMachine.getVerificationRequest(otherUserId, transactionId)
|
||||||
|
|
||||||
return if (request != null) {
|
return if (request != null) {
|
||||||
val outgoingRequest = request.accept_with_methods(methods)
|
val outgoingRequest = request.acceptWithMethods(methods)
|
||||||
|
|
||||||
if (outgoingRequest != null) {
|
if (outgoingRequest != null) {
|
||||||
runBlocking { sendRequest(outgoingRequest) }
|
runBlocking { sendRequest(outgoingRequest) }
|
||||||
|
@ -335,16 +327,7 @@ constructor(
|
||||||
suspend fun sendRequest(request: OutgoingVerificationRequest) {
|
suspend fun sendRequest(request: OutgoingVerificationRequest) {
|
||||||
when (request) {
|
when (request) {
|
||||||
is OutgoingVerificationRequest.ToDevice -> {
|
is OutgoingVerificationRequest.ToDevice -> {
|
||||||
val adapter =
|
this.requestSender.sendToDevice(request.eventType, request.body)
|
||||||
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)
|
|
||||||
}
|
}
|
||||||
else -> {}
|
else -> {}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue