- Share only the first chunk of inbound sessions instead of the whole key history
- Download keys if the user is unknown (first invite)
This commit is contained in:
parent
e861edd544
commit
b3bfd05ecb
@ -40,6 +40,7 @@ import org.matrix.android.sdk.api.session.crypto.verification.VerificationServic
|
||||
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.content.RoomKeyWithHeldContent
|
||||
import org.matrix.android.sdk.internal.database.helper.SessionInfoPair
|
||||
|
||||
interface CryptoService {
|
||||
|
||||
@ -178,7 +179,12 @@ interface CryptoService {
|
||||
fun prepareToEncrypt(roomId: String, callback: MatrixCallback<Unit>)
|
||||
|
||||
/**
|
||||
* Share existing inbound sessions with the provided userId devices
|
||||
* Share all existing inbound sessions to the provided userId devices
|
||||
*/
|
||||
fun sendSharedHistoryKeys(roomId: String, userId: String)
|
||||
|
||||
/**
|
||||
* Share all inbound sessions of the last chunk messages to the provided userId devices
|
||||
*/
|
||||
fun sendSharedHistoryKeysToLastChunk(roomId: String, userId: String, sessionInfoSet: Set<SessionInfoPair>?)
|
||||
}
|
||||
|
@ -92,6 +92,7 @@ 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.DefaultVerificationService
|
||||
import org.matrix.android.sdk.internal.crypto.verification.VerificationMessageProcessor
|
||||
import org.matrix.android.sdk.internal.database.helper.SessionInfoPair
|
||||
import org.matrix.android.sdk.internal.di.DeviceId
|
||||
import org.matrix.android.sdk.internal.di.MoshiProvider
|
||||
import org.matrix.android.sdk.internal.di.UserId
|
||||
@ -1337,6 +1338,34 @@ internal class DefaultCryptoService @Inject constructor(
|
||||
}
|
||||
}
|
||||
|
||||
override fun sendSharedHistoryKeysToLastChunk(roomId: String, userId: String, sessionInfoSet: Set<SessionInfoPair>?) {
|
||||
cryptoCoroutineScope.launch(coroutineDispatchers.crypto) {
|
||||
runCatching {
|
||||
deviceListManager.downloadKeys(listOf(userId), false)
|
||||
}.mapCatching {
|
||||
val userDevices = cryptoStore.getUserDevices(userId)
|
||||
userDevices?.forEach {
|
||||
// Lets share the provided inbound sessions for every user device
|
||||
val deviceId = it.key
|
||||
sessionInfoSet?.mapNotNull { sessionInfoPair ->
|
||||
// Get inbound session from sessionId and sessionKey
|
||||
cryptoStore.getInboundGroupSession(sessionInfoPair.first, sessionInfoPair.second)
|
||||
}?.filter { inboundGroupSession ->
|
||||
// Filter only sessions with sharedHistory enabled
|
||||
inboundGroupSession.sharedHistory
|
||||
}?.forEach { inboundGroupSession ->
|
||||
// Share the session to userId with deviceId
|
||||
val exportedKeys = inboundGroupSession.exportKeys()
|
||||
val algorithm = exportedKeys?.algorithm
|
||||
val decryptor = roomDecryptorProvider.getRoomDecryptor(roomId, algorithm)
|
||||
decryptor?.shareKeysWithDevice(exportedKeys, deviceId, userId)
|
||||
Timber.i("## CRYPTO | Sharing inbound session")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun sendSharedHistoryKeys(roomId: String, userId: String) {
|
||||
cryptoCoroutineScope.launch(coroutineDispatchers.crypto) {
|
||||
val userDevices = cryptoStore.getUserDevices(userId)
|
||||
@ -1347,7 +1376,7 @@ internal class DefaultCryptoService @Inject constructor(
|
||||
inboundSessions.filter { inboundGroupSession ->
|
||||
inboundGroupSession.sharedHistory
|
||||
}.forEach { inboundGroupSession ->
|
||||
// Share the session with the to userId with deviceId
|
||||
// Share the session to userId with deviceId
|
||||
val exportedKeys = inboundGroupSession.exportKeys()
|
||||
val algorithm = exportedKeys?.algorithm
|
||||
val decryptor = roomDecryptorProvider.getRoomDecryptor(roomId, algorithm)
|
||||
|
@ -18,7 +18,10 @@ package org.matrix.android.sdk.internal.database.helper
|
||||
|
||||
import io.realm.Realm
|
||||
import io.realm.kotlin.createObject
|
||||
import org.matrix.android.sdk.api.session.events.model.content.EncryptedEventContent
|
||||
import org.matrix.android.sdk.api.session.events.model.toModel
|
||||
import org.matrix.android.sdk.api.session.room.model.RoomMemberContent
|
||||
import org.matrix.android.sdk.internal.database.mapper.asDomain
|
||||
import org.matrix.android.sdk.internal.database.model.ChunkEntity
|
||||
import org.matrix.android.sdk.internal.database.model.CurrentStateEventEntityFields
|
||||
import org.matrix.android.sdk.internal.database.model.EventAnnotationsSummaryEntity
|
||||
@ -31,6 +34,7 @@ import org.matrix.android.sdk.internal.database.model.RoomMemberSummaryEntityFie
|
||||
import org.matrix.android.sdk.internal.database.model.TimelineEventEntity
|
||||
import org.matrix.android.sdk.internal.database.model.TimelineEventEntityFields
|
||||
import org.matrix.android.sdk.internal.database.query.find
|
||||
import org.matrix.android.sdk.internal.database.query.findLastForwardChunkOfRoom
|
||||
import org.matrix.android.sdk.internal.database.query.getOrCreate
|
||||
import org.matrix.android.sdk.internal.database.query.where
|
||||
import org.matrix.android.sdk.internal.session.room.timeline.PaginationDirection
|
||||
@ -180,3 +184,14 @@ internal fun ChunkEntity.isMoreRecentThan(chunkToCheck: ChunkEntity): Boolean {
|
||||
// We don't know, so we assume it's false
|
||||
return false
|
||||
}
|
||||
|
||||
internal fun ChunkEntity.Companion.findLatestSessionInfo(realm: Realm, roomId: String): Set<SessionInfoPair>? =
|
||||
ChunkEntity.findLastForwardChunkOfRoom(realm, roomId)?.timelineEvents?.mapNotNull { timelineEvent ->
|
||||
timelineEvent?.root?.asDomain()?.content?.toModel<EncryptedEventContent>()?.let { content ->
|
||||
content.sessionId ?: return@mapNotNull null
|
||||
content.senderKey ?: return@mapNotNull null
|
||||
Pair(content.sessionId, content.senderKey)
|
||||
}
|
||||
}?.toSet()
|
||||
|
||||
internal typealias SessionInfoPair = Pair<String, String>
|
||||
|
@ -29,7 +29,9 @@ import org.matrix.android.sdk.api.session.room.members.MembershipService
|
||||
import org.matrix.android.sdk.api.session.room.members.RoomMemberQueryParams
|
||||
import org.matrix.android.sdk.api.session.room.model.Membership
|
||||
import org.matrix.android.sdk.api.session.room.model.RoomMemberSummary
|
||||
import org.matrix.android.sdk.internal.database.helper.findLatestSessionInfo
|
||||
import org.matrix.android.sdk.internal.database.mapper.asDomain
|
||||
import org.matrix.android.sdk.internal.database.model.ChunkEntity
|
||||
import org.matrix.android.sdk.internal.database.model.RoomMemberSummaryEntity
|
||||
import org.matrix.android.sdk.internal.database.model.RoomMemberSummaryEntityFields
|
||||
import org.matrix.android.sdk.internal.database.model.RoomMembersLoadStatusType
|
||||
@ -141,7 +143,10 @@ internal class DefaultMembershipService @AssistedInject constructor(
|
||||
}
|
||||
|
||||
override suspend fun invite(userId: String, reason: String?) {
|
||||
cryptoService.sendSharedHistoryKeys(roomId, userId)
|
||||
val sessionInfoSet = Realm.getInstance(monarchy.realmConfiguration).use {
|
||||
ChunkEntity.findLatestSessionInfo(it, roomId)
|
||||
}
|
||||
cryptoService.sendSharedHistoryKeysToLastChunk(roomId, userId, sessionInfoSet)
|
||||
val params = InviteTask.Params(roomId, userId, reason)
|
||||
inviteTask.execute(params)
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user