logo

pleroma

My custom branche(s) on git.pleroma.social/pleroma/pleroma git clone https://anongit.hacktivis.me/git/pleroma.git/

hashtag_policy.ex (4094B)


  1. # Pleroma: A lightweight social networking server
  2. # Copyright © 2017-2022 Pleroma Authors <https://pleroma.social/>
  3. # SPDX-License-Identifier: AGPL-3.0-only
  4. defmodule Pleroma.Web.ActivityPub.MRF.HashtagPolicy do
  5. require Pleroma.Constants
  6. alias Pleroma.Config
  7. alias Pleroma.Object
  8. @moduledoc """
  9. Reject, TWKN-remove or Set-Sensitive activities with specific hashtags (without the leading #)
  10. Note: This MRF Policy is always enabled, if you want to disable it you have to set empty lists.
  11. """
  12. @behaviour Pleroma.Web.ActivityPub.MRF.Policy
  13. @impl true
  14. def history_awareness, do: :manual
  15. defp check_reject(activity, hashtags) do
  16. if Enum.any?(Config.get([:mrf_hashtag, :reject]), fn match -> match in hashtags end) do
  17. {:reject, "[HashtagPolicy] Matches with rejected keyword"}
  18. else
  19. {:ok, activity}
  20. end
  21. end
  22. defp check_ftl_removal(%{"to" => to} = activity, hashtags) do
  23. if Pleroma.Constants.as_public() in to and
  24. Enum.any?(Config.get([:mrf_hashtag, :federated_timeline_removal]), fn match ->
  25. match in hashtags
  26. end) do
  27. to = List.delete(to, Pleroma.Constants.as_public())
  28. cc = [Pleroma.Constants.as_public() | activity["cc"] || []]
  29. activity =
  30. activity
  31. |> Map.put("to", to)
  32. |> Map.put("cc", cc)
  33. |> Kernel.put_in(["object", "to"], to)
  34. |> Kernel.put_in(["object", "cc"], cc)
  35. {:ok, activity}
  36. else
  37. {:ok, activity}
  38. end
  39. end
  40. defp check_ftl_removal(activity, _hashtags), do: {:ok, activity}
  41. defp check_sensitive(activity) do
  42. {:ok, new_object} =
  43. Object.Updater.do_with_history(activity["object"], fn object ->
  44. hashtags = Object.hashtags(%Object{data: object})
  45. if Enum.any?(Config.get([:mrf_hashtag, :sensitive]), fn match -> match in hashtags end) do
  46. {:ok, Map.put(object, "sensitive", true)}
  47. else
  48. {:ok, object}
  49. end
  50. end)
  51. {:ok, Map.put(activity, "object", new_object)}
  52. end
  53. @impl true
  54. def filter(%{"type" => type, "object" => object} = activity)
  55. when type in ["Create", "Update"] do
  56. history_items =
  57. with %{"formerRepresentations" => %{"orderedItems" => items}} <- object do
  58. items
  59. else
  60. _ -> []
  61. end
  62. historical_hashtags =
  63. Enum.reduce(history_items, [], fn item, acc ->
  64. acc ++ Object.hashtags(%Object{data: item})
  65. end)
  66. hashtags = Object.hashtags(%Object{data: object}) ++ historical_hashtags
  67. if hashtags != [] do
  68. with {:ok, activity} <- check_reject(activity, hashtags),
  69. {:ok, activity} <-
  70. (if type == "Create" do
  71. check_ftl_removal(activity, hashtags)
  72. else
  73. {:ok, activity}
  74. end),
  75. {:ok, activity} <- check_sensitive(activity) do
  76. {:ok, activity}
  77. end
  78. else
  79. {:ok, activity}
  80. end
  81. end
  82. @impl true
  83. def filter(activity), do: {:ok, activity}
  84. @impl true
  85. def describe do
  86. mrf_hashtag =
  87. Config.get(:mrf_hashtag)
  88. |> Enum.into(%{})
  89. {:ok, %{mrf_hashtag: mrf_hashtag}}
  90. end
  91. @impl true
  92. def config_description do
  93. %{
  94. key: :mrf_hashtag,
  95. related_policy: "Pleroma.Web.ActivityPub.MRF.HashtagPolicy",
  96. label: "MRF Hashtag",
  97. description: @moduledoc,
  98. children: [
  99. %{
  100. key: :reject,
  101. type: {:list, :string},
  102. description: "A list of hashtags which result in the activity being rejected.",
  103. suggestions: ["foo"]
  104. },
  105. %{
  106. key: :federated_timeline_removal,
  107. type: {:list, :string},
  108. description:
  109. "A list of hashtags which result in the activity being removed from federated timelines (a.k.a unlisted).",
  110. suggestions: ["foo"]
  111. },
  112. %{
  113. key: :sensitive,
  114. type: {:list, :string},
  115. description:
  116. "A list of hashtags which result in the activity being set as sensitive (a.k.a NSFW/R-18)",
  117. suggestions: ["nsfw", "r18"]
  118. }
  119. ]
  120. }
  121. end
  122. end