faucet_cli/
auth_catalog.rs1use std::collections::HashMap;
10
11use faucet_core::SharedAuthProvider;
12use serde_json::Value;
13
14use crate::error::{CliError, CliResult};
15
16pub type AuthCatalog = HashMap<String, SharedAuthProvider>;
20
21pub fn build_auth_catalog(specs: Option<&HashMap<String, Value>>) -> CliResult<AuthCatalog> {
23 let mut catalog = AuthCatalog::new();
24 let Some(specs) = specs else {
25 return Ok(catalog);
26 };
27 for (name, spec) in specs {
28 let provider =
29 faucet_auth::build_provider(spec).map_err(|e| CliError::AuthProviderBuild {
30 name: name.clone(),
31 message: e.to_string(),
32 })?;
33 catalog.insert(name.clone(), provider);
34 }
35 Ok(catalog)
36}
37
38pub fn auth_ref(config: &Value) -> Option<String> {
41 config
42 .get("auth")
43 .and_then(|a| a.get("ref"))
44 .and_then(|r| r.as_str())
45 .map(String::from)
46}
47
48pub fn resolve(catalog: &AuthCatalog, name: &str) -> CliResult<SharedAuthProvider> {
50 catalog
51 .get(name)
52 .cloned()
53 .ok_or_else(|| CliError::UnknownAuthProvider {
54 name: name.to_string(),
55 known: {
56 let mut k: Vec<String> = catalog.keys().cloned().collect();
57 k.sort();
58 k
59 },
60 })
61}
62
63#[cfg(test)]
64mod tests {
65 use super::*;
66
67 #[test]
68 fn empty_block_yields_empty_catalog() {
69 assert!(build_auth_catalog(None).unwrap().is_empty());
70 }
71
72 #[test]
73 fn builds_static_provider_and_resolves() {
74 let mut specs = HashMap::new();
75 specs.insert(
76 "tok".to_string(),
77 serde_json::json!({"type": "static", "config": {"token": "abc"}}),
78 );
79 let catalog = build_auth_catalog(Some(&specs)).unwrap();
80 assert!(resolve(&catalog, "tok").is_ok());
81 let err = resolve(&catalog, "missing").unwrap_err();
82 assert!(matches!(err, CliError::UnknownAuthProvider { .. }));
83 }
84
85 #[test]
86 fn bad_spec_errors_with_name() {
87 let mut specs = HashMap::new();
88 specs.insert("bad".to_string(), serde_json::json!({"type": "nope"}));
89 let err = build_auth_catalog(Some(&specs)).unwrap_err();
90 assert!(matches!(err, CliError::AuthProviderBuild { name, .. } if name == "bad"));
91 }
92
93 #[test]
94 fn auth_ref_extracts_reference() {
95 assert_eq!(
96 auth_ref(&serde_json::json!({"auth": {"ref": "sf"}})),
97 Some("sf".to_string())
98 );
99 assert_eq!(
100 auth_ref(&serde_json::json!({"auth": {"type": "bearer", "config": {"token": "x"}}})),
101 None
102 );
103 assert_eq!(auth_ref(&serde_json::json!({})), None);
104 }
105}