Implement history key sharing functionality with respect to room visibility settings
This commit is contained in:
parent
6e57aeb9e5
commit
e861edd544
|
@ -48,3 +48,9 @@ enum class RoomHistoryVisibility {
|
|||
*/
|
||||
@Json(name = "joined") JOINED
|
||||
}
|
||||
|
||||
/**
|
||||
* Room history should be shared only if room visibility is world_readable or shared
|
||||
*/
|
||||
internal fun RoomHistoryVisibility.shouldShareHistory() =
|
||||
this == RoomHistoryVisibility.WORLD_READABLE || this == RoomHistoryVisibility.SHARED
|
||||
|
|
|
@ -71,6 +71,7 @@ import org.matrix.android.sdk.api.session.room.model.Membership
|
|||
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.RoomMemberContent
|
||||
import org.matrix.android.sdk.api.session.room.model.shouldShareHistory
|
||||
import org.matrix.android.sdk.api.session.sync.model.SyncResponse
|
||||
import org.matrix.android.sdk.internal.crypto.actions.MegolmSessionDataImporter
|
||||
import org.matrix.android.sdk.internal.crypto.actions.SetDeviceVerificationAction
|
||||
|
@ -964,8 +965,8 @@ internal class DefaultCryptoService @Inject constructor(
|
|||
if (!event.isStateEvent()) return
|
||||
val eventContent = event.content.toModel<RoomHistoryVisibilityContent>()
|
||||
eventContent?.historyVisibility?.let {
|
||||
Timber.i("-----> onRoomHistoryVisibilityEvent $it")
|
||||
cryptoStore.setShouldEncryptForInvitedMembers(roomId, it != RoomHistoryVisibility.JOINED)
|
||||
cryptoStore.setShouldShareHistory(roomId, it.shouldShareHistory())
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1335,6 +1336,7 @@ internal class DefaultCryptoService @Inject constructor(
|
|||
)
|
||||
}
|
||||
}
|
||||
|
||||
override fun sendSharedHistoryKeys(roomId: String, userId: String) {
|
||||
cryptoCoroutineScope.launch(coroutineDispatchers.crypto) {
|
||||
val userDevices = cryptoStore.getUserDevices(userId)
|
||||
|
@ -1342,12 +1344,15 @@ internal class DefaultCryptoService @Inject constructor(
|
|||
// Lets share our existing inbound sessions for every user device
|
||||
val deviceId = it.key
|
||||
val inboundSessions = cryptoStore.getInboundGroupSessions(roomId)
|
||||
inboundSessions.forEach { inboundGroupSession ->
|
||||
inboundSessions.filter { inboundGroupSession ->
|
||||
inboundGroupSession.sharedHistory
|
||||
}.forEach { inboundGroupSession ->
|
||||
// Share the session with the 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")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -43,6 +43,10 @@ internal class OlmInboundGroupSessionWrapper2 : Serializable {
|
|||
// Devices which forwarded this session to us (normally empty).
|
||||
var forwardingCurve25519KeyChain: List<String>? = ArrayList()
|
||||
|
||||
// Flag that indicates whether or not the current inboundSession will be shared to
|
||||
// invited users to decrypt past messages
|
||||
var sharedHistory: Boolean = false
|
||||
|
||||
/**
|
||||
* @return the first known message index
|
||||
*/
|
||||
|
|
|
@ -258,6 +258,17 @@ internal interface IMXCryptoStore {
|
|||
|
||||
fun setShouldEncryptForInvitedMembers(roomId: String, shouldEncryptForInvitedMembers: Boolean)
|
||||
|
||||
fun shouldShareHistory(roomId: String): Boolean
|
||||
|
||||
/**
|
||||
* Sets a boolean flag that will determine whether or not room history (existing inbound sessions)
|
||||
* will be shared to new user invites
|
||||
*
|
||||
* @param roomId the room id
|
||||
* @param shouldShareHistory The boolean flag
|
||||
*/
|
||||
fun setShouldShareHistory(roomId: String, shouldShareHistory: Boolean)
|
||||
|
||||
/**
|
||||
* Store a session between the logged-in user and another device.
|
||||
*
|
||||
|
|
|
@ -657,12 +657,25 @@ internal class RealmCryptoStore @Inject constructor(
|
|||
?: false
|
||||
}
|
||||
|
||||
override fun shouldShareHistory(roomId: String): Boolean {
|
||||
return doWithRealm(realmConfiguration) {
|
||||
CryptoRoomEntity.getById(it, roomId)?.shouldShareHistory
|
||||
}
|
||||
?: false
|
||||
}
|
||||
|
||||
override fun setShouldEncryptForInvitedMembers(roomId: String, shouldEncryptForInvitedMembers: Boolean) {
|
||||
doRealmTransaction(realmConfiguration) {
|
||||
CryptoRoomEntity.getOrCreate(it, roomId).shouldEncryptForInvitedMembers = shouldEncryptForInvitedMembers
|
||||
}
|
||||
}
|
||||
|
||||
override fun setShouldShareHistory(roomId: String, shouldShareHistory: Boolean) {
|
||||
doRealmTransaction(realmConfiguration) {
|
||||
CryptoRoomEntity.getOrCreate(it, roomId).shouldShareHistory = shouldShareHistory
|
||||
}
|
||||
}
|
||||
|
||||
override fun storeSession(olmSessionWrapper: OlmSessionWrapper, deviceKey: String) {
|
||||
var sessionIdentifier: String? = null
|
||||
|
||||
|
@ -743,6 +756,10 @@ internal class RealmCryptoStore @Inject constructor(
|
|||
}
|
||||
|
||||
if (sessionIdentifier != null) {
|
||||
val shouldShareHistory = session.roomId?.let { roomId ->
|
||||
CryptoRoomEntity.getById(realm, roomId)?.shouldShareHistory
|
||||
} ?: false
|
||||
session.sharedHistory = shouldShareHistory
|
||||
val key = OlmInboundGroupSessionEntity.createPrimaryKey(sessionIdentifier, session.senderKey)
|
||||
|
||||
val realmOlmInboundGroupSession = OlmInboundGroupSessionEntity().apply {
|
||||
|
@ -750,22 +767,11 @@ internal class RealmCryptoStore @Inject constructor(
|
|||
sessionId = sessionIdentifier
|
||||
senderKey = session.senderKey
|
||||
roomId = session.roomId
|
||||
sharedHistory = shouldShareHistory
|
||||
putInboundGroupSession(session)
|
||||
}
|
||||
|
||||
if (existing != null) {
|
||||
// we want to keep the existing backup status
|
||||
existing.putInboundGroupSession(session)
|
||||
} else {
|
||||
val realmOlmInboundGroupSession = OlmInboundGroupSessionEntity().apply {
|
||||
primaryKey = key
|
||||
sessionId = sessionIdentifier
|
||||
senderKey = session.senderKey
|
||||
putInboundGroupSession(session)
|
||||
}
|
||||
|
||||
realm.insertOrUpdate(realmOlmInboundGroupSession)
|
||||
}
|
||||
Timber.i("## CRYPTO | shouldShareHistory: $shouldShareHistory for $key")
|
||||
realm.insertOrUpdate(realmOlmInboundGroupSession)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -73,6 +73,9 @@ internal class RealmCryptoStoreMigration @Inject constructor(
|
|||
if (oldVersion < 14) MigrateCryptoTo014(realm).perform()
|
||||
if (oldVersion < 15) MigrateCryptoTo015(realm).perform()
|
||||
if (oldVersion < 16) MigrateCryptoTo016(realm).perform()
|
||||
<<<<<<< develop
|
||||
if (oldVersion < 17) MigrateCryptoTo017(realm).perform()
|
||||
=======
|
||||
>>>>>>> Implement history key sharing functionality with respect to room visibility settings
|
||||
}
|
||||
}
|
||||
|
|
|
@ -17,6 +17,7 @@
|
|||
package org.matrix.android.sdk.internal.crypto.store.db.migration
|
||||
|
||||
import io.realm.DynamicRealm
|
||||
import org.matrix.android.sdk.internal.crypto.store.db.model.CryptoRoomEntityFields
|
||||
|
||||
import org.matrix.android.sdk.internal.crypto.store.db.model.OlmInboundGroupSessionEntityFields
|
||||
import org.matrix.android.sdk.internal.util.database.RealmMigrator
|
||||
|
@ -28,5 +29,8 @@ internal class MigrateCryptoTo017(realm: DynamicRealm) : RealmMigrator(realm, 16
|
|||
realm.schema.get("OlmInboundGroupSessionEntity")
|
||||
?.addField(OlmInboundGroupSessionEntityFields.SHARED_HISTORY, Boolean::class.java)
|
||||
?.addField(OlmInboundGroupSessionEntityFields.ROOM_ID, String::class.java)
|
||||
|
||||
realm.schema.get("CryptoRoomEntity")
|
||||
?.addField(CryptoRoomEntityFields.SHOULD_SHARE_HISTORY, Boolean::class.java)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -24,6 +24,8 @@ internal open class CryptoRoomEntity(
|
|||
var algorithm: String? = null,
|
||||
var shouldEncryptForInvitedMembers: Boolean? = null,
|
||||
var blacklistUnverifiedDevices: Boolean = false,
|
||||
// Determines whether or not room history should be shared on new member invites
|
||||
var shouldShareHistory: Boolean = false,
|
||||
// Store the current outbound session for this room,
|
||||
// to avoid re-create and re-share at each startup (if rotation not needed..)
|
||||
// This is specific to megolm but not sure how to model it better
|
||||
|
|
Loading…
Reference in New Issue