activitypub: fix filtering of boosts from blocked users
[akkoma] / lib / pleroma / web / activity_pub / activity_pub.ex
index 5311583382100e64042a4f4e22604fdbe58d7bb8..cb88ba308c105deb2d9411d257ed1eb9f75c41a0 100644 (file)
@@ -91,12 +91,11 @@ defmodule Pleroma.Web.ActivityPub.ActivityPub do
   end
 
   def increase_replies_count_if_reply(%{
-        "object" =>
-          %{"inReplyTo" => reply_ap_id, "inReplyToStatusId" => reply_status_id} = object,
+        "object" => %{"inReplyTo" => reply_ap_id} = object,
         "type" => "Create"
       }) do
     if is_public?(object) do
-      Activity.increase_replies_count(reply_status_id)
+      Activity.increase_replies_count(reply_ap_id)
       Object.increase_replies_count(reply_ap_id)
     end
   end
@@ -104,25 +103,25 @@ defmodule Pleroma.Web.ActivityPub.ActivityPub do
   def increase_replies_count_if_reply(_create_data), do: :noop
 
   def decrease_replies_count_if_reply(%Object{
-        data: %{"inReplyTo" => reply_ap_id, "inReplyToStatusId" => reply_status_id} = object
+        data: %{"inReplyTo" => reply_ap_id} = object
       }) do
     if is_public?(object) do
-      Activity.decrease_replies_count(reply_status_id)
+      Activity.decrease_replies_count(reply_ap_id)
       Object.decrease_replies_count(reply_ap_id)
     end
   end
 
   def decrease_replies_count_if_reply(_object), do: :noop
 
-  def insert(map, local \\ true) when is_map(map) do
+  def insert(map, local \\ true, fake \\ false) when is_map(map) do
     with nil <- Activity.normalize(map),
-         map <- lazy_put_activity_defaults(map),
+         map <- lazy_put_activity_defaults(map, fake),
          :ok <- check_actor_is_active(map["actor"]),
          {_, true} <- {:remote_limit_error, check_remote_limit(map)},
          {:ok, map} <- MRF.filter(map),
+         {recipients, _, _} = get_recipients(map),
+         {:fake, false, map, recipients} <- {:fake, fake, map, recipients},
          {:ok, object} <- insert_full_object(map) do
-      {recipients, _, _} = get_recipients(map)
-
       {:ok, activity} =
         Repo.insert(%Activity{
           data: map,
@@ -147,8 +146,23 @@ defmodule Pleroma.Web.ActivityPub.ActivityPub do
       stream_out(activity)
       {:ok, activity}
     else
-      %Activity{} = activity -> {:ok, activity}
-      error -> {:error, error}
+      %Activity{} = activity ->
+        {:ok, activity}
+
+      {:fake, true, map, recipients} ->
+        activity = %Activity{
+          data: map,
+          local: local,
+          actor: map["actor"],
+          recipients: recipients,
+          id: "pleroma:fakeid"
+        }
+
+        Pleroma.Web.RichMedia.Helpers.fetch_data_for_activity(activity)
+        {:ok, activity}
+
+      error ->
+        {:error, error}
     end
   end
 
@@ -191,7 +205,7 @@ defmodule Pleroma.Web.ActivityPub.ActivityPub do
     end
   end
 
-  def create(%{to: to, actor: actor, context: context, object: object} = params) do
+  def create(%{to: to, actor: actor, context: context, object: object} = params, fake \\ false) do
     additional = params[:additional] || %{}
     # only accept false as false value
     local = !(params[:local] == false)
@@ -202,13 +216,17 @@ defmodule Pleroma.Web.ActivityPub.ActivityPub do
              %{to: to, actor: actor, published: published, context: context, object: object},
              additional
            ),
-         {:ok, activity} <- insert(create_data, local),
+         {:ok, activity} <- insert(create_data, local, fake),
+         {:fake, false, activity} <- {:fake, fake, activity},
          _ <- increase_replies_count_if_reply(create_data),
          # Changing note count prior to enqueuing federation task in order to avoid
          # race conditions on updating user.info
          {:ok, _actor} <- increase_note_count_if_public(actor, activity),
          :ok <- maybe_federate(activity) do
       {:ok, activity}
+    else
+      {:fake, true, activity} ->
+        {:ok, activity}
     end
   end
 
@@ -431,8 +449,8 @@ defmodule Pleroma.Web.ActivityPub.ActivityPub do
          :ok <- maybe_federate(activity) do
       Enum.each(User.all_superusers(), fn superuser ->
         superuser
-        |> Pleroma.AdminEmail.report(actor, account, statuses, content)
-        |> Pleroma.Mailer.deliver_async()
+        |> Pleroma.Emails.AdminEmail.report(actor, account, statuses, content)
+        |> Pleroma.Emails.Mailer.deliver_async()
       end)
 
       {:ok, activity}
@@ -694,7 +712,14 @@ defmodule Pleroma.Web.ActivityPub.ActivityPub do
     from(
       activity in query,
       where: fragment("not (? = ANY(?))", activity.actor, ^blocks),
-      where: fragment("not (?->'to' \\?| ?)", activity.data, ^blocks),
+      where: fragment("not (? && ?)", activity.recipients, ^blocks),
+      where:
+        fragment(
+          "not (?->>'type' = 'Announce' and ?->'to' \\?| ?)",
+          activity.data,
+          activity.data,
+          ^blocks
+        ),
       where: fragment("not (split_part(?, '/', 3) = ANY(?))", activity.actor, ^domain_blocks)
     )
   end