summaryrefslogtreecommitdiff
path: root/lib/pleroma/web/activity_pub/mrf/hashtag_policy.ex
diff options
context:
space:
mode:
Diffstat (limited to 'lib/pleroma/web/activity_pub/mrf/hashtag_policy.ex')
-rw-r--r--lib/pleroma/web/activity_pub/mrf/hashtag_policy.ex116
1 files changed, 116 insertions, 0 deletions
diff --git a/lib/pleroma/web/activity_pub/mrf/hashtag_policy.ex b/lib/pleroma/web/activity_pub/mrf/hashtag_policy.ex
new file mode 100644
index 000000000..b7db4fa3d
--- /dev/null
+++ b/lib/pleroma/web/activity_pub/mrf/hashtag_policy.ex
@@ -0,0 +1,116 @@
+# Pleroma: A lightweight social networking server
+# Copyright © 2017-2021 Pleroma Authors <https://pleroma.social/>
+# SPDX-License-Identifier: AGPL-3.0-only
+
+defmodule Pleroma.Web.ActivityPub.MRF.HashtagPolicy do
+ require Pleroma.Constants
+
+ alias Pleroma.Config
+ alias Pleroma.Object
+
+ @moduledoc """
+ Reject, TWKN-remove or Set-Sensitive messsages with specific hashtags (without the leading #)
+
+ Note: This MRF Policy is always enabled, if you want to disable it you have to set empty lists.
+ """
+
+ @behaviour Pleroma.Web.ActivityPub.MRF.Policy
+
+ defp check_reject(message, hashtags) do
+ if Enum.any?(Config.get([:mrf_hashtag, :reject]), fn match -> match in hashtags end) do
+ {:reject, "[HashtagPolicy] Matches with rejected keyword"}
+ else
+ {:ok, message}
+ end
+ end
+
+ defp check_ftl_removal(%{"to" => to} = message, hashtags) do
+ if Pleroma.Constants.as_public() in to and
+ Enum.any?(Config.get([:mrf_hashtag, :federated_timeline_removal]), fn match ->
+ match in hashtags
+ end) do
+ to = List.delete(to, Pleroma.Constants.as_public())
+ cc = [Pleroma.Constants.as_public() | message["cc"] || []]
+
+ message =
+ message
+ |> Map.put("to", to)
+ |> Map.put("cc", cc)
+ |> Kernel.put_in(["object", "to"], to)
+ |> Kernel.put_in(["object", "cc"], cc)
+
+ {:ok, message}
+ else
+ {:ok, message}
+ end
+ end
+
+ defp check_ftl_removal(message, _hashtags), do: {:ok, message}
+
+ defp check_sensitive(message, hashtags) do
+ if Enum.any?(Config.get([:mrf_hashtag, :sensitive]), fn match -> match in hashtags end) do
+ {:ok, Kernel.put_in(message, ["object", "sensitive"], true)}
+ else
+ {:ok, message}
+ end
+ end
+
+ @impl true
+ def filter(%{"type" => "Create", "object" => object} = message) do
+ hashtags = Object.hashtags(%Object{data: object})
+
+ if hashtags != [] do
+ with {:ok, message} <- check_reject(message, hashtags),
+ {:ok, message} <- check_ftl_removal(message, hashtags),
+ {:ok, message} <- check_sensitive(message, hashtags) do
+ {:ok, message}
+ end
+ else
+ {:ok, message}
+ end
+ end
+
+ @impl true
+ def filter(message), do: {:ok, message}
+
+ @impl true
+ def describe do
+ mrf_hashtag =
+ Config.get(:mrf_hashtag)
+ |> Enum.into(%{})
+
+ {:ok, %{mrf_hashtag: mrf_hashtag}}
+ end
+
+ @impl true
+ def config_description do
+ %{
+ key: :mrf_hashtag,
+ related_policy: "Pleroma.Web.ActivityPub.MRF.HashtagPolicy",
+ label: "MRF Hashtag",
+ description: @moduledoc,
+ children: [
+ %{
+ key: :reject,
+ type: {:list, :string},
+ description: "A list of hashtags which result in message being rejected.",
+ suggestions: ["foo"]
+ },
+ %{
+ key: :federated_timeline_removal,
+ type: {:list, :string},
+ description:
+ "A list of hashtags which result in message being removed from federated timelines (a.k.a unlisted).",
+ suggestions: ["foo"]
+ },
+ %{
+ key: :sensitive,
+ type: {:list, :string},
+ description:
+ "A list of hashtags which result in message being set as sensitive (a.k.a NSFW/R-18)",
+ suggestions: ["nsfw", "r18"]
+ }
+ ]
+ }
+ end
+end