1use std::time::Duration;
6use std::sync::Arc;
7use serde::{Deserialize, Serialize};
8use sa_token_adapter::storage::SaStorage;
9use crate::event::SaTokenListener;
10
11#[derive(Debug, Clone, Serialize, Deserialize)]
13pub struct SaTokenConfig {
14 pub token_name: String,
16
17 pub timeout: i64,
19
20 pub active_timeout: i64,
24
25 pub dynamic_active_timeout: bool,
27
28 pub auto_renew: bool,
39
40 pub is_concurrent: bool,
42
43 pub is_share: bool,
45
46 pub token_style: TokenStyle,
48
49 pub is_log: bool,
51
52 pub is_read_cookie: bool,
54
55 pub is_read_header: bool,
57
58 pub is_read_body: bool,
60
61 pub jwt_secret_key: Option<String>,
63
64 pub jwt_algorithm: Option<String>,
66
67 pub jwt_issuer: Option<String>,
69
70 pub jwt_audience: Option<String>,
72
73 pub jwt_fallback_on_error: bool,
75
76 pub enable_nonce: bool,
78
79 pub nonce_timeout: i64,
81
82 pub enable_refresh_token: bool,
84
85 pub refresh_token_timeout: i64,
87
88 pub storage_key_prefix: String,
92
93 pub max_login_count: i64,
95
96 pub overflow_logout_mode: LogoutMode,
98
99 pub replaced_login_exit_mode: ReplacedLoginExitMode,
101
102 pub replaced_range: ReplacedRange,
104
105 pub right_now_create_token_session: bool,
107
108 pub token_session_check_login: bool,
110
111 pub logout_range: LogoutRange,
113
114 pub is_logout_keep_token_session: bool,
116}
117
118impl Default for SaTokenConfig {
119 fn default() -> Self {
120 Self {
121 token_name: "sa-token".to_string(),
122 timeout: 2592000, active_timeout: -1,
124 dynamic_active_timeout: false,
125 auto_renew: true,
126 is_concurrent: true,
127 is_share: false,
128 token_style: TokenStyle::Uuid,
129 is_log: false,
130 is_read_cookie: true,
131 is_read_header: true,
132 is_read_body: true,
133 jwt_secret_key: None,
134 jwt_algorithm: Some("HS256".to_string()),
135 jwt_issuer: None,
136 jwt_audience: None,
137 jwt_fallback_on_error: true,
138 enable_nonce: false,
139 nonce_timeout: -1,
140 enable_refresh_token: false,
141 refresh_token_timeout: 604800, storage_key_prefix: "sa:".to_string(),
143 max_login_count: -1,
144 overflow_logout_mode: LogoutMode::Logout,
145 replaced_login_exit_mode: ReplacedLoginExitMode::OldDevice,
146 replaced_range: ReplacedRange::CurrDeviceType,
147 right_now_create_token_session: false,
148 token_session_check_login: true,
149 logout_range: LogoutRange::Token,
150 is_logout_keep_token_session: false,
151 }
152 }
153}
154
155impl SaTokenConfig {
156 pub fn builder() -> SaTokenConfigBuilder {
157 SaTokenConfigBuilder::default()
158 }
159
160 pub fn timeout_duration(&self) -> Option<Duration> {
161 if self.timeout < 0 {
162 None
163 } else {
164 Some(Duration::from_secs(self.timeout as u64))
165 }
166 }
167
168 pub fn make_key(&self, suffix: &str, id: &str) -> String {
171 format!("{}{}{}", self.storage_key_prefix, suffix, id)
172 }
173
174 pub fn key_prefix(&self) -> &str {
176 &self.storage_key_prefix
177 }
178}
179
180#[derive(Debug, Clone, Copy, Serialize, Deserialize)]
182pub enum TokenStyle {
183 Uuid,
185 SimpleUuid,
187 Random32,
189 Random64,
191 Random128,
193 Jwt,
195 Hash,
197 Timestamp,
199 Tik,
201}
202
203#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize, Default)]
205pub enum LogoutMode {
206 #[default]
207 Logout,
208 KickOut,
209 Replaced,
210}
211
212#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize, Default)]
214pub enum ReplacedLoginExitMode {
215 #[default]
216 OldDevice,
217 NewDevice,
218}
219
220#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize, Default)]
222pub enum ReplacedRange {
223 #[default]
224 CurrDeviceType,
225 AllDeviceType,
226}
227
228#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize, Default)]
230pub enum LogoutRange {
231 #[default]
232 Token,
233 Account,
234}
235
236#[derive(Default)]
238pub struct SaTokenConfigBuilder {
239 config: SaTokenConfig,
240 storage: Option<Arc<dyn SaStorage>>,
241 listeners: Vec<Arc<dyn SaTokenListener>>,
242}
243
244
245impl SaTokenConfigBuilder {
246 pub fn token_name(mut self, name: impl Into<String>) -> Self {
247 self.config.token_name = name.into();
248 self
249 }
250
251 pub fn timeout(mut self, timeout: i64) -> Self {
252 self.config.timeout = timeout;
253 self
254 }
255
256 pub fn active_timeout(mut self, timeout: i64) -> Self {
257 self.config.active_timeout = timeout;
258 self
259 }
260
261 pub fn dynamic_active_timeout(mut self, enabled: bool) -> Self {
263 self.config.dynamic_active_timeout = enabled;
264 self
265 }
266
267 pub fn auto_renew(mut self, enabled: bool) -> Self {
269 self.config.auto_renew = enabled;
270 self
271 }
272
273 pub fn is_concurrent(mut self, concurrent: bool) -> Self {
274 self.config.is_concurrent = concurrent;
275 self
276 }
277
278 pub fn is_share(mut self, share: bool) -> Self {
279 self.config.is_share = share;
280 self
281 }
282
283 pub fn token_style(mut self, style: TokenStyle) -> Self {
284 self.config.token_style = style;
285 self
286 }
287
288
289 pub fn storage_key_prefix(mut self, prefix: impl Into<String>) -> Self {
294 self.config.storage_key_prefix = prefix.into();
295 self
296 }
297
298 pub fn jwt_secret_key(mut self, key: impl Into<String>) -> Self {
299 self.config.jwt_secret_key = Some(key.into());
300 self
301 }
302
303 pub fn jwt_algorithm(mut self, algorithm: impl Into<String>) -> Self {
305 self.config.jwt_algorithm = Some(algorithm.into());
306 self
307 }
308
309 pub fn jwt_issuer(mut self, issuer: impl Into<String>) -> Self {
311 self.config.jwt_issuer = Some(issuer.into());
312 self
313 }
314
315 pub fn jwt_audience(mut self, audience: impl Into<String>) -> Self {
317 self.config.jwt_audience = Some(audience.into());
318 self
319 }
320
321 pub fn jwt_fallback_on_error(mut self, fallback: bool) -> Self {
322 self.config.jwt_fallback_on_error = fallback;
323 self
324 }
325
326 pub fn enable_nonce(mut self, enable: bool) -> Self {
328 self.config.enable_nonce = enable;
329 self
330 }
331
332 pub fn nonce_timeout(mut self, timeout: i64) -> Self {
334 self.config.nonce_timeout = timeout;
335 self
336 }
337
338 pub fn enable_refresh_token(mut self, enable: bool) -> Self {
340 self.config.enable_refresh_token = enable;
341 self
342 }
343
344 pub fn refresh_token_timeout(mut self, timeout: i64) -> Self {
346 self.config.refresh_token_timeout = timeout;
347 self
348 }
349
350 pub fn max_login_count(mut self, count: i64) -> Self {
351 self.config.max_login_count = count;
352 self
353 }
354
355 pub fn overflow_logout_mode(mut self, mode: LogoutMode) -> Self {
356 self.config.overflow_logout_mode = mode;
357 self
358 }
359
360 pub fn replaced_login_exit_mode(mut self, mode: ReplacedLoginExitMode) -> Self {
361 self.config.replaced_login_exit_mode = mode;
362 self
363 }
364
365 pub fn replaced_range(mut self, range: ReplacedRange) -> Self {
366 self.config.replaced_range = range;
367 self
368 }
369
370 pub fn right_now_create_token_session(mut self, enabled: bool) -> Self {
371 self.config.right_now_create_token_session = enabled;
372 self
373 }
374
375 pub fn token_session_check_login(mut self, enabled: bool) -> Self {
376 self.config.token_session_check_login = enabled;
377 self
378 }
379
380 pub fn logout_range(mut self, range: LogoutRange) -> Self {
381 self.config.logout_range = range;
382 self
383 }
384
385 pub fn is_logout_keep_token_session(mut self, keep: bool) -> Self {
386 self.config.is_logout_keep_token_session = keep;
387 self
388 }
389
390 pub fn storage(mut self, storage: Arc<dyn SaStorage>) -> Self {
392 self.storage = Some(storage);
393 self
394 }
395
396 pub fn register_listener(mut self, listener: Arc<dyn SaTokenListener>) -> Self {
414 self.listeners.push(listener);
415 self
416 }
417
418 pub fn build(self) -> crate::SaTokenManager {
448 let storage = self.storage.expect("Storage must be set before building SaTokenManager. Use .storage() method.");
449 let manager = crate::SaTokenManager::new(storage, self.config);
450
451 if !self.listeners.is_empty() {
454 let event_bus = manager.event_bus();
455 for listener in self.listeners {
456 event_bus.register(listener);
457 }
458 }
459
460 crate::StpUtil::init_manager(manager.clone());
463
464 manager
465 }
466
467 pub fn build_config(self) -> SaTokenConfig {
469 self.config
470 }
471}