1use crate::validation::ValidationConfig;
2use serde::{Deserialize, Serialize};
3
4#[derive(Debug, Clone, Serialize, Deserialize)]
6pub struct AuthConfig {
7 #[serde(default = "default_leeway")]
9 pub leeway_seconds: i64,
10
11 #[serde(default)]
13 pub issuers: Vec<String>,
14
15 #[serde(default)]
17 pub audiences: Vec<String>,
18
19 #[serde(default)]
21 pub jwks: Option<JwksConfig>,
22}
23
24fn default_leeway() -> i64 {
25 60
26}
27
28impl Default for AuthConfig {
29 fn default() -> Self {
30 Self {
31 leeway_seconds: 60,
32 issuers: Vec::new(),
33 audiences: Vec::new(),
34 jwks: None,
35 }
36 }
37}
38
39impl From<&AuthConfig> for ValidationConfig {
40 fn from(config: &AuthConfig) -> Self {
41 Self {
42 allowed_issuers: config.issuers.clone(),
43 allowed_audiences: config.audiences.clone(),
44 leeway_seconds: config.leeway_seconds,
45 }
46 }
47}
48
49#[derive(Debug, Clone, Serialize, Deserialize)]
51pub struct JwksConfig {
52 pub uri: String,
54
55 #[serde(default = "default_refresh_interval")]
57 pub refresh_interval_seconds: u64,
58
59 #[serde(default = "default_max_backoff")]
61 pub max_backoff_seconds: u64,
62}
63
64fn default_refresh_interval() -> u64 {
65 300
66}
67
68fn default_max_backoff() -> u64 {
69 3600
70}
71
72#[cfg(test)]
73#[cfg_attr(coverage_nightly, coverage(off))]
74mod tests {
75 use super::*;
76
77 #[test]
78 fn test_default_config() {
79 let config = AuthConfig::default();
80 assert_eq!(config.leeway_seconds, 60);
81 assert!(config.issuers.is_empty());
82 assert!(config.audiences.is_empty());
83 assert!(config.jwks.is_none());
84 }
85
86 #[test]
87 fn test_auth_config_serialization() {
88 let config = AuthConfig {
89 leeway_seconds: 120,
90 issuers: vec!["https://auth.example.com".to_owned()],
91 audiences: vec!["api".to_owned()],
92 jwks: Some(JwksConfig {
93 uri: "https://auth.example.com/.well-known/jwks.json".to_owned(),
94 refresh_interval_seconds: 300,
95 max_backoff_seconds: 3600,
96 }),
97 };
98
99 let json = serde_json::to_string_pretty(&config).unwrap();
100 let deserialized: AuthConfig = serde_json::from_str(&json).unwrap();
101 assert_eq!(deserialized.leeway_seconds, 120);
102 assert_eq!(deserialized.issuers, vec!["https://auth.example.com"]);
103 assert_eq!(deserialized.audiences, vec!["api"]);
104 let jwks = deserialized.jwks.expect("jwks should be present");
105 assert_eq!(jwks.uri, "https://auth.example.com/.well-known/jwks.json");
106 assert_eq!(jwks.refresh_interval_seconds, 300);
107 assert_eq!(jwks.max_backoff_seconds, 3600);
108 }
109
110 #[test]
111 fn test_jwks_config_serialization() {
112 let config = JwksConfig {
113 uri: "https://auth.example.com/.well-known/jwks.json".to_owned(),
114 refresh_interval_seconds: 300,
115 max_backoff_seconds: 3600,
116 };
117
118 let json = serde_json::to_string_pretty(&config).unwrap();
119 let deserialized: JwksConfig = serde_json::from_str(&json).unwrap();
120 assert_eq!(deserialized.uri, config.uri);
121 assert_eq!(
122 deserialized.refresh_interval_seconds,
123 config.refresh_interval_seconds
124 );
125 assert_eq!(deserialized.max_backoff_seconds, config.max_backoff_seconds);
126 }
127
128 #[test]
129 fn test_auth_config_to_validation_config() {
130 let auth_config = AuthConfig {
131 leeway_seconds: 30,
132 issuers: vec!["https://auth.example.com".to_owned()],
133 audiences: vec!["api".to_owned()],
134 jwks: None,
135 };
136 let validation_config = ValidationConfig::from(&auth_config);
137 assert_eq!(validation_config.allowed_issuers, auth_config.issuers);
138 assert_eq!(validation_config.allowed_audiences, auth_config.audiences);
139 assert_eq!(validation_config.leeway_seconds, auth_config.leeway_seconds);
140 }
141
142 #[test]
143 fn test_jwks_config_defaults() {
144 let json = r#"{"uri": "https://example.com/jwks"}"#;
145 let config: JwksConfig = serde_json::from_str(json).unwrap();
146 assert_eq!(config.refresh_interval_seconds, 300);
147 assert_eq!(config.max_backoff_seconds, 3600);
148 }
149}