From d55faa2f8fc3d613a3fa44b521fed27f8231c558 Mon Sep 17 00:00:00 2001 From: Alex Gleason Date: Mon, 17 Aug 2020 21:52:28 -0500 Subject: [PATCH 1/5] Purge a local user upon deletion, fixes #2062 --- lib/pleroma/user.ex | 14 ++++++++++- .../controllers/admin_api_controller_test.exs | 25 +++++++++++++++++-- 2 files changed, 36 insertions(+), 3 deletions(-) diff --git a/lib/pleroma/user.ex b/lib/pleroma/user.ex index ac065e9dc..a8bdcdad7 100644 --- a/lib/pleroma/user.ex +++ b/lib/pleroma/user.ex @@ -1583,6 +1583,18 @@ defmodule Pleroma.User do |> update_and_set_cache() end + @spec purge_user_changeset(User.t()) :: Changeset.t() + def purge_user_changeset(user) do + change(user, %{ + deactivated: true, + email: nil, + avatar: %{}, + banner: %{}, + background: %{}, + fields: [] + }) + end + def delete(users) when is_list(users) do for user <- users, do: delete(user) end @@ -1610,7 +1622,7 @@ defmodule Pleroma.User do _ -> user - |> change(%{deactivated: true, email: nil}) + |> purge_user_changeset() |> update_and_set_cache() end end diff --git a/test/web/admin_api/controllers/admin_api_controller_test.exs b/test/web/admin_api/controllers/admin_api_controller_test.exs index 66d4b1ef3..f23d23e05 100644 --- a/test/web/admin_api/controllers/admin_api_controller_test.exs +++ b/test/web/admin_api/controllers/admin_api_controller_test.exs @@ -155,13 +155,28 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIControllerTest do describe "DELETE /api/pleroma/admin/users" do test "single user", %{admin: admin, conn: conn} do - user = insert(:user) clear_config([:instance, :federating], true) + user = + insert(:user, + avatar: %{"url" => [%{"href" => "https://someurl"}]}, + banner: %{"url" => [%{"href" => "https://somebanner"}]} + ) + + # Create some activities to check they got deleted later + follower = insert(:user) + {:ok, _} = CommonAPI.post(user, %{status: "test"}) + {:ok, _, _, _} = CommonAPI.follow(user, follower) + {:ok, _, _, _} = CommonAPI.follow(follower, user) + user = Repo.get(User, user.id) + assert user.note_count == 1 + assert user.follower_count == 1 + assert user.following_count == 1 refute user.deactivated with_mock Pleroma.Web.Federator, - publish: fn _ -> nil end do + publish: fn _ -> nil end, + perform: fn _, _ -> nil end do conn = conn |> put_req_header("accept", "application/json") @@ -181,6 +196,12 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIControllerTest do user = Repo.get(User, user.id) assert user.deactivated + assert user.avatar == %{} + assert user.banner == %{} + assert user.note_count == 0 + assert user.follower_count == 0 + assert user.following_count == 0 + assert called(Pleroma.Web.Federator.publish(:_)) end end From c12c576ee28016444b89c426d67c960f156e831e Mon Sep 17 00:00:00 2001 From: Alex Gleason Date: Mon, 17 Aug 2020 22:08:08 -0500 Subject: [PATCH 2/5] Also purge bio and display name --- lib/pleroma/user.ex | 4 +++- .../web/admin_api/controllers/admin_api_controller_test.exs | 6 +++++- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/lib/pleroma/user.ex b/lib/pleroma/user.ex index a8bdcdad7..1a7d25801 100644 --- a/lib/pleroma/user.ex +++ b/lib/pleroma/user.ex @@ -1591,7 +1591,9 @@ defmodule Pleroma.User do avatar: %{}, banner: %{}, background: %{}, - fields: [] + fields: [], + bio: nil, + name: nil }) end diff --git a/test/web/admin_api/controllers/admin_api_controller_test.exs b/test/web/admin_api/controllers/admin_api_controller_test.exs index f23d23e05..2eb698807 100644 --- a/test/web/admin_api/controllers/admin_api_controller_test.exs +++ b/test/web/admin_api/controllers/admin_api_controller_test.exs @@ -160,7 +160,9 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIControllerTest do user = insert(:user, avatar: %{"url" => [%{"href" => "https://someurl"}]}, - banner: %{"url" => [%{"href" => "https://somebanner"}]} + banner: %{"url" => [%{"href" => "https://somebanner"}]}, + bio: "Hello world!", + name: "A guy" ) # Create some activities to check they got deleted later @@ -201,6 +203,8 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIControllerTest do assert user.note_count == 0 assert user.follower_count == 0 assert user.following_count == 0 + assert user.bio == nil + assert user.name == nil assert called(Pleroma.Web.Federator.publish(:_)) end From 72cbe20a5887cf2457895b0559e7eb97cc1bc871 Mon Sep 17 00:00:00 2001 From: Alex Gleason Date: Mon, 17 Aug 2020 23:44:44 -0500 Subject: [PATCH 3/5] Purge most user fields upon deletion, "right to be forgotten" #859 --- lib/pleroma/user.ex | 35 ++++++++++++++++++++++++++++++++--- 1 file changed, 32 insertions(+), 3 deletions(-) diff --git a/lib/pleroma/user.ex b/lib/pleroma/user.ex index 1a7d25801..a9820affa 100644 --- a/lib/pleroma/user.ex +++ b/lib/pleroma/user.ex @@ -1585,15 +1585,44 @@ defmodule Pleroma.User do @spec purge_user_changeset(User.t()) :: Changeset.t() def purge_user_changeset(user) do + # "Right to be forgotten" + # https://gdpr.eu/right-to-be-forgotten/ change(user, %{ - deactivated: true, + bio: nil, + raw_bio: nil, email: nil, + name: nil, + password_hash: nil, + keys: nil, + public_key: nil, avatar: %{}, + tags: [], + last_refreshed_at: nil, + last_digest_emailed_at: nil, banner: %{}, background: %{}, + note_count: 0, + follower_count: 0, + following_count: 0, + locked: false, + confirmation_pending: false, + password_reset_pending: false, + approval_pending: false, + registration_reason: nil, + confirmation_token: nil, + domain_blocks: [], + deactivated: true, + ap_enabled: false, + is_moderator: false, + is_admin: false, + mastofe_settings: nil, + mascot: nil, + emoji: %{}, + pleroma_settings_store: %{}, fields: [], - bio: nil, - name: nil + raw_fields: [], + discoverable: false, + also_known_as: [] }) end From dcc8926ff1bb7206295dcfe9ad9388cb3c05be2a Mon Sep 17 00:00:00 2001 From: Alex Gleason Date: Tue, 18 Aug 2020 00:10:09 -0500 Subject: [PATCH 4/5] Test purging a user with User.delete/1 --- test/user_test.exs | 80 +++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 79 insertions(+), 1 deletion(-) diff --git a/test/user_test.exs b/test/user_test.exs index b47405895..3cf248659 100644 --- a/test/user_test.exs +++ b/test/user_test.exs @@ -1417,7 +1417,6 @@ defmodule Pleroma.UserTest do test "delete/1 when approval is pending deletes the user" do user = insert(:user, approval_pending: true) - {:ok, user: user} {:ok, job} = User.delete(user) {:ok, _} = ObanHelpers.perform(job) @@ -1426,6 +1425,85 @@ defmodule Pleroma.UserTest do refute User.get_by_id(user.id) end + test "delete/1 purges a user when they wouldn't be fully deleted" do + user = + insert(:user, %{ + bio: "eyy lmao", + name: "qqqqqqq", + password_hash: "pdfk2$1b3n159001", + keys: "RSA begin buplic key", + public_key: "--PRIVATE KEYE--", + avatar: %{"a" => "b"}, + tags: ["qqqqq"], + banner: %{"a" => "b"}, + background: %{"a" => "b"}, + note_count: 9, + follower_count: 9, + following_count: 9001, + locked: true, + confirmation_pending: true, + password_reset_pending: true, + approval_pending: true, + registration_reason: "ahhhhh", + confirmation_token: "qqqq", + domain_blocks: ["lain.com"], + deactivated: true, + ap_enabled: true, + is_moderator: true, + is_admin: true, + mastofe_settings: %{"a" => "b"}, + mascot: %{"a" => "b"}, + emoji: %{"a" => "b"}, + pleroma_settings_store: %{"q" => "x"}, + fields: [%{"gg" => "qq"}], + raw_fields: [%{"gg" => "qq"}], + discoverable: true, + also_known_as: ["https://lol.olo/users/loll"] + }) + + {:ok, job} = User.delete(user) + {:ok, _} = ObanHelpers.perform(job) + user = User.get_by_id(user.id) + + assert %User{ + bio: nil, + raw_bio: nil, + email: nil, + name: nil, + password_hash: nil, + keys: nil, + public_key: nil, + avatar: %{}, + tags: [], + last_refreshed_at: nil, + last_digest_emailed_at: nil, + banner: %{}, + background: %{}, + note_count: 0, + follower_count: 0, + following_count: 0, + locked: false, + confirmation_pending: false, + password_reset_pending: false, + approval_pending: false, + registration_reason: nil, + confirmation_token: nil, + domain_blocks: [], + deactivated: true, + ap_enabled: false, + is_moderator: false, + is_admin: false, + mastofe_settings: nil, + mascot: nil, + emoji: %{}, + pleroma_settings_store: %{}, + fields: [], + raw_fields: [], + discoverable: false, + also_known_as: [] + } = user + end + test "get_public_key_for_ap_id fetches a user that's not in the db" do assert {:ok, _key} = User.get_public_key_for_ap_id("http://mastodon.example.org/users/admin") end From a0f5eb1a552cf161f0efb746d74c4c590de4f02f Mon Sep 17 00:00:00 2001 From: Alex Gleason Date: Tue, 18 Aug 2020 00:24:28 -0500 Subject: [PATCH 5/5] Test that `POST /api/pleroma/delete_account` purges the user --- test/web/twitter_api/util_controller_test.exs | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/test/web/twitter_api/util_controller_test.exs b/test/web/twitter_api/util_controller_test.exs index 109c1e637..354d77b56 100644 --- a/test/web/twitter_api/util_controller_test.exs +++ b/test/web/twitter_api/util_controller_test.exs @@ -586,10 +586,16 @@ defmodule Pleroma.Web.TwitterAPI.UtilControllerTest do end end - test "with proper permissions and valid password", %{conn: conn} do + test "with proper permissions and valid password", %{conn: conn, user: user} do conn = post(conn, "/api/pleroma/delete_account", %{"password" => "test"}) - + ObanHelpers.perform_all() assert json_response(conn, 200) == %{"status" => "success"} + + user = User.get_by_id(user.id) + assert user.deactivated == true + assert user.name == nil + assert user.bio == nil + assert user.password_hash == nil end end end