auth_framework/server/core/
common_config.rs1use crate::errors::Result;
7use serde::{Deserialize, Serialize};
8use std::collections::HashMap;
9use std::time::Duration;
10
11pub trait ServerConfig {
13 fn validate(&self) -> Result<()> {
15 Ok(())
16 }
17
18 fn config_name(&self) -> &'static str;
20
21 fn is_enabled(&self) -> bool {
23 true
24 }
25}
26
27#[derive(Debug, Clone, Serialize, Deserialize)]
29pub struct TimeoutConfig {
30 pub connect_timeout: Duration,
32 pub read_timeout: Duration,
34 pub write_timeout: Duration,
36}
37
38impl Default for TimeoutConfig {
39 fn default() -> Self {
40 Self {
41 connect_timeout: Duration::from_secs(30),
42 read_timeout: Duration::from_secs(30),
43 write_timeout: Duration::from_secs(30),
44 }
45 }
46}
47
48#[derive(Debug, Clone, Serialize, Deserialize)]
50pub struct SecurityConfig {
51 pub enable_tls: bool,
53 pub min_tls_version: String,
55 pub cipher_suites: Vec<String>,
57 pub cert_validation: CertificateValidation,
59 pub verify_certificates: bool,
61}
62
63impl Default for SecurityConfig {
64 fn default() -> Self {
65 Self {
66 enable_tls: true,
67 min_tls_version: "1.2".to_string(),
68 cipher_suites: vec![
69 "TLS_AES_256_GCM_SHA384".to_string(),
70 "TLS_CHACHA20_POLY1305_SHA256".to_string(),
71 "TLS_AES_128_GCM_SHA256".to_string(),
72 ],
73 cert_validation: CertificateValidation::Full,
74 verify_certificates: true,
75 }
76 }
77}
78
79#[derive(Debug, Clone, Serialize, Deserialize)]
81pub enum CertificateValidation {
82 Full,
84 SkipHostname,
86 None,
88}
89
90#[derive(Debug, Clone, Serialize, Deserialize)]
92pub struct EndpointConfig {
93 pub base_url: String,
95 pub api_version: Option<String>,
97 pub headers: HashMap<String, String>,
99 pub timeout: TimeoutConfig,
101 pub security: SecurityConfig,
103}
104
105impl EndpointConfig {
106 pub fn new(base_url: impl Into<String>) -> Self {
108 Self {
109 base_url: base_url.into(),
110 api_version: None,
111 headers: HashMap::new(),
112 timeout: TimeoutConfig::default(),
113 security: SecurityConfig::default(),
114 }
115 }
116
117 pub fn with_header(mut self, key: impl Into<String>, value: impl Into<String>) -> Self {
119 self.headers.insert(key.into(), value.into());
120 self
121 }
122
123 pub fn with_api_version(mut self, version: impl Into<String>) -> Self {
125 self.api_version = Some(version.into());
126 self
127 }
128}
129
130#[derive(Debug, Clone, Serialize, Deserialize)]
132pub struct RetryConfig {
133 pub max_attempts: u32,
135 pub initial_delay: Duration,
137 pub max_delay: Duration,
139 pub backoff_multiplier: f64,
141 pub jitter_factor: f64,
143}
144
145impl Default for RetryConfig {
146 fn default() -> Self {
147 Self {
148 max_attempts: 3,
149 initial_delay: Duration::from_millis(100),
150 max_delay: Duration::from_secs(30),
151 backoff_multiplier: 2.0,
152 jitter_factor: 0.1,
153 }
154 }
155}
156
157#[derive(Debug, Clone, Serialize, Deserialize)]
159pub struct LoggingConfig {
160 pub debug: bool,
162 pub log_bodies: bool,
164 pub log_sensitive: bool,
166 pub max_log_size: usize,
168}
169
170impl Default for LoggingConfig {
171 fn default() -> Self {
172 Self {
173 debug: false,
174 log_bodies: false,
175 log_sensitive: false,
176 max_log_size: 4096,
177 }
178 }
179}
180
181pub mod validation {
183 use super::*;
184
185 pub fn validate_url(url: &str) -> Result<()> {
187 if url.is_empty() {
188 return Err(crate::errors::AuthError::ConfigurationError(
189 "URL cannot be empty".to_string(),
190 ));
191 }
192
193 if !url.starts_with("http://") && !url.starts_with("https://") {
194 return Err(crate::errors::AuthError::ConfigurationError(format!(
195 "Invalid URL format: {}",
196 url
197 )));
198 }
199
200 Ok(())
201 }
202
203 pub fn validate_positive_duration(duration: &Duration, field_name: &str) -> Result<()> {
205 if duration.is_zero() {
206 return Err(crate::errors::AuthError::ConfigurationError(format!(
207 "{} must be greater than zero",
208 field_name
209 )));
210 }
211 Ok(())
212 }
213
214 pub fn validate_port(port: u16) -> Result<()> {
216 if port == 0 {
217 return Err(crate::errors::AuthError::ConfigurationError(
218 "Port cannot be zero".to_string(),
219 ));
220 }
221 Ok(())
222 }
223
224 pub fn validate_required_field(value: &str, field_name: &str) -> Result<()> {
226 if value.trim().is_empty() {
227 return Err(crate::errors::AuthError::ConfigurationError(format!(
228 "{} is required and cannot be empty",
229 field_name
230 )));
231 }
232 Ok(())
233 }
234}
235
236