From 001ca45e385c05b0eaa36d9879e051853aaff107 Mon Sep 17 00:00:00 2001 From: DanConwayDev Date: Tue, 4 Nov 2025 06:17:55 +0000 Subject: created POC grasp-auditor --- grasp-audit/src/bin/grasp-audit.rs | 95 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 95 insertions(+) create mode 100644 grasp-audit/src/bin/grasp-audit.rs (limited to 'grasp-audit/src/bin') diff --git a/grasp-audit/src/bin/grasp-audit.rs b/grasp-audit/src/bin/grasp-audit.rs new file mode 100644 index 0000000..6c063db --- /dev/null +++ b/grasp-audit/src/bin/grasp-audit.rs @@ -0,0 +1,95 @@ +//! GRASP Audit CLI Tool + +use clap::{Parser, Subcommand}; +use grasp_audit::*; + +#[derive(Parser)] +#[command(name = "grasp-audit")] +#[command(about = "GRASP audit and compliance testing tool", long_about = None)] +struct Cli { + #[command(subcommand)] + command: Commands, +} + +#[derive(Subcommand)] +enum Commands { + /// Run audit tests against a server + Audit { + /// Relay URL (e.g., ws://localhost:7000) + #[arg(short, long)] + relay: String, + + /// Mode: ci or production + #[arg(short, long, default_value = "ci")] + mode: String, + + /// Spec to test (nip01-smoke, all) + #[arg(short, long, default_value = "nip01-smoke")] + spec: String, + }, +} + +#[tokio::main] +async fn main() -> Result<()> { + // Initialize logging + tracing_subscriber::fmt() + .with_env_filter( + tracing_subscriber::EnvFilter::from_default_env() + .add_directive(tracing::Level::INFO.into()) + ) + .init(); + + let cli = Cli::parse(); + + match cli.command { + Commands::Audit { relay, mode, spec } => { + let config = match mode.as_str() { + "ci" => AuditConfig::ci(), + "production" => AuditConfig::production(), + _ => return Err(anyhow!("Invalid mode: {}. Use 'ci' or 'production'", mode)), + }; + + println!("🔍 GRASP Audit Tool"); + println!("━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"); + println!("Relay: {}", relay); + println!("Mode: {}", mode); + println!("Spec: {}", spec); + println!("Run ID: {}", config.run_id); + println!("━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"); + println!(); + + println!("Connecting to relay..."); + let client = AuditClient::new(&relay, config).await + .map_err(|e| anyhow!("Failed to connect to relay: {}", e))?; + + if !client.is_connected().await { + return Err(anyhow!("Could not establish connection to relay")); + } + + println!("✓ Connected\n"); + + let results = match spec.as_str() { + "nip01-smoke" => { + println!("Running NIP-01 smoke tests...\n"); + specs::Nip01SmokeTests::run_all(&client).await + } + "all" => { + println!("Running all tests...\n"); + specs::Nip01SmokeTests::run_all(&client).await + } + _ => return Err(anyhow!("Unknown spec: {}. Use 'nip01-smoke' or 'all'", spec)), + }; + + results.print_report(); + + if !results.all_passed() { + println!("❌ Some tests failed"); + std::process::exit(1); + } else { + println!("✅ All tests passed!"); + } + } + } + + Ok(()) +} -- cgit v1.2.3