Skip to main content

alibi_core/store/stateless/
sessions.rs

1use 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}