baseless/lib/pleroma/web/activity_pub/mrf/anti_duplication_policy.ex
2025-01-24 09:36:38 -08:00

39 lines
1.2 KiB
Elixir

defmodule Pleroma.Web.ActivityPub.MRF.AntiDuplicationPolicy do
@moduledoc "Prevents messages with the exact same content from being posted repeatedly, regardless of its source."
@behaviour Pleroma.Web.ActivityPub.MRF.Policy
@cachex Pleroma.Config.get([:cachex, :provider], Cachex)
@cache :anti_duplication_mrf_cache
@impl true
def filter(%{"type" => "Create", "object" => %{"content" => content}} = activity)
when is_binary(content) do
ttl = Pleroma.Config.get([:mrf_anti_duplication, :ttl], :timer.minutes(1))
min_length = Pleroma.Config.get([:mrf_anti_duplication, :min_length], 50)
if String.length(content) >= min_length do
# We use SHA1 because it's faster and we don't need cryptographic security here.
key = :crypto.hash(:sha, content) |> Base.encode64(case: :lower)
case @cachex.exists?(@cache, key) do
{:ok, true} ->
@cachex.expire(@cache, key, ttl)
{:reject, "[AntiDuplicationPolicy] Message is a duplicate"}
{:ok, false} ->
@cachex.put(@cache, key, true, ttl: ttl)
{:ok, activity}
end
else
{:ok, activity}
end
end
def filter(object) do
{:ok, object}
end
@impl true
def describe, do: {:ok, %{}}
end