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_manager(
129 manager: &SaTokenManager,
130 login_id: impl Into<String>,
131 ) -> SaTokenResult<TokenValue> {
132 manager.login(login_id).await
133 }
134
135 pub async fn logout(token: &TokenValue) -> SaTokenResult<()> {
137 Self::get_manager().logout(token).await
138 }
139
140 pub async fn logout_with_manager(
141 manager: &SaTokenManager,
142 token: &TokenValue,
143 ) -> SaTokenResult<()> {
144 manager.logout(token).await
145 }
146
147 pub async fn kick_out(login_id: impl LoginId) -> SaTokenResult<()> {
149 Self::get_manager().kick_out(&login_id.to_login_id()).await
150 }
151
152 pub async fn kick_out_with_manager(
153 manager: &SaTokenManager,
154 login_id: &str,
155 ) -> SaTokenResult<()> {
156 manager.kick_out(login_id).await
157 }
158
159 pub async fn logout_by_login_id(login_id: impl LoginId) -> SaTokenResult<()> {
161 Self::get_manager().logout_by_login_id(&login_id.to_login_id()).await
162 }
163
164 pub async fn logout_by_token(token: &TokenValue) -> SaTokenResult<()> {
166 Self::logout(token).await
167 }
168
169 pub fn get_token_value() -> SaTokenResult<TokenValue> {
179 let ctx = SaTokenContext::get_current()
180 .ok_or(SaTokenError::NotLogin)?;
181 ctx.token.ok_or(SaTokenError::NotLogin)
182 }
183
184 pub async fn logout_current() -> SaTokenResult<()> {
192 let token = Self::get_token_value()?;
193 Self::logout(&token).await
194 }
195
196 pub fn is_login_current() -> bool {
206 if let Ok(_token) = Self::get_token_value() {
207 true
210 } else {
211 false
212 }
213 }
214
215 pub fn check_login_current() -> SaTokenResult<()> {
223 Self::get_token_value()?;
224 Ok(())
225 }
226
227 pub fn get_login_id_as_string() -> SaTokenResult<String> {
235 let ctx = SaTokenContext::get_current()
236 .ok_or(SaTokenError::NotLogin)?;
237 ctx.login_id.ok_or(SaTokenError::NotLogin)
238 }
239
240 pub fn get_login_id_as_long() -> SaTokenResult<i64> {
248 let login_id_str = Self::get_login_id_as_string()?;
249 login_id_str.parse::<i64>()
250 .map_err(|_| SaTokenError::LoginIdNotNumber)
251 }
252
253 pub fn get_token_info_current() -> SaTokenResult<Arc<TokenInfo>> {
262 let ctx = SaTokenContext::get_current()
263 .ok_or(SaTokenError::NotLogin)?;
264 ctx.token_info.ok_or(SaTokenError::NotLogin)
265 }
266
267 pub async fn is_login(token: &TokenValue) -> bool {
271 Self::get_manager().is_valid(token).await
272 }
273
274 pub async fn is_login_by_login_id(login_id: impl LoginId) -> bool {
282 match Self::get_token_by_login_id(login_id).await {
283 Ok(token) => Self::is_login(&token).await,
284 Err(_) => false,
285 }
286 }
287
288 pub async fn is_login_with_manager(
289 manager: &SaTokenManager,
290 token: &TokenValue,
291 ) -> bool {
292 manager.is_valid(token).await
293 }
294
295 pub async fn check_login(token: &TokenValue) -> SaTokenResult<()> {
297 if !Self::is_login(token).await {
298 return Err(SaTokenError::NotLogin);
299 }
300 Ok(())
301 }
302
303 pub async fn get_token_info(token: &TokenValue) -> SaTokenResult<TokenInfo> {
305 Self::get_manager().get_token_info(token).await
306 }
307
308 pub async fn get_login_id(token: &TokenValue) -> SaTokenResult<String> {
310 let token_info = Self::get_manager().get_token_info(token).await?;
311 Ok(token_info.login_id)
312 }
313
314 pub async fn get_login_id_or_default(
316 token: &TokenValue,
317 default: impl Into<String>,
318 ) -> String {
319 Self::get_login_id(token)
320 .await
321 .unwrap_or_else(|_| default.into())
322 }
323
324 pub async fn get_token_by_login_id(login_id: impl LoginId) -> SaTokenResult<TokenValue> {
332 let manager = Self::get_manager();
333 let login_id_str = login_id.to_login_id();
334
335 let key = format!("sa:login:token:{}", login_id_str);
337 match manager.storage.get(&key).await {
338 Ok(Some(token_str)) => Ok(TokenValue::new(token_str)),
339 Ok(None) => Err(SaTokenError::NotLogin),
340 Err(e) => Err(SaTokenError::StorageError(e.to_string())),
341 }
342 }
343
344 pub async fn get_all_tokens_by_login_id(login_id: impl LoginId) -> SaTokenResult<Vec<TokenValue>> {
351 let manager = Self::get_manager();
352 let login_id_str = login_id.to_login_id();
353
354 let key = format!("sa:login:tokens:{}", login_id_str);
356 match manager.storage.get(&key).await {
357 Ok(Some(tokens_str)) => {
358 let token_strings: Vec<String> = serde_json::from_str(&tokens_str)
359 .map_err(|e| SaTokenError::SerializationError(e))?;
360 Ok(token_strings.into_iter().map(TokenValue::new).collect())
361 }
362 Ok(None) => Ok(Vec::new()),
363 Err(e) => Err(SaTokenError::StorageError(e.to_string())),
364 }
365 }
366
367 pub async fn get_session(login_id: impl LoginId) -> SaTokenResult<SaSession> {
371 Self::get_manager().get_session(&login_id.to_login_id()).await
372 }
373
374 pub async fn save_session(session: &SaSession) -> SaTokenResult<()> {
376 Self::get_manager().save_session(session).await
377 }
378
379 pub async fn delete_session(login_id: impl LoginId) -> SaTokenResult<()> {
381 Self::get_manager().delete_session(&login_id.to_login_id()).await
382 }
383
384 pub async fn set_session_value<T: serde::Serialize>(
386 login_id: impl LoginId,
387 key: &str,
388 value: T,
389 ) -> SaTokenResult<()> {
390 let manager = Self::get_manager();
391 let login_id_str = login_id.to_login_id();
392 let mut session = manager.get_session(&login_id_str).await?;
393 session.set(key, value)?;
394 manager.save_session(&session).await
395 }
396
397 pub async fn get_session_value<T: serde::de::DeserializeOwned>(
399 login_id: impl LoginId,
400 key: &str,
401 ) -> SaTokenResult<Option<T>> {
402 let session = Self::get_manager().get_session(&login_id.to_login_id()).await?;
403 Ok(session.get::<T>(key))
404 }
405
406 pub fn create_token(token_value: impl Into<String>) -> TokenValue {
410 TokenValue::new(token_value.into())
411 }
412
413 pub fn is_valid_token_format(token: &str) -> bool {
415 !token.is_empty() && token.len() >= 16
416 }
417}
418
419impl StpUtil {
422 pub async fn set_permissions(
424 login_id: impl LoginId,
425 permissions: Vec<String>,
426 ) -> SaTokenResult<()> {
427 let manager = Self::get_manager();
428 let mut map = manager.user_permissions.write().await;
429 map.insert(login_id.to_login_id(), permissions);
430 Ok(())
431 }
432
433 pub async fn add_permission(
435 login_id: impl LoginId,
436 permission: impl Into<String>,
437 ) -> SaTokenResult<()> {
438 let manager = Self::get_manager();
439 let mut map = manager.user_permissions.write().await;
440 let login_id_str = login_id.to_login_id();
441 let permissions = map.entry(login_id_str).or_insert_with(Vec::new);
442 let perm = permission.into();
443 if !permissions.contains(&perm) {
444 permissions.push(perm);
445 }
446 Ok(())
447 }
448
449 pub async fn remove_permission(
451 login_id: impl LoginId,
452 permission: &str,
453 ) -> SaTokenResult<()> {
454 let manager = Self::get_manager();
455 let mut map = manager.user_permissions.write().await;
456 if let Some(permissions) = map.get_mut(&login_id.to_login_id()) {
457 permissions.retain(|p| p != permission);
458 }
459 Ok(())
460 }
461
462 pub async fn clear_permissions(login_id: impl LoginId) -> SaTokenResult<()> {
464 let manager = Self::get_manager();
465 let mut map = manager.user_permissions.write().await;
466 map.remove(&login_id.to_login_id());
467 Ok(())
468 }
469
470 pub async fn get_permissions(login_id: impl LoginId) -> Vec<String> {
472 let manager = Self::get_manager();
473 let map = manager.user_permissions.read().await;
474 map.get(&login_id.to_login_id()).cloned().unwrap_or_default()
475 }
476
477 pub async fn has_permission(
479 login_id: impl LoginId,
480 permission: &str,
481 ) -> bool {
482 let manager = Self::get_manager();
483 let map = manager.user_permissions.read().await;
484 if let Some(permissions) = map.get(&login_id.to_login_id()) {
485 if permissions.contains(&permission.to_string()) {
487 return true;
488 }
489
490 for perm in permissions {
492 if perm.ends_with(":*") {
493 let prefix = &perm[..perm.len() - 2];
494 if permission.starts_with(prefix) {
495 return true;
496 }
497 }
498 }
499 }
500 false
501 }
502
503 pub async fn has_all_permissions(
505 login_id: impl LoginId,
506 permissions: &[&str],
507 ) -> bool {
508 let login_id_str = login_id.to_login_id();
509 for permission in permissions {
510 if !Self::has_permission(&login_id_str, permission).await {
511 return false;
512 }
513 }
514 true
515 }
516
517 pub async fn has_permissions_and(
519 login_id: impl LoginId,
520 permissions: &[&str],
521 ) -> bool {
522 Self::has_all_permissions(login_id, permissions).await
523 }
524
525 pub async fn has_any_permission(
527 login_id: impl LoginId,
528 permissions: &[&str],
529 ) -> bool {
530 let login_id_str = login_id.to_login_id();
531 for permission in permissions {
532 if Self::has_permission(&login_id_str, permission).await {
533 return true;
534 }
535 }
536 false
537 }
538
539 pub async fn has_permissions_or(
541 login_id: impl LoginId,
542 permissions: &[&str],
543 ) -> bool {
544 Self::has_any_permission(login_id, permissions).await
545 }
546
547 pub async fn check_permission(
549 login_id: impl LoginId,
550 permission: &str,
551 ) -> SaTokenResult<()> {
552 if !Self::has_permission(login_id, permission).await {
553 return Err(SaTokenError::PermissionDeniedDetail(permission.to_string()));
554 }
555 Ok(())
556 }
557}
558
559impl StpUtil {
562 pub async fn set_roles(
564 login_id: impl LoginId,
565 roles: Vec<String>,
566 ) -> SaTokenResult<()> {
567 let manager = Self::get_manager();
568 let mut map = manager.user_roles.write().await;
569 map.insert(login_id.to_login_id(), roles);
570 Ok(())
571 }
572
573 pub async fn add_role(
575 login_id: impl LoginId,
576 role: impl Into<String>,
577 ) -> SaTokenResult<()> {
578 let manager = Self::get_manager();
579 let mut map = manager.user_roles.write().await;
580 let login_id_str = login_id.to_login_id();
581 let roles = map.entry(login_id_str).or_insert_with(Vec::new);
582 let r = role.into();
583 if !roles.contains(&r) {
584 roles.push(r);
585 }
586 Ok(())
587 }
588
589 pub async fn remove_role(
591 login_id: impl LoginId,
592 role: &str,
593 ) -> SaTokenResult<()> {
594 let manager = Self::get_manager();
595 let mut map = manager.user_roles.write().await;
596 if let Some(roles) = map.get_mut(&login_id.to_login_id()) {
597 roles.retain(|r| r != role);
598 }
599 Ok(())
600 }
601
602 pub async fn clear_roles(login_id: impl LoginId) -> SaTokenResult<()> {
604 let manager = Self::get_manager();
605 let mut map = manager.user_roles.write().await;
606 map.remove(&login_id.to_login_id());
607 Ok(())
608 }
609
610 pub async fn get_roles(login_id: impl LoginId) -> Vec<String> {
612 let manager = Self::get_manager();
613 let map = manager.user_roles.read().await;
614 map.get(&login_id.to_login_id()).cloned().unwrap_or_default()
615 }
616
617 pub async fn has_role(
619 login_id: impl LoginId,
620 role: &str,
621 ) -> bool {
622 let manager = Self::get_manager();
623 let map = manager.user_roles.read().await;
624 if let Some(roles) = map.get(&login_id.to_login_id()) {
625 roles.contains(&role.to_string())
626 } else {
627 false
628 }
629 }
630
631 pub async fn has_all_roles(
633 login_id: impl LoginId,
634 roles: &[&str],
635 ) -> bool {
636 let login_id_str = login_id.to_login_id();
637 for role in roles {
638 if !Self::has_role(&login_id_str, role).await {
639 return false;
640 }
641 }
642 true
643 }
644
645 pub async fn has_roles_and(
647 login_id: impl LoginId,
648 roles: &[&str],
649 ) -> bool {
650 Self::has_all_roles(login_id, roles).await
651 }
652
653 pub async fn has_any_role(
655 login_id: impl LoginId,
656 roles: &[&str],
657 ) -> bool {
658 let login_id_str = login_id.to_login_id();
659 for role in roles {
660 if Self::has_role(&login_id_str, role).await {
661 return true;
662 }
663 }
664 false
665 }
666
667 pub async fn has_roles_or(
669 login_id: impl LoginId,
670 roles: &[&str],
671 ) -> bool {
672 Self::has_any_role(login_id, roles).await
673 }
674
675 pub async fn check_role(
677 login_id: impl LoginId,
678 role: &str,
679 ) -> SaTokenResult<()> {
680 if !Self::has_role(login_id, role).await {
681 return Err(SaTokenError::RoleDenied(role.to_string()));
682 }
683 Ok(())
684 }
685}
686
687impl StpUtil {
690 pub async fn kick_out_batch<T: LoginId>(
692 login_ids: &[T],
693 ) -> SaTokenResult<Vec<Result<(), SaTokenError>>> {
694 let manager = Self::get_manager();
695 let mut results = Vec::new();
696 for login_id in login_ids {
697 results.push(manager.kick_out(&login_id.to_login_id()).await);
698 }
699 Ok(results)
700 }
701
702 pub async fn get_token_timeout(token: &TokenValue) -> SaTokenResult<Option<i64>> {
704 let manager = Self::get_manager();
705 let token_info = manager.get_token_info(token).await?;
706
707 if let Some(expire_time) = token_info.expire_time {
708 let now = chrono::Utc::now();
709 let duration = expire_time.signed_duration_since(now);
710 Ok(Some(duration.num_seconds()))
711 } else {
712 Ok(None) }
714 }
715
716 pub async fn renew_timeout(
718 token: &TokenValue,
719 timeout_seconds: i64,
720 ) -> SaTokenResult<()> {
721 let manager = Self::get_manager();
722 let mut token_info = manager.get_token_info(token).await?;
723
724 let new_expire_time = chrono::Utc::now() + chrono::Duration::seconds(timeout_seconds);
726 token_info.expire_time = Some(new_expire_time);
727
728 let key = format!("sa:token:{}", token.as_str());
730 let value = serde_json::to_string(&token_info)
731 .map_err(|e| SaTokenError::SerializationError(e))?;
732
733 let timeout = std::time::Duration::from_secs(timeout_seconds as u64);
734 manager.storage.set(&key, &value, Some(timeout)).await
735 .map_err(|e| SaTokenError::StorageError(e.to_string()))?;
736
737 Ok(())
738 }
739}
740
741#[cfg(test)]
742mod tests {
743 use super::*;
744
745 #[test]
746 fn test_token_format_validation() {
747 assert!(StpUtil::is_valid_token_format("1234567890abcdef"));
748 assert!(!StpUtil::is_valid_token_format(""));
749 assert!(!StpUtil::is_valid_token_format("short"));
750 }
751
752 #[test]
753 fn test_create_token() {
754 let token = StpUtil::create_token("test-token-123");
755 assert_eq!(token.as_str(), "test-token-123");
756 }
757}