1use async_trait::async_trait;
8use futures_util::future::BoxFuture;
9use thiserror::Error;
10
11use crate::{
12 app_session::AppSessionRepository,
13 compat::{
14 CompatAccessTokenRepository, CompatRefreshTokenRepository, CompatSessionRepository,
15 CompatSsoLoginRepository,
16 },
17 oauth2::{
18 OAuth2AccessTokenRepository, OAuth2AuthorizationGrantRepository, OAuth2ClientRepository,
19 OAuth2DeviceCodeGrantRepository, OAuth2RefreshTokenRepository, OAuth2SessionRepository,
20 },
21 policy_data::PolicyDataRepository,
22 queue::{QueueJobRepository, QueueScheduleRepository, QueueWorkerRepository},
23 upstream_oauth2::{
24 UpstreamOAuthLinkRepository, UpstreamOAuthProviderRepository,
25 UpstreamOAuthSessionRepository,
26 },
27 user::{
28 BrowserSessionRepository, UserEmailRepository, UserPasswordRepository,
29 UserRecoveryRepository, UserRegistrationRepository, UserRegistrationTokenRepository,
30 UserRepository, UserTermsRepository,
31 },
32};
33
34#[async_trait]
38pub trait RepositoryFactory {
39 async fn create(&self) -> Result<BoxRepository, RepositoryError>;
41}
42
43pub type BoxRepositoryFactory = Box<dyn RepositoryFactory + Send + Sync + 'static>;
45
46pub trait Repository<E>:
48 RepositoryAccess<Error = E> + RepositoryTransaction<Error = E> + Send
49where
50 E: std::error::Error + Send + Sync + 'static,
51{
52}
53
54#[derive(Debug, Error)]
56#[error(transparent)]
57pub struct RepositoryError {
58 source: Box<dyn std::error::Error + Send + Sync + 'static>,
59}
60
61impl RepositoryError {
62 pub fn from_error<E>(value: E) -> Self
64 where
65 E: std::error::Error + Send + Sync + 'static,
66 {
67 Self {
68 source: Box::new(value),
69 }
70 }
71}
72
73pub type BoxRepository = Box<dyn Repository<RepositoryError> + Send + Sync + 'static>;
75
76pub trait RepositoryTransaction {
79 type Error;
81
82 fn save(self: Box<Self>) -> BoxFuture<'static, Result<(), Self::Error>>;
89
90 fn cancel(self: Box<Self>) -> BoxFuture<'static, Result<(), Self::Error>>;
97}
98
99pub trait RepositoryAccess: Send {
115 type Error: std::error::Error + Send + Sync + 'static;
117
118 fn upstream_oauth_link<'c>(
120 &'c mut self,
121 ) -> Box<dyn UpstreamOAuthLinkRepository<Error = Self::Error> + 'c>;
122
123 fn upstream_oauth_provider<'c>(
125 &'c mut self,
126 ) -> Box<dyn UpstreamOAuthProviderRepository<Error = Self::Error> + 'c>;
127
128 fn upstream_oauth_session<'c>(
130 &'c mut self,
131 ) -> Box<dyn UpstreamOAuthSessionRepository<Error = Self::Error> + 'c>;
132
133 fn user<'c>(&'c mut self) -> Box<dyn UserRepository<Error = Self::Error> + 'c>;
135
136 fn user_email<'c>(&'c mut self) -> Box<dyn UserEmailRepository<Error = Self::Error> + 'c>;
138
139 fn user_password<'c>(&'c mut self)
141 -> Box<dyn UserPasswordRepository<Error = Self::Error> + 'c>;
142
143 fn user_recovery<'c>(&'c mut self)
145 -> Box<dyn UserRecoveryRepository<Error = Self::Error> + 'c>;
146
147 fn user_registration<'c>(
149 &'c mut self,
150 ) -> Box<dyn UserRegistrationRepository<Error = Self::Error> + 'c>;
151
152 fn user_registration_token<'c>(
154 &'c mut self,
155 ) -> Box<dyn UserRegistrationTokenRepository<Error = Self::Error> + 'c>;
156
157 fn user_terms<'c>(&'c mut self) -> Box<dyn UserTermsRepository<Error = Self::Error> + 'c>;
159
160 fn browser_session<'c>(
162 &'c mut self,
163 ) -> Box<dyn BrowserSessionRepository<Error = Self::Error> + 'c>;
164
165 fn app_session<'c>(&'c mut self) -> Box<dyn AppSessionRepository<Error = Self::Error> + 'c>;
167
168 fn oauth2_client<'c>(&'c mut self)
170 -> Box<dyn OAuth2ClientRepository<Error = Self::Error> + 'c>;
171
172 fn oauth2_authorization_grant<'c>(
174 &'c mut self,
175 ) -> Box<dyn OAuth2AuthorizationGrantRepository<Error = Self::Error> + 'c>;
176
177 fn oauth2_session<'c>(
179 &'c mut self,
180 ) -> Box<dyn OAuth2SessionRepository<Error = Self::Error> + 'c>;
181
182 fn oauth2_access_token<'c>(
184 &'c mut self,
185 ) -> Box<dyn OAuth2AccessTokenRepository<Error = Self::Error> + 'c>;
186
187 fn oauth2_refresh_token<'c>(
189 &'c mut self,
190 ) -> Box<dyn OAuth2RefreshTokenRepository<Error = Self::Error> + 'c>;
191
192 fn oauth2_device_code_grant<'c>(
194 &'c mut self,
195 ) -> Box<dyn OAuth2DeviceCodeGrantRepository<Error = Self::Error> + 'c>;
196
197 fn compat_session<'c>(
199 &'c mut self,
200 ) -> Box<dyn CompatSessionRepository<Error = Self::Error> + 'c>;
201
202 fn compat_sso_login<'c>(
204 &'c mut self,
205 ) -> Box<dyn CompatSsoLoginRepository<Error = Self::Error> + 'c>;
206
207 fn compat_access_token<'c>(
209 &'c mut self,
210 ) -> Box<dyn CompatAccessTokenRepository<Error = Self::Error> + 'c>;
211
212 fn compat_refresh_token<'c>(
214 &'c mut self,
215 ) -> Box<dyn CompatRefreshTokenRepository<Error = Self::Error> + 'c>;
216
217 fn queue_worker<'c>(&'c mut self) -> Box<dyn QueueWorkerRepository<Error = Self::Error> + 'c>;
219
220 fn queue_job<'c>(&'c mut self) -> Box<dyn QueueJobRepository<Error = Self::Error> + 'c>;
222
223 fn queue_schedule<'c>(
225 &'c mut self,
226 ) -> Box<dyn QueueScheduleRepository<Error = Self::Error> + 'c>;
227
228 fn policy_data<'c>(&'c mut self) -> Box<dyn PolicyDataRepository<Error = Self::Error> + 'c>;
230}
231
232mod impls {
235 use futures_util::{FutureExt, TryFutureExt, future::BoxFuture};
236
237 use super::RepositoryAccess;
238 use crate::{
239 MapErr, Repository, RepositoryTransaction,
240 app_session::AppSessionRepository,
241 compat::{
242 CompatAccessTokenRepository, CompatRefreshTokenRepository, CompatSessionRepository,
243 CompatSsoLoginRepository,
244 },
245 oauth2::{
246 OAuth2AccessTokenRepository, OAuth2AuthorizationGrantRepository,
247 OAuth2ClientRepository, OAuth2DeviceCodeGrantRepository, OAuth2RefreshTokenRepository,
248 OAuth2SessionRepository,
249 },
250 policy_data::PolicyDataRepository,
251 queue::{QueueJobRepository, QueueScheduleRepository, QueueWorkerRepository},
252 upstream_oauth2::{
253 UpstreamOAuthLinkRepository, UpstreamOAuthProviderRepository,
254 UpstreamOAuthSessionRepository,
255 },
256 user::{
257 BrowserSessionRepository, UserEmailRepository, UserPasswordRepository,
258 UserRegistrationRepository, UserRegistrationTokenRepository, UserRepository,
259 UserTermsRepository,
260 },
261 };
262
263 impl<R, F, E1, E2> Repository<E2> for MapErr<R, F>
265 where
266 R: Repository<E1> + RepositoryAccess<Error = E1> + RepositoryTransaction<Error = E1>,
267 F: FnMut(E1) -> E2 + Send + Sync + 'static,
268 E1: std::error::Error + Send + Sync + 'static,
269 E2: std::error::Error + Send + Sync + 'static,
270 {
271 }
272
273 impl<R, F, E> RepositoryTransaction for MapErr<R, F>
275 where
276 R: RepositoryTransaction,
277 R::Error: 'static,
278 F: FnMut(R::Error) -> E + Send + Sync + 'static,
279 E: std::error::Error,
280 {
281 type Error = E;
282
283 fn save(self: Box<Self>) -> BoxFuture<'static, Result<(), Self::Error>> {
284 Box::new(self.inner).save().map_err(self.mapper).boxed()
285 }
286
287 fn cancel(self: Box<Self>) -> BoxFuture<'static, Result<(), Self::Error>> {
288 Box::new(self.inner).cancel().map_err(self.mapper).boxed()
289 }
290 }
291
292 impl<R, F, E> RepositoryAccess for MapErr<R, F>
294 where
295 R: RepositoryAccess,
296 R::Error: 'static,
297 F: FnMut(R::Error) -> E + Send + Sync + 'static,
298 E: std::error::Error + Send + Sync + 'static,
299 {
300 type Error = E;
301
302 fn upstream_oauth_link<'c>(
303 &'c mut self,
304 ) -> Box<dyn UpstreamOAuthLinkRepository<Error = Self::Error> + 'c> {
305 Box::new(MapErr::new(
306 self.inner.upstream_oauth_link(),
307 &mut self.mapper,
308 ))
309 }
310
311 fn upstream_oauth_provider<'c>(
312 &'c mut self,
313 ) -> Box<dyn UpstreamOAuthProviderRepository<Error = Self::Error> + 'c> {
314 Box::new(MapErr::new(
315 self.inner.upstream_oauth_provider(),
316 &mut self.mapper,
317 ))
318 }
319
320 fn upstream_oauth_session<'c>(
321 &'c mut self,
322 ) -> Box<dyn UpstreamOAuthSessionRepository<Error = Self::Error> + 'c> {
323 Box::new(MapErr::new(
324 self.inner.upstream_oauth_session(),
325 &mut self.mapper,
326 ))
327 }
328
329 fn user<'c>(&'c mut self) -> Box<dyn UserRepository<Error = Self::Error> + 'c> {
330 Box::new(MapErr::new(self.inner.user(), &mut self.mapper))
331 }
332
333 fn user_email<'c>(&'c mut self) -> Box<dyn UserEmailRepository<Error = Self::Error> + 'c> {
334 Box::new(MapErr::new(self.inner.user_email(), &mut self.mapper))
335 }
336
337 fn user_password<'c>(
338 &'c mut self,
339 ) -> Box<dyn UserPasswordRepository<Error = Self::Error> + 'c> {
340 Box::new(MapErr::new(self.inner.user_password(), &mut self.mapper))
341 }
342
343 fn user_recovery<'c>(
344 &'c mut self,
345 ) -> Box<dyn crate::user::UserRecoveryRepository<Error = Self::Error> + 'c> {
346 Box::new(MapErr::new(self.inner.user_recovery(), &mut self.mapper))
347 }
348
349 fn user_registration<'c>(
350 &'c mut self,
351 ) -> Box<dyn UserRegistrationRepository<Error = Self::Error> + 'c> {
352 Box::new(MapErr::new(
353 self.inner.user_registration(),
354 &mut self.mapper,
355 ))
356 }
357
358 fn user_registration_token<'c>(
359 &'c mut self,
360 ) -> Box<dyn UserRegistrationTokenRepository<Error = Self::Error> + 'c> {
361 Box::new(MapErr::new(
362 self.inner.user_registration_token(),
363 &mut self.mapper,
364 ))
365 }
366
367 fn user_terms<'c>(&'c mut self) -> Box<dyn UserTermsRepository<Error = Self::Error> + 'c> {
368 Box::new(MapErr::new(self.inner.user_terms(), &mut self.mapper))
369 }
370
371 fn browser_session<'c>(
372 &'c mut self,
373 ) -> Box<dyn BrowserSessionRepository<Error = Self::Error> + 'c> {
374 Box::new(MapErr::new(self.inner.browser_session(), &mut self.mapper))
375 }
376
377 fn app_session<'c>(
378 &'c mut self,
379 ) -> Box<dyn AppSessionRepository<Error = Self::Error> + 'c> {
380 Box::new(MapErr::new(self.inner.app_session(), &mut self.mapper))
381 }
382
383 fn oauth2_client<'c>(
384 &'c mut self,
385 ) -> Box<dyn OAuth2ClientRepository<Error = Self::Error> + 'c> {
386 Box::new(MapErr::new(self.inner.oauth2_client(), &mut self.mapper))
387 }
388
389 fn oauth2_authorization_grant<'c>(
390 &'c mut self,
391 ) -> Box<dyn OAuth2AuthorizationGrantRepository<Error = Self::Error> + 'c> {
392 Box::new(MapErr::new(
393 self.inner.oauth2_authorization_grant(),
394 &mut self.mapper,
395 ))
396 }
397
398 fn oauth2_session<'c>(
399 &'c mut self,
400 ) -> Box<dyn OAuth2SessionRepository<Error = Self::Error> + 'c> {
401 Box::new(MapErr::new(self.inner.oauth2_session(), &mut self.mapper))
402 }
403
404 fn oauth2_access_token<'c>(
405 &'c mut self,
406 ) -> Box<dyn OAuth2AccessTokenRepository<Error = Self::Error> + 'c> {
407 Box::new(MapErr::new(
408 self.inner.oauth2_access_token(),
409 &mut self.mapper,
410 ))
411 }
412
413 fn oauth2_refresh_token<'c>(
414 &'c mut self,
415 ) -> Box<dyn OAuth2RefreshTokenRepository<Error = Self::Error> + 'c> {
416 Box::new(MapErr::new(
417 self.inner.oauth2_refresh_token(),
418 &mut self.mapper,
419 ))
420 }
421
422 fn oauth2_device_code_grant<'c>(
423 &'c mut self,
424 ) -> Box<dyn OAuth2DeviceCodeGrantRepository<Error = Self::Error> + 'c> {
425 Box::new(MapErr::new(
426 self.inner.oauth2_device_code_grant(),
427 &mut self.mapper,
428 ))
429 }
430
431 fn compat_session<'c>(
432 &'c mut self,
433 ) -> Box<dyn CompatSessionRepository<Error = Self::Error> + 'c> {
434 Box::new(MapErr::new(self.inner.compat_session(), &mut self.mapper))
435 }
436
437 fn compat_sso_login<'c>(
438 &'c mut self,
439 ) -> Box<dyn CompatSsoLoginRepository<Error = Self::Error> + 'c> {
440 Box::new(MapErr::new(self.inner.compat_sso_login(), &mut self.mapper))
441 }
442
443 fn compat_access_token<'c>(
444 &'c mut self,
445 ) -> Box<dyn CompatAccessTokenRepository<Error = Self::Error> + 'c> {
446 Box::new(MapErr::new(
447 self.inner.compat_access_token(),
448 &mut self.mapper,
449 ))
450 }
451
452 fn compat_refresh_token<'c>(
453 &'c mut self,
454 ) -> Box<dyn CompatRefreshTokenRepository<Error = Self::Error> + 'c> {
455 Box::new(MapErr::new(
456 self.inner.compat_refresh_token(),
457 &mut self.mapper,
458 ))
459 }
460
461 fn queue_worker<'c>(
462 &'c mut self,
463 ) -> Box<dyn QueueWorkerRepository<Error = Self::Error> + 'c> {
464 Box::new(MapErr::new(self.inner.queue_worker(), &mut self.mapper))
465 }
466
467 fn queue_job<'c>(&'c mut self) -> Box<dyn QueueJobRepository<Error = Self::Error> + 'c> {
468 Box::new(MapErr::new(self.inner.queue_job(), &mut self.mapper))
469 }
470
471 fn queue_schedule<'c>(
472 &'c mut self,
473 ) -> Box<dyn QueueScheduleRepository<Error = Self::Error> + 'c> {
474 Box::new(MapErr::new(self.inner.queue_schedule(), &mut self.mapper))
475 }
476
477 fn policy_data<'c>(
478 &'c mut self,
479 ) -> Box<dyn PolicyDataRepository<Error = Self::Error> + 'c> {
480 Box::new(MapErr::new(self.inner.policy_data(), &mut self.mapper))
481 }
482 }
483
484 impl<R: RepositoryAccess + ?Sized> RepositoryAccess for Box<R> {
485 type Error = R::Error;
486
487 fn upstream_oauth_link<'c>(
488 &'c mut self,
489 ) -> Box<dyn UpstreamOAuthLinkRepository<Error = Self::Error> + 'c> {
490 (**self).upstream_oauth_link()
491 }
492
493 fn upstream_oauth_provider<'c>(
494 &'c mut self,
495 ) -> Box<dyn UpstreamOAuthProviderRepository<Error = Self::Error> + 'c> {
496 (**self).upstream_oauth_provider()
497 }
498
499 fn upstream_oauth_session<'c>(
500 &'c mut self,
501 ) -> Box<dyn UpstreamOAuthSessionRepository<Error = Self::Error> + 'c> {
502 (**self).upstream_oauth_session()
503 }
504
505 fn user<'c>(&'c mut self) -> Box<dyn UserRepository<Error = Self::Error> + 'c> {
506 (**self).user()
507 }
508
509 fn user_email<'c>(&'c mut self) -> Box<dyn UserEmailRepository<Error = Self::Error> + 'c> {
510 (**self).user_email()
511 }
512
513 fn user_password<'c>(
514 &'c mut self,
515 ) -> Box<dyn UserPasswordRepository<Error = Self::Error> + 'c> {
516 (**self).user_password()
517 }
518
519 fn user_recovery<'c>(
520 &'c mut self,
521 ) -> Box<dyn crate::user::UserRecoveryRepository<Error = Self::Error> + 'c> {
522 (**self).user_recovery()
523 }
524
525 fn user_registration<'c>(
526 &'c mut self,
527 ) -> Box<dyn UserRegistrationRepository<Error = Self::Error> + 'c> {
528 (**self).user_registration()
529 }
530
531 fn user_registration_token<'c>(
532 &'c mut self,
533 ) -> Box<dyn UserRegistrationTokenRepository<Error = Self::Error> + 'c> {
534 (**self).user_registration_token()
535 }
536
537 fn user_terms<'c>(&'c mut self) -> Box<dyn UserTermsRepository<Error = Self::Error> + 'c> {
538 (**self).user_terms()
539 }
540
541 fn browser_session<'c>(
542 &'c mut self,
543 ) -> Box<dyn BrowserSessionRepository<Error = Self::Error> + 'c> {
544 (**self).browser_session()
545 }
546
547 fn app_session<'c>(
548 &'c mut self,
549 ) -> Box<dyn AppSessionRepository<Error = Self::Error> + 'c> {
550 (**self).app_session()
551 }
552
553 fn oauth2_client<'c>(
554 &'c mut self,
555 ) -> Box<dyn OAuth2ClientRepository<Error = Self::Error> + 'c> {
556 (**self).oauth2_client()
557 }
558
559 fn oauth2_authorization_grant<'c>(
560 &'c mut self,
561 ) -> Box<dyn OAuth2AuthorizationGrantRepository<Error = Self::Error> + 'c> {
562 (**self).oauth2_authorization_grant()
563 }
564
565 fn oauth2_session<'c>(
566 &'c mut self,
567 ) -> Box<dyn OAuth2SessionRepository<Error = Self::Error> + 'c> {
568 (**self).oauth2_session()
569 }
570
571 fn oauth2_access_token<'c>(
572 &'c mut self,
573 ) -> Box<dyn OAuth2AccessTokenRepository<Error = Self::Error> + 'c> {
574 (**self).oauth2_access_token()
575 }
576
577 fn oauth2_refresh_token<'c>(
578 &'c mut self,
579 ) -> Box<dyn OAuth2RefreshTokenRepository<Error = Self::Error> + 'c> {
580 (**self).oauth2_refresh_token()
581 }
582
583 fn oauth2_device_code_grant<'c>(
584 &'c mut self,
585 ) -> Box<dyn OAuth2DeviceCodeGrantRepository<Error = Self::Error> + 'c> {
586 (**self).oauth2_device_code_grant()
587 }
588
589 fn compat_session<'c>(
590 &'c mut self,
591 ) -> Box<dyn CompatSessionRepository<Error = Self::Error> + 'c> {
592 (**self).compat_session()
593 }
594
595 fn compat_sso_login<'c>(
596 &'c mut self,
597 ) -> Box<dyn CompatSsoLoginRepository<Error = Self::Error> + 'c> {
598 (**self).compat_sso_login()
599 }
600
601 fn compat_access_token<'c>(
602 &'c mut self,
603 ) -> Box<dyn CompatAccessTokenRepository<Error = Self::Error> + 'c> {
604 (**self).compat_access_token()
605 }
606
607 fn compat_refresh_token<'c>(
608 &'c mut self,
609 ) -> Box<dyn CompatRefreshTokenRepository<Error = Self::Error> + 'c> {
610 (**self).compat_refresh_token()
611 }
612
613 fn queue_worker<'c>(
614 &'c mut self,
615 ) -> Box<dyn QueueWorkerRepository<Error = Self::Error> + 'c> {
616 (**self).queue_worker()
617 }
618
619 fn queue_job<'c>(&'c mut self) -> Box<dyn QueueJobRepository<Error = Self::Error> + 'c> {
620 (**self).queue_job()
621 }
622
623 fn queue_schedule<'c>(
624 &'c mut self,
625 ) -> Box<dyn QueueScheduleRepository<Error = Self::Error> + 'c> {
626 (**self).queue_schedule()
627 }
628
629 fn policy_data<'c>(
630 &'c mut self,
631 ) -> Box<dyn PolicyDataRepository<Error = Self::Error> + 'c> {
632 (**self).policy_data()
633 }
634 }
635}