1#[allow(unused_macros)]
32#[macro_export]
33macro_rules! cryptostore_integration_tests {
34 () => {
35 mod cryptostore_integration_tests {
36 use std::collections::{BTreeMap, HashMap};
37 use std::time::Duration;
38
39 use assert_matches::assert_matches;
40 use matrix_sdk_test::async_test;
41 use ruma::{
42 device_id, events::secret::request::SecretName, room_id, serde::Raw,
43 to_device::DeviceIdOrAllDevices, user_id, DeviceId, RoomId, TransactionId, UserId,
44 };
45 use serde_json::value::to_raw_value;
46 use serde_json::json;
47 use matrix_sdk_common::deserialized_responses::WithheldCode;
48 use $crate::{
49 olm::{
50 Account, Curve25519PublicKey, InboundGroupSession, OlmMessageHash,
51 PrivateCrossSigningIdentity, SenderData, SenderDataType, Session
52 },
53 store::{
54 types::{
55 BackupDecryptionKey, Changes, DehydratedDeviceKey, DeviceChanges,
56 IdentityChanges, PendingChanges, StoredRoomKeyBundleData, RoomSettings,
57 },
58 CryptoStore, GossipRequest,
59 },
60 testing::{get_device, get_other_identity, get_own_identity},
61 types::{
62 events::{
63 dummy::DummyEventContent,
64 olm_v1::{DecryptedSecretSendEvent, OlmV1Keys},
65 room_key_request::MegolmV1AesSha2Content,
66 room_key_withheld::{
67 CommonWithheldCodeContent, MegolmV1AesSha2WithheldContent,
68 RoomKeyWithheldContent,
69 },
70 room_key_bundle::RoomKeyBundleContent,
71 secret_send::SecretSendContent,
72 ToDeviceEvent,
73 },
74 requests::ToDeviceRequest,
75 DeviceKeys,
76 EventEncryptionAlgorithm,
77 },
78 vodozemac::megolm::{GroupSession, SessionConfig}, DeviceData, GossippedSecret, LocalTrust, SecretInfo,
79 TrackedUser,
80 };
81
82 use super::get_store;
83
84 fn alice_id() -> &'static UserId {
85 user_id!("@alice:example.org")
86 }
87
88 fn alice_device_id() -> &'static DeviceId {
89 device_id!("ALICEDEVICE")
90 }
91
92 fn bob_id() -> &'static UserId {
93 user_id!("@bob:example.org")
94 }
95
96 fn bob_device_id() -> &'static DeviceId {
97 device_id!("BOBDEVICE")
98 }
99
100 pub async fn get_loaded_store(name: &str) -> (Account, impl CryptoStore) {
101 let store = get_store(name, None, true).await;
102 let account = get_account();
103
104 store.save_pending_changes(PendingChanges { account: Some(account.deep_clone()), }).await.expect("Can't save account");
105
106 (account, store)
107 }
108
109 fn get_account() -> Account {
110 Account::with_device_id(alice_id(), alice_device_id())
111 }
112
113 pub(crate) async fn get_account_and_session() -> (Account, Session) {
114 let alice = Account::with_device_id(alice_id(), alice_device_id());
115 let mut bob = Account::with_device_id(bob_id(), bob_device_id());
116
117 bob.generate_one_time_keys(1);
118 let one_time_key = *bob.one_time_keys().values().next().unwrap();
119 let sender_key = bob.identity_keys().curve25519;
120 let session = alice.create_outbound_session_helper(
121 Default::default(),
122 sender_key,
123 one_time_key,
124 false,
125 alice.device_keys(),
126 );
127
128 (alice, session)
129 }
130
131 #[async_test]
132 async fn test_save_account_via_generic_save() {
133 let store = get_store("save_account_via_generic", None, true).await;
134 assert!(store.get_static_account().is_none());
135 assert!(store.load_account().await.unwrap().is_none());
136 let account = get_account();
137
138 store
139 .save_pending_changes(PendingChanges { account: Some(account) })
140 .await
141 .expect("Can't save account");
142 assert!(store.get_static_account().is_some());
143 }
144
145 #[async_test]
146 async fn test_save_account() {
147 let store = get_store("save_account", None, true).await;
148 assert!(store.get_static_account().is_none());
149 assert!(store.load_account().await.unwrap().is_none());
150 let account = get_account();
151
152 store
153 .save_pending_changes(PendingChanges { account: Some(account) })
154 .await
155 .expect("Can't save account");
156 assert!(store.get_static_account().is_some());
157 }
158
159 #[async_test]
160 async fn test_load_account() {
161 let store = get_store("load_account", None, true).await;
162 let account = get_account();
163
164 store
165 .save_pending_changes(PendingChanges { account: Some(account.deep_clone()) })
166 .await
167 .expect("Can't save account");
168
169 let loaded_account = store.load_account().await.expect("Can't load account");
170 let loaded_account = loaded_account.unwrap();
171
172 assert_eq!(account, loaded_account);
173 }
174
175 #[async_test]
176 async fn test_load_account_with_passphrase() {
177 let passphrase = Some("secret_passphrase");
178 let store = get_store("load_account_with_passphrase", passphrase, true).await;
179 let account = get_account();
180
181 store
182 .save_pending_changes(PendingChanges { account: Some(account.deep_clone()) })
183 .await
184 .expect("Can't save account");
185
186 let loaded_account = store.load_account().await.expect("Can't load account");
187 let loaded_account = loaded_account.unwrap();
188
189 assert_eq!(account, loaded_account);
190 }
191
192 #[async_test]
193 async fn test_save_and_share_account() {
194 let store = get_store("save_and_share_account", None, true).await;
195 let mut account = get_account();
196
197 store
198 .save_pending_changes(PendingChanges { account: Some(account.deep_clone()) })
199 .await
200 .expect("Can't save account");
201
202 account.mark_as_shared();
203 account.update_uploaded_key_count(50);
204
205 store
206 .save_pending_changes(PendingChanges { account: Some(account.deep_clone()) })
207 .await
208 .expect("Can't save account");
209
210 let loaded_account = store.load_account().await.expect("Can't load account");
211 let loaded_account = loaded_account.unwrap();
212
213 assert_eq!(account, loaded_account);
214 assert_eq!(account.uploaded_key_count(), loaded_account.uploaded_key_count());
215 }
216
217 #[async_test]
218 async fn test_load_sessions() {
219 let store = get_store("load_sessions", None, true).await;
220 let (account, session) = get_account_and_session().await;
221 store
222 .save_pending_changes(PendingChanges { account: Some(account.deep_clone()) })
223 .await
224 .expect("Can't save account");
225
226 let changes = Changes {
227 sessions: vec![session.clone()],
228 devices: DeviceChanges { new: vec![DeviceData::from_account(&account)], ..Default::default() },
229 ..Default::default()
230 };
231
232 store.save_changes(changes).await.unwrap();
233
234 let sessions = store
235 .get_sessions(&session.sender_key.to_base64())
236 .await
237 .expect("Can't load sessions")
238 .unwrap();
239 let loaded_session = sessions.get(0).cloned().expect("We should find the session in the store.");
240
241 assert_eq!(&session, &loaded_session, "The loaded session should be the same one we put into the store.");
242 }
243
244 #[async_test]
245 async fn test_add_and_save_session() {
246 let store_name = "add_and_save_session";
247
248 let (session_id, account, sender_key) = {
250 let store = get_store(store_name, None, true).await;
251 let (account, session) = get_account_and_session().await;
252 let sender_key = session.sender_key.to_base64();
253 let session_id = session.session_id().to_owned();
254
255 store
256 .save_pending_changes(PendingChanges {
257 account: Some(account.deep_clone()),
258 })
259 .await
260 .expect("Can't save account");
261 store
262 .save_changes(Changes {
263 devices: DeviceChanges {
264 new: vec![DeviceData::from_account(&account)],
265 ..Default::default()
266 },
267 ..Default::default()
268 })
269 .await
270 .unwrap();
271
272 let changes = Changes { sessions: vec![session.clone()], ..Default::default() };
273 store.save_changes(changes).await.unwrap();
274
275 let sessions = store.get_sessions(&sender_key).await.unwrap().unwrap();
276 let session = &sessions[0];
277
278 assert_eq!(session_id, session.session_id());
279
280 (session_id, account, sender_key)
281 };
282
283 let store = get_store(store_name, None, false).await;
285
286 let loaded_account = store.load_account().await.unwrap().unwrap();
288 assert_eq!(account, loaded_account);
289
290 let sessions = store.get_sessions(&sender_key).await.unwrap().unwrap();
291 let session = &sessions[0];
292
293 assert_eq!(session_id, session.session_id());
294 }
295
296 #[async_test]
297 async fn test_load_outbound_group_session() {
298 let dir = "load_outbound_group_session";
299 let room_id = room_id!("!test:localhost");
300
301 {
303 let (account, store) = get_loaded_store(dir.clone()).await;
304 assert!(
305 store.get_outbound_group_session(&room_id).await.unwrap().is_none(),
306 "Initially there should be no outbound group session"
307 );
308
309 let (session, _) =
310 account.create_group_session_pair_with_defaults(&room_id).await;
311
312 let user_id = user_id!("@example:localhost");
313 let request = ToDeviceRequest::new(
314 user_id,
315 DeviceIdOrAllDevices::AllDevices,
316 "m.dummy",
317 Raw::from_json(to_raw_value(&DummyEventContent::new()).unwrap()),
318 );
319
320 session.add_request(TransactionId::new(), request.into(), Default::default());
321
322 let changes = Changes {
323 outbound_group_sessions: vec![session.clone()],
324 ..Default::default()
325 };
326
327 store.save_changes(changes).await.expect("Can't save group session");
328 assert!(
329 store.get_outbound_group_session(&room_id).await.unwrap().is_some(),
330 "Sanity: after we've saved one, there should be an outbound_group_session"
331 );
332 }
333
334 let store = get_store(dir, None, false).await;
336 store.load_account().await.unwrap();
337
338 assert!(
340 store.get_outbound_group_session(&room_id).await.unwrap().is_some(),
341 "The outbound_group_session should have been loaded"
342 );
343 }
344
345 #[async_test]
347 async fn test_save_changes_save_inbound_group_session() {
348 let (account, store) = get_loaded_store("save_inbound_group_session").await;
349
350 let room_id = &room_id!("!test:localhost");
351 let (_, session) = account.create_group_session_pair_with_defaults(room_id).await;
352
353 let changes =
354 Changes { inbound_group_sessions: vec![session], ..Default::default() };
355
356 store.save_changes(changes).await.expect("Can't save group session");
357 }
358
359 #[async_test]
362 async fn test_save_inbound_group_session_from_backup() {
363 let (account, store) =
364 get_loaded_store("save_inbound_group_session_from_backup").await;
365
366 let room_id = &room_id!("!test:localhost");
367 let (_, session) = account.create_group_session_pair_with_defaults(room_id).await;
368
369 session.mark_as_backed_up();
370 store
371 .save_inbound_group_sessions(vec![session.clone()], Some(&"bkpver1"))
372 .await
373 .expect("could not save sessions");
374
375 let loaded_session = store
376 .get_inbound_group_session(&session.room_id, session.session_id())
377 .await
378 .expect("error when loading session")
379 .expect("session not found in store");
380 assert_eq!(session, loaded_session);
381 assert_eq!(store.get_inbound_group_sessions().await.unwrap().len(), 1);
382 assert_eq!(store.inbound_group_session_counts(None).await.unwrap().total, 1);
383
384 let to_back_up = store.inbound_group_sessions_for_backup("bkpver1", 1).await.unwrap();
386 assert_eq!(to_back_up.len(), 0, "backup was returned by backup query");
387 assert_eq!(
388 store.inbound_group_session_counts(Some(&"bkpver1")).await.unwrap().backed_up, 1,
389 "backed_up count",
390 );
391 }
392
393 #[ignore]
398 #[async_test]
399 async fn test_save_inbound_group_session_from_old_backup() {
400 let (account, store) =
401 get_loaded_store("save_inbound_group_session_from_old_backup").await;
402
403 let room_id = &room_id!("!test:localhost");
404 let (_, session) = account.create_group_session_pair_with_defaults(room_id).await;
405
406 session.mark_as_backed_up();
407 store
408 .save_inbound_group_sessions(vec![session.clone()], Some(&"bkpver1"))
409 .await
410 .expect("could not save sessions");
411
412 let to_back_up = store.inbound_group_sessions_for_backup("bkpver2", 1).await.unwrap();
414 assert_eq!(to_back_up, vec![session]);
415 assert_eq!(
416 store.inbound_group_session_counts(Some(&"bkpver2")).await.unwrap().backed_up, 0,
417 "backed_up count for backup version 2",
418 );
419 }
420
421 #[async_test]
424 async fn test_save_inbound_group_session_from_import() {
425 let (account, store) =
426 get_loaded_store("save_inbound_group_session_from_import").await;
427
428 let room_id = &room_id!("!test:localhost");
429 let (_, session) = account.create_group_session_pair_with_defaults(room_id).await;
430
431 store
432 .save_inbound_group_sessions(vec![session.clone()], None)
433 .await
434 .expect("could not save sessions");
435
436 let loaded_session = store
437 .get_inbound_group_session(&session.room_id, session.session_id())
438 .await
439 .expect("error when loading session")
440 .expect("session not found in store");
441 assert_eq!(session, loaded_session);
442 assert_eq!(store.get_inbound_group_sessions().await.unwrap().len(), 1);
443 assert_eq!(store.inbound_group_session_counts(None).await.unwrap().total, 1);
444 assert_eq!(store.inbound_group_session_counts(None).await.unwrap().backed_up, 0);
445
446 let to_back_up = store.inbound_group_sessions_for_backup("bkpver1", 1).await.unwrap();
448 assert_eq!(to_back_up, vec![session]);
449 }
450
451 #[async_test]
452 async fn test_mark_inbound_group_sessions_as_backed_up() {
453 let (account, store) =
455 get_loaded_store("mark_inbound_group_sessions_as_backed_up").await;
456 let room_id = &room_id!("!test:localhost");
457 let mut sessions: Vec<InboundGroupSession> = Vec::with_capacity(10);
458 for _i in 0..10 {
459 sessions.push(account.create_group_session_pair_with_defaults(room_id).await.1);
460 }
461 let changes = Changes { inbound_group_sessions: sessions.clone(), ..Default::default() };
462 store.save_changes(changes).await.expect("Can't save group session");
463 assert_eq!(store.inbound_group_sessions_for_backup("bkpver", 100).await.unwrap().len(), 10);
464
465 store.mark_inbound_group_sessions_as_backed_up("bkpver", &[
467 session_info(&sessions[1]),
468 session_info(&sessions[3]),
469 session_info(&sessions[5]),
470 session_info(&sessions[7]),
471 session_info(&sessions[9]),
472 ]).await.expect("Failed to mark sessions as backed up");
473
474 let to_back_up = store.inbound_group_sessions_for_backup("bkpver", 10).await.unwrap();
476 let needs_backing_up = |i: usize| to_back_up.iter().any(|s| s.session_id() == sessions[i].session_id());
477
478 assert!(!needs_backing_up(1));
480 assert!(!needs_backing_up(3));
481 assert!(!needs_backing_up(5));
482 assert!(!needs_backing_up(7));
483 assert!(!needs_backing_up(9));
484
485 assert!(needs_backing_up(0));
487 assert!(needs_backing_up(2));
488 assert!(needs_backing_up(4));
489 assert!(needs_backing_up(6));
490 assert!(needs_backing_up(8));
491 assert_eq!(to_back_up.len(), 5);
492 }
493
494 #[async_test]
495 async fn test_reset_inbound_group_session_for_backup() {
496 let (account, store) =
498 get_loaded_store("reset_inbound_group_session_for_backup").await;
499 let room_id = &room_id!("!test:localhost");
500 let mut sessions: Vec<InboundGroupSession> = Vec::with_capacity(10);
501 for _ in 0..10 {
502 sessions.push(account.create_group_session_pair_with_defaults(room_id).await.1);
503 }
504 let changes = Changes { inbound_group_sessions: sessions.clone(), ..Default::default() };
505 store.save_changes(changes).await.expect("Can't save group session");
506 assert_eq!(store.inbound_group_sessions_for_backup("backup_1", 100).await.unwrap().len(), 10);
507 store.mark_inbound_group_sessions_as_backed_up(
508 "backup_1",
509 &(0..10).map(|i| session_info(&sessions[i])).collect::<Vec<_>>(),
510 ).await.expect("Failed to mark sessions as backed up");
511
512 {
514 let to_back_up_old = store.inbound_group_sessions_for_backup("backup_1", 10).await.unwrap();
515 assert_eq!(to_back_up_old.len(), 0);
516 }
517
518 store.reset_backup_state().await.expect("reset failed");
521
522 let to_back_up = store.inbound_group_sessions_for_backup("backup_02", 10).await.unwrap();
524
525 let needs_backing_up = |i: usize| to_back_up.iter().any(|s| s.session_id() == sessions[i].session_id());
527 assert!(needs_backing_up(0));
528 assert!(needs_backing_up(1));
529 assert!(needs_backing_up(8));
530 assert!(needs_backing_up(9));
531 assert_eq!(to_back_up.len(), 10);
532 }
533
534 #[async_test]
535 async fn test_load_inbound_group_session() {
536 let dir = "load_inbound_group_session";
537 let (account, store) = get_loaded_store(dir).await;
538 assert_eq!(store.get_inbound_group_sessions().await.unwrap().len(), 0);
539
540 let room_id = &room_id!("!test:localhost");
541 let (_, session) = account.create_group_session_pair_with_defaults(room_id).await;
542
543 let export = session.export().await;
544
545 let session = InboundGroupSession::from_export(&export).unwrap();
546
547 let changes =
548 Changes { inbound_group_sessions: vec![session.clone()], ..Default::default() };
549
550 store.save_changes(changes).await.expect("Can't save group session");
551
552 drop(store);
553
554 let store = get_store(dir, None, false).await;
555
556 store.load_account().await.unwrap();
557
558 let loaded_session = store
559 .get_inbound_group_session(&session.room_id, session.session_id())
560 .await
561 .unwrap()
562 .unwrap();
563 assert_eq!(session, loaded_session);
564 loaded_session.export().await;
565
566 assert_eq!(store.get_inbound_group_sessions().await.unwrap().len(), 1);
567 assert_eq!(store.inbound_group_session_counts(None).await.unwrap().total, 1);
568 }
569
570 #[async_test]
571 async fn test_get_inbound_group_sessions_by_room_id_empty() {
572 let dir = "get_inbound_group_session_by_room_id_empty";
573 let (_, store) = get_loaded_store(dir).await;
574 assert_eq!(store.get_inbound_group_sessions().await.unwrap().len(), 0);
575
576 let room_id = &room_id!("!testing:localhost");
577 assert_eq!(store.get_inbound_group_sessions_by_room_id(room_id).await.unwrap().len(), 0);
578 }
579
580 #[async_test]
581 async fn test_get_inbound_group_sessions_by_room_id() {
582 let dir = "get_inbound_group_session_by_room_id";
583 let (account, store) = get_loaded_store(dir).await;
584 assert_eq!(store.get_inbound_group_sessions().await.unwrap().len(), 0);
585
586 let room_id = &room_id!("!testing:localhost");
587 let (_, session_1) = account.create_group_session_pair_with_defaults(room_id).await;
588 let (_, session_2) = account.create_group_session_pair_with_defaults(room_id).await;
589
590 let second_room_id = &room_id!("!other_room_testing:localhost");
591 let (_, session_3) = account.create_group_session_pair_with_defaults(second_room_id).await;
592
593 let mut sessions = vec![
594 session_1,
595 session_2,
596 session_3
597 ];
598
599 let changes = Changes {
600 inbound_group_sessions: sessions.clone(),
601 ..Default::default()
602 };
603 store.save_changes(changes).await.expect("Can't save group session");
604
605 drop(store);
606
607 sessions.pop();
610
611 let store = get_store(dir, None, false).await;
612 assert_eq!(store.get_inbound_group_sessions().await.unwrap().len(), 3);
614
615 store.load_account().await.unwrap();
616
617 let loaded_sessions = store
618 .get_inbound_group_sessions_by_room_id(room_id)
619 .await
620 .unwrap();
621
622 assert_eq!(loaded_sessions.len(), 2);
623 assert_session_lists_eq(sessions, loaded_sessions, "room by id sessions");
624 }
625
626 #[async_test]
627 async fn test_fetch_inbound_group_sessions_for_device() {
628 let (account, store) =
630 get_loaded_store("fetch_inbound_group_sessions_for_device").await;
631
632 let dev1 = Curve25519PublicKey::from_base64(
633 "wjLpTLRqbqBzLs63aYaEv2Boi6cFEbbM/sSRQ2oAKk4"
634 ).unwrap();
635 let dev2 = Curve25519PublicKey::from_base64(
636 "LTpv2DGMhggPAXO02+7f68CNEp6A40F0Yl8B094Y8gc"
637 ).unwrap();
638
639 let dev_1_unknown_a = create_session(&account, &dev1, SenderDataType::UnknownDevice).await;
640 let dev_1_unknown_b = create_session(&account, &dev1, SenderDataType::UnknownDevice).await;
641
642 let dev_1_keys_a = create_session(&account, &dev1, SenderDataType::DeviceInfo).await;
643 let dev_1_keys_b = create_session(&account, &dev1, SenderDataType::DeviceInfo).await;
644 let dev_1_keys_c = create_session(&account, &dev1, SenderDataType::DeviceInfo).await;
645 let dev_1_keys_d = create_session(&account, &dev1, SenderDataType::DeviceInfo).await;
646
647 let dev_2_unknown = create_session(
648 &account, &dev2, SenderDataType::UnknownDevice).await;
649
650 let dev_2_keys = create_session(
651 &account, &dev2, SenderDataType::DeviceInfo).await;
652
653 let sessions = vec![
654 dev_1_unknown_a.clone(),
655 dev_1_unknown_b.clone(),
656 dev_1_keys_a.clone(),
657 dev_1_keys_b.clone(),
658 dev_1_keys_c.clone(),
659 dev_1_keys_d.clone(),
660 dev_2_unknown.clone(),
661 dev_2_keys.clone(),
662 ];
663
664 let changes = Changes {
665 inbound_group_sessions: sessions,
666 ..Default::default()
667 };
668 store.save_changes(changes).await.expect("Can't save group session");
669
670 let sessions_1_u = store.get_inbound_group_sessions_for_device_batch(
672 dev1,
673 SenderDataType::UnknownDevice,
674 None,
675 10
676 ).await.expect("Failed to get sessions for dev1");
677
678 assert_session_lists_eq(sessions_1_u, [dev_1_unknown_a, dev_1_unknown_b], "device 1 sessions");
680
681 let sessions_2_d = store
683 .get_inbound_group_sessions_for_device_batch(dev2, SenderDataType::DeviceInfo, None, 10)
684 .await
685 .expect("Failed to get sessions for dev2");
686
687 assert_eq!(sessions_2_d, vec![dev_2_keys], "device 2 sessions");
689
690 let mut sessions_1_k = Vec::new();
693 let mut previous_last_session_id: Option<String> = None;
694 loop {
695 let mut sessions_1_k_batch = store.get_inbound_group_sessions_for_device_batch(
696 dev1,
697 SenderDataType::DeviceInfo,
698 previous_last_session_id,
699 2
700 ).await.expect("Failed to get batch 1");
701
702 let Some(last_session) = sessions_1_k_batch.last() else {
704 break;
705 };
706
707 assert_eq!(sessions_1_k_batch.len(), 2);
709
710 previous_last_session_id = Some(last_session.session_id().to_owned());
711
712 let mut last_session = last_session.clone();
714 last_session.sender_data = SenderData::unknown();
715 store.save_inbound_group_sessions(vec![last_session], None).await.unwrap();
716
717 sessions_1_k.append(&mut sessions_1_k_batch);
718 }
719
720 assert_session_lists_eq(
721 sessions_1_k,
722 [dev_1_keys_a, dev_1_keys_b, dev_1_keys_c, dev_1_keys_d],
723 "device 1 batched results"
724 );
725 }
726
727 fn assert_session_lists_eq<I, J>(actual: I, expected: J, message: &str)
733 where I: IntoIterator<Item = InboundGroupSession>, J: IntoIterator<Item = InboundGroupSession>
734 {
735 let sorter = |a: &InboundGroupSession, b: &InboundGroupSession| Ord::cmp(a.session_id(), b.session_id());
736
737 let mut actual = Vec::from_iter(actual);
738 actual.sort_unstable_by(sorter);
739 let mut expected = Vec::from_iter(expected);
740 expected.sort_unstable_by(sorter);
741 assert_eq!(actual, expected, "{}", message);
742 }
743
744 #[async_test]
745 async fn test_tracked_users() {
746 let dir = "test_tracked_users";
747 let (_account, store) = get_loaded_store(dir.clone()).await;
748
749 let alice = user_id!("@alice:example.org");
750 let bob = user_id!("@bob:example.org");
751 let candy = user_id!("@candy:example.org");
752
753 let loaded = store.load_tracked_users().await.unwrap();
754 assert!(loaded.is_empty(), "Initially there are no tracked users");
755
756 let users = vec![(alice, true), (bob, false)];
757 store.save_tracked_users(&users).await.unwrap();
758
759 let check_loaded_users = |loaded: Vec<TrackedUser>| {
760 let loaded: HashMap<_, _> =
761 loaded.into_iter().map(|u| (u.user_id.to_owned(), u)).collect();
762
763 let loaded_alice =
764 loaded.get(alice).expect("Alice should be in the store as a tracked user");
765 let loaded_bob =
766 loaded.get(bob).expect("Bob should be in the store as as tracked user");
767
768 assert!(!loaded.contains_key(candy), "Candy shouldn't be part of the store");
769 assert_eq!(loaded.len(), 2, "Candy shouldn't be part of the store");
770
771 assert!(loaded_alice.dirty, "Alice should be considered to be dirty");
772 assert!(!loaded_bob.dirty, "Bob should not be considered to be dirty");
773 };
774
775 let loaded = store.load_tracked_users().await.unwrap();
776 check_loaded_users(loaded);
777
778 drop(store);
779
780 let name = dir.clone();let store = get_store(name, None, false).await;
781 let loaded = store.load_tracked_users().await.unwrap();
782 check_loaded_users(loaded);
783 }
784
785 #[async_test]
786 async fn test_device_saving() {
787 let dir = "device_saving";
788 let (_account, store) = get_loaded_store(dir.clone()).await;
789
790 let alice_device_1 = DeviceData::from_account(&Account::with_device_id(
791 "@alice:localhost".try_into().unwrap(),
792 "FIRSTDEVICE".into(),
793 ));
794
795 let alice_device_2 = DeviceData::from_account(&Account::with_device_id(
796 "@alice:localhost".try_into().unwrap(),
797 "SECONDDEVICE".into(),
798 ));
799
800 let json = json!({
801 "algorithms": ["m.olm.v1.curve25519-aes-sha2", "m.megolm.v1.aes-sha2"],
802 "user_id": "@bob:localhost",
803 "device_id": "BOBDEVICE",
804 "extra_property": "somevalue",
805 "keys": {
806 "curve25519:BOBDEVICE": "n0zs7qnaPLLf/OTL+dDLcI5kaPexbUeQ8jLQ2q6sO0E",
807 "ed25519:BOBDEVICE": "RrKiu4+5EHRBWY6Qj6OtQGC0txpmEeanOz2irEZ/IN4",
808 },
809 "signatures": {
810 "@bob:localhost": {
811 "ed25519:BOBDEVICE": "9NjPewVHfB7Ah32mJ+CBx64mVoiQ8gbh+/2pc9WfAgut/H0Kqd/bbpgJq9Pn518szaXcGqEq0DxDP6CABBX8CQ",
812 },
813 },
814 });
815
816 let bob_device_1_keys: DeviceKeys = serde_json::from_value(json).unwrap();
817 let bob_device_1 = DeviceData::new(bob_device_1_keys, LocalTrust::Unset);
818
819 let changes = Changes {
820 devices: DeviceChanges {
821 new: vec![alice_device_1.clone(), alice_device_2.clone(), bob_device_1.clone()],
822 ..Default::default()
823 },
824 ..Default::default()
825 };
826
827 store.save_changes(changes).await.unwrap();
828
829 drop(store);
830
831 let store = get_store(dir, None, false).await;
832
833 store.load_account().await.unwrap();
834
835 let loaded_device = store
836 .get_device(alice_device_1.user_id(), alice_device_1.device_id())
837 .await
838 .unwrap()
839 .unwrap();
840
841 assert_eq!(alice_device_1, loaded_device);
842
843 for algorithm in loaded_device.algorithms() {
844 assert!(alice_device_1.algorithms().contains(algorithm));
845 }
846 assert_eq!(alice_device_1.algorithms().len(), loaded_device.algorithms().len());
847 assert_eq!(alice_device_1.keys(), loaded_device.keys());
848
849 let user_devices = store.get_user_devices(alice_device_1.user_id()).await.unwrap();
850 assert_eq!(user_devices.len(), 2);
851
852 let bob_device = store
853 .get_device(bob_device_1.user_id(), bob_device_1.device_id())
854 .await
855 .unwrap();
856
857 let bob_device_json = serde_json::to_value(bob_device).unwrap();
858 assert_eq!(bob_device_json["device_keys"]["extra_property"], json!("somevalue"));
859 }
860
861 #[async_test]
862 async fn test_device_deleting() {
863 let dir = "device_deleting";
864 let (_account, store) = get_loaded_store(dir.clone()).await;
865 let device = get_device();
866
867 let changes = Changes {
868 devices: DeviceChanges { changed: vec![device.clone()], ..Default::default() },
869 ..Default::default()
870 };
871
872 store.save_changes(changes).await.unwrap();
873
874 let changes = Changes {
875 devices: DeviceChanges { deleted: vec![device.clone()], ..Default::default() },
876 ..Default::default()
877 };
878
879 store.save_changes(changes).await.unwrap();
880 drop(store);
881
882 let store = get_store(dir, None, false).await;
883
884 store.load_account().await.unwrap();
885
886 let loaded_device =
887 store.get_device(device.user_id(), device.device_id()).await.unwrap();
888
889 assert!(loaded_device.is_none());
890 }
891
892 #[async_test]
893 async fn test_user_saving() {
894 let dir = "user_saving";
895
896 let user_id = user_id!("@example:localhost");
897 let device_id: &DeviceId = "WSKKLTJZCL".into();
898
899 let store = get_store(dir, None, true).await;
900
901 let account = Account::with_device_id(&user_id, device_id);
902
903 store.save_pending_changes(PendingChanges { account: Some(account), })
904 .await
905 .expect("Can't save account");
906
907 let own_identity = get_own_identity();
908
909 let changes = Changes {
910 identities: IdentityChanges {
911 changed: vec![own_identity.clone().into()],
912 ..Default::default()
913 },
914 ..Default::default()
915 };
916
917 store.save_changes(changes).await.expect("Can't save identity");
918
919 drop(store);
920
921 let store = get_store(dir, None, false).await;
922
923 store.load_account().await.unwrap();
924
925 let loaded_user =
926 store.get_user_identity(own_identity.user_id()).await.unwrap().unwrap();
927
928 assert_eq!(loaded_user.master_key(), own_identity.master_key());
929 assert_eq!(loaded_user.self_signing_key(), own_identity.self_signing_key());
930 assert_eq!(loaded_user.own().unwrap().clone(), own_identity.clone());
931
932 let other_identity = get_other_identity();
933
934 let changes = Changes {
935 identities: IdentityChanges {
936 changed: vec![other_identity.clone().into()],
937 ..Default::default()
938 },
939 ..Default::default()
940 };
941
942 store.save_changes(changes).await.unwrap();
943
944 let loaded_user =
945 store.get_user_identity(other_identity.user_id()).await.unwrap().unwrap();
946
947 assert_eq!(loaded_user.master_key(), other_identity.master_key());
948 assert_eq!(loaded_user.self_signing_key(), other_identity.self_signing_key());
949 assert_eq!(loaded_user.user_id(), other_identity.user_id());
950 assert_eq!(loaded_user.other().unwrap().clone(), other_identity);
951
952 own_identity.mark_as_verified();
953
954 let changes = Changes {
955 identities: IdentityChanges {
956 changed: vec![own_identity.into()],
957 ..Default::default()
958 },
959 ..Default::default()
960 };
961
962 store.save_changes(changes).await.unwrap();
963 let loaded_user = store.get_user_identity(&user_id).await.unwrap().unwrap();
964 assert!(loaded_user.own().unwrap().is_verified())
965 }
966
967 #[async_test]
968 async fn test_private_identity_saving() {
969 let (_, store) = get_loaded_store("private_identity_saving").await;
970 assert!(store.load_identity().await.unwrap().is_none());
971 let identity = PrivateCrossSigningIdentity::new(alice_id().to_owned());
972
973 let changes =
974 Changes { private_identity: Some(identity.clone()), ..Default::default() };
975
976 store.save_changes(changes).await.unwrap();
977 let loaded_identity = store.load_identity().await.unwrap().unwrap();
978 assert_eq!(identity.user_id(), loaded_identity.user_id());
979 }
980
981 #[async_test]
982 async fn test_olm_hash_saving() {
983 let (_, store) = get_loaded_store("olm_hash_saving").await;
984
985 let hash = OlmMessageHash {
986 sender_key: "test_sender".to_owned(),
987 hash: "test_hash".to_owned(),
988 };
989
990 let mut changes = Changes::default();
991 changes.message_hashes.push(hash.clone());
992
993 assert!(!store.is_message_known(&hash).await.unwrap());
994 store.save_changes(changes).await.unwrap();
995 assert!(store.is_message_known(&hash).await.unwrap());
996 }
997
998 #[async_test]
999 async fn test_key_request_saving() {
1000 let (account, store) = get_loaded_store("key_request_saving").await;
1001 let sender_key =
1002 Curve25519PublicKey::from_base64("Nn0L2hkcCMFKqynTjyGsJbth7QrVmX3lbrksMkrGOAw")
1003 .unwrap();
1004
1005 let id = TransactionId::new();
1006 let info: SecretInfo = MegolmV1AesSha2Content {
1007 room_id: room_id!("!test:localhost").to_owned(),
1008 sender_key: Some(sender_key),
1009 session_id: "test_session_id".to_owned(),
1010 }
1011 .into();
1012
1013 let request = GossipRequest {
1014 request_recipient: account.user_id().to_owned(),
1015 request_id: id.clone(),
1016 info: info.clone(),
1017 sent_out: false,
1018 };
1019
1020 assert!(store.get_outgoing_secret_requests(&id).await.unwrap().is_none());
1021
1022 let mut changes = Changes::default();
1023 changes.key_requests.push(request.clone());
1024 store.save_changes(changes).await.unwrap();
1025
1026 let request = Some(request);
1027
1028 let stored_request = store.get_outgoing_secret_requests(&id).await.unwrap();
1029 assert_eq!(request, stored_request);
1030
1031 let stored_request = store.get_secret_request_by_info(&info).await.unwrap();
1032 assert_eq!(request, stored_request);
1033 assert!(!store.get_unsent_secret_requests().await.unwrap().is_empty());
1034
1035 let request = GossipRequest {
1036 request_recipient: account.user_id().to_owned(),
1037 request_id: id.clone(),
1038 info: info.clone(),
1039 sent_out: true,
1040 };
1041
1042 let mut changes = Changes::default();
1043 changes.key_requests.push(request.clone());
1044 store.save_changes(changes).await.unwrap();
1045
1046 assert!(store.get_unsent_secret_requests().await.unwrap().is_empty());
1047 let stored_request = store.get_outgoing_secret_requests(&id).await.unwrap();
1048 assert_eq!(Some(request), stored_request);
1049
1050 store.delete_outgoing_secret_requests(&id).await.unwrap();
1051
1052 let stored_request = store.get_outgoing_secret_requests(&id).await.unwrap();
1053 assert_eq!(None, stored_request);
1054
1055 let stored_request = store.get_secret_request_by_info(&info).await.unwrap();
1056 assert_eq!(None, stored_request);
1057 assert!(store.get_unsent_secret_requests().await.unwrap().is_empty());
1058 }
1059
1060 #[async_test]
1061 async fn test_gossipped_secret_saving() {
1062 let (account, store) = get_loaded_store("gossipped_secret_saving").await;
1063
1064 let secret = "It is a secret to everybody";
1065
1066 let id = TransactionId::new();
1067 let info: SecretInfo = MegolmV1AesSha2Content {
1068 room_id: room_id!("!test:localhost").to_owned(),
1069 sender_key: Some(account.identity_keys().curve25519),
1070 session_id: "test_session_id".to_owned(),
1071 }
1072 .into();
1073
1074 let gossip_request = GossipRequest {
1075 request_recipient: account.user_id().to_owned(),
1076 request_id: id.clone(),
1077 info: info.clone(),
1078 sent_out: true,
1079 };
1080
1081 let mut event = DecryptedSecretSendEvent {
1082 sender: account.user_id().to_owned(),
1083 recipient: account.user_id().to_owned(),
1084 keys: OlmV1Keys {
1085 ed25519: account.identity_keys().ed25519,
1086 },
1087 recipient_keys: OlmV1Keys {
1088 ed25519: account.identity_keys().ed25519,
1089 },
1090 sender_device_keys: None,
1091 content: SecretSendContent::new(id.to_owned(), secret.to_owned()),
1092 };
1093
1094 let value = GossippedSecret {
1095 secret_name: SecretName::RecoveryKey,
1096 gossip_request: gossip_request.to_owned(),
1097 event: event.to_owned(),
1098 };
1099
1100 assert!(
1101 store.get_secrets_from_inbox(&SecretName::RecoveryKey).await.unwrap().is_empty(),
1102 "No secret should initially be found in the store"
1103 );
1104
1105 let mut changes = Changes::default();
1106 changes.secrets.push(value);
1107 store.save_changes(changes).await.unwrap();
1108
1109 let restored = store.get_secrets_from_inbox(&SecretName::RecoveryKey).await.unwrap();
1110 let first_secret = restored.first().expect("We should have restored a secret now");
1111 assert_eq!(first_secret.event.content.secret, secret);
1112 assert_eq!(restored.len(), 1, "We should only have one secret stored for now");
1113
1114 event.content.request_id = TransactionId::new();
1115 let another_secret = GossippedSecret {
1116 secret_name: SecretName::RecoveryKey,
1117 gossip_request,
1118 event,
1119 };
1120
1121 let mut changes = Changes::default();
1122 changes.secrets.push(another_secret);
1123 store.save_changes(changes).await.unwrap();
1124
1125 let restored = store.get_secrets_from_inbox(&SecretName::RecoveryKey).await.unwrap();
1126 assert_eq!(restored.len(), 2, "We should only have two secrets stored");
1127
1128 let restored = store.get_secrets_from_inbox(&SecretName::CrossSigningMasterKey).await.unwrap();
1129 assert!(restored.is_empty(), "We should not have secrets of a different type stored");
1130
1131 store.delete_secrets_from_inbox(&SecretName::RecoveryKey).await.unwrap();
1132
1133 let restored = store.get_secrets_from_inbox(&SecretName::RecoveryKey).await.unwrap();
1134 assert!(restored.is_empty(), "We should not have any secrets after we have deleted them");
1135 }
1136
1137 #[async_test]
1138 async fn test_withheld_info_storage() {
1139 let (account, store) = get_loaded_store("withheld_info_storage").await;
1140
1141 let mut info_list: BTreeMap<_, BTreeMap<_, _>> = BTreeMap::new();
1142
1143 let user_id = account.user_id().to_owned();
1144 let room_id = room_id!("!DwLygpkclUAfQNnfva:example.com");
1145 let session_id_1 = "GBnDxGP9i3IkPsz3/ihNr6P7qjIXxSRVWZ1MYmSn09w";
1146 let session_id_2 = "IDLtnNCH2kIr3xIf1B7JFkGpQmTjyMca2jww+X6zeOE";
1147
1148 let content = RoomKeyWithheldContent::MegolmV1AesSha2(
1149 MegolmV1AesSha2WithheldContent::Unverified(
1150 CommonWithheldCodeContent::new(
1151 room_id.to_owned(),
1152 session_id_1.into(),
1153 Curve25519PublicKey::from_base64(
1154 "9n7mdWKOjr9c4NTlG6zV8dbFtNK79q9vZADoh7nMUwA",
1155 )
1156 .unwrap(),
1157 "DEVICEID".into(),
1158 )
1159 .into(),
1160 ),
1161 );
1162 let event = ToDeviceEvent::new(user_id.to_owned(), content);
1163 info_list
1164 .entry(room_id.to_owned())
1165 .or_default()
1166 .insert(session_id_1.to_owned(), event);
1167
1168 let content = RoomKeyWithheldContent::MegolmV1AesSha2(
1169 MegolmV1AesSha2WithheldContent::BlackListed(
1170 CommonWithheldCodeContent::new(
1171 room_id.to_owned(),
1172 session_id_2.into(),
1173 Curve25519PublicKey::from_base64(
1174 "9n7mdWKOjr9c4NTlG6zV8dbFtNK79q9vZADoh7nMUwA",
1175 )
1176 .unwrap(),
1177 "DEVICEID".into(),
1178 )
1179 .into(),
1180 ),
1181 );
1182 let event = ToDeviceEvent::new(user_id.to_owned(), content);
1183 info_list
1184 .entry(room_id.to_owned())
1185 .or_default()
1186 .insert(session_id_2.to_owned(), event);
1187
1188 let changes = Changes { withheld_session_info: info_list, ..Default::default() };
1189 store.save_changes(changes).await.unwrap();
1190
1191 let is_withheld = store.get_withheld_info(room_id, session_id_1).await.unwrap();
1192
1193 assert_matches!(
1194 is_withheld, Some(event)
1195 if event.content.algorithm() == EventEncryptionAlgorithm::MegolmV1AesSha2 &&
1196 event.content.withheld_code() == WithheldCode::Unverified
1197 );
1198
1199 let is_withheld = store.get_withheld_info(room_id, session_id_2).await.unwrap();
1200
1201 assert_matches!(
1202 is_withheld, Some(event)
1203 if event.content.algorithm() == EventEncryptionAlgorithm::MegolmV1AesSha2 &&
1204 event.content.withheld_code() == WithheldCode::Blacklisted
1205 );
1206
1207 let other_room_id = room_id!("!nQRyiRFuyUhXeaQfiR:example.com");
1208
1209 let is_withheld =
1210 store.get_withheld_info(other_room_id, session_id_2).await.unwrap();
1211
1212 assert!(is_withheld.is_none());
1213 }
1214
1215 #[async_test]
1216 async fn test_room_settings_saving() {
1217 let (_, store) = get_loaded_store("room_settings_saving").await;
1218
1219 let room_1 = room_id!("!test_1:localhost");
1220 let settings_1 = RoomSettings {
1221 algorithm: EventEncryptionAlgorithm::MegolmV1AesSha2,
1222 #[cfg(feature = "experimental-encrypted-state-events")]
1223 encrypt_state_events: false,
1224 only_allow_trusted_devices: true,
1225 session_rotation_period: Some(Duration::from_secs(10)),
1226 session_rotation_period_messages: Some(123),
1227 };
1228
1229 let room_2 = room_id!("!test_2:localhost");
1230 let settings_2 = RoomSettings {
1231 algorithm: EventEncryptionAlgorithm::OlmV1Curve25519AesSha2,
1232 only_allow_trusted_devices: false,
1233 ..Default::default()
1234 };
1235
1236 let room_3 = room_id!("!test_3:localhost");
1237
1238 let changes = Changes {
1239 room_settings: HashMap::from([
1240 (room_1.into(), settings_1.clone()),
1241 (room_2.into(), settings_2.clone()),
1242 ]),
1243 ..Default::default()
1244 };
1245
1246 store.save_changes(changes).await.unwrap();
1247
1248 let loaded_settings_1 = store.get_room_settings(room_1).await.unwrap();
1249 assert_eq!(Some(settings_1), loaded_settings_1);
1250
1251 let loaded_settings_2 = store.get_room_settings(room_2).await.unwrap();
1252 assert_eq!(Some(settings_2), loaded_settings_2);
1253
1254 let loaded_settings_3 = store.get_room_settings(room_3).await.unwrap();
1255 assert_eq!(None, loaded_settings_3);
1256 }
1257
1258 #[async_test]
1259 async fn test_backup_keys_saving() {
1260 let (_account, store) = get_loaded_store("backup_keys_saving").await;
1261
1262 let restored = store.load_backup_keys().await.unwrap();
1263 assert!(restored.decryption_key.is_none(), "Initially no backup decryption key should be present");
1264
1265 let backup_decryption_key = Some(BackupDecryptionKey::new().unwrap());
1266
1267 let changes = Changes { backup_decryption_key, ..Default::default() };
1268 store.save_changes(changes).await.unwrap();
1269
1270 let restored = store.load_backup_keys().await.unwrap();
1271 assert!(restored.decryption_key.is_some(), "We should be able to restore a backup decryption key");
1272 assert!(restored.backup_version.is_none(), "The backup version should still be None");
1273
1274 let changes = Changes { backup_version: Some("some_version".to_owned()), ..Default::default() };
1275 store.save_changes(changes).await.unwrap();
1276
1277 let restored = store.load_backup_keys().await.unwrap();
1278 assert!(restored.decryption_key.is_some(), "The backup decryption key should still be known");
1279 assert!(restored.backup_version.is_some(), "The backup version should now be Some as well");
1280 }
1281
1282 #[async_test]
1283 async fn test_dehydration_pickle_key_saving() {
1284 let (_account, store) = get_loaded_store("dehydration_pickle_key_saving").await;
1285
1286 let restored = store.load_dehydrated_device_pickle_key().await.unwrap();
1287 assert!(restored.is_none(), "Initially no pickle key should be present");
1288
1289 let dehydrated_device_pickle_key = Some(DehydratedDeviceKey::new().unwrap());
1290 let exported_base64 = dehydrated_device_pickle_key.clone().unwrap().to_base64();
1291
1292 let changes = Changes { dehydrated_device_pickle_key, ..Default::default() };
1293 store.save_changes(changes).await.unwrap();
1294
1295 let restored = store.load_dehydrated_device_pickle_key().await.unwrap();
1296 assert!(restored.is_some(), "We should be able to restore a pickle key");
1297 assert_eq!(restored.unwrap().to_base64(), exported_base64);
1298
1299 let changes = Changes { dehydrated_device_pickle_key: None, ..Default::default() };
1301 store.save_changes(changes).await.unwrap();
1302
1303 let restored = store.load_dehydrated_device_pickle_key().await.unwrap();
1304 assert!(restored.is_some(), "We should be able to restore a pickle key");
1305 assert_eq!(restored.unwrap().to_base64(), exported_base64);
1306
1307 }
1308
1309 #[async_test]
1310 async fn test_delete_dehydration_pickle_key() {
1311 let (_account, store) = get_loaded_store("delete_dehydration_pickle_key").await;
1312
1313 let dehydrated_device_pickle_key = DehydratedDeviceKey::new().unwrap();
1314
1315 let changes = Changes { dehydrated_device_pickle_key: Some(dehydrated_device_pickle_key), ..Default::default() };
1316 store.save_changes(changes).await.unwrap();
1317
1318 let restored = store.load_dehydrated_device_pickle_key().await.unwrap();
1319 assert!(restored.is_some(), "We should be able to restore a pickle key");
1320
1321 store.delete_dehydrated_device_pickle_key().await.unwrap();
1322
1323 let restored = store.load_dehydrated_device_pickle_key().await.unwrap();
1324 assert!(restored.is_none(), "The previously saved key should be deleted");
1325
1326 }
1327
1328
1329 #[async_test]
1330 async fn test_custom_value_saving() {
1331 let (_, store) = get_loaded_store("custom_value_saving").await;
1332 store.set_custom_value("A", "Hello".as_bytes().to_vec()).await.unwrap();
1333
1334 let loaded_1 = store.get_custom_value("A").await.unwrap();
1335 assert_eq!(Some("Hello".as_bytes().to_vec()), loaded_1);
1336
1337 let loaded_2 = store.get_custom_value("B").await.unwrap();
1338 assert_eq!(None, loaded_2);
1339 }
1340
1341 #[async_test]
1342 async fn test_received_room_key_bundle() {
1343 let store = get_store("received_room_key_bundle", None, true).await;
1344 let test_room = room_id!("!room:example.org");
1345
1346 fn make_bundle_data(sender_user: &UserId, bundle_uri: &str) -> StoredRoomKeyBundleData {
1347 let jwk = ruma::events::room::JsonWebKeyInit {
1348 kty: "oct".to_owned(),
1349 key_ops: vec!["encrypt".to_owned(), "decrypt".to_owned()],
1350 alg: "A256CTR".to_owned(),
1351 k: ruma::serde::Base64::new(vec![0u8; 0]),
1352 ext: true,
1353 }.into();
1354
1355 let file = ruma::events::room::EncryptedFileInit {
1356 url: ruma::OwnedMxcUri::from(bundle_uri),
1357 key: jwk,
1358 iv: ruma::serde::Base64::new(vec![0u8; 0]),
1359 hashes: Default::default(),
1360 v: "".to_owned(),
1361 }.into();
1362
1363 StoredRoomKeyBundleData {
1364 sender_user: sender_user.to_owned(),
1365 sender_key: Curve25519PublicKey::from_bytes([0u8; 32]),
1366 sender_data: SenderData::unknown(),
1367 bundle_data: RoomKeyBundleContent {
1368 room_id: room_id!("!room:example.org").to_owned(),
1369 file,
1370 },
1371 }
1372 }
1373
1374 let changes = Changes {
1376 received_room_key_bundles: vec![
1377 make_bundle_data(user_id!("@alice:example.com"), "alice1"),
1378 make_bundle_data(user_id!("@bob:example.com"), "bob1"),
1379 make_bundle_data(user_id!("@alice:example.com"), "alice2"),
1380 ],
1381 ..Default::default()
1382 };
1383 store.save_changes(changes).await.unwrap();
1384
1385 let bundle = store.get_received_room_key_bundle_data(
1387 test_room, user_id!("@alice:example.com")
1388 ).await.unwrap().expect("Did not get any bundle data");
1389 assert_eq!(bundle.bundle_data.file.url.to_string(), "alice2");
1390 }
1391
1392 fn session_info(session: &InboundGroupSession) -> (&RoomId, &str) {
1393 (&session.room_id(), &session.session_id())
1394 }
1395
1396 async fn create_session(
1397 account: &Account,
1398 device_curve_key: &Curve25519PublicKey,
1399 sender_data_type: SenderDataType,
1400 ) -> InboundGroupSession {
1401 let sender_data = match sender_data_type {
1402 SenderDataType::UnknownDevice => {
1403 SenderData::UnknownDevice { legacy_session: false, owner_check_failed: false }
1404 }
1405 SenderDataType::DeviceInfo => SenderData::DeviceInfo {
1406 device_keys: account.device_keys().clone(),
1407 legacy_session: false,
1408 },
1409 SenderDataType::VerificationViolation => panic!("VerificationViolation not supported"),
1410 SenderDataType::SenderUnverified=> panic!("SenderUnverified not supported"),
1411 SenderDataType::SenderVerified => panic!("SenderVerified not supported"),
1412 };
1413
1414 let session_key = GroupSession::new(SessionConfig::default()).session_key();
1415
1416 InboundGroupSession::new(
1417 device_curve_key.clone(),
1418 account.device_keys().ed25519_key().unwrap(),
1419 room_id!("!r:s.co"),
1420 &session_key,
1421 sender_data,
1422 EventEncryptionAlgorithm::MegolmV1AesSha2,
1423 None,
1424 false,
1425 )
1426 .unwrap()
1427 }
1428 }
1429 };
1430}
1431
1432#[allow(unused_macros)]
1433#[macro_export]
1434macro_rules! cryptostore_integration_tests_time {
1435 () => {
1436 mod cryptostore_integration_tests_time {
1437 use std::time::Duration;
1438
1439 use matrix_sdk_test::async_test;
1440 use $crate::store::CryptoStore as _;
1441
1442 use super::cryptostore_integration_tests::*;
1443
1444 #[async_test]
1445 async fn test_lease_locks() {
1446 let (_account, store) = get_loaded_store("lease_locks").await;
1447
1448 let acquired0 = store.try_take_leased_lock(0, "key", "alice").await.unwrap();
1449 assert!(acquired0);
1450
1451 let acquired2 = store.try_take_leased_lock(300, "key", "alice").await.unwrap();
1453 assert!(acquired2);
1454
1455 let acquired3 = store.try_take_leased_lock(300, "key", "alice").await.unwrap();
1457 assert!(acquired3);
1458
1459 let acquired4 = store.try_take_leased_lock(300, "key", "bob").await.unwrap();
1461 assert!(!acquired4);
1462
1463 let acquired5 = store.try_take_leased_lock(300, "key", "bob").await.unwrap();
1465 assert!(!acquired5);
1466
1467 tokio::time::sleep(Duration::from_millis(50)).await;
1469
1470 let acquired55 = store.try_take_leased_lock(300, "key", "bob").await.unwrap();
1472 assert!(!acquired55);
1473
1474 tokio::time::sleep(Duration::from_millis(250)).await;
1476
1477 let acquired6 = store.try_take_leased_lock(0, "key", "bob").await.unwrap();
1479 assert!(acquired6);
1480
1481 tokio::time::sleep(Duration::from_millis(1)).await;
1482
1483 let acquired7 = store.try_take_leased_lock(0, "key", "alice").await.unwrap();
1485 assert!(acquired7);
1486
1487 tokio::time::sleep(Duration::from_millis(1)).await;
1488
1489 let acquired8 = store.try_take_leased_lock(300, "key", "bob").await.unwrap();
1491 assert!(acquired8);
1492
1493 let acquired9 = store.try_take_leased_lock(300, "key", "alice").await.unwrap();
1495 assert!(!acquired9);
1496
1497 let acquired10 = store.try_take_leased_lock(300, "key", "bob").await.unwrap();
1499 assert!(acquired10);
1500 }
1501 }
1502 };
1503}