diff --git a/config/description.exs b/config/description.exs index 9401bed5c..3777905a3 100644 --- a/config/description.exs +++ b/config/description.exs @@ -1689,6 +1689,13 @@ type: :integer, description: "Following handshake timeout", suggestions: [500] + }, + %{ + key: :max_collection_objects, + type: :integer, + description: + "The maximum number of items to fetch from a remote collections. Setting this too low can lead to only getting partial collections, but too high and you can end up fetching far too many objects.", + suggestions: [50] } ] }, diff --git a/docs/configuration/cheatsheet.md b/docs/configuration/cheatsheet.md index 3097f1190..11083e831 100644 --- a/docs/configuration/cheatsheet.md +++ b/docs/configuration/cheatsheet.md @@ -236,6 +236,7 @@ Notes: * `deny_follow_blocked`: Whether to disallow following an account that has blocked the user in question * `sign_object_fetches`: Sign object fetches with HTTP signatures * `authorized_fetch_mode`: Require HTTP signatures for AP fetches +* `max_collection_objects`: The maximum number of objects to fetch from a remote AP collection. ## Pleroma.User diff --git a/lib/pleroma/collections/fetcher.ex b/lib/pleroma/collections/fetcher.ex index 205c62b4e..382defff4 100644 --- a/lib/pleroma/collections/fetcher.ex +++ b/lib/pleroma/collections/fetcher.ex @@ -14,12 +14,21 @@ def fetch_collection_by_ap_id(ap_id) when is_binary(ap_id) do fetch_collection(ap_id) end - defp fetch_collection(ap_id) do + def fetch_collection(ap_id) when is_binary(ap_id) do with {:ok, page} <- Fetcher.fetch_and_contain_remote_object_from_id(ap_id) do {:ok, objects_from_collection(page)} + else + e -> + Logger.error("Could not fetch collection #{ap_id} - #{inspect(e)}") + e end end + def fetch_collection(%{"type" => type} = page) + when type in ["Collection", "OrderedCollection"] do + {:ok, objects_from_collection(page)} + end + defp items_in_page(%{"type" => type, "orderedItems" => items}) when is_list(items) and type in ["OrderedCollection", "OrderedCollectionPage"], do: items diff --git a/lib/pleroma/web/activity_pub/activity_pub.ex b/lib/pleroma/web/activity_pub/activity_pub.ex index bf766699d..77f38f9f1 100644 --- a/lib/pleroma/web/activity_pub/activity_pub.ex +++ b/lib/pleroma/web/activity_pub/activity_pub.ex @@ -3,6 +3,7 @@ # SPDX-License-Identifier: AGPL-3.0-only defmodule Pleroma.Web.ActivityPub.ActivityPub do + alias Akkoma.Collections alias Pleroma.Activity alias Pleroma.Activity.Ir.Topics alias Pleroma.Config @@ -1677,26 +1678,13 @@ def pin_data_from_featured_collection(%{ end end - def pin_data_from_featured_collection(%{ - "type" => "Collection", - "first" => first - }) do - with {:ok, page} <- Fetcher.fetch_and_contain_remote_object_from_id(first) do - page - |> Map.get("items") - |> Map.new(fn %{"id" => object_ap_id} -> {object_ap_id, NaiveDateTime.utc_now()} end) - else - e -> - Logger.error("Could not decode featured collection at fetch #{first}, #{inspect(e)}") - {:ok, %{}} - end - end - - def pin_data_from_featured_collection(%{ - "type" => type, - "orderedItems" => objects - }) + def pin_data_from_featured_collection( + %{ + "type" => type + } = collection + ) when type in ["OrderedCollection", "Collection"] do + {:ok, objects} = Collections.Fetcher.fetch_collection(collection) Map.new(objects, fn %{"id" => object_ap_id} -> {object_ap_id, NaiveDateTime.utc_now()} end) end