Skip to main content

cc_audit/scanner/
mod.rs

1pub mod command;
2pub mod common;
3pub mod dependency;
4pub mod dockerfile;
5pub mod hook;
6pub mod mcp;
7pub mod plugin;
8pub mod rules_dir;
9pub mod skill;
10pub mod subagent;
11
12use crate::error::{AuditError, Result};
13use crate::rules::Finding;
14use std::path::Path;
15
16pub use command::CommandScanner;
17pub use common::ScannerConfig;
18pub use dependency::DependencyScanner;
19pub use dockerfile::DockerScanner;
20pub use hook::HookScanner;
21pub use mcp::McpScanner;
22pub use plugin::PluginScanner;
23pub use rules_dir::RulesDirScanner;
24pub use skill::{FrontmatterParser, SkillFileFilter, SkillScanner};
25pub use subagent::SubagentScanner;
26
27/// Core trait for all security scanners.
28pub trait Scanner {
29    fn scan_file(&self, path: &Path) -> Result<Vec<Finding>>;
30    fn scan_directory(&self, dir: &Path) -> Result<Vec<Finding>>;
31
32    fn scan_path(&self, path: &Path) -> Result<Vec<Finding>> {
33        if !path.exists() {
34            return Err(AuditError::FileNotFound(path.display().to_string()));
35        }
36
37        if path.is_file() {
38            return self.scan_file(path);
39        }
40
41        if !path.is_dir() {
42            return Err(AuditError::NotADirectory(path.display().to_string()));
43        }
44
45        self.scan_directory(path)
46    }
47}
48
49/// Extended trait for scanners that support content-based scanning.
50///
51/// This trait provides a unified interface for scanning raw content strings,
52/// which is useful for testing and for scanners that parse structured files
53/// (like JSON) before applying rules.
54pub trait ContentScanner: Scanner {
55    /// Returns a reference to the scanner's configuration.
56    fn config(&self) -> &ScannerConfig;
57
58    /// Scans content and returns findings.
59    ///
60    /// Default implementation delegates to ScannerConfig::check_content.
61    /// Override this method for scanners that need custom content processing
62    /// (e.g., JSON parsing, frontmatter extraction).
63    fn scan_content(&self, content: &str, file_path: &str) -> Result<Vec<Finding>> {
64        Ok(self.config().check_content(content, file_path))
65    }
66}