Skip to main content

alibi_core/store/contracts/
user.rs

1use super::*;
2/// Numeric binding used when a registered user text field accepts a JSON number.
3/// The HTTP caller first rounds it to a JavaScript number, preserving negative zero.
4#[derive(Clone, Copy, Debug)]
5pub enum NumericTextInput {
6    Integer(i64),
7    Real(f64),
8}
9
10#[async_trait]
11pub trait UserStore<S: AuthSchema>: Send + Sync {
12    /// Read the provider verification column using the adapter's physical scalar
13    /// rules. This is retained output, not authorization input; typed models
14    /// continue to supply the canonical boolean accessor.
15    async fn provider_verification_output(
16        &self,
17        _id: &str,
18    ) -> AuthResult<Option<serde_json::Value>> {
19        Ok(None)
20    }
21
22    /// Return a retained adapter record. The default is the physical model's
23    /// serialized snapshot; initialized stores apply their declared output policy.
24    async fn create_user_record(
25        &self,
26        create_user: CreateUser,
27    ) -> AuthResult<crate::AdapterRecord<S::User>> {
28        crate::AdapterRecord::physical(self.create_user(create_user).await?)
29    }
30
31    /// Return a retained adapter record. The default is the physical model's
32    /// serialized snapshot; initialized stores apply their declared output policy.
33    async fn create_user_with_source_record(
34        &self,
35        create_user: CreateUser,
36        source: UserValidationSource,
37    ) -> AuthResult<crate::AdapterRecord<S::User>> {
38        crate::AdapterRecord::physical(self.create_user_with_source(create_user, source).await?)
39    }
40
41    /// Return a retained adapter record. The default is the physical model's
42    /// serialized snapshot; initialized stores apply their declared output policy.
43    async fn create_user_prepared_record(
44        &self,
45        prepared: PreparedUserCreation,
46    ) -> AuthResult<crate::AdapterRecord<S::User>> {
47        crate::AdapterRecord::physical(self.create_user_prepared(prepared).await?)
48    }
49
50    /// Return a retained adapter record. The default is the physical model's
51    /// serialized snapshot; initialized stores apply their declared output policy.
52    async fn get_user_by_id_record(
53        &self,
54        id: &str,
55    ) -> AuthResult<Option<crate::AdapterRecord<S::User>>> {
56        self.get_user_by_id(id)
57            .await?
58            .map(crate::AdapterRecord::physical)
59            .transpose()
60    }
61
62    /// Return a retained adapter record. The default is the physical model's
63    /// serialized snapshot; initialized stores apply their declared output policy.
64    async fn get_user_by_email_record(
65        &self,
66        email: &str,
67    ) -> AuthResult<Option<crate::AdapterRecord<S::User>>> {
68        self.get_user_by_email(email)
69            .await?
70            .map(crate::AdapterRecord::physical)
71            .transpose()
72    }
73
74    /// Return a retained adapter record. The default is the physical model's
75    /// serialized snapshot; initialized stores apply their declared output policy.
76    async fn get_user_by_username_record(
77        &self,
78        username: &str,
79    ) -> AuthResult<Option<crate::AdapterRecord<S::User>>> {
80        self.get_user_by_username(username)
81            .await?
82            .map(crate::AdapterRecord::physical)
83            .transpose()
84    }
85
86    /// Return a retained adapter record. The default is the physical model's
87    /// serialized snapshot; initialized stores apply their declared output policy.
88    async fn get_user_by_phone_number_record(
89        &self,
90        phone_number: &str,
91    ) -> AuthResult<Option<crate::AdapterRecord<S::User>>> {
92        self.get_user_by_phone_number(phone_number)
93            .await?
94            .map(crate::AdapterRecord::physical)
95            .transpose()
96    }
97
98    /// Return a retained adapter record. The default is the physical model's
99    /// serialized snapshot; initialized stores apply their declared output policy.
100    async fn list_users_by_ids_record(
101        &self,
102        ids: &[String],
103    ) -> AuthResult<Vec<crate::AdapterRecord<S::User>>> {
104        self.list_users_by_ids(ids)
105            .await?
106            .into_iter()
107            .map(crate::AdapterRecord::physical)
108            .collect()
109    }
110
111    /// Return a retained adapter record. The default is the physical model's
112    /// serialized snapshot; initialized stores apply their declared output policy.
113    async fn list_users_by_ids_page_record(
114        &self,
115        ids: &[String],
116        limit: f64,
117    ) -> AuthResult<Vec<crate::AdapterRecord<S::User>>> {
118        self.list_users_by_ids_page(ids, limit)
119            .await?
120            .into_iter()
121            .map(crate::AdapterRecord::physical)
122            .collect()
123    }
124
125    /// Return a retained adapter record. The default is the physical model's
126    /// serialized snapshot; initialized stores apply their declared output policy.
127    async fn update_user_record(
128        &self,
129        id: &str,
130        update: UpdateUser,
131    ) -> AuthResult<crate::AdapterRecord<S::User>> {
132        crate::AdapterRecord::physical(self.update_user(id, update).await?)
133    }
134
135    /// Return a retained adapter record. The default is the physical model's
136    /// serialized snapshot; initialized stores apply their declared output policy.
137    async fn list_users_record(
138        &self,
139        params: ListUsersParams,
140    ) -> AuthResult<(Vec<crate::AdapterRecord<S::User>>, usize)> {
141        let (models, count) = self.list_users(params).await?;
142        Ok((
143            models
144                .into_iter()
145                .map(crate::AdapterRecord::physical)
146                .collect::<AuthResult<Vec<_>>>()?,
147            count,
148        ))
149    }
150
151    async fn create_user(&self, create_user: CreateUser) -> AuthResult<S::User>;
152    /// Create with endpoint-owned identity provenance, retaining the finalized
153    /// instance's validation and database-hook ordering.
154    async fn create_user_with_source(
155        &self,
156        create_user: CreateUser,
157        _source: UserValidationSource,
158    ) -> AuthResult<S::User> {
159        self.create_user(create_user).await
160    }
161    /// Persist a normalized, admitted candidate without normalizing trusted
162    /// callback mutations again. Unsupported custom adapters fail closed.
163    async fn create_user_prepared(&self, _prepared: PreparedUserCreation) -> AuthResult<S::User> {
164        Err(AuthError::NotImplemented(
165            "Prepared user creation is not supported by this store".into(),
166        ))
167    }
168    /// Coerce a numeric binding with the configured adapter's text semantics.
169    /// Custom adapters must implement this explicitly when accepting such input.
170    async fn coerce_user_text_number(&self, _input: NumericTextInput) -> AuthResult<String> {
171        Err(AuthError::NotImplemented(
172            "Numeric user-field text coercion is not supported by this store".into(),
173        ))
174    }
175    async fn get_user_by_id(&self, id: &str) -> AuthResult<Option<S::User>>;
176    /// Fetch multiple users by id.
177    ///
178    /// Implementations may return rows in any order. Callers must remap by id
179    /// when response order matters.
180    async fn list_users_by_ids(&self, ids: &[String]) -> AuthResult<Vec<S::User>>;
181    /// Apply the adapter's raw numeric page to actual matching users. Unsupported
182    /// stores fail closed rather than rounding, capping, or delegating to an unpaged read.
183    async fn list_users_by_ids_page(
184        &self,
185        _ids: &[String],
186        _limit: f64,
187    ) -> AuthResult<Vec<S::User>> {
188        Err(AuthError::NotImplemented(
189            "Raw numeric user pages are not supported by this store".into(),
190        ))
191    }
192    async fn get_user_by_email(&self, email: &str) -> AuthResult<Option<S::User>>;
193    async fn get_user_by_username(&self, username: &str) -> AuthResult<Option<S::User>>;
194    async fn get_user_by_phone_number(&self, _phone_number: &str) -> AuthResult<Option<S::User>> {
195        Err(AuthError::internal(
196            "phone-number lookup is not supported by this store",
197        ))
198    }
199    async fn update_user(&self, id: &str, update: UpdateUser) -> AuthResult<S::User>;
200    async fn delete_user(&self, id: &str) -> AuthResult<()>;
201    async fn list_users(&self, params: ListUsersParams) -> AuthResult<(Vec<S::User>, usize)>;
202}