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);
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();
393 if backed_up != backed_up_to_version.is_some() {
394 warn!(
395 backed_up,
396 backed_up_to_version,
397 "Session backed-up flag does not correspond to backup version setting",
398 );
399 }
400
401 if let Some(backup_version) = backed_up_to_version {
402 self.inbound_group_sessions_backed_up_to
403 .write()
404 .entry(room_id.to_owned())
405 .or_default()
406 .insert(session_id.to_owned(), BackupVersion::from(backup_version));
407 }
408
409 let pickle = session.pickle().await;
410 self.inbound_group_sessions
411 .write()
412 .entry(session.room_id().to_owned())
413 .or_default()
414 .insert(
415 session.session_id().to_owned(),
416 serde_json::to_string(&pickle)
417 .expect("Pickle pickle data should serialize to json"),
418 );
419 }
420 Ok(())
421 }
422
423 async fn get_sessions(&self, sender_key: &str) -> Result<Option<Vec<Session>>> {
424 let device_keys = self.get_own_device().await?.as_device_keys().clone();
425
426 if let Some(pickles) = self.sessions.read().get(sender_key) {
427 let mut sessions: Vec<Session> = Vec::new();
428 for serialized_pickle in pickles.values() {
429 let pickle: PickledSession = serde_json::from_str(serialized_pickle.as_str())
430 .expect("Pickle pickle deserialization should work");
431 let session = Session::from_pickle(device_keys.clone(), pickle)
432 .expect("Expect from pickle to always work");
433 sessions.push(session);
434 }
435 Ok(Some(sessions))
436 } else {
437 Ok(None)
438 }
439 }
440
441 async fn get_inbound_group_session(
442 &self,
443 room_id: &RoomId,
444 session_id: &str,
445 ) -> Result<Option<InboundGroupSession>> {
446 let pickle: Option<PickledInboundGroupSession> = self
447 .inbound_group_sessions
448 .read()
449 .get(room_id)
450 .and_then(|m| m.get(session_id))
451 .and_then(|ser| {
452 serde_json::from_str(ser).expect("Pickle pickle deserialization should work")
453 });
454
455 Ok(pickle.map(|p| {
456 InboundGroupSession::from_pickle(p).expect("Expect from pickle to always work")
457 }))
458 }
459
460 async fn get_withheld_info(
461 &self,
462 room_id: &RoomId,
463 session_id: &str,
464 ) -> Result<Option<RoomKeyWithheldEntry>> {
465 Ok(self
466 .direct_withheld_info
467 .read()
468 .get(room_id)
469 .and_then(|e| Some(e.get(session_id)?.to_owned())))
470 }
471
472 async fn get_withheld_sessions_by_room_id(
473 &self,
474 room_id: &RoomId,
475 ) -> crate::store::Result<Vec<RoomKeyWithheldEntry>, Self::Error> {
476 Ok(self
477 .direct_withheld_info
478 .read()
479 .get(room_id)
480 .map(|e| e.values().cloned().collect())
481 .unwrap_or_default())
482 }
483
484 async fn get_inbound_group_sessions(&self) -> Result<Vec<InboundGroupSession>> {
485 let inbounds = self
486 .inbound_group_sessions
487 .read()
488 .values()
489 .flat_map(HashMap::values)
490 .map(|ser| {
491 let pickle: PickledInboundGroupSession =
492 serde_json::from_str(ser).expect("Pickle deserialization should work");
493 InboundGroupSession::from_pickle(pickle).expect("Expect from pickle to always work")
494 })
495 .collect();
496 Ok(inbounds)
497 }
498
499 async fn inbound_group_session_counts(
500 &self,
501 backup_version: Option<&str>,
502 ) -> Result<RoomKeyCounts> {
503 let backed_up = if let Some(backup_version) = backup_version {
504 self.get_inbound_group_sessions_and_backed_up_to()
505 .await?
506 .into_iter()
507 .filter(|(_, o)| o.as_ref().is_some_and(|o| o.as_str() == backup_version))
509 .count()
510 } else {
511 0
515 };
516
517 let total = self.inbound_group_sessions.read().values().map(HashMap::len).sum();
518 Ok(RoomKeyCounts { total, backed_up })
519 }
520
521 async fn get_inbound_group_sessions_by_room_id(
522 &self,
523 room_id: &RoomId,
524 ) -> Result<Vec<InboundGroupSession>> {
525 let inbounds = match self.inbound_group_sessions.read().get(room_id) {
526 None => Vec::new(),
527 Some(v) => v
528 .values()
529 .map(|ser| {
530 let pickle: PickledInboundGroupSession =
531 serde_json::from_str(ser).expect("Pickle deserialization should work");
532 InboundGroupSession::from_pickle(pickle)
533 .expect("Expect from pickle to always work")
534 })
535 .collect(),
536 };
537 Ok(inbounds)
538 }
539
540 async fn get_inbound_group_sessions_for_device_batch(
541 &self,
542 sender_key: Curve25519PublicKey,
543 sender_data_type: SenderDataType,
544 after_session_id: Option<String>,
545 limit: usize,
546 ) -> Result<Vec<InboundGroupSession>> {
547 let mut sessions: Vec<_> = self
550 .get_inbound_group_sessions()
551 .await?
552 .into_iter()
553 .filter(|session: &InboundGroupSession| {
554 session.creator_info.curve25519_key == sender_key
555 && session.sender_data.to_type() == sender_data_type
556 })
557 .collect();
558
559 sessions.sort_by_key(|s| s.session_id().to_owned());
561
562 let start_index = {
564 match after_session_id {
565 None => 0,
566 Some(id) => {
567 sessions
571 .iter()
572 .position(|session| session.session_id() > id.as_str())
573 .unwrap_or(sessions.len())
574 }
575 }
576 };
577
578 Ok(sessions.drain(start_index..).take(limit).collect())
581 }
582
583 async fn inbound_group_sessions_for_backup(
584 &self,
585 backup_version: &str,
586 limit: usize,
587 ) -> Result<Vec<InboundGroupSession>> {
588 Ok(self
589 .get_inbound_group_sessions_and_backed_up_to()
590 .await?
591 .into_iter()
592 .filter_map(|(session, backed_up_to)| {
593 if let Some(ref existing_version) = backed_up_to
594 && existing_version.as_str() == backup_version
595 {
596 None
598 } else {
599 Some(session)
602 }
603 })
604 .take(limit)
605 .collect())
606 }
607
608 async fn mark_inbound_group_sessions_as_backed_up(
609 &self,
610 backup_version: &str,
611 room_and_session_ids: &[(&RoomId, &str)],
612 ) -> Result<()> {
613 for &(room_id, session_id) in room_and_session_ids {
614 let session = self.get_inbound_group_session(room_id, session_id).await?;
615
616 if let Some(session) = session {
617 session.mark_as_backed_up();
618
619 self.inbound_group_sessions_backed_up_to
620 .write()
621 .entry(room_id.to_owned())
622 .or_default()
623 .insert(session_id.to_owned(), BackupVersion::from(backup_version));
624
625 let updated_pickle = session.pickle().await;
627
628 self.inbound_group_sessions.write().entry(room_id.to_owned()).or_default().insert(
629 session_id.to_owned(),
630 serde_json::to_string(&updated_pickle)
631 .expect("Pickle serialization should work"),
632 );
633 }
634 }
635
636 Ok(())
637 }
638
639 async fn reset_backup_state(&self) -> Result<()> {
640 Ok(())
647 }
648
649 async fn load_backup_keys(&self) -> Result<BackupKeys> {
650 Ok(self.backup_keys.read().await.to_owned())
651 }
652
653 async fn load_dehydrated_device_pickle_key(&self) -> Result<Option<DehydratedDeviceKey>> {
654 Ok(self.dehydrated_device_pickle_key.read().await.to_owned())
655 }
656
657 async fn delete_dehydrated_device_pickle_key(&self) -> Result<()> {
658 let mut lock = self.dehydrated_device_pickle_key.write().await;
659 *lock = None;
660 Ok(())
661 }
662
663 async fn get_outbound_group_session(
664 &self,
665 room_id: &RoomId,
666 ) -> Result<Option<OutboundGroupSession>> {
667 Ok(self.outbound_group_sessions.read().get(room_id).cloned())
668 }
669
670 async fn load_tracked_users(&self) -> Result<Vec<TrackedUser>> {
671 Ok(self.tracked_users.read().values().cloned().collect())
672 }
673
674 async fn save_tracked_users(&self, tracked_users: &[(&UserId, bool)]) -> Result<()> {
675 self.tracked_users.write().extend(tracked_users.iter().map(|(user_id, dirty)| {
676 let user_id: OwnedUserId = user_id.to_owned().into();
677 (user_id.clone(), TrackedUser { user_id, dirty: *dirty })
678 }));
679 Ok(())
680 }
681
682 async fn get_device(
683 &self,
684 user_id: &UserId,
685 device_id: &DeviceId,
686 ) -> Result<Option<DeviceData>> {
687 Ok(self.devices.get(user_id, device_id))
688 }
689
690 async fn get_user_devices(
691 &self,
692 user_id: &UserId,
693 ) -> Result<HashMap<OwnedDeviceId, DeviceData>> {
694 Ok(self.devices.user_devices(user_id))
695 }
696
697 async fn get_own_device(&self) -> Result<DeviceData> {
698 let account =
699 self.get_static_account().expect("Expect account to exist when getting own device");
700
701 Ok(self
702 .devices
703 .get(&account.user_id, &account.device_id)
704 .expect("Invalid state: Should always have a own device"))
705 }
706
707 async fn get_user_identity(&self, user_id: &UserId) -> Result<Option<UserIdentityData>> {
708 let serialized = self.identities.read().get(user_id).cloned();
709 match serialized {
710 None => Ok(None),
711 Some(serialized) => {
712 let id: UserIdentityData = serde_json::from_str(serialized.as_str())
713 .expect("Only valid serialized identity are saved");
714 Ok(Some(id))
715 }
716 }
717 }
718
719 async fn is_message_known(&self, message_hash: &crate::olm::OlmMessageHash) -> Result<bool> {
720 Ok(self
721 .olm_hashes
722 .write()
723 .entry(message_hash.sender_key.to_owned())
724 .or_default()
725 .contains(&message_hash.hash))
726 }
727
728 async fn get_outgoing_secret_requests(
729 &self,
730 request_id: &TransactionId,
731 ) -> Result<Option<GossipRequest>> {
732 Ok(self.outgoing_key_requests.read().get(request_id).cloned())
733 }
734
735 async fn get_secret_request_by_info(
736 &self,
737 key_info: &SecretInfo,
738 ) -> Result<Option<GossipRequest>> {
739 let key_info_string = encode_key_info(key_info);
740
741 Ok(self
742 .key_requests_by_info
743 .read()
744 .get(&key_info_string)
745 .and_then(|i| self.outgoing_key_requests.read().get(i).cloned()))
746 }
747
748 async fn get_unsent_secret_requests(&self) -> Result<Vec<GossipRequest>> {
749 Ok(self
750 .outgoing_key_requests
751 .read()
752 .values()
753 .filter(|req| !req.sent_out)
754 .cloned()
755 .collect())
756 }
757
758 async fn delete_outgoing_secret_requests(&self, request_id: &TransactionId) -> Result<()> {
759 let req = self.outgoing_key_requests.write().remove(request_id);
760 if let Some(i) = req {
761 let key_info_string = encode_key_info(&i.info);
762 self.key_requests_by_info.write().remove(&key_info_string);
763 }
764
765 Ok(())
766 }
767
768 async fn get_secrets_from_inbox(
769 &self,
770 secret_name: &SecretName,
771 ) -> Result<Vec<Zeroizing<String>>> {
772 Ok(self.secret_inbox.write().entry(secret_name.to_string()).or_default().to_owned())
773 }
774
775 async fn delete_secrets_from_inbox(&self, secret_name: &SecretName) -> Result<()> {
776 self.secret_inbox.write().remove(secret_name.as_str());
777
778 Ok(())
779 }
780
781 async fn get_room_settings(&self, room_id: &RoomId) -> Result<Option<RoomSettings>> {
782 Ok(self.room_settings.read().get(room_id).cloned())
783 }
784
785 async fn get_received_room_key_bundle_data(
786 &self,
787 room_id: &RoomId,
788 user_id: &UserId,
789 ) -> Result<Option<StoredRoomKeyBundleData>> {
790 let guard = self.room_key_bundles.read();
791
792 let result = guard.get(room_id).and_then(|bundles| bundles.get(user_id).cloned());
793
794 Ok(result)
795 }
796
797 async fn get_pending_key_bundle_details_for_room(
798 &self,
799 room_id: &RoomId,
800 ) -> Result<Option<RoomPendingKeyBundleDetails>> {
801 Ok(self.rooms_pending_key_bundle.read().get(room_id).cloned())
802 }
803
804 async fn get_all_rooms_pending_key_bundles(&self) -> Result<Vec<RoomPendingKeyBundleDetails>> {
805 Ok(self.rooms_pending_key_bundle.read().values().cloned().collect())
806 }
807
808 async fn has_downloaded_all_room_keys(&self, room_id: &RoomId) -> Result<bool> {
809 let guard = self.room_key_backups_fully_downloaded.read();
810 Ok(guard.contains(room_id))
811 }
812
813 async fn get_custom_value(&self, key: &str) -> Result<Option<Vec<u8>>> {
814 Ok(self.custom_values.read().get(key).cloned())
815 }
816
817 async fn set_custom_value(&self, key: &str, value: Vec<u8>) -> Result<()> {
818 self.custom_values.write().insert(key.to_owned(), value);
819 Ok(())
820 }
821
822 async fn remove_custom_value(&self, key: &str) -> Result<()> {
823 self.custom_values.write().remove(key);
824 Ok(())
825 }
826
827 async fn try_take_leased_lock(
828 &self,
829 lease_duration_ms: u32,
830 key: &str,
831 holder: &str,
832 ) -> Result<Option<CrossProcessLockGeneration>> {
833 Ok(try_take_leased_lock(&mut self.leases.write(), lease_duration_ms, key, holder))
834 }
835
836 async fn get_size(&self) -> Result<Option<usize>> {
837 Ok(None)
838 }
839}
840
841#[cfg(test)]
842mod tests {
843 use std::collections::HashMap;
844
845 use matrix_sdk_test::async_test;
846 use ruma::{RoomId, room_id, user_id};
847 use vodozemac::{Curve25519PublicKey, Ed25519PublicKey};
848
849 use super::SessionId;
850 use crate::{
851 DeviceData,
852 identities::device::testing::get_device,
853 olm::{
854 Account, InboundGroupSession, OlmMessageHash, PrivateCrossSigningIdentity, SenderData,
855 tests::get_account_and_session_test_helper,
856 },
857 store::{
858 CryptoStore,
859 memorystore::MemoryStore,
860 types::{Changes, DeviceChanges, PendingChanges},
861 },
862 };
863
864 #[async_test]
865 async fn test_session_store() {
866 let (account, session) = get_account_and_session_test_helper();
867 let own_device = DeviceData::from_account(&account);
868 let store = MemoryStore::new();
869
870 assert!(store.load_account().await.unwrap().is_none());
871
872 store
873 .save_changes(Changes {
874 devices: DeviceChanges { new: vec![own_device], ..Default::default() },
875 ..Default::default()
876 })
877 .await
878 .unwrap();
879 store.save_pending_changes(PendingChanges { account: Some(account) }).await.unwrap();
880
881 store
882 .save_changes(Changes { sessions: (vec![session.clone()]), ..Default::default() })
883 .await
884 .unwrap();
885
886 let sessions = store.get_sessions(&session.sender_key.to_base64()).await.unwrap().unwrap();
887
888 let loaded_session = &sessions[0];
889
890 assert_eq!(&session, loaded_session);
891 }
892
893 #[async_test]
894 async fn test_inbound_group_session_store() {
895 let (account, _) = get_account_and_session_test_helper();
896 let room_id = room_id!("!test:localhost");
897 let curve_key = "Nn0L2hkcCMFKqynTjyGsJbth7QrVmX3lbrksMkrGOAw";
898
899 let (outbound, _) = account.create_group_session_pair_with_defaults(room_id).await;
900 let inbound = InboundGroupSession::new(
901 Curve25519PublicKey::from_base64(curve_key).unwrap(),
902 Ed25519PublicKey::from_base64("ee3Ek+J2LkkPmjGPGLhMxiKnhiX//xcqaVL4RP6EypE").unwrap(),
903 room_id,
904 &outbound.session_key().await,
905 SenderData::unknown(),
906 None,
907 outbound.settings().algorithm.to_owned(),
908 None,
909 false,
910 )
911 .unwrap();
912
913 let store = MemoryStore::new();
914 store.save_inbound_group_sessions(vec![inbound.clone()], None).await.unwrap();
915
916 let loaded_session =
917 store.get_inbound_group_session(room_id, outbound.session_id()).await.unwrap().unwrap();
918 assert_eq!(inbound, loaded_session);
919 }
920
921 #[async_test]
922 async fn test_backing_up_marks_sessions_as_backed_up() {
923 let room_id = room_id!("!test:localhost");
925 let (store, sessions) = store_with_sessions(2, room_id).await;
926
927 mark_backed_up(&store, room_id, "bkp1", &sessions).await;
929
930 let but = backed_up_tos(&store).await;
932 assert_eq!(but[sessions[0].session_id()], "bkp1");
933 assert_eq!(but[sessions[1].session_id()], "bkp1");
934 }
935
936 #[async_test]
937 async fn test_backing_up_a_second_set_of_sessions_updates_their_backup_order() {
938 let room_id = room_id!("!test:localhost");
940 let (store, sessions) = store_with_sessions(3, room_id).await;
941
942 mark_backed_up(&store, room_id, "bkp1", &sessions[..2]).await;
944
945 mark_backed_up(&store, room_id, "bkp2", &sessions[1..]).await;
947
948 let but = backed_up_tos(&store).await;
950 assert_eq!(but[sessions[0].session_id()], "bkp1");
951 assert_eq!(but[sessions[1].session_id()], "bkp2");
952 assert_eq!(but[sessions[2].session_id()], "bkp2");
953 }
954
955 #[async_test]
956 async fn test_backing_up_again_to_the_same_version_has_no_effect() {
957 let room_id = room_id!("!test:localhost");
959 let (store, sessions) = store_with_sessions(3, room_id).await;
960
961 mark_backed_up(&store, room_id, "bkp1", &sessions[..2]).await;
963
964 mark_backed_up(&store, room_id, "bkp1", &sessions[1..]).await;
966
967 let but = backed_up_tos(&store).await;
969 assert_eq!(but[sessions[0].session_id()], "bkp1");
970 assert_eq!(but[sessions[1].session_id()], "bkp1");
971 assert_eq!(but[sessions[2].session_id()], "bkp1");
972 }
973
974 #[async_test]
975 async fn test_backing_up_to_an_old_backup_version_can_increase_backed_up_to() {
976 let room_id = room_id!("!test:localhost");
979 let (store, sessions) = store_with_sessions(4, room_id).await;
980 mark_backed_up(&store, room_id, "older_bkp", &sessions[..2]).await;
981 mark_backed_up(&store, room_id, "newer_bkp", &sessions[1..2]).await;
982
983 mark_backed_up(&store, room_id, "older_bkp", &sessions[2..]).await;
985
986 let but = backed_up_tos(&store).await;
988 assert_eq!(but[sessions[0].session_id()], "older_bkp");
989 assert_eq!(but[sessions[1].session_id()], "newer_bkp");
990 assert_eq!(but[sessions[2].session_id()], "older_bkp");
991 assert_eq!(but[sessions[3].session_id()], "older_bkp");
992 }
993
994 #[async_test]
995 async fn test_backing_up_to_an_old_backup_version_overwrites_a_newer_one() {
996 let room_id = room_id!("!test:localhost");
998 let (store, sessions) = store_with_sessions(4, room_id).await;
999 mark_backed_up(&store, room_id, "older_bkp", &sessions).await;
1000 assert_eq!(backed_up_tos(&store).await[sessions[0].session_id()], "older_bkp");
1002 mark_backed_up(&store, room_id, "newer_bkp", &sessions).await;
1003 assert_eq!(backed_up_tos(&store).await[sessions[0].session_id()], "newer_bkp");
1005
1006 mark_backed_up(&store, room_id, "older_bkp", &sessions[..2]).await;
1008
1009 let but = backed_up_tos(&store).await;
1011 assert_eq!(but[sessions[0].session_id()], "older_bkp");
1012 assert_eq!(but[sessions[1].session_id()], "older_bkp");
1013 assert_eq!(but[sessions[2].session_id()], "newer_bkp");
1014 assert_eq!(but[sessions[3].session_id()], "newer_bkp");
1015 }
1016
1017 #[async_test]
1018 async fn test_not_backed_up_sessions_are_eligible_for_backup() {
1019 let room_id = room_id!("!test:localhost");
1021 let (store, sessions) = store_with_sessions(4, room_id).await;
1022 mark_backed_up(&store, room_id, "bkp1", &sessions[..2]).await;
1023
1024 let mut to_backup = store
1026 .inbound_group_sessions_for_backup("bkp1", 10)
1027 .await
1028 .expect("Failed to ask for sessions to backup");
1029 to_backup.sort_by_key(|s| s.session_id().to_owned());
1030
1031 assert_eq!(to_backup, &[sessions[2].clone(), sessions[3].clone()]);
1033 }
1034
1035 #[async_test]
1036 async fn test_all_sessions_are_eligible_for_backup_if_version_is_unknown() {
1037 let room_id = room_id!("!test:localhost");
1039 let (store, sessions) = store_with_sessions(4, room_id).await;
1040 mark_backed_up(&store, room_id, "bkp1", &sessions[..2]).await;
1041
1042 let mut to_backup = store
1044 .inbound_group_sessions_for_backup("unknown_bkp", 10)
1045 .await
1046 .expect("Failed to ask for sessions to backup");
1047 to_backup.sort_by_key(|s| s.session_id().to_owned());
1048
1049 assert_eq!(
1051 to_backup,
1052 &[sessions[0].clone(), sessions[1].clone(), sessions[2].clone(), sessions[3].clone()]
1053 );
1054 }
1055
1056 #[async_test]
1057 async fn test_sessions_backed_up_to_a_later_version_are_eligible_for_backup() {
1058 let room_id = room_id!("!test:localhost");
1061 let (store, sessions) = store_with_sessions(4, room_id).await;
1062 mark_backed_up(&store, room_id, "bkp0", &sessions[..1]).await;
1063 mark_backed_up(&store, room_id, "bkp1", &sessions[1..2]).await;
1064 mark_backed_up(&store, room_id, "bkp2", &sessions[2..3]).await;
1065
1066 let mut to_backup = store
1068 .inbound_group_sessions_for_backup("bkp1", 10)
1069 .await
1070 .expect("Failed to ask for sessions to backup");
1071 to_backup.sort_by_key(|s| s.session_id().to_owned());
1072
1073 assert_eq!(
1075 to_backup,
1076 &[
1077 sessions[0].clone(), sessions[2].clone(), sessions[3].clone(), ]
1083 );
1084 }
1085
1086 #[async_test]
1087 async fn test_outbound_group_session_store() {
1088 let (account, _) = get_account_and_session_test_helper();
1090 let room_id = room_id!("!test:localhost");
1091 let (outbound, _) = account.create_group_session_pair_with_defaults(room_id).await;
1092
1093 let store = MemoryStore::new();
1095 store.save_outbound_group_sessions(vec![outbound.clone()]);
1096
1097 let loaded_session = store.get_outbound_group_session(room_id).await.unwrap().unwrap();
1099 assert_eq!(
1100 serde_json::to_string(&outbound.pickle().await).unwrap(),
1101 serde_json::to_string(&loaded_session.pickle().await).unwrap()
1102 );
1103 }
1104
1105 #[async_test]
1106 async fn test_tracked_users_are_stored_once_per_user_id() {
1107 let user1 = user_id!("@user1:s");
1109 let user2 = user_id!("@user2:s");
1110 let user3 = user_id!("@user3:s");
1111 let store = MemoryStore::new();
1112 store.save_tracked_users(&[(user1, true), (user2, true)]).await.unwrap();
1113
1114 store.save_tracked_users(&[(user2, false), (user3, false)]).await.unwrap();
1116
1117 let loaded_tracked_users =
1119 store.load_tracked_users().await.expect("failed to load tracked users");
1120
1121 let tracked_contains = |user_id, dirty| {
1122 loaded_tracked_users.iter().any(|u| u.user_id == user_id && u.dirty == dirty)
1123 };
1124
1125 assert!(tracked_contains(user1, true));
1126 assert!(tracked_contains(user2, false));
1127 assert!(tracked_contains(user3, false));
1128 assert_eq!(loaded_tracked_users.len(), 3);
1129 }
1130
1131 #[async_test]
1132 async fn test_private_identity_store() {
1133 let private_identity = PrivateCrossSigningIdentity::empty(user_id!("@u:s"));
1135
1136 let store = MemoryStore::new();
1138 store.save_private_identity(Some(private_identity.clone()));
1139
1140 let loaded_identity =
1142 store.load_identity().await.expect("failed to load private identity").unwrap();
1143
1144 assert_eq!(loaded_identity.user_id(), "@u:s");
1145 }
1146
1147 #[async_test]
1148 async fn test_device_store() {
1149 let device = get_device();
1150 let store = MemoryStore::new();
1151
1152 store.save_devices(vec![device.clone()]);
1153
1154 let loaded_device =
1155 store.get_device(device.user_id(), device.device_id()).await.unwrap().unwrap();
1156
1157 assert_eq!(device, loaded_device);
1158
1159 let user_devices = store.get_user_devices(device.user_id()).await.unwrap();
1160
1161 assert_eq!(&**user_devices.keys().next().unwrap(), device.device_id());
1162 assert_eq!(user_devices.values().next().unwrap(), &device);
1163
1164 let loaded_device = user_devices.get(device.device_id()).unwrap();
1165
1166 assert_eq!(&device, loaded_device);
1167
1168 store.delete_devices(vec![device.clone()]);
1169 assert!(store.get_device(device.user_id(), device.device_id()).await.unwrap().is_none());
1170 }
1171
1172 #[async_test]
1173 async fn test_message_hash() {
1174 let store = MemoryStore::new();
1175
1176 let hash =
1177 OlmMessageHash { sender_key: "test_sender".to_owned(), hash: "test_hash".to_owned() };
1178
1179 let mut changes = Changes::default();
1180 changes.message_hashes.push(hash.clone());
1181
1182 assert!(!store.is_message_known(&hash).await.unwrap());
1183 store.save_changes(changes).await.unwrap();
1184 assert!(store.is_message_known(&hash).await.unwrap());
1185 }
1186
1187 #[async_test]
1188 async fn test_key_counts_of_empty_store_are_zero() {
1189 let store = MemoryStore::new();
1191
1192 let key_counts = store.inbound_group_session_counts(Some("")).await.unwrap();
1194
1195 assert_eq!(key_counts.total, 0);
1197 assert_eq!(key_counts.backed_up, 0);
1198 }
1199
1200 #[async_test]
1201 async fn test_counting_sessions_reports_the_number_of_sessions() {
1202 let room_id = room_id!("!test:localhost");
1204 let (store, _) = store_with_sessions(4, room_id).await;
1205
1206 let key_counts = store.inbound_group_session_counts(Some("bkp")).await.unwrap();
1208
1209 assert_eq!(key_counts.total, 4);
1211 assert_eq!(key_counts.backed_up, 0);
1213 }
1214
1215 #[async_test]
1216 async fn test_counting_backed_up_sessions_reports_the_number_backed_up_in_this_backup() {
1217 let room_id = room_id!("!test:localhost");
1219 let (store, sessions) = store_with_sessions(5, room_id).await;
1220 mark_backed_up(&store, room_id, "bkp", &sessions[..2]).await;
1221
1222 let key_counts = store.inbound_group_session_counts(Some("bkp")).await.unwrap();
1224
1225 assert_eq!(key_counts.total, 5);
1227 assert_eq!(key_counts.backed_up, 2);
1229 }
1230
1231 #[async_test]
1232 async fn test_counting_backed_up_sessions_for_null_backup_reports_zero() {
1233 let room_id = room_id!("!test:localhost");
1235 let (store, sessions) = store_with_sessions(4, room_id).await;
1236 mark_backed_up(&store, room_id, "bkp", &sessions[..2]).await;
1237
1238 let key_counts = store.inbound_group_session_counts(None).await.unwrap();
1240
1241 assert_eq!(key_counts.backed_up, 0);
1243 }
1244
1245 #[async_test]
1246 async fn test_counting_backed_up_sessions_only_reports_sessions_in_the_version_specified() {
1247 let room_id = room_id!("!test:localhost");
1249 let (store, sessions) = store_with_sessions(4, room_id).await;
1250 mark_backed_up(&store, room_id, "bkp1", &sessions[..2]).await;
1251 mark_backed_up(&store, room_id, "bkp2", &sessions[3..]).await;
1252
1253 let key_counts = store.inbound_group_session_counts(Some("bkp2")).await.unwrap();
1255
1256 assert_eq!(key_counts.backed_up, 1);
1259 }
1260
1261 async fn mark_backed_up(
1263 store: &MemoryStore,
1264 room_id: &RoomId,
1265 backup_version: &str,
1266 sessions: &[InboundGroupSession],
1267 ) {
1268 let rooms_and_ids: Vec<_> = sessions.iter().map(|s| (room_id, s.session_id())).collect();
1269
1270 store
1271 .mark_inbound_group_sessions_as_backed_up(backup_version, &rooms_and_ids)
1272 .await
1273 .expect("Failed to mark sessions as backed up");
1274 }
1275
1276 async fn store_with_sessions(
1280 num_sessions: usize,
1281 room_id: &RoomId,
1282 ) -> (MemoryStore, Vec<InboundGroupSession>) {
1283 let (account, _) = get_account_and_session_test_helper();
1284
1285 let mut sessions = Vec::with_capacity(num_sessions);
1286 for _ in 0..num_sessions {
1287 sessions.push(new_session(&account, room_id).await);
1288 }
1289 sessions.sort_by_key(|s| s.session_id().to_owned());
1290
1291 let store = MemoryStore::new();
1292 store.save_inbound_group_sessions(sessions.clone(), None).await.unwrap();
1293
1294 (store, sessions)
1295 }
1296
1297 async fn new_session(account: &Account, room_id: &RoomId) -> InboundGroupSession {
1299 let curve_key = "Nn0L2hkcCMFKqynTjyGsJbth7QrVmX3lbrksMkrGOAw";
1300 let (outbound, _) = account.create_group_session_pair_with_defaults(room_id).await;
1301
1302 InboundGroupSession::new(
1303 Curve25519PublicKey::from_base64(curve_key).unwrap(),
1304 Ed25519PublicKey::from_base64("ee3Ek+J2LkkPmjGPGLhMxiKnhiX//xcqaVL4RP6EypE").unwrap(),
1305 room_id,
1306 &outbound.session_key().await,
1307 SenderData::unknown(),
1308 None,
1309 outbound.settings().algorithm.to_owned(),
1310 None,
1311 false,
1312 )
1313 .unwrap()
1314 }
1315
1316 async fn backed_up_tos(store: &MemoryStore) -> HashMap<SessionId, String> {
1319 store
1320 .get_inbound_group_sessions_and_backed_up_to()
1321 .await
1322 .expect("Unable to get inbound group sessions and backup order")
1323 .iter()
1324 .map(|(s, o)| {
1325 (
1326 s.session_id().to_owned(),
1327 o.as_ref().map(|v| v.as_str().to_owned()).unwrap_or("".to_owned()),
1328 )
1329 })
1330 .collect()
1331 }
1332}
1333
1334#[cfg(test)]
1335mod integration_tests {
1336 use std::{
1337 collections::HashMap,
1338 sync::{Arc, Mutex, OnceLock},
1339 };
1340
1341 use async_trait::async_trait;
1342 use matrix_sdk_common::cross_process_lock::CrossProcessLockGeneration;
1343 use ruma::{
1344 DeviceId, OwnedDeviceId, RoomId, TransactionId, UserId, events::secret::request::SecretName,
1345 };
1346 use vodozemac::Curve25519PublicKey;
1347 use zeroize::Zeroizing;
1348
1349 use super::MemoryStore;
1350 use crate::{
1351 Account, DeviceData, GossipRequest, SecretInfo, Session, UserIdentityData,
1352 cryptostore_integration_tests, cryptostore_integration_tests_time,
1353 olm::{
1354 InboundGroupSession, OlmMessageHash, OutboundGroupSession, PrivateCrossSigningIdentity,
1355 SenderDataType, StaticAccountData,
1356 },
1357 store::{
1358 CryptoStore,
1359 types::{
1360 BackupKeys, Changes, DehydratedDeviceKey, PendingChanges, RoomKeyCounts,
1361 RoomKeyWithheldEntry, RoomPendingKeyBundleDetails, RoomSettings,
1362 StoredRoomKeyBundleData, TrackedUser,
1363 },
1364 },
1365 };
1366
1367 #[derive(Clone, Debug)]
1370 struct PersistentMemoryStore(Arc<MemoryStore>);
1371
1372 impl PersistentMemoryStore {
1373 fn new() -> Self {
1374 Self(Arc::new(MemoryStore::new()))
1375 }
1376
1377 fn get_static_account(&self) -> Option<StaticAccountData> {
1378 self.0.get_static_account()
1379 }
1380 }
1381
1382 async fn get_store(
1387 name: &str,
1388 _passphrase: Option<&str>,
1389 clear_data: bool,
1390 ) -> PersistentMemoryStore {
1391 static STORES: OnceLock<Mutex<HashMap<String, PersistentMemoryStore>>> = OnceLock::new();
1396 let stores = STORES.get_or_init(|| Mutex::new(HashMap::new()));
1397
1398 let mut stores = stores.lock().unwrap();
1399
1400 if clear_data {
1401 let new_store = PersistentMemoryStore::new();
1403 stores.insert(name.to_owned(), new_store.clone());
1404 new_store
1405 } else {
1406 stores.entry(name.to_owned()).or_insert_with(PersistentMemoryStore::new).clone()
1407 }
1408 }
1409
1410 #[cfg_attr(target_family = "wasm", async_trait(?Send))]
1412 #[cfg_attr(not(target_family = "wasm"), async_trait)]
1413 impl CryptoStore for PersistentMemoryStore {
1414 type Error = <MemoryStore as CryptoStore>::Error;
1415
1416 async fn close(&self) -> Result<(), Self::Error> {
1417 self.0.close().await
1418 }
1419
1420 async fn reopen(&self) -> Result<(), Self::Error> {
1421 self.0.reopen().await
1422 }
1423
1424 async fn load_account(&self) -> Result<Option<Account>, Self::Error> {
1425 self.0.load_account().await
1426 }
1427
1428 async fn load_identity(&self) -> Result<Option<PrivateCrossSigningIdentity>, Self::Error> {
1429 self.0.load_identity().await
1430 }
1431
1432 async fn save_changes(&self, changes: Changes) -> Result<(), Self::Error> {
1433 self.0.save_changes(changes).await
1434 }
1435
1436 async fn save_pending_changes(&self, changes: PendingChanges) -> Result<(), Self::Error> {
1437 self.0.save_pending_changes(changes).await
1438 }
1439
1440 async fn save_inbound_group_sessions(
1441 &self,
1442 sessions: Vec<InboundGroupSession>,
1443 backed_up_to_version: Option<&str>,
1444 ) -> Result<(), Self::Error> {
1445 self.0.save_inbound_group_sessions(sessions, backed_up_to_version).await
1446 }
1447
1448 async fn get_sessions(
1449 &self,
1450 sender_key: &str,
1451 ) -> Result<Option<Vec<Session>>, Self::Error> {
1452 self.0.get_sessions(sender_key).await
1453 }
1454
1455 async fn get_inbound_group_session(
1456 &self,
1457 room_id: &RoomId,
1458 session_id: &str,
1459 ) -> Result<Option<InboundGroupSession>, Self::Error> {
1460 self.0.get_inbound_group_session(room_id, session_id).await
1461 }
1462
1463 async fn get_withheld_info(
1464 &self,
1465 room_id: &RoomId,
1466 session_id: &str,
1467 ) -> Result<Option<RoomKeyWithheldEntry>, Self::Error> {
1468 self.0.get_withheld_info(room_id, session_id).await
1469 }
1470
1471 async fn get_withheld_sessions_by_room_id(
1472 &self,
1473 room_id: &RoomId,
1474 ) -> Result<Vec<RoomKeyWithheldEntry>, Self::Error> {
1475 self.0.get_withheld_sessions_by_room_id(room_id).await
1476 }
1477
1478 async fn get_inbound_group_sessions(
1479 &self,
1480 ) -> Result<Vec<InboundGroupSession>, Self::Error> {
1481 self.0.get_inbound_group_sessions().await
1482 }
1483
1484 async fn inbound_group_session_counts(
1485 &self,
1486 backup_version: Option<&str>,
1487 ) -> Result<RoomKeyCounts, Self::Error> {
1488 self.0.inbound_group_session_counts(backup_version).await
1489 }
1490
1491 async fn get_inbound_group_sessions_by_room_id(
1492 &self,
1493 room_id: &RoomId,
1494 ) -> Result<Vec<InboundGroupSession>, Self::Error> {
1495 self.0.get_inbound_group_sessions_by_room_id(room_id).await
1496 }
1497
1498 async fn get_inbound_group_sessions_for_device_batch(
1499 &self,
1500 sender_key: Curve25519PublicKey,
1501 sender_data_type: SenderDataType,
1502 after_session_id: Option<String>,
1503 limit: usize,
1504 ) -> Result<Vec<InboundGroupSession>, Self::Error> {
1505 self.0
1506 .get_inbound_group_sessions_for_device_batch(
1507 sender_key,
1508 sender_data_type,
1509 after_session_id,
1510 limit,
1511 )
1512 .await
1513 }
1514
1515 async fn inbound_group_sessions_for_backup(
1516 &self,
1517 backup_version: &str,
1518 limit: usize,
1519 ) -> Result<Vec<InboundGroupSession>, Self::Error> {
1520 self.0.inbound_group_sessions_for_backup(backup_version, limit).await
1521 }
1522
1523 async fn mark_inbound_group_sessions_as_backed_up(
1524 &self,
1525 backup_version: &str,
1526 room_and_session_ids: &[(&RoomId, &str)],
1527 ) -> Result<(), Self::Error> {
1528 self.0
1529 .mark_inbound_group_sessions_as_backed_up(backup_version, room_and_session_ids)
1530 .await
1531 }
1532
1533 async fn reset_backup_state(&self) -> Result<(), Self::Error> {
1534 self.0.reset_backup_state().await
1535 }
1536
1537 async fn load_backup_keys(&self) -> Result<BackupKeys, Self::Error> {
1538 self.0.load_backup_keys().await
1539 }
1540
1541 async fn load_dehydrated_device_pickle_key(
1542 &self,
1543 ) -> Result<Option<DehydratedDeviceKey>, Self::Error> {
1544 self.0.load_dehydrated_device_pickle_key().await
1545 }
1546
1547 async fn delete_dehydrated_device_pickle_key(&self) -> Result<(), Self::Error> {
1548 self.0.delete_dehydrated_device_pickle_key().await
1549 }
1550
1551 async fn get_outbound_group_session(
1552 &self,
1553 room_id: &RoomId,
1554 ) -> Result<Option<OutboundGroupSession>, Self::Error> {
1555 self.0.get_outbound_group_session(room_id).await
1556 }
1557
1558 async fn load_tracked_users(&self) -> Result<Vec<TrackedUser>, Self::Error> {
1559 self.0.load_tracked_users().await
1560 }
1561
1562 async fn save_tracked_users(&self, users: &[(&UserId, bool)]) -> Result<(), Self::Error> {
1563 self.0.save_tracked_users(users).await
1564 }
1565
1566 async fn get_device(
1567 &self,
1568 user_id: &UserId,
1569 device_id: &DeviceId,
1570 ) -> Result<Option<DeviceData>, Self::Error> {
1571 self.0.get_device(user_id, device_id).await
1572 }
1573
1574 async fn get_user_devices(
1575 &self,
1576 user_id: &UserId,
1577 ) -> Result<HashMap<OwnedDeviceId, DeviceData>, Self::Error> {
1578 self.0.get_user_devices(user_id).await
1579 }
1580
1581 async fn get_own_device(&self) -> Result<DeviceData, Self::Error> {
1582 self.0.get_own_device().await
1583 }
1584
1585 async fn get_user_identity(
1586 &self,
1587 user_id: &UserId,
1588 ) -> Result<Option<UserIdentityData>, Self::Error> {
1589 self.0.get_user_identity(user_id).await
1590 }
1591
1592 async fn is_message_known(
1593 &self,
1594 message_hash: &OlmMessageHash,
1595 ) -> Result<bool, Self::Error> {
1596 self.0.is_message_known(message_hash).await
1597 }
1598
1599 async fn get_outgoing_secret_requests(
1600 &self,
1601 request_id: &TransactionId,
1602 ) -> Result<Option<GossipRequest>, Self::Error> {
1603 self.0.get_outgoing_secret_requests(request_id).await
1604 }
1605
1606 async fn get_secret_request_by_info(
1607 &self,
1608 secret_info: &SecretInfo,
1609 ) -> Result<Option<GossipRequest>, Self::Error> {
1610 self.0.get_secret_request_by_info(secret_info).await
1611 }
1612
1613 async fn get_unsent_secret_requests(&self) -> Result<Vec<GossipRequest>, Self::Error> {
1614 self.0.get_unsent_secret_requests().await
1615 }
1616
1617 async fn delete_outgoing_secret_requests(
1618 &self,
1619 request_id: &TransactionId,
1620 ) -> Result<(), Self::Error> {
1621 self.0.delete_outgoing_secret_requests(request_id).await
1622 }
1623
1624 async fn get_secrets_from_inbox(
1625 &self,
1626 secret_name: &SecretName,
1627 ) -> Result<Vec<Zeroizing<String>>, Self::Error> {
1628 self.0.get_secrets_from_inbox(secret_name).await
1629 }
1630
1631 async fn delete_secrets_from_inbox(
1632 &self,
1633 secret_name: &SecretName,
1634 ) -> Result<(), Self::Error> {
1635 self.0.delete_secrets_from_inbox(secret_name).await
1636 }
1637
1638 async fn get_room_settings(
1639 &self,
1640 room_id: &RoomId,
1641 ) -> Result<Option<RoomSettings>, Self::Error> {
1642 self.0.get_room_settings(room_id).await
1643 }
1644
1645 async fn get_received_room_key_bundle_data(
1646 &self,
1647 room_id: &RoomId,
1648 user_id: &UserId,
1649 ) -> crate::store::Result<Option<StoredRoomKeyBundleData>, Self::Error> {
1650 self.0.get_received_room_key_bundle_data(room_id, user_id).await
1651 }
1652
1653 async fn has_downloaded_all_room_keys(
1654 &self,
1655 room_id: &RoomId,
1656 ) -> Result<bool, Self::Error> {
1657 self.0.has_downloaded_all_room_keys(room_id).await
1658 }
1659
1660 async fn get_pending_key_bundle_details_for_room(
1661 &self,
1662 room_id: &RoomId,
1663 ) -> Result<Option<RoomPendingKeyBundleDetails>, Self::Error> {
1664 self.0.get_pending_key_bundle_details_for_room(room_id).await
1665 }
1666
1667 async fn get_all_rooms_pending_key_bundles(
1668 &self,
1669 ) -> Result<Vec<RoomPendingKeyBundleDetails>, Self::Error> {
1670 self.0.get_all_rooms_pending_key_bundles().await
1671 }
1672
1673 async fn get_custom_value(&self, key: &str) -> Result<Option<Vec<u8>>, Self::Error> {
1674 self.0.get_custom_value(key).await
1675 }
1676
1677 async fn set_custom_value(&self, key: &str, value: Vec<u8>) -> Result<(), Self::Error> {
1678 self.0.set_custom_value(key, value).await
1679 }
1680
1681 async fn remove_custom_value(&self, key: &str) -> Result<(), Self::Error> {
1682 self.0.remove_custom_value(key).await
1683 }
1684
1685 async fn try_take_leased_lock(
1686 &self,
1687 lease_duration_ms: u32,
1688 key: &str,
1689 holder: &str,
1690 ) -> Result<Option<CrossProcessLockGeneration>, Self::Error> {
1691 self.0.try_take_leased_lock(lease_duration_ms, key, holder).await
1692 }
1693
1694 async fn next_batch_token(&self) -> Result<Option<String>, Self::Error> {
1695 self.0.next_batch_token().await
1696 }
1697
1698 async fn get_size(&self) -> Result<Option<usize>, Self::Error> {
1699 self.0.get_size().await
1700 }
1701 }
1702
1703 cryptostore_integration_tests!();
1704 cryptostore_integration_tests_time!();
1705}