1use async_trait::async_trait;
2use std::sync::Arc;
3
4use crate::crypto::Aead;
5use crate::storage::{StorageBackend, StorageEntry, StorageResult};
6
7pub struct Barrier<B: StorageBackend> {
10 inner: B,
11 aead: Arc<dyn Aead>,
12}
13
14impl<B: StorageBackend> Barrier<B> {
15 pub fn new(inner: B, aead: Arc<dyn Aead>) -> Self {
16 Self { inner, aead }
17 }
18}
19
20#[async_trait]
21impl<B: StorageBackend> StorageBackend for Barrier<B> {
22 async fn get(&self, path: &str) -> StorageResult<Option<StorageEntry>> {
23 let Some(entry) = self.inner.get(path).await? else {
24 return Ok(None);
25 };
26 let plaintext = self
27 .aead
28 .open(&entry.value)
29 .map_err(|e| crate::storage::StorageError::Backend(e.to_string()))?;
30 Ok(Some(StorageEntry {
31 value: plaintext,
32 expires_at: entry.expires_at,
33 }))
34 }
35
36 async fn put(&self, path: &str, entry: StorageEntry) -> StorageResult<()> {
37 let ciphertext = self
38 .aead
39 .seal(&entry.value)
40 .map_err(|e| crate::storage::StorageError::Backend(e.to_string()))?;
41 self.inner
42 .put(
43 path,
44 StorageEntry {
45 value: ciphertext,
46 expires_at: entry.expires_at,
47 },
48 )
49 .await
50 }
51
52 async fn delete(&self, path: &str) -> StorageResult<()> {
53 self.inner.delete(path).await
54 }
55
56 async fn list(&self, prefix: &str) -> StorageResult<Vec<String>> {
57 self.inner.list(prefix).await
58 }
59}