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_extra(
133 login_id: impl LoginId,
134 extra_data: serde_json::Value,
135 ) -> SaTokenResult<TokenValue> {
136 let token = Self::get_manager().login(login_id.to_login_id()).await?;
137 Self::set_extra_data(&token, extra_data).await?;
138 Ok(token)
139 }
140
141 pub async fn login_with_manager(
143 manager: &SaTokenManager,
144 login_id: impl Into<String>,
145 ) -> SaTokenResult<TokenValue> {
146 manager.login(login_id).await
147 }
148
149 pub async fn logout(token: &TokenValue) -> SaTokenResult<()> {
151 Self::get_manager().logout(token).await
152 }
153
154 pub async fn logout_with_manager(
155 manager: &SaTokenManager,
156 token: &TokenValue,
157 ) -> SaTokenResult<()> {
158 manager.logout(token).await
159 }
160
161 pub async fn kick_out(login_id: impl LoginId) -> SaTokenResult<()> {
163 Self::get_manager().kick_out(&login_id.to_login_id()).await
164 }
165
166 pub async fn kick_out_with_manager(
167 manager: &SaTokenManager,
168 login_id: &str,
169 ) -> SaTokenResult<()> {
170 manager.kick_out(login_id).await
171 }
172
173 pub async fn logout_by_login_id(login_id: impl LoginId) -> SaTokenResult<()> {
175 Self::get_manager().logout_by_login_id(&login_id.to_login_id()).await
176 }
177
178 pub async fn logout_by_token(token: &TokenValue) -> SaTokenResult<()> {
180 Self::logout(token).await
181 }
182
183 pub fn get_token_value() -> SaTokenResult<TokenValue> {
193 let ctx = SaTokenContext::get_current()
194 .ok_or(SaTokenError::NotLogin)?;
195 ctx.token.ok_or(SaTokenError::NotLogin)
196 }
197
198 pub async fn logout_current() -> SaTokenResult<()> {
206 let token = Self::get_token_value()?;
207 Self::logout(&token).await
208 }
209
210 pub fn is_login_current() -> bool {
220 if let Ok(_token) = Self::get_token_value() {
221 true
224 } else {
225 false
226 }
227 }
228
229 pub fn check_login_current() -> SaTokenResult<()> {
237 Self::get_token_value()?;
238 Ok(())
239 }
240
241 pub fn get_login_id_as_string() -> SaTokenResult<String> {
249 let ctx = SaTokenContext::get_current()
250 .ok_or(SaTokenError::NotLogin)?;
251 ctx.login_id.ok_or(SaTokenError::NotLogin)
252 }
253
254 pub fn get_login_id_as_long() -> SaTokenResult<i64> {
262 let login_id_str = Self::get_login_id_as_string()?;
263 login_id_str.parse::<i64>()
264 .map_err(|_| SaTokenError::LoginIdNotNumber)
265 }
266
267 pub fn get_token_info_current() -> SaTokenResult<Arc<TokenInfo>> {
276 let ctx = SaTokenContext::get_current()
277 .ok_or(SaTokenError::NotLogin)?;
278 ctx.token_info.ok_or(SaTokenError::NotLogin)
279 }
280
281 pub async fn is_login(token: &TokenValue) -> bool {
285 Self::get_manager().is_valid(token).await
286 }
287
288 pub async fn is_login_by_login_id(login_id: impl LoginId) -> bool {
296 match Self::get_token_by_login_id(login_id).await {
297 Ok(token) => Self::is_login(&token).await,
298 Err(_) => false,
299 }
300 }
301
302 pub async fn is_login_with_manager(
303 manager: &SaTokenManager,
304 token: &TokenValue,
305 ) -> bool {
306 manager.is_valid(token).await
307 }
308
309 pub async fn check_login(token: &TokenValue) -> SaTokenResult<()> {
311 if !Self::is_login(token).await {
312 return Err(SaTokenError::NotLogin);
313 }
314 Ok(())
315 }
316
317 pub async fn get_token_info(token: &TokenValue) -> SaTokenResult<TokenInfo> {
319 Self::get_manager().get_token_info(token).await
320 }
321
322 pub async fn get_login_id(token: &TokenValue) -> SaTokenResult<String> {
324 let token_info = Self::get_manager().get_token_info(token).await?;
325 Ok(token_info.login_id)
326 }
327
328 pub async fn get_login_id_or_default(
330 token: &TokenValue,
331 default: impl Into<String>,
332 ) -> String {
333 Self::get_login_id(token)
334 .await
335 .unwrap_or_else(|_| default.into())
336 }
337
338 pub async fn get_token_by_login_id(login_id: impl LoginId) -> SaTokenResult<TokenValue> {
346 let manager = Self::get_manager();
347 let login_id_str = login_id.to_login_id();
348
349 let key = format!("sa:login:token:{}", login_id_str);
351 match manager.storage.get(&key).await {
352 Ok(Some(token_str)) => Ok(TokenValue::new(token_str)),
353 Ok(None) => Err(SaTokenError::NotLogin),
354 Err(e) => Err(SaTokenError::StorageError(e.to_string())),
355 }
356 }
357
358 pub async fn get_all_tokens_by_login_id(login_id: impl LoginId) -> SaTokenResult<Vec<TokenValue>> {
365 let manager = Self::get_manager();
366 let login_id_str = login_id.to_login_id();
367
368 let key = format!("sa:login:tokens:{}", login_id_str);
370 match manager.storage.get(&key).await {
371 Ok(Some(tokens_str)) => {
372 let token_strings: Vec<String> = serde_json::from_str(&tokens_str)
373 .map_err(|e| SaTokenError::SerializationError(e))?;
374 Ok(token_strings.into_iter().map(TokenValue::new).collect())
375 }
376 Ok(None) => Ok(Vec::new()),
377 Err(e) => Err(SaTokenError::StorageError(e.to_string())),
378 }
379 }
380
381 pub async fn get_session(login_id: impl LoginId) -> SaTokenResult<SaSession> {
385 Self::get_manager().get_session(&login_id.to_login_id()).await
386 }
387
388 pub async fn save_session(session: &SaSession) -> SaTokenResult<()> {
390 Self::get_manager().save_session(session).await
391 }
392
393 pub async fn delete_session(login_id: impl LoginId) -> SaTokenResult<()> {
395 Self::get_manager().delete_session(&login_id.to_login_id()).await
396 }
397
398 pub async fn set_session_value<T: serde::Serialize>(
400 login_id: impl LoginId,
401 key: &str,
402 value: T,
403 ) -> SaTokenResult<()> {
404 let manager = Self::get_manager();
405 let login_id_str = login_id.to_login_id();
406 let mut session = manager.get_session(&login_id_str).await?;
407 session.set(key, value)?;
408 manager.save_session(&session).await
409 }
410
411 pub async fn get_session_value<T: serde::de::DeserializeOwned>(
413 login_id: impl LoginId,
414 key: &str,
415 ) -> SaTokenResult<Option<T>> {
416 let session = Self::get_manager().get_session(&login_id.to_login_id()).await?;
417 Ok(session.get::<T>(key))
418 }
419
420 pub fn create_token(token_value: impl Into<String>) -> TokenValue {
424 TokenValue::new(token_value.into())
425 }
426
427 pub fn is_valid_token_format(token: &str) -> bool {
429 !token.is_empty() && token.len() >= 16
430 }
431}
432
433impl StpUtil {
436 pub async fn set_permissions(
438 login_id: impl LoginId,
439 permissions: Vec<String>,
440 ) -> SaTokenResult<()> {
441 let manager = Self::get_manager();
442 let mut map = manager.user_permissions.write().await;
443 map.insert(login_id.to_login_id(), permissions);
444 Ok(())
445 }
446
447 pub async fn add_permission(
449 login_id: impl LoginId,
450 permission: impl Into<String>,
451 ) -> SaTokenResult<()> {
452 let manager = Self::get_manager();
453 let mut map = manager.user_permissions.write().await;
454 let login_id_str = login_id.to_login_id();
455 let permissions = map.entry(login_id_str).or_insert_with(Vec::new);
456 let perm = permission.into();
457 if !permissions.contains(&perm) {
458 permissions.push(perm);
459 }
460 Ok(())
461 }
462
463 pub async fn remove_permission(
465 login_id: impl LoginId,
466 permission: &str,
467 ) -> SaTokenResult<()> {
468 let manager = Self::get_manager();
469 let mut map = manager.user_permissions.write().await;
470 if let Some(permissions) = map.get_mut(&login_id.to_login_id()) {
471 permissions.retain(|p| p != permission);
472 }
473 Ok(())
474 }
475
476 pub async fn clear_permissions(login_id: impl LoginId) -> SaTokenResult<()> {
478 let manager = Self::get_manager();
479 let mut map = manager.user_permissions.write().await;
480 map.remove(&login_id.to_login_id());
481 Ok(())
482 }
483
484 pub async fn get_permissions(login_id: impl LoginId) -> Vec<String> {
486 let manager = Self::get_manager();
487 let map = manager.user_permissions.read().await;
488 map.get(&login_id.to_login_id()).cloned().unwrap_or_default()
489 }
490
491 pub async fn has_permission(
493 login_id: impl LoginId,
494 permission: &str,
495 ) -> bool {
496 let manager = Self::get_manager();
497 let map = manager.user_permissions.read().await;
498 if let Some(permissions) = map.get(&login_id.to_login_id()) {
499 if permissions.contains(&permission.to_string()) {
501 return true;
502 }
503
504 for perm in permissions {
506 if perm.ends_with(":*") {
507 let prefix = &perm[..perm.len() - 2];
508 if permission.starts_with(prefix) {
509 return true;
510 }
511 }
512 }
513 }
514 false
515 }
516
517 pub async fn has_all_permissions(
519 login_id: impl LoginId,
520 permissions: &[&str],
521 ) -> bool {
522 let login_id_str = login_id.to_login_id();
523 for permission in permissions {
524 if !Self::has_permission(&login_id_str, permission).await {
525 return false;
526 }
527 }
528 true
529 }
530
531 pub async fn has_permissions_and(
533 login_id: impl LoginId,
534 permissions: &[&str],
535 ) -> bool {
536 Self::has_all_permissions(login_id, permissions).await
537 }
538
539 pub async fn has_any_permission(
541 login_id: impl LoginId,
542 permissions: &[&str],
543 ) -> bool {
544 let login_id_str = login_id.to_login_id();
545 for permission in permissions {
546 if Self::has_permission(&login_id_str, permission).await {
547 return true;
548 }
549 }
550 false
551 }
552
553 pub async fn has_permissions_or(
555 login_id: impl LoginId,
556 permissions: &[&str],
557 ) -> bool {
558 Self::has_any_permission(login_id, permissions).await
559 }
560
561 pub async fn check_permission(
563 login_id: impl LoginId,
564 permission: &str,
565 ) -> SaTokenResult<()> {
566 if !Self::has_permission(login_id, permission).await {
567 return Err(SaTokenError::PermissionDeniedDetail(permission.to_string()));
568 }
569 Ok(())
570 }
571}
572
573impl StpUtil {
576 pub async fn set_roles(
578 login_id: impl LoginId,
579 roles: Vec<String>,
580 ) -> SaTokenResult<()> {
581 let manager = Self::get_manager();
582 let mut map = manager.user_roles.write().await;
583 map.insert(login_id.to_login_id(), roles);
584 Ok(())
585 }
586
587 pub async fn add_role(
589 login_id: impl LoginId,
590 role: impl Into<String>,
591 ) -> SaTokenResult<()> {
592 let manager = Self::get_manager();
593 let mut map = manager.user_roles.write().await;
594 let login_id_str = login_id.to_login_id();
595 let roles = map.entry(login_id_str).or_insert_with(Vec::new);
596 let r = role.into();
597 if !roles.contains(&r) {
598 roles.push(r);
599 }
600 Ok(())
601 }
602
603 pub async fn remove_role(
605 login_id: impl LoginId,
606 role: &str,
607 ) -> SaTokenResult<()> {
608 let manager = Self::get_manager();
609 let mut map = manager.user_roles.write().await;
610 if let Some(roles) = map.get_mut(&login_id.to_login_id()) {
611 roles.retain(|r| r != role);
612 }
613 Ok(())
614 }
615
616 pub async fn clear_roles(login_id: impl LoginId) -> SaTokenResult<()> {
618 let manager = Self::get_manager();
619 let mut map = manager.user_roles.write().await;
620 map.remove(&login_id.to_login_id());
621 Ok(())
622 }
623
624 pub async fn get_roles(login_id: impl LoginId) -> Vec<String> {
626 let manager = Self::get_manager();
627 let map = manager.user_roles.read().await;
628 map.get(&login_id.to_login_id()).cloned().unwrap_or_default()
629 }
630
631 pub async fn has_role(
633 login_id: impl LoginId,
634 role: &str,
635 ) -> bool {
636 let manager = Self::get_manager();
637 let map = manager.user_roles.read().await;
638 if let Some(roles) = map.get(&login_id.to_login_id()) {
639 roles.contains(&role.to_string())
640 } else {
641 false
642 }
643 }
644
645 pub async fn has_all_roles(
647 login_id: impl LoginId,
648 roles: &[&str],
649 ) -> bool {
650 let login_id_str = login_id.to_login_id();
651 for role in roles {
652 if !Self::has_role(&login_id_str, role).await {
653 return false;
654 }
655 }
656 true
657 }
658
659 pub async fn has_roles_and(
661 login_id: impl LoginId,
662 roles: &[&str],
663 ) -> bool {
664 Self::has_all_roles(login_id, roles).await
665 }
666
667 pub async fn has_any_role(
669 login_id: impl LoginId,
670 roles: &[&str],
671 ) -> bool {
672 let login_id_str = login_id.to_login_id();
673 for role in roles {
674 if Self::has_role(&login_id_str, role).await {
675 return true;
676 }
677 }
678 false
679 }
680
681 pub async fn has_roles_or(
683 login_id: impl LoginId,
684 roles: &[&str],
685 ) -> bool {
686 Self::has_any_role(login_id, roles).await
687 }
688
689 pub async fn check_role(
691 login_id: impl LoginId,
692 role: &str,
693 ) -> SaTokenResult<()> {
694 if !Self::has_role(login_id, role).await {
695 return Err(SaTokenError::RoleDenied(role.to_string()));
696 }
697 Ok(())
698 }
699}
700
701impl StpUtil {
704 pub async fn kick_out_batch<T: LoginId>(
706 login_ids: &[T],
707 ) -> SaTokenResult<Vec<Result<(), SaTokenError>>> {
708 let manager = Self::get_manager();
709 let mut results = Vec::new();
710 for login_id in login_ids {
711 results.push(manager.kick_out(&login_id.to_login_id()).await);
712 }
713 Ok(results)
714 }
715
716 pub async fn get_token_timeout(token: &TokenValue) -> SaTokenResult<Option<i64>> {
718 let manager = Self::get_manager();
719 let token_info = manager.get_token_info(token).await?;
720
721 if let Some(expire_time) = token_info.expire_time {
722 let now = chrono::Utc::now();
723 let duration = expire_time.signed_duration_since(now);
724 Ok(Some(duration.num_seconds()))
725 } else {
726 Ok(None) }
728 }
729
730 pub async fn renew_timeout(
732 token: &TokenValue,
733 timeout_seconds: i64,
734 ) -> SaTokenResult<()> {
735 let manager = Self::get_manager();
736 let mut token_info = manager.get_token_info(token).await?;
737
738 let new_expire_time = chrono::Utc::now() + chrono::Duration::seconds(timeout_seconds);
740 token_info.expire_time = Some(new_expire_time);
741
742 let key = format!("sa:token:{}", token.as_str());
744 let value = serde_json::to_string(&token_info)
745 .map_err(|e| SaTokenError::SerializationError(e))?;
746
747 let timeout = std::time::Duration::from_secs(timeout_seconds as u64);
748 manager.storage.set(&key, &value, Some(timeout)).await
749 .map_err(|e| SaTokenError::StorageError(e.to_string()))?;
750
751 Ok(())
752 }
753
754 pub async fn set_extra_data(
762 token: &TokenValue,
763 extra_data: serde_json::Value,
764 ) -> SaTokenResult<()> {
765 let manager = Self::get_manager();
766 let mut token_info = manager.get_token_info(token).await?;
767 token_info.extra_data = Some(extra_data);
768
769 let key = format!("sa:token:{}", token.as_str());
770 let value = serde_json::to_string(&token_info)
771 .map_err(|e| SaTokenError::SerializationError(e))?;
772
773 manager.storage.set(&key, &value, manager.config.timeout_duration()).await
774 .map_err(|e| SaTokenError::StorageError(e.to_string()))?;
775
776 Ok(())
777 }
778
779 pub async fn get_extra_data(token: &TokenValue) -> SaTokenResult<Option<serde_json::Value>> {
784 let manager = Self::get_manager();
785 let token_info = manager.get_token_info(token).await?;
786 Ok(token_info.extra_data)
787 }
788
789 pub fn builder(login_id: impl LoginId) -> TokenBuilder {
806 TokenBuilder::new(login_id.to_login_id())
807 }
808}
809
810pub struct TokenBuilder {
812 login_id: String,
813 extra_data: Option<serde_json::Value>,
814 device: Option<String>,
815 login_type: Option<String>,
816}
817
818impl TokenBuilder {
819 pub fn new(login_id: String) -> Self {
821 Self {
822 login_id,
823 extra_data: None,
824 device: None,
825 login_type: None,
826 }
827 }
828
829 pub fn extra_data(mut self, data: serde_json::Value) -> Self {
831 self.extra_data = Some(data);
832 self
833 }
834
835 pub fn device(mut self, device: impl Into<String>) -> Self {
837 self.device = Some(device.into());
838 self
839 }
840
841 pub fn login_type(mut self, login_type: impl Into<String>) -> Self {
843 self.login_type = Some(login_type.into());
844 self
845 }
846
847 pub async fn login<T: LoginId>(self, login_id: Option<T>) -> SaTokenResult<TokenValue> {
851 let manager = StpUtil::get_manager();
852
853 let final_login_id = match login_id {
855 Some(id) => id.to_login_id(),
856 None => self.login_id,
857 };
858 let token = manager.login(final_login_id).await?;
859
860 let mut token_info = manager.get_token_info(&token).await?;
862
863 if let Some(data) = self.extra_data {
865 token_info.extra_data = Some(data);
866 }
867
868 if let Some(device) = self.device {
869 token_info.device = Some(device);
870 }
871
872 if let Some(login_type) = self.login_type {
873 token_info.login_type = login_type;
874 }
875
876 let key = format!("sa:token:{}", token.as_str());
878 let value = serde_json::to_string(&token_info)
879 .map_err(|e| SaTokenError::SerializationError(e))?;
880
881 manager.storage.set(&key, &value, manager.config.timeout_duration()).await
882 .map_err(|e| SaTokenError::StorageError(e.to_string()))?;
883
884 Ok(token)
885 }
886}
887
888#[cfg(test)]
889mod tests {
890 use super::*;
891
892 #[test]
893 fn test_token_format_validation() {
894 assert!(StpUtil::is_valid_token_format("1234567890abcdef"));
895 assert!(!StpUtil::is_valid_token_format(""));
896 assert!(!StpUtil::is_valid_token_format("short"));
897 }
898
899 #[test]
900 fn test_create_token() {
901 let token = StpUtil::create_token("test-token-123");
902 assert_eq!(token.as_str(), "test-token-123");
903 }
904}