webgates_sessions/
config.rs1use std::time::Duration;
7
8use crate::errors::ConfigError;
9use crate::lease::LeaseTtl;
10
11pub type ConfigResult<T> = std::result::Result<T, ConfigError>;
13
14#[derive(Debug, Clone, PartialEq, Eq)]
45pub struct SessionConfig {
46 pub auth_token_ttl: Duration,
48 pub refresh_token_ttl: Duration,
50 pub proactive_renewal_window: Duration,
53 pub renewal_lease_ttl: LeaseTtl,
55 pub clock_skew_tolerance: Duration,
57}
58
59impl SessionConfig {
60 #[must_use]
62 pub const fn new(
63 auth_token_ttl: Duration,
64 refresh_token_ttl: Duration,
65 proactive_renewal_window: Duration,
66 renewal_lease_ttl: LeaseTtl,
67 clock_skew_tolerance: Duration,
68 ) -> Self {
69 Self {
70 auth_token_ttl,
71 refresh_token_ttl,
72 proactive_renewal_window,
73 renewal_lease_ttl,
74 clock_skew_tolerance,
75 }
76 }
77
78 #[must_use]
80 pub fn renewal_lease_duration(&self) -> Duration {
81 self.renewal_lease_ttl.duration()
82 }
83
84 pub fn validate(self) -> ConfigResult<Self> {
93 if self.auth_token_ttl.is_zero()
94 || self.refresh_token_ttl.is_zero()
95 || self.renewal_lease_duration().is_zero()
96 {
97 return Err(ConfigError::Invalid);
98 }
99
100 if self.proactive_renewal_window > self.auth_token_ttl {
101 return Err(ConfigError::Invalid);
102 }
103
104 Ok(self)
105 }
106
107 #[must_use]
109 pub fn is_valid(&self) -> bool {
110 self.clone().validate().is_ok()
111 }
112}
113
114impl Default for SessionConfig {
115 fn default() -> Self {
116 Self {
117 auth_token_ttl: Duration::from_secs(15 * 60),
118 refresh_token_ttl: Duration::from_secs(30 * 24 * 60 * 60),
119 proactive_renewal_window: Duration::from_secs(2 * 60),
120 renewal_lease_ttl: LeaseTtl::default(),
121 clock_skew_tolerance: Duration::from_secs(5),
122 }
123 }
124}
125
126#[cfg(test)]
127mod tests {
128 use super::SessionConfig;
129 use crate::lease::LeaseTtl;
130 use std::time::Duration;
131
132 #[test]
133 fn default_config_is_valid() {
134 assert!(SessionConfig::default().is_valid());
135 }
136
137 #[test]
138 fn config_exposes_typed_lease_duration() {
139 let config = SessionConfig::default();
140
141 assert_eq!(
142 config.renewal_lease_duration(),
143 LeaseTtl::default().duration()
144 );
145 }
146
147 #[test]
148 fn config_is_invalid_when_proactive_window_exceeds_auth_ttl() {
149 let config = SessionConfig::new(
150 Duration::from_secs(60),
151 Duration::from_secs(3600),
152 Duration::from_secs(61),
153 LeaseTtl::new(Duration::from_secs(30)),
154 Duration::from_secs(5),
155 );
156
157 assert!(!config.is_valid());
158 }
159
160 #[test]
161 fn config_is_invalid_when_required_durations_are_zero() {
162 let config = SessionConfig::new(
163 Duration::ZERO,
164 Duration::from_secs(3600),
165 Duration::ZERO,
166 LeaseTtl::new(Duration::from_secs(30)),
167 Duration::from_secs(5),
168 );
169
170 assert!(!config.is_valid());
171 }
172
173 #[test]
174 fn config_is_invalid_when_lease_ttl_is_zero() {
175 let config = SessionConfig::new(
176 Duration::from_secs(60),
177 Duration::from_secs(3600),
178 Duration::from_secs(30),
179 LeaseTtl::new(Duration::ZERO),
180 Duration::from_secs(5),
181 );
182
183 assert!(!config.is_valid());
184 }
185}