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.

172 line
4.4KB

  1. # Pleroma: A lightweight social networking server
  2. # Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
  3. # SPDX-License-Identifier: AGPL-3.0-only
  4. defmodule Pleroma.Web.ActivityPub.MRF.TagPolicy do
  5. alias Pleroma.User
  6. @behaviour Pleroma.Web.ActivityPub.MRF
  7. @moduledoc """
  8. Apply policies based on user tags
  9. This policy applies policies on a user activities depending on their tags
  10. on your instance.
  11. - `mrf_tag:media-force-nsfw`: Mark as sensitive on presence of attachments
  12. - `mrf_tag:media-strip`: Remove attachments
  13. - `mrf_tag:force-unlisted`: Mark as unlisted (removes from the federated timeline)
  14. - `mrf_tag:sandbox`: Remove from public (local and federated) timelines
  15. - `mrf_tag:disable-remote-subscription`: Reject non-local follow requests
  16. - `mrf_tag:disable-any-subscription`: Reject any follow requests
  17. """
  18. require Pleroma.Constants
  19. defp get_tags(%User{tags: tags}) when is_list(tags), do: tags
  20. defp get_tags(_), do: []
  21. defp process_tag(
  22. "mrf_tag:media-force-nsfw",
  23. %{
  24. "type" => "Create",
  25. "object" => %{"attachment" => child_attachment} = object
  26. } = message
  27. )
  28. when length(child_attachment) > 0 do
  29. tags = (object["tag"] || []) ++ ["nsfw"]
  30. object =
  31. object
  32. |> Map.put("tag", tags)
  33. |> Map.put("sensitive", true)
  34. message = Map.put(message, "object", object)
  35. {:ok, message}
  36. end
  37. defp process_tag(
  38. "mrf_tag:media-strip",
  39. %{
  40. "type" => "Create",
  41. "object" => %{"attachment" => child_attachment} = object
  42. } = message
  43. )
  44. when length(child_attachment) > 0 do
  45. object = Map.delete(object, "attachment")
  46. message = Map.put(message, "object", object)
  47. {:ok, message}
  48. end
  49. defp process_tag(
  50. "mrf_tag:force-unlisted",
  51. %{
  52. "type" => "Create",
  53. "to" => to,
  54. "cc" => cc,
  55. "actor" => actor,
  56. "object" => object
  57. } = message
  58. ) do
  59. user = User.get_cached_by_ap_id(actor)
  60. if Enum.member?(to, Pleroma.Constants.as_public()) do
  61. to = List.delete(to, Pleroma.Constants.as_public()) ++ [user.follower_address]
  62. cc = List.delete(cc, user.follower_address) ++ [Pleroma.Constants.as_public()]
  63. object =
  64. object
  65. |> Map.put("to", to)
  66. |> Map.put("cc", cc)
  67. message =
  68. message
  69. |> Map.put("to", to)
  70. |> Map.put("cc", cc)
  71. |> Map.put("object", object)
  72. {:ok, message}
  73. else
  74. {:ok, message}
  75. end
  76. end
  77. defp process_tag(
  78. "mrf_tag:sandbox",
  79. %{
  80. "type" => "Create",
  81. "to" => to,
  82. "cc" => cc,
  83. "actor" => actor,
  84. "object" => object
  85. } = message
  86. ) do
  87. user = User.get_cached_by_ap_id(actor)
  88. if Enum.member?(to, Pleroma.Constants.as_public()) or
  89. Enum.member?(cc, Pleroma.Constants.as_public()) do
  90. to = List.delete(to, Pleroma.Constants.as_public()) ++ [user.follower_address]
  91. cc = List.delete(cc, Pleroma.Constants.as_public())
  92. object =
  93. object
  94. |> Map.put("to", to)
  95. |> Map.put("cc", cc)
  96. message =
  97. message
  98. |> Map.put("to", to)
  99. |> Map.put("cc", cc)
  100. |> Map.put("object", object)
  101. {:ok, message}
  102. else
  103. {:ok, message}
  104. end
  105. end
  106. defp process_tag(
  107. "mrf_tag:disable-remote-subscription",
  108. %{"type" => "Follow", "actor" => actor} = message
  109. ) do
  110. user = User.get_cached_by_ap_id(actor)
  111. if user.local == true do
  112. {:ok, message}
  113. else
  114. {:reject, nil}
  115. end
  116. end
  117. defp process_tag("mrf_tag:disable-any-subscription", %{"type" => "Follow"}),
  118. do: {:reject, nil}
  119. defp process_tag(_, message), do: {:ok, message}
  120. def filter_message(actor, message) do
  121. User.get_cached_by_ap_id(actor)
  122. |> get_tags()
  123. |> Enum.reduce({:ok, message}, fn
  124. tag, {:ok, message} ->
  125. process_tag(tag, message)
  126. _, error ->
  127. error
  128. end)
  129. end
  130. @impl true
  131. def filter(%{"object" => target_actor, "type" => "Follow"} = message),
  132. do: filter_message(target_actor, message)
  133. @impl true
  134. def filter(%{"actor" => actor, "type" => "Create"} = message),
  135. do: filter_message(actor, message)
  136. @impl true
  137. def filter(message), do: {:ok, message}
  138. @impl true
  139. def describe, do: {:ok, %{}}
  140. end