From 24adcee21bb972580462d6826183f4fcd33f20e5 Mon Sep 17 00:00:00 2001 From: arch_agent Date: Mon, 15 Jun 2026 17:09:40 +0200 Subject: [PATCH] Add ./src/config.rs --- src/config.rs | 139 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 139 insertions(+) create mode 100644 src/config.rs diff --git a/src/config.rs b/src/config.rs new file mode 100644 index 0000000..6434d1b --- /dev/null +++ b/src/config.rs @@ -0,0 +1,139 @@ +use anyhow::{Context, Result}; +use serde::{Deserialize, Serialize}; +use std::collections::HashSet; +use std::path::PathBuf; +use tokio::fs; +use tracing::info; + +/// Konfiguration für AegisAUR +#[derive(Debug, Clone, Serialize, Deserialize)] +pub struct AegisConfig { + pub config_path: PathBuf, + pub cache_dir: PathBuf, + pub data_dir: PathBuf, + + // Scan-Settings + pub auto_check_iocs: bool, + pub auto_check_pkgbuild: bool, + pub ioc_cache_ttl_minutes: u64, + + // Thresholds + pub warning_threshold: u32, // Score unter diesem Wert = Warnung + pub critical_threshold: u32, // Score unter diesem Wert = Kritisch + + // Verhalten + pub block_install_on_critical: bool, + pub block_install_on_ioc: bool, + pub notify_desktop: bool, + + // Quellen + pub ioc_sources: Vec, + + // Whitelist + pub whitelisted_packages: HashSet, +} + +#[derive(Debug, Clone, Serialize, Deserialize)] +pub struct IocSource { + pub name: String, + pub url: String, + pub source_type: IocSourceType, + pub enabled: bool, +} + +#[derive(Debug, Clone, Serialize, Deserialize)] +pub enum IocSourceType { + Gist, + JsonApi, + TextList, + GitHubRelease, +} + +impl Default for AegisConfig { + fn default() -> Self { + let base_dirs = directories::ProjectDirs::from("eu", "heimatlosen", "aegisaur") + .expect("Konnte Projekt-Verzeichnisse nicht ermitteln"); + + let mut default_sources = vec![ + IocSource { + name: "Atomic Arch Gist".to_string(), + url: "https://gist.githubusercontent.com/Kidev/85756c3dcad3623ca5604a8135bafd14/raw".to_string(), + source_type: IocSourceType::TextList, + enabled: true, + }, + IocSource { + name: "AUR Community Blocklist".to_string(), + url: "https://raw.githubusercontent.com/Kidev/AUR-Blocklist/main/blocklist.txt".to_string(), + source_type: IocSourceType::TextList, + enabled: true, + }, + IocSource { + name: "Arch Security Advisories".to_string(), + url: "https://security.archlinux.org/advisories.json".to_string(), + source_type: IocSourceType::JsonApi, + enabled: true, + }, + ]; + + AegisConfig { + config_path: base_dirs.config_local_dir().join("config.toml"), + cache_dir: base_dirs.cache_dir().to_path_buf(), + data_dir: base_dirs.data_dir().to_path_buf(), + auto_check_iocs: true, + auto_check_pkgbuild: true, + ioc_cache_ttl_minutes: 60, + warning_threshold: 60, + critical_threshold: 30, + block_install_on_critical: false, + block_install_on_ioc: true, + notify_desktop: true, + ioc_sources: default_sources, + whitelisted_packages: HashSet::new(), + } + } +} + +impl AegisConfig { + /// Lädt Konfiguration oder erstellt Default + pub async fn load_or_default() -> Result { + let config_path = Self::default().config_path; + + if config_path.exists() { + info!("Lade Konfiguration von: {}", config_path.display()); + let content = fs::read_to_string(&config_path).await?; + let config: AegisConfig = toml::from_str(&content)?; + Ok(config) + } else { + info!("Erstelle Standard-Konfiguration..."); + let config = AegisConfig::default(); + config.save().await?; + Ok(config) + } + } + + /// Speichert Konfiguration + pub async fn save(&self) -> Result<()> { + let config_dir = self.config_path.parent().unwrap(); + fs::create_dir_all(config_dir).await?; + + let content = toml::to_string_pretty(self)?; + fs::write(&self.config_path, content).await?; + info!("Konfiguration gespeichert: {}", self.config_path.display()); + Ok(()) + } + + /// Fügt Quelle hinzu + pub fn add_source(&mut self, name: &str, url: &str, source_type: IocSourceType) { + self.ioc_sources.push(IocSource { + name: name.to_string(), + url: url.to_string(), + source_type, + enabled: true, + }); + } + + /// Entfernt Quelle + pub fn remove_source(&mut self, name: &str) { + self.ioc_sources.retain(|s| s.name != name); + } +} \ No newline at end of file