1use std::{
16 collections::{BTreeMap, HashMap, HashSet},
17 convert::Infallible,
18 sync::Arc,
19};
20
21use async_trait::async_trait;
22use matrix_sdk_common::{
23 cross_process_lock::{
24 CrossProcessLockGeneration,
25 memory_store_helper::{Lease, try_take_leased_lock},
26 },
27 locks::RwLock as StdRwLock,
28};
29use ruma::{
30 DeviceId, OwnedDeviceId, OwnedRoomId, OwnedTransactionId, OwnedUserId, RoomId, TransactionId,
31 UserId, events::secret::request::SecretName,
32};
33use tokio::sync::{Mutex, RwLock};
34use tracing::warn;
35use vodozemac::Curve25519PublicKey;
36use zeroize::Zeroizing;
37
38use super::{
39 Account, CryptoStore, InboundGroupSession, Session,
40 caches::DeviceStore,
41 types::{
42 BackupKeys, Changes, DehydratedDeviceKey, PendingChanges, RoomKeyCounts, RoomSettings,
43 StoredRoomKeyBundleData, TrackedUser,
44 },
45};
46use crate::{
47 gossiping::{GossipRequest, SecretInfo},
48 identities::{DeviceData, UserIdentityData},
49 olm::{
50 OutboundGroupSession, PickledAccount, PickledInboundGroupSession, PickledSession,
51 PrivateCrossSigningIdentity, SenderDataType, StaticAccountData,
52 },
53 store::types::{RoomKeyWithheldEntry, RoomPendingKeyBundleDetails},
54};
55
56fn encode_key_info(info: &SecretInfo) -> String {
57 match info {
58 SecretInfo::KeyRequest(info) => {
59 format!("{}{}{}", info.room_id(), info.algorithm(), info.session_id())
60 }
61 SecretInfo::SecretRequest(i) => i.as_ref().to_owned(),
62 }
63}
64
65type SessionId = String;
66
67#[derive(Clone, Debug, PartialEq)]
69struct BackupVersion(String);
70
71impl BackupVersion {
72 fn from(s: &str) -> Self {
73 Self(s.to_owned())
74 }
75
76 fn as_str(&self) -> &str {
77 &self.0
78 }
79}
80
81#[derive(Default, Debug)]
83pub struct MemoryStore {
84 static_account: Arc<StdRwLock<Option<StaticAccountData>>>,
85
86 account: StdRwLock<Option<String>>,
87 sessions: StdRwLock<BTreeMap<String, BTreeMap<String, String>>>,
89 inbound_group_sessions: StdRwLock<BTreeMap<OwnedRoomId, HashMap<String, String>>>,
90
91 inbound_group_sessions_backed_up_to:
95 StdRwLock<HashMap<OwnedRoomId, HashMap<SessionId, BackupVersion>>>,
96
97 outbound_group_sessions: StdRwLock<BTreeMap<OwnedRoomId, OutboundGroupSession>>,
98 private_identity: StdRwLock<Option<PrivateCrossSigningIdentity>>,
99 tracked_users: StdRwLock<HashMap<OwnedUserId, TrackedUser>>,
100 olm_hashes: StdRwLock<HashMap<String, HashSet<String>>>,
101 devices: DeviceStore,
102 identities: StdRwLock<HashMap<OwnedUserId, String>>,
103 outgoing_key_requests: StdRwLock<HashMap<OwnedTransactionId, GossipRequest>>,
104 key_requests_by_info: StdRwLock<HashMap<String, OwnedTransactionId>>,
105 direct_withheld_info: StdRwLock<HashMap<OwnedRoomId, HashMap<String, RoomKeyWithheldEntry>>>,
106 custom_values: StdRwLock<HashMap<String, Vec<u8>>>,
107 leases: StdRwLock<HashMap<String, Lease>>,
108 secret_inbox: StdRwLock<HashMap<String, Vec<Zeroizing<String>>>>,
109 backup_keys: RwLock<BackupKeys>,
110 dehydrated_device_pickle_key: RwLock<Option<DehydratedDeviceKey>>,
111 next_batch_token: RwLock<Option<String>>,
112 room_settings: StdRwLock<HashMap<OwnedRoomId, RoomSettings>>,
113 room_key_bundles:
114 StdRwLock<HashMap<OwnedRoomId, HashMap<OwnedUserId, StoredRoomKeyBundleData>>>,
115 room_key_backups_fully_downloaded: StdRwLock<HashSet<OwnedRoomId>>,
116 rooms_pending_key_bundle: StdRwLock<HashMap<OwnedRoomId, RoomPendingKeyBundleDetails>>,
117
118 save_changes_lock: Arc<Mutex<()>>,
119}
120
121impl MemoryStore {
122 pub fn new() -> Self {
124 Self::default()
125 }
126
127 fn get_static_account(&self) -> Option<StaticAccountData> {
128 self.static_account.read().clone()
129 }
130
131 pub(crate) fn save_devices(&self, devices: Vec<DeviceData>) {
132 for device in devices {
133 let _ = self.devices.add(device);
134 }
135 }
136
137 fn delete_devices(&self, devices: Vec<DeviceData>) {
138 for device in devices {
139 let _ = self.devices.remove(device.user_id(), device.device_id());
140 }
141 }
142
143 fn save_sessions(&self, sessions: Vec<(String, PickledSession)>) {
144 let mut session_store = self.sessions.write();
145
146 for (session_id, pickle) in sessions {
147 let entry = session_store.entry(pickle.sender_key.to_base64()).or_default();
148
149 entry.insert(
151 session_id,
152 serde_json::to_string(&pickle).expect("Failed to serialize olm session"),
153 );
154 }
155 }
156
157 fn save_outbound_group_sessions(&self, sessions: Vec<OutboundGroupSession>) {
158 self.outbound_group_sessions
159 .write()
160 .extend(sessions.into_iter().map(|s| (s.room_id().to_owned(), s)));
161 }
162
163 fn save_private_identity(&self, private_identity: Option<PrivateCrossSigningIdentity>) {
164 *self.private_identity.write() = private_identity;
165 }
166
167 async fn get_inbound_group_sessions_and_backed_up_to(
171 &self,
172 ) -> Result<Vec<(InboundGroupSession, Option<BackupVersion>)>> {
173 let lookup = |s: &InboundGroupSession| {
174 self.inbound_group_sessions_backed_up_to
175 .read()
176 .get(&s.room_id)?
177 .get(s.session_id())
178 .cloned()
179 };
180
181 Ok(self
182 .get_inbound_group_sessions()
183 .await?
184 .into_iter()
185 .map(|s| {
186 let v = lookup(&s);
187 (s, v)
188 })
189 .collect())
190 }
191}
192
193type Result<T> = std::result::Result<T, Infallible>;
194
195#[cfg_attr(target_family = "wasm", async_trait(?Send))]
196#[cfg_attr(not(target_family = "wasm"), async_trait)]
197impl CryptoStore for MemoryStore {
198 type Error = Infallible;
199
200 async fn close(&self) -> Result<()> {
201 Ok(())
202 }
203
204 async fn reopen(&self) -> Result<()> {
205 Ok(())
206 }
207
208 async fn load_account(&self) -> Result<Option<Account>> {
209 let pickled_account: Option<PickledAccount> = self.account.read().as_ref().map(|acc| {
210 serde_json::from_str(acc)
211 .expect("Deserialization failed: invalid pickled account JSON format")
212 });
213
214 if let Some(pickle) = pickled_account {
215 let account =
216 Account::from_pickle(pickle).expect("From pickle failed: invalid pickle format");
217
218 *self.static_account.write() = Some(account.static_data().clone());
219
220 Ok(Some(account))
221 } else {
222 Ok(None)
223 }
224 }
225
226 async fn load_identity(&self) -> Result<Option<PrivateCrossSigningIdentity>> {
227 Ok(self.private_identity.read().clone())
228 }
229
230 async fn next_batch_token(&self) -> Result<Option<String>> {
231 Ok(self.next_batch_token.read().await.clone())
232 }
233
234 async fn save_pending_changes(&self, changes: PendingChanges) -> Result<()> {
235 let _guard = self.save_changes_lock.lock().await;
236
237 let pickled_account = if let Some(account) = changes.account {
238 *self.static_account.write() = Some(account.static_data().clone());
239 Some(account.pickle())
240 } else {
241 None
242 };
243
244 *self.account.write() = pickled_account.map(|pickle| {
245 serde_json::to_string(&pickle)
246 .expect("Serialization failed: invalid pickled account JSON format")
247 });
248
249 Ok(())
250 }
251
252 async fn save_changes(&self, changes: Changes) -> Result<()> {
253 let _guard = self.save_changes_lock.lock().await;
254
255 let mut pickled_session: Vec<(String, PickledSession)> = Vec::new();
256 for session in changes.sessions {
257 let session_id = session.session_id().to_owned();
258 let pickle = session.pickle().await;
259 pickled_session.push((session_id.clone(), pickle));
260 }
261 self.save_sessions(pickled_session);
262
263 self.save_inbound_group_sessions(changes.inbound_group_sessions, None).await?;
264 self.save_outbound_group_sessions(changes.outbound_group_sessions);
265 self.save_private_identity(changes.private_identity);
266
267 self.save_devices(changes.devices.new);
268 self.save_devices(changes.devices.changed);
269 self.delete_devices(changes.devices.deleted);
270
271 {
272 let mut identities = self.identities.write();
273 for identity in changes.identities.new.into_iter().chain(changes.identities.changed) {
274 identities.insert(
275 identity.user_id().to_owned(),
276 serde_json::to_string(&identity)
277 .expect("UserIdentityData should always serialize to json"),
278 );
279 }
280 }
281
282 {
283 let mut olm_hashes = self.olm_hashes.write();
284 for hash in changes.message_hashes {
285 olm_hashes.entry(hash.sender_key.to_owned()).or_default().insert(hash.hash.clone());
286 }
287 }
288
289 {
290 let mut outgoing_key_requests = self.outgoing_key_requests.write();
291 let mut key_requests_by_info = self.key_requests_by_info.write();
292
293 for key_request in changes.key_requests {
294 let id = key_request.request_id.clone();
295 let info_string = encode_key_info(&key_request.info);
296
297 if let Some(old_id) = key_requests_by_info.get(&info_string) {
299 outgoing_key_requests.remove(old_id);
300 key_requests_by_info.remove(&info_string);
301 }
302
303 outgoing_key_requests.insert(id.clone(), key_request);
304 key_requests_by_info.insert(info_string, id);
305 }
306 }
307
308 if let Some(key) = changes.backup_decryption_key {
309 self.backup_keys.write().await.decryption_key = Some(key);
310 }
311
312 if let Some(version) = changes.backup_version {
313 self.backup_keys.write().await.backup_version = Some(version);
314 }
315
316 if let Some(pickle_key) = changes.dehydrated_device_pickle_key {
317 let mut lock = self.dehydrated_device_pickle_key.write().await;
318 *lock = Some(pickle_key);
319 }
320
321 {
322 let mut secret_inbox = self.secret_inbox.write();
323 for secret in changes.secrets {
324 secret_inbox.entry(secret.secret_name.to_string()).or_default().push(secret.secret);
325 }
326 }
327
328 {
329 let mut direct_withheld_info = self.direct_withheld_info.write();
330 for (room_id, data) in changes.withheld_session_info {
331 for (session_id, event) in data {
332 direct_withheld_info
333 .entry(room_id.to_owned())
334 .or_default()
335 .insert(session_id, event);
336 }
337 }
338 }
339
340 if let Some(next_batch_token) = changes.next_batch_token {
341 *self.next_batch_token.write().await = Some(next_batch_token);
342 }
343
344 if !changes.room_settings.is_empty() {
345 let mut settings = self.room_settings.write();
346 settings.extend(changes.room_settings);
347 }
348
349 if !changes.received_room_key_bundles.is_empty() {
350 let mut room_key_bundles = self.room_key_bundles.write();
351 for bundle in changes.received_room_key_bundles {
352 room_key_bundles
353 .entry(bundle.bundle_data.room_id.clone())
354 .or_default()
355 .insert(bundle.sender_user.clone(), bundle);
356 }
357 }
358
359 if !changes.room_key_backups_fully_downloaded.is_empty() {
360 let mut room_key_backups_fully_downloaded =
361 self.room_key_backups_fully_downloaded.write();
362 for room in changes.room_key_backups_fully_downloaded {
363 room_key_backups_fully_downloaded.insert(room);
364 }
365 }
366
367 if !changes.rooms_pending_key_bundle.is_empty() {
368 let mut lock = self.rooms_pending_key_bundle.write();
369 for (room, details) in changes.rooms_pending_key_bundle {
370 if let Some(details) = details {
371 lock.insert(room, details);
372 } else {
373 lock.remove(&room);
374 }
375 }
376 }
377
378 Ok(())
379 }
380
381 async fn save_inbound_group_sessions(
382 &self,
383 sessions: Vec<InboundGroupSession>,
384 backed_up_to_version: Option<&str>,
385 ) -> Result<()> {
386 for session in sessions {
387 let room_id = session.room_id();
388 let session_id = session.session_id();
389
390 let backed_up = session.backed_up();
392 if backed_up != backed_up_to_version.is_some() {
393 warn!(
394 backed_up,
395 backed_up_to_version,
396 "Session backed-up flag does not correspond to backup version setting",
397 );
398 }
399
400 if let Some(backup_version) = backed_up_to_version {
401 self.inbound_group_sessions_backed_up_to
402 .write()
403 .entry(room_id.to_owned())
404 .or_default()
405 .insert(session_id.to_owned(), BackupVersion::from(backup_version));
406 }
407
408 let pickle = session.pickle().await;
409 self.inbound_group_sessions
410 .write()
411 .entry(session.room_id().to_owned())
412 .or_default()
413 .insert(
414 session.session_id().to_owned(),
415 serde_json::to_string(&pickle)
416 .expect("Pickle pickle data should serialize to json"),
417 );
418 }
419 Ok(())
420 }
421
422 async fn get_sessions(&self, sender_key: &str) -> Result<Option<Vec<Session>>> {
423 let device_keys = self.get_own_device().await?.as_device_keys().clone();
424
425 if let Some(pickles) = self.sessions.read().get(sender_key) {
426 let mut sessions: Vec<Session> = Vec::new();
427 for serialized_pickle in pickles.values() {
428 let pickle: PickledSession = serde_json::from_str(serialized_pickle.as_str())
429 .expect("Pickle pickle deserialization should work");
430 let session = Session::from_pickle(device_keys.clone(), pickle)
431 .expect("Expect from pickle to always work");
432 sessions.push(session);
433 }
434 Ok(Some(sessions))
435 } else {
436 Ok(None)
437 }
438 }
439
440 async fn get_inbound_group_session(
441 &self,
442 room_id: &RoomId,
443 session_id: &str,
444 ) -> Result<Option<InboundGroupSession>> {
445 let pickle: Option<PickledInboundGroupSession> = self
446 .inbound_group_sessions
447 .read()
448 .get(room_id)
449 .and_then(|m| m.get(session_id))
450 .and_then(|ser| {
451 serde_json::from_str(ser).expect("Pickle pickle deserialization should work")
452 });
453
454 Ok(pickle.map(|p| {
455 InboundGroupSession::from_pickle(p).expect("Expect from pickle to always work")
456 }))
457 }
458
459 async fn get_withheld_info(
460 &self,
461 room_id: &RoomId,
462 session_id: &str,
463 ) -> Result<Option<RoomKeyWithheldEntry>> {
464 Ok(self
465 .direct_withheld_info
466 .read()
467 .get(room_id)
468 .and_then(|e| Some(e.get(session_id)?.to_owned())))
469 }
470
471 async fn get_withheld_sessions_by_room_id(
472 &self,
473 room_id: &RoomId,
474 ) -> crate::store::Result<Vec<RoomKeyWithheldEntry>, Self::Error> {
475 Ok(self
476 .direct_withheld_info
477 .read()
478 .get(room_id)
479 .map(|e| e.values().cloned().collect())
480 .unwrap_or_default())
481 }
482
483 async fn get_inbound_group_sessions(&self) -> Result<Vec<InboundGroupSession>> {
484 let inbounds = self
485 .inbound_group_sessions
486 .read()
487 .values()
488 .flat_map(HashMap::values)
489 .map(|ser| {
490 let pickle: PickledInboundGroupSession =
491 serde_json::from_str(ser).expect("Pickle deserialization should work");
492 InboundGroupSession::from_pickle(pickle).expect("Expect from pickle to always work")
493 })
494 .collect();
495 Ok(inbounds)
496 }
497
498 async fn inbound_group_session_counts(
499 &self,
500 backup_version: Option<&str>,
501 ) -> Result<RoomKeyCounts> {
502 let backed_up = if let Some(backup_version) = backup_version {
503 self.get_inbound_group_sessions_and_backed_up_to()
504 .await?
505 .into_iter()
506 .filter(|(_, o)| o.as_ref().is_some_and(|o| o.as_str() == backup_version))
508 .count()
509 } else {
510 0
514 };
515
516 let total = self.inbound_group_sessions.read().values().map(HashMap::len).sum();
517 Ok(RoomKeyCounts { total, backed_up })
518 }
519
520 async fn get_inbound_group_sessions_by_room_id(
521 &self,
522 room_id: &RoomId,
523 ) -> Result<Vec<InboundGroupSession>> {
524 let inbounds = match self.inbound_group_sessions.read().get(room_id) {
525 None => Vec::new(),
526 Some(v) => v
527 .values()
528 .map(|ser| {
529 let pickle: PickledInboundGroupSession =
530 serde_json::from_str(ser).expect("Pickle deserialization should work");
531 InboundGroupSession::from_pickle(pickle)
532 .expect("Expect from pickle to always work")
533 })
534 .collect(),
535 };
536 Ok(inbounds)
537 }
538
539 async fn get_inbound_group_sessions_for_device_batch(
540 &self,
541 sender_key: Curve25519PublicKey,
542 sender_data_type: SenderDataType,
543 after_session_id: Option<String>,
544 limit: usize,
545 ) -> Result<Vec<InboundGroupSession>> {
546 let mut sessions: Vec<_> = self
549 .get_inbound_group_sessions()
550 .await?
551 .into_iter()
552 .filter(|session: &InboundGroupSession| {
553 session.creator_info.curve25519_key == sender_key
554 && session.sender_data.to_type() == sender_data_type
555 })
556 .collect();
557
558 sessions.sort_by_key(|s| s.session_id().to_owned());
560
561 let start_index = {
563 match after_session_id {
564 None => 0,
565 Some(id) => {
566 sessions
569 .iter()
570 .position(|session| session.session_id() > id.as_str())
571 .unwrap_or(sessions.len())
572 }
573 }
574 };
575
576 Ok(sessions.drain(start_index..).take(limit).collect())
578 }
579
580 async fn inbound_group_sessions_for_backup(
581 &self,
582 backup_version: &str,
583 limit: usize,
584 ) -> Result<Vec<InboundGroupSession>> {
585 Ok(self
586 .get_inbound_group_sessions_and_backed_up_to()
587 .await?
588 .into_iter()
589 .filter_map(|(session, backed_up_to)| {
590 if let Some(ref existing_version) = backed_up_to
591 && existing_version.as_str() == backup_version
592 {
593 None
595 } else {
596 Some(session)
598 }
599 })
600 .take(limit)
601 .collect())
602 }
603
604 async fn mark_inbound_group_sessions_as_backed_up(
605 &self,
606 backup_version: &str,
607 room_and_session_ids: &[(&RoomId, &str)],
608 ) -> Result<()> {
609 for &(room_id, session_id) in room_and_session_ids {
610 let session = self.get_inbound_group_session(room_id, session_id).await?;
611
612 if let Some(session) = session {
613 session.mark_as_backed_up();
614
615 self.inbound_group_sessions_backed_up_to
616 .write()
617 .entry(room_id.to_owned())
618 .or_default()
619 .insert(session_id.to_owned(), BackupVersion::from(backup_version));
620
621 let updated_pickle = session.pickle().await;
623
624 self.inbound_group_sessions.write().entry(room_id.to_owned()).or_default().insert(
625 session_id.to_owned(),
626 serde_json::to_string(&updated_pickle)
627 .expect("Pickle serialization should work"),
628 );
629 }
630 }
631
632 Ok(())
633 }
634
635 async fn reset_backup_state(&self) -> Result<()> {
636 Ok(())
643 }
644
645 async fn load_backup_keys(&self) -> Result<BackupKeys> {
646 Ok(self.backup_keys.read().await.to_owned())
647 }
648
649 async fn load_dehydrated_device_pickle_key(&self) -> Result<Option<DehydratedDeviceKey>> {
650 Ok(self.dehydrated_device_pickle_key.read().await.to_owned())
651 }
652
653 async fn delete_dehydrated_device_pickle_key(&self) -> Result<()> {
654 let mut lock = self.dehydrated_device_pickle_key.write().await;
655 *lock = None;
656 Ok(())
657 }
658
659 async fn get_outbound_group_session(
660 &self,
661 room_id: &RoomId,
662 ) -> Result<Option<OutboundGroupSession>> {
663 Ok(self.outbound_group_sessions.read().get(room_id).cloned())
664 }
665
666 async fn load_tracked_users(&self) -> Result<Vec<TrackedUser>> {
667 Ok(self.tracked_users.read().values().cloned().collect())
668 }
669
670 async fn save_tracked_users(&self, tracked_users: &[(&UserId, bool)]) -> Result<()> {
671 self.tracked_users.write().extend(tracked_users.iter().map(|(user_id, dirty)| {
672 let user_id: OwnedUserId = user_id.to_owned().into();
673 (user_id.clone(), TrackedUser { user_id, dirty: *dirty })
674 }));
675 Ok(())
676 }
677
678 async fn get_device(
679 &self,
680 user_id: &UserId,
681 device_id: &DeviceId,
682 ) -> Result<Option<DeviceData>> {
683 Ok(self.devices.get(user_id, device_id))
684 }
685
686 async fn get_user_devices(
687 &self,
688 user_id: &UserId,
689 ) -> Result<HashMap<OwnedDeviceId, DeviceData>> {
690 Ok(self.devices.user_devices(user_id))
691 }
692
693 async fn get_own_device(&self) -> Result<DeviceData> {
694 let account =
695 self.get_static_account().expect("Expect account to exist when getting own device");
696
697 Ok(self
698 .devices
699 .get(&account.user_id, &account.device_id)
700 .expect("Invalid state: Should always have a own device"))
701 }
702
703 async fn get_user_identity(&self, user_id: &UserId) -> Result<Option<UserIdentityData>> {
704 let serialized = self.identities.read().get(user_id).cloned();
705 match serialized {
706 None => Ok(None),
707 Some(serialized) => {
708 let id: UserIdentityData = serde_json::from_str(serialized.as_str())
709 .expect("Only valid serialized identity are saved");
710 Ok(Some(id))
711 }
712 }
713 }
714
715 async fn is_message_known(&self, message_hash: &crate::olm::OlmMessageHash) -> Result<bool> {
716 Ok(self
717 .olm_hashes
718 .write()
719 .entry(message_hash.sender_key.to_owned())
720 .or_default()
721 .contains(&message_hash.hash))
722 }
723
724 async fn get_outgoing_secret_requests(
725 &self,
726 request_id: &TransactionId,
727 ) -> Result<Option<GossipRequest>> {
728 Ok(self.outgoing_key_requests.read().get(request_id).cloned())
729 }
730
731 async fn get_secret_request_by_info(
732 &self,
733 key_info: &SecretInfo,
734 ) -> Result<Option<GossipRequest>> {
735 let key_info_string = encode_key_info(key_info);
736
737 Ok(self
738 .key_requests_by_info
739 .read()
740 .get(&key_info_string)
741 .and_then(|i| self.outgoing_key_requests.read().get(i).cloned()))
742 }
743
744 async fn get_unsent_secret_requests(&self) -> Result<Vec<GossipRequest>> {
745 Ok(self
746 .outgoing_key_requests
747 .read()
748 .values()
749 .filter(|req| !req.sent_out)
750 .cloned()
751 .collect())
752 }
753
754 async fn delete_outgoing_secret_requests(&self, request_id: &TransactionId) -> Result<()> {
755 let req = self.outgoing_key_requests.write().remove(request_id);
756 if let Some(i) = req {
757 let key_info_string = encode_key_info(&i.info);
758 self.key_requests_by_info.write().remove(&key_info_string);
759 }
760
761 Ok(())
762 }
763
764 async fn get_secrets_from_inbox(
765 &self,
766 secret_name: &SecretName,
767 ) -> Result<Vec<Zeroizing<String>>> {
768 Ok(self.secret_inbox.write().entry(secret_name.to_string()).or_default().to_owned())
769 }
770
771 async fn delete_secrets_from_inbox(&self, secret_name: &SecretName) -> Result<()> {
772 self.secret_inbox.write().remove(secret_name.as_str());
773
774 Ok(())
775 }
776
777 async fn get_room_settings(&self, room_id: &RoomId) -> Result<Option<RoomSettings>> {
778 Ok(self.room_settings.read().get(room_id).cloned())
779 }
780
781 async fn get_received_room_key_bundle_data(
782 &self,
783 room_id: &RoomId,
784 user_id: &UserId,
785 ) -> Result<Option<StoredRoomKeyBundleData>> {
786 let guard = self.room_key_bundles.read();
787
788 let result = guard.get(room_id).and_then(|bundles| bundles.get(user_id).cloned());
789
790 Ok(result)
791 }
792
793 async fn get_pending_key_bundle_details_for_room(
794 &self,
795 room_id: &RoomId,
796 ) -> Result<Option<RoomPendingKeyBundleDetails>> {
797 Ok(self.rooms_pending_key_bundle.read().get(room_id).cloned())
798 }
799
800 async fn get_all_rooms_pending_key_bundles(&self) -> Result<Vec<RoomPendingKeyBundleDetails>> {
801 Ok(self.rooms_pending_key_bundle.read().values().cloned().collect())
802 }
803
804 async fn has_downloaded_all_room_keys(&self, room_id: &RoomId) -> Result<bool> {
805 let guard = self.room_key_backups_fully_downloaded.read();
806 Ok(guard.contains(room_id))
807 }
808
809 async fn get_custom_value(&self, key: &str) -> Result<Option<Vec<u8>>> {
810 Ok(self.custom_values.read().get(key).cloned())
811 }
812
813 async fn set_custom_value(&self, key: &str, value: Vec<u8>) -> Result<()> {
814 self.custom_values.write().insert(key.to_owned(), value);
815 Ok(())
816 }
817
818 async fn remove_custom_value(&self, key: &str) -> Result<()> {
819 self.custom_values.write().remove(key);
820 Ok(())
821 }
822
823 async fn try_take_leased_lock(
824 &self,
825 lease_duration_ms: u32,
826 key: &str,
827 holder: &str,
828 ) -> Result<Option<CrossProcessLockGeneration>> {
829 Ok(try_take_leased_lock(&mut self.leases.write(), lease_duration_ms, key, holder))
830 }
831
832 async fn get_size(&self) -> Result<Option<usize>> {
833 Ok(None)
834 }
835}
836
837#[cfg(test)]
838mod tests {
839 use std::collections::HashMap;
840
841 use matrix_sdk_test::async_test;
842 use ruma::{RoomId, room_id, user_id};
843 use vodozemac::{Curve25519PublicKey, Ed25519PublicKey};
844
845 use super::SessionId;
846 use crate::{
847 DeviceData,
848 identities::device::testing::get_device,
849 olm::{
850 Account, InboundGroupSession, OlmMessageHash, PrivateCrossSigningIdentity, SenderData,
851 tests::get_account_and_session_test_helper,
852 },
853 store::{
854 CryptoStore,
855 memorystore::MemoryStore,
856 types::{Changes, DeviceChanges, PendingChanges},
857 },
858 };
859
860 #[async_test]
861 async fn test_session_store() {
862 let (account, session) = get_account_and_session_test_helper();
863 let own_device = DeviceData::from_account(&account);
864 let store = MemoryStore::new();
865
866 assert!(store.load_account().await.unwrap().is_none());
867
868 store
869 .save_changes(Changes {
870 devices: DeviceChanges { new: vec![own_device], ..Default::default() },
871 ..Default::default()
872 })
873 .await
874 .unwrap();
875 store.save_pending_changes(PendingChanges { account: Some(account) }).await.unwrap();
876
877 store
878 .save_changes(Changes { sessions: (vec![session.clone()]), ..Default::default() })
879 .await
880 .unwrap();
881
882 let sessions = store.get_sessions(&session.sender_key.to_base64()).await.unwrap().unwrap();
883
884 let loaded_session = &sessions[0];
885
886 assert_eq!(&session, loaded_session);
887 }
888
889 #[async_test]
890 async fn test_inbound_group_session_store() {
891 let (account, _) = get_account_and_session_test_helper();
892 let room_id = room_id!("!test:localhost");
893 let curve_key = "Nn0L2hkcCMFKqynTjyGsJbth7QrVmX3lbrksMkrGOAw";
894
895 let (outbound, _) = account.create_group_session_pair_with_defaults(room_id).await;
896 let inbound = InboundGroupSession::new(
897 Curve25519PublicKey::from_base64(curve_key).unwrap(),
898 Ed25519PublicKey::from_base64("ee3Ek+J2LkkPmjGPGLhMxiKnhiX//xcqaVL4RP6EypE").unwrap(),
899 room_id,
900 &outbound.session_key().await,
901 SenderData::unknown(),
902 None,
903 outbound.settings().algorithm.to_owned(),
904 None,
905 false,
906 )
907 .unwrap();
908
909 let store = MemoryStore::new();
910 store.save_inbound_group_sessions(vec![inbound.clone()], None).await.unwrap();
911
912 let loaded_session =
913 store.get_inbound_group_session(room_id, outbound.session_id()).await.unwrap().unwrap();
914 assert_eq!(inbound, loaded_session);
915 }
916
917 #[async_test]
918 async fn test_backing_up_marks_sessions_as_backed_up() {
919 let room_id = room_id!("!test:localhost");
921 let (store, sessions) = store_with_sessions(2, room_id).await;
922
923 mark_backed_up(&store, room_id, "bkp1", &sessions).await;
925
926 let but = backed_up_tos(&store).await;
928 assert_eq!(but[sessions[0].session_id()], "bkp1");
929 assert_eq!(but[sessions[1].session_id()], "bkp1");
930 }
931
932 #[async_test]
933 async fn test_backing_up_a_second_set_of_sessions_updates_their_backup_order() {
934 let room_id = room_id!("!test:localhost");
936 let (store, sessions) = store_with_sessions(3, room_id).await;
937
938 mark_backed_up(&store, room_id, "bkp1", &sessions[..2]).await;
940
941 mark_backed_up(&store, room_id, "bkp2", &sessions[1..]).await;
943
944 let but = backed_up_tos(&store).await;
946 assert_eq!(but[sessions[0].session_id()], "bkp1");
947 assert_eq!(but[sessions[1].session_id()], "bkp2");
948 assert_eq!(but[sessions[2].session_id()], "bkp2");
949 }
950
951 #[async_test]
952 async fn test_backing_up_again_to_the_same_version_has_no_effect() {
953 let room_id = room_id!("!test:localhost");
955 let (store, sessions) = store_with_sessions(3, room_id).await;
956
957 mark_backed_up(&store, room_id, "bkp1", &sessions[..2]).await;
959
960 mark_backed_up(&store, room_id, "bkp1", &sessions[1..]).await;
962
963 let but = backed_up_tos(&store).await;
965 assert_eq!(but[sessions[0].session_id()], "bkp1");
966 assert_eq!(but[sessions[1].session_id()], "bkp1");
967 assert_eq!(but[sessions[2].session_id()], "bkp1");
968 }
969
970 #[async_test]
971 async fn test_backing_up_to_an_old_backup_version_can_increase_backed_up_to() {
972 let room_id = room_id!("!test:localhost");
975 let (store, sessions) = store_with_sessions(4, room_id).await;
976 mark_backed_up(&store, room_id, "older_bkp", &sessions[..2]).await;
977 mark_backed_up(&store, room_id, "newer_bkp", &sessions[1..2]).await;
978
979 mark_backed_up(&store, room_id, "older_bkp", &sessions[2..]).await;
981
982 let but = backed_up_tos(&store).await;
984 assert_eq!(but[sessions[0].session_id()], "older_bkp");
985 assert_eq!(but[sessions[1].session_id()], "newer_bkp");
986 assert_eq!(but[sessions[2].session_id()], "older_bkp");
987 assert_eq!(but[sessions[3].session_id()], "older_bkp");
988 }
989
990 #[async_test]
991 async fn test_backing_up_to_an_old_backup_version_overwrites_a_newer_one() {
992 let room_id = room_id!("!test:localhost");
994 let (store, sessions) = store_with_sessions(4, room_id).await;
995 mark_backed_up(&store, room_id, "older_bkp", &sessions).await;
996 assert_eq!(backed_up_tos(&store).await[sessions[0].session_id()], "older_bkp");
998 mark_backed_up(&store, room_id, "newer_bkp", &sessions).await;
999 assert_eq!(backed_up_tos(&store).await[sessions[0].session_id()], "newer_bkp");
1001
1002 mark_backed_up(&store, room_id, "older_bkp", &sessions[..2]).await;
1004
1005 let but = backed_up_tos(&store).await;
1007 assert_eq!(but[sessions[0].session_id()], "older_bkp");
1008 assert_eq!(but[sessions[1].session_id()], "older_bkp");
1009 assert_eq!(but[sessions[2].session_id()], "newer_bkp");
1010 assert_eq!(but[sessions[3].session_id()], "newer_bkp");
1011 }
1012
1013 #[async_test]
1014 async fn test_not_backed_up_sessions_are_eligible_for_backup() {
1015 let room_id = room_id!("!test:localhost");
1017 let (store, sessions) = store_with_sessions(4, room_id).await;
1018 mark_backed_up(&store, room_id, "bkp1", &sessions[..2]).await;
1019
1020 let mut to_backup = store
1022 .inbound_group_sessions_for_backup("bkp1", 10)
1023 .await
1024 .expect("Failed to ask for sessions to backup");
1025 to_backup.sort_by_key(|s| s.session_id().to_owned());
1026
1027 assert_eq!(to_backup, &[sessions[2].clone(), sessions[3].clone()]);
1029 }
1030
1031 #[async_test]
1032 async fn test_all_sessions_are_eligible_for_backup_if_version_is_unknown() {
1033 let room_id = room_id!("!test:localhost");
1035 let (store, sessions) = store_with_sessions(4, room_id).await;
1036 mark_backed_up(&store, room_id, "bkp1", &sessions[..2]).await;
1037
1038 let mut to_backup = store
1040 .inbound_group_sessions_for_backup("unknown_bkp", 10)
1041 .await
1042 .expect("Failed to ask for sessions to backup");
1043 to_backup.sort_by_key(|s| s.session_id().to_owned());
1044
1045 assert_eq!(
1047 to_backup,
1048 &[sessions[0].clone(), sessions[1].clone(), sessions[2].clone(), sessions[3].clone()]
1049 );
1050 }
1051
1052 #[async_test]
1053 async fn test_sessions_backed_up_to_a_later_version_are_eligible_for_backup() {
1054 let room_id = room_id!("!test:localhost");
1056 let (store, sessions) = store_with_sessions(4, room_id).await;
1057 mark_backed_up(&store, room_id, "bkp0", &sessions[..1]).await;
1058 mark_backed_up(&store, room_id, "bkp1", &sessions[1..2]).await;
1059 mark_backed_up(&store, room_id, "bkp2", &sessions[2..3]).await;
1060
1061 let mut to_backup = store
1063 .inbound_group_sessions_for_backup("bkp1", 10)
1064 .await
1065 .expect("Failed to ask for sessions to backup");
1066 to_backup.sort_by_key(|s| s.session_id().to_owned());
1067
1068 assert_eq!(
1070 to_backup,
1071 &[
1072 sessions[0].clone(), sessions[2].clone(), sessions[3].clone(), ]
1077 );
1078 }
1079
1080 #[async_test]
1081 async fn test_outbound_group_session_store() {
1082 let (account, _) = get_account_and_session_test_helper();
1084 let room_id = room_id!("!test:localhost");
1085 let (outbound, _) = account.create_group_session_pair_with_defaults(room_id).await;
1086
1087 let store = MemoryStore::new();
1089 store.save_outbound_group_sessions(vec![outbound.clone()]);
1090
1091 let loaded_session = store.get_outbound_group_session(room_id).await.unwrap().unwrap();
1093 assert_eq!(
1094 serde_json::to_string(&outbound.pickle().await).unwrap(),
1095 serde_json::to_string(&loaded_session.pickle().await).unwrap()
1096 );
1097 }
1098
1099 #[async_test]
1100 async fn test_tracked_users_are_stored_once_per_user_id() {
1101 let user1 = user_id!("@user1:s");
1103 let user2 = user_id!("@user2:s");
1104 let user3 = user_id!("@user3:s");
1105 let store = MemoryStore::new();
1106 store.save_tracked_users(&[(user1, true), (user2, true)]).await.unwrap();
1107
1108 store.save_tracked_users(&[(user2, false), (user3, false)]).await.unwrap();
1110
1111 let loaded_tracked_users =
1113 store.load_tracked_users().await.expect("failed to load tracked users");
1114
1115 let tracked_contains = |user_id, dirty| {
1116 loaded_tracked_users.iter().any(|u| u.user_id == user_id && u.dirty == dirty)
1117 };
1118
1119 assert!(tracked_contains(user1, true));
1120 assert!(tracked_contains(user2, false));
1121 assert!(tracked_contains(user3, false));
1122 assert_eq!(loaded_tracked_users.len(), 3);
1123 }
1124
1125 #[async_test]
1126 async fn test_private_identity_store() {
1127 let private_identity = PrivateCrossSigningIdentity::empty(user_id!("@u:s"));
1129
1130 let store = MemoryStore::new();
1132 store.save_private_identity(Some(private_identity.clone()));
1133
1134 let loaded_identity =
1136 store.load_identity().await.expect("failed to load private identity").unwrap();
1137
1138 assert_eq!(loaded_identity.user_id(), user_id!("@u:s"));
1139 }
1140
1141 #[async_test]
1142 async fn test_device_store() {
1143 let device = get_device();
1144 let store = MemoryStore::new();
1145
1146 store.save_devices(vec![device.clone()]);
1147
1148 let loaded_device =
1149 store.get_device(device.user_id(), device.device_id()).await.unwrap().unwrap();
1150
1151 assert_eq!(device, loaded_device);
1152
1153 let user_devices = store.get_user_devices(device.user_id()).await.unwrap();
1154
1155 assert_eq!(&**user_devices.keys().next().unwrap(), device.device_id());
1156 assert_eq!(user_devices.values().next().unwrap(), &device);
1157
1158 let loaded_device = user_devices.get(device.device_id()).unwrap();
1159
1160 assert_eq!(&device, loaded_device);
1161
1162 store.delete_devices(vec![device.clone()]);
1163 assert!(store.get_device(device.user_id(), device.device_id()).await.unwrap().is_none());
1164 }
1165
1166 #[async_test]
1167 async fn test_message_hash() {
1168 let store = MemoryStore::new();
1169
1170 let hash =
1171 OlmMessageHash { sender_key: "test_sender".to_owned(), hash: "test_hash".to_owned() };
1172
1173 let mut changes = Changes::default();
1174 changes.message_hashes.push(hash.clone());
1175
1176 assert!(!store.is_message_known(&hash).await.unwrap());
1177 store.save_changes(changes).await.unwrap();
1178 assert!(store.is_message_known(&hash).await.unwrap());
1179 }
1180
1181 #[async_test]
1182 async fn test_key_counts_of_empty_store_are_zero() {
1183 let store = MemoryStore::new();
1185
1186 let key_counts = store.inbound_group_session_counts(Some("")).await.unwrap();
1188
1189 assert_eq!(key_counts.total, 0);
1191 assert_eq!(key_counts.backed_up, 0);
1192 }
1193
1194 #[async_test]
1195 async fn test_counting_sessions_reports_the_number_of_sessions() {
1196 let room_id = room_id!("!test:localhost");
1198 let (store, _) = store_with_sessions(4, room_id).await;
1199
1200 let key_counts = store.inbound_group_session_counts(Some("bkp")).await.unwrap();
1202
1203 assert_eq!(key_counts.total, 4);
1205 assert_eq!(key_counts.backed_up, 0);
1207 }
1208
1209 #[async_test]
1210 async fn test_counting_backed_up_sessions_reports_the_number_backed_up_in_this_backup() {
1211 let room_id = room_id!("!test:localhost");
1213 let (store, sessions) = store_with_sessions(5, room_id).await;
1214 mark_backed_up(&store, room_id, "bkp", &sessions[..2]).await;
1215
1216 let key_counts = store.inbound_group_session_counts(Some("bkp")).await.unwrap();
1218
1219 assert_eq!(key_counts.total, 5);
1221 assert_eq!(key_counts.backed_up, 2);
1223 }
1224
1225 #[async_test]
1226 async fn test_counting_backed_up_sessions_for_null_backup_reports_zero() {
1227 let room_id = room_id!("!test:localhost");
1229 let (store, sessions) = store_with_sessions(4, room_id).await;
1230 mark_backed_up(&store, room_id, "bkp", &sessions[..2]).await;
1231
1232 let key_counts = store.inbound_group_session_counts(None).await.unwrap();
1234
1235 assert_eq!(key_counts.backed_up, 0);
1237 }
1238
1239 #[async_test]
1240 async fn test_counting_backed_up_sessions_only_reports_sessions_in_the_version_specified() {
1241 let room_id = room_id!("!test:localhost");
1243 let (store, sessions) = store_with_sessions(4, room_id).await;
1244 mark_backed_up(&store, room_id, "bkp1", &sessions[..2]).await;
1245 mark_backed_up(&store, room_id, "bkp2", &sessions[3..]).await;
1246
1247 let key_counts = store.inbound_group_session_counts(Some("bkp2")).await.unwrap();
1249
1250 assert_eq!(key_counts.backed_up, 1);
1252 }
1253
1254 async fn mark_backed_up(
1256 store: &MemoryStore,
1257 room_id: &RoomId,
1258 backup_version: &str,
1259 sessions: &[InboundGroupSession],
1260 ) {
1261 let rooms_and_ids: Vec<_> = sessions.iter().map(|s| (room_id, s.session_id())).collect();
1262
1263 store
1264 .mark_inbound_group_sessions_as_backed_up(backup_version, &rooms_and_ids)
1265 .await
1266 .expect("Failed to mark sessions as backed up");
1267 }
1268
1269 async fn store_with_sessions(
1273 num_sessions: usize,
1274 room_id: &RoomId,
1275 ) -> (MemoryStore, Vec<InboundGroupSession>) {
1276 let (account, _) = get_account_and_session_test_helper();
1277
1278 let mut sessions = Vec::with_capacity(num_sessions);
1279 for _ in 0..num_sessions {
1280 sessions.push(new_session(&account, room_id).await);
1281 }
1282 sessions.sort_by_key(|s| s.session_id().to_owned());
1283
1284 let store = MemoryStore::new();
1285 store.save_inbound_group_sessions(sessions.clone(), None).await.unwrap();
1286
1287 (store, sessions)
1288 }
1289
1290 async fn new_session(account: &Account, room_id: &RoomId) -> InboundGroupSession {
1292 let curve_key = "Nn0L2hkcCMFKqynTjyGsJbth7QrVmX3lbrksMkrGOAw";
1293 let (outbound, _) = account.create_group_session_pair_with_defaults(room_id).await;
1294
1295 InboundGroupSession::new(
1296 Curve25519PublicKey::from_base64(curve_key).unwrap(),
1297 Ed25519PublicKey::from_base64("ee3Ek+J2LkkPmjGPGLhMxiKnhiX//xcqaVL4RP6EypE").unwrap(),
1298 room_id,
1299 &outbound.session_key().await,
1300 SenderData::unknown(),
1301 None,
1302 outbound.settings().algorithm.to_owned(),
1303 None,
1304 false,
1305 )
1306 .unwrap()
1307 }
1308
1309 async fn backed_up_tos(store: &MemoryStore) -> HashMap<SessionId, String> {
1312 store
1313 .get_inbound_group_sessions_and_backed_up_to()
1314 .await
1315 .expect("Unable to get inbound group sessions and backup order")
1316 .iter()
1317 .map(|(s, o)| {
1318 (
1319 s.session_id().to_owned(),
1320 o.as_ref().map(|v| v.as_str().to_owned()).unwrap_or("".to_owned()),
1321 )
1322 })
1323 .collect()
1324 }
1325}
1326
1327#[cfg(test)]
1328mod integration_tests {
1329 use std::{
1330 collections::HashMap,
1331 sync::{Arc, Mutex, OnceLock},
1332 };
1333
1334 use async_trait::async_trait;
1335 use matrix_sdk_common::cross_process_lock::CrossProcessLockGeneration;
1336 use ruma::{
1337 DeviceId, OwnedDeviceId, RoomId, TransactionId, UserId, events::secret::request::SecretName,
1338 };
1339 use vodozemac::Curve25519PublicKey;
1340 use zeroize::Zeroizing;
1341
1342 use super::MemoryStore;
1343 use crate::{
1344 Account, DeviceData, GossipRequest, SecretInfo, Session, UserIdentityData,
1345 cryptostore_integration_tests, cryptostore_integration_tests_time,
1346 olm::{
1347 InboundGroupSession, OlmMessageHash, OutboundGroupSession, PrivateCrossSigningIdentity,
1348 SenderDataType, StaticAccountData,
1349 },
1350 store::{
1351 CryptoStore,
1352 types::{
1353 BackupKeys, Changes, DehydratedDeviceKey, PendingChanges, RoomKeyCounts,
1354 RoomKeyWithheldEntry, RoomPendingKeyBundleDetails, RoomSettings,
1355 StoredRoomKeyBundleData, TrackedUser,
1356 },
1357 },
1358 };
1359
1360 #[derive(Clone, Debug)]
1363 struct PersistentMemoryStore(Arc<MemoryStore>);
1364
1365 impl PersistentMemoryStore {
1366 fn new() -> Self {
1367 Self(Arc::new(MemoryStore::new()))
1368 }
1369
1370 fn get_static_account(&self) -> Option<StaticAccountData> {
1371 self.0.get_static_account()
1372 }
1373 }
1374
1375 async fn get_store(
1380 name: &str,
1381 _passphrase: Option<&str>,
1382 clear_data: bool,
1383 ) -> PersistentMemoryStore {
1384 static STORES: OnceLock<Mutex<HashMap<String, PersistentMemoryStore>>> = OnceLock::new();
1389 let stores = STORES.get_or_init(|| Mutex::new(HashMap::new()));
1390
1391 let mut stores = stores.lock().unwrap();
1392
1393 if clear_data {
1394 let new_store = PersistentMemoryStore::new();
1396 stores.insert(name.to_owned(), new_store.clone());
1397 new_store
1398 } else {
1399 stores.entry(name.to_owned()).or_insert_with(PersistentMemoryStore::new).clone()
1400 }
1401 }
1402
1403 #[cfg_attr(target_family = "wasm", async_trait(?Send))]
1405 #[cfg_attr(not(target_family = "wasm"), async_trait)]
1406 impl CryptoStore for PersistentMemoryStore {
1407 type Error = <MemoryStore as CryptoStore>::Error;
1408
1409 async fn close(&self) -> Result<(), Self::Error> {
1410 self.0.close().await
1411 }
1412
1413 async fn reopen(&self) -> Result<(), Self::Error> {
1414 self.0.reopen().await
1415 }
1416
1417 async fn load_account(&self) -> Result<Option<Account>, Self::Error> {
1418 self.0.load_account().await
1419 }
1420
1421 async fn load_identity(&self) -> Result<Option<PrivateCrossSigningIdentity>, Self::Error> {
1422 self.0.load_identity().await
1423 }
1424
1425 async fn save_changes(&self, changes: Changes) -> Result<(), Self::Error> {
1426 self.0.save_changes(changes).await
1427 }
1428
1429 async fn save_pending_changes(&self, changes: PendingChanges) -> Result<(), Self::Error> {
1430 self.0.save_pending_changes(changes).await
1431 }
1432
1433 async fn save_inbound_group_sessions(
1434 &self,
1435 sessions: Vec<InboundGroupSession>,
1436 backed_up_to_version: Option<&str>,
1437 ) -> Result<(), Self::Error> {
1438 self.0.save_inbound_group_sessions(sessions, backed_up_to_version).await
1439 }
1440
1441 async fn get_sessions(
1442 &self,
1443 sender_key: &str,
1444 ) -> Result<Option<Vec<Session>>, Self::Error> {
1445 self.0.get_sessions(sender_key).await
1446 }
1447
1448 async fn get_inbound_group_session(
1449 &self,
1450 room_id: &RoomId,
1451 session_id: &str,
1452 ) -> Result<Option<InboundGroupSession>, Self::Error> {
1453 self.0.get_inbound_group_session(room_id, session_id).await
1454 }
1455
1456 async fn get_withheld_info(
1457 &self,
1458 room_id: &RoomId,
1459 session_id: &str,
1460 ) -> Result<Option<RoomKeyWithheldEntry>, Self::Error> {
1461 self.0.get_withheld_info(room_id, session_id).await
1462 }
1463
1464 async fn get_withheld_sessions_by_room_id(
1465 &self,
1466 room_id: &RoomId,
1467 ) -> Result<Vec<RoomKeyWithheldEntry>, Self::Error> {
1468 self.0.get_withheld_sessions_by_room_id(room_id).await
1469 }
1470
1471 async fn get_inbound_group_sessions(
1472 &self,
1473 ) -> Result<Vec<InboundGroupSession>, Self::Error> {
1474 self.0.get_inbound_group_sessions().await
1475 }
1476
1477 async fn inbound_group_session_counts(
1478 &self,
1479 backup_version: Option<&str>,
1480 ) -> Result<RoomKeyCounts, Self::Error> {
1481 self.0.inbound_group_session_counts(backup_version).await
1482 }
1483
1484 async fn get_inbound_group_sessions_by_room_id(
1485 &self,
1486 room_id: &RoomId,
1487 ) -> Result<Vec<InboundGroupSession>, Self::Error> {
1488 self.0.get_inbound_group_sessions_by_room_id(room_id).await
1489 }
1490
1491 async fn get_inbound_group_sessions_for_device_batch(
1492 &self,
1493 sender_key: Curve25519PublicKey,
1494 sender_data_type: SenderDataType,
1495 after_session_id: Option<String>,
1496 limit: usize,
1497 ) -> Result<Vec<InboundGroupSession>, Self::Error> {
1498 self.0
1499 .get_inbound_group_sessions_for_device_batch(
1500 sender_key,
1501 sender_data_type,
1502 after_session_id,
1503 limit,
1504 )
1505 .await
1506 }
1507
1508 async fn inbound_group_sessions_for_backup(
1509 &self,
1510 backup_version: &str,
1511 limit: usize,
1512 ) -> Result<Vec<InboundGroupSession>, Self::Error> {
1513 self.0.inbound_group_sessions_for_backup(backup_version, limit).await
1514 }
1515
1516 async fn mark_inbound_group_sessions_as_backed_up(
1517 &self,
1518 backup_version: &str,
1519 room_and_session_ids: &[(&RoomId, &str)],
1520 ) -> Result<(), Self::Error> {
1521 self.0
1522 .mark_inbound_group_sessions_as_backed_up(backup_version, room_and_session_ids)
1523 .await
1524 }
1525
1526 async fn reset_backup_state(&self) -> Result<(), Self::Error> {
1527 self.0.reset_backup_state().await
1528 }
1529
1530 async fn load_backup_keys(&self) -> Result<BackupKeys, Self::Error> {
1531 self.0.load_backup_keys().await
1532 }
1533
1534 async fn load_dehydrated_device_pickle_key(
1535 &self,
1536 ) -> Result<Option<DehydratedDeviceKey>, Self::Error> {
1537 self.0.load_dehydrated_device_pickle_key().await
1538 }
1539
1540 async fn delete_dehydrated_device_pickle_key(&self) -> Result<(), Self::Error> {
1541 self.0.delete_dehydrated_device_pickle_key().await
1542 }
1543
1544 async fn get_outbound_group_session(
1545 &self,
1546 room_id: &RoomId,
1547 ) -> Result<Option<OutboundGroupSession>, Self::Error> {
1548 self.0.get_outbound_group_session(room_id).await
1549 }
1550
1551 async fn load_tracked_users(&self) -> Result<Vec<TrackedUser>, Self::Error> {
1552 self.0.load_tracked_users().await
1553 }
1554
1555 async fn save_tracked_users(&self, users: &[(&UserId, bool)]) -> Result<(), Self::Error> {
1556 self.0.save_tracked_users(users).await
1557 }
1558
1559 async fn get_device(
1560 &self,
1561 user_id: &UserId,
1562 device_id: &DeviceId,
1563 ) -> Result<Option<DeviceData>, Self::Error> {
1564 self.0.get_device(user_id, device_id).await
1565 }
1566
1567 async fn get_user_devices(
1568 &self,
1569 user_id: &UserId,
1570 ) -> Result<HashMap<OwnedDeviceId, DeviceData>, Self::Error> {
1571 self.0.get_user_devices(user_id).await
1572 }
1573
1574 async fn get_own_device(&self) -> Result<DeviceData, Self::Error> {
1575 self.0.get_own_device().await
1576 }
1577
1578 async fn get_user_identity(
1579 &self,
1580 user_id: &UserId,
1581 ) -> Result<Option<UserIdentityData>, Self::Error> {
1582 self.0.get_user_identity(user_id).await
1583 }
1584
1585 async fn is_message_known(
1586 &self,
1587 message_hash: &OlmMessageHash,
1588 ) -> Result<bool, Self::Error> {
1589 self.0.is_message_known(message_hash).await
1590 }
1591
1592 async fn get_outgoing_secret_requests(
1593 &self,
1594 request_id: &TransactionId,
1595 ) -> Result<Option<GossipRequest>, Self::Error> {
1596 self.0.get_outgoing_secret_requests(request_id).await
1597 }
1598
1599 async fn get_secret_request_by_info(
1600 &self,
1601 secret_info: &SecretInfo,
1602 ) -> Result<Option<GossipRequest>, Self::Error> {
1603 self.0.get_secret_request_by_info(secret_info).await
1604 }
1605
1606 async fn get_unsent_secret_requests(&self) -> Result<Vec<GossipRequest>, Self::Error> {
1607 self.0.get_unsent_secret_requests().await
1608 }
1609
1610 async fn delete_outgoing_secret_requests(
1611 &self,
1612 request_id: &TransactionId,
1613 ) -> Result<(), Self::Error> {
1614 self.0.delete_outgoing_secret_requests(request_id).await
1615 }
1616
1617 async fn get_secrets_from_inbox(
1618 &self,
1619 secret_name: &SecretName,
1620 ) -> Result<Vec<Zeroizing<String>>, Self::Error> {
1621 self.0.get_secrets_from_inbox(secret_name).await
1622 }
1623
1624 async fn delete_secrets_from_inbox(
1625 &self,
1626 secret_name: &SecretName,
1627 ) -> Result<(), Self::Error> {
1628 self.0.delete_secrets_from_inbox(secret_name).await
1629 }
1630
1631 async fn get_room_settings(
1632 &self,
1633 room_id: &RoomId,
1634 ) -> Result<Option<RoomSettings>, Self::Error> {
1635 self.0.get_room_settings(room_id).await
1636 }
1637
1638 async fn get_received_room_key_bundle_data(
1639 &self,
1640 room_id: &RoomId,
1641 user_id: &UserId,
1642 ) -> crate::store::Result<Option<StoredRoomKeyBundleData>, Self::Error> {
1643 self.0.get_received_room_key_bundle_data(room_id, user_id).await
1644 }
1645
1646 async fn has_downloaded_all_room_keys(
1647 &self,
1648 room_id: &RoomId,
1649 ) -> Result<bool, Self::Error> {
1650 self.0.has_downloaded_all_room_keys(room_id).await
1651 }
1652
1653 async fn get_pending_key_bundle_details_for_room(
1654 &self,
1655 room_id: &RoomId,
1656 ) -> Result<Option<RoomPendingKeyBundleDetails>, Self::Error> {
1657 self.0.get_pending_key_bundle_details_for_room(room_id).await
1658 }
1659
1660 async fn get_all_rooms_pending_key_bundles(
1661 &self,
1662 ) -> Result<Vec<RoomPendingKeyBundleDetails>, Self::Error> {
1663 self.0.get_all_rooms_pending_key_bundles().await
1664 }
1665
1666 async fn get_custom_value(&self, key: &str) -> Result<Option<Vec<u8>>, Self::Error> {
1667 self.0.get_custom_value(key).await
1668 }
1669
1670 async fn set_custom_value(&self, key: &str, value: Vec<u8>) -> Result<(), Self::Error> {
1671 self.0.set_custom_value(key, value).await
1672 }
1673
1674 async fn remove_custom_value(&self, key: &str) -> Result<(), Self::Error> {
1675 self.0.remove_custom_value(key).await
1676 }
1677
1678 async fn try_take_leased_lock(
1679 &self,
1680 lease_duration_ms: u32,
1681 key: &str,
1682 holder: &str,
1683 ) -> Result<Option<CrossProcessLockGeneration>, Self::Error> {
1684 self.0.try_take_leased_lock(lease_duration_ms, key, holder).await
1685 }
1686
1687 async fn next_batch_token(&self) -> Result<Option<String>, Self::Error> {
1688 self.0.next_batch_token().await
1689 }
1690
1691 async fn get_size(&self) -> Result<Option<usize>, Self::Error> {
1692 self.0.get_size().await
1693 }
1694 }
1695
1696 cryptostore_integration_tests!();
1697 cryptostore_integration_tests_time!();
1698}