From 4e310f16d52770987ba40a1c622b3e96b68f15af Mon Sep 17 00:00:00 2001 From: Krille Date: Thu, 19 Oct 2023 16:44:27 +0200 Subject: [PATCH] feat: Add methods to load all room keys from online key backup This makes it possible to load and sync all room keys right after the bootstrap if the app wants to do this. --- lib/encryption/key_manager.dart | 25 ++++++++++++++++ test/encryption/online_key_backup_test.dart | 32 +++++++++++++++++++-- test/fake_matrix_api.dart | 4 +-- 3 files changed, 56 insertions(+), 5 deletions(-) diff --git a/lib/encryption/key_manager.dart b/lib/encryption/key_manager.dart index c179e5b8..d8cb59fb 100644 --- a/lib/encryption/key_manager.dart +++ b/lib/encryption/key_manager.dart @@ -667,6 +667,31 @@ class KeyManager { } } + /// Loads and stores all keys from the online key backup. This may take a + /// while for older and big accounts. + Future loadAllKeys() async { + final info = await getRoomKeysBackupInfo(); + final ret = await client.getRoomKeys(info.version); + await loadFromResponse(ret); + } + + /// Loads all room keys for a single room and stores them. This may take a + /// while for older and big rooms. + Future loadAllKeysFromRoom(String roomId) async { + final info = await getRoomKeysBackupInfo(); + final ret = await client.getRoomKeysByRoomId(roomId, info.version); + final keys = RoomKeys.fromJson({ + 'rooms': { + roomId: { + 'sessions': ret.sessions.map((k, s) => MapEntry(k, s.toJson())), + }, + }, + }); + await loadFromResponse(keys); + } + + /// Loads a single key for the specified room from the online key backup + /// and stores it. Future loadSingleKey(String roomId, String sessionId) async { final info = await getRoomKeysBackupInfo(); final ret = diff --git a/test/encryption/online_key_backup_test.dart b/test/encryption/online_key_backup_test.dart index 4e920615..acc76f0a 100644 --- a/test/encryption/online_key_backup_test.dart +++ b/test/encryption/online_key_backup_test.dart @@ -67,9 +67,35 @@ void main() { .request(client.getRoomById(roomId)!, sessionId, senderKey); expect( client.encryption!.keyManager - .getInboundGroupSession(roomId, sessionId) != - null, - true); + .getInboundGroupSession(roomId, sessionId) + ?.sessionId, + sessionId); + }); + + test('Load all Room Keys', () async { + if (!olmEnabled) return; + final keyManager = client.encryption!.keyManager; + const roomId = '!getroomkeys726s6s6q:example.com'; + const sessionId = 'ciM/JWTPrmiWPPZNkRLDPQYf9AW/I46bxyLSr+Bx5oU'; + expect(keyManager.getInboundGroupSession(roomId, sessionId), null); + await client.encryption!.keyManager.loadAllKeysFromRoom(roomId); + expect( + keyManager.getInboundGroupSession(roomId, sessionId)?.sessionId, + sessionId, + ); + }); + + test('Load all Keys', () async { + if (!olmEnabled) return; + final keyManager = client.encryption!.keyManager; + const roomId = '!getallkeys726s6s6q:example.com'; + const sessionId = 'ciM/JWTPrmiWPPZNkRLDPQYf9AW/I46bxyLSr+Bx5oU'; + expect(keyManager.getInboundGroupSession(roomId, sessionId), null); + await client.encryption!.keyManager.loadAllKeys(); + expect( + keyManager.getInboundGroupSession(roomId, sessionId)?.sessionId, + sessionId, + ); }); test('upload key', () async { diff --git a/test/fake_matrix_api.dart b/test/fake_matrix_api.dart index 0cb417a2..f92fa357 100644 --- a/test/fake_matrix_api.dart +++ b/test/fake_matrix_api.dart @@ -1936,7 +1936,7 @@ class FakeMatrixApi extends BaseClient { 'mac': 'QzKV/fgAs4U', }, }, - '/client/v3/room_keys/keys/${Uri.encodeComponent('!726s6s6q:example.com')}?version=5': + '/client/v3/room_keys/keys/${Uri.encodeComponent('!getroomkeys726s6s6q:example.com')}?version=5': (var req) => { 'sessions': { 'ciM/JWTPrmiWPPZNkRLDPQYf9AW/I46bxyLSr+Bx5oU': { @@ -1955,7 +1955,7 @@ class FakeMatrixApi extends BaseClient { }, '/client/v3/room_keys/keys?version=5': (var req) => { 'rooms': { - '!726s6s6q:example.com': { + '!getallkeys726s6s6q:example.com': { 'sessions': { 'ciM/JWTPrmiWPPZNkRLDPQYf9AW/I46bxyLSr+Bx5oU': { 'first_message_index': 0,