1use async_trait::async_trait;
2use sea_orm::{prelude::Uuid, DatabaseConnection, ModelTrait};
3use shield::{EmailAddress, StorageError};
4
5#[cfg(feature = "entity")]
6use crate::entities::entity;
7use crate::entities::{email_address, user};
8
9#[derive(Clone, Debug)]
10pub struct User {
11 database: DatabaseConnection,
12 user: user::Model,
13 #[cfg(feature = "entity")]
14 entity: entity::Model,
15}
16
17impl User {
18 pub(crate) fn new(
19 database: DatabaseConnection,
20 user: user::Model,
21 #[cfg(feature = "entity")] entity: entity::Model,
22 ) -> Self {
23 Self {
24 database,
25 user,
26 #[cfg(feature = "entity")]
27 entity,
28 }
29 }
30}
31
32#[async_trait]
33impl shield::User for User {
34 fn id(&self) -> String {
35 self.user.id.to_string()
36 }
37
38 fn name(&self) -> Option<String> {
39 #[cfg(feature = "entity")]
40 {
41 Some(self.entity.name.clone())
42 }
43
44 #[cfg(not(feature = "entity"))]
45 {
46 Some(self.user.name.clone())
47 }
48 }
49
50 async fn email_addresses(&self) -> Result<Vec<EmailAddress>, StorageError> {
51 #[cfg(feature = "entity")]
52 {
53 self.entity
54 .find_related(email_address::Entity)
55 .all(&self.database)
56 .await
57 .map_err(|err| StorageError::Engine(err.to_string()))
58 .map(|email_addresses| {
59 email_addresses
60 .into_iter()
61 .map(|email_address| {
62 EmailAddress::from(EmailAddressWithUserId(email_address, self.user.id))
63 })
64 .collect()
65 })
66 }
67
68 #[cfg(not(feature = "entity"))]
69 {
70 self.user
71 .find_related(email_address::Entity)
72 .all(&self.database)
73 .await
74 .map_err(|err| StorageError::Engine(err.to_string()))
75 .map(|email_addresses| {
76 email_addresses
77 .into_iter()
78 .map(EmailAddress::from)
79 .collect()
80 })
81 }
82 }
83}
84
85#[cfg(not(feature = "entity"))]
86impl From<email_address::Model> for EmailAddress {
87 fn from(value: email_address::Model) -> Self {
88 Self {
89 id: value.id.to_string(),
90 email: value.email,
91 is_primary: value.is_primary,
92 is_verified: value.is_verified,
93 verification_token: value.verification_token,
94 verification_token_expired_at: value.verification_token_expired_at,
95 verified_at: value.verified_at,
96 user_id: value.user_id.to_string(),
97 }
98 }
99}
100
101struct EmailAddressWithUserId(email_address::Model, Uuid);
102
103impl From<EmailAddressWithUserId> for EmailAddress {
104 fn from(EmailAddressWithUserId(value, user_id): EmailAddressWithUserId) -> Self {
105 Self {
106 id: value.id.to_string(),
107 email: value.email,
108 is_primary: value.is_primary,
109 is_verified: value.is_verified,
110 verification_token: value.verification_token,
111 verification_token_expired_at: value.verification_token_expired_at,
112 verified_at: value.verified_at,
113 user_id: user_id.to_string(),
114 }
115 }
116}