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