]> Untitled Git - lemmy.git/blobdiff - 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
index 419ab7928947de937fd67aee201c0c634d946db4..0a72811ae37e4b7d203818ed6e9b31f83b16fb6c 100644 (file)
@@ -1,85 +1,31 @@
 use crate::{
   newtypes::LocalUserId,
-  schema::local_user::dsl::*,
-  source::local_user::{LocalUser, LocalUserForm},
+  schema::local_user::dsl::{
+    accepted_application,
+    email,
+    email_verified,
+    local_user,
+    password_encrypted,
+    validator_time,
+  },
+  source::{
+    actor_language::{LocalUserLanguage, SiteLanguage},
+    local_user::{LocalUser, LocalUserInsertForm, LocalUserUpdateForm},
+  },
   traits::Crud,
-  utils::naive_now,
+  utils::{get_conn, naive_now, DbPool},
 };
 use bcrypt::{hash, DEFAULT_COST};
-use diesel::{dsl::*, result::Error, *};
-
-mod safe_settings_type {
-  use crate::{
-    schema::local_user::columns::*,
-    source::local_user::LocalUser,
-    traits::ToSafeSettings,
-  };
-
-  type Columns = (
-    id,
-    person_id,
-    email,
-    show_nsfw,
-    theme,
-    default_sort_type,
-    default_listing_type,
-    lang,
-    show_avatars,
-    send_notifications_to_email,
-    validator_time,
-    show_bot_accounts,
-    show_scores,
-    show_read_posts,
-    show_new_post_notifs,
-    email_verified,
-    accepted_application,
-  );
-
-  impl ToSafeSettings for LocalUser {
-    type SafeSettingsColumns = Columns;
-
-    /// Includes everything but the hashed password
-    fn safe_settings_columns_tuple() -> Self::SafeSettingsColumns {
-      (
-        id,
-        person_id,
-        email,
-        show_nsfw,
-        theme,
-        default_sort_type,
-        default_listing_type,
-        lang,
-        show_avatars,
-        send_notifications_to_email,
-        validator_time,
-        show_bot_accounts,
-        show_scores,
-        show_read_posts,
-        show_new_post_notifs,
-        email_verified,
-        accepted_application,
-      )
-    }
-  }
-}
+use diesel::{dsl::insert_into, result::Error, ExpressionMethods, QueryDsl};
+use diesel_async::RunQueryDsl;
 
 impl LocalUser {
-  pub fn register(conn: &PgConnection, form: &LocalUserForm) -> Result<Self, Error> {
-    let mut edited_user = form.clone();
-    let password_hash = form
-      .password_encrypted
-      .as_ref()
-      .map(|p| hash(p, DEFAULT_COST).expect("Couldn't hash password"));
-    edited_user.password_encrypted = password_hash;
-
-    Self::create(conn, &edited_user)
-  }
-
-  pub fn update_password(
-    conn: &PgConnection,
+  pub async fn update_password(
+    pool: &mut DbPool<'_>,
     local_user_id: LocalUserId,
     new_password: &str,
   ) -> Result<Self, Error> {
+    let conn = &mut get_conn(pool).await?;
     let password_hash = hash(new_password, DEFAULT_COST).expect("Couldn't hash password");
 
     diesel::update(local_user.find(local_user_id))
@@ -88,44 +34,84 @@ impl LocalUser {
         validator_time.eq(naive_now()),
       ))
       .get_result::<Self>(conn)
+      .await
   }
 
-  pub fn set_all_users_email_verified(conn: &PgConnection) -> Result<Vec<Self>, Error> {
+  pub async fn set_all_users_email_verified(pool: &mut DbPool<'_>) -> Result<Vec<Self>, Error> {
+    let conn = &mut get_conn(pool).await?;
     diesel::update(local_user)
       .set(email_verified.eq(true))
       .get_results::<Self>(conn)
+      .await
   }
 
-  pub fn set_all_users_registration_applications_accepted(
-    conn: &PgConnection,
+  pub async fn set_all_users_registration_applications_accepted(
+    pool: &mut DbPool<'_>,
   ) -> Result<Vec<Self>, Error> {
+    let conn = &mut get_conn(pool).await?;
     diesel::update(local_user)
       .set(accepted_application.eq(true))
       .get_results::<Self>(conn)
+      .await
+  }
+
+  pub async fn is_email_taken(pool: &mut DbPool<'_>, email_: &str) -> Result<bool, Error> {
+    use diesel::dsl::{exists, select};
+    let conn = &mut get_conn(pool).await?;
+    select(exists(local_user.filter(email.eq(email_))))
+      .get_result(conn)
+      .await
   }
 }
 
+#[async_trait]
 impl Crud for LocalUser {
-  type Form = LocalUserForm;
+  type InsertForm = LocalUserInsertForm;
+  type UpdateForm = LocalUserUpdateForm;
   type IdType = LocalUserId;
-  fn read(conn: &PgConnection, local_user_id: LocalUserId) -> Result<Self, Error> {
-    local_user.find(local_user_id).first::<Self>(conn)
+  async fn read(pool: &mut DbPool<'_>, local_user_id: LocalUserId) -> Result<Self, Error> {
+    let conn = &mut get_conn(pool).await?;
+    local_user.find(local_user_id).first::<Self>(conn).await
   }
-  fn delete(conn: &PgConnection, local_user_id: LocalUserId) -> Result<usize, Error> {
-    diesel::delete(local_user.find(local_user_id)).execute(conn)
+  async fn delete(pool: &mut DbPool<'_>, local_user_id: LocalUserId) -> Result<usize, Error> {
+    let conn = &mut get_conn(pool).await?;
+    diesel::delete(local_user.find(local_user_id))
+      .execute(conn)
+      .await
   }
-  fn create(conn: &PgConnection, form: &LocalUserForm) -> Result<Self, Error> {
-    insert_into(local_user)
-      .values(form)
+  async fn create(pool: &mut DbPool<'_>, form: &Self::InsertForm) -> Result<Self, Error> {
+    let conn = &mut get_conn(pool).await?;
+    let mut form_with_encrypted_password = form.clone();
+    let password_hash =
+      hash(&form.password_encrypted, DEFAULT_COST).expect("Couldn't hash password");
+    form_with_encrypted_password.password_encrypted = password_hash;
+
+    let local_user_ = insert_into(local_user)
+      .values(form_with_encrypted_password)
       .get_result::<Self>(conn)
+      .await?;
+
+    let site_languages = SiteLanguage::read_local_raw(pool).await;
+    if let Ok(langs) = site_languages {
+      // if site exists, init user with site languages
+      LocalUserLanguage::update(pool, langs, local_user_.id).await?;
+    } else {
+      // otherwise, init with all languages (this only happens during tests and
+      // for first admin user, which is created before site)
+      LocalUserLanguage::update(pool, vec![], local_user_.id).await?;
+    }
+
+    Ok(local_user_)
   }
-  fn update(
-    conn: &PgConnection,
+  async fn update(
+    pool: &mut DbPool<'_>,
     local_user_id: LocalUserId,
-    form: &LocalUserForm,
+    form: &Self::UpdateForm,
   ) -> Result<Self, Error> {
+    let conn = &mut get_conn(pool).await?;
     diesel::update(local_user.find(local_user_id))
       .set(form)
       .get_result::<Self>(conn)
+      .await
   }
 }