1use crate::{Secret, SecretManagerError, SecretManagerImpl, SetSecretOutcome};
12use serde::{Deserialize, Serialize};
13use std::{collections::HashMap, convert::Infallible, fmt::Debug, sync::Arc};
14use thiserror::Error;
15use tokio::sync::RwLock;
16
17#[derive(Clone, Default, Deserialize, Serialize)]
19#[serde(default)]
20pub struct MemorySecretManagerConfig {
21 pub secrets: HashMap<String, String>,
23 pub default: Option<String>,
25}
26
27#[derive(Debug, Error)]
30pub enum MemorySecretManagerConfigError {
31 #[error("failed to parse DOCBOX_SECRET_MANAGER_MEMORY_SECRETS")]
33 ParseSecrets,
34}
35
36impl MemorySecretManagerConfig {
37 pub fn from_env() -> Result<Self, MemorySecretManagerConfigError> {
39 let default = std::env::var("DOCBOX_SECRET_MANAGER_MEMORY_DEFAULT").ok();
40 let secrets = match std::env::var("DOCBOX_SECRET_MANAGER_MEMORY_SECRETS") {
41 Ok(secrets) => serde_json::from_str(&secrets).map_err(|error| {
42 tracing::error!(?error, "failed to parse memory secrets");
43 MemorySecretManagerConfigError::ParseSecrets
44 })?,
45 Err(_) => Default::default(),
46 };
47
48 Ok(Self { default, secrets })
49 }
50}
51
52impl Debug for MemorySecretManagerConfig {
53 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
54 f.debug_struct("MemorySecretManagerConfig").finish()
55 }
56}
57
58#[derive(Default, Clone)]
60pub struct MemorySecretManager {
61 inner: Arc<RwLock<MemorySecretManagerInner>>,
62}
63
64#[derive(Default)]
65struct MemorySecretManagerInner {
66 data: HashMap<String, Secret>,
67 default: Option<Secret>,
68}
69
70impl MemorySecretManager {
71 pub fn new(data: HashMap<String, Secret>, default: Option<Secret>) -> Self {
73 Self {
74 inner: Arc::new(RwLock::new(MemorySecretManagerInner { data, default })),
75 }
76 }
77}
78
79pub type MemorySecretError = Infallible;
81
82impl SecretManagerImpl for MemorySecretManager {
83 async fn get_secret(&self, name: &str) -> Result<Option<super::Secret>, SecretManagerError> {
84 let inner = &*self.inner.read().await;
85
86 if let Some(value) = inner.data.get(name) {
87 return Ok(Some(value.clone()));
88 }
89
90 if let Some(value) = inner.default.as_ref() {
91 return Ok(Some(value.clone()));
92 }
93
94 Ok(None)
95 }
96
97 async fn has_secret(&self, name: &str) -> Result<bool, SecretManagerError> {
98 let inner = &*self.inner.read().await;
99 Ok(inner.data.contains_key(name))
100 }
101
102 async fn set_secret(
103 &self,
104 name: &str,
105 value: &str,
106 ) -> Result<SetSecretOutcome, SecretManagerError> {
107 let previous = self
108 .inner
109 .write()
110 .await
111 .data
112 .insert(name.to_string(), Secret::String(value.to_string()));
113 Ok(if previous.is_some() {
114 SetSecretOutcome::Updated
115 } else {
116 SetSecretOutcome::Created
117 })
118 }
119
120 async fn delete_secret(&self, name: &str, _force: bool) -> Result<(), SecretManagerError> {
121 self.inner.write().await.data.remove(name);
122 Ok(())
123 }
124}