Fix deactivated user deletion
authorMaxim Filippov <colixer@gmail.com>
Fri, 9 Aug 2019 20:05:28 +0000 (23:05 +0300)
committerMaxim Filippov <colixer@gmail.com>
Fri, 9 Aug 2019 20:05:28 +0000 (23:05 +0300)
lib/mix/tasks/pleroma/user.ex
lib/pleroma/user.ex
lib/pleroma/web/activity_pub/activity_pub.ex
lib/pleroma/web/activity_pub/transmogrifier.ex
lib/pleroma/web/admin_api/admin_api_controller.ex
lib/pleroma/web/ostatus/handlers/delete_handler.ex
test/user_test.exs

index a3f8bc9450a226fc523a8d42a02db4459869e69a..f33d0142907010e3f069b9f31fc386139eded450 100644 (file)
@@ -176,7 +176,7 @@ defmodule Mix.Tasks.Pleroma.User do
     start_pleroma()
 
     with %User{local: true} = user <- User.get_cached_by_nickname(nickname) do
-      User.perform(:delete, user)
+      User.perform(:delete, user, nil)
       shell_info("User #{nickname} deleted.")
     else
       _ ->
index 7d18f099e8914b3964f480b49d0be9d99fe3a5b3..14057a0e44636b3fedc23b6cab3e5c72ca1b1899 100644 (file)
@@ -1029,13 +1029,26 @@ defmodule Pleroma.User do
     |> update_and_set_cache()
   end
 
+  @spec perform(atom(), User.t()) :: {:ok, User.t()}
+  def perform(:fetch_initial_posts, %User{} = user) do
+    pages = Pleroma.Config.get!([:fetch_initial_posts, :pages])
+
+    Enum.each(
+      # Insert all the posts in reverse order, so they're in the right order on the timeline
+      Enum.reverse(Utils.fetch_ordered_collection(user.info.source_data["outbox"], pages)),
+      &Pleroma.Web.Federator.incoming_ap_doc/1
+    )
+
+    {:ok, user}
+  end
+
   @spec delete(User.t()) :: :ok
-  def delete(%User{} = user),
-    do: PleromaJobQueue.enqueue(:background, __MODULE__, [:delete, user])
+  def delete(%User{} = user, actor \\ nil),
+    do: PleromaJobQueue.enqueue(:background, __MODULE__, [:delete, user, actor])
 
   @spec perform(atom(), User.t()) :: {:ok, User.t()}
-  def perform(:delete, %User{} = user) do
-    {:ok, _user} = ActivityPub.delete(user)
+  def perform(:delete, %User{} = user, actor) do
+    {:ok, _user} = ActivityPub.delete(user, actor: actor)
 
     # Remove all relationships
     {:ok, followers} = User.get_followers(user)
@@ -1057,19 +1070,6 @@ defmodule Pleroma.User do
     Repo.delete(user)
   end
 
-  @spec perform(atom(), User.t()) :: {:ok, User.t()}
-  def perform(:fetch_initial_posts, %User{} = user) do
-    pages = Pleroma.Config.get!([:fetch_initial_posts, :pages])
-
-    Enum.each(
-      # Insert all the posts in reverse order, so they're in the right order on the timeline
-      Enum.reverse(Utils.fetch_ordered_collection(user.info.source_data["outbox"], pages)),
-      &Pleroma.Web.Federator.incoming_ap_doc/1
-    )
-
-    {:ok, user}
-  end
-
   def perform(:deactivate_async, user, status), do: deactivate(user, status)
 
   @spec perform(atom(), User.t(), list()) :: list() | {:error, any()}
index 1a279a7df1b7f00e06c6ef3120d8f77585221f2d..8f669acb9092dd93ac21d57ed0971343d3fdcf62 100644 (file)
@@ -403,11 +403,13 @@ defmodule Pleroma.Web.ActivityPub.ActivityPub do
     end
   end
 
-  def delete(%User{ap_id: ap_id, follower_address: follower_address} = user) do
+  def delete(data, opts \\ %{actor: nil, local: true})
+
+  def delete(%User{ap_id: ap_id, follower_address: follower_address} = user, opts) do
     with data <- %{
            "to" => [follower_address],
            "type" => "Delete",
-           "actor" => ap_id,
+           "actor" => opts[:actor] || ap_id,
            "object" => %{"type" => "Person", "id" => ap_id}
          },
          {:ok, activity} <- insert(data, true, true),
@@ -416,7 +418,7 @@ defmodule Pleroma.Web.ActivityPub.ActivityPub do
     end
   end
 
-  def delete(%Object{data: %{"id" => id, "actor" => actor}} = object, local \\ true) do
+  def delete(%Object{data: %{"id" => id, "actor" => actor}} = object, opts) do
     user = User.get_cached_by_ap_id(actor)
     to = (object.data["to"] || []) ++ (object.data["cc"] || [])
 
@@ -428,7 +430,7 @@ defmodule Pleroma.Web.ActivityPub.ActivityPub do
            "to" => to,
            "deleted_activity_id" => activity && activity.id
          },
-         {:ok, activity} <- insert(data, local, false),
+         {:ok, activity} <- insert(data, opts[:local], false),
          stream_out_participations(object, user),
          _ <- decrease_replies_count_if_reply(object),
          # Changing note count prior to enqueuing federation task in order to avoid
index 5403b71d831e3ccc6b8cef38f14e1f83827742e7..b34ef73c0f64c129b845906857d991e123ab22f5 100644 (file)
@@ -649,7 +649,7 @@ defmodule Pleroma.Web.ActivityPub.Transmogrifier do
          {:ok, %User{} = actor} <- User.get_or_fetch_by_ap_id(actor),
          {:ok, object} <- get_obj_helper(object_id),
          :ok <- Containment.contain_origin(actor.ap_id, object.data),
-         {:ok, activity} <- ActivityPub.delete(object, false) do
+         {:ok, activity} <- ActivityPub.delete(object, local: false) do
       {:ok, activity}
     else
       nil ->
index 2d3d0adc44f63d8fd9a7c3dcafb71778f4f44207..63c9a7d7f49c83fb2adba9865d10495c0a23820d 100644 (file)
@@ -25,9 +25,9 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIController do
 
   action_fallback(:errors)
 
-  def user_delete(conn, %{"nickname" => nickname}) do
+  def user_delete(%{assigns: %{user: admin}} = conn, %{"nickname" => nickname}) do
     User.get_cached_by_nickname(nickname)
-    |> User.delete()
+    |> User.delete(admin.ap_id)
 
     conn
     |> json(nickname)
index b2f9f39463deab9d9324af6bd9995df55f9a1fcf..ac2dc115c33bb6165af6eaa55b777658e04baf71 100644 (file)
@@ -11,7 +11,7 @@ defmodule Pleroma.Web.OStatus.DeleteHandler do
   def handle_delete(entry, _doc \\ nil) do
     with id <- XML.string_from_xpath("//id", entry),
          %Object{} = object <- Object.normalize(id),
-         {:ok, delete} <- ActivityPub.delete(object, false) do
+         {:ok, delete} <- ActivityPub.delete(object, local: false) do
       delete
     end
   end
index 8440d456df40ace3079378a7e6ff719ab82393df..e2da8d84bd0f82d8c0fecb20c6d657de41b4e913 100644 (file)
@@ -998,6 +998,14 @@ defmodule Pleroma.UserTest do
       refute Activity.get_by_id(activity.id)
     end
 
+    test "it deletes deactivated user" do
+      admin = insert(:user, %{info: %{is_admin: true}})
+      {:ok, user} = insert(:user, info: %{deactivated: true}) |> User.set_cache()
+
+      assert {:ok, _} = User.delete(user, admin.ap_id)
+      refute User.get_by_id(user.id)
+    end
+
     test "it deletes a user, all follow relationships and all activities", %{user: user} do
       follower = insert(:user)
       {:ok, follower} = User.follow(follower, user)