syncable_cli/analyzer/security/
mod.rs1use std::path::Path;
12use thiserror::Error;
13
14pub mod core;
15pub mod javascript;
16pub mod python;
17pub mod patterns;
18pub mod config;
19pub mod gitignore;
20
21pub use core::{SecurityAnalyzer, SecurityReport, SecurityFinding, SecuritySeverity, SecurityCategory};
22pub use javascript::JavaScriptSecurityAnalyzer;
23pub use python::PythonSecurityAnalyzer;
24pub use patterns::SecretPatternManager;
25pub use config::SecurityAnalysisConfig;
26pub use gitignore::{GitIgnoreAnalyzer, GitIgnoreStatus, GitIgnoreRisk};
27
28pub struct ModularSecurityAnalyzer {
30 javascript_analyzer: JavaScriptSecurityAnalyzer,
31 }
35
36impl ModularSecurityAnalyzer {
37 pub fn new() -> Result<Self, SecurityError> {
38 Ok(Self {
39 javascript_analyzer: JavaScriptSecurityAnalyzer::new()?,
40 })
41 }
42
43 pub fn with_config(config: SecurityAnalysisConfig) -> Result<Self, SecurityError> {
44 Ok(Self {
45 javascript_analyzer: JavaScriptSecurityAnalyzer::with_config(config.clone())?,
46 })
47 }
48
49 pub fn analyze_project(&mut self, project_root: &Path, languages: &[crate::analyzer::DetectedLanguage]) -> Result<SecurityReport, SecurityError> {
51 let mut all_findings = Vec::new();
52
53 if languages.iter().any(|lang| matches!(lang.name.as_str(), "JavaScript" | "TypeScript" | "JSX" | "TSX")) {
55 let js_report = self.javascript_analyzer.analyze_project(project_root)?;
56 all_findings.extend(js_report.findings);
57 }
58
59 Ok(SecurityReport::from_findings(all_findings))
63 }
64}
65
66#[derive(Debug, Error)]
67pub enum SecurityError {
68 #[error("Security analysis failed: {0}")]
69 AnalysisFailed(String),
70
71 #[error("Pattern compilation error: {0}")]
72 PatternError(#[from] regex::Error),
73
74 #[error("IO error: {0}")]
75 Io(#[from] std::io::Error),
76
77 #[error("JavaScript security analysis error: {0}")]
78 JavaScriptError(String),
79}