Skip to content

Commit ffd0c80

Browse files
Implement history key sharing functionality with respect to room visibility settings
1 parent 588b3e4 commit ffd0c80

File tree

8 files changed

+77
-18
lines changed

8 files changed

+77
-18
lines changed

matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/model/RoomHistoryVisibility.kt

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,3 +48,9 @@ enum class RoomHistoryVisibility {
4848
*/
4949
@Json(name = "joined") JOINED
5050
}
51+
52+
/**
53+
* Room history should be shared only if room visibility is world_readable or shared
54+
*/
55+
internal fun RoomHistoryVisibility.shouldShareHistory() =
56+
this == RoomHistoryVisibility.WORLD_READABLE || this == RoomHistoryVisibility.SHARED

matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/DefaultCryptoService.kt

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,7 @@ import org.matrix.android.sdk.api.session.room.model.Membership
7171
import org.matrix.android.sdk.api.session.room.model.RoomHistoryVisibility
7272
import org.matrix.android.sdk.api.session.room.model.RoomHistoryVisibilityContent
7373
import org.matrix.android.sdk.api.session.room.model.RoomMemberContent
74+
import org.matrix.android.sdk.api.session.room.model.shouldShareHistory
7475
import org.matrix.android.sdk.api.session.sync.model.SyncResponse
7576
import org.matrix.android.sdk.internal.crypto.actions.MegolmSessionDataImporter
7677
import org.matrix.android.sdk.internal.crypto.actions.SetDeviceVerificationAction
@@ -710,8 +711,10 @@ internal class DefaultCryptoService @Inject constructor(
710711
}.foldToCallback(callback)
711712
} else {
712713
val algorithm = getEncryptionAlgorithm(roomId)
713-
val reason = String.format(MXCryptoError.UNABLE_TO_ENCRYPT_REASON,
714-
algorithm ?: MXCryptoError.NO_MORE_ALGORITHM_REASON)
714+
val reason = String.format(
715+
MXCryptoError.UNABLE_TO_ENCRYPT_REASON,
716+
algorithm ?: MXCryptoError.NO_MORE_ALGORITHM_REASON
717+
)
715718
Timber.tag(loggerTag.value).e("encryptEventContent() : failed $reason")
716719
callback.onFailure(Failure.CryptoError(MXCryptoError.Base(MXCryptoError.ErrorType.UNABLE_TO_ENCRYPT, reason)))
717720
}
@@ -952,8 +955,8 @@ internal class DefaultCryptoService @Inject constructor(
952955
if (!event.isStateEvent()) return
953956
val eventContent = event.content.toModel<RoomHistoryVisibilityContent>()
954957
eventContent?.historyVisibility?.let {
955-
Timber.i("-----> onRoomHistoryVisibilityEvent $it")
956958
cryptoStore.setShouldEncryptForInvitedMembers(roomId, it != RoomHistoryVisibility.JOINED)
959+
cryptoStore.setShouldShareHistory(roomId, it.shouldShareHistory())
957960
}
958961
}
959962

@@ -1371,19 +1374,23 @@ internal class DefaultCryptoService @Inject constructor(
13711374
)
13721375
}
13731376
}
1377+
13741378
override fun sendSharedHistoryKeys(roomId: String, userId: String) {
13751379
cryptoCoroutineScope.launch(coroutineDispatchers.crypto) {
13761380
val userDevices = cryptoStore.getUserDevices(userId)
13771381
userDevices?.forEach {
13781382
// Lets share our existing inbound sessions for every user device
13791383
val deviceId = it.key
13801384
val inboundSessions = cryptoStore.getInboundGroupSessions(roomId)
1381-
inboundSessions.forEach { inboundGroupSession ->
1385+
inboundSessions.filter { inboundGroupSession ->
1386+
inboundGroupSession.sharedHistory
1387+
}.forEach { inboundGroupSession ->
13821388
// Share the session with the to userId with deviceId
13831389
val exportedKeys = inboundGroupSession.exportKeys()
13841390
val algorithm = exportedKeys?.algorithm
13851391
val decryptor = roomDecryptorProvider.getRoomDecryptor(roomId, algorithm)
13861392
decryptor?.shareKeysWithDevice(exportedKeys, deviceId, userId)
1393+
Timber.i("## CRYPTO | Sharing inbound session")
13871394
}
13881395
}
13891396
}

matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/model/OlmInboundGroupSessionWrapper2.kt

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,10 @@ internal class OlmInboundGroupSessionWrapper2 : Serializable {
4343
// Devices which forwarded this session to us (normally empty).
4444
var forwardingCurve25519KeyChain: List<String>? = ArrayList()
4545

46+
// Flag that indicates whether or not the current inboundSession will be shared to
47+
// invited users to decrypt past messages
48+
var sharedHistory: Boolean = false
49+
4650
/**
4751
* @return the first known message index
4852
*/

matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/IMXCryptoStore.kt

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -262,6 +262,17 @@ internal interface IMXCryptoStore {
262262

263263
fun setShouldEncryptForInvitedMembers(roomId: String, shouldEncryptForInvitedMembers: Boolean)
264264

265+
fun shouldShareHistory(roomId: String): Boolean
266+
267+
/**
268+
* Sets a boolean flag that will determine whether or not room history (existing inbound sessions)
269+
* will be shared to new user invites
270+
*
271+
* @param roomId the room id
272+
* @param shouldShareHistory The boolean flag
273+
*/
274+
fun setShouldShareHistory(roomId: String, shouldShareHistory: Boolean)
275+
265276
/**
266277
* Store a session between the logged-in user and another device.
267278
*

matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/RealmCryptoStore.kt

Lines changed: 40 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -653,12 +653,25 @@ internal class RealmCryptoStore @Inject constructor(
653653
?: false
654654
}
655655

656+
override fun shouldShareHistory(roomId: String): Boolean {
657+
return doWithRealm(realmConfiguration) {
658+
CryptoRoomEntity.getById(it, roomId)?.shouldShareHistory
659+
}
660+
?: false
661+
}
662+
656663
override fun setShouldEncryptForInvitedMembers(roomId: String, shouldEncryptForInvitedMembers: Boolean) {
657664
doRealmTransaction(realmConfiguration) {
658665
CryptoRoomEntity.getOrCreate(it, roomId).shouldEncryptForInvitedMembers = shouldEncryptForInvitedMembers
659666
}
660667
}
661668

669+
override fun setShouldShareHistory(roomId: String, shouldShareHistory: Boolean) {
670+
doRealmTransaction(realmConfiguration) {
671+
CryptoRoomEntity.getOrCreate(it, roomId).shouldShareHistory = shouldShareHistory
672+
}
673+
}
674+
662675
override fun storeSession(olmSessionWrapper: OlmSessionWrapper, deviceKey: String) {
663676
var sessionIdentifier: String? = null
664677

@@ -738,16 +751,21 @@ internal class RealmCryptoStore @Inject constructor(
738751
}
739752

740753
if (sessionIdentifier != null) {
754+
val shouldShareHistory = session.roomId?.let { roomId ->
755+
CryptoRoomEntity.getById(realm, roomId)?.shouldShareHistory
756+
} ?: false
757+
session.sharedHistory = shouldShareHistory
741758
val key = OlmInboundGroupSessionEntity.createPrimaryKey(sessionIdentifier, session.senderKey)
742759

743760
val realmOlmInboundGroupSession = OlmInboundGroupSessionEntity().apply {
744761
primaryKey = key
745762
sessionId = sessionIdentifier
746763
senderKey = session.senderKey
747764
roomId = session.roomId
765+
sharedHistory = shouldShareHistory
748766
putInboundGroupSession(session)
749767
}
750-
768+
Timber.i("## CRYPTO | shouldShareHistory: $shouldShareHistory for $key")
751769
realm.insertOrUpdate(realmOlmInboundGroupSession)
752770
}
753771
}
@@ -893,7 +911,8 @@ internal class RealmCryptoStore @Inject constructor(
893911
try {
894912
val key = OlmInboundGroupSessionEntity.createPrimaryKey(
895913
olmInboundGroupSessionWrapper.olmInboundGroupSession?.sessionIdentifier(),
896-
olmInboundGroupSessionWrapper.senderKey)
914+
olmInboundGroupSessionWrapper.senderKey
915+
)
897916

898917
it.where<OlmInboundGroupSessionEntity>()
899918
.equalTo(OlmInboundGroupSessionEntityFields.PRIMARY_KEY, key)
@@ -1068,13 +1087,16 @@ internal class RealmCryptoStore @Inject constructor(
10681087
localCreationTimestamp = 0
10691088
)
10701089
}
1071-
return monarchy.findAllPagedWithChanges(realmDataSourceFactory,
1072-
LivePagedListBuilder(dataSourceFactory,
1090+
return monarchy.findAllPagedWithChanges(
1091+
realmDataSourceFactory,
1092+
LivePagedListBuilder(
1093+
dataSourceFactory,
10731094
PagedList.Config.Builder()
10741095
.setPageSize(20)
10751096
.setEnablePlaceholders(false)
10761097
.setPrefetchDistance(1)
1077-
.build())
1098+
.build()
1099+
)
10781100
)
10791101
}
10801102

@@ -1083,13 +1105,16 @@ internal class RealmCryptoStore @Inject constructor(
10831105
realm.where<GossipingEventEntity>().sort(GossipingEventEntityFields.AGE_LOCAL_TS, Sort.DESCENDING)
10841106
}
10851107
val dataSourceFactory = realmDataSourceFactory.map { it.toModel() }
1086-
val trail = monarchy.findAllPagedWithChanges(realmDataSourceFactory,
1087-
LivePagedListBuilder(dataSourceFactory,
1108+
val trail = monarchy.findAllPagedWithChanges(
1109+
realmDataSourceFactory,
1110+
LivePagedListBuilder(
1111+
dataSourceFactory,
10881112
PagedList.Config.Builder()
10891113
.setPageSize(20)
10901114
.setEnablePlaceholders(false)
10911115
.setPrefetchDistance(1)
1092-
.build())
1116+
.build()
1117+
)
10931118
)
10941119
return trail
10951120
}
@@ -1337,7 +1362,7 @@ internal class RealmCryptoStore @Inject constructor(
13371362
.findAll()
13381363
.mapNotNull { entity ->
13391364
when (entity.type) {
1340-
GossipRequestType.KEY -> {
1365+
GossipRequestType.KEY -> {
13411366
IncomingRoomKeyRequest(
13421367
userId = entity.otherUserId,
13431368
deviceId = entity.otherDeviceId,
@@ -1547,13 +1572,16 @@ internal class RealmCryptoStore @Inject constructor(
15471572
it.toOutgoingGossipingRequest() as? OutgoingRoomKeyRequest
15481573
?: OutgoingRoomKeyRequest(requestBody = null, requestId = "?", recipients = emptyMap(), state = OutgoingGossipingRequestState.CANCELLED)
15491574
}
1550-
val trail = monarchy.findAllPagedWithChanges(realmDataSourceFactory,
1551-
LivePagedListBuilder(dataSourceFactory,
1575+
val trail = monarchy.findAllPagedWithChanges(
1576+
realmDataSourceFactory,
1577+
LivePagedListBuilder(
1578+
dataSourceFactory,
15521579
PagedList.Config.Builder()
15531580
.setPageSize(20)
15541581
.setEnablePlaceholders(false)
15551582
.setPrefetchDistance(1)
1556-
.build())
1583+
.build()
1584+
)
15571585
)
15581586
return trail
15591587
}

matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/RealmCryptoStoreMigration.kt

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,5 @@ internal class RealmCryptoStoreMigration @Inject constructor() : RealmMigration
6969
if (oldVersion < 14) MigrateCryptoTo014(realm).perform()
7070
if (oldVersion < 15) MigrateCryptoTo015(realm).perform()
7171
if (oldVersion < 16) MigrateCryptoTo016(realm).perform()
72-
7372
}
7473
}

matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/migration/MigrateCryptoTo016.kt

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,6 @@
1717
package org.matrix.android.sdk.internal.crypto.store.db.migration
1818

1919
import io.realm.DynamicRealm
20-
import org.matrix.android.sdk.api.crypto.MXCRYPTO_ALGORITHM_MEGOLM
2120
import org.matrix.android.sdk.internal.crypto.store.db.model.CryptoRoomEntityFields
2221
import org.matrix.android.sdk.internal.crypto.store.db.model.OlmInboundGroupSessionEntityFields
2322
import org.matrix.android.sdk.internal.util.database.RealmMigrator
@@ -29,5 +28,8 @@ internal class MigrateCryptoTo016(realm: DynamicRealm) : RealmMigrator(realm, 16
2928
realm.schema.get("OlmInboundGroupSessionEntity")
3029
?.addField(OlmInboundGroupSessionEntityFields.SHARED_HISTORY, Boolean::class.java)
3130
?.addField(OlmInboundGroupSessionEntityFields.ROOM_ID, String::class.java)
31+
32+
realm.schema.get("CryptoRoomEntity")
33+
?.addField(CryptoRoomEntityFields.SHOULD_SHARE_HISTORY, Boolean::class.java)
3234
}
3335
}

matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/model/CryptoRoomEntity.kt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,8 @@ internal open class CryptoRoomEntity(
2424
var algorithm: String? = null,
2525
var shouldEncryptForInvitedMembers: Boolean? = null,
2626
var blacklistUnverifiedDevices: Boolean = false,
27+
// Determines whether or not room history should be shared on new member invites
28+
var shouldShareHistory: Boolean = false,
2729
// Store the current outbound session for this room,
2830
// to avoid re-create and re-share at each startup (if rotation not needed..)
2931
// This is specific to megolm but not sure how to model it better

0 commit comments

Comments
 (0)