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