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