alibi_core/plugin/
initialization.rs1use super::*;
2pub struct AuthInitParts {
3 pub metadata: MetadataMap,
4 pub email_provider: Option<Arc<dyn EmailProvider>>,
5 pub extensions: ContextExtensions,
6}
7
8pub struct AuthInitContext<S: AuthSchema> {
10 pub config: Arc<AuthConfig>,
11 pub database: Arc<dyn AuthStore<S>>,
12 pub email_provider: Option<Arc<dyn EmailProvider>>,
13 pub metadata: MetadataMap,
14 pub extensions: ContextExtensions,
15}
16
17impl<S: AuthSchema> AuthInitContext<S> {
18 #[must_use]
19 pub fn new(config: Arc<AuthConfig>, database: Arc<dyn AuthStore<S>>) -> Self {
20 let email_provider = config.email_provider.clone();
21 Self {
22 config,
23 database,
24 email_provider,
25 metadata: MetadataMap::new(),
26 extensions: ContextExtensions::default(),
27 }
28 }
29
30 pub fn set_metadata(&mut self, key: impl Into<String>, value: serde_json::Value) {
31 drop(self.metadata.insert(key.into(), value));
32 }
33
34 pub fn register_password_hash_hook(
37 &mut self,
38 hook: Arc<dyn crate::utils::password::PasswordHashHook>,
39 ) {
40 let mut hooks = self
41 .extensions
42 .get::<crate::utils::password::PasswordHashHooks>()
43 .map(|value| (*value).clone())
44 .unwrap_or_default();
45 hooks.0.push(hook);
46 self.extensions.insert(hooks);
47 }
48
49 #[must_use]
50 pub fn get_metadata(&self, key: &str) -> Option<&serde_json::Value> {
51 self.metadata.get(key)
52 }
53
54 pub fn register_user_create_transform<F>(&mut self, transform: F)
56 where
57 F: Fn(crate::types::CreateUser) -> AuthResult<crate::types::CreateUser>
58 + Send
59 + Sync
60 + 'static,
61 {
62 let mut transforms = self
63 .extensions
64 .get::<crate::store::UserTransforms>()
65 .map(|value| (*value).clone())
66 .unwrap_or_default();
67 transforms.creates.push(Arc::new(transform));
68 self.extensions.insert(transforms);
69 }
70
71 pub fn register_user_creation_adapter_default<F>(&mut self, default: F)
74 where
75 F: Fn(crate::types::CreateUser) -> AuthResult<crate::types::CreateUser>
76 + Send
77 + Sync
78 + 'static,
79 {
80 let mut transforms = self
81 .extensions
82 .get::<crate::store::UserTransforms>()
83 .map(|value| (*value).clone())
84 .unwrap_or_default();
85 transforms.adapter_defaults.0.push(Arc::new(default));
86 self.extensions.insert(transforms);
87 }
88
89 pub fn register_user_update_transform<F>(&mut self, transform: F)
91 where
92 F: Fn(&str, crate::types::UpdateUser) -> AuthResult<crate::types::UpdateUser>
93 + Send
94 + Sync
95 + 'static,
96 {
97 let mut transforms = self
98 .extensions
99 .get::<crate::store::UserTransforms>()
100 .map(|value| (*value).clone())
101 .unwrap_or_default();
102 transforms.updates.push(Arc::new(transform));
103 self.extensions.insert(transforms);
104 }
105
106 pub fn register_session_created_hook(
111 &mut self,
112 callback: Arc<dyn crate::store::SessionCreatedHook<S>>,
113 ) {
114 let mut callbacks = self
115 .extensions
116 .get::<crate::store::SessionCreatedCallbacks<S>>()
117 .map(|value| (*value).clone())
118 .unwrap_or_default();
119 callbacks.callbacks.push(callback);
120 self.extensions.insert(callbacks);
121 }
122
123 pub fn register_adapter_after_hook(
126 &mut self,
127 callback: Arc<dyn crate::store::AdapterAfterHook<S>>,
128 ) {
129 let mut callbacks = self
130 .extensions
131 .get::<crate::store::AdapterCallbacks<S>>()
132 .map(|callbacks| (*callbacks).clone())
133 .unwrap_or_default();
134 callbacks.0.push(callback);
135 self.extensions.insert(callbacks);
136 }
137
138 #[must_use]
140 pub fn database_with_registered_transforms(&self) -> Arc<dyn AuthStore<S>> {
141 let transforms = self
142 .extensions
143 .get::<crate::store::UserTransforms>()
144 .map(|value| (*value).clone())
145 .unwrap_or_default();
146 let session_callbacks = self
147 .extensions
148 .get::<crate::store::SessionCreatedCallbacks<S>>()
149 .map(|value| (*value).clone())
150 .unwrap_or_default();
151 let fields = self.extensions.get::<crate::field_policy::SessionFields>();
152 if self.config.session.secondary_storage.is_none()
153 && transforms.creates.is_empty()
154 && transforms.updates.is_empty()
155 && session_callbacks.callbacks.is_empty()
156 && fields.is_none()
157 && self.config.user.additional_fields.is_empty()
158 && self.config.session.additional_fields.is_empty()
159 && self.config.account.additional_fields.is_empty()
160 && self
161 .extensions
162 .get::<crate::store::AdapterCallbacks<S>>()
163 .is_none_or(|callbacks| callbacks.0.is_empty())
164 && self.config.user_validation.is_none()
165 {
166 return Arc::clone(&self.database);
167 }
168 Arc::new(crate::store::PluginStore::new(
169 Arc::clone(&self.database),
170 Arc::clone(&self.config),
171 transforms,
172 session_callbacks,
173 fields.map_or_else(
174 || {
175 crate::field_policy::SessionFields(
176 self.config.session.additional_fields.clone(),
177 )
178 },
179 |fields| (*fields).clone(),
180 ),
181 self.extensions
182 .get::<crate::field_policy::SessionAdapterFields>()
183 .map(|fields_2| (*fields_2).clone())
184 .unwrap_or_else(|| {
185 crate::field_policy::SessionAdapterFields(Arc::new(
186 self.config.session.additional_fields.clone(),
187 ))
188 }),
189 AuthContext::with_metadata(
190 Arc::clone(&self.config),
191 Arc::clone(&self.database),
192 self.metadata.clone(),
193 )
194 .with_extensions(self.extensions.clone()),
195 ))
196 }
197
198 pub fn set_email_verification_override(
199 &mut self,
200 sender: Arc<dyn VerificationEmailOverride<S>>,
201 ) {
202 self.extensions
203 .insert(VerificationEmailOverrideHandle(sender));
204 }
205
206 #[must_use]
207 pub fn into_parts(self) -> AuthInitParts {
208 AuthInitParts {
209 metadata: self.metadata,
210 email_provider: self.email_provider,
211 extensions: self.extensions,
212 }
213 }
214}
215
216impl std::fmt::Debug for AuthInitParts {
217 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
218 f.debug_struct("AuthInitParts").finish_non_exhaustive()
219 }
220}
221
222impl<S: AuthSchema> std::fmt::Debug for AuthInitContext<S> {
223 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
224 f.debug_struct("AuthInitContext").finish_non_exhaustive()
225 }
226}