use crypto service in CreateRoomBodyBuilder

This commit is contained in:
Valere 2021-11-25 16:57:03 +01:00
parent 893e6e3962
commit 46ba0eec9f
6 changed files with 57 additions and 41 deletions

View file

@ -119,7 +119,7 @@ interface CryptoService {
fun shouldEncryptForInvitedMembers(roomId: String): Boolean fun shouldEncryptForInvitedMembers(roomId: String): Boolean
fun downloadKeys(userIds: List<String>, forceDownload: Boolean, callback: MatrixCallback<MXUsersDevicesMap<CryptoDeviceInfo>>) suspend fun downloadKeys(userIds: List<String>, forceDownload: Boolean = false): MXUsersDevicesMap<CryptoDeviceInfo>
fun getCryptoDeviceInfo(userId: String): List<CryptoDeviceInfo> fun getCryptoDeviceInfo(userId: String): List<CryptoDeviceInfo>

View file

@ -30,6 +30,7 @@ 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.MatrixCoroutineDispatchers import org.matrix.android.sdk.api.MatrixCoroutineDispatchers
import org.matrix.android.sdk.api.NoOpMatrixCallback import org.matrix.android.sdk.api.NoOpMatrixCallback
@ -178,7 +179,13 @@ internal class DefaultCryptoService @Inject constructor(
this.callback = object : MatrixCallback<Unit> { this.callback = object : MatrixCallback<Unit> {
override fun onSuccess(data: Unit) { override fun onSuccess(data: Unit) {
// bg refresh of crypto device // bg refresh of crypto device
downloadKeys(listOf(userId), true, NoOpMatrixCallback()) cryptoCoroutineScope.launch {
try {
downloadKeys(listOf(userId), true)
} catch (failure: Throwable) {
Timber.w(failure, "setDeviceName: Failed to refresh of crypto device")
}
}
callback.onSuccess(data) callback.onSuccess(data)
} }
@ -1005,11 +1012,9 @@ internal class DefaultCryptoService @Inject constructor(
// TODO // TODO
} }
override fun downloadKeys(userIds: List<String>, forceDownload: Boolean, callback: MatrixCallback<MXUsersDevicesMap<CryptoDeviceInfo>>) { override suspend fun downloadKeys(userIds: List<String>, forceDownload: Boolean): MXUsersDevicesMap<CryptoDeviceInfo> {
cryptoCoroutineScope.launch(coroutineDispatchers.crypto) { return withContext(coroutineDispatchers.crypto) {
runCatching { olmMachine.ensureUserDevicesMap(userIds, forceDownload)
olmMachine.ensureUserDevicesMap(userIds, forceDownload)
}.foldToCallback(callback)
} }
} }

View file

@ -17,6 +17,7 @@
package org.matrix.android.sdk.internal.session.room.create package org.matrix.android.sdk.internal.session.room.create
import org.matrix.android.sdk.api.extensions.tryOrNull import org.matrix.android.sdk.api.extensions.tryOrNull
import org.matrix.android.sdk.api.session.crypto.CryptoService
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.session.events.model.EventType import org.matrix.android.sdk.api.session.events.model.EventType
import org.matrix.android.sdk.api.session.identity.IdentityServiceError import org.matrix.android.sdk.api.session.identity.IdentityServiceError
@ -24,7 +25,6 @@ import org.matrix.android.sdk.api.session.identity.toMedium
import org.matrix.android.sdk.api.session.room.model.create.CreateRoomParams import org.matrix.android.sdk.api.session.room.model.create.CreateRoomParams
import org.matrix.android.sdk.api.util.MimeTypes import org.matrix.android.sdk.api.util.MimeTypes
import org.matrix.android.sdk.internal.crypto.MXCRYPTO_ALGORITHM_MEGOLM import org.matrix.android.sdk.internal.crypto.MXCRYPTO_ALGORITHM_MEGOLM
import org.matrix.android.sdk.internal.crypto.OlmMachineProvider
import org.matrix.android.sdk.internal.di.AuthenticatedIdentity import org.matrix.android.sdk.internal.di.AuthenticatedIdentity
import org.matrix.android.sdk.internal.di.UserId import org.matrix.android.sdk.internal.di.UserId
import org.matrix.android.sdk.internal.network.token.AccessTokenProvider import org.matrix.android.sdk.internal.network.token.AccessTokenProvider
@ -40,7 +40,7 @@ import javax.inject.Inject
internal class CreateRoomBodyBuilder @Inject constructor( internal class CreateRoomBodyBuilder @Inject constructor(
private val ensureIdentityTokenTask: EnsureIdentityTokenTask, private val ensureIdentityTokenTask: EnsureIdentityTokenTask,
// private val deviceListManager: DeviceListManager, // private val deviceListManager: DeviceListManager,
private val olmMachineProvider: OlmMachineProvider, private val cryptoService: CryptoService,
private val identityStore: IdentityStore, private val identityStore: IdentityStore,
private val fileUploader: FileUploader, private val fileUploader: FileUploader,
@UserId @UserId
@ -181,20 +181,20 @@ internal class CreateRoomBodyBuilder @Inject constructor(
params.invite3pids.isEmpty() && params.invite3pids.isEmpty() &&
params.invitedUserIds.isNotEmpty() && params.invitedUserIds.isNotEmpty() &&
params.invitedUserIds.let { userIds -> params.invitedUserIds.let { userIds ->
val keys = olmMachineProvider.olmMachine.ensureUserDevicesMap(userIds, forceDownload = false) val keys = cryptoService.downloadKeys(userIds, forceDownload = false)
// deviceListManager.downloadKeys(userIds, forceDownload = false) // deviceListManager.downloadKeys(userIds, forceDownload = false)
userIds.all { userId -> userIds.all { userId ->
keys.map[userId].let { deviceMap -> keys.map[userId].let { deviceMap ->
if (deviceMap.isNullOrEmpty()) { if (deviceMap.isNullOrEmpty()) {
// A user has no device, so do not enable encryption // A user has no device, so do not enable encryption
false false
} else { } else {
// Check that every user's device have at least one key // Check that every user's device have at least one key
deviceMap.values.all { !it.keys.isNullOrEmpty() } deviceMap.values.all { !it.keys.isNullOrEmpty() }
}
}
} }
} }
}
}
} }
} }

View file

@ -22,7 +22,13 @@ import im.vector.app.core.date.DateFormatKind
import im.vector.app.core.date.VectorDateFormatter import im.vector.app.core.date.VectorDateFormatter
import im.vector.app.features.popup.DefaultVectorAlert import im.vector.app.features.popup.DefaultVectorAlert
import im.vector.app.features.popup.PopupAlertManager import im.vector.app.features.popup.PopupAlertManager
import org.matrix.android.sdk.api.MatrixCallback import im.vector.app.features.session.coroutineScope
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.SupervisorJob
import kotlinx.coroutines.cancel
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import org.matrix.android.sdk.api.session.Session import org.matrix.android.sdk.api.session.Session
import org.matrix.android.sdk.api.session.crypto.keyshare.GossipingRequestListener import org.matrix.android.sdk.api.session.crypto.keyshare.GossipingRequestListener
import org.matrix.android.sdk.api.session.crypto.verification.SasVerificationTransaction import org.matrix.android.sdk.api.session.crypto.verification.SasVerificationTransaction
@ -34,7 +40,6 @@ import org.matrix.android.sdk.internal.crypto.IncomingRoomKeyRequest
import org.matrix.android.sdk.internal.crypto.IncomingSecretShareRequest import org.matrix.android.sdk.internal.crypto.IncomingSecretShareRequest
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.model.CryptoDeviceInfo import org.matrix.android.sdk.internal.crypto.model.CryptoDeviceInfo
import org.matrix.android.sdk.internal.crypto.model.MXUsersDevicesMap
import org.matrix.android.sdk.internal.crypto.model.rest.DeviceInfo import org.matrix.android.sdk.internal.crypto.model.rest.DeviceInfo
import timber.log.Timber import timber.log.Timber
import javax.inject.Inject import javax.inject.Inject
@ -48,6 +53,7 @@ import javax.inject.Singleton
* depending on user action) * depending on user action)
*/ */
// TODO Do we ever request to users anymore?
@Singleton @Singleton
class KeyRequestHandler @Inject constructor( class KeyRequestHandler @Inject constructor(
private val context: Context, private val context: Context,
@ -60,13 +66,18 @@ class KeyRequestHandler @Inject constructor(
var session: Session? = null var session: Session? = null
var scope: CoroutineScope? = null
fun start(session: Session) { fun start(session: Session) {
this.session = session this.session = session
scope = CoroutineScope(SupervisorJob() + session.coroutineScope.coroutineContext)
session.cryptoService().verificationService().addListener(this) session.cryptoService().verificationService().addListener(this)
session.cryptoService().addRoomKeysRequestListener(this) session.cryptoService().addRoomKeysRequestListener(this)
} }
fun stop() { fun stop() {
scope?.cancel()
scope = null
session?.cryptoService()?.verificationService()?.removeListener(this) session?.cryptoService()?.verificationService()?.removeListener(this)
session?.cryptoService()?.removeRoomKeysRequestListener(this) session?.cryptoService()?.removeRoomKeysRequestListener(this)
session = null session = null
@ -104,15 +115,16 @@ class KeyRequestHandler @Inject constructor(
alertsToRequests[mappingKey] = ArrayList<IncomingRoomKeyRequest>().apply { this.add(request) } alertsToRequests[mappingKey] = ArrayList<IncomingRoomKeyRequest>().apply { this.add(request) }
// Add a notification for every incoming request scope?.launch {
session?.cryptoService()?.downloadKeys(listOf(userId), false, object : MatrixCallback<MXUsersDevicesMap<CryptoDeviceInfo>> { try {
override fun onSuccess(data: MXUsersDevicesMap<CryptoDeviceInfo>) { val data = session?.cryptoService()?.downloadKeys(listOf(userId), false)
?: return@launch
val deviceInfo = data.getObject(userId, deviceId) val deviceInfo = data.getObject(userId, deviceId)
if (null == deviceInfo) { if (null == deviceInfo) {
Timber.e("## displayKeyShareDialog() : No details found for device $userId:$deviceId") Timber.e("## displayKeyShareDialog() : No details found for device $userId:$deviceId")
// ignore // ignore
return return@launch
} }
if (deviceInfo.isUnknown) { if (deviceInfo.isUnknown) {
@ -122,20 +134,23 @@ class KeyRequestHandler @Inject constructor(
// can we get more info on this device? // can we get more info on this device?
session?.cryptoService()?.getMyDevicesInfo()?.firstOrNull { it.deviceId == deviceId }?.let { session?.cryptoService()?.getMyDevicesInfo()?.firstOrNull { it.deviceId == deviceId }?.let {
postAlert(context, userId, deviceId, true, deviceInfo, it) withContext(Dispatchers.Main) {
postAlert(context, userId, deviceId, true, deviceInfo, it)
}
} ?: run { } ?: run {
postAlert(context, userId, deviceId, true, deviceInfo) withContext(Dispatchers.Main) {
postAlert(context, userId, deviceId, true, deviceInfo)
}
} }
} else { } else {
postAlert(context, userId, deviceId, false, deviceInfo) withContext(Dispatchers.Main) {
postAlert(context, userId, deviceId, false, deviceInfo)
}
} }
} } catch (failure: Throwable) {
override fun onFailure(failure: Throwable) {
// ignore
Timber.e(failure, "## displayKeyShareDialog : downloadKeys") Timber.e(failure, "## displayKeyShareDialog : downloadKeys")
} }
}) }
} }
private fun postAlert(context: Context, private fun postAlert(context: Context,

View file

@ -47,8 +47,6 @@ 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.session.room.roomSummaryQueryParams
import org.matrix.android.sdk.api.util.toMatrixItem import org.matrix.android.sdk.api.util.toMatrixItem
import org.matrix.android.sdk.flow.flow import org.matrix.android.sdk.flow.flow
import org.matrix.android.sdk.internal.crypto.model.CryptoDeviceInfo
import org.matrix.android.sdk.internal.crypto.model.MXUsersDevicesMap
import org.matrix.android.sdk.internal.util.awaitCallback import org.matrix.android.sdk.internal.util.awaitCallback
import timber.log.Timber import timber.log.Timber
import kotlin.coroutines.Continuation import kotlin.coroutines.Continuation
@ -181,9 +179,7 @@ class HomeActivityViewModel @AssistedInject constructor(
val session = activeSessionHolder.getSafeActiveSession() ?: return@launch val session = activeSessionHolder.getSafeActiveSession() ?: return@launch
tryOrNull("## MaybeBootstrapCrossSigning: Failed to download keys") { tryOrNull("## MaybeBootstrapCrossSigning: Failed to download keys") {
awaitCallback<MXUsersDevicesMap<CryptoDeviceInfo>> { session.cryptoService().downloadKeys(listOf(session.myUserId), true)
session.cryptoService().downloadKeys(listOf(session.myUserId), true, it)
}
} }
// From there we are up to date with server // From there we are up to date with server

View file

@ -169,7 +169,7 @@ class DevicesViewModel @AssistedInject constructor(
refreshSource.stream().throttleFirst(4_000) refreshSource.stream().throttleFirst(4_000)
.onEach { .onEach {
session.cryptoService().fetchDevicesList(NoOpMatrixCallback()) session.cryptoService().fetchDevicesList(NoOpMatrixCallback())
session.cryptoService().downloadKeys(listOf(session.myUserId), true, NoOpMatrixCallback()) session.cryptoService().downloadKeys(listOf(session.myUserId), true)
} }
.launchIn(viewModelScope) .launchIn(viewModelScope)
// then force download // then force download