sync15/client/
collection_keys.rs
1use crate::error::Result;
6use crate::record_types::CryptoKeysRecord;
7use crate::{EncryptedPayload, KeyBundle, ServerTimestamp};
8use std::collections::HashMap;
9
10#[derive(Clone, Debug, PartialEq, Eq)]
11pub struct CollectionKeys {
12 pub timestamp: ServerTimestamp,
13 pub default: KeyBundle,
14 pub collections: HashMap<String, KeyBundle>,
15}
16
17impl CollectionKeys {
18 pub fn new_random() -> Result<CollectionKeys> {
19 let default = KeyBundle::new_random()?;
20 Ok(CollectionKeys {
21 timestamp: ServerTimestamp(0),
22 default,
23 collections: HashMap::new(),
24 })
25 }
26
27 pub fn from_encrypted_payload(
28 record: EncryptedPayload,
29 timestamp: ServerTimestamp,
30 root_key: &KeyBundle,
31 ) -> Result<CollectionKeys> {
32 let keys: CryptoKeysRecord = record.decrypt_into(root_key)?;
33 Ok(CollectionKeys {
34 timestamp,
35 default: KeyBundle::from_base64(&keys.default[0], &keys.default[1])?,
36 collections: keys
37 .collections
38 .into_iter()
39 .map(|kv| Ok((kv.0, KeyBundle::from_base64(&kv.1[0], &kv.1[1])?)))
40 .collect::<Result<HashMap<String, KeyBundle>>>()?,
41 })
42 }
43
44 pub fn to_encrypted_payload(&self, root_key: &KeyBundle) -> Result<EncryptedPayload> {
45 let record = CryptoKeysRecord {
46 id: "keys".into(),
47 collection: "crypto".into(),
48 default: self.default.to_b64_array(),
49 collections: self
50 .collections
51 .iter()
52 .map(|kv| (kv.0.clone(), kv.1.to_b64_array()))
53 .collect(),
54 };
55 EncryptedPayload::from_cleartext_payload(root_key, &record)
56 }
57
58 pub fn key_for_collection<'a>(&'a self, collection: &str) -> &'a KeyBundle {
59 self.collections.get(collection).unwrap_or(&self.default)
60 }
61}