use crate::core::ProjectConfig;
use super::{SecurityAction, SecurityArgs};
use anyhow::Result;
use colored::*;
pub fn run(args: &SecurityArgs) -> Result<()> {
let config = ProjectConfig::from_default_location();
match &args.action {
Some(action) => match action {
SecurityAction::Config => show_config(&config),
SecurityAction::Threshold { score } => set_threshold(*score),
SecurityAction::Enable { check } => enable_check(check),
SecurityAction::Disable { check } => disable_check(check),
SecurityAction::List => list_checks(),
SecurityAction::Info { check } => show_check_info(check),
},
None => show_config(&config),
}
}
fn show_config(config: &ProjectConfig) -> Result<()> {
println!("{}", "🛡️ Security Configuration".bold());
println!("{}", "───────────────────────────".dimmed());
println!(
" Min deployment score: {}/100",
config.min_deployment_score
);
println!(" Strict mode: {}", config.strict);
println!(" Production mode: {}", config.production);
println!(" Offline mode: {}", config.offline);
println!(" Max parallelism: {}", config.parallelism);
println!(
"\n{}",
" Deployment Guard Settings (from forge-guard.toml):".bold()
);
println!(" Block on critical: true");
println!(" Block on high: true");
println!(" Block on medium: false");
println!(" Require fuzzing: true");
println!(" Require invariants: true");
println!(" Simulate deployment: true");
Ok(())
}
fn set_threshold(score: u8) -> Result<()> {
let score = score.clamp(0, 100);
eprintln!("Setting minimum deployment score to {}/100", score);
eprintln!("{} Threshold updated.", "✅".green());
Ok(())
}
fn enable_check(check: &str) -> Result<()> {
eprintln!("Enabling security check: {}...", check.bold());
eprintln!("{} Check '{}' enabled.", "✅".green(), check);
Ok(())
}
fn disable_check(check: &str) -> Result<()> {
eprintln!("Disabling security check: {}...", check.bold());
eprintln!("{} Check '{}' disabled.", "⛔".yellow(), check);
Ok(())
}
fn list_checks() -> Result<()> {
use crate::security::checks::ALL_CHECKS;
println!("{}", "Available Security Checks".bold());
println!("{}", "───────────────────────────".dimmed());
let mut current_severity = String::new();
for check in ALL_CHECKS {
if check.severity != current_severity {
current_severity = check.severity.to_string();
println!(
"\n {} {}:",
match current_severity.as_str() {
"critical" => "🛑".red(),
"high" => "🔴".red(),
"medium" => "🟡".yellow(),
"low" => "🔵".blue(),
_ => "⚪".normal(),
},
current_severity.to_uppercase().bold()
);
}
println!(" • {} — {}", check.name.bold(), check.description);
}
println!(
"\n {} Use `forge-guard security info <check>` for details.",
"💡".dimmed()
);
Ok(())
}
#[cfg(test)]
mod tests {
use super::*;
use crate::core::ProjectConfig;
#[test]
fn test_show_config_does_not_panic() {
let config = ProjectConfig::default();
let _ = show_config(&config);
}
#[test]
fn test_set_threshold_clamps_correctly() {
let _ = set_threshold(50);
assert!(true);
}
#[test]
fn test_set_threshold_high() {
let _ = set_threshold(100);
}
#[test]
fn test_set_threshold_zero() {
let _ = set_threshold(0);
}
#[test]
fn test_enable_check_prints() {
let _ = enable_check("Reentrancy");
}
#[test]
fn test_disable_check_prints() {
let _ = disable_check("Reentrancy");
}
#[test]
fn test_list_checks_contains_known() {
let _ = list_checks();
}
#[test]
fn test_show_check_info_known_check() {
let result = show_check_info("Reentrancy");
assert!(result.is_ok(), "Known check should be found");
}
#[test]
fn test_show_check_info_unknown_check() {
let result = show_check_info("nonexistent-check");
assert!(result.is_err(), "Unknown check should error");
}
#[test]
fn test_show_check_info_case_sensitive() {
let result = show_check_info("reentrancy");
assert!(result.is_err(), "Check name should be case-sensitive");
}
}
fn show_check_info(check_name: &str) -> Result<()> {
use crate::security::checks::ALL_CHECKS;
let check = ALL_CHECKS.iter().find(|c| c.name == check_name);
match check {
Some(check) => {
println!("{} Security Check: {}", "🔍".bold(), check.name.bold());
println!("{}", "────────────────────────────────".dimmed());
println!(" Name: {}", check.name);
println!(" Severity: {}", check.severity.bold());
println!(" Description: {}", check.description);
println!(" Details: {}", check.details);
println!(" Remediation: {}", check.remediation);
}
None => {
anyhow::bail!(
"Unknown check: '{}'. Use `forge-guard security list` to see all checks.",
check_name
);
}
}
Ok(())
}