]> Untitled Git - lemmy.git/blob - crates/db_schema/src/impls/local_user.rs
Various pedantic clippy fixes (#2568)
[lemmy.git] / crates / db_schema / src / impls / local_user.rs
1 use crate::{
2   newtypes::LocalUserId,
3   schema::local_user::dsl::{
4     accepted_application,
5     email_verified,
6     local_user,
7     password_encrypted,
8     validator_time,
9   },
10   source::{
11     actor_language::{LocalUserLanguage, SiteLanguage},
12     local_user::{LocalUser, LocalUserInsertForm, LocalUserUpdateForm},
13   },
14   traits::Crud,
15   utils::{get_conn, naive_now, DbPool},
16 };
17 use bcrypt::{hash, DEFAULT_COST};
18 use diesel::{dsl::insert_into, result::Error, ExpressionMethods, QueryDsl};
19 use diesel_async::RunQueryDsl;
20
21 mod safe_settings_type {
22   use crate::{
23     schema::local_user::columns::{
24       accepted_application,
25       default_listing_type,
26       default_sort_type,
27       email,
28       email_verified,
29       id,
30       interface_language,
31       person_id,
32       send_notifications_to_email,
33       show_avatars,
34       show_bot_accounts,
35       show_new_post_notifs,
36       show_nsfw,
37       show_read_posts,
38       show_scores,
39       theme,
40       validator_time,
41     },
42     source::local_user::LocalUser,
43     traits::ToSafeSettings,
44   };
45
46   type Columns = (
47     id,
48     person_id,
49     email,
50     show_nsfw,
51     theme,
52     default_sort_type,
53     default_listing_type,
54     interface_language,
55     show_avatars,
56     send_notifications_to_email,
57     validator_time,
58     show_bot_accounts,
59     show_scores,
60     show_read_posts,
61     show_new_post_notifs,
62     email_verified,
63     accepted_application,
64   );
65
66   impl ToSafeSettings for LocalUser {
67     type SafeSettingsColumns = Columns;
68
69     /// Includes everything but the hashed password
70     fn safe_settings_columns_tuple() -> Self::SafeSettingsColumns {
71       (
72         id,
73         person_id,
74         email,
75         show_nsfw,
76         theme,
77         default_sort_type,
78         default_listing_type,
79         interface_language,
80         show_avatars,
81         send_notifications_to_email,
82         validator_time,
83         show_bot_accounts,
84         show_scores,
85         show_read_posts,
86         show_new_post_notifs,
87         email_verified,
88         accepted_application,
89       )
90     }
91   }
92 }
93
94 impl LocalUser {
95   pub async fn update_password(
96     pool: &DbPool,
97     local_user_id: LocalUserId,
98     new_password: &str,
99   ) -> Result<Self, Error> {
100     let conn = &mut get_conn(pool).await?;
101     let password_hash = hash(new_password, DEFAULT_COST).expect("Couldn't hash password");
102
103     diesel::update(local_user.find(local_user_id))
104       .set((
105         password_encrypted.eq(password_hash),
106         validator_time.eq(naive_now()),
107       ))
108       .get_result::<Self>(conn)
109       .await
110   }
111
112   pub async fn set_all_users_email_verified(pool: &DbPool) -> Result<Vec<Self>, Error> {
113     let conn = &mut get_conn(pool).await?;
114     diesel::update(local_user)
115       .set(email_verified.eq(true))
116       .get_results::<Self>(conn)
117       .await
118   }
119
120   pub async fn set_all_users_registration_applications_accepted(
121     pool: &DbPool,
122   ) -> Result<Vec<Self>, Error> {
123     let conn = &mut get_conn(pool).await?;
124     diesel::update(local_user)
125       .set(accepted_application.eq(true))
126       .get_results::<Self>(conn)
127       .await
128   }
129 }
130
131 #[async_trait]
132 impl Crud for LocalUser {
133   type InsertForm = LocalUserInsertForm;
134   type UpdateForm = LocalUserUpdateForm;
135   type IdType = LocalUserId;
136   async fn read(pool: &DbPool, local_user_id: LocalUserId) -> Result<Self, Error> {
137     let conn = &mut get_conn(pool).await?;
138     local_user.find(local_user_id).first::<Self>(conn).await
139   }
140   async fn delete(pool: &DbPool, local_user_id: LocalUserId) -> Result<usize, Error> {
141     let conn = &mut get_conn(pool).await?;
142     diesel::delete(local_user.find(local_user_id))
143       .execute(conn)
144       .await
145   }
146   async fn create(pool: &DbPool, form: &Self::InsertForm) -> Result<Self, Error> {
147     let conn = &mut get_conn(pool).await?;
148     let mut form_with_encrypted_password = form.clone();
149     let password_hash =
150       hash(&form.password_encrypted, DEFAULT_COST).expect("Couldn't hash password");
151     form_with_encrypted_password.password_encrypted = password_hash;
152
153     let local_user_ = insert_into(local_user)
154       .values(form_with_encrypted_password)
155       .get_result::<Self>(conn)
156       .await
157       .expect("couldnt create local user");
158
159     let site_languages = SiteLanguage::read_local(pool).await;
160     if let Ok(langs) = site_languages {
161       // if site exists, init user with site languages
162       LocalUserLanguage::update(pool, langs, local_user_.id).await?;
163     } else {
164       // otherwise, init with all languages (this only happens during tests and
165       // for first admin user, which is created before site)
166       LocalUserLanguage::update(pool, vec![], local_user_.id).await?;
167     }
168
169     Ok(local_user_)
170   }
171   async fn update(
172     pool: &DbPool,
173     local_user_id: LocalUserId,
174     form: &Self::UpdateForm,
175   ) -> Result<Self, Error> {
176     let conn = &mut get_conn(pool).await?;
177     diesel::update(local_user.find(local_user_id))
178       .set(form)
179       .get_result::<Self>(conn)
180       .await
181   }
182 }