mirror of
https://github.com/SchildiChat/SchildiChat-android.git
synced 2025-02-18 13:00:18 +03:00
Implement history key sharing functionality with respect to room visibility settings
This commit is contained in:
parent
6e57aeb9e5
commit
e861edd544
8 changed files with 57 additions and 16 deletions
|
@ -48,3 +48,9 @@ enum class RoomHistoryVisibility {
|
||||||
*/
|
*/
|
||||||
@Json(name = "joined") JOINED
|
@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.RoomHistoryVisibility
|
||||||
import org.matrix.android.sdk.api.session.room.model.RoomHistoryVisibilityContent
|
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.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.api.session.sync.model.SyncResponse
|
||||||
import org.matrix.android.sdk.internal.crypto.actions.MegolmSessionDataImporter
|
import org.matrix.android.sdk.internal.crypto.actions.MegolmSessionDataImporter
|
||||||
import org.matrix.android.sdk.internal.crypto.actions.SetDeviceVerificationAction
|
import org.matrix.android.sdk.internal.crypto.actions.SetDeviceVerificationAction
|
||||||
|
@ -964,8 +965,8 @@ internal class DefaultCryptoService @Inject constructor(
|
||||||
if (!event.isStateEvent()) return
|
if (!event.isStateEvent()) return
|
||||||
val eventContent = event.content.toModel<RoomHistoryVisibilityContent>()
|
val eventContent = event.content.toModel<RoomHistoryVisibilityContent>()
|
||||||
eventContent?.historyVisibility?.let {
|
eventContent?.historyVisibility?.let {
|
||||||
Timber.i("-----> onRoomHistoryVisibilityEvent $it")
|
|
||||||
cryptoStore.setShouldEncryptForInvitedMembers(roomId, it != RoomHistoryVisibility.JOINED)
|
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) {
|
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)
|
||||||
|
@ -1342,12 +1344,15 @@ internal class DefaultCryptoService @Inject constructor(
|
||||||
// Lets share our existing inbound sessions for every user device
|
// Lets share our existing inbound sessions for every user device
|
||||||
val deviceId = it.key
|
val deviceId = it.key
|
||||||
val inboundSessions = cryptoStore.getInboundGroupSessions(roomId)
|
val inboundSessions = cryptoStore.getInboundGroupSessions(roomId)
|
||||||
inboundSessions.forEach { inboundGroupSession ->
|
inboundSessions.filter { inboundGroupSession ->
|
||||||
|
inboundGroupSession.sharedHistory
|
||||||
|
}.forEach { inboundGroupSession ->
|
||||||
// Share the session with the to userId with deviceId
|
// Share the session with the 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)
|
||||||
decryptor?.shareKeysWithDevice(exportedKeys, deviceId, userId)
|
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).
|
// Devices which forwarded this session to us (normally empty).
|
||||||
var forwardingCurve25519KeyChain: List<String>? = ArrayList()
|
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
|
* @return the first known message index
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -258,6 +258,17 @@ internal interface IMXCryptoStore {
|
||||||
|
|
||||||
fun setShouldEncryptForInvitedMembers(roomId: String, shouldEncryptForInvitedMembers: Boolean)
|
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.
|
* Store a session between the logged-in user and another device.
|
||||||
*
|
*
|
||||||
|
|
|
@ -657,12 +657,25 @@ internal class RealmCryptoStore @Inject constructor(
|
||||||
?: false
|
?: false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun shouldShareHistory(roomId: String): Boolean {
|
||||||
|
return doWithRealm(realmConfiguration) {
|
||||||
|
CryptoRoomEntity.getById(it, roomId)?.shouldShareHistory
|
||||||
|
}
|
||||||
|
?: false
|
||||||
|
}
|
||||||
|
|
||||||
override fun setShouldEncryptForInvitedMembers(roomId: String, shouldEncryptForInvitedMembers: Boolean) {
|
override fun setShouldEncryptForInvitedMembers(roomId: String, shouldEncryptForInvitedMembers: Boolean) {
|
||||||
doRealmTransaction(realmConfiguration) {
|
doRealmTransaction(realmConfiguration) {
|
||||||
CryptoRoomEntity.getOrCreate(it, roomId).shouldEncryptForInvitedMembers = shouldEncryptForInvitedMembers
|
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) {
|
override fun storeSession(olmSessionWrapper: OlmSessionWrapper, deviceKey: String) {
|
||||||
var sessionIdentifier: String? = null
|
var sessionIdentifier: String? = null
|
||||||
|
|
||||||
|
@ -743,6 +756,10 @@ internal class RealmCryptoStore @Inject constructor(
|
||||||
}
|
}
|
||||||
|
|
||||||
if (sessionIdentifier != null) {
|
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 key = OlmInboundGroupSessionEntity.createPrimaryKey(sessionIdentifier, session.senderKey)
|
||||||
|
|
||||||
val realmOlmInboundGroupSession = OlmInboundGroupSessionEntity().apply {
|
val realmOlmInboundGroupSession = OlmInboundGroupSessionEntity().apply {
|
||||||
|
@ -750,26 +767,15 @@ internal class RealmCryptoStore @Inject constructor(
|
||||||
sessionId = sessionIdentifier
|
sessionId = sessionIdentifier
|
||||||
senderKey = session.senderKey
|
senderKey = session.senderKey
|
||||||
roomId = session.roomId
|
roomId = session.roomId
|
||||||
|
sharedHistory = shouldShareHistory
|
||||||
putInboundGroupSession(session)
|
putInboundGroupSession(session)
|
||||||
}
|
}
|
||||||
|
Timber.i("## CRYPTO | shouldShareHistory: $shouldShareHistory for $key")
|
||||||
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)
|
realm.insertOrUpdate(realmOlmInboundGroupSession)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
override fun getInboundGroupSession(sessionId: String, senderKey: String): OlmInboundGroupSessionWrapper2? {
|
override fun getInboundGroupSession(sessionId: String, senderKey: String): OlmInboundGroupSessionWrapper2? {
|
||||||
val key = OlmInboundGroupSessionEntity.createPrimaryKey(sessionId, senderKey)
|
val key = OlmInboundGroupSessionEntity.createPrimaryKey(sessionId, senderKey)
|
||||||
|
|
|
@ -73,6 +73,9 @@ internal class RealmCryptoStoreMigration @Inject constructor(
|
||||||
if (oldVersion < 14) MigrateCryptoTo014(realm).perform()
|
if (oldVersion < 14) MigrateCryptoTo014(realm).perform()
|
||||||
if (oldVersion < 15) MigrateCryptoTo015(realm).perform()
|
if (oldVersion < 15) MigrateCryptoTo015(realm).perform()
|
||||||
if (oldVersion < 16) MigrateCryptoTo016(realm).perform()
|
if (oldVersion < 16) MigrateCryptoTo016(realm).perform()
|
||||||
|
<<<<<<< develop
|
||||||
if (oldVersion < 17) MigrateCryptoTo017(realm).perform()
|
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
|
package org.matrix.android.sdk.internal.crypto.store.db.migration
|
||||||
|
|
||||||
import io.realm.DynamicRealm
|
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.crypto.store.db.model.OlmInboundGroupSessionEntityFields
|
||||||
import org.matrix.android.sdk.internal.util.database.RealmMigrator
|
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")
|
realm.schema.get("OlmInboundGroupSessionEntity")
|
||||||
?.addField(OlmInboundGroupSessionEntityFields.SHARED_HISTORY, Boolean::class.java)
|
?.addField(OlmInboundGroupSessionEntityFields.SHARED_HISTORY, Boolean::class.java)
|
||||||
?.addField(OlmInboundGroupSessionEntityFields.ROOM_ID, String::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 algorithm: String? = null,
|
||||||
var shouldEncryptForInvitedMembers: Boolean? = null,
|
var shouldEncryptForInvitedMembers: Boolean? = null,
|
||||||
var blacklistUnverifiedDevices: Boolean = false,
|
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,
|
// Store the current outbound session for this room,
|
||||||
// to avoid re-create and re-share at each startup (if rotation not needed..)
|
// 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
|
// This is specific to megolm but not sure how to model it better
|
||||||
|
|
Loading…
Add table
Reference in a new issue