- 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.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.session.events.model.content.RoomKeyWithHeldContent
|
import org.matrix.android.sdk.api.session.events.model.content.RoomKeyWithHeldContent
|
||||||
|
import org.matrix.android.sdk.internal.database.helper.SessionInfoPair
|
||||||
|
|
||||||
interface CryptoService {
|
interface CryptoService {
|
||||||
|
|
||||||
@ -178,7 +179,12 @@ interface CryptoService {
|
|||||||
fun prepareToEncrypt(roomId: String, callback: MatrixCallback<Unit>)
|
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)
|
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.tasks.UploadKeysTask
|
||||||
import org.matrix.android.sdk.internal.crypto.verification.DefaultVerificationService
|
import org.matrix.android.sdk.internal.crypto.verification.DefaultVerificationService
|
||||||
import org.matrix.android.sdk.internal.crypto.verification.VerificationMessageProcessor
|
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.DeviceId
|
||||||
import org.matrix.android.sdk.internal.di.MoshiProvider
|
import org.matrix.android.sdk.internal.di.MoshiProvider
|
||||||
import org.matrix.android.sdk.internal.di.UserId
|
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) {
|
override fun sendSharedHistoryKeys(roomId: String, userId: String) {
|
||||||
cryptoCoroutineScope.launch(coroutineDispatchers.crypto) {
|
cryptoCoroutineScope.launch(coroutineDispatchers.crypto) {
|
||||||
val userDevices = cryptoStore.getUserDevices(userId)
|
val userDevices = cryptoStore.getUserDevices(userId)
|
||||||
@ -1347,7 +1376,7 @@ internal class DefaultCryptoService @Inject constructor(
|
|||||||
inboundSessions.filter { inboundGroupSession ->
|
inboundSessions.filter { inboundGroupSession ->
|
||||||
inboundGroupSession.sharedHistory
|
inboundGroupSession.sharedHistory
|
||||||
}.forEach { inboundGroupSession ->
|
}.forEach { inboundGroupSession ->
|
||||||
// Share the session with the to userId with deviceId
|
// Share the session to userId with deviceId
|
||||||
val exportedKeys = inboundGroupSession.exportKeys()
|
val exportedKeys = inboundGroupSession.exportKeys()
|
||||||
val algorithm = exportedKeys?.algorithm
|
val algorithm = exportedKeys?.algorithm
|
||||||
val decryptor = roomDecryptorProvider.getRoomDecryptor(roomId, 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.Realm
|
||||||
import io.realm.kotlin.createObject
|
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.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.ChunkEntity
|
||||||
import org.matrix.android.sdk.internal.database.model.CurrentStateEventEntityFields
|
import org.matrix.android.sdk.internal.database.model.CurrentStateEventEntityFields
|
||||||
import org.matrix.android.sdk.internal.database.model.EventAnnotationsSummaryEntity
|
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.TimelineEventEntity
|
||||||
import org.matrix.android.sdk.internal.database.model.TimelineEventEntityFields
|
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.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.getOrCreate
|
||||||
import org.matrix.android.sdk.internal.database.query.where
|
import org.matrix.android.sdk.internal.database.query.where
|
||||||
import org.matrix.android.sdk.internal.session.room.timeline.PaginationDirection
|
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
|
// We don't know, so we assume it's false
|
||||||
return 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.members.RoomMemberQueryParams
|
||||||
import org.matrix.android.sdk.api.session.room.model.Membership
|
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.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.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.RoomMemberSummaryEntity
|
||||||
import org.matrix.android.sdk.internal.database.model.RoomMemberSummaryEntityFields
|
import org.matrix.android.sdk.internal.database.model.RoomMemberSummaryEntityFields
|
||||||
import org.matrix.android.sdk.internal.database.model.RoomMembersLoadStatusType
|
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?) {
|
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)
|
val params = InviteTask.Params(roomId, userId, reason)
|
||||||
inviteTask.execute(params)
|
inviteTask.execute(params)
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user