extend reject MRF to check if originating instance is blocked
[akkoma] / lib / pleroma / web / activity_pub / mrf / hashtag_policy.ex
index def0c437cc06628e32da2ca38b0a9fd57d0fd0bb..b5ad8b5b4d8b7ff2137588cde1dda9f9ca90ec67 100644 (file)
@@ -14,7 +14,10 @@ defmodule Pleroma.Web.ActivityPub.MRF.HashtagPolicy do
   Note: This MRF Policy is always enabled, if you want to disable it you have to set empty lists.
   """
 
-  @behaviour Pleroma.Web.ActivityPub.MRF
+  @behaviour Pleroma.Web.ActivityPub.MRF.Policy
+
+  @impl true
+  def history_awareness, do: :manual
 
   defp check_reject(message, hashtags) do
     if Enum.any?(Config.get([:mrf_hashtag, :reject]), fn match -> match in hashtags end) do
@@ -47,22 +50,46 @@ defmodule Pleroma.Web.ActivityPub.MRF.HashtagPolicy do
 
   defp check_ftl_removal(message, _hashtags), do: {:ok, message}
 
-  defp check_sensitive(message, hashtags) do
-    if Enum.any?(Config.get([:mrf_hashtag, :sensitive]), fn match -> match in hashtags end) do
-      {:ok, Kernel.put_in(message, ["object", "sensitive"], true)}
-    else
-      {:ok, message}
-    end
+  defp check_sensitive(message) do
+    {:ok, new_object} =
+      Object.Updater.do_with_history(message["object"], fn object ->
+        hashtags = Object.hashtags(%Object{data: object})
+
+        if Enum.any?(Config.get([:mrf_hashtag, :sensitive]), fn match -> match in hashtags end) do
+          {:ok, Map.put(object, "sensitive", true)}
+        else
+          {:ok, object}
+        end
+      end)
+
+    {:ok, Map.put(message, "object", new_object)}
   end
 
   @impl true
-  def filter(%{"type" => "Create", "object" => object} = message) do
-    hashtags = Object.hashtags(%Object{data: object})
+  def filter(%{"type" => type, "object" => object} = message) when type in ["Create", "Update"] do
+    history_items =
+      with %{"formerRepresentations" => %{"orderedItems" => items}} <- object do
+        items
+      else
+        _ -> []
+      end
+
+    historical_hashtags =
+      Enum.reduce(history_items, [], fn item, acc ->
+        acc ++ Object.hashtags(%Object{data: item})
+      end)
+
+    hashtags = Object.hashtags(%Object{data: object}) ++ historical_hashtags
 
     if hashtags != [] do
       with {:ok, message} <- check_reject(message, hashtags),
-           {:ok, message} <- check_ftl_removal(message, hashtags),
-           {:ok, message} <- check_sensitive(message, hashtags) do
+           {:ok, message} <-
+             (if "type" == "Create" do
+                check_ftl_removal(message, hashtags)
+              else
+                {:ok, message}
+              end),
+           {:ok, message} <- check_sensitive(message) do
         {:ok, message}
       end
     else