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 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>

View file

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

View file

@ -17,6 +17,7 @@
package org.matrix.android.sdk.internal.session.room.create
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.EventType
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.util.MimeTypes
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.UserId
import org.matrix.android.sdk.internal.network.token.AccessTokenProvider
@ -40,7 +40,7 @@ import javax.inject.Inject
internal class CreateRoomBodyBuilder @Inject constructor(
private val ensureIdentityTokenTask: EnsureIdentityTokenTask,
// private val deviceListManager: DeviceListManager,
private val olmMachineProvider: OlmMachineProvider,
private val cryptoService: CryptoService,
private val identityStore: IdentityStore,
private val fileUploader: FileUploader,
@UserId
@ -181,20 +181,20 @@ internal class CreateRoomBodyBuilder @Inject constructor(
params.invite3pids.isEmpty() &&
params.invitedUserIds.isNotEmpty() &&
params.invitedUserIds.let { userIds ->
val keys = olmMachineProvider.olmMachine.ensureUserDevicesMap(userIds, forceDownload = false)
// deviceListManager.downloadKeys(userIds, forceDownload = false)
val keys = cryptoService.downloadKeys(userIds, forceDownload = false)
// deviceListManager.downloadKeys(userIds, forceDownload = false)
userIds.all { userId ->
keys.map[userId].let { deviceMap ->
if (deviceMap.isNullOrEmpty()) {
// A user has no device, so do not enable encryption
false
} else {
// Check that every user's device have at least one key
deviceMap.values.all { !it.keys.isNullOrEmpty() }
userIds.all { userId ->
keys.map[userId].let { deviceMap ->
if (deviceMap.isNullOrEmpty()) {
// A user has no device, so do not enable encryption
false
} else {
// Check that every user's device have at least one key
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.features.popup.DefaultVectorAlert
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.crypto.keyshare.GossipingRequestListener
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.crosssigning.DeviceTrustLevel
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 timber.log.Timber
import javax.inject.Inject
@ -48,6 +53,7 @@ import javax.inject.Singleton
* depending on user action)
*/
// TODO Do we ever request to users anymore?
@Singleton
class KeyRequestHandler @Inject constructor(
private val context: Context,
@ -60,13 +66,18 @@ class KeyRequestHandler @Inject constructor(
var session: Session? = null
var scope: CoroutineScope? = null
fun start(session: Session) {
this.session = session
scope = CoroutineScope(SupervisorJob() + session.coroutineScope.coroutineContext)
session.cryptoService().verificationService().addListener(this)
session.cryptoService().addRoomKeysRequestListener(this)
}
fun stop() {
scope?.cancel()
scope = null
session?.cryptoService()?.verificationService()?.removeListener(this)
session?.cryptoService()?.removeRoomKeysRequestListener(this)
session = null
@ -104,15 +115,16 @@ class KeyRequestHandler @Inject constructor(
alertsToRequests[mappingKey] = ArrayList<IncomingRoomKeyRequest>().apply { this.add(request) }
// Add a notification for every incoming request
session?.cryptoService()?.downloadKeys(listOf(userId), false, object : MatrixCallback<MXUsersDevicesMap<CryptoDeviceInfo>> {
override fun onSuccess(data: MXUsersDevicesMap<CryptoDeviceInfo>) {
scope?.launch {
try {
val data = session?.cryptoService()?.downloadKeys(listOf(userId), false)
?: return@launch
val deviceInfo = data.getObject(userId, deviceId)
if (null == deviceInfo) {
Timber.e("## displayKeyShareDialog() : No details found for device $userId:$deviceId")
// ignore
return
return@launch
}
if (deviceInfo.isUnknown) {
@ -122,20 +134,23 @@ class KeyRequestHandler @Inject constructor(
// can we get more info on this device?
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 {
postAlert(context, userId, deviceId, true, deviceInfo)
withContext(Dispatchers.Main) {
postAlert(context, userId, deviceId, true, deviceInfo)
}
}
} else {
postAlert(context, userId, deviceId, false, deviceInfo)
withContext(Dispatchers.Main) {
postAlert(context, userId, deviceId, false, deviceInfo)
}
}
}
override fun onFailure(failure: Throwable) {
// ignore
} catch (failure: Throwable) {
Timber.e(failure, "## displayKeyShareDialog : downloadKeys")
}
})
}
}
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.util.toMatrixItem
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 timber.log.Timber
import kotlin.coroutines.Continuation
@ -181,9 +179,7 @@ class HomeActivityViewModel @AssistedInject constructor(
val session = activeSessionHolder.getSafeActiveSession() ?: return@launch
tryOrNull("## MaybeBootstrapCrossSigning: Failed to download keys") {
awaitCallback<MXUsersDevicesMap<CryptoDeviceInfo>> {
session.cryptoService().downloadKeys(listOf(session.myUserId), true, it)
}
session.cryptoService().downloadKeys(listOf(session.myUserId), true)
}
// From there we are up to date with server

View file

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