1use anyhow::Result;
2use serde::Deserialize;
3
4#[cfg(feature = "private")]
5use doppler_rs::{apis::client::Client, apis::Error as DopplerError};
6
7#[derive(Debug, Clone, Deserialize, PartialEq)]
8pub enum DeploymentType {
9 OSS,
10 Private,
11}
12
13impl std::str::FromStr for DeploymentType {
14 type Err = anyhow::Error;
15
16 fn from_str(s: &str) -> Result<Self> {
17 match s.to_lowercase().as_str() {
18 "oss" => Ok(DeploymentType::OSS),
19 "private" => Ok(DeploymentType::Private),
20 _ => Err(anyhow::anyhow!("Invalid deployment type: {}", s)),
21 }
22 }
23}
24
25#[derive(Debug, Clone, Deserialize)]
26pub struct Config {
27 pub port: u16,
28 pub base_url: String,
29 pub fips_mode: bool,
30 pub fips_validation: bool,
31 pub deployment_type: DeploymentType,
32 pub license_signing_key: String,
33}
34
35impl Default for Config {
36 fn default() -> Self {
37 Self {
38 port: 8080,
39 base_url: "http://localhost:8080".to_string(),
40 fips_mode: false,
41 fips_validation: false,
42 deployment_type: DeploymentType::OSS,
43 license_signing_key: "t6eLp6y0Ly8BZJIVv_wK71WyBtJ1zY2Pxz2M_0z5t8Q".to_string(),
44 }
45 }
46}
47
48impl Config {
49 pub fn from_env() -> Result<Self> {
50 dotenvy::dotenv().ok();
51
52 let deployment_type = std::env::var("NABLA_DEPLOYMENT")
53 .unwrap_or_else(|_| "oss".to_string())
54 .parse()?;
55
56 let license_signing_key = Self::get_license_signing_key(&deployment_type)?;
57
58 let config = Config {
59 port: std::env::var("PORT")
60 .unwrap_or_else(|_| "8080".to_string())
61 .parse()?,
62 base_url: std::env::var("BASE_URL")
63 .unwrap_or_else(|_| "http://localhost:8080".to_string()),
64 fips_mode: std::env::var("FIPS_MODE")
65 .unwrap_or_else(|_| "false".to_string())
66 .parse()
67 .unwrap_or(false),
68 fips_validation: std::env::var("FIPS_VALIDATION")
69 .unwrap_or_else(|_| "false".to_string())
70 .parse()
71 .unwrap_or(false),
72 deployment_type,
73 license_signing_key,
74 };
75
76 Ok(config)
77 }
78
79 fn get_license_signing_key(deployment_type: &DeploymentType) -> Result<String> {
80 match deployment_type {
81 DeploymentType::OSS => {
82 Ok("t6eLp6y0Ly8BZJIVv_wK71WyBtJ1zY2Pxz2M_0z5t8Q".to_string())
84 }
85 DeploymentType::Private => {
86 #[cfg(feature = "private")]
87 {
88 if let (Ok(project), Ok(config_name)) = (
90 std::env::var("DOPPLER_PROJECT"),
91 std::env::var("DOPPLER_CONFIG")
92 ) {
93 if let Ok(doppler_token) = std::env::var("DOPPLER_TOKEN") {
94 let client = Client::new(&doppler_token);
95 if let Ok(secret) = client.get_secret(&project, &config_name, "LICENSE_SIGNING_KEY") {
96 return Ok(secret.value);
97 }
98 }
99 }
100 }
101
102 std::env::var("LICENSE_SIGNING_KEY")
104 .map_err(|_| anyhow::anyhow!("LICENSE_SIGNING_KEY env missing for private deployment"))
105 }
106 }
107 }
108}