diff --git a/lib/pleroma/web/activity_pub/mrf/anti_hellthread_policy.ex b/lib/pleroma/web/activity_pub/mrf/anti_hellthread_policy.ex
new file mode 100644
index 000000000..0c063f103
--- /dev/null
+++ b/lib/pleroma/web/activity_pub/mrf/anti_hellthread_policy.ex
@@ -0,0 +1,90 @@
+# Pleroma: A lightweight social networking server
+# Copyright © 2017-2021 Pleroma Authors
+# SPDX-License-Identifier: AGPL-3.0-only
+
+defmodule Pleroma.Web.ActivityPub.MRF.AntiHellthreadPolicy do
+ @moduledoc "Notify local users upon remote block."
+ @behaviour Pleroma.Web.ActivityPub.MRF.Policy
+
+ alias Pleroma.User
+ alias Pleroma.Web.CommonAPI
+
+ defp is_block_or_unblock(%{"type" => "Block", "object" => object}),
+ do: {true, "blocked", object}
+
+ defp is_block_or_unblock(%{
+ "type" => "Undo",
+ "object" => %{"type" => "Block", "object" => object}
+ }),
+ do: {true, "unblocked", object}
+
+ defp is_block_or_unblock(_), do: {false, nil, nil}
+
+ defp is_remote_or_displaying_local?(%User{local: false}), do: true
+
+ defp is_remote_or_displaying_local?(_),
+ do: Pleroma.Config.get([:mrf_anti_hellthread_policy, :display_local])
+
+ @impl true
+ def filter(message) do
+ with {true, action, object} <- is_block_or_unblock(message),
+ %User{} = actor <- User.get_cached_by_ap_id(message["actor"]),
+ %User{} = recipient <- User.get_cached_by_ap_id(object),
+ true <- recipient.local,
+ true <- is_remote_or_displaying_local?(actor),
+ false <- User.blocks_user?(recipient, actor) do
+ bot_user = Pleroma.Config.get([:mrf_anti_hellthread_policy, :user])
+
+ _reply =
+ CommonAPI.post(User.get_by_nickname(bot_user), %{
+ status:
+ "@" <> recipient.nickname <> " you have been " <> action <> " by @" <> actor.nickname,
+ visibility: "direct"
+ })
+ end
+
+ {:ok, message}
+ end
+
+ @impl true
+ @spec config_description :: %{
+ children: [
+ %{
+ description: <<_::200, _::_*24>>,
+ key: :display_local | :user,
+ suggestions: [...],
+ type: :boolean | :string
+ },
+ ...
+ ],
+ description: <<_::296>>,
+ key: :mrf_anti_hellthread_policy,
+ label: <<_::208>>,
+ related_policy: <<_::384>>
+ }
+ def config_description do
+ %{
+ key: :mrf_anti_hellthread_policy,
+ related_policy: "Pleroma.Web.ActivityPub.MRF.AntiHellthreadPolicy",
+ label: "MRF Anti Hellthread Policy",
+ description: "Notify local users upon remote block.",
+ children: [
+ %{
+ key: :user,
+ type: :string,
+ description: "The user who will notify of the block",
+ suggestions: ["blockbot"]
+ },
+ %{
+ key: :display_local,
+ type: :boolean,
+ description: "Display blocks from local users as well?",
+ suggestions: [false]
+ }
+ ]
+ }
+ end
+
+ @impl true
+ def describe, do: {:ok, %{}}
+end
diff --git a/lib/pleroma/web/activity_pub/mrf/racism_remover.ex b/lib/pleroma/web/activity_pub/mrf/racism_remover.ex
new file mode 100644
index 000000000..dea678f8e
--- /dev/null
+++ b/lib/pleroma/web/activity_pub/mrf/racism_remover.ex
@@ -0,0 +1,23 @@
+defmodule Pleroma.Web.ActivityPub.MRF.RacismRemover do
+ require Logger
+ @behaviour Pleroma.Web.ActivityPub.MRF.Policy
+
+ @impl true
+ def filter(%{"type" => "Delete", "actor" => actor} = object) do
+ actor_info = URI.parse(actor)
+
+ if actor_info.host == "froth.zone" do
+ Logger.warn("DELETE from local, not rejecting: #{inspect(object)}")
+ {:ok, object}
+ else
+ Logger.warn("DELETE rejected: #{inspect(object)}")
+ {:reject, object}
+ end
+ end
+
+ @impl true
+ def filter(object), do: {:ok, object}
+
+ @impl true
+ def describe, do: {:ok, %{}}
+end
diff --git a/lib/pleroma/web/activity_pub/mrf/remove_sponsorship.ex b/lib/pleroma/web/activity_pub/mrf/remove_sponsorship.ex
new file mode 100644
index 000000000..1a66ef32f
--- /dev/null
+++ b/lib/pleroma/web/activity_pub/mrf/remove_sponsorship.ex
@@ -0,0 +1,24 @@
+defmodule Pleroma.Web.ActivityPub.MRF.RemoveSponsorship do
+ @behaviour Pleroma.Web.ActivityPub.MRF.Policy
+
+ @impl true
+ def filter(
+ %{
+ "type" => "Create",
+ "object" => %{"content" => content, "attachment" => _} = _child_object
+ } = object
+ ) do
+ nc =
+ content
+ |> String.replace(~r/(
=>|ufgloves).*/, "")
+ |> String.replace(~r/
--
Original: