stackless_cloud/
credential.rs1use std::collections::BTreeMap;
7use std::path::Path;
8
9#[derive(Debug, Clone)]
12pub struct CredentialMissing {
13 pub env_var: String,
14 pub key_file: String,
15}
16
17pub fn resolve(
22 env_var: &str,
23 key_file_name: &str,
24 definition_dir: &Path,
25 secrets: &BTreeMap<String, String>,
26) -> Result<String, CredentialMissing> {
27 if let Ok(value) = std::env::var(env_var) {
28 let value = value.trim().to_owned();
29 if !value.is_empty() {
30 return Ok(value);
31 }
32 }
33 if let Some(value) = secrets.get(env_var) {
34 let value = value.trim().to_owned();
35 if !value.is_empty() {
36 return Ok(value);
37 }
38 }
39 let key_file = definition_dir.join(key_file_name);
40 if let Ok(contents) = std::fs::read_to_string(&key_file) {
41 let value = contents.trim().to_owned();
42 if !value.is_empty() {
43 return Ok(value);
44 }
45 }
46 Err(CredentialMissing {
47 env_var: env_var.to_owned(),
48 key_file: key_file.display().to_string(),
49 })
50}
51
52#[cfg(test)]
53mod tests {
54 use super::*;
55
56 const ENV: &str = "STACKLESS_CLOUD_TEST_KEY";
57 const FILE: &str = ".cloud-test-key";
58
59 fn secret(key: &str, value: &str) -> BTreeMap<String, String> {
60 let mut map = BTreeMap::new();
61 map.insert(key.to_owned(), value.to_owned());
62 map
63 }
64
65 #[test]
66 fn resolves_from_secret() {
67 let dir = tempfile::tempdir().unwrap();
68 let key = resolve(ENV, FILE, dir.path(), &secret(ENV, "from_secrets")).unwrap();
69 assert_eq!(key, "from_secrets");
70 }
71
72 #[test]
73 fn key_file_is_a_fallback_when_secret_absent() {
74 let dir = tempfile::tempdir().unwrap();
75 std::fs::write(dir.path().join(FILE), "from_file\n").unwrap();
76 let key = resolve(ENV, FILE, dir.path(), &BTreeMap::new()).unwrap();
77 assert_eq!(key, "from_file");
78 }
79
80 #[test]
81 fn missing_everywhere_names_both_sources() {
82 let dir = tempfile::tempdir().unwrap();
83 let err = resolve(ENV, FILE, dir.path(), &BTreeMap::new()).unwrap_err();
84 assert_eq!(err.env_var, ENV);
85 assert!(err.key_file.ends_with(FILE));
86 }
87}