1use crate::{Secret, SecretManager};
12use anyhow::Context;
13use serde::{Deserialize, Serialize};
14use std::{collections::HashMap, fmt::Debug};
15use tokio::sync::Mutex;
16
17#[derive(Clone, Deserialize, Serialize)]
18pub struct MemorySecretManagerConfig {
19 #[serde(default)]
21 pub secrets: HashMap<String, String>,
22 #[serde(default)]
24 pub default: Option<String>,
25}
26
27impl MemorySecretManagerConfig {
28 pub fn from_env() -> anyhow::Result<Self> {
29 let default = std::env::var("DOCBOX_SECRET_MANAGER_MEMORY_DEFAULT").ok();
30 let secrets = match std::env::var("DOCBOX_SECRET_MANAGER_MEMORY_SECRETS") {
31 Ok(secrets) => serde_json::from_str(&secrets)
32 .context("failed to parse DOCBOX_SECRET_MANAGER_MEMORY_SECRETS")?,
33 Err(_) => Default::default(),
34 };
35
36 Ok(Self { default, secrets })
37 }
38}
39
40impl Debug for MemorySecretManagerConfig {
41 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
42 f.debug_struct("MemorySecretManagerConfig").finish()
43 }
44}
45
46#[derive(Default)]
48pub struct MemorySecretManager {
49 data: Mutex<HashMap<String, Secret>>,
50 default: Option<Secret>,
51}
52
53impl MemorySecretManager {
54 pub fn new(data: HashMap<String, Secret>, default: Option<Secret>) -> Self {
55 Self {
56 data: Mutex::new(data),
57 default,
58 }
59 }
60}
61
62impl SecretManager for MemorySecretManager {
63 async fn get_secret(&self, name: &str) -> anyhow::Result<Option<super::Secret>> {
64 if let Some(value) = self.data.lock().await.get(name) {
65 return Ok(Some(value.clone()));
66 }
67
68 if let Some(value) = self.default.as_ref() {
69 return Ok(Some(value.clone()));
70 }
71
72 Ok(None)
73 }
74
75 async fn set_secret(&self, name: &str, value: &str) -> anyhow::Result<()> {
76 self.data
77 .lock()
78 .await
79 .insert(name.to_string(), Secret::String(value.to_string()));
80 Ok(())
81 }
82
83 async fn delete_secret(&self, name: &str) -> anyhow::Result<()> {
84 self.data.lock().await.remove(name);
85 Ok(())
86 }
87}