Skip to main content

alibi_core/store/stateless/
accounts.rs

1use crate::store::AccountStore;
2use crate::store::stateless::{StatelessSchema, StatelessStore};
3use crate::{AccountView, AuthError, AuthResult, CreateAccount, UpdateAccount};
4use async_trait::async_trait;
5use chrono::Utc;
6#[async_trait]
7impl AccountStore<StatelessSchema> for StatelessStore {
8    async fn create_account(&self, create_account: CreateAccount) -> AuthResult<AccountView> {
9        let now = Utc::now();
10        let account = AccountView {
11            id: uuid::Uuid::new_v4().to_string(),
12            account_id: create_account.account_id,
13            provider_id: create_account.provider_id,
14            user_id: create_account.user_id,
15            access_token: create_account.access_token,
16            refresh_token: create_account.refresh_token,
17            id_token: create_account.id_token,
18            access_token_expires_at: create_account.access_token_expires_at,
19            refresh_token_expires_at: create_account.refresh_token_expires_at,
20            scope: create_account.scope,
21            password: create_account.password,
22            created_at: now,
23            updated_at: now,
24        };
25        _ = self
26            .lock()?
27            .accounts
28            .insert(account.id.clone(), account.clone());
29        Ok(account)
30    }
31
32    async fn get_account(
33        &self,
34        provider: &str,
35        provider_account_id: &str,
36    ) -> AuthResult<Option<AccountView>> {
37        let storage = self.lock()?;
38        let mut matches = storage.accounts.values().filter(|account| {
39            account.provider_id == provider && account.account_id == provider_account_id
40        });
41        let first = matches.next().cloned();
42        if matches.next().is_some() {
43            return Err(AuthError::Database(
44                crate::DatabaseError::AmbiguousAccount {
45                    provider: provider.to_owned(),
46                },
47            ));
48        }
49        Ok(first)
50    }
51
52    async fn get_user_accounts(&self, user_id: &str) -> AuthResult<Vec<AccountView>> {
53        Ok(self
54            .lock()?
55            .accounts
56            .values()
57            .filter(|account| account.user_id == user_id)
58            .cloned()
59            .collect())
60    }
61
62    async fn update_account(&self, id: &str, update: UpdateAccount) -> AuthResult<AccountView> {
63        let mut state = self.lock()?;
64        let account = state
65            .accounts
66            .get_mut(id)
67            .ok_or_else(|| AuthError::not_found("Account not found"))?;
68        if let Some(access_token) = update.access_token {
69            account.access_token = Some(access_token);
70        }
71        if let Some(refresh_token) = update.refresh_token {
72            account.refresh_token = Some(refresh_token);
73        }
74        if let Some(id_token) = update.id_token {
75            account.id_token = Some(id_token);
76        }
77        if let Some(access_token_expires_at) = update.access_token_expires_at {
78            account.access_token_expires_at = Some(access_token_expires_at);
79        }
80        if let Some(refresh_token_expires_at) = update.refresh_token_expires_at {
81            account.refresh_token_expires_at = Some(refresh_token_expires_at);
82        }
83        if let Some(scope) = update.scope {
84            account.scope = Some(scope);
85        }
86        if let Some(password) = update.password {
87            account.password = Some(password);
88        }
89        account.updated_at = Utc::now();
90        Ok(account.clone())
91    }
92
93    async fn delete_account(&self, id: &str) -> AuthResult<()> {
94        _ = self.lock()?.accounts.shift_remove(id);
95        Ok(())
96    }
97}