]> Untitled Git - lemmy.git/blob - crates/db_schema/src/impls/local_user.rs
Automatically resolve report when post/comment is removed (#3850)
[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
73   async fn create(pool: &mut DbPool<'_>, form: &Self::InsertForm) -> Result<Self, Error> {
74     let conn = &mut get_conn(pool).await?;
75     let mut form_with_encrypted_password = form.clone();
76     let password_hash =
77       hash(&form.password_encrypted, DEFAULT_COST).expect("Couldn't hash password");
78     form_with_encrypted_password.password_encrypted = password_hash;
79
80     let local_user_ = insert_into(local_user)
81       .values(form_with_encrypted_password)
82       .get_result::<Self>(conn)
83       .await?;
84
85     let site_languages = SiteLanguage::read_local_raw(pool).await;
86     if let Ok(langs) = site_languages {
87       // if site exists, init user with site languages
88       LocalUserLanguage::update(pool, langs, local_user_.id).await?;
89     } else {
90       // otherwise, init with all languages (this only happens during tests and
91       // for first admin user, which is created before site)
92       LocalUserLanguage::update(pool, vec![], local_user_.id).await?;
93     }
94
95     Ok(local_user_)
96   }
97   async fn update(
98     pool: &mut DbPool<'_>,
99     local_user_id: LocalUserId,
100     form: &Self::UpdateForm,
101   ) -> Result<Self, Error> {
102     let conn = &mut get_conn(pool).await?;
103     diesel::update(local_user.find(local_user_id))
104       .set(form)
105       .get_result::<Self>(conn)
106       .await
107   }
108 }