Add Instance.delete_users_and_activities/1 to delete all content from a remote instance
authorAlex Gleason <alex@alexgleason.me>
Sat, 17 Jul 2021 19:06:35 +0000 (14:06 -0500)
committerAlex Gleason <alex@alexgleason.me>
Sat, 17 Jul 2021 19:06:35 +0000 (14:06 -0500)
lib/pleroma/instances/instance.ex
lib/pleroma/workers/background_worker.ex
test/pleroma/instances/instance_test.exs

index 4d0e8034d61400f623169a0d47c3bc21f236e1a6..2f338b3e2bae30518508b31f49f022dcccb0d436 100644 (file)
@@ -8,6 +8,8 @@ defmodule Pleroma.Instances.Instance do
   alias Pleroma.Instances
   alias Pleroma.Instances.Instance
   alias Pleroma.Repo
   alias Pleroma.Instances
   alias Pleroma.Instances.Instance
   alias Pleroma.Repo
+  alias Pleroma.User
+  alias Pleroma.Workers.BackgroundWorker
 
   use Ecto.Schema
 
 
   use Ecto.Schema
 
@@ -195,4 +197,24 @@ defmodule Pleroma.Instances.Instance do
         nil
     end
   end
         nil
     end
   end
+
+  @doc """
+  Deletes all users from an instance in a background task, thus also deleting
+  all of those users' activities and notifications.
+  """
+  def delete_users_and_activities(host) when is_binary(host) do
+    BackgroundWorker.enqueue("delete_instance", %{"host" => host})
+  end
+
+  def perform(:delete_instance, host) when is_binary(host) do
+    User.Query.build(%{nickname: "@#{host}"})
+    |> Repo.chunk_stream(100, :batches)
+    |> Stream.each(fn users ->
+      users
+      |> Enum.each(fn user ->
+        User.perform(:delete, user)
+      end)
+    end)
+    |> Stream.run()
+  end
 end
 end
index 1e28384cb188d7fe626e1cf9d9b7dc7cab7601c2..4db077232a850eac077dd98793496f217e2c8f36 100644 (file)
@@ -3,6 +3,7 @@
 # SPDX-License-Identifier: AGPL-3.0-only
 
 defmodule Pleroma.Workers.BackgroundWorker do
 # SPDX-License-Identifier: AGPL-3.0-only
 
 defmodule Pleroma.Workers.BackgroundWorker do
+  alias Pleroma.Instances.Instance
   alias Pleroma.User
 
   use Pleroma.Workers.WorkerHelper, queue: "background"
   alias Pleroma.User
 
   use Pleroma.Workers.WorkerHelper, queue: "background"
@@ -38,4 +39,8 @@ defmodule Pleroma.Workers.BackgroundWorker do
 
     Pleroma.FollowingRelationship.move_following(origin, target)
   end
 
     Pleroma.FollowingRelationship.move_following(origin, target)
   end
+
+  def perform(%Job{args: %{"op" => "delete_instance", "host" => host}}) do
+    Instance.perform(:delete_instance, host)
+  end
 end
 end
index bacc0b19be1517756ee84f0acda65628a128756d..e49922724e12fc9890c2221e9dfc2f7f7ac043d2 100644 (file)
@@ -6,6 +6,8 @@ defmodule Pleroma.Instances.InstanceTest do
   alias Pleroma.Instances
   alias Pleroma.Instances.Instance
   alias Pleroma.Repo
   alias Pleroma.Instances
   alias Pleroma.Instances.Instance
   alias Pleroma.Repo
+  alias Pleroma.Tests.ObanHelpers
+  alias Pleroma.Web.CommonAPI
 
   use Pleroma.DataCase
 
 
   use Pleroma.DataCase
 
@@ -158,4 +160,33 @@ defmodule Pleroma.Instances.InstanceTest do
                "Instance.scrape_favicon(\"#{url}\") ignored unreachable host"
     end
   end
                "Instance.scrape_favicon(\"#{url}\") ignored unreachable host"
     end
   end
+
+  test "delete_users_and_activities/1 deletes remote instance users and activities" do
+    [mario, luigi, _peach, wario] =
+      users = [
+        insert(:user, nickname: "mario@mushroom.kingdom", name: "Mario"),
+        insert(:user, nickname: "luigi@mushroom.kingdom", name: "Luigi"),
+        insert(:user, nickname: "peach@mushroom.kingdom", name: "Peach"),
+        insert(:user, nickname: "wario@greedville.biz", name: "Wario")
+      ]
+
+    {:ok, post1} = CommonAPI.post(mario, %{status: "letsa go!"})
+    {:ok, post2} = CommonAPI.post(luigi, %{status: "itsa me... luigi"})
+    {:ok, post3} = CommonAPI.post(wario, %{status: "WHA-HA-HA!"})
+
+    {:ok, job} = Instance.delete_users_and_activities("mushroom.kingdom")
+    :ok = ObanHelpers.perform(job)
+
+    [mario, luigi, peach, wario] = Repo.reload(users)
+
+    refute mario.is_active
+    refute luigi.is_active
+    refute peach.is_active
+    refute peach.name == "Peach"
+
+    assert wario.is_active
+    assert wario.name == "Wario"
+
+    assert [nil, nil, %{}] = Repo.reload([post1, post2, post3])
+  end
 end
 end