lb_rs/service/
share.rs

1use crate::Lb;
2use crate::model::api::GetPublicKeyRequest;
3use crate::model::errors::{LbErr, LbResult};
4use crate::model::file::{File, ShareMode};
5use crate::model::file_metadata::Owner;
6use crate::model::tree_like::TreeLike;
7use libsecp256k1::PublicKey;
8use uuid::Uuid;
9
10impl Lb {
11    // todo: this can check whether the username is known already
12    #[instrument(level = "debug", skip(self))]
13    pub async fn share_file(&self, id: Uuid, username: &str, mode: ShareMode) -> LbResult<()> {
14        let account = self.get_account()?;
15        let username = username.to_lowercase();
16
17        let sharee = Owner(
18            self.client
19                .request(account, GetPublicKeyRequest { username: username.clone() })
20                .await
21                .map_err(LbErr::from)?
22                .key,
23        );
24
25        let mut tx = self.begin_tx().await;
26        let db = tx.db();
27
28        let mut tree = (&db.base_metadata)
29            .to_staged(&mut db.local_metadata)
30            .to_lazy();
31        db.pub_key_lookup.insert(sharee, username)?;
32
33        tree.add_share(id, sharee, mode, &self.keychain)?;
34
35        tx.end();
36
37        self.events.meta_changed();
38
39        Ok(())
40    }
41
42    /// returns pending shares -- files shared with us that we haven't accepted or rejected
43    /// this function just returns the actual files that were shared -- or the roots of shared
44    /// trees. For the full set of shares see [Self::get_pending_share_files]
45    #[instrument(level = "debug", skip(self))]
46    pub async fn get_pending_shares(&self) -> LbResult<Vec<File>> {
47        let tx = self.ro_tx().await;
48        let db = tx.db();
49
50        let mut tree = (&db.base_metadata).to_staged(&db.local_metadata).to_lazy();
51        let pending_roots = tree.pending_roots(&self.keychain)?.into_iter();
52
53        tree.decrypt_all(&self.keychain, pending_roots, &db.pub_key_lookup, false)
54    }
55
56    /// returns *all* the files associated with any pending shares (the share as well as it's
57    /// descendants).
58    #[instrument(level = "debug", skip(self))]
59    pub async fn get_pending_share_files(&self) -> LbResult<Vec<File>> {
60        let tx = self.ro_tx().await;
61        let db = tx.db();
62
63        let mut tree = (&db.base_metadata).to_staged(&db.local_metadata).to_lazy();
64        let pending_files = tree.non_deleted_pending_files(&self.keychain)?.into_iter();
65
66        tree.decrypt_all(&self.keychain, pending_files, &db.pub_key_lookup, false)
67    }
68
69    #[instrument(level = "debug", skip(self))]
70    async fn delete_share(
71        &self, id: &Uuid, maybe_encrypted_for: Option<PublicKey>,
72    ) -> LbResult<()> {
73        let mut tx = self.begin_tx().await;
74        let db = tx.db();
75
76        let mut tree = (&db.base_metadata)
77            .to_staged(&mut db.local_metadata)
78            .to_lazy();
79
80        tree.delete_share(id, maybe_encrypted_for, &self.keychain)?;
81
82        tx.end();
83        self.events.meta_changed();
84
85        Ok(())
86    }
87
88    #[instrument(level = "debug", skip(self))]
89    pub async fn known_usernames(&self) -> LbResult<Vec<String>> {
90        let db = self.ro_tx().await;
91        let db = db.db();
92
93        Ok(db.pub_key_lookup.get().values().cloned().collect())
94    }
95
96    #[instrument(level = "debug", skip(self))]
97    pub async fn reject_share(&self, id: &Uuid) -> Result<(), LbErr> {
98        let pk = self.keychain.get_pk()?;
99        self.delete_share(id, Some(pk)).await
100    }
101}