summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorfeld <feld@feld.me>2024-10-11 20:23:46 +0000
committerfeld <feld@feld.me>2024-10-11 20:23:46 +0000
commit4557cd960e4345dd218eb0cf07751ea1545e4a27 (patch)
treea96f0a45539ecfc9574f9b8ece4a976314586102 /lib
parentdd7f699d4a3580a59405fbfc51b96f90f5d84d7d (diff)
parenteb971aa022f524f364daf24d6e6d617bfc5ca036 (diff)
downloadpleroma-4557cd960e4345dd218eb0cf07751ea1545e4a27.tar.gz
pleroma-4557cd960e4345dd218eb0cf07751ea1545e4a27.zip
Merge branch 'remote-report-policy' into 'develop'
Remote report policy See merge request pleroma/pleroma!4280
Diffstat (limited to 'lib')
-rw-r--r--lib/pleroma/web/activity_pub/mrf/remote_report_policy.ex118
1 files changed, 118 insertions, 0 deletions
diff --git a/lib/pleroma/web/activity_pub/mrf/remote_report_policy.ex b/lib/pleroma/web/activity_pub/mrf/remote_report_policy.ex
new file mode 100644
index 000000000..fa0610bf1
--- /dev/null
+++ b/lib/pleroma/web/activity_pub/mrf/remote_report_policy.ex
@@ -0,0 +1,118 @@
+defmodule Pleroma.Web.ActivityPub.MRF.RemoteReportPolicy do
+ @moduledoc "Drop remote reports if they don't contain enough information."
+ @behaviour Pleroma.Web.ActivityPub.MRF.Policy
+
+ alias Pleroma.Config
+
+ @impl true
+ def filter(%{"type" => "Flag"} = object) do
+ with {_, false} <- {:local, local?(object)},
+ {:ok, _} <- maybe_reject_all(object),
+ {:ok, _} <- maybe_reject_anonymous(object),
+ {:ok, _} <- maybe_reject_third_party(object),
+ {:ok, _} <- maybe_reject_empty_message(object) do
+ {:ok, object}
+ else
+ {:local, true} -> {:ok, object}
+ {:reject, message} -> {:reject, message}
+ error -> {:reject, error}
+ end
+ end
+
+ def filter(object), do: {:ok, object}
+
+ defp maybe_reject_all(object) do
+ if Config.get([:mrf_remote_report, :reject_all]) do
+ {:reject, "[RemoteReportPolicy] Remote report"}
+ else
+ {:ok, object}
+ end
+ end
+
+ defp maybe_reject_anonymous(%{"actor" => actor} = object) do
+ with true <- Config.get([:mrf_remote_report, :reject_anonymous]),
+ %URI{path: "/actor"} <- URI.parse(actor) do
+ {:reject, "[RemoteReportPolicy] Anonymous: #{actor}"}
+ else
+ _ -> {:ok, object}
+ end
+ end
+
+ defp maybe_reject_third_party(%{"object" => objects} = object) do
+ {_, to} =
+ case objects do
+ [head | tail] when is_binary(head) -> {tail, head}
+ s when is_binary(s) -> {[], s}
+ _ -> {[], ""}
+ end
+
+ with true <- Config.get([:mrf_remote_report, :reject_third_party]),
+ false <- String.starts_with?(to, Pleroma.Web.Endpoint.url()) do
+ {:reject, "[RemoteReportPolicy] Third-party: #{to}"}
+ else
+ _ -> {:ok, object}
+ end
+ end
+
+ defp maybe_reject_empty_message(%{"content" => content} = object)
+ when is_binary(content) and content != "" do
+ {:ok, object}
+ end
+
+ defp maybe_reject_empty_message(object) do
+ if Config.get([:mrf_remote_report, :reject_empty_message]) do
+ {:reject, ["RemoteReportPolicy] No content"]}
+ else
+ {:ok, object}
+ end
+ end
+
+ defp local?(%{"actor" => actor}) do
+ String.starts_with?(actor, Pleroma.Web.Endpoint.url())
+ end
+
+ @impl true
+ def describe do
+ mrf_remote_report =
+ Config.get(:mrf_remote_report)
+ |> Enum.into(%{})
+
+ {:ok, %{mrf_remote_report: mrf_remote_report}}
+ end
+
+ @impl true
+ def config_description do
+ %{
+ key: :mrf_remote_report,
+ related_policy: "Pleroma.Web.ActivityPub.MRF.RemoteReportPolicy",
+ label: "MRF Remote Report",
+ description: "Drop remote reports if they don't contain enough information.",
+ children: [
+ %{
+ key: :reject_all,
+ type: :boolean,
+ description: "Reject all remote reports? (this option takes precedence)",
+ suggestions: [false]
+ },
+ %{
+ key: :reject_anonymous,
+ type: :boolean,
+ description: "Reject anonymous remote reports?",
+ suggestions: [true]
+ },
+ %{
+ key: :reject_third_party,
+ type: :boolean,
+ description: "Reject reports on users from third-party instances?",
+ suggestions: [true]
+ },
+ %{
+ key: :reject_empty_message,
+ type: :boolean,
+ description: "Reject remote reports with no message?",
+ suggestions: [true]
+ }
+ ]
+ }
+ end
+end