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.

117 lines
3.3KB

  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.HashtagPolicy do
  5. require Pleroma.Constants
  6. alias Pleroma.Config
  7. alias Pleroma.Object
  8. @moduledoc """
  9. Reject, TWKN-remove or Set-Sensitive messsages 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. defp check_reject(message, hashtags) do
  14. if Enum.any?(Config.get([:mrf_hashtag, :reject]), fn match -> match in hashtags end) do
  15. {:reject, "[HashtagPolicy] Matches with rejected keyword"}
  16. else
  17. {:ok, message}
  18. end
  19. end
  20. defp check_ftl_removal(%{"to" => to} = message, hashtags) do
  21. if Pleroma.Constants.as_public() in to and
  22. Enum.any?(Config.get([:mrf_hashtag, :federated_timeline_removal]), fn match ->
  23. match in hashtags
  24. end) do
  25. to = List.delete(to, Pleroma.Constants.as_public())
  26. cc = [Pleroma.Constants.as_public() | message["cc"] || []]
  27. message =
  28. message
  29. |> Map.put("to", to)
  30. |> Map.put("cc", cc)
  31. |> Kernel.put_in(["object", "to"], to)
  32. |> Kernel.put_in(["object", "cc"], cc)
  33. {:ok, message}
  34. else
  35. {:ok, message}
  36. end
  37. end
  38. defp check_ftl_removal(message, _hashtags), do: {:ok, message}
  39. defp check_sensitive(message, hashtags) do
  40. if Enum.any?(Config.get([:mrf_hashtag, :sensitive]), fn match -> match in hashtags end) do
  41. {:ok, Kernel.put_in(message, ["object", "sensitive"], true)}
  42. else
  43. {:ok, message}
  44. end
  45. end
  46. @impl true
  47. def filter(%{"type" => "Create", "object" => object} = message) do
  48. hashtags = Object.hashtags(%Object{data: object})
  49. if hashtags != [] do
  50. with {:ok, message} <- check_reject(message, hashtags),
  51. {:ok, message} <- check_ftl_removal(message, hashtags),
  52. {:ok, message} <- check_sensitive(message, hashtags) do
  53. {:ok, message}
  54. end
  55. else
  56. {:ok, message}
  57. end
  58. end
  59. @impl true
  60. def filter(message), do: {:ok, message}
  61. @impl true
  62. def describe do
  63. mrf_hashtag =
  64. Config.get(:mrf_hashtag)
  65. |> Enum.into(%{})
  66. {:ok, %{mrf_hashtag: mrf_hashtag}}
  67. end
  68. @impl true
  69. def config_description do
  70. %{
  71. key: :mrf_hashtag,
  72. related_policy: "Pleroma.Web.ActivityPub.MRF.HashtagPolicy",
  73. label: "MRF Hashtag",
  74. description: @moduledoc,
  75. children: [
  76. %{
  77. key: :reject,
  78. type: {:list, :string},
  79. description: "A list of hashtags which result in message being rejected.",
  80. suggestions: ["foo"]
  81. },
  82. %{
  83. key: :federated_timeline_removal,
  84. type: {:list, :string},
  85. description:
  86. "A list of hashtags which result in message being removed from federated timelines (a.k.a unlisted).",
  87. suggestions: ["foo"]
  88. },
  89. %{
  90. key: :sensitive,
  91. type: {:list, :string},
  92. description:
  93. "A list of hashtags which result in message being set as sensitive (a.k.a NSFW/R-18)",
  94. suggestions: ["nsfw", "r18"]
  95. }
  96. ]
  97. }
  98. end
  99. end