sos_backend/
access_point.rs

1use crate::{BackendTarget, Error, Result};
2use async_trait::async_trait;
3use sos_core::{
4    crypto::{AccessKey, AeadPack, PrivateKey},
5    events::{ReadEvent, WriteEvent},
6    SecretId, VaultCommit, VaultFlags, VaultId,
7};
8use sos_database::VaultDatabaseWriter;
9use sos_filesystem::VaultFileWriter;
10use sos_vault::{
11    secret::{Secret, SecretMeta, SecretRow},
12    AccessPoint, SecretAccess, Summary, Vault, VaultMeta,
13};
14use std::path::Path;
15
16/// Backend storage access point.
17pub struct BackendAccessPoint(AccessPoint<Error>);
18
19impl BackendAccessPoint {
20    /// Wrap an access point.
21    pub fn wrap(access_point: AccessPoint<Error>) -> Self {
22        Self(access_point)
23    }
24
25    /// In-memory access point from a vault.
26    pub fn from_vault(vault: Vault) -> Self {
27        Self(AccessPoint::<Error>::new(vault))
28    }
29
30    /// Access point for a folder in a backend target.
31    ///
32    /// Changes are mirrored to the backend target.
33    pub async fn new(target: BackendTarget, vault: Vault) -> Self {
34        match target {
35            BackendTarget::FileSystem(paths) => {
36                let path = paths.vault_path(vault.id());
37                Self::from_path(path, vault)
38            }
39            BackendTarget::Database(_, client) => {
40                let mirror =
41                    VaultDatabaseWriter::<Error>::new(client, *vault.id());
42                Self(AccessPoint::<Error>::new_mirror(
43                    vault,
44                    Box::new(mirror),
45                ))
46            }
47        }
48    }
49
50    /// Access point that mirrors to disc.
51    pub fn from_path<P: AsRef<Path>>(path: P, vault: Vault) -> Self {
52        let mirror = VaultFileWriter::<Error>::new(path);
53        Self(AccessPoint::<Error>::new_mirror(vault, Box::new(mirror)))
54    }
55}
56
57#[async_trait]
58impl SecretAccess for BackendAccessPoint {
59    type Error = Error;
60
61    fn is_mirror(&self) -> bool {
62        self.0.is_mirror()
63    }
64
65    fn vault(&self) -> &Vault {
66        self.0.vault()
67    }
68
69    async fn replace_vault(
70        &mut self,
71        vault: Vault,
72        mirror_changes: bool,
73    ) -> Result<()> {
74        Ok(self.0.replace_vault(vault, mirror_changes).await?)
75    }
76
77    async fn reload_vault<P: AsRef<Path> + Send>(
78        &mut self,
79        path: P,
80    ) -> Result<()> {
81        Ok(self.0.reload_vault(path).await?)
82    }
83
84    fn summary(&self) -> &Summary {
85        self.0.summary()
86    }
87
88    fn id(&self) -> &VaultId {
89        self.0.id()
90    }
91
92    fn name(&self) -> &str {
93        self.0.name()
94    }
95
96    async fn set_vault_name(&mut self, name: String) -> Result<WriteEvent> {
97        Ok(self.0.set_vault_name(name).await?)
98    }
99
100    async fn set_vault_flags(
101        &mut self,
102        flags: VaultFlags,
103    ) -> Result<WriteEvent> {
104        Ok(self.0.set_vault_flags(flags).await?)
105    }
106
107    async fn vault_meta(&self) -> Result<VaultMeta> {
108        Ok(self.0.vault_meta().await?)
109    }
110
111    /// Set the meta data for the vault.
112    async fn set_vault_meta(
113        &mut self,
114        meta_data: &VaultMeta,
115    ) -> Result<WriteEvent> {
116        Ok(self.0.set_vault_meta(meta_data).await?)
117    }
118
119    async fn decrypt_meta(&self, meta_aead: &AeadPack) -> Result<VaultMeta> {
120        Ok(self.0.decrypt_meta(meta_aead).await?)
121    }
122
123    async fn decrypt_secret(
124        &self,
125        vault_commit: &VaultCommit,
126        private_key: Option<&PrivateKey>,
127    ) -> Result<(SecretMeta, Secret)> {
128        Ok(self.0.decrypt_secret(vault_commit, private_key).await?)
129    }
130
131    async fn create_secret(
132        &mut self,
133        secret_data: &SecretRow,
134    ) -> Result<WriteEvent> {
135        Ok(self.0.create_secret(secret_data).await?)
136    }
137
138    async fn raw_secret(
139        &self,
140        id: &SecretId,
141    ) -> Result<Option<(VaultCommit, ReadEvent)>> {
142        Ok(self.0.raw_secret(id).await?)
143    }
144
145    async fn read_secret(
146        &self,
147        id: &SecretId,
148    ) -> Result<Option<(SecretMeta, Secret, ReadEvent)>> {
149        Ok(self.0.read_secret(id).await?)
150    }
151
152    async fn update_secret(
153        &mut self,
154        id: &SecretId,
155        meta: SecretMeta,
156        secret: Secret,
157    ) -> Result<Option<WriteEvent>> {
158        Ok(self.0.update_secret(id, meta, secret).await?)
159    }
160
161    async fn delete_secret(
162        &mut self,
163        id: &SecretId,
164    ) -> Result<Option<WriteEvent>> {
165        Ok(self.0.delete_secret(id).await?)
166    }
167
168    async fn verify(&self, key: &AccessKey) -> Result<()> {
169        Ok(self.0.verify(key).await?)
170    }
171
172    async fn unlock(&mut self, key: &AccessKey) -> Result<VaultMeta> {
173        Ok(self.0.unlock(key).await?)
174    }
175
176    fn lock(&mut self) {
177        self.0.lock();
178    }
179}
180
181impl From<BackendAccessPoint> for Vault {
182    fn from(value: BackendAccessPoint) -> Self {
183        value.0.into()
184    }
185}