1use chrono::Utc;
7use std::collections::HashMap;
8use rust_threat_detector::{
9 IncidentResponseManager, IncidentStatus, ThreatAlert,
10 ThreatCategory, ThreatSeverity, ResponseAction, Playbook,
11 PlaybookAction, incident_response::FailureAction,
12};
13
14fn main() {
15 println!("=== Automated Incident Response Demo v2.0 ===\n");
16
17 let mut manager = IncidentResponseManager::new();
18
19 println!("--- Example 1: Create Incident from Alert ---");
21 let alert = ThreatAlert {
22 alert_id: "ALERT-001".to_string(),
23 timestamp: Utc::now(),
24 severity: ThreatSeverity::High,
25 category: ThreatCategory::BruteForce,
26 description: "Multiple failed login attempts detected from external IP".to_string(),
27 source_log: "auth.log - 500 failed attempts in 10 minutes".to_string(),
28 indicators: vec!["203.0.113.50".to_string(), "admin".to_string()],
29 recommended_action: "Block source IP and review user account".to_string(),
30 threat_score: 85,
31 correlated_alerts: vec![],
32 };
33
34 let incident_id = manager.create_incident(&alert);
35 println!("Created incident: {}", incident_id);
36
37 if let Some(incident) = manager.get_incident(&incident_id) {
39 println!(" Title: {}", incident.title);
40 println!(" Status: {:?}", incident.status);
41 println!(" Severity: {:?}", incident.severity);
42 println!(" Category: {:?}", incident.category);
43 }
44
45 println!("\n--- Example 2: Execute Response Playbook ---");
47 let playbook = {
48 manager.find_playbooks(&alert).first().map(|&p| p.clone())
49 };
50
51 if let Some(playbook) = playbook {
52 println!("Found applicable playbook: {}", playbook.name);
53 println!(" Actions to execute: {}", playbook.actions.len());
54
55 let mut context = HashMap::new();
56 context.insert("source_ip".to_string(), "203.0.113.50".to_string());
57 context.insert("username".to_string(), "admin".to_string());
58
59 let results = manager.execute_playbook(&incident_id, &playbook, &context);
60 println!(" Executed {} actions:", results.len());
61 for result in &results {
62 println!(" - {}: {} ({}ms)",
63 result.action.name(),
64 if result.success { "Success" } else { "Failed" },
65 result.execution_time_ms
66 );
67 }
68 }
69
70 println!("\n--- Example 3: Incident Lifecycle ---");
72 if let Some(incident) = manager.get_incident_mut(&incident_id) {
73 incident.update_status(IncidentStatus::Acknowledged, "analyst1");
75 println!("Status updated to: {:?}", incident.status);
76
77 incident.add_note("analyst1", "Initial triage complete. IP belongs to known malicious range.");
79 println!("Added investigation note");
80
81 incident.update_status(IncidentStatus::Investigating, "analyst1");
83 println!("Status updated to: {:?}", incident.status);
84
85 incident.update_status(IncidentStatus::Containing, "analyst1");
87 println!("Status updated to: {:?}", incident.status);
88
89 println!("\nIncident Timeline:");
91 for entry in &incident.timeline {
92 println!(" [{}] {} by {}: {}",
93 entry.timestamp.format("%H:%M:%S"),
94 entry.event_type,
95 entry.actor,
96 entry.description
97 );
98 }
99
100 println!("\nIncident Metrics:");
102 println!(" Time to Acknowledge: {:?} seconds", incident.metrics.time_to_acknowledge_seconds);
103 println!(" Time to Contain: {:?} seconds", incident.metrics.time_to_contain_seconds);
104 println!(" Total Actions: {}", incident.metrics.total_actions);
105 println!(" Successful Actions: {}", incident.metrics.successful_actions);
106 }
107
108 println!("\n--- Example 4: Incident Statistics ---");
110
111 for i in 2..=5 {
113 let test_alert = ThreatAlert {
114 alert_id: format!("ALERT-{:03}", i),
115 timestamp: Utc::now(),
116 severity: if i % 2 == 0 { ThreatSeverity::High } else { ThreatSeverity::Medium },
117 category: if i % 3 == 0 { ThreatCategory::MalwareDetection } else { ThreatCategory::BruteForce },
118 description: format!("Test alert {}", i),
119 source_log: "test.log".to_string(),
120 indicators: vec![],
121 recommended_action: "Investigate".to_string(),
122 threat_score: 60 + i * 5,
123 correlated_alerts: vec![],
124 };
125 manager.create_incident(&test_alert);
126 }
127
128 let stats = manager.get_statistics();
129 println!("Incident Statistics:");
130 println!(" Total Incidents: {}", stats.total_incidents);
131 println!(" Active Incidents: {}", stats.active_incidents);
132 println!(" Resolved Incidents: {}", stats.resolved_incidents);
133 println!(" By Severity:");
134 for (severity, count) in &stats.by_severity {
135 println!(" {:?}: {}", severity, count);
136 }
137 println!(" By Category:");
138 for (category, count) in &stats.by_category {
139 println!(" {:?}: {}", category, count);
140 }
141
142 println!("\n--- Example 5: Available Playbooks ---");
144 let playbooks = manager.get_playbooks();
145 println!("Available playbooks: {}", playbooks.len());
146 for pb in playbooks {
147 println!("\n {} ({})", pb.name, pb.id);
148 println!(" Description: {}", pb.description);
149 println!(" Categories: {:?}", pb.threat_categories);
150 println!(" Min Severity: {:?}", pb.min_severity);
151 println!(" Requires Approval: {}", pb.requires_approval);
152 println!(" Actions: {}", pb.actions.len());
153 }
154
155 println!("\n--- Example 6: Query Incidents ---");
157
158 let active = manager.get_active_incidents();
159 println!("Active incidents: {}", active.len());
160
161 let high_severity = manager.get_incidents_by_severity(ThreatSeverity::High);
162 println!("High severity or above: {}", high_severity.len());
163
164 println!("\n--- Example 7: Response Action Types ---");
166 let actions = vec![
167 ResponseAction::BlockIP { ip: "1.2.3.4".to_string(), duration_hours: 24 },
168 ResponseAction::DisableAccount { account: "compromised_user".to_string() },
169 ResponseAction::IsolateHost { hostname: "infected-host".to_string() },
170 ResponseAction::NotifyTeam { team: "SOC".to_string(), message: "Critical incident".to_string() },
171 ResponseAction::EscalateToSOC { priority: "P1".to_string() },
172 ];
173
174 println!("Available response actions:");
175 for action in &actions {
176 println!(" - {} (reversible: {})", action.name(), action.is_reversible());
177 }
178
179 println!("\n=== Demo Complete ===");
180}