sos_backend/
vault_writer.rs1use crate::{BackendTarget, Error, Result};
2use async_trait::async_trait;
3use sos_core::{
4 commit::CommitHash,
5 crypto::AeadPack,
6 events::{ReadEvent, WriteEvent},
7 SecretId, VaultCommit, VaultEntry, VaultFlags, VaultId,
8};
9use sos_database::VaultDatabaseWriter;
10use sos_filesystem::VaultFileWriter;
11use sos_vault::{EncryptedEntry, Summary, Vault};
12use std::borrow::Cow;
13
14pub enum VaultWriter {
16 Database(VaultDatabaseWriter<Error>),
18 FileSystem(VaultFileWriter<Error>),
20}
21
22impl VaultWriter {
23 pub fn new(target: BackendTarget, folder_id: &VaultId) -> Self {
25 match target {
26 BackendTarget::FileSystem(paths) => {
27 let path = paths.vault_path(folder_id);
28 Self::FileSystem(VaultFileWriter::<Error>::new(path))
29 }
30 BackendTarget::Database(_, client) => Self::Database(
31 VaultDatabaseWriter::<Error>::new(client, *folder_id),
32 ),
33 }
34 }
35}
36
37#[async_trait]
38impl EncryptedEntry for VaultWriter {
39 type Error = Error;
40
41 async fn summary(&self) -> Result<Summary> {
42 Ok(match self {
43 Self::Database(inner) => inner.summary().await?,
44 Self::FileSystem(inner) => inner.summary().await?,
45 })
46 }
47
48 async fn vault_name(&self) -> Result<Cow<'_, str>> {
49 Ok(match self {
50 Self::Database(inner) => inner.vault_name().await?,
51 Self::FileSystem(inner) => inner.vault_name().await?,
52 })
53 }
54
55 async fn set_vault_name(&mut self, name: String) -> Result<WriteEvent> {
56 Ok(match self {
57 Self::Database(inner) => inner.set_vault_name(name).await?,
58 Self::FileSystem(inner) => inner.set_vault_name(name).await?,
59 })
60 }
61
62 async fn set_vault_flags(
63 &mut self,
64 flags: VaultFlags,
65 ) -> Result<WriteEvent> {
66 Ok(match self {
67 Self::Database(inner) => inner.set_vault_flags(flags).await?,
68 Self::FileSystem(inner) => inner.set_vault_flags(flags).await?,
69 })
70 }
71
72 async fn set_vault_meta(&mut self, meta: AeadPack) -> Result<WriteEvent> {
73 Ok(match self {
74 Self::Database(inner) => inner.set_vault_meta(meta).await?,
75 Self::FileSystem(inner) => inner.set_vault_meta(meta).await?,
76 })
77 }
78
79 async fn create_secret(
80 &mut self,
81 commit: CommitHash,
82 secret: VaultEntry,
83 ) -> Result<WriteEvent> {
84 self.insert_secret(SecretId::new_v4(), commit, secret).await
85 }
86
87 async fn insert_secret(
88 &mut self,
89 secret_id: SecretId,
90 commit: CommitHash,
91 secret: VaultEntry,
92 ) -> Result<WriteEvent> {
93 Ok(match self {
94 Self::Database(inner) => {
95 inner.insert_secret(secret_id, commit, secret).await?
96 }
97 Self::FileSystem(inner) => {
98 inner.insert_secret(secret_id, commit, secret).await?
99 }
100 })
101 }
102
103 async fn read_secret<'a>(
104 &'a self,
105 secret_id: &SecretId,
106 ) -> Result<Option<(Cow<'a, VaultCommit>, ReadEvent)>> {
107 Ok(match self {
108 Self::Database(inner) => inner.read_secret(secret_id).await?,
109 Self::FileSystem(inner) => inner.read_secret(secret_id).await?,
110 })
111 }
112
113 async fn update_secret(
114 &mut self,
115 secret_id: &SecretId,
116 commit: CommitHash,
117 secret: VaultEntry,
118 ) -> Result<Option<WriteEvent>> {
119 Ok(match self {
120 Self::Database(inner) => {
121 inner.update_secret(secret_id, commit, secret).await?
122 }
123 Self::FileSystem(inner) => {
124 inner.update_secret(secret_id, commit, secret).await?
125 }
126 })
127 }
128
129 async fn delete_secret(
130 &mut self,
131 secret_id: &SecretId,
132 ) -> Result<Option<WriteEvent>> {
133 Ok(match self {
134 Self::Database(inner) => inner.delete_secret(secret_id).await?,
135 Self::FileSystem(inner) => inner.delete_secret(secret_id).await?,
136 })
137 }
138
139 async fn replace_vault(&mut self, vault: &Vault) -> Result<()> {
140 Ok(match self {
141 Self::Database(inner) => inner.replace_vault(vault).await?,
142 Self::FileSystem(inner) => inner.replace_vault(vault).await?,
143 })
144 }
145}