use serde::{Deserialize, Serialize}; use crate::config::settings::{Validate, ValidationError}; #[derive(Debug, Clone, Serialize, Deserialize)] pub enum MAuthSettings { Tls(TLSSettings), } /// TLS certificate settings #[derive(Debug, Clone, Serialize, Deserialize)] pub enum TLSSettings { RawPath { ca_path: String, cert_path: String, key_path: String, }, ZipPath { cert_zip_path: String, }, } impl Validate for MAuthSettings { fn validate(&self) -> Result<(), ValidationError> { match self { MAuthSettings::Tls(tls_settings) => tls_settings.validate()?, } Ok(()) } } impl Validate for TLSSettings { fn validate(&self) -> Result<(), ValidationError> { match self { TLSSettings::RawPath { ca_path, cert_path, key_path, } => { if !std::path::Path::new(ca_path).exists() { return Err(format!("CA file not found: {}", ca_path)); } if !std::path::Path::new(cert_path).exists() { return Err(format!("Certificate file not found: {}", cert_path)); } if !std::path::Path::new(key_path).exists() { return Err(format!("Key file not found: {}", key_path)); } } TLSSettings::ZipPath { cert_zip_path } => { if !std::path::Path::new(cert_zip_path).exists() { return Err(format!("Certificate zip file not found: {}", cert_zip_path)); } } } Ok(()) } } #[cfg(test)] mod tests { use std::{ fs, os::unix::fs::PermissionsExt, path::{Path, PathBuf}, }; use tempfile::TempDir; use super::*; #[test] fn test_esnure_send_and_sync() { fn assert_send_sync() {} assert_send_sync::(); } fn write_file(path: &Path) { let result = fs::write(path, b"content"); assert!(result.is_ok()); } fn create_exec_file(path: &Path) { write_file(path); let metadata = fs::metadata(path); assert!(metadata.is_ok()); let metadata = metadata.ok(); assert!(metadata.is_some()); let metadata = metadata.unwrap_or_else(|| unreachable!()); let mut perms = metadata.permissions(); perms.set_mode(0o755); let result = fs::set_permissions(path, perms); assert!(result.is_ok()); } fn create_non_exec_file(path: &Path) { write_file(path); let metadata = fs::metadata(path); assert!(metadata.is_ok()); let metadata = metadata.ok(); assert!(metadata.is_some()); let metadata = metadata.unwrap_or_else(|| unreachable!()); let mut perms = metadata.permissions(); perms.set_mode(0o644); let result = fs::set_permissions(path, perms); assert!(result.is_ok()); } fn valid_tls_raw_paths(temp_dir: &TempDir) -> (PathBuf, PathBuf, PathBuf) { let ca_path = temp_dir.path().join("ca.pem"); let cert_path = temp_dir.path().join("cert.pem"); let key_path = temp_dir.path().join("key.pem"); write_file(&ca_path); write_file(&cert_path); write_file(&key_path); (ca_path, cert_path, key_path) } #[test] fn tls_raw_path_validate_succeeds_when_all_files_exist() { let temp_dir = TempDir::new(); assert!(temp_dir.is_ok()); let temp_dir = temp_dir.ok(); assert!(temp_dir.is_some()); let temp_dir = temp_dir.unwrap_or_else(|| unreachable!()); let (ca_path, cert_path, key_path) = valid_tls_raw_paths(&temp_dir); let settings = TLSSettings::RawPath { ca_path: ca_path.to_string_lossy().to_string(), cert_path: cert_path.to_string_lossy().to_string(), key_path: key_path.to_string_lossy().to_string(), }; assert!(settings.validate().is_ok()); } #[test] fn tls_raw_path_validate_fails_when_ca_missing() { let settings = TLSSettings::RawPath { ca_path: "/tmp/does-not-exist-ca.pem".into(), cert_path: "/tmp/does-not-exist-cert.pem".into(), key_path: "/tmp/does-not-exist-key.pem".into(), }; let result = settings.validate(); assert!(result.is_err()); let msg = result.err().unwrap_or_else(|| unreachable!()); assert!(msg.contains("CA file not found")); } #[test] fn tls_zip_path_validate_fails_when_zip_missing() { let settings = TLSSettings::ZipPath { cert_zip_path: "/tmp/missing-certs.zip".into(), }; let result = settings.validate(); assert!(result.is_err()); let msg = result.err().unwrap_or_else(|| unreachable!()); assert!(msg.contains("Certificate zip file not found")); } }