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;
30use crate::event::{SaTokenEventBus, SaTokenListener};
31
32static GLOBAL_MANAGER: OnceCell<Arc<SaTokenManager>> = OnceCell::new();
34
35pub trait LoginId {
39 fn to_login_id(&self) -> String;
40}
41
42impl<T: Display> LoginId for T {
44 fn to_login_id(&self) -> String {
45 self.to_string()
46 }
47}
48
49pub struct StpUtil;
53
54impl StpUtil {
55 pub fn init_manager(manager: SaTokenManager) {
67 GLOBAL_MANAGER.set(Arc::new(manager))
68 .unwrap_or_else(|_| panic!("StpUtil manager already initialized"));
69 }
70
71 fn get_manager() -> &'static Arc<SaTokenManager> {
73 GLOBAL_MANAGER.get()
74 .expect("StpUtil not initialized. Call StpUtil::init_manager() first.")
75 }
76
77 pub fn event_bus() -> &'static SaTokenEventBus {
97 &Self::get_manager().event_bus
98 }
99
100 pub fn register_listener(listener: Arc<dyn SaTokenListener>) {
107 Self::event_bus().register(listener);
108 }
109
110 pub async fn login(login_id: impl LoginId) -> SaTokenResult<TokenValue> {
124 Self::get_manager().login(login_id.to_login_id()).await
125 }
126
127 pub async fn login_with_type(login_id: impl LoginId, _login_type: impl Into<String>) -> SaTokenResult<TokenValue> {
128 Self::get_manager().login(login_id.to_login_id()).await
129 }
130
131 pub async fn login_with_extra(
137 login_id: impl LoginId,
138 extra_data: serde_json::Value,
139 ) -> SaTokenResult<TokenValue> {
140 Self::get_manager().login_with_options(
141 login_id.to_login_id(),
142 None, None, Some(extra_data),
145 None, None, ).await
148 }
149
150 pub async fn login_with_manager(
152 manager: &SaTokenManager,
153 login_id: impl Into<String>,
154 ) -> SaTokenResult<TokenValue> {
155 manager.login(login_id).await
156 }
157
158 pub async fn logout(token: &TokenValue) -> SaTokenResult<()> {
160 tracing::debug!("开始执行 logout,token: {}", token);
161 let result = Self::get_manager().logout(token).await;
162 match &result {
163 Ok(_) => tracing::debug!("logout 执行成功,token: {}", token),
164 Err(e) => tracing::debug!("logout 执行失败,token: {}, 错误: {}", token, e),
165 }
166 result
167 }
168
169 pub async fn logout_with_manager(
170 manager: &SaTokenManager,
171 token: &TokenValue,
172 ) -> SaTokenResult<()> {
173 manager.logout(token).await
174 }
175
176 pub async fn kick_out(login_id: impl LoginId) -> SaTokenResult<()> {
178 Self::get_manager().kick_out(&login_id.to_login_id()).await
179 }
180
181 pub async fn kick_out_with_manager(
182 manager: &SaTokenManager,
183 login_id: &str,
184 ) -> SaTokenResult<()> {
185 manager.kick_out(login_id).await
186 }
187
188 pub async fn logout_by_login_id(login_id: impl LoginId) -> SaTokenResult<()> {
190 Self::get_manager().logout_by_login_id(&login_id.to_login_id()).await
191 }
192
193 pub async fn logout_by_token(token: &TokenValue) -> SaTokenResult<()> {
195 Self::logout(token).await
196 }
197
198 pub fn get_token_value() -> SaTokenResult<TokenValue> {
208 let ctx = SaTokenContext::try_current().ok_or(SaTokenError::NotLogin)?;
209 ctx.token.ok_or(SaTokenError::NotLogin)
210 }
211
212 pub async fn logout_current() -> SaTokenResult<()> {
220 let token = Self::get_token_value()?;
221 tracing::debug!("成功获取 token: {}", token);
222
223 let result = Self::logout(&token).await;
224 match &result {
225 Ok(_) => tracing::debug!("logout_current 执行成功,token: {}", token),
226 Err(e) => tracing::debug!("logout_current 执行失败,token: {}, 错误: {}", token, e),
227 }
228 result
229 }
230
231 pub fn is_login_current() -> bool {
241 if let Ok(_token) = Self::get_token_value() {
242 true
245 } else {
246 false
247 }
248 }
249
250 pub fn check_login_current() -> SaTokenResult<()> {
258 Self::get_token_value()?;
259 Ok(())
260 }
261
262 pub async fn get_login_id_as_string() -> SaTokenResult<String> {
270 let token = Self::get_token_value()?;
271 Self::get_login_id(&token).await
272 }
273
274 pub async fn get_login_id_as_long() -> SaTokenResult<i64> {
282 let login_id_str = Self::get_login_id_as_string().await?;
283 login_id_str.parse::<i64>()
284 .map_err(|_| SaTokenError::LoginIdNotNumber)
285 }
286
287 pub fn get_token_info_current() -> SaTokenResult<Arc<TokenInfo>> {
296 let ctx = SaTokenContext::try_current().ok_or(SaTokenError::NotLogin)?;
297 ctx.token_info.ok_or(SaTokenError::NotLogin)
298 }
299
300 pub async fn is_login(token: &TokenValue) -> bool {
304 Self::get_manager().is_valid(token).await
305 }
306
307 pub async fn is_login_by_login_id(login_id: impl LoginId) -> bool {
315 match Self::get_token_by_login_id(login_id).await {
316 Ok(token) => Self::is_login(&token).await,
317 Err(_) => false,
318 }
319 }
320
321 pub async fn is_login_with_manager(
322 manager: &SaTokenManager,
323 token: &TokenValue,
324 ) -> bool {
325 manager.is_valid(token).await
326 }
327
328 pub async fn check_login(token: &TokenValue) -> SaTokenResult<()> {
330 if !Self::is_login(token).await {
331 return Err(SaTokenError::NotLogin);
332 }
333 Ok(())
334 }
335
336 pub async fn get_token_info(token: &TokenValue) -> SaTokenResult<TokenInfo> {
338 Self::get_manager().get_token_info(token).await
339 }
340
341 pub async fn get_login_id(token: &TokenValue) -> SaTokenResult<String> {
343 let token_info = Self::get_manager().get_token_info(token).await?;
344 Ok(token_info.login_id)
345 }
346
347 pub async fn get_login_id_or_default(
349 token: &TokenValue,
350 default: impl Into<String>,
351 ) -> String {
352 Self::get_login_id(token)
353 .await
354 .unwrap_or_else(|_| default.into())
355 }
356
357 pub async fn get_token_by_login_id(login_id: impl LoginId) -> SaTokenResult<TokenValue> {
365 let manager = Self::get_manager();
366 let login_id_str = login_id.to_login_id();
367
368 let key = manager.config.make_key("login:token:", &login_id_str);
370 match manager.storage.get(&key).await {
371 Ok(Some(token_str)) => Ok(TokenValue::new(token_str)),
372 Ok(None) => Err(SaTokenError::NotLogin),
373 Err(e) => Err(SaTokenError::StorageError(e.to_string())),
374 }
375 }
376
377 pub async fn get_all_tokens_by_login_id(login_id: impl LoginId) -> SaTokenResult<Vec<TokenValue>> {
384 let manager = Self::get_manager();
385 let login_id_str = login_id.to_login_id();
386
387 let key = manager.config.make_key("login:tokens:", &login_id_str);
389 match manager.storage.get(&key).await {
390 Ok(Some(tokens_str)) => {
391 let token_strings: Vec<String> = serde_json::from_str(&tokens_str)
392 .map_err(SaTokenError::SerializationError)?;
393 Ok(token_strings.into_iter().map(TokenValue::new).collect())
394 }
395 Ok(None) => Ok(Vec::new()),
396 Err(e) => Err(SaTokenError::StorageError(e.to_string())),
397 }
398 }
399
400 pub async fn get_session(login_id: impl LoginId) -> SaTokenResult<SaSession> {
404 Self::get_manager().get_session(&login_id.to_login_id()).await
405 }
406
407 pub async fn save_session(session: &SaSession) -> SaTokenResult<()> {
409 Self::get_manager().save_session(session).await
410 }
411
412 pub async fn delete_session(login_id: impl LoginId) -> SaTokenResult<()> {
414 Self::get_manager().delete_session(&login_id.to_login_id()).await
415 }
416
417 pub async fn set_session_value<T: serde::Serialize>(
419 login_id: impl LoginId,
420 key: &str,
421 value: T,
422 ) -> SaTokenResult<()> {
423 let manager = Self::get_manager();
424 let login_id_str = login_id.to_login_id();
425 let mut session = manager.get_session(&login_id_str).await?;
426 session.set(key, value)?;
427 manager.save_session(&session).await
428 }
429
430 pub async fn get_session_value<T: serde::de::DeserializeOwned>(
432 login_id: impl LoginId,
433 key: &str,
434 ) -> SaTokenResult<Option<T>> {
435 let session = Self::get_manager().get_session(&login_id.to_login_id()).await?;
436 Ok(session.get::<T>(key))
437 }
438
439 pub fn create_token(token_value: impl Into<String>) -> TokenValue {
443 TokenValue::new(token_value.into())
444 }
445
446 pub fn is_valid_token_format(token: &str) -> bool {
448 !token.is_empty() && token.len() >= 16
449 }
450}
451
452impl StpUtil {
455 pub async fn set_permissions(
458 login_id: impl LoginId,
459 permissions: Vec<String>,
460 ) -> SaTokenResult<()> {
461 Self::get_manager()
462 .set_permissions(&login_id.to_login_id(), permissions)
463 .await
464 }
465
466 pub async fn add_permission(
468 login_id: impl LoginId,
469 permission: impl Into<String>,
470 ) -> SaTokenResult<()> {
471 Self::get_manager()
472 .add_permission(&login_id.to_login_id(), permission.into())
473 .await
474 }
475
476 pub async fn remove_permission(
478 login_id: impl LoginId,
479 permission: &str,
480 ) -> SaTokenResult<()> {
481 Self::get_manager()
482 .remove_permission(&login_id.to_login_id(), permission)
483 .await
484 }
485
486 pub async fn clear_permissions(login_id: impl LoginId) -> SaTokenResult<()> {
488 Self::get_manager()
489 .clear_permissions(&login_id.to_login_id())
490 .await
491 }
492
493 pub async fn get_permissions(login_id: impl LoginId) -> Vec<String> {
496 Self::get_manager()
497 .get_permissions(&login_id.to_login_id())
498 .await
499 .unwrap_or_default()
500 }
501
502 pub async fn has_permission(
506 login_id: impl LoginId,
507 permission: &str,
508 ) -> bool {
509 let permissions = match Self::get_manager()
510 .get_permissions(&login_id.to_login_id())
511 .await
512 {
513 Ok(list) => list,
514 Err(_) => return false,
515 };
516
517 if permissions.iter().any(|p| p == permission) {
519 return true;
520 }
521
522 permissions.iter().any(|perm| {
524 perm.ends_with(":*") && permission.starts_with(&perm[..perm.len() - 2])
525 })
526 }
527
528 pub async fn has_all_permissions(
530 login_id: impl LoginId,
531 permissions: &[&str],
532 ) -> bool {
533 let login_id_str = login_id.to_login_id();
534 for permission in permissions {
535 if !Self::has_permission(&login_id_str, permission).await {
536 return false;
537 }
538 }
539 true
540 }
541
542 pub async fn has_permissions_and(
544 login_id: impl LoginId,
545 permissions: &[&str],
546 ) -> bool {
547 Self::has_all_permissions(login_id, permissions).await
548 }
549
550 pub async fn has_any_permission(
552 login_id: impl LoginId,
553 permissions: &[&str],
554 ) -> bool {
555 let login_id_str = login_id.to_login_id();
556 for permission in permissions {
557 if Self::has_permission(&login_id_str, permission).await {
558 return true;
559 }
560 }
561 false
562 }
563
564 pub async fn has_permissions_or(
566 login_id: impl LoginId,
567 permissions: &[&str],
568 ) -> bool {
569 Self::has_any_permission(login_id, permissions).await
570 }
571
572 pub async fn check_permission(
574 login_id: impl LoginId,
575 permission: &str,
576 ) -> SaTokenResult<()> {
577 if !Self::has_permission(login_id, permission).await {
578 return Err(SaTokenError::PermissionDeniedDetail(permission.to_string()));
579 }
580 Ok(())
581 }
582}
583
584impl StpUtil {
587 pub async fn set_roles(
590 login_id: impl LoginId,
591 roles: Vec<String>,
592 ) -> SaTokenResult<()> {
593 Self::get_manager()
594 .set_roles(&login_id.to_login_id(), roles)
595 .await
596 }
597
598 pub async fn add_role(
600 login_id: impl LoginId,
601 role: impl Into<String>,
602 ) -> SaTokenResult<()> {
603 Self::get_manager()
604 .add_role(&login_id.to_login_id(), role.into())
605 .await
606 }
607
608 pub async fn remove_role(
610 login_id: impl LoginId,
611 role: &str,
612 ) -> SaTokenResult<()> {
613 Self::get_manager()
614 .remove_role(&login_id.to_login_id(), role)
615 .await
616 }
617
618 pub async fn clear_roles(login_id: impl LoginId) -> SaTokenResult<()> {
620 Self::get_manager()
621 .clear_roles(&login_id.to_login_id())
622 .await
623 }
624
625 pub async fn get_roles(login_id: impl LoginId) -> Vec<String> {
628 Self::get_manager()
629 .get_roles(&login_id.to_login_id())
630 .await
631 .unwrap_or_default()
632 }
633
634 pub async fn has_role(
637 login_id: impl LoginId,
638 role: &str,
639 ) -> bool {
640 match Self::get_manager().get_roles(&login_id.to_login_id()).await {
641 Ok(roles) => roles.iter().any(|r| r == role),
642 Err(_) => false,
643 }
644 }
645
646 pub async fn has_all_roles(
648 login_id: impl LoginId,
649 roles: &[&str],
650 ) -> bool {
651 let login_id_str = login_id.to_login_id();
652 for role in roles {
653 if !Self::has_role(&login_id_str, role).await {
654 return false;
655 }
656 }
657 true
658 }
659
660 pub async fn has_roles_and(
662 login_id: impl LoginId,
663 roles: &[&str],
664 ) -> bool {
665 Self::has_all_roles(login_id, roles).await
666 }
667
668 pub async fn has_any_role(
670 login_id: impl LoginId,
671 roles: &[&str],
672 ) -> bool {
673 let login_id_str = login_id.to_login_id();
674 for role in roles {
675 if Self::has_role(&login_id_str, role).await {
676 return true;
677 }
678 }
679 false
680 }
681
682 pub async fn has_roles_or(
684 login_id: impl LoginId,
685 roles: &[&str],
686 ) -> bool {
687 Self::has_any_role(login_id, roles).await
688 }
689
690 pub async fn check_role(
692 login_id: impl LoginId,
693 role: &str,
694 ) -> SaTokenResult<()> {
695 if !Self::has_role(login_id, role).await {
696 return Err(SaTokenError::RoleDenied(role.to_string()));
697 }
698 Ok(())
699 }
700}
701
702impl StpUtil {
705 pub async fn kick_out_batch<T: LoginId>(
707 login_ids: &[T],
708 ) -> SaTokenResult<Vec<Result<(), SaTokenError>>> {
709 let manager = Self::get_manager();
710 let mut results = Vec::new();
711 for login_id in login_ids {
712 results.push(manager.kick_out(&login_id.to_login_id()).await);
713 }
714 Ok(results)
715 }
716
717 pub async fn get_token_timeout(token: &TokenValue) -> SaTokenResult<Option<i64>> {
719 let manager = Self::get_manager();
720 let token_info = manager.get_token_info(token).await?;
721
722 if let Some(expire_time) = token_info.expire_time {
723 let now = chrono::Utc::now();
724 let duration = expire_time.signed_duration_since(now);
725 Ok(Some(duration.num_seconds()))
726 } else {
727 Ok(None) }
729 }
730
731 pub async fn renew_timeout(
733 token: &TokenValue,
734 timeout_seconds: i64,
735 ) -> SaTokenResult<()> {
736 let manager = Self::get_manager();
737 let mut token_info = manager.get_token_info(token).await?;
738
739 let new_expire_time = chrono::Utc::now() + chrono::Duration::seconds(timeout_seconds);
741 token_info.expire_time = Some(new_expire_time);
742
743 let key = manager.config.make_key("token:", token.as_str());
745 let value = serde_json::to_string(&token_info)
746 .map_err(SaTokenError::SerializationError)?;
747
748 let timeout = std::time::Duration::from_secs(timeout_seconds as u64);
749 manager.storage.set(&key, &value, Some(timeout)).await
750 .map_err(|e| SaTokenError::StorageError(e.to_string()))?;
751
752 Ok(())
753 }
754
755 pub async fn set_extra_data(
763 token: &TokenValue,
764 extra_data: serde_json::Value,
765 ) -> SaTokenResult<()> {
766 let manager = Self::get_manager();
767 let mut token_info = manager.get_token_info(token).await?;
768 token_info.extra_data = Some(extra_data);
769
770 let key = manager.config.make_key("token:", token.as_str());
771 let value = serde_json::to_string(&token_info)
772 .map_err(SaTokenError::SerializationError)?;
773
774 manager.storage.set(&key, &value, manager.config.timeout_duration()).await
775 .map_err(|e| SaTokenError::StorageError(e.to_string()))?;
776
777 Ok(())
778 }
779
780 pub async fn get_extra_data(token: &TokenValue) -> SaTokenResult<Option<serde_json::Value>> {
785 let manager = Self::get_manager();
786 let token_info = manager.get_token_info(token).await?;
787 Ok(token_info.extra_data)
788 }
789
790 pub fn builder(login_id: impl LoginId) -> TokenBuilder {
807 TokenBuilder::new(login_id.to_login_id())
808 }
809}
810
811pub struct TokenBuilder {
813 login_id: String,
814 extra_data: Option<serde_json::Value>,
815 device: Option<String>,
816 login_type: Option<String>,
817}
818
819impl TokenBuilder {
820 pub fn new(login_id: String) -> Self {
822 Self {
823 login_id,
824 extra_data: None,
825 device: None,
826 login_type: None,
827 }
828 }
829
830 pub fn extra_data(mut self, data: serde_json::Value) -> Self {
832 self.extra_data = Some(data);
833 self
834 }
835
836 pub fn device(mut self, device: impl Into<String>) -> Self {
838 self.device = Some(device.into());
839 self
840 }
841
842 pub fn login_type(mut self, login_type: impl Into<String>) -> Self {
844 self.login_type = Some(login_type.into());
845 self
846 }
847
848 pub async fn login<T: LoginId>(self, login_id: Option<T>) -> SaTokenResult<TokenValue> {
852 let manager = StpUtil::get_manager();
853
854 let final_login_id = match login_id {
856 Some(id) => id.to_login_id(),
857 None => self.login_id,
858 };
859 let token = manager.login(final_login_id).await?;
860
861 let mut token_info = manager.get_token_info(&token).await?;
863
864 if let Some(data) = self.extra_data {
866 token_info.extra_data = Some(data);
867 }
868
869 if let Some(device) = self.device {
870 token_info.device = Some(device);
871 }
872
873 if let Some(login_type) = self.login_type {
874 token_info.login_type = login_type;
875 }
876
877 let key = manager.config.make_key("token:", token.as_str());
879 let value = serde_json::to_string(&token_info)
880 .map_err(SaTokenError::SerializationError)?;
881
882 manager.storage.set(&key, &value, manager.config.timeout_duration()).await
883 .map_err(|e| SaTokenError::StorageError(e.to_string()))?;
884
885 Ok(token)
886 }
887}
888
889#[cfg(test)]
890mod tests {
891 use super::*;
892
893 #[test]
894 fn test_token_format_validation() {
895 assert!(StpUtil::is_valid_token_format("1234567890abcdef"));
896 assert!(!StpUtil::is_valid_token_format(""));
897 assert!(!StpUtil::is_valid_token_format("short"));
898 }
899
900 #[test]
901 fn test_create_token() {
902 let token = StpUtil::create_token("test-token-123");
903 assert_eq!(token.as_str(), "test-token-123");
904 }
905}