1use crate::network::{AirgapConfig, NetworkConfig};
2use crate::response::{ConfigEntry, ConfigResponse};
3
4pub fn execute(
5 command: Option<crate::ConfigCommands>,
6) -> Result<ConfigResponse, crate::errors::LitError> {
7 match command {
8 Some(crate::ConfigCommands::Show) | None => show_config(),
9 Some(crate::ConfigCommands::Get { key }) => get_config(&key),
10 Some(crate::ConfigCommands::Set { key, value }) => set_config(&key, &value),
11 }
12}
13
14fn show_config() -> Result<ConfigResponse, crate::errors::LitError> {
15 let network_config = NetworkConfig::load()?;
16 let airgap_config = AirgapConfig::load()?;
17
18 let mut entries = Vec::new();
19
20 entries.push(ConfigEntry {
21 key: "airgap.enabled".to_string(),
22 value: airgap_config.enabled.to_string(),
23 });
24 entries.push(ConfigEntry {
25 key: "airgap.strict_mode".to_string(),
26 value: airgap_config.strict_mode.to_string(),
27 });
28 entries.push(ConfigEntry {
29 key: "airgap.allowed_transports".to_string(),
30 value: format!("{:?}", airgap_config.allowed_transports),
31 });
32 if !airgap_config.allowed_media.is_empty() {
33 entries.push(ConfigEntry {
34 key: "airgap.allowed_media".to_string(),
35 value: airgap_config.allowed_media.join(", "),
36 });
37 }
38 if !airgap_config.allowed_shares.is_empty() {
39 entries.push(ConfigEntry {
40 key: "airgap.allowed_shares".to_string(),
41 value: airgap_config.allowed_shares.join(", "),
42 });
43 }
44 entries.push(ConfigEntry {
45 key: "network.allowed_networks".to_string(),
46 value: network_config.allowed_networks.join(", "),
47 });
48 entries.push(ConfigEntry {
49 key: "network.allowed_hosts".to_string(),
50 value: if network_config.allowed_hosts.is_empty() {
51 "(none)".to_string()
52 } else {
53 network_config.allowed_hosts.join(", ")
54 },
55 });
56 entries.push(ConfigEntry {
57 key: "security.network_audit_log".to_string(),
58 value: network_config.audit_log.to_string(),
59 });
60 if let Some(path) = &network_config.audit_log_path {
61 entries.push(ConfigEntry {
62 key: "security.network_audit_log_path".to_string(),
63 value: path.clone(),
64 });
65 }
66 entries.push(ConfigEntry {
67 key: "security.airgap_audit_log".to_string(),
68 value: airgap_config.audit_log.to_string(),
69 });
70 if let Some(path) = &airgap_config.audit_log_path {
71 entries.push(ConfigEntry {
72 key: "security.airgap_audit_log_path".to_string(),
73 value: path.clone(),
74 });
75 }
76
77 Ok(ConfigResponse::Show { entries })
78}
79
80fn get_config(key: &str) -> Result<ConfigResponse, crate::errors::LitError> {
81 let network_config = NetworkConfig::load()?;
82 let airgap_config = AirgapConfig::load()?;
83
84 let value = match key {
85 "airgap.enabled" => airgap_config.enabled.to_string(),
86 "airgap.strict_mode" => airgap_config.strict_mode.to_string(),
87 "network.allowed_networks" => network_config.allowed_networks.join(", "),
88 "network.allowed_hosts" => network_config.allowed_hosts.join(", "),
89 "security.audit_log" => network_config.audit_log.to_string(),
90 "security.audit_log_path" => network_config.audit_log_path.unwrap_or_default(),
91 _ => return Err(format!("Unknown configuration key: {}", key).into()),
92 };
93
94 Ok(ConfigResponse::Get {
95 key: key.to_string(),
96 value,
97 })
98}
99
100fn set_config(key: &str, value: &str) -> Result<ConfigResponse, crate::errors::LitError> {
101 match key {
102 "airgap.enabled" => {
103 let mut config = AirgapConfig::load()?;
104 config.enabled = value
105 .parse::<bool>()
106 .map_err(|_| "Invalid boolean value (use 'true' or 'false')".to_string())?;
107 config.save()?;
108 Ok(ConfigResponse::Set {
109 key: key.to_string(),
110 value: value.to_string(),
111 })
112 }
113 "airgap.strict_mode" => {
114 let mut config = AirgapConfig::load()?;
115 config.strict_mode = value
116 .parse::<bool>()
117 .map_err(|_| "Invalid boolean value (use 'true' or 'false')".to_string())?;
118 config.save()?;
119 Ok(ConfigResponse::Set {
120 key: key.to_string(),
121 value: value.to_string(),
122 })
123 }
124 _ => Err(format!(
125 "Setting '{}' is not supported via command line.\n\
126 Supported keys: airgap.enabled, airgap.strict_mode\n\
127 For other settings, edit ~/.lit/airgap.toml or ~/.litconfig directly.",
128 key
129 )
130 .into()),
131 }
132}