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 omitted_fields: std::collections::BTreeSet::default(),
48 })
49 }
50 async fn prepare_secondary_session_update(
51 &self,
52 mut session: SessionView,
53 expires_at: Option<DateTime<Utc>>,
54 mut fields: FieldValues,
55 ) -> AuthResult<Option<(SessionView, FieldValues)>> {
56 fields.apply_adapter_transforms_async().await?;
57 for (key, value) in &fields {
58 match key.as_str() {
59 "activeOrganizationId" => {
60 session.active_organization_id = value.as_str().map(str::to_owned);
61 }
62 "activeTeamId" => session.active_team_id = value.as_str().map(str::to_owned),
63 "impersonatedBy" => session.impersonated_by = value.as_str().map(str::to_owned),
64 _ => {
65 _ = session
66 .extension_fields
67 .insert(key.clone(), value.to_json_value()?);
68 }
69 }
70 }
71 if let Some(expires_at) = expires_at {
72 session.expires_at = expires_at;
73 }
74 session.updated_at = Utc::now();
75 Ok(Some((session, fields)))
76 }
77 async fn complete_secondary_session_update(
78 &self,
79 session: SessionView,
80 _expires_at: Option<DateTime<Utc>>,
81 _fields: FieldValues,
82 persist: bool,
83 ) -> AuthResult<Option<SessionView>> {
84 if persist {
85 return Err(AuthError::config(
86 "No-database store cannot persist sessions",
87 ));
88 }
89 Ok(Some(session))
90 }
91 async fn get_session(&self, _token: &str) -> AuthResult<Option<SessionView>> {
92 Ok(None)
93 }
94 async fn get_user_sessions(&self, _user: &str) -> AuthResult<Vec<SessionView>> {
95 Ok(Vec::new())
96 }
97 async fn update_session_expiry(
98 &self,
99 _token: &str,
100 _expires: chrono::DateTime<Utc>,
101 ) -> AuthResult<()> {
102 Err(AuthError::SessionNotFound)
103 }
104 async fn update_session_active_organization(
105 &self,
106 _token: &str,
107 _id: Option<&str>,
108 ) -> AuthResult<SessionView> {
109 Err(AuthError::SessionNotFound)
110 }
111 async fn delete_session(&self, _token: &str) -> AuthResult<()> {
112 Ok(())
113 }
114 async fn delete_user_sessions(&self, _user: &str) -> AuthResult<()> {
115 Ok(())
116 }
117 async fn delete_expired_sessions(&self) -> AuthResult<usize> {
118 Ok(0)
119 }
120}