alibi_core/store/contracts/
user.rs1use crate::AdapterRecord;
2use crate::user_validation::{PreparedUserCreation, UserValidationSource};
3use crate::{AuthError, AuthResult, AuthSchema, CreateUser, ListUsersParams, UpdateUser};
4use async_trait::async_trait;
5#[derive(Clone, Copy, Debug)]
8pub enum NumericTextInput {
9 Integer(i64),
10 Real(f64),
11}
12
13#[async_trait]
14pub trait UserStore<S: AuthSchema>: Send + Sync {
15 async fn provider_verification_output(
19 &self,
20 _id: &str,
21 ) -> AuthResult<Option<serde_json::Value>> {
22 Ok(None)
23 }
24
25 async fn create_user_record(
28 &self,
29 create_user: CreateUser,
30 ) -> AuthResult<AdapterRecord<S::User>> {
31 AdapterRecord::physical(self.create_user(create_user).await?)
32 }
33
34 async fn create_user_with_source_record(
37 &self,
38 create_user: CreateUser,
39 source: UserValidationSource,
40 ) -> AuthResult<AdapterRecord<S::User>> {
41 AdapterRecord::physical(self.create_user_with_source(create_user, source).await?)
42 }
43
44 async fn create_user_prepared_record(
47 &self,
48 prepared: PreparedUserCreation,
49 ) -> AuthResult<AdapterRecord<S::User>> {
50 AdapterRecord::physical(self.create_user_prepared(prepared).await?)
51 }
52
53 async fn get_user_by_id_record(&self, id: &str) -> AuthResult<Option<AdapterRecord<S::User>>> {
56 self.get_user_by_id(id)
57 .await?
58 .map(AdapterRecord::physical)
59 .transpose()
60 }
61
62 async fn get_user_by_email_record(
65 &self,
66 email: &str,
67 ) -> AuthResult<Option<AdapterRecord<S::User>>> {
68 self.get_user_by_email(email)
69 .await?
70 .map(AdapterRecord::physical)
71 .transpose()
72 }
73
74 async fn get_user_by_username_record(
77 &self,
78 username: &str,
79 ) -> AuthResult<Option<AdapterRecord<S::User>>> {
80 self.get_user_by_username(username)
81 .await?
82 .map(AdapterRecord::physical)
83 .transpose()
84 }
85
86 async fn get_user_by_phone_number_record(
89 &self,
90 phone_number: &str,
91 ) -> AuthResult<Option<AdapterRecord<S::User>>> {
92 self.get_user_by_phone_number(phone_number)
93 .await?
94 .map(AdapterRecord::physical)
95 .transpose()
96 }
97
98 async fn list_users_by_ids_record(
101 &self,
102 ids: &[String],
103 ) -> AuthResult<Vec<AdapterRecord<S::User>>> {
104 self.list_users_by_ids(ids)
105 .await?
106 .into_iter()
107 .map(AdapterRecord::physical)
108 .collect()
109 }
110
111 async fn list_users_by_ids_page_record(
114 &self,
115 ids: &[String],
116 limit: f64,
117 ) -> AuthResult<Vec<AdapterRecord<S::User>>> {
118 self.list_users_by_ids_page(ids, limit)
119 .await?
120 .into_iter()
121 .map(AdapterRecord::physical)
122 .collect()
123 }
124
125 async fn update_user_record(
128 &self,
129 id: &str,
130 update: UpdateUser,
131 ) -> AuthResult<AdapterRecord<S::User>> {
132 AdapterRecord::physical(self.update_user(id, update).await?)
133 }
134
135 async fn list_users_record(
138 &self,
139 params: ListUsersParams,
140 ) -> AuthResult<(Vec<AdapterRecord<S::User>>, usize)> {
141 let (models, count) = self.list_users(params).await?;
142 Ok((
143 models
144 .into_iter()
145 .map(AdapterRecord::physical)
146 .collect::<AuthResult<Vec<_>>>()?,
147 count,
148 ))
149 }
150
151 async fn create_user(&self, create_user: CreateUser) -> AuthResult<S::User>;
152 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 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 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 async fn list_users_by_ids(&self, ids: &[String]) -> AuthResult<Vec<S::User>>;
181 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}