From be2da95c36c14ac42eee4009c6e3e803bafd3d2c Mon Sep 17 00:00:00 2001 From: Alex Gleason Date: Tue, 29 Jun 2021 21:45:38 -0500 Subject: Correctly purge a remote user --- lib/pleroma/user.ex | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) (limited to 'lib') diff --git a/lib/pleroma/user.ex b/lib/pleroma/user.ex index 9942617d8..aebb5da95 100644 --- a/lib/pleroma/user.ex +++ b/lib/pleroma/user.ex @@ -1713,6 +1713,12 @@ defmodule Pleroma.User do }) end + def purge(%User{} = user) do + user + |> purge_user_changeset() + |> update_and_set_cache() + end + def delete(users) when is_list(users) do for user <- users, do: delete(user) end @@ -1726,9 +1732,9 @@ defmodule Pleroma.User do Repo.delete(user) end - defp delete_or_deactivate(%User{local: false} = user), do: delete_and_invalidate_cache(user) + defp delete_or_purge(%User{local: false} = user), do: purge(user) - defp delete_or_deactivate(%User{local: true} = user) do + defp delete_or_purge(%User{local: true} = user) do status = account_status(user) case status do @@ -1739,9 +1745,7 @@ defmodule Pleroma.User do delete_and_invalidate_cache(user) _ -> - user - |> purge_user_changeset() - |> update_and_set_cache() + purge(user) end end @@ -1769,7 +1773,7 @@ defmodule Pleroma.User do delete_outgoing_pending_follow_requests(user) - delete_or_deactivate(user) + delete_or_purge(user) end def perform(:set_activation_async, user, status), do: set_activation(user, status) -- cgit v1.2.3 From c6d4133727ba623d4c96358e3c4de5f2194d07f8 Mon Sep 17 00:00:00 2001 From: Alex Gleason Date: Tue, 29 Jun 2021 22:30:48 -0500 Subject: Deletions: purge the user immediately --- lib/pleroma/user.ex | 25 ++++++++++--------------- 1 file changed, 10 insertions(+), 15 deletions(-) (limited to 'lib') diff --git a/lib/pleroma/user.ex b/lib/pleroma/user.ex index aebb5da95..406a7f5f9 100644 --- a/lib/pleroma/user.ex +++ b/lib/pleroma/user.ex @@ -1724,31 +1724,27 @@ defmodule Pleroma.User do end def delete(%User{} = user) do + purge(user) BackgroundWorker.enqueue("delete_user", %{"user_id" => user.id}) end - defp delete_and_invalidate_cache(%User{} = user) do + defp delete_from_db(%User{} = user) do invalidate_cache(user) Repo.delete(user) end - defp delete_or_purge(%User{local: false} = user), do: purge(user) - - defp delete_or_purge(%User{local: true} = user) do + defp maybe_delete_from_db(%User{local: true} = user) do status = account_status(user) - case status do - :confirmation_pending -> - delete_and_invalidate_cache(user) - - :approval_pending -> - delete_and_invalidate_cache(user) - - _ -> - purge(user) + if status in [:confirmation_pending, :approval_pending] do + delete_from_db(user) + else + {:ok, user} end end + defp maybe_delete_from_db(user), do: {:ok, user} + def perform(:force_password_reset, user), do: force_password_reset(user) @spec perform(atom(), User.t()) :: {:ok, User.t()} @@ -1770,10 +1766,9 @@ defmodule Pleroma.User do delete_user_activities(user) delete_notifications_from_user_activities(user) - delete_outgoing_pending_follow_requests(user) - delete_or_purge(user) + maybe_delete_from_db(user) end def perform(:set_activation_async, user, status), do: set_activation(user, status) -- cgit v1.2.3 From 01c2d2a29670d8b3a4acee06c5f91b52e371fd00 Mon Sep 17 00:00:00 2001 From: Alex Gleason Date: Tue, 29 Jun 2021 22:53:33 -0500 Subject: Also purge the user in User.perform/2 --- lib/pleroma/user.ex | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'lib') diff --git a/lib/pleroma/user.ex b/lib/pleroma/user.ex index 406a7f5f9..f3cf3c69b 100644 --- a/lib/pleroma/user.ex +++ b/lib/pleroma/user.ex @@ -1724,6 +1724,7 @@ defmodule Pleroma.User do end def delete(%User{} = user) do + # Purge the user immediately purge(user) BackgroundWorker.enqueue("delete_user", %{"user_id" => user.id}) end @@ -1749,6 +1750,9 @@ defmodule Pleroma.User do @spec perform(atom(), User.t()) :: {:ok, User.t()} def perform(:delete, %User{} = user) do + # Purge the user again, in case perform/2 is called directly + purge(user) + # Remove all relationships user |> get_followers() -- cgit v1.2.3 From a7929c4d89a07a7f577e7cde5638bde8b1cb586a Mon Sep 17 00:00:00 2001 From: Alex Gleason Date: Tue, 29 Jun 2021 23:56:19 -0500 Subject: Deletions: preserve account status fields during purge, fix checks --- lib/pleroma/user.ex | 22 ++++++++++++---------- 1 file changed, 12 insertions(+), 10 deletions(-) (limited to 'lib') diff --git a/lib/pleroma/user.ex b/lib/pleroma/user.ex index f3cf3c69b..5d8b936aa 100644 --- a/lib/pleroma/user.ex +++ b/lib/pleroma/user.ex @@ -1692,9 +1692,7 @@ defmodule Pleroma.User do follower_count: 0, following_count: 0, is_locked: false, - is_confirmed: true, password_reset_pending: false, - is_approved: true, registration_reason: nil, confirmation_token: nil, domain_blocks: [], @@ -1710,9 +1708,15 @@ defmodule Pleroma.User do raw_fields: [], is_discoverable: false, also_known_as: [] + # id: preserved + # ap_id: preserved + # nickname: preserved }) end + # Purge doesn't delete the user from the database. + # It just nulls all its fields and deactivates it. + # See `User.purge_user_changeset/1` above. def purge(%User{} = user) do user |> purge_user_changeset() @@ -1729,20 +1733,18 @@ defmodule Pleroma.User do BackgroundWorker.enqueue("delete_user", %{"user_id" => user.id}) end + # *Actually* delete the user from the DB defp delete_from_db(%User{} = user) do invalidate_cache(user) Repo.delete(user) end - defp maybe_delete_from_db(%User{local: true} = user) do - status = account_status(user) + # If the user never finalized their account, it's safe to delete them. + defp maybe_delete_from_db(%User{local: true, is_confirmed: false} = user), + do: delete_from_db(user) - if status in [:confirmation_pending, :approval_pending] do - delete_from_db(user) - else - {:ok, user} - end - end + defp maybe_delete_from_db(%User{local: true, is_approved: false} = user), + do: delete_from_db(user) defp maybe_delete_from_db(user), do: {:ok, user} -- cgit v1.2.3 From 43800d83f4fc3b251cdd93c28dab2df7297021b3 Mon Sep 17 00:00:00 2001 From: Alex Gleason Date: Wed, 30 Jun 2021 01:14:34 -0500 Subject: Deletions: allow deactivated users to be deleted --- lib/pleroma/web/activity_pub/activity_pub.ex | 9 ++++++--- .../web/activity_pub/object_validators/delete_validator.ex | 12 +++++++++++- .../web/activity_pub/object_validators/undo_validator.ex | 12 +++++++++++- 3 files changed, 28 insertions(+), 5 deletions(-) (limited to 'lib') diff --git a/lib/pleroma/web/activity_pub/activity_pub.ex b/lib/pleroma/web/activity_pub/activity_pub.ex index 5b45e2ca1..787b5884f 100644 --- a/lib/pleroma/web/activity_pub/activity_pub.ex +++ b/lib/pleroma/web/activity_pub/activity_pub.ex @@ -52,15 +52,18 @@ defmodule Pleroma.Web.ActivityPub.ActivityPub do {recipients, to, cc} end - defp check_actor_is_active(nil), do: true + defp check_actor_can_insert(%{"type" => "Delete"}), do: true + defp check_actor_can_insert(%{"type" => "Undo"}), do: true - defp check_actor_is_active(actor) when is_binary(actor) do + defp check_actor_can_insert(%{"actor" => actor}) when is_binary(actor) do case User.get_cached_by_ap_id(actor) do %User{is_active: true} -> true _ -> false end end + defp check_actor_can_insert(_), do: true + defp check_remote_limit(%{"object" => %{"content" => content}}) when not is_nil(content) do limit = Config.get([:instance, :remote_limit]) String.length(content) <= limit @@ -116,7 +119,7 @@ defmodule Pleroma.Web.ActivityPub.ActivityPub do def insert(map, local \\ true, fake \\ false, bypass_actor_check \\ false) when is_map(map) do with nil <- Activity.normalize(map), map <- lazy_put_activity_defaults(map, fake), - {_, true} <- {:actor_check, bypass_actor_check || check_actor_is_active(map["actor"])}, + {_, true} <- {:actor_check, bypass_actor_check || check_actor_can_insert(map)}, {_, true} <- {:remote_limit_pass, check_remote_limit(map)}, {:ok, map} <- MRF.filter(map), {recipients, _, _} = get_recipients(map), diff --git a/lib/pleroma/web/activity_pub/object_validators/delete_validator.ex b/lib/pleroma/web/activity_pub/object_validators/delete_validator.ex index fc1a79a72..750ea0f7f 100644 --- a/lib/pleroma/web/activity_pub/object_validators/delete_validator.ex +++ b/lib/pleroma/web/activity_pub/object_validators/delete_validator.ex @@ -7,6 +7,7 @@ defmodule Pleroma.Web.ActivityPub.ObjectValidators.DeleteValidator do alias Pleroma.Activity alias Pleroma.EctoType.ActivityPub.ObjectValidators + alias Pleroma.User import Ecto.Changeset import Pleroma.Web.ActivityPub.ObjectValidators.CommonValidations @@ -57,7 +58,7 @@ defmodule Pleroma.Web.ActivityPub.ObjectValidators.DeleteValidator do cng |> validate_required([:id, :type, :actor, :to, :cc, :object]) |> validate_inclusion(:type, ["Delete"]) - |> validate_actor_presence() + |> validate_delete_actor(:actor) |> validate_modification_rights() |> validate_object_or_user_presence(allowed_types: @deletable_types) |> add_deleted_activity_id() @@ -72,4 +73,13 @@ defmodule Pleroma.Web.ActivityPub.ObjectValidators.DeleteValidator do |> cast_data |> validate_data end + + defp validate_delete_actor(cng, field_name) do + validate_change(cng, field_name, fn field_name, actor -> + case User.get_cached_by_ap_id(actor) do + %User{} -> [] + _ -> [{field_name, "can't find user"}] + end + end) + end end diff --git a/lib/pleroma/web/activity_pub/object_validators/undo_validator.ex b/lib/pleroma/web/activity_pub/object_validators/undo_validator.ex index 783a79ddb..ab29f9820 100644 --- a/lib/pleroma/web/activity_pub/object_validators/undo_validator.ex +++ b/lib/pleroma/web/activity_pub/object_validators/undo_validator.ex @@ -7,6 +7,7 @@ defmodule Pleroma.Web.ActivityPub.ObjectValidators.UndoValidator do alias Pleroma.Activity alias Pleroma.EctoType.ActivityPub.ObjectValidators + alias Pleroma.User import Ecto.Changeset import Pleroma.Web.ActivityPub.ObjectValidators.CommonValidations @@ -42,7 +43,7 @@ defmodule Pleroma.Web.ActivityPub.ObjectValidators.UndoValidator do data_cng |> validate_inclusion(:type, ["Undo"]) |> validate_required([:id, :type, :object, :actor, :to, :cc]) - |> validate_actor_presence() + |> validate_undo_actor(:actor) |> validate_object_presence() |> validate_undo_rights() end @@ -59,4 +60,13 @@ defmodule Pleroma.Web.ActivityPub.ObjectValidators.UndoValidator do _ -> cng end end + + defp validate_undo_actor(cng, field_name) do + validate_change(cng, field_name, fn field_name, actor -> + case User.get_cached_by_ap_id(actor) do + %User{} -> [] + _ -> [{field_name, "can't find user"}] + end + end) + end end -- cgit v1.2.3 From beb1c98ab5e0848127a4490180364552f6fcdbf5 Mon Sep 17 00:00:00 2001 From: Alex Gleason Date: Wed, 30 Jun 2021 01:48:17 -0500 Subject: Deletions: don't purge keys so Delete/Undo activities can be signed --- lib/pleroma/user.ex | 2 -- 1 file changed, 2 deletions(-) (limited to 'lib') diff --git a/lib/pleroma/user.ex b/lib/pleroma/user.ex index 5d8b936aa..de3b8ca3b 100644 --- a/lib/pleroma/user.ex +++ b/lib/pleroma/user.ex @@ -1680,8 +1680,6 @@ defmodule Pleroma.User do email: nil, name: nil, password_hash: nil, - keys: nil, - public_key: nil, avatar: %{}, tags: [], last_refreshed_at: nil, -- cgit v1.2.3 From 310ef6b70d9ca18d857f43677d857d09d91ffe0e Mon Sep 17 00:00:00 2001 From: Alex Gleason Date: Wed, 30 Jun 2021 12:25:20 -0500 Subject: Deletions: change User.purge/1 to defp, add CHANGELOG entry --- lib/pleroma/user.ex | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'lib') diff --git a/lib/pleroma/user.ex b/lib/pleroma/user.ex index f5b12abad..62506f37a 100644 --- a/lib/pleroma/user.ex +++ b/lib/pleroma/user.ex @@ -1730,7 +1730,7 @@ defmodule Pleroma.User do # Purge doesn't delete the user from the database. # It just nulls all its fields and deactivates it. # See `User.purge_user_changeset/1` above. - def purge(%User{} = user) do + defp purge(%User{} = user) do user |> purge_user_changeset() |> update_and_set_cache() -- cgit v1.2.3