auths_cli/factories/
mod.rs1pub mod storage;
2
3use std::io::IsTerminal;
4use std::sync::Arc;
5
6use anyhow::Result;
7
8use auths_sdk::core_config::{EnvironmentConfig, load_config};
9use auths_sdk::keychain::{get_passphrase_cache, parse_duration_str};
10use auths_sdk::paths::auths_home;
11use auths_sdk::ports::agent::AgentSigningPort;
12use auths_sdk::signing::{KeychainPassphraseProvider, PassphraseProvider};
13use auths_telemetry::TelemetryShutdown;
14use auths_telemetry::config::{build_sinks_from_config, load_audit_config};
15use auths_telemetry::sinks::composite::CompositeSink;
16
17use crate::adapters::config_store::FileConfigStore;
18use crate::cli::AuthsCli;
19use crate::config::{CliConfig, OutputFormat};
20use crate::core::provider::{CliPassphraseProvider, PrefilledPassphraseProvider};
21
22pub fn build_config(cli: &AuthsCli) -> Result<CliConfig> {
39 let output_format = if cli.json {
40 OutputFormat::Json
41 } else {
42 OutputFormat::Text
43 };
44
45 let env_config = EnvironmentConfig::from_env();
46
47 let passphrase_provider: Arc<dyn PassphraseProvider + Send + Sync> =
48 if let Some(passphrase) = env_config.keychain.passphrase.clone() {
49 Arc::new(PrefilledPassphraseProvider::new(zeroize::Zeroizing::new(
50 passphrase,
51 )))
52 } else {
53 let config = load_config(&FileConfigStore);
54 let cache = get_passphrase_cache(config.passphrase.biometric);
55 let ttl_secs = config
56 .passphrase
57 .duration
58 .as_deref()
59 .and_then(parse_duration_str);
60 let inner = Arc::new(CliPassphraseProvider::new());
61 Arc::new(KeychainPassphraseProvider::new(
62 inner,
63 cache,
64 "default".to_string(),
65 config.passphrase.cache,
66 ttl_secs,
67 ))
68 };
69
70 let is_interactive = std::io::stdout().is_terminal();
71
72 let repo_path = cli.repo.clone().or_else(|| {
75 std::env::var("AUTHS_REPO")
76 .ok()
77 .filter(|s| !s.is_empty())
78 .map(std::path::PathBuf::from)
79 });
80
81 Ok(CliConfig {
82 repo_path,
83 output_format,
84 is_interactive,
85 passphrase_provider,
86 env_config,
87 })
88}
89
90pub fn init_audit_sinks() -> Option<TelemetryShutdown> {
100 let audit_path = match auths_home() {
101 Ok(h) => h.join("audit.toml"),
102 Err(_) => return None,
103 };
104 let config = load_audit_config(&audit_path);
105 #[allow(clippy::disallowed_methods)] let sinks = build_sinks_from_config(&config, |name| std::env::var(name).ok());
107 if sinks.is_empty() {
108 return None;
109 }
110 let composite = Arc::new(CompositeSink::new(sinks));
111 Some(auths_telemetry::init_telemetry_with_sink(composite))
112}
113
114pub fn build_agent_provider() -> Arc<dyn AgentSigningPort + Send + Sync> {
124 #[cfg(unix)]
125 {
126 Arc::new(crate::adapters::agent::CliAgentAdapter)
127 }
128 #[cfg(not(unix))]
129 {
130 Arc::new(auths_sdk::ports::agent::NoopAgentProvider)
131 }
132}