alibi_core/store/stateless/
sessions.rs1use crate::field_policy::FieldValues;
2use crate::store::SessionStore;
3use crate::store::stateless::{StatelessSchema, StatelessStore};
4use crate::{AuthError, AuthResult, CreateSession, SessionView};
5use async_trait::async_trait;
6use chrono::{DateTime, Utc};
7#[async_trait]
8impl SessionStore<StatelessSchema> for StatelessStore {
9 async fn prepare_secondary_session_creation(
10 &self,
11 input: CreateSession,
12 persist: bool,
13 ) -> AuthResult<SessionView> {
14 if persist {
15 return Err(AuthError::config("StatelessStore cannot persist sessions"));
16 }
17 SessionStore::<StatelessSchema>::create_session(self, input).await
18 }
19 async fn complete_secondary_session_creation(&self, _session: &SessionView) -> AuthResult<()> {
20 Ok(())
21 }
22 async fn create_session(&self, mut input: CreateSession) -> AuthResult<SessionView> {
23 input
24 .additional_fields
25 .apply_adapter_transforms_async()
26 .await?;
27 let now = Utc::now();
28 Ok(SessionView {
29 id: uuid::Uuid::new_v4().to_string(),
30 token: input
31 .token
32 .unwrap_or_else(crate::utils::sessions::generate_session_token),
33 user_id: input.user_id,
34 expires_at: input.expires_at,
35 created_at: now,
36 updated_at: now,
37 ip_address: input.ip_address.or_else(|| Some(String::new())),
38 user_agent: input.user_agent.or_else(|| Some(String::new())),
39 active_organization_id: input.active_organization_id,
40 active_team_id: input.active_team_id,
41 impersonated_by: input.impersonated_by,
42 extension_fields: input
43 .additional_fields
44 .into_iter()
45 .map(|(key, value)| value.to_json_value().map(|value| (key, value)))
46 .collect::<Result<_, _>>()?,
47 active: true,
48 omitted_fields: std::collections::BTreeSet::default(),
49 })
50 }
51 async fn prepare_secondary_session_update(
52 &self,
53 mut session: SessionView,
54 expires_at: Option<DateTime<Utc>>,
55 mut fields: FieldValues,
56 ) -> AuthResult<Option<(SessionView, FieldValues)>> {
57 fields.apply_adapter_transforms_async().await?;
58 for (key, value) in &fields {
59 match key.as_str() {
60 "activeOrganizationId" => {
61 session.active_organization_id = value.as_str().map(str::to_owned);
62 }
63 "activeTeamId" => session.active_team_id = value.as_str().map(str::to_owned),
64 "impersonatedBy" => session.impersonated_by = value.as_str().map(str::to_owned),
65 _ => {
66 _ = session
67 .extension_fields
68 .insert(key.clone(), value.to_json_value()?);
69 }
70 }
71 }
72 if let Some(expires_at) = expires_at {
73 session.expires_at = expires_at;
74 }
75 session.updated_at = Utc::now();
76 Ok(Some((session, fields)))
77 }
78 async fn complete_secondary_session_update(
79 &self,
80 session: SessionView,
81 _expires_at: Option<DateTime<Utc>>,
82 _fields: FieldValues,
83 persist: bool,
84 ) -> AuthResult<Option<SessionView>> {
85 if persist {
86 return Err(AuthError::config(
87 "No-database store cannot persist sessions",
88 ));
89 }
90 Ok(Some(session))
91 }
92 async fn get_session(&self, _token: &str) -> AuthResult<Option<SessionView>> {
93 Ok(None)
94 }
95 async fn get_user_sessions(&self, _user: &str) -> AuthResult<Vec<SessionView>> {
96 Ok(Vec::new())
97 }
98 async fn update_session_expiry(
99 &self,
100 _token: &str,
101 _expires: chrono::DateTime<Utc>,
102 ) -> AuthResult<()> {
103 Err(AuthError::SessionNotFound)
104 }
105 async fn update_session_active_organization(
106 &self,
107 _token: &str,
108 _id: Option<&str>,
109 ) -> AuthResult<SessionView> {
110 Err(AuthError::SessionNotFound)
111 }
112 async fn delete_session(&self, _token: &str) -> AuthResult<()> {
113 Ok(())
114 }
115 async fn delete_user_sessions(&self, _user: &str) -> AuthResult<()> {
116 Ok(())
117 }
118 async fn delete_expired_sessions(&self) -> AuthResult<usize> {
119 Ok(0)
120 }
121}