Skip to main content

alibi_core/store/stateless/
accounts.rs

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