Pipeline: Move transctioning to common pipeline.
[akkoma] / lib / pleroma / web / activity_pub / activity_pub.ex
index 8b170b7f82c84faa75d2ec8e8a93bea929b6b9de..1f4a093702053b1a82e5adc66328b5d4939db728 100644 (file)
@@ -270,9 +270,9 @@ defmodule Pleroma.Web.ActivityPub.ActivityPub do
            ),
          {:ok, activity} <- insert(create_data, local, fake),
          {:fake, false, activity} <- {:fake, fake, activity},
-         {:quick_insert, false, activity} <- {:quick_insert, quick_insert?, activity},
          _ <- increase_replies_count_if_reply(create_data),
          _ <- increase_poll_votes_if_vote(create_data),
+         {:quick_insert, false, activity} <- {:quick_insert, quick_insert?, activity},
          {:ok, _actor} <- increase_note_count_if_public(actor, activity),
          :ok <- maybe_federate(activity) do
       {:ok, activity}
@@ -438,6 +438,7 @@ defmodule Pleroma.Web.ActivityPub.ActivityPub do
 
   defp do_announce(user, object, activity_id, local, public) do
     with true <- is_announceable?(object, user, public),
+         object <- Object.get_by_id(object.id),
          announce_data <- make_announce_data(user, object, activity_id, public),
          {:ok, activity} <- insert(announce_data, local),
          {:ok, object} <- add_announce_to_object(activity, object),
@@ -700,14 +701,12 @@ defmodule Pleroma.Web.ActivityPub.ActivityPub do
         do: [opts["user"].ap_id | User.following(opts["user"])] ++ public,
         else: public
 
-    opts = Map.put(opts, "user", opts["user"])
-
     from(activity in Activity)
     |> maybe_preload_objects(opts)
     |> maybe_preload_bookmarks(opts)
     |> maybe_set_thread_muted_field(opts)
     |> restrict_blocked(opts)
-    |> restrict_recipients(recipients, opts)
+    |> restrict_recipients(recipients, opts["user"])
     |> where(
       [activity],
       fragment(
@@ -742,10 +741,7 @@ defmodule Pleroma.Web.ActivityPub.ActivityPub do
 
   @spec fetch_public_activities(map(), Pagination.type()) :: [Activity.t()]
   def fetch_public_activities(opts \\ %{}, pagination \\ :keyset) do
-    opts =
-      opts
-      |> Map.put("reply_user", opts["user"])
-      |> Map.delete("user")
+    opts = Map.drop(opts, ["user"])
 
     [Constants.as_public()]
     |> fetch_activities_query(opts)
@@ -829,7 +825,7 @@ defmodule Pleroma.Web.ActivityPub.ActivityPub do
   end
 
   defp exclude_visibility(query, %{"exclude_visibilities" => visibility})
-       when visibility not in @valid_visibilities do
+       when visibility not in [nil | @valid_visibilities] do
     Logger.error("Could not exclude visibility to #{visibility}")
     query
   end
@@ -981,65 +977,13 @@ defmodule Pleroma.Web.ActivityPub.ActivityPub do
 
   defp restrict_tag(query, _), do: query
 
-  defp reply_recipients(user, "following") do
-    [user.ap_id | User.get_cached_user_friends_ap_ids(user)]
-  end
-
-  defp reply_recipients(user, "self"), do: [user.ap_id]
-
-  defp restrict_recipients(query, [], _opts), do: query
-
-  defp restrict_recipients(
-         query,
-         recipients,
-         %{"user" => nil, "reply_user" => user, "reply_visibility" => visibility}
-       )
-       when not is_nil(user) and visibility in ["following", "self"] do
-    reply_recipients = reply_recipients(user, visibility)
-
-    from([activity, object] in query,
-      where:
-        fragment(
-          "? && ? AND (?->>'inReplyTo' IS NULL OR array_remove(?, ?) && ? OR ? = ?)",
-          ^recipients,
-          activity.recipients,
-          object.data,
-          activity.recipients,
-          activity.actor,
-          ^reply_recipients,
-          activity.actor,
-          ^user.ap_id
-        )
-    )
-  end
+  defp restrict_recipients(query, [], _user), do: query
 
-  defp restrict_recipients(query, recipients, %{"user" => nil}) do
-    from(activity in query,
-      where: fragment("? && ?", ^recipients, activity.recipients)
-    )
+  defp restrict_recipients(query, recipients, nil) do
+    from(activity in query, where: fragment("? && ?", ^recipients, activity.recipients))
   end
 
-  defp restrict_recipients(query, recipients, %{"user" => user, "reply_visibility" => visibility})
-       when visibility in ["following", "self"] do
-    reply_recipients = reply_recipients(user, visibility)
-
-    from(
-      [activity, object] in query,
-      where:
-        fragment(
-          "? && ? AND (?->>'inReplyTo' IS NULL OR array_remove(?, ?) && ?)",
-          ^recipients,
-          activity.recipients,
-          object.data,
-          activity.recipients,
-          activity.actor,
-          ^reply_recipients
-        ),
-      or_where: activity.actor == ^user.ap_id
-    )
-  end
-
-  defp restrict_recipients(query, recipients, %{"user" => user}) do
+  defp restrict_recipients(query, recipients, user) do
     from(
       activity in query,
       where: fragment("? && ?", ^recipients, activity.recipients),
@@ -1088,7 +1032,7 @@ defmodule Pleroma.Web.ActivityPub.ActivityPub do
     raise "Can't use the child object without preloading!"
   end
 
-  defp restrict_media(query, %{"only_media" => val}) when val == "true" or val == "1" do
+  defp restrict_media(query, %{"only_media" => val}) when val in [true, "true", "1"] do
     from(
       [_activity, object] in query,
       where: fragment("not (?)->'attachment' = (?)", object.data, ^[])
@@ -1097,16 +1041,51 @@ defmodule Pleroma.Web.ActivityPub.ActivityPub do
 
   defp restrict_media(query, _), do: query
 
-  defp restrict_replies(query, %{"exclude_replies" => val}) when val == "true" or val == "1" do
+  defp restrict_replies(query, %{"exclude_replies" => val}) when val in [true, "true", "1"] do
     from(
       [_activity, object] in query,
       where: fragment("?->>'inReplyTo' is null", object.data)
     )
   end
 
+  defp restrict_replies(query, %{
+         "reply_filtering_user" => user,
+         "reply_visibility" => "self"
+       }) do
+    from(
+      [activity, object] in query,
+      where:
+        fragment(
+          "?->>'inReplyTo' is null OR ? = ANY(?)",
+          object.data,
+          ^user.ap_id,
+          activity.recipients
+        )
+    )
+  end
+
+  defp restrict_replies(query, %{
+         "reply_filtering_user" => user,
+         "reply_visibility" => "following"
+       }) do
+    from(
+      [activity, object] in query,
+      where:
+        fragment(
+          "?->>'inReplyTo' is null OR ? && array_remove(?, ?) OR ? = ?",
+          object.data,
+          ^[user.ap_id | User.get_cached_user_friends_ap_ids(user)],
+          activity.recipients,
+          activity.actor,
+          activity.actor,
+          ^user.ap_id
+        )
+    )
+  end
+
   defp restrict_replies(query, _), do: query
 
-  defp restrict_reblogs(query, %{"exclude_reblogs" => val}) when val == "true" or val == "1" do
+  defp restrict_reblogs(query, %{"exclude_reblogs" => val}) when val in [true, "true", "1"] do
     from(activity in query, where: fragment("?->>'type' != 'Announce'", activity.data))
   end
 
@@ -1185,7 +1164,12 @@ defmodule Pleroma.Web.ActivityPub.ActivityPub do
     )
   end
 
-  defp restrict_pinned(query, %{"pinned" => "true", "pinned_activity_ids" => ids}) do
+  # TODO: when all endpoints migrated to OpenAPI compare `pinned` with `true` (boolean) only,
+  # the same for `restrict_media/2`, `restrict_replies/2`, 'restrict_reblogs/2'
+  # and `restrict_muted/2`
+
+  defp restrict_pinned(query, %{"pinned" => pinned, "pinned_activity_ids" => ids})
+       when pinned in [true, "true", "1"] do
     from(activity in query, where: activity.id in ^ids)
   end
 
@@ -1311,15 +1295,14 @@ defmodule Pleroma.Web.ActivityPub.ActivityPub do
       skip_thread_containment: Config.get([:instance, :skip_thread_containment])
     }
 
-    opts = Map.put(opts, "user", opts["user"])
-
     Activity
     |> maybe_preload_objects(opts)
     |> maybe_preload_bookmarks(opts)
     |> maybe_preload_report_notes(opts)
     |> maybe_set_thread_muted_field(opts)
     |> maybe_order(opts)
-    |> restrict_recipients(recipients, opts)
+    |> restrict_recipients(recipients, opts["user"])
+    |> restrict_replies(opts)
     |> restrict_tag(opts)
     |> restrict_tag_reject(opts)
     |> restrict_tag_all(opts)
@@ -1334,7 +1317,6 @@ defmodule Pleroma.Web.ActivityPub.ActivityPub do
     |> restrict_media(opts)
     |> restrict_visibility(opts)
     |> restrict_thread_visibility(opts, config)
-    |> restrict_replies(opts)
     |> restrict_reblogs(opts)
     |> restrict_pinned(opts)
     |> restrict_muted_reblogs(restrict_muted_reblogs_opts)