kindly_guard_server/storage/
mod.rs1use anyhow::Result;
21use async_trait::async_trait;
22use chrono::{DateTime, Utc};
23use serde::{Deserialize, Serialize};
24use std::sync::Arc;
25use std::time::Duration;
26
27#[cfg(feature = "enhanced")]
28pub mod enhanced;
29pub mod memory;
30
31#[cfg(feature = "enhanced")]
33pub use enhanced::EnhancedStorage;
34pub use memory::InMemoryStorage;
35
36use crate::traits::{RateLimitKey, SecurityEvent};
37
38#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)]
40pub struct EventId(pub String);
41
42#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)]
44pub struct SnapshotId(pub String);
45
46#[derive(Debug, Clone, Default, Serialize, Deserialize)]
48pub struct EventFilter {
49 pub client_id: Option<String>,
51 pub event_type: Option<String>,
53 pub from_time: Option<DateTime<Utc>>,
55 pub to_time: Option<DateTime<Utc>>,
57 pub limit: Option<usize>,
59 pub min_severity: Option<String>,
61}
62
63#[derive(Debug, Clone, Serialize, Deserialize)]
65pub struct RateLimitState {
66 pub tokens: f64,
68 pub last_refill: DateTime<Utc>,
70 pub request_count: u64,
72 pub penalty_multiplier: f64,
74}
75
76#[derive(Debug, Clone, Serialize, Deserialize)]
78pub struct CorrelationState {
79 pub windows: Vec<CorrelationWindow>,
81 pub patterns: Vec<DetectedPattern>,
83 pub last_update: DateTime<Utc>,
85}
86
87#[derive(Debug, Clone, Serialize, Deserialize)]
89pub struct CorrelationWindow {
90 pub id: String,
91 pub start_time: DateTime<Utc>,
92 pub end_time: DateTime<Utc>,
93 pub events: Vec<EventId>,
94}
95
96#[derive(Debug, Clone, Serialize, Deserialize)]
98pub struct DetectedPattern {
99 pub pattern_type: String,
100 pub confidence: f64,
101 pub events: Vec<EventId>,
102 pub detected_at: DateTime<Utc>,
103}
104
105#[async_trait]
107pub trait StorageProvider: Send + Sync {
108 async fn store_event(&self, event: &SecurityEvent) -> Result<EventId>;
110
111 async fn get_event(&self, id: &EventId) -> Result<Option<SecurityEvent>>;
113
114 async fn query_events(&self, filter: EventFilter) -> Result<Vec<SecurityEvent>>;
116
117 async fn store_rate_limit_state(
119 &self,
120 key: &RateLimitKey,
121 state: &RateLimitState,
122 ) -> Result<()>;
123
124 async fn get_rate_limit_state(&self, key: &RateLimitKey) -> Result<Option<RateLimitState>>;
126
127 async fn cleanup_rate_limit_states(&self, older_than: Duration) -> Result<u64>;
129
130 async fn store_correlation_state(
132 &self,
133 client_id: &str,
134 state: &CorrelationState,
135 ) -> Result<()>;
136
137 async fn get_correlation_state(&self, client_id: &str) -> Result<Option<CorrelationState>>;
139
140 async fn create_snapshot(&self) -> Result<SnapshotId>;
142
143 async fn list_snapshots(&self) -> Result<Vec<(SnapshotId, DateTime<Utc>)>>;
145
146 async fn restore_snapshot(&self, id: &SnapshotId) -> Result<()>;
148
149 async fn delete_snapshot(&self, id: &SnapshotId) -> Result<()>;
151
152 async fn get_stats(&self) -> Result<StorageStats>;
154
155 async fn compact(&self) -> Result<()>;
157}
158
159#[async_trait]
161pub trait ArchivalStorage: StorageProvider {
162 async fn archive_events(&self, older_than: Duration) -> Result<u64>;
164
165 async fn query_archived_events(&self, filter: EventFilter) -> Result<Vec<SecurityEvent>>;
167
168 async fn restore_from_archive(&self, filter: EventFilter) -> Result<u64>;
170
171 async fn get_archive_stats(&self) -> Result<ArchiveStats>;
173}
174
175#[derive(Debug, Clone, Serialize, Deserialize)]
177pub struct StorageStats {
178 pub event_count: u64,
180 pub total_size: u64,
182 pub rate_limit_entries: u64,
184 pub correlation_states: u64,
186 pub storage_type: String,
188 pub metadata: serde_json::Value,
190}
191
192#[derive(Debug, Clone, Serialize, Deserialize)]
194pub struct ArchiveStats {
195 pub archived_events: u64,
197 pub archive_size: u64,
199 pub oldest_event: Option<DateTime<Utc>>,
201 pub newest_event: Option<DateTime<Utc>>,
203}
204
205#[derive(Debug, Clone, Serialize, Deserialize)]
207pub struct StorageConfig {
208 pub enabled: bool,
210 pub storage_type: StorageType,
212 pub data_dir: Option<String>,
214 pub connection_string: Option<String>,
216 pub retention_days: u32,
218 pub archive_after_days: Option<u32>,
220 pub max_storage_mb: Option<u64>,
222 pub compression: bool,
224 pub encryption_at_rest: bool,
226}
227
228impl Default for StorageConfig {
229 fn default() -> Self {
230 Self {
231 enabled: false,
232 storage_type: StorageType::Memory,
233 data_dir: None,
234 connection_string: None,
235 retention_days: 30,
236 archive_after_days: None,
237 max_storage_mb: Some(1024), compression: true,
239 encryption_at_rest: false,
240 }
241 }
242}
243
244#[derive(Debug, Clone, Serialize, Deserialize)]
246#[serde(rename_all = "lowercase")]
247pub enum StorageType {
248 Memory,
250 File,
252 RocksDb,
254 Redis,
256 Postgres,
258 S3,
260 #[cfg(feature = "enhanced")]
262 Enhanced,
263}
264
265pub trait StorageProviderFactory: Send + Sync {
267 fn create(&self, config: &StorageConfig) -> Result<Arc<dyn StorageProvider>>;
269}
270
271pub struct DefaultStorageFactory;
273
274impl StorageProviderFactory for DefaultStorageFactory {
275 fn create(&self, config: &StorageConfig) -> Result<Arc<dyn StorageProvider>> {
276 match config.storage_type {
277 StorageType::Memory => Ok(Arc::new(InMemoryStorage::new())),
278 #[cfg(feature = "enhanced")]
279 StorageType::Enhanced => Ok(Arc::new(EnhancedStorage::new(config.clone())?)),
280 _ => Ok(Arc::new(InMemoryStorage::new())), }
282 }
283}
284
285pub fn create_storage_provider(_config: &crate::config::Config) -> Arc<dyn StorageProvider> {
287 let factory = DefaultStorageFactory;
288 let storage_config = StorageConfig::default();
291 factory
292 .create(&storage_config)
293 .unwrap_or_else(|_| Arc::new(InMemoryStorage::new()))
294}