From 4eba55179e3111a65205ebe1945650a7b0a078af Mon Sep 17 00:00:00 2001
From: Taras Smakula <tarassmakula@gmail.com>
Date: Wed, 8 Nov 2023 15:24:40 +0200
Subject: [PATCH] Implement key sharing

---
 .../membership/DefaultMembershipService.kt    | 15 +++++++-------
 .../sdk/internal/crypto/RustCryptoService.kt  | 20 +++++++++++++------
 2 files changed, 21 insertions(+), 14 deletions(-)

diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/membership/DefaultMembershipService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/membership/DefaultMembershipService.kt
index 2b69821b..fa6c2a95 100644
--- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/membership/DefaultMembershipService.kt
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/membership/DefaultMembershipService.kt
@@ -30,9 +30,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.crypto.store.db.model.CryptoRoomEntity
+import org.matrix.android.sdk.internal.crypto.store.db.query.getById
 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
@@ -157,12 +157,11 @@ internal class DefaultMembershipService @AssistedInject constructor(
     }
 
     private suspend fun sendShareHistoryKeysIfNeeded(userId: String) {
-        if (!cryptoService.isShareKeysOnInviteEnabled()) return
-        // TODO not sure it's the right way to get the latest messages in a room
-        val sessionInfo = Realm.getInstance(monarchy.realmConfiguration).use {
-            ChunkEntity.findLatestSessionInfo(it, roomId)
-        }
-        cryptoService.sendSharedHistoryKeys(roomId, userId, sessionInfo)
+        val room = monarchy.fetchCopied {
+            CryptoRoomEntity.getById(it, roomId)
+        } ?: return
+        if (room.shouldEncryptForInvitedMembers == true && room.shouldShareHistory)
+            cryptoService.sendSharedHistoryKeys(roomId, userId, null)
     }
 
     override suspend fun invite3pid(threePid: ThreePid) {
diff --git a/matrix-sdk-android/src/rustCrypto/java/org/matrix/android/sdk/internal/crypto/RustCryptoService.kt b/matrix-sdk-android/src/rustCrypto/java/org/matrix/android/sdk/internal/crypto/RustCryptoService.kt
index d5069fe0..a1a31698 100755
--- a/matrix-sdk-android/src/rustCrypto/java/org/matrix/android/sdk/internal/crypto/RustCryptoService.kt
+++ b/matrix-sdk-android/src/rustCrypto/java/org/matrix/android/sdk/internal/crypto/RustCryptoService.kt
@@ -735,7 +735,7 @@ internal class RustCryptoService @Inject constructor(
         return true
     }
 
-    override fun supportsShareKeysOnInvite() = false
+    override fun supportsShareKeysOnInvite() = true
 
     override fun supportsKeyWithheld() = true
     override fun supportsForwardedKeyWiththeld() = false
@@ -746,7 +746,7 @@ internal class RustCryptoService @Inject constructor(
         }
     }
 
-    override fun isShareKeysOnInviteEnabled() = false
+    override fun isShareKeysOnInviteEnabled() = true
 
     override fun setRoomUnBlockUnverifiedDevices(roomId: String) {
         cryptoStore.blockUnverifiedDevicesInRoom(roomId, false)
@@ -845,9 +845,9 @@ internal class RustCryptoService @Inject constructor(
     override fun removeSessionListener(listener: NewSessionListener) {
         megolmSessionImportManager.removeListener(listener)
     }
-/* ==========================================================================================
- * DEBUG INFO
- * ========================================================================================== */
+    /* ==========================================================================================
+     * DEBUG INFO
+     * ========================================================================================== */
 
     override fun toString(): String {
         return "DefaultCryptoService of $myUserId ($deviceId)"
@@ -901,7 +901,15 @@ internal class RustCryptoService @Inject constructor(
     override suspend fun prepareToEncrypt(roomId: String) = prepareToEncrypt.invoke(roomId, ensureAllMembersAreLoaded = true)
 
     override suspend fun sendSharedHistoryKeys(roomId: String, userId: String, sessionInfoSet: Set<SessionInfo>?) {
-        // TODO("Not yet implemented")
+        withContext(coroutineDispatchers.crypto) {
+            downloadKeysIfNeeded(listOf(userId))
+            getUserDevices(userId)
+            with(olmMachine) {
+                inner().shareRoomHistoryKeys(roomId, listOf(userId))
+                updateTrackedUsers(listOf(userId))
+                outgoingRequestsProcessor.processOutgoingRequests(olmMachine)
+            }
+        }
     }
 
     companion object {
-- 
GitLab