Skip to main content

alibi_core/store/contracts/
account.rs

1use super::*;
2#[async_trait]
3pub trait AccountStore<S: AuthSchema>: Send + Sync {
4    /// Apply the physical token TEXT column's scalar affinity before persistence.
5    /// SQL adapters override this for their own boolean/numeric representation.
6    async fn provider_token_text(&self, value: &serde_json::Value) -> AuthResult<Option<String>> {
7        if value.is_null() {
8            return Ok(None);
9        }
10        if value.is_object() || value.is_array() {
11            return Err(AuthError::internal(
12                "Unsupported provider token SQL parameter",
13            ));
14        }
15        crate::utils::json::JsValue::from(value.clone())
16            .coerce_string()
17            .map(Some)
18            .map_err(AuthError::internal)
19    }
20
21    /// Return a retained adapter record. The default is the physical model's
22    /// serialized snapshot; initialized stores apply their declared output policy.
23    async fn create_account_record(
24        &self,
25        create_account: CreateAccount,
26    ) -> AuthResult<crate::AdapterRecord<S::Account>> {
27        crate::AdapterRecord::physical(self.create_account(create_account).await?)
28    }
29
30    /// Return a retained adapter record. The default is the physical model's
31    /// serialized snapshot; initialized stores apply their declared output policy.
32    async fn get_account_record(
33        &self,
34        provider: &str,
35        provider_account_id: &str,
36    ) -> AuthResult<Option<crate::AdapterRecord<S::Account>>> {
37        self.get_account(provider, provider_account_id)
38            .await?
39            .map(crate::AdapterRecord::physical)
40            .transpose()
41    }
42
43    /// Return a retained adapter record. The default is the physical model's
44    /// serialized snapshot; initialized stores apply their declared output policy.
45    /// Retain the selected physical credential result. Initialization applies
46    /// output policy only to that selected row, never unrelated linked accounts.
47    async fn get_credential_account_record(
48        &self,
49        user_id: &str,
50    ) -> AuthResult<Option<crate::AdapterRecord<S::Account>>> {
51        use crate::AuthAccount;
52        self.get_user_accounts(user_id)
53            .await?
54            .into_iter()
55            .find(|account| {
56                account.provider_id() == "credential" && account.account_id() == user_id
57            })
58            .map(crate::AdapterRecord::physical)
59            .transpose()
60    }
61
62    async fn get_user_accounts_record(
63        &self,
64        user_id: &str,
65    ) -> AuthResult<Vec<crate::AdapterRecord<S::Account>>> {
66        self.get_user_accounts(user_id)
67            .await?
68            .into_iter()
69            .map(crate::AdapterRecord::physical)
70            .collect()
71    }
72
73    /// Return a retained adapter record. The default is the physical model's
74    /// serialized snapshot; initialized stores apply their declared output policy.
75    async fn update_account_record(
76        &self,
77        id: &str,
78        update: UpdateAccount,
79    ) -> AuthResult<crate::AdapterRecord<S::Account>> {
80        crate::AdapterRecord::physical(self.update_account(id, update).await?)
81    }
82
83    async fn create_account(&self, create_account: CreateAccount) -> AuthResult<S::Account>;
84    /// Resolve a global provider identity only when exactly one physical row matches.
85    /// Duplicate rows (including duplicates owned by one user) must return
86    /// `DatabaseError::AmbiguousAccount`; choosing a row would make ownership arbitrary.
87    async fn get_account(
88        &self,
89        provider: &str,
90        provider_account_id: &str,
91    ) -> AuthResult<Option<S::Account>>;
92    /// Return all scoped physical rows in the adapter's native order. Do not
93    /// select or collapse duplicate provider identities, or sort by mutable dates.
94    async fn get_user_accounts(&self, user_id: &str) -> AuthResult<Vec<S::Account>>;
95    async fn update_account(&self, id: &str, update: UpdateAccount) -> AuthResult<S::Account>;
96    async fn delete_account(&self, id: &str) -> AuthResult<()>;
97}