From 3ceeecc63ea0839b449c2729878191a9b9a601bc Mon Sep 17 00:00:00 2001
From: nutomic <nutomic@noreply.yerbamate.ml>
Date: Fri, 27 Nov 2020 21:00:18 +0000
Subject: [PATCH] Better account deletion (fixes #730) (#143)

Also clear bio

Better account deletion (fixes #730)

Co-authored-by: Felix Ableitner <me@nutomic.com>
Reviewed-on: https://yerbamate.ml/LemmyNet/lemmy/pulls/143
---
 lemmy_api/src/comment.rs                      |  4 +--
 lemmy_api/src/post.rs                         |  4 +--
 lemmy_api/src/user.rs                         |  5 ++++
 lemmy_db/src/schema.rs                        |  1 +
 lemmy_db/src/user.rs                          | 27 +++++++++++++++++--
 .../2020-11-26-134531_delete_user/down.sql    |  1 +
 .../2020-11-26-134531_delete_user/up.sql      |  1 +
 7 files changed, 37 insertions(+), 6 deletions(-)
 create mode 100644 migrations/2020-11-26-134531_delete_user/down.sql
 create mode 100644 migrations/2020-11-26-134531_delete_user/up.sql

diff --git a/lemmy_api/src/comment.rs b/lemmy_api/src/comment.rs
index b1107d0d..e74fa808 100644
--- a/lemmy_api/src/comment.rs
+++ b/lemmy_api/src/comment.rs
@@ -782,9 +782,9 @@ impl Perform for ResolveCommentReport {
     let resolved = data.resolved;
     let resolve_fun = move |conn: &'_ _| {
       if resolved {
-        CommentReport::resolve(conn, report_id.clone(), user_id)
+        CommentReport::resolve(conn, report_id, user_id)
       } else {
-        CommentReport::unresolve(conn, report_id.clone(), user_id)
+        CommentReport::unresolve(conn, report_id, user_id)
       }
     };
 
diff --git a/lemmy_api/src/post.rs b/lemmy_api/src/post.rs
index 707c8335..d5515b5c 100644
--- a/lemmy_api/src/post.rs
+++ b/lemmy_api/src/post.rs
@@ -839,9 +839,9 @@ impl Perform for ResolvePostReport {
     let resolved = data.resolved;
     let resolve_fun = move |conn: &'_ _| {
       if resolved {
-        PostReport::resolve(conn, report_id.clone(), user_id)
+        PostReport::resolve(conn, report_id, user_id)
       } else {
-        PostReport::unresolve(conn, report_id.clone(), user_id)
+        PostReport::unresolve(conn, report_id, user_id)
       }
     };
 
diff --git a/lemmy_api/src/user.rs b/lemmy_api/src/user.rs
index 3b0b6d3f..0d96c2a2 100644
--- a/lemmy_api/src/user.rs
+++ b/lemmy_api/src/user.rs
@@ -890,6 +890,11 @@ impl Perform for DeleteAccount {
       return Err(APIError::err("couldnt_update_post").into());
     }
 
+    blocking(context.pool(), move |conn| {
+      User_::delete_account(conn, user_id)
+    })
+    .await??;
+
     Ok(LoginResponse {
       jwt: data.auth.to_owned(),
     })
diff --git a/lemmy_db/src/schema.rs b/lemmy_db/src/schema.rs
index 400c87d4..49bbc46f 100644
--- a/lemmy_db/src/schema.rs
+++ b/lemmy_db/src/schema.rs
@@ -467,6 +467,7 @@ table! {
         public_key -> Nullable<Text>,
         last_refreshed_at -> Timestamp,
         banner -> Nullable<Text>,
+        deleted -> Bool,
     }
 }
 
diff --git a/lemmy_db/src/user.rs b/lemmy_db/src/user.rs
index 378bbad9..2c4c67ea 100644
--- a/lemmy_db/src/user.rs
+++ b/lemmy_db/src/user.rs
@@ -37,6 +37,7 @@ pub struct User_ {
   pub public_key: Option<String>,
   pub last_refreshed_at: chrono::NaiveDateTime,
   pub banner: Option<String>,
+  pub deleted: bool,
 }
 
 #[derive(Insertable, AsChangeset, Clone)]
@@ -70,7 +71,10 @@ pub struct UserForm {
 
 impl Crud<UserForm> for User_ {
   fn read(conn: &PgConnection, user_id: i32) -> Result<Self, Error> {
-    user_.find(user_id).first::<Self>(conn)
+    user_
+      .filter(deleted.eq(false))
+      .find(user_id)
+      .first::<Self>(conn)
   }
   fn delete(conn: &PgConnection, user_id: i32) -> Result<usize, Error> {
     diesel::delete(user_.find(user_id)).execute(conn)
@@ -114,6 +118,7 @@ impl User_ {
   pub fn read_from_name(conn: &PgConnection, from_user_name: &str) -> Result<Self, Error> {
     user_
       .filter(local.eq(true))
+      .filter(deleted.eq(false))
       .filter(name.eq(from_user_name))
       .first::<Self>(conn)
   }
@@ -132,7 +137,10 @@ impl User_ {
 
   pub fn read_from_actor_id(conn: &PgConnection, object_id: &str) -> Result<Self, Error> {
     use crate::schema::user_::dsl::*;
-    user_.filter(actor_id.eq(object_id)).first::<Self>(conn)
+    user_
+      .filter(deleted.eq(false))
+      .filter(actor_id.eq(object_id))
+      .first::<Self>(conn)
   }
 
   pub fn find_by_email_or_username(
@@ -148,6 +156,7 @@ impl User_ {
 
   pub fn find_by_username(conn: &PgConnection, username: &str) -> Result<User_, Error> {
     user_
+      .filter(deleted.eq(false))
       .filter(local.eq(true))
       .filter(name.ilike(username))
       .first::<User_>(conn)
@@ -155,6 +164,7 @@ impl User_ {
 
   pub fn find_by_email(conn: &PgConnection, from_email: &str) -> Result<User_, Error> {
     user_
+      .filter(deleted.eq(false))
       .filter(local.eq(true))
       .filter(email.eq(from_email))
       .first::<User_>(conn)
@@ -177,6 +187,19 @@ impl User_ {
       .set(user_form)
       .get_result::<Self>(conn)
   }
+
+  pub fn delete_account(conn: &PgConnection, user_id: i32) -> Result<User_, Error> {
+    diesel::update(user_.find(user_id))
+      .set((
+        preferred_username.eq::<Option<String>>(None),
+        email.eq::<Option<String>>(None),
+        matrix_user_id.eq::<Option<String>>(None),
+        bio.eq::<Option<String>>(None),
+        deleted.eq(true),
+        updated.eq(naive_now()),
+      ))
+      .get_result::<Self>(conn)
+  }
 }
 
 #[cfg(test)]
diff --git a/migrations/2020-11-26-134531_delete_user/down.sql b/migrations/2020-11-26-134531_delete_user/down.sql
new file mode 100644
index 00000000..09b05878
--- /dev/null
+++ b/migrations/2020-11-26-134531_delete_user/down.sql
@@ -0,0 +1 @@
+ALTER TABLE user_ DROP COLUMN deleted;
diff --git a/migrations/2020-11-26-134531_delete_user/up.sql b/migrations/2020-11-26-134531_delete_user/up.sql
new file mode 100644
index 00000000..1d752c57
--- /dev/null
+++ b/migrations/2020-11-26-134531_delete_user/up.sql
@@ -0,0 +1 @@
+ALTER TABLE user_ ADD COLUMN deleted BOOLEAN DEFAULT FALSE NOT NULL;
-- 
2.44.1