1use std::sync::Arc;
24use std::fmt::Display;
25use once_cell::sync::OnceCell;
26use crate::{SaTokenManager, SaTokenResult, SaTokenError};
27use crate::token::{TokenValue, TokenInfo};
28use crate::session::SaSession;
29use crate::context::SaTokenContext;
30
31static GLOBAL_MANAGER: OnceCell<Arc<SaTokenManager>> = OnceCell::new();
33
34pub trait LoginId {
38 fn to_login_id(&self) -> String;
39}
40
41impl<T: Display> LoginId for T {
43 fn to_login_id(&self) -> String {
44 self.to_string()
45 }
46}
47
48pub struct StpUtil;
52
53impl StpUtil {
54 pub fn init_manager(manager: SaTokenManager) {
66 GLOBAL_MANAGER.set(Arc::new(manager))
67 .unwrap_or_else(|_| panic!("StpUtil manager already initialized"));
68 }
69
70 fn get_manager() -> &'static Arc<SaTokenManager> {
72 GLOBAL_MANAGER.get()
73 .expect("StpUtil not initialized. Call StpUtil::init_manager() first.")
74 }
75
76 pub async fn login(login_id: impl LoginId) -> SaTokenResult<TokenValue> {
90 Self::get_manager().login(login_id.to_login_id()).await
91 }
92
93 pub async fn login_with_manager(
95 manager: &SaTokenManager,
96 login_id: impl Into<String>,
97 ) -> SaTokenResult<TokenValue> {
98 manager.login(login_id).await
99 }
100
101 pub async fn logout(token: &TokenValue) -> SaTokenResult<()> {
103 Self::get_manager().logout(token).await
104 }
105
106 pub async fn logout_with_manager(
107 manager: &SaTokenManager,
108 token: &TokenValue,
109 ) -> SaTokenResult<()> {
110 manager.logout(token).await
111 }
112
113 pub async fn kick_out(login_id: impl LoginId) -> SaTokenResult<()> {
115 Self::get_manager().kick_out(&login_id.to_login_id()).await
116 }
117
118 pub async fn kick_out_with_manager(
119 manager: &SaTokenManager,
120 login_id: &str,
121 ) -> SaTokenResult<()> {
122 manager.kick_out(login_id).await
123 }
124
125 pub async fn logout_by_login_id(login_id: impl LoginId) -> SaTokenResult<()> {
127 Self::get_manager().logout_by_login_id(&login_id.to_login_id()).await
128 }
129
130 pub async fn logout_by_token(token: &TokenValue) -> SaTokenResult<()> {
132 Self::logout(token).await
133 }
134
135 pub fn get_token_value() -> SaTokenResult<TokenValue> {
145 let ctx = SaTokenContext::get_current()
146 .ok_or(SaTokenError::NotLogin)?;
147 ctx.token.ok_or(SaTokenError::NotLogin)
148 }
149
150 pub async fn logout_current() -> SaTokenResult<()> {
158 let token = Self::get_token_value()?;
159 Self::logout(&token).await
160 }
161
162 pub fn is_login_current() -> bool {
172 if let Ok(_token) = Self::get_token_value() {
173 true
176 } else {
177 false
178 }
179 }
180
181 pub fn check_login_current() -> SaTokenResult<()> {
189 Self::get_token_value()?;
190 Ok(())
191 }
192
193 pub fn get_login_id_as_string() -> SaTokenResult<String> {
201 let ctx = SaTokenContext::get_current()
202 .ok_or(SaTokenError::NotLogin)?;
203 ctx.login_id.ok_or(SaTokenError::NotLogin)
204 }
205
206 pub fn get_login_id_as_long() -> SaTokenResult<i64> {
214 let login_id_str = Self::get_login_id_as_string()?;
215 login_id_str.parse::<i64>()
216 .map_err(|_| SaTokenError::InvalidToken("Login ID is not a valid number".to_string()))
217 }
218
219 pub fn get_token_info_current() -> SaTokenResult<Arc<TokenInfo>> {
228 let ctx = SaTokenContext::get_current()
229 .ok_or(SaTokenError::NotLogin)?;
230 ctx.token_info.ok_or(SaTokenError::NotLogin)
231 }
232
233 pub async fn is_login(token: &TokenValue) -> bool {
237 Self::get_manager().is_valid(token).await
238 }
239
240 pub async fn is_login_by_login_id(login_id: impl LoginId) -> bool {
248 match Self::get_token_by_login_id(login_id).await {
249 Ok(token) => Self::is_login(&token).await,
250 Err(_) => false,
251 }
252 }
253
254 pub async fn is_login_with_manager(
255 manager: &SaTokenManager,
256 token: &TokenValue,
257 ) -> bool {
258 manager.is_valid(token).await
259 }
260
261 pub async fn check_login(token: &TokenValue) -> SaTokenResult<()> {
263 if !Self::is_login(token).await {
264 return Err(SaTokenError::NotLogin);
265 }
266 Ok(())
267 }
268
269 pub async fn get_token_info(token: &TokenValue) -> SaTokenResult<TokenInfo> {
271 Self::get_manager().get_token_info(token).await
272 }
273
274 pub async fn get_login_id(token: &TokenValue) -> SaTokenResult<String> {
276 let token_info = Self::get_manager().get_token_info(token).await?;
277 Ok(token_info.login_id)
278 }
279
280 pub async fn get_login_id_or_default(
282 token: &TokenValue,
283 default: impl Into<String>,
284 ) -> String {
285 Self::get_login_id(token)
286 .await
287 .unwrap_or_else(|_| default.into())
288 }
289
290 pub async fn get_token_by_login_id(login_id: impl LoginId) -> SaTokenResult<TokenValue> {
298 let manager = Self::get_manager();
299 let login_id_str = login_id.to_login_id();
300
301 let key = format!("sa:login:token:{}", login_id_str);
303 match manager.storage.get(&key).await {
304 Ok(Some(token_str)) => Ok(TokenValue::new(token_str)),
305 Ok(None) => Err(SaTokenError::NotLogin),
306 Err(e) => Err(SaTokenError::StorageError(e.to_string())),
307 }
308 }
309
310 pub async fn get_all_tokens_by_login_id(login_id: impl LoginId) -> SaTokenResult<Vec<TokenValue>> {
317 let manager = Self::get_manager();
318 let login_id_str = login_id.to_login_id();
319
320 let key = format!("sa:login:tokens:{}", login_id_str);
322 match manager.storage.get(&key).await {
323 Ok(Some(tokens_str)) => {
324 let token_strings: Vec<String> = serde_json::from_str(&tokens_str)
325 .map_err(|e| SaTokenError::SerializationError(e))?;
326 Ok(token_strings.into_iter().map(TokenValue::new).collect())
327 }
328 Ok(None) => Ok(Vec::new()),
329 Err(e) => Err(SaTokenError::StorageError(e.to_string())),
330 }
331 }
332
333 pub async fn get_session(login_id: impl LoginId) -> SaTokenResult<SaSession> {
337 Self::get_manager().get_session(&login_id.to_login_id()).await
338 }
339
340 pub async fn save_session(session: &SaSession) -> SaTokenResult<()> {
342 Self::get_manager().save_session(session).await
343 }
344
345 pub async fn delete_session(login_id: impl LoginId) -> SaTokenResult<()> {
347 Self::get_manager().delete_session(&login_id.to_login_id()).await
348 }
349
350 pub async fn set_session_value<T: serde::Serialize>(
352 login_id: impl LoginId,
353 key: &str,
354 value: T,
355 ) -> SaTokenResult<()> {
356 let manager = Self::get_manager();
357 let login_id_str = login_id.to_login_id();
358 let mut session = manager.get_session(&login_id_str).await?;
359 session.set(key, value)?;
360 manager.save_session(&session).await
361 }
362
363 pub async fn get_session_value<T: serde::de::DeserializeOwned>(
365 login_id: impl LoginId,
366 key: &str,
367 ) -> SaTokenResult<Option<T>> {
368 let session = Self::get_manager().get_session(&login_id.to_login_id()).await?;
369 Ok(session.get::<T>(key))
370 }
371
372 pub fn create_token(token_value: impl Into<String>) -> TokenValue {
376 TokenValue::new(token_value.into())
377 }
378
379 pub fn is_valid_token_format(token: &str) -> bool {
381 !token.is_empty() && token.len() >= 16
382 }
383}
384
385impl StpUtil {
388 pub async fn set_permissions(
390 login_id: impl LoginId,
391 permissions: Vec<String>,
392 ) -> SaTokenResult<()> {
393 let manager = Self::get_manager();
394 let mut map = manager.user_permissions.write().await;
395 map.insert(login_id.to_login_id(), permissions);
396 Ok(())
397 }
398
399 pub async fn add_permission(
401 login_id: impl LoginId,
402 permission: impl Into<String>,
403 ) -> SaTokenResult<()> {
404 let manager = Self::get_manager();
405 let mut map = manager.user_permissions.write().await;
406 let login_id_str = login_id.to_login_id();
407 let permissions = map.entry(login_id_str).or_insert_with(Vec::new);
408 let perm = permission.into();
409 if !permissions.contains(&perm) {
410 permissions.push(perm);
411 }
412 Ok(())
413 }
414
415 pub async fn remove_permission(
417 login_id: impl LoginId,
418 permission: &str,
419 ) -> SaTokenResult<()> {
420 let manager = Self::get_manager();
421 let mut map = manager.user_permissions.write().await;
422 if let Some(permissions) = map.get_mut(&login_id.to_login_id()) {
423 permissions.retain(|p| p != permission);
424 }
425 Ok(())
426 }
427
428 pub async fn clear_permissions(login_id: impl LoginId) -> SaTokenResult<()> {
430 let manager = Self::get_manager();
431 let mut map = manager.user_permissions.write().await;
432 map.remove(&login_id.to_login_id());
433 Ok(())
434 }
435
436 pub async fn get_permissions(login_id: impl LoginId) -> Vec<String> {
438 let manager = Self::get_manager();
439 let map = manager.user_permissions.read().await;
440 map.get(&login_id.to_login_id()).cloned().unwrap_or_default()
441 }
442
443 pub async fn has_permission(
445 login_id: impl LoginId,
446 permission: &str,
447 ) -> bool {
448 let manager = Self::get_manager();
449 let map = manager.user_permissions.read().await;
450 if let Some(permissions) = map.get(&login_id.to_login_id()) {
451 if permissions.contains(&permission.to_string()) {
453 return true;
454 }
455
456 for perm in permissions {
458 if perm.ends_with(":*") {
459 let prefix = &perm[..perm.len() - 2];
460 if permission.starts_with(prefix) {
461 return true;
462 }
463 }
464 }
465 }
466 false
467 }
468
469 pub async fn has_all_permissions(
471 login_id: impl LoginId,
472 permissions: &[&str],
473 ) -> bool {
474 let login_id_str = login_id.to_login_id();
475 for permission in permissions {
476 if !Self::has_permission(&login_id_str, permission).await {
477 return false;
478 }
479 }
480 true
481 }
482
483 pub async fn has_permissions_and(
485 login_id: impl LoginId,
486 permissions: &[&str],
487 ) -> bool {
488 Self::has_all_permissions(login_id, permissions).await
489 }
490
491 pub async fn has_any_permission(
493 login_id: impl LoginId,
494 permissions: &[&str],
495 ) -> bool {
496 let login_id_str = login_id.to_login_id();
497 for permission in permissions {
498 if Self::has_permission(&login_id_str, permission).await {
499 return true;
500 }
501 }
502 false
503 }
504
505 pub async fn has_permissions_or(
507 login_id: impl LoginId,
508 permissions: &[&str],
509 ) -> bool {
510 Self::has_any_permission(login_id, permissions).await
511 }
512
513 pub async fn check_permission(
515 login_id: impl LoginId,
516 permission: &str,
517 ) -> SaTokenResult<()> {
518 if !Self::has_permission(login_id, permission).await {
519 return Err(SaTokenError::PermissionDenied(permission.to_string()));
520 }
521 Ok(())
522 }
523}
524
525impl StpUtil {
528 pub async fn set_roles(
530 login_id: impl LoginId,
531 roles: Vec<String>,
532 ) -> SaTokenResult<()> {
533 let manager = Self::get_manager();
534 let mut map = manager.user_roles.write().await;
535 map.insert(login_id.to_login_id(), roles);
536 Ok(())
537 }
538
539 pub async fn add_role(
541 login_id: impl LoginId,
542 role: impl Into<String>,
543 ) -> SaTokenResult<()> {
544 let manager = Self::get_manager();
545 let mut map = manager.user_roles.write().await;
546 let login_id_str = login_id.to_login_id();
547 let roles = map.entry(login_id_str).or_insert_with(Vec::new);
548 let r = role.into();
549 if !roles.contains(&r) {
550 roles.push(r);
551 }
552 Ok(())
553 }
554
555 pub async fn remove_role(
557 login_id: impl LoginId,
558 role: &str,
559 ) -> SaTokenResult<()> {
560 let manager = Self::get_manager();
561 let mut map = manager.user_roles.write().await;
562 if let Some(roles) = map.get_mut(&login_id.to_login_id()) {
563 roles.retain(|r| r != role);
564 }
565 Ok(())
566 }
567
568 pub async fn clear_roles(login_id: impl LoginId) -> SaTokenResult<()> {
570 let manager = Self::get_manager();
571 let mut map = manager.user_roles.write().await;
572 map.remove(&login_id.to_login_id());
573 Ok(())
574 }
575
576 pub async fn get_roles(login_id: impl LoginId) -> Vec<String> {
578 let manager = Self::get_manager();
579 let map = manager.user_roles.read().await;
580 map.get(&login_id.to_login_id()).cloned().unwrap_or_default()
581 }
582
583 pub async fn has_role(
585 login_id: impl LoginId,
586 role: &str,
587 ) -> bool {
588 let manager = Self::get_manager();
589 let map = manager.user_roles.read().await;
590 if let Some(roles) = map.get(&login_id.to_login_id()) {
591 roles.contains(&role.to_string())
592 } else {
593 false
594 }
595 }
596
597 pub async fn has_all_roles(
599 login_id: impl LoginId,
600 roles: &[&str],
601 ) -> bool {
602 let login_id_str = login_id.to_login_id();
603 for role in roles {
604 if !Self::has_role(&login_id_str, role).await {
605 return false;
606 }
607 }
608 true
609 }
610
611 pub async fn has_roles_and(
613 login_id: impl LoginId,
614 roles: &[&str],
615 ) -> bool {
616 Self::has_all_roles(login_id, roles).await
617 }
618
619 pub async fn has_any_role(
621 login_id: impl LoginId,
622 roles: &[&str],
623 ) -> bool {
624 let login_id_str = login_id.to_login_id();
625 for role in roles {
626 if Self::has_role(&login_id_str, role).await {
627 return true;
628 }
629 }
630 false
631 }
632
633 pub async fn has_roles_or(
635 login_id: impl LoginId,
636 roles: &[&str],
637 ) -> bool {
638 Self::has_any_role(login_id, roles).await
639 }
640
641 pub async fn check_role(
643 login_id: impl LoginId,
644 role: &str,
645 ) -> SaTokenResult<()> {
646 if !Self::has_role(login_id, role).await {
647 return Err(SaTokenError::RoleDenied(role.to_string()));
648 }
649 Ok(())
650 }
651}
652
653impl StpUtil {
656 pub async fn kick_out_batch<T: LoginId>(
658 login_ids: &[T],
659 ) -> SaTokenResult<Vec<Result<(), SaTokenError>>> {
660 let manager = Self::get_manager();
661 let mut results = Vec::new();
662 for login_id in login_ids {
663 results.push(manager.kick_out(&login_id.to_login_id()).await);
664 }
665 Ok(results)
666 }
667
668 pub async fn get_token_timeout(token: &TokenValue) -> SaTokenResult<Option<i64>> {
670 let manager = Self::get_manager();
671 let token_info = manager.get_token_info(token).await?;
672
673 if let Some(expire_time) = token_info.expire_time {
674 let now = chrono::Utc::now();
675 let duration = expire_time.signed_duration_since(now);
676 Ok(Some(duration.num_seconds()))
677 } else {
678 Ok(None) }
680 }
681
682 pub async fn renew_timeout(
684 token: &TokenValue,
685 timeout_seconds: i64,
686 ) -> SaTokenResult<()> {
687 let manager = Self::get_manager();
688 let mut token_info = manager.get_token_info(token).await?;
689
690 let new_expire_time = chrono::Utc::now() + chrono::Duration::seconds(timeout_seconds);
692 token_info.expire_time = Some(new_expire_time);
693
694 let key = format!("sa:token:{}", token.as_str());
696 let value = serde_json::to_string(&token_info)
697 .map_err(|e| SaTokenError::SerializationError(e))?;
698
699 let timeout = std::time::Duration::from_secs(timeout_seconds as u64);
700 manager.storage.set(&key, &value, Some(timeout)).await
701 .map_err(|e| SaTokenError::StorageError(e.to_string()))?;
702
703 Ok(())
704 }
705}
706
707#[cfg(test)]
708mod tests {
709 use super::*;
710
711 #[test]
712 fn test_token_format_validation() {
713 assert!(StpUtil::is_valid_token_format("1234567890abcdef"));
714 assert!(!StpUtil::is_valid_token_format(""));
715 assert!(!StpUtil::is_valid_token_format("short"));
716 }
717
718 #[test]
719 fn test_create_token() {
720 let token = StpUtil::create_token("test-token-123");
721 assert_eq!(token.as_str(), "test-token-123");
722 }
723}