use crate::rate_limit::RateLimitConfig;
use serde::{Deserialize, Serialize};
use std::collections::HashMap;
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct SecretConfig {
pub default_provider: String,
pub providers: HashMap<String, SecretProviderConfig>,
pub enable_masking: bool,
pub timeout_seconds: u64,
pub enable_caching: bool,
pub cache_ttl_seconds: u64,
#[serde(skip)]
pub rate_limit: RateLimitConfig,
}
impl Default for SecretConfig {
fn default() -> Self {
let mut providers = HashMap::new();
providers.insert(
"env".to_string(),
SecretProviderConfig::Environment { prefix: None },
);
providers.insert(
"file".to_string(),
SecretProviderConfig::File {
path: "~/.wrkflw/secrets".to_string(),
},
);
Self {
default_provider: "env".to_string(),
providers,
enable_masking: true,
timeout_seconds: 30,
enable_caching: true,
cache_ttl_seconds: 300, rate_limit: RateLimitConfig::default(),
}
}
}
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(tag = "type", rename_all = "snake_case")]
pub enum SecretProviderConfig {
Environment {
prefix: Option<String>,
},
File {
path: String,
},
}
impl SecretConfig {
pub fn from_file(path: &str) -> crate::SecretResult<Self> {
let content = std::fs::read_to_string(path)?;
if path.ends_with(".json") {
Ok(serde_json::from_str(&content)?)
} else if path.ends_with(".yml") || path.ends_with(".yaml") {
Ok(serde_yaml::from_str(&content)?)
} else {
Err(crate::SecretError::invalid_config(
"Unsupported config file format. Use .json, .yml, or .yaml",
))
}
}
pub fn to_file(&self, path: &str) -> crate::SecretResult<()> {
let content = if path.ends_with(".json") {
serde_json::to_string_pretty(self)?
} else if path.ends_with(".yml") || path.ends_with(".yaml") {
serde_yaml::to_string(self)?
} else {
return Err(crate::SecretError::invalid_config(
"Unsupported config file format. Use .json, .yml, or .yaml",
));
};
std::fs::write(path, content)?;
Ok(())
}
pub fn from_env() -> Self {
let mut config = Self::default();
if let Ok(provider) = std::env::var("WRKFLW_DEFAULT_SECRET_PROVIDER") {
config.default_provider = provider;
}
if let Ok(masking) = std::env::var("WRKFLW_SECRET_MASKING") {
config.enable_masking = masking.parse().unwrap_or(true);
}
if let Ok(timeout) = std::env::var("WRKFLW_SECRET_TIMEOUT") {
config.timeout_seconds = timeout.parse().unwrap_or(30);
}
config
}
}