diff --git a/lib/pleroma/constants.ex b/lib/pleroma/constants.ex index 2681d7671..0f4be3b78 100644 --- a/lib/pleroma/constants.ex +++ b/lib/pleroma/constants.ex @@ -43,17 +43,19 @@ defmodule Pleroma.Constants do ] ) - const(updatable_object_types, - do: [ - "Note", - "Question", - "Audio", - "Video", - "Event", - "Article", - "Page" - ] - ) + @updatable_object_types [ + "Note", + "Question", + "Audio", + "Video", + "Event", + "Article", + "Page" + ] + + const(updatable_object_types, do: @updatable_object_types) + + const(object_types, do: @updatable_object_types ++ ["Answer"]) const(actor_types, do: [ diff --git a/lib/pleroma/web/activity_pub/mrf/object_age_policy.ex b/lib/pleroma/web/activity_pub/mrf/object_age_policy.ex index 02c9b18ed..1cdb507f0 100644 --- a/lib/pleroma/web/activity_pub/mrf/object_age_policy.ex +++ b/lib/pleroma/web/activity_pub/mrf/object_age_policy.ex @@ -11,12 +11,36 @@ defmodule Pleroma.Web.ActivityPub.MRF.ObjectAgePolicy do @moduledoc "Filter activities depending on their age" @behaviour Pleroma.Web.ActivityPub.MRF.Policy - defp check_date(%{"object" => %{"published" => published}} = message) do + defp update_to_cc(message, to, cc) do + message = + message + |> Map.put("to", to) + |> Map.put("cc", cc) + + if Map.has_key?(message, "object") do + message + |> Kernel.put_in(["object", "to"], to) + |> Kernel.put_in(["object", "cc"], cc) + else + message + end + end + + defp check_date(%{"object" => %{"published" => _} = object} = activity) do + with {:ok, object} <- check_date(object) do + activity = activity |> Map.put("object", object) + {:ok, activity} + else + e -> e + end + end + + defp check_date(%{"published" => published} = object) do with %DateTime{} = now <- DateTime.utc_now(), {:ok, %DateTime{} = then, _} <- DateTime.from_iso8601(published), max_ttl <- Config.get([:mrf_object_age, :threshold]), {:ttl, false} <- {:ttl, DateTime.diff(now, then) > max_ttl} do - {:ok, message} + {:ok, object} else {:ttl, true} -> {:reject, nil} @@ -47,10 +71,7 @@ defp check_delist(message, actions) do message = message - |> Map.put("to", to) - |> Map.put("cc", cc) - |> Kernel.put_in(["object", "to"], to) - |> Kernel.put_in(["object", "cc"], cc) + |> update_to_cc(to, cc) {:ok, message} else @@ -70,10 +91,7 @@ defp check_strip_followers(message, actions) do message = message - |> Map.put("to", to) - |> Map.put("cc", cc) - |> Kernel.put_in(["object", "to"], to) - |> Kernel.put_in(["object", "cc"], cc) + |> update_to_cc(to, cc) {:ok, message} else @@ -85,11 +103,18 @@ defp check_strip_followers(message, actions) do end end - @impl true - def filter(%{"type" => "Create", "object" => %{"published" => _}} = message) do + defp maybe_check_reject(message, _actions, false) do + {:ok, message} + end + + defp maybe_check_reject(message, actions, true) do + check_reject(message, actions) + end + + defp check(message, allow_reject) do with actions <- Config.get([:mrf_object_age, :actions]), {:reject, _} <- check_date(message), - {:ok, message} <- check_reject(message, actions), + {:ok, message} <- maybe_check_reject(message, actions, allow_reject), {:ok, message} <- check_delist(message, actions), {:ok, message} <- check_strip_followers(message, actions) do {:ok, message} @@ -99,6 +124,17 @@ def filter(%{"type" => "Create", "object" => %{"published" => _}} = message) do end end + @impl true + def filter(%{"type" => "Create", "object" => %{"published" => _}} = message) do + check(message, true) + end + + @impl true + def filter(%{"type" => type, "published" => _} = message) + when type in Pleroma.Constants.object_types() do + check(message, false) + end + @impl true def filter(message), do: {:ok, message} diff --git a/test/pleroma/web/activity_pub/mrf/object_age_policy_test.exs b/test/pleroma/web/activity_pub/mrf/object_age_policy_test.exs index 2f649a0a4..1d571bb46 100644 --- a/test/pleroma/web/activity_pub/mrf/object_age_policy_test.exs +++ b/test/pleroma/web/activity_pub/mrf/object_age_policy_test.exs @@ -57,6 +57,15 @@ test "it rejects an old post" do assert match?({:reject, _}, ObjectAgePolicy.filter(data)) end + test "it doesn't reject a fetched post" do + clear_config([:mrf_object_age, :actions], [:reject]) + + data = get_old_message() + object = data["object"] + + assert match?({:ok, _}, ObjectAgePolicy.filter(object)) + end + test "it allows a new post" do clear_config([:mrf_object_age, :actions], [:reject])