Fork of Pleroma with site-specific changes and feature branches https://git.pleroma.social/pleroma/pleroma
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

58 lines
1.6KB

  1. # Pleroma: A lightweight social networking server
  2. # Copyright © 2017-2021 Pleroma Authors <https://pleroma.social/>
  3. # SPDX-License-Identifier: AGPL-3.0-only
  4. defmodule Pleroma.Web.ActivityPub.MRF.AntiLinkSpamPolicy do
  5. alias Pleroma.User
  6. @behaviour Pleroma.Web.ActivityPub.MRF.Policy
  7. require Logger
  8. # has the user successfully posted before?
  9. defp old_user?(%User{} = u) do
  10. u.note_count > 0 || u.follower_count > 0
  11. end
  12. # does the post contain links?
  13. defp contains_links?(%{"content" => content} = _object) do
  14. content
  15. |> Floki.parse_fragment!()
  16. |> Floki.filter_out("a.mention,a.hashtag,a[rel~=\"tag\"],a.zrl")
  17. |> Floki.attribute("a", "href")
  18. |> length() > 0
  19. end
  20. defp contains_links?(_), do: false
  21. @impl true
  22. def filter(%{"type" => "Create", "actor" => actor, "object" => object} = message) do
  23. with {:ok, %User{local: false} = u} <- User.get_or_fetch_by_ap_id(actor),
  24. {:contains_links, true} <- {:contains_links, contains_links?(object)},
  25. {:old_user, true} <- {:old_user, old_user?(u)} do
  26. {:ok, message}
  27. else
  28. {:ok, %User{local: true}} ->
  29. {:ok, message}
  30. {:contains_links, false} ->
  31. {:ok, message}
  32. {:old_user, false} ->
  33. {:reject, "[AntiLinkSpamPolicy] User has no posts nor followers"}
  34. {:error, _} ->
  35. {:reject, "[AntiLinkSpamPolicy] Failed to get or fetch user by ap_id"}
  36. e ->
  37. {:reject, "[AntiLinkSpamPolicy] Unhandled error #{inspect(e)}"}
  38. end
  39. end
  40. # in all other cases, pass through
  41. def filter(message), do: {:ok, message}
  42. @impl true
  43. def describe, do: {:ok, %{}}
  44. end