]> Untitled Git - lemmy.git/blob - crates/db_schema/src/impls/local_user.rs
Make functions work with both connection and pool (#3420)
[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,
6     email_verified,
7     local_user,
8     password_encrypted,
9     validator_time,
10   },
11   source::{
12     actor_language::{LocalUserLanguage, SiteLanguage},
13     local_user::{LocalUser, LocalUserInsertForm, LocalUserUpdateForm},
14   },
15   traits::Crud,
16   utils::{get_conn, naive_now, DbPool},
17 };
18 use bcrypt::{hash, DEFAULT_COST};
19 use diesel::{dsl::insert_into, result::Error, ExpressionMethods, QueryDsl};
20 use diesel_async::RunQueryDsl;
21
22 impl LocalUser {
23   pub async fn update_password(
24     pool: &mut DbPool<'_>,
25     local_user_id: LocalUserId,
26     new_password: &str,
27   ) -> Result<Self, Error> {
28     let conn = &mut get_conn(pool).await?;
29     let password_hash = hash(new_password, DEFAULT_COST).expect("Couldn't hash password");
30
31     diesel::update(local_user.find(local_user_id))
32       .set((
33         password_encrypted.eq(password_hash),
34         validator_time.eq(naive_now()),
35       ))
36       .get_result::<Self>(conn)
37       .await
38   }
39
40   pub async fn set_all_users_email_verified(pool: &mut DbPool<'_>) -> Result<Vec<Self>, Error> {
41     let conn = &mut get_conn(pool).await?;
42     diesel::update(local_user)
43       .set(email_verified.eq(true))
44       .get_results::<Self>(conn)
45       .await
46   }
47
48   pub async fn set_all_users_registration_applications_accepted(
49     pool: &mut DbPool<'_>,
50   ) -> Result<Vec<Self>, Error> {
51     let conn = &mut get_conn(pool).await?;
52     diesel::update(local_user)
53       .set(accepted_application.eq(true))
54       .get_results::<Self>(conn)
55       .await
56   }
57
58   pub async fn is_email_taken(pool: &mut DbPool<'_>, email_: &str) -> Result<bool, Error> {
59     use diesel::dsl::{exists, select};
60     let conn = &mut get_conn(pool).await?;
61     select(exists(local_user.filter(email.eq(email_))))
62       .get_result(conn)
63       .await
64   }
65 }
66
67 #[async_trait]
68 impl Crud for LocalUser {
69   type InsertForm = LocalUserInsertForm;
70   type UpdateForm = LocalUserUpdateForm;
71   type IdType = LocalUserId;
72   async fn read(pool: &mut DbPool<'_>, local_user_id: LocalUserId) -> Result<Self, Error> {
73     let conn = &mut get_conn(pool).await?;
74     local_user.find(local_user_id).first::<Self>(conn).await
75   }
76   async fn delete(pool: &mut DbPool<'_>, local_user_id: LocalUserId) -> Result<usize, Error> {
77     let conn = &mut get_conn(pool).await?;
78     diesel::delete(local_user.find(local_user_id))
79       .execute(conn)
80       .await
81   }
82   async fn create(pool: &mut DbPool<'_>, form: &Self::InsertForm) -> Result<Self, Error> {
83     let conn = &mut get_conn(pool).await?;
84     let mut form_with_encrypted_password = form.clone();
85     let password_hash =
86       hash(&form.password_encrypted, DEFAULT_COST).expect("Couldn't hash password");
87     form_with_encrypted_password.password_encrypted = password_hash;
88
89     let local_user_ = insert_into(local_user)
90       .values(form_with_encrypted_password)
91       .get_result::<Self>(conn)
92       .await?;
93
94     let site_languages = SiteLanguage::read_local_raw(pool).await;
95     if let Ok(langs) = site_languages {
96       // if site exists, init user with site languages
97       LocalUserLanguage::update(pool, langs, local_user_.id).await?;
98     } else {
99       // otherwise, init with all languages (this only happens during tests and
100       // for first admin user, which is created before site)
101       LocalUserLanguage::update(pool, vec![], local_user_.id).await?;
102     }
103
104     Ok(local_user_)
105   }
106   async fn update(
107     pool: &mut DbPool<'_>,
108     local_user_id: LocalUserId,
109     form: &Self::UpdateForm,
110   ) -> Result<Self, Error> {
111     let conn = &mut get_conn(pool).await?;
112     diesel::update(local_user.find(local_user_id))
113       .set(form)
114       .get_result::<Self>(conn)
115       .await
116   }
117 }