diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/DefaultCryptoService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/DefaultCryptoService.kt index afec7d17d3..5a18241534 100755 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/DefaultCryptoService.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/DefaultCryptoService.kt @@ -79,11 +79,13 @@ import org.matrix.android.sdk.internal.crypto.model.event.SecretSendEventContent import org.matrix.android.sdk.internal.crypto.model.rest.DeviceInfo import org.matrix.android.sdk.internal.crypto.model.rest.DevicesListResponse import org.matrix.android.sdk.internal.crypto.model.rest.KeysUploadResponse +import org.matrix.android.sdk.internal.crypto.model.rest.KeysQueryResponse import org.matrix.android.sdk.internal.crypto.model.rest.RoomKeyRequestBody import org.matrix.android.sdk.internal.crypto.repository.WarnOnUnknownDeviceRepository import org.matrix.android.sdk.internal.crypto.store.IMXCryptoStore import org.matrix.android.sdk.internal.crypto.tasks.DeleteDeviceTask import org.matrix.android.sdk.internal.crypto.tasks.DeleteDeviceWithUserPasswordTask +import org.matrix.android.sdk.internal.crypto.tasks.DownloadKeysForUsersTask import org.matrix.android.sdk.internal.crypto.tasks.GetDeviceInfoTask import org.matrix.android.sdk.internal.crypto.tasks.GetDevicesTask import org.matrix.android.sdk.internal.crypto.tasks.NewUploadKeysTask @@ -169,6 +171,7 @@ internal class DefaultCryptoService @Inject constructor( private val deleteDeviceWithUserPasswordTask: DeleteDeviceWithUserPasswordTask, // Tasks private val getDevicesTask: GetDevicesTask, + private val downloadKeysForUsersTask: DownloadKeysForUsersTask, private val getDeviceInfoTask: GetDeviceInfoTask, private val setDeviceNameTask: SetDeviceNameTask, private val uploadKeysTask: UploadKeysTask, @@ -185,7 +188,7 @@ internal class DefaultCryptoService @Inject constructor( private val isStarted = AtomicBoolean(false) private var olmMachine: OlmMachine? = null - fun onStateEvent(roomId: String, event: Event) { + suspend fun onStateEvent(roomId: String, event: Event) { when (event.getClearType()) { EventType.STATE_ROOM_ENCRYPTION -> onRoomEncryptionEvent(roomId, event) EventType.STATE_ROOM_MEMBER -> onRoomMembershipEvent(roomId, event) @@ -193,7 +196,7 @@ internal class DefaultCryptoService @Inject constructor( } } - fun onLiveEvent(roomId: String, event: Event) { + suspend fun onLiveEvent(roomId: String, event: Event) { when (event.getClearType()) { EventType.STATE_ROOM_ENCRYPTION -> onRoomEncryptionEvent(roomId, event) EventType.STATE_ROOM_MEMBER -> onRoomMembershipEvent(roomId, event) @@ -899,6 +902,7 @@ internal class DefaultCryptoService @Inject constructor( Timber.e(throwable, "## CRYPTO | onRoomEncryptionEvent ERROR FAILED TO SETUP CRYPTO ") } finally { val userIds = getRoomUserIds(roomId) + olmMachine!!.updateTrackedUsers(userIds) setEncryptionInRoom(roomId, event.content?.get("algorithm")?.toString(), true, userIds) } } @@ -915,13 +919,14 @@ internal class DefaultCryptoService @Inject constructor( * * @param event the membership event causing the change */ - private fun onRoomMembershipEvent(roomId: String, event: Event) { + private suspend fun onRoomMembershipEvent(roomId: String, event: Event) { roomEncryptorsStore.get(roomId) ?: /* No encrypting in this room */ return event.stateKey?.let { userId -> val roomMember: RoomMemberContent? = event.content.toModel() val membership = roomMember?.membership if (membership == Membership.JOIN) { + olmMachine!!.updateTrackedUsers(listOf(userId)) // make sure we are tracking the deviceList for this user. deviceListManager.startTrackingDeviceList(listOf(userId)) } else if (membership == Membership.INVITE @@ -966,8 +971,24 @@ internal class DefaultCryptoService @Inject constructor( olmMachine!!.markRequestAsSent(outgoingRequest.requestId, RequestType.KEYS_UPLOAD, json_response) Timber.v("HELLO UPLOADED KEYS $response") } - is Request.KeysQuery -> Timber.v("HELLO KEYS QUERY REQUEST ${outgoingRequest.body}") - is Request.ToDevice -> Timber.v("HELLO TO DEVICE REQUEST ${outgoingRequest.body}") + is Request.KeysQuery -> { + Timber.v("HELLO KEYS QUERY REQUEST ${outgoingRequest.users}") + val params = DownloadKeysForUsersTask.Params(outgoingRequest.users, null) + + try { + val response = downloadKeysForUsersTask.execute(params) + val adapter = MoshiProvider.providesMoshi().adapter(KeysQueryResponse::class.java) + val json_response = adapter.toJson(response)!! + olmMachine!!.markRequestAsSent(outgoingRequest.requestId, RequestType.KEYS_QUERY, json_response) + } catch (throwable: Throwable) { + Timber.e(throwable, "## CRYPTO | doKeyDownloadForUsers(): error") + } + + + } + is Request.ToDevice -> { + // Timber.v("HELLO TO DEVICE REQUEST ${outgoingRequest.body}") + } } } } diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/newCrypto.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/newCrypto.kt index 7712da129b..d6fb5035a8 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/newCrypto.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/newCrypto.kt @@ -87,6 +87,10 @@ internal class OlmMachine(user_id: String, device_id: String, path: File) { inner.outgoingRequests() } + suspend fun updateTrackedUsers(users: List) = withContext(Dispatchers.IO) { + inner.updateTrackedUsers(users) + } + suspend fun receiveSyncChanges( toDevice: ToDeviceSyncResponse?, deviceChanges: DeviceListResponse?, diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/RoomSyncHandler.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/RoomSyncHandler.kt index 6d1b3ae034..974041a59a 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/RoomSyncHandler.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/RoomSyncHandler.kt @@ -83,7 +83,7 @@ internal class RoomSyncHandler @Inject constructor(private val readReceiptHandle data class LEFT(val data: Map) : HandlingStrategy() } - fun handle( + suspend fun handle( realm: Realm, roomsSyncResponse: RoomsSyncResponse, isInitialSync: Boolean, @@ -97,7 +97,7 @@ internal class RoomSyncHandler @Inject constructor(private val readReceiptHandle // PRIVATE METHODS ***************************************************************************** - private fun handleRoomSync(realm: Realm, handlingStrategy: HandlingStrategy, isInitialSync: Boolean, reporter: DefaultInitialSyncProgressService?) { + private suspend fun handleRoomSync(realm: Realm, handlingStrategy: HandlingStrategy, isInitialSync: Boolean, reporter: DefaultInitialSyncProgressService?) { val insertType = if (isInitialSync) { EventInsertType.INITIAL_SYNC } else { @@ -123,7 +123,7 @@ internal class RoomSyncHandler @Inject constructor(private val readReceiptHandle realm.insertOrUpdate(rooms) } - private fun handleJoinedRoom(realm: Realm, + private suspend fun handleJoinedRoom(realm: Realm, roomId: String, roomSync: RoomSync, isInitialSync: Boolean, @@ -271,7 +271,7 @@ internal class RoomSyncHandler @Inject constructor(private val readReceiptHandle return roomEntity } - private fun handleTimelineEvents(realm: Realm, + private suspend fun handleTimelineEvents(realm: Realm, roomId: String, roomEntity: RoomEntity, eventList: List, diff --git a/rust-sdk/src/machine.rs b/rust-sdk/src/machine.rs index 12072f4e73..4f0b8b0b12 100644 --- a/rust-sdk/src/machine.rs +++ b/rust-sdk/src/machine.rs @@ -17,7 +17,7 @@ use matrix_sdk_common::{ }, assign, deserialized_responses::events::{AlgorithmInfo, SyncMessageEvent}, - events::{room::encrypted::EncryptedEventContent, EventContent}, + events::{room::encrypted::EncryptedEventContent, AnyMessageEventContent, EventContent}, identifiers::{DeviceKeyAlgorithm, RoomId, UserId}, uuid::Uuid, UInt, @@ -128,7 +128,7 @@ pub enum Request { }, KeysQuery { request_id: String, - body: String, + users: Vec, }, } @@ -150,12 +150,10 @@ impl From for Request { } } KeysQuery(k) => { - let body = json!({ - "device_keys": k.device_keys, - }); + let users: Vec = k.device_keys.keys().map(|u| u.to_string()).collect(); Request::KeysQuery { request_id: r.request_id().to_string(), - body: serde_json::to_string(&body).expect("Can't serialize keys query request"), + users, } } ToDeviceRequest(t) => Request::from(t), @@ -334,6 +332,16 @@ impl OlmMachine { .unwrap(); } + pub fn update_tracked_users(&self, users: Vec) { + let users: Vec = users + .into_iter() + .filter_map(|u| UserId::try_from(u).ok()) + .collect(); + + self.runtime + .block_on(self.inner.update_tracked_users(users.iter())); + } + pub fn decrypt_room_event( &self, event: &str, diff --git a/rust-sdk/src/olm.udl b/rust-sdk/src/olm.udl index 30eee9a50d..0d38c07081 100644 --- a/rust-sdk/src/olm.udl +++ b/rust-sdk/src/olm.udl @@ -54,7 +54,7 @@ dictionary Sas { interface Request { ToDevice(string request_id, string event_type, string body); KeysUpload(string request_id, string body); - KeysQuery(string request_id, string body); + KeysQuery(string request_id, sequence users); }; enum RequestType { @@ -83,6 +83,7 @@ interface OlmMachine { Device? get_device([ByRef] string user_id, [ByRef] string device_id); sequence get_user_devices([ByRef] string user_id); sequence outgoing_requests(); + void update_tracked_users(sequence users); [Throws=CryptoStoreError] void mark_request_as_sent(