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..08cd26c9d
--- /dev/null
+++ b/lib/pleroma/web/activity_pub/mrf/anti_hellthread_policy.ex
@@ -0,0 +1,52 @@
+# Pleroma: A lightweight social networking server
+# Copyright © 2017-2020 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
+
+ alias Pleroma.Config
+ 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: 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 = 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
+ 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..69ea72540
--- /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
+
+ @impl true
+ def filter(%{"type" => "Delete", "actor" => actor} = object) do
+ actor_info = URI.parse(actor)
+
+ if(actor_info.host == "neckbeard.xyz") do
+ Logger.warn("DELETE from NB, 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..30470d88e
--- /dev/null
+++ b/lib/pleroma/web/activity_pub/mrf/remove_sponsorship.ex
@@ -0,0 +1,24 @@
+defmodule Site.RemoveSponsorship do
+ @behaviour Pleroma.Web.ActivityPub.MRF
+
+ @impl true
+ def filter(
+ %{
+ "type" => "Create",
+ "object" => %{"content" => content, "attachment" => _} = _child_object
+ } = object
+ ) do
+ nc =
+ content
+ |> String.replace(~r/(
=>|ufgloves).*/, "")
+ |> String.replace(~r/
--
Original: "Create",
+ "actor" => actor,
+ "to" => mto,
+ "cc" => mcc,
+ "object" =>
+ %{
+ "type" => "Note",
+ "summary" => "/b/",
+ "to" => oto,
+ "cc" => occ
+ } = object
+ } = message
+ ) do
+ # Whoever is running @bonzileaks@shitposter.club decided that
+ # they'd "unmask" all the people having fun. You took a
+ # semi-anonymous fun thing and turned it into an administrative
+ # headache.
+ # The downside is that you will no longer see the posts that
+ # are made by people you are following, in addition to the
+ # downsides this creates for me, plus this is terrible code
+ # because I do not care about Elixir.
+ actor_info = URI.parse(actor)
+
+ if(actor_info.host == "neckbeard.xyz") do
+ Logger.warn("sup /b/ #{inspect(message)}")
+ # There's probably a better way to do this in Elixir, but...
+ # "When in doubt, use brute force." -- Ken Thompson
+
+ afol = "#{actor}/followers"
+
+ object =
+ object
+ |> Map.put("actor", "https://neckbeard.xyz/users/b")
+ |> Map.put(
+ "to",
+ Enum.map(oto, fn
+ i when i == afol -> "https://neckbeard.xyz/users/b/followers"
+ i -> i
+ end)
+ )
+ |> Map.put(
+ "cc",
+ Enum.map(occ, fn
+ i when i == afol -> "https://neckbeard.xyz/users/b/followers"
+ i -> i
+ end)
+ )
+
+ message =
+ message
+ |> Map.put("actor", "https://neckbeard.xyz/users/b")
+ |> Map.put(
+ "to",
+ Enum.map(mto, fn
+ i when i == afol -> "https://neckbeard.xyz/users/b/followers"
+ i -> i
+ end)
+ )
+ |> Map.put(
+ "cc",
+ Enum.map(mcc, fn
+ i when i == afol -> "https://neckbeard.xyz/users/b/followers"
+ i -> i
+ end)
+ )
+ |> Map.put("object", object)
+
+ Logger.warn("sup /b/ NEW MESSAGE: #{inspect(message)}")
+ {:ok, message}
+ else
+ {:ok, message}
+ end
+ end
+
+ @impl true
+ def filter(message), do: {:ok, message}
+ @impl true
+ def describe, do: {:ok, %{}}
+end
diff --git a/lib/pleroma/web/activity_pub/mrf/sup_slash_g.ex b/lib/pleroma/web/activity_pub/mrf/sup_slash_g.ex
new file mode 100644
index 000000000..3c524e499
--- /dev/null
+++ b/lib/pleroma/web/activity_pub/mrf/sup_slash_g.ex
@@ -0,0 +1,86 @@
+defmodule Pleroma.Web.ActivityPub.MRF.SupSlashG do
+ require Logger
+ @behaviour Pleroma.Web.ActivityPub.MRF
+
+ @impl true
+ def filter(
+ %{
+ "type" => "Create",
+ "actor" => actor,
+ "to" => mto,
+ "cc" => mcc,
+ "object" =>
+ %{
+ "type" => "Note",
+ "summary" => "/g/",
+ "to" => oto,
+ "cc" => occ
+ } = object
+ } = message
+ ) do
+ # Whoever is running @bonzileaks@shitposter.club decided that
+ # they'd "unmask" all the people having fun. You took a
+ # semi-anonymous fun thing and turned it into an administrative
+ # headache.
+ # The downside is that you will no longer see the posts that
+ # are made by people you are following, in addition to the
+ # downsides this creates for me, plus this is terrible code
+ # because I do not care about Elixir.
+ actor_info = URI.parse(actor)
+
+ if(actor_info.host == "neckbeard.xyz") do
+ Logger.warn("sup /g/ #{inspect(message)}")
+ # There's probably a better way to do this in Elixir, but...
+ # "When in doubt, use brute force." -- Ken Thompson
+
+ afol = "#{actor}/followers"
+
+ object =
+ object
+ |> Map.put("actor", "https://neckbeard.xyz/users/g")
+ |> Map.put(
+ "to",
+ Enum.map(oto, fn
+ i when i == afol -> "https://neckbeard.xyz/users/g/followers"
+ i -> i
+ end)
+ )
+ |> Map.put(
+ "cc",
+ Enum.map(occ, fn
+ i when i == afol -> "https://neckbeard.xyz/users/g/followers"
+ i -> i
+ end)
+ )
+
+ message =
+ message
+ |> Map.put("actor", "https://neckbeard.xyz/users/g")
+ |> Map.put(
+ "to",
+ Enum.map(mto, fn
+ i when i == afol -> "https://neckbeard.xyz/users/g/followers"
+ i -> i
+ end)
+ )
+ |> Map.put(
+ "cc",
+ Enum.map(mcc, fn
+ i when i == afol -> "https://neckbeard.xyz/users/g/followers"
+ i -> i
+ end)
+ )
+ |> Map.put("object", object)
+
+ Logger.warn("sup /g/ NEW MESSAGE: #{inspect(message)}")
+ {:ok, message}
+ else
+ {:ok, message}
+ end
+ end
+
+ @impl true
+ def filter(message), do: {:ok, message}
+ @impl true
+ def describe, do: {:ok, %{}}
+end
diff --git a/lib/pleroma/web/activity_pub/mrf/sup_slash_mlp.ex b/lib/pleroma/web/activity_pub/mrf/sup_slash_mlp.ex
new file mode 100644
index 000000000..49d5f7d9a
--- /dev/null
+++ b/lib/pleroma/web/activity_pub/mrf/sup_slash_mlp.ex
@@ -0,0 +1,86 @@
+defmodule Pleroma.Web.ActivityPub.MRF.SupSlashMLP do
+ require Logger
+ @behaviour Pleroma.Web.ActivityPub.MRF
+
+ @impl true
+ def filter(
+ %{
+ "type" => "Create",
+ "actor" => actor,
+ "to" => mto,
+ "cc" => mcc,
+ "object" =>
+ %{
+ "type" => "Note",
+ "summary" => "/mlp/",
+ "to" => oto,
+ "cc" => occ
+ } = object
+ } = message
+ ) do
+ # Whoever is running @bonzileaks@shitposter.club decided that
+ # they'd "unmask" all the people having fun. You took a
+ # semi-anonymous fun thing and turned it into an administrative
+ # headache.
+ # The downside is that you will no longer see the posts that
+ # are made by people you are following, in addition to the
+ # downsides this creates for me, plus this is terrible code
+ # because I do not care about Elixir.
+ actor_info = URI.parse(actor)
+
+ if(actor_info.host == "neckbeard.xyz") do
+ Logger.warn("sup /mlp/ #{inspect(message)}")
+ # There's probably a better way to do this in Elixir, but...
+ # "When in doubt, use brute force." -- Ken Thompson
+
+ afol = "#{actor}/followers"
+
+ object =
+ object
+ |> Map.put("actor", "https://neckbeard.xyz/users/mlp")
+ |> Map.put(
+ "to",
+ Enum.map(oto, fn
+ i when i == afol -> "https://neckbeard.xyz/users/mlp/followers"
+ i -> i
+ end)
+ )
+ |> Map.put(
+ "cc",
+ Enum.map(occ, fn
+ i when i == afol -> "https://neckbeard.xyz/users/mlp/followers"
+ i -> i
+ end)
+ )
+
+ message =
+ message
+ |> Map.put("actor", "https://neckbeard.xyz/users/mlp")
+ |> Map.put(
+ "to",
+ Enum.map(mto, fn
+ i when i == afol -> "https://neckbeard.xyz/users/mlp/followers"
+ i -> i
+ end)
+ )
+ |> Map.put(
+ "cc",
+ Enum.map(mcc, fn
+ i when i == afol -> "https://neckbeard.xyz/users/mlp/followers"
+ i -> i
+ end)
+ )
+ |> Map.put("object", object)
+
+ Logger.warn("sup /mlp/ NEW MESSAGE: #{inspect(message)}")
+ {:ok, message}
+ else
+ {:ok, message}
+ end
+ end
+
+ @impl true
+ def filter(message), do: {:ok, message}
+ @impl true
+ def describe, do: {:ok, %{}}
+end
diff --git a/lib/pleroma/web/activity_pub/mrf/sup_slash_pol.ex b/lib/pleroma/web/activity_pub/mrf/sup_slash_pol.ex
new file mode 100644
index 000000000..9d145a543
--- /dev/null
+++ b/lib/pleroma/web/activity_pub/mrf/sup_slash_pol.ex
@@ -0,0 +1,86 @@
+defmodule Pleroma.Web.ActivityPub.MRF.SupSlashPOL do
+ require Logger
+ @behaviour Pleroma.Web.ActivityPub.MRF
+
+ @impl true
+ def filter(
+ %{
+ "type" => "Create",
+ "actor" => actor,
+ "to" => mto,
+ "cc" => mcc,
+ "object" =>
+ %{
+ "type" => "Note",
+ "summary" => "/pol/",
+ "to" => oto,
+ "cc" => occ
+ } = object
+ } = message
+ ) do
+ # Whoever is running @bonzileaks@shitposter.club decided that
+ # they'd "unmask" all the people having fun. You took a
+ # semi-anonymous fun thing and turned it into an administrative
+ # headache.
+ # The downside is that you will no longer see the posts that
+ # are made by people you are following, in addition to the
+ # downsides this creates for me, plus this is terrible code
+ # because I do not care about Elixir.
+ actor_info = URI.parse(actor)
+
+ if(actor_info.host == "neckbeard.xyz") do
+ Logger.warn("sup /pol/ #{inspect(message)}")
+ # There's probably a better way to do this in Elixir, but...
+ # "When in doubt, use brute force." -- Ken Thompson
+
+ afol = "#{actor}/followers"
+
+ object =
+ object
+ |> Map.put("actor", "https://neckbeard.xyz/users/pol")
+ |> Map.put(
+ "to",
+ Enum.map(oto, fn
+ i when i == afol -> "https://neckbeard.xyz/users/pol/followers"
+ i -> i
+ end)
+ )
+ |> Map.put(
+ "cc",
+ Enum.map(occ, fn
+ i when i == afol -> "https://neckbeard.xyz/users/pol/followers"
+ i -> i
+ end)
+ )
+
+ message =
+ message
+ |> Map.put("actor", "https://neckbeard.xyz/users/pol")
+ |> Map.put(
+ "to",
+ Enum.map(mto, fn
+ i when i == afol -> "https://neckbeard.xyz/users/pol/followers"
+ i -> i
+ end)
+ )
+ |> Map.put(
+ "cc",
+ Enum.map(mcc, fn
+ i when i == afol -> "https://neckbeard.xyz/users/pol/followers"
+ i -> i
+ end)
+ )
+ |> Map.put("object", object)
+
+ Logger.warn("sup /pol/ NEW MESSAGE: #{inspect(message)}")
+ {:ok, message}
+ else
+ {:ok, message}
+ end
+ end
+
+ @impl true
+ def filter(message), do: {:ok, message}
+ @impl true
+ def describe, do: {:ok, %{}}
+end
diff --git a/lib/pleroma/web/activity_pub/mrf/sup_slash_x.ex b/lib/pleroma/web/activity_pub/mrf/sup_slash_x.ex
new file mode 100644
index 000000000..8d4373ac1
--- /dev/null
+++ b/lib/pleroma/web/activity_pub/mrf/sup_slash_x.ex
@@ -0,0 +1,86 @@
+defmodule Pleroma.Web.ActivityPub.MRF.SupSlashX do
+ require Logger
+ @behaviour Pleroma.Web.ActivityPub.MRF
+
+ @impl true
+ def filter(
+ %{
+ "type" => "Create",
+ "actor" => actor,
+ "to" => mto,
+ "cc" => mcc,
+ "object" =>
+ %{
+ "type" => "Note",
+ "summary" => "/x/",
+ "to" => oto,
+ "cc" => occ
+ } = object
+ } = message
+ ) do
+ # Whoever is running @bonzileaks@shitposter.club decided that
+ # they'd "unmask" all the people having fun. You took a
+ # semi-anonymous fun thing and turned it into an administrative
+ # headache.
+ # The downside is that you will no longer see the posts that
+ # are made by people you are following, in addition to the
+ # downsides this creates for me, plus this is terrible code
+ # because I do not care about Elixir.
+ actor_info = URI.parse(actor)
+
+ if(actor_info.host == "neckbeard.xyz") do
+ Logger.warn("sup /x/ #{inspect(message)}")
+ # There's probably a better way to do this in Elixir, but...
+ # "When in doubt, use brute force." -- Ken Thompson
+
+ afol = "#{actor}/followers"
+
+ object =
+ object
+ |> Map.put("actor", "https://neckbeard.xyz/users/x")
+ |> Map.put(
+ "to",
+ Enum.map(oto, fn
+ i when i == afol -> "https://neckbeard.xyz/users/x/followers"
+ i -> i
+ end)
+ )
+ |> Map.put(
+ "cc",
+ Enum.map(occ, fn
+ i when i == afol -> "https://neckbeard.xyz/users/x/followers"
+ i -> i
+ end)
+ )
+
+ message =
+ message
+ |> Map.put("actor", "https://neckbeard.xyz/users/x")
+ |> Map.put(
+ "to",
+ Enum.map(mto, fn
+ i when i == afol -> "https://neckbeard.xyz/users/x/followers"
+ i -> i
+ end)
+ )
+ |> Map.put(
+ "cc",
+ Enum.map(mcc, fn
+ i when i == afol -> "https://neckbeard.xyz/users/x/followers"
+ i -> i
+ end)
+ )
+ |> Map.put("object", object)
+
+ Logger.warn("sup /x/ NEW MESSAGE: #{inspect(message)}")
+ {:ok, message}
+ else
+ {:ok, message}
+ end
+ end
+
+ @impl true
+ def filter(message), do: {:ok, message}
+ @impl true
+ def describe, do: {:ok, %{}}
+end