271 lines
8.2 KiB
Rust
271 lines
8.2 KiB
Rust
//! Default implementations for configuration types.
|
|
|
|
use std::path::PathBuf;
|
|
|
|
use super::types::{
|
|
AliasConfig, AutonomousConfig, CommunityConfig, CorpusConfig, DepVersionConfig, EntropyConfig,
|
|
EpistemeConfig, ExtractorConfig, HostedConfig, LearningConfig, LlmConfig, OfflineFallback,
|
|
PromotionConfig, ScanConfig, SyncMode, ThresholdConfig, TimeoutExtractorConfig,
|
|
DEFAULT_LLM_MODEL,
|
|
};
|
|
|
|
impl Default for EpistemeConfig {
|
|
fn default() -> Self {
|
|
Self { data_dir: dirs_default_data_dir(), url: None }
|
|
}
|
|
}
|
|
|
|
impl Default for ThresholdConfig {
|
|
fn default() -> Self {
|
|
Self { block: 0.7, flag: 0.4 }
|
|
}
|
|
}
|
|
|
|
impl Default for ExtractorConfig {
|
|
fn default() -> Self {
|
|
Self {
|
|
enabled: vec![
|
|
"tls_verify".to_string(),
|
|
"tls_version".to_string(),
|
|
"jwt_config".to_string(),
|
|
"hardcoded_secrets".to_string(),
|
|
"timeout_config".to_string(),
|
|
"dep_versions".to_string(),
|
|
"cors_config".to_string(),
|
|
"durability_config".to_string(),
|
|
"rate_limit".to_string(),
|
|
// Phase 2 extractors
|
|
"weak_crypto".to_string(),
|
|
"sql_injection".to_string(),
|
|
"command_injection".to_string(),
|
|
// Unreal Engine extractors
|
|
"unreal_cpp".to_string(),
|
|
"unreal_config".to_string(),
|
|
"unreal_performance".to_string(),
|
|
// Phase 8: Enterprise extractors (first batch)
|
|
"high_entropy_secrets".to_string(),
|
|
"auth_bypass".to_string(),
|
|
"api_key_security".to_string(),
|
|
"import_graph".to_string(),
|
|
"derive_pattern".to_string(),
|
|
"const_declarations".to_string(),
|
|
"unsafe_atomic".to_string(),
|
|
"circuit_breaker_config".to_string(),
|
|
"insecure_cookies".to_string(),
|
|
// Phase 8: Enterprise extractors (second batch)
|
|
"path_traversal".to_string(),
|
|
"unvalidated_redirects".to_string(),
|
|
"weak_password".to_string(),
|
|
"security_headers".to_string(),
|
|
"insecure_deserialization".to_string(),
|
|
"ssrf".to_string(),
|
|
"orm_injection".to_string(),
|
|
"xxe".to_string(),
|
|
// Phase 8.3: Config deep parsing
|
|
"config_security".to_string(),
|
|
// Phase 8.2: Framework-specific security extractors
|
|
"django_security".to_string(),
|
|
"express_security".to_string(),
|
|
"flask_security".to_string(),
|
|
"fastapi_security".to_string(),
|
|
"nestjs_security".to_string(),
|
|
"nextjs_security".to_string(),
|
|
"spring_security".to_string(),
|
|
"laravel_security".to_string(),
|
|
"rails_security".to_string(),
|
|
"aspnet_security".to_string(),
|
|
],
|
|
disabled: vec![],
|
|
timeout_config: TimeoutExtractorConfig::default(),
|
|
dep_versions: DepVersionConfig::default(),
|
|
entropy: EntropyConfig::default(),
|
|
declarative: vec![],
|
|
}
|
|
}
|
|
}
|
|
|
|
impl Default for TimeoutExtractorConfig {
|
|
fn default() -> Self {
|
|
Self { min_reasonable_ms: 1000, max_reasonable_ms: 300_000 }
|
|
}
|
|
}
|
|
|
|
impl Default for DepVersionConfig {
|
|
fn default() -> Self {
|
|
Self {
|
|
enabled: false, // OPT-IN: Disabled by default to reduce noise
|
|
advisory_db: dirs_default_advisory_db(),
|
|
}
|
|
}
|
|
}
|
|
|
|
impl Default for EntropyConfig {
|
|
fn default() -> Self {
|
|
Self { min_entropy: 4.5, min_charset_variety: 0.4, min_length: 20, max_length: 200 }
|
|
}
|
|
}
|
|
|
|
impl Default for ScanConfig {
|
|
fn default() -> Self {
|
|
Self {
|
|
exclude: vec![
|
|
"target/".to_string(),
|
|
"node_modules/".to_string(),
|
|
".git/".to_string(),
|
|
"vendor/".to_string(),
|
|
],
|
|
max_file_size: 1_048_576, // 1MB
|
|
include_tests: false,
|
|
}
|
|
}
|
|
}
|
|
|
|
impl Default for AliasConfig {
|
|
fn default() -> Self {
|
|
Self { auto_suggest: true, auto_accept_tier0: true, auto_create_aliases: true }
|
|
}
|
|
}
|
|
|
|
impl Default for CorpusConfig {
|
|
fn default() -> Self {
|
|
Self {
|
|
cache_dir: dirs_default_cache_dir(),
|
|
include_hardcoded: true,
|
|
include_rfc: true,
|
|
include_owasp: true,
|
|
include_vendor: true,
|
|
rfc_list: None,
|
|
}
|
|
}
|
|
}
|
|
|
|
impl Default for HostedConfig {
|
|
fn default() -> Self {
|
|
Self {
|
|
url: None,
|
|
project_id: None,
|
|
team_id: None,
|
|
sync_mode: SyncMode::default(),
|
|
offline_fallback: OfflineFallback::default(),
|
|
max_retries: 3,
|
|
retry_delay_ms: 1000,
|
|
api_key_env: "APHORIA_API_KEY".to_string(),
|
|
}
|
|
}
|
|
}
|
|
|
|
impl Default for CommunityConfig {
|
|
fn default() -> Self {
|
|
Self {
|
|
enabled: false, // CRITICAL: Opt-in only
|
|
anonymize: true, // CRITICAL: Privacy by default
|
|
exclude: vec![],
|
|
include: vec![],
|
|
min_confidence: 0.8,
|
|
}
|
|
}
|
|
}
|
|
|
|
impl Default for LlmConfig {
|
|
fn default() -> Self {
|
|
Self {
|
|
enabled: false,
|
|
provider: "gemini".to_string(),
|
|
model: DEFAULT_LLM_MODEL.to_string(),
|
|
api_key_env: "GEMINI_API_KEY".to_string(),
|
|
max_tokens_per_scan: 50000,
|
|
max_tokens_per_file: 4000,
|
|
cache_responses: true,
|
|
timeout_secs: 60,
|
|
high_value_only: true,
|
|
min_confidence: 0.7,
|
|
}
|
|
}
|
|
}
|
|
|
|
impl Default for LearningConfig {
|
|
fn default() -> Self {
|
|
Self {
|
|
enabled: false,
|
|
store: "local".to_string(),
|
|
min_confidence: 0.7,
|
|
prune_after_days: 90,
|
|
max_patterns: 10_000,
|
|
promotion: PromotionConfig::default(),
|
|
}
|
|
}
|
|
}
|
|
|
|
impl Default for PromotionConfig {
|
|
fn default() -> Self {
|
|
Self {
|
|
min_projects: 5,
|
|
min_confidence: 0.8,
|
|
auto_promote: false,
|
|
output_dir: PathBuf::from(".aphoria/extractors/learned"),
|
|
require_review: true,
|
|
}
|
|
}
|
|
}
|
|
|
|
impl Default for AutonomousConfig {
|
|
fn default() -> Self {
|
|
Self {
|
|
// CRITICAL: Opt-in only - kill switch defaults to off
|
|
enabled: false,
|
|
// Stricter than standard promotion thresholds
|
|
min_confidence: 0.95,
|
|
min_projects: 10,
|
|
// Require perfect validation by default
|
|
require_zero_failures: true,
|
|
require_zero_warnings: true,
|
|
// Audit logging on by default for compliance
|
|
audit_log: true,
|
|
audit_dir: None, // Uses ~/.aphoria/audit/ via get_audit_dir()
|
|
}
|
|
}
|
|
}
|
|
|
|
/// Get the default Aphoria data directory.
|
|
fn dirs_default_data_dir() -> PathBuf {
|
|
if let Some(home) = dirs::home_dir() {
|
|
home.join(".aphoria").join("db")
|
|
} else {
|
|
PathBuf::from(".aphoria/db")
|
|
}
|
|
}
|
|
|
|
/// Get the default advisory database directory.
|
|
fn dirs_default_advisory_db() -> PathBuf {
|
|
if let Some(home) = dirs::home_dir() {
|
|
home.join(".aphoria").join("advisory-db")
|
|
} else {
|
|
PathBuf::from(".aphoria/advisory-db")
|
|
}
|
|
}
|
|
|
|
/// Get the default cache directory for corpus downloads.
|
|
fn dirs_default_cache_dir() -> PathBuf {
|
|
if let Some(cache) = dirs::cache_dir() {
|
|
cache.join("aphoria")
|
|
} else if let Some(home) = dirs::home_dir() {
|
|
home.join(".cache").join("aphoria")
|
|
} else {
|
|
PathBuf::from(".aphoria/cache")
|
|
}
|
|
}
|
|
|
|
/// Get the LLM response cache directory.
|
|
///
|
|
/// Used to cache Claude API responses keyed by content hash + model.
|
|
/// This avoids redundant API calls for the same file content.
|
|
pub fn llm_cache_dir() -> PathBuf {
|
|
if let Some(cache) = dirs::cache_dir() {
|
|
cache.join("aphoria").join("llm-cache")
|
|
} else if let Some(home) = dirs::home_dir() {
|
|
home.join(".cache").join("aphoria").join("llm-cache")
|
|
} else {
|
|
PathBuf::from(".aphoria/llm-cache")
|
|
}
|
|
}
|