sa_token_core/sso/
session_store.rs1use std::sync::Arc;
6
7use crate::dao::SaTokenDao;
8use crate::error::{SaTokenError, SaTokenResult};
9use crate::sso::SsoSession;
10
11pub struct SsoSessionStore {
14 dao: Arc<SaTokenDao>,
15}
16
17impl std::fmt::Debug for SsoSessionStore {
18 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
19 f.write_str("SsoSessionStore { .. }")
20 }
21}
22
23impl SsoSessionStore {
24 pub fn new(dao: Arc<SaTokenDao>) -> Self {
27 Self { dao }
28 }
29
30 pub async fn upsert_client(&self, login_id: &str, service: &str) -> SaTokenResult<()> {
33 let key = self.dao.keys().sso_session(login_id);
34 for _ in 0..8 {
35 let current = self.dao.get_string(&key).await?;
36 let mut session = match ¤t {
37 Some(raw) => self.dao.decode::<SsoSession>(raw)?,
38 None => SsoSession::new(login_id.to_string()),
39 };
40 session.add_client(service.to_string());
41 let new_raw = self.dao.encode(&session)?;
42 let ok = self
43 .dao
44 .cas(&key, current.as_deref(), &new_raw, None)
45 .await?;
46 if ok {
47 return Ok(());
48 }
49 }
50 Err(SaTokenError::InternalError(
51 "SSO session CAS retries exhausted".into(),
52 ))
53 }
54
55 pub async fn remove(&self, login_id: &str) -> SaTokenResult<Vec<String>> {
58 let key = self.dao.keys().sso_session(login_id);
59 let session = self.dao.get_object::<SsoSession>(&key).await?;
60 let clients = session.map(|s| s.clients).unwrap_or_default();
61 self.dao.delete(&key).await?;
62 Ok(clients)
63 }
64
65 pub async fn get(&self, login_id: &str) -> SaTokenResult<Option<SsoSession>> {
68 let key = self.dao.keys().sso_session(login_id);
69 self.dao.get_object(&key).await
70 }
71}