pub mod errors;
pub mod input;
pub mod rate_limit;
pub mod crypto;
pub mod policy;
pub mod audit;
pub mod validation;
pub use errors::{SecurityError, SecurityResult};
pub use input::{InputValidator, SanitizationConfig};
pub use rate_limit::{RateLimiter, RateLimitConfig};
pub use crypto::{CryptoValidator, KeyValidator};
pub use policy::{SecurityPolicy, PolicyEnforcer};
pub use audit::{AuditValidator, AuditConfig};
pub use validation::{Validator, ValidationRule};
#[derive(Debug, Clone)]
pub struct SecurityContext {
pub user_id: String,
pub ip_address: String,
pub timestamp: chrono::DateTime<chrono::Utc>,
pub session_id: Option<String>,
pub metadata: std::collections::HashMap<String, String>,
}
impl SecurityContext {
pub fn new(user_id: impl Into<String>, ip_address: impl Into<String>) -> Self {
Self {
user_id: user_id.into(),
ip_address: ip_address.into(),
timestamp: chrono::Utc::now(),
session_id: None,
metadata: std::collections::HashMap::new(),
}
}
pub fn with_session(mut self, session_id: impl Into<String>) -> Self {
self.session_id = Some(session_id.into());
self
}
pub fn with_metadata(mut self, key: impl Into<String>, value: impl Into<String>) -> Self {
self.metadata.insert(key.into(), value.into());
self
}
}
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
pub struct SecurityConfig {
pub enable_input_validation: bool,
pub enable_rate_limiting: bool,
pub enable_crypto_validation: bool,
pub enable_audit_validation: bool,
pub max_request_size: usize,
pub session_timeout_seconds: u64,
pub password_min_length: usize,
pub password_require_special: bool,
pub enable_cors: bool,
pub cors_allowed_origins: Vec<String>,
}
impl Default for SecurityConfig {
fn default() -> Self {
Self {
enable_input_validation: true,
enable_rate_limiting: true,
enable_crypto_validation: true,
enable_audit_validation: true,
max_request_size: 10 * 1024 * 1024, session_timeout_seconds: 3600, password_min_length: 12,
password_require_special: true,
enable_cors: false,
cors_allowed_origins: vec![],
}
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_security_context_creation() {
let ctx = SecurityContext::new("user123", "192.168.1.1")
.with_session("sess_abc123")
.with_metadata("request_id", "req_xyz789");
assert_eq!(ctx.user_id, "user123");
assert_eq!(ctx.ip_address, "192.168.1.1");
assert_eq!(ctx.session_id, Some("sess_abc123".to_string()));
assert_eq!(ctx.metadata.get("request_id"), Some(&"req_xyz789".to_string()));
}
#[test]
fn test_security_config_defaults() {
let config = SecurityConfig::default();
assert!(config.enable_input_validation);
assert!(config.enable_rate_limiting);
assert_eq!(config.max_request_size, 10 * 1024 * 1024);
assert_eq!(config.password_min_length, 12);
}
}