From da67e69af522d0c31cb9b2ce9fc6bafca5d990dc Mon Sep 17 00:00:00 2001 From: Floatingghost Date: Sun, 26 May 2024 17:09:26 +0100 Subject: [PATCH 1/2] Allow for attachment to be a single object in user data --- lib/pleroma/web/activity_pub/activity_pub.ex | 5 ++ test/fixtures/users_mock/takahe_user.json | 53 +++++++++++++++++++ .../web/activity_pub/activity_pub_test.exs | 23 ++++++++ 3 files changed, 81 insertions(+) create mode 100644 test/fixtures/users_mock/takahe_user.json diff --git a/lib/pleroma/web/activity_pub/activity_pub.ex b/lib/pleroma/web/activity_pub/activity_pub.ex index 505fa7462..73828c27f 100644 --- a/lib/pleroma/web/activity_pub/activity_pub.ex +++ b/lib/pleroma/web/activity_pub/activity_pub.ex @@ -1545,10 +1545,15 @@ defmodule Pleroma.Web.ActivityPub.ActivityPub do defp normalize_also_known_as(aka) when is_binary(aka), do: [aka] defp normalize_also_known_as(nil), do: [] + defp normalize_attachment(%{} = attachment), do: [attachment] + defp normalize_attachment(attachment) when is_list(attachment), do: attachment + defp normalize_attachment(_), do: [] + defp object_to_user_data(data, additional) do fields = data |> Map.get("attachment", []) + |> normalize_attachment() |> Enum.filter(fn %{"type" => t} -> t == "PropertyValue" end) |> Enum.map(fn fields -> Map.take(fields, ["name", "value"]) end) diff --git a/test/fixtures/users_mock/takahe_user.json b/test/fixtures/users_mock/takahe_user.json new file mode 100644 index 000000000..247cf2052 --- /dev/null +++ b/test/fixtures/users_mock/takahe_user.json @@ -0,0 +1,53 @@ +{ + "@context": [ + "https://www.w3.org/ns/activitystreams", + { + "blurhash": "toot:blurhash", + "Emoji": "toot:Emoji", + "focalPoint": { + "@container": "@list", + "@id": "toot:focalPoint" + }, + "Hashtag": "as:Hashtag", + "manuallyApprovesFollowers": "as:manuallyApprovesFollowers", + "sensitive": "as:sensitive", + "toot": "http://joinmastodon.org/ns#", + "votersCount": "toot:votersCount", + "featured": { + "@id": "toot:featured", + "@type": "@id" + } + }, + "https://w3id.org/security/v1" + ], + "id": "https://fedi.vision/@vote@fedi.vision/", + "type": "Person", + "toot:discoverable": true, + "inbox": "https://fedi.vision/@vote@fedi.vision/inbox/", + "publicKey": { + "id": "https://fedi.vision/@vote@fedi.vision/#main-key", + "owner": "https://fedi.vision/@vote@fedi.vision/", + "publicKeyPem": "-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAj2f+uQtdoBO9X/u2Qso4\nxHYdfy8zB24m9Gg982/ts88DAMLxZUzX0JsBWT7coL0Ipf4NSbVaqS6nKrr2P8Qs\nf97wMhowyuYxK22BMPcbpfZkFj3tVT/JkDx2iujBJJ5ZBO5KRlupjDTqV4rOAY7F\n58ad0jK9PsJNJMsJ/b8+0t3Q/K+RqCGVmtK+iPSigOYoiKoquyRzHLTfP+mpOlDa\n3f+uyAbFya7CpcgBx1zz0PALWA+oh/zhZK4yT6719Esa8SDcoJ0ws70zMxWekq1A\n3ia88/Io6SY2qFNBpzzXGO3JK8OFRFtmPV8ZfAh5Pv6y52iuTJ21kxjAG7ZTP/fY\nBQIDAQAB\n-----END PUBLIC KEY-----\n" + }, + "attachment": { + "type": "PropertyValue", + "value": "https://fedivision.party/vote", + "name": "More details" + }, + "endpoints": { + "sharedInbox": "https://fedi.vision/inbox/" + }, + "followers": "https://fedi.vision/@vote@fedi.vision/followers/", + "following": "https://fedi.vision/@vote@fedi.vision/following/", + "icon": { + "type": "Image", + "mediaType": "image/webp", + "url": "https://eu-central-1.linodeobjects.com:443/st4/profile_images/2024/5/9/RwqTbeYx16gauXPXvt-CaysOnGw.webp" + }, + "name": "FediVision Vote Bot", + "outbox": "https://fedi.vision/@vote@fedi.vision/outbox/", + "preferredUsername": "vote", + "published": "2024-05-09T09:04:04Z", + "summary": "

New in 2024, this is the bot that will count your #Fedivision vote! Accept no substitutes!

Send this account a toot in the form
vote ABCD EFGH IJKL
substituting the (up to) three codes for the songs you want to win. Punctuation ignored, case insensitive, order is unimportant. Only your latest toot counts, so change your vote with a new toot.

", + "url": "https://fedi.vision/@vote/" +} diff --git a/test/pleroma/web/activity_pub/activity_pub_test.exs b/test/pleroma/web/activity_pub/activity_pub_test.exs index 5ad6d4716..6d73f777c 100644 --- a/test/pleroma/web/activity_pub/activity_pub_test.exs +++ b/test/pleroma/web/activity_pub/activity_pub_test.exs @@ -233,6 +233,29 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubTest do } end + test "works for takahe actors" do + user_id = "https://fedi.vision/@vote@fedi.vision/" + + Tesla.Mock.mock(fn + %{method: :get, url: ^user_id} -> + %Tesla.Env{ + status: 200, + body: File.read!("test/fixtures/users_mock/takahe_user.json"), + headers: [{"content-type", "application/activity+json"}] + } + end) + + {:ok, user} = ActivityPub.make_user_from_ap_id(user_id) + + assert user.actor_type == "Person" + + assert [ + %{ + "name" => "More details" + } + ] = user.fields + end + test "fetches user featured collection" do ap_id = "https://example.com/users/lain" From f15eded3e1e7ea1342c66a210147b0d5e9df5a75 Mon Sep 17 00:00:00 2001 From: Floatingghost Date: Mon, 27 May 2024 02:09:48 +0100 Subject: [PATCH 2/2] Add extra test case for nonsense field, increase timeouts --- lib/pleroma/web/activity_pub/activity_pub.ex | 5 +- .../users_mock/nonsense_attachment_user.json | 51 +++++++++++++++++++ test/mix/tasks/pleroma/app_test.exs | 6 +-- test/pleroma/http/backoff_test.exs | 2 +- .../web/activity_pub/activity_pub_test.exs | 19 +++++++ 5 files changed, 78 insertions(+), 5 deletions(-) create mode 100644 test/fixtures/users_mock/nonsense_attachment_user.json diff --git a/lib/pleroma/web/activity_pub/activity_pub.ex b/lib/pleroma/web/activity_pub/activity_pub.ex index 73828c27f..4512393f3 100644 --- a/lib/pleroma/web/activity_pub/activity_pub.ex +++ b/lib/pleroma/web/activity_pub/activity_pub.ex @@ -1554,7 +1554,10 @@ defmodule Pleroma.Web.ActivityPub.ActivityPub do data |> Map.get("attachment", []) |> normalize_attachment() - |> Enum.filter(fn %{"type" => t} -> t == "PropertyValue" end) + |> Enum.filter(fn + %{"type" => t} -> t == "PropertyValue" + _ -> false + end) |> Enum.map(fn fields -> Map.take(fields, ["name", "value"]) end) emojis = diff --git a/test/fixtures/users_mock/nonsense_attachment_user.json b/test/fixtures/users_mock/nonsense_attachment_user.json new file mode 100644 index 000000000..68042e76e --- /dev/null +++ b/test/fixtures/users_mock/nonsense_attachment_user.json @@ -0,0 +1,51 @@ +{ + "@context": [ + "https://www.w3.org/ns/activitystreams", + { + "blurhash": "toot:blurhash", + "Emoji": "toot:Emoji", + "focalPoint": { + "@container": "@list", + "@id": "toot:focalPoint" + }, + "Hashtag": "as:Hashtag", + "manuallyApprovesFollowers": "as:manuallyApprovesFollowers", + "sensitive": "as:sensitive", + "toot": "http://joinmastodon.org/ns#", + "votersCount": "toot:votersCount", + "featured": { + "@id": "toot:featured", + "@type": "@id" + } + }, + "https://w3id.org/security/v1" + ], + "id": "https://fedi.vision/@vote@fedi.vision/", + "type": "Person", + "toot:discoverable": true, + "inbox": "https://fedi.vision/@vote@fedi.vision/inbox/", + "publicKey": { + "id": "https://fedi.vision/@vote@fedi.vision/#main-key", + "owner": "https://fedi.vision/@vote@fedi.vision/", + "publicKeyPem": "-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAj2f+uQtdoBO9X/u2Qso4\nxHYdfy8zB24m9Gg982/ts88DAMLxZUzX0JsBWT7coL0Ipf4NSbVaqS6nKrr2P8Qs\nf97wMhowyuYxK22BMPcbpfZkFj3tVT/JkDx2iujBJJ5ZBO5KRlupjDTqV4rOAY7F\n58ad0jK9PsJNJMsJ/b8+0t3Q/K+RqCGVmtK+iPSigOYoiKoquyRzHLTfP+mpOlDa\n3f+uyAbFya7CpcgBx1zz0PALWA+oh/zhZK4yT6719Esa8SDcoJ0ws70zMxWekq1A\n3ia88/Io6SY2qFNBpzzXGO3JK8OFRFtmPV8ZfAh5Pv6y52iuTJ21kxjAG7ZTP/fY\nBQIDAQAB\n-----END PUBLIC KEY-----\n" + }, + "attachment": { + "haha": "you expected a proper object, but it was me, random nonsense" + }, + "endpoints": { + "sharedInbox": "https://fedi.vision/inbox/" + }, + "followers": "https://fedi.vision/@vote@fedi.vision/followers/", + "following": "https://fedi.vision/@vote@fedi.vision/following/", + "icon": { + "type": "Image", + "mediaType": "image/webp", + "url": "https://eu-central-1.linodeobjects.com:443/st4/profile_images/2024/5/9/RwqTbeYx16gauXPXvt-CaysOnGw.webp" + }, + "name": "FediVision Vote Bot", + "outbox": "https://fedi.vision/@vote@fedi.vision/outbox/", + "preferredUsername": "vote", + "published": "2024-05-09T09:04:04Z", + "summary": "

New in 2024, this is the bot that will count your #Fedivision vote! Accept no substitutes!

Send this account a toot in the form
vote ABCD EFGH IJKL
substituting the (up to) three codes for the songs you want to win. Punctuation ignored, case insensitive, order is unimportant. Only your latest toot counts, so change your vote with a new toot.

", + "url": "https://fedi.vision/@vote/" +} diff --git a/test/mix/tasks/pleroma/app_test.exs b/test/mix/tasks/pleroma/app_test.exs index 7eb4c4352..a86bfaf97 100644 --- a/test/mix/tasks/pleroma/app_test.exs +++ b/test/mix/tasks/pleroma/app_test.exs @@ -50,13 +50,13 @@ defmodule Mix.Tasks.Pleroma.AppTest do defp assert_app(name, redirect, scopes) do app = Repo.get_by(Pleroma.Web.OAuth.App, client_name: name) - assert_receive {:mix_shell, :info, [message]}, 1_000 + assert_receive {:mix_shell, :info, [message]}, 5_000 assert message == "#{name} successfully created:" - assert_receive {:mix_shell, :info, [message]}, 1_000 + assert_receive {:mix_shell, :info, [message]}, 5_000 assert message == "App client_id: #{app.client_id}" - assert_receive {:mix_shell, :info, [message]}, 1_000 + assert_receive {:mix_shell, :info, [message]}, 5_000 assert message == "App client_secret: #{app.client_secret}" assert app.scopes == scopes diff --git a/test/pleroma/http/backoff_test.exs b/test/pleroma/http/backoff_test.exs index f1b27f5b5..8e0afad05 100644 --- a/test/pleroma/http/backoff_test.exs +++ b/test/pleroma/http/backoff_test.exs @@ -4,7 +4,7 @@ defmodule Pleroma.HTTP.BackoffTest do alias Pleroma.HTTP.Backoff defp within_tolerance?(ttl, expected) do - ttl > expected - 10 and ttl < expected + 10 + ttl > expected - 15 and ttl < expected + 15 end describe "get/3" do diff --git a/test/pleroma/web/activity_pub/activity_pub_test.exs b/test/pleroma/web/activity_pub/activity_pub_test.exs index 6d73f777c..4c4bbdd4b 100644 --- a/test/pleroma/web/activity_pub/activity_pub_test.exs +++ b/test/pleroma/web/activity_pub/activity_pub_test.exs @@ -256,6 +256,25 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubTest do ] = user.fields end + test "works for actors with malformed attachment fields" do + user_id = "https://fedi.vision/@vote@fedi.vision/" + + Tesla.Mock.mock(fn + %{method: :get, url: ^user_id} -> + %Tesla.Env{ + status: 200, + body: File.read!("test/fixtures/users_mock/nonsense_attachment_user.json"), + headers: [{"content-type", "application/activity+json"}] + } + end) + + {:ok, user} = ActivityPub.make_user_from_ap_id(user_id) + + assert user.actor_type == "Person" + + assert [] = user.fields + end + test "fetches user featured collection" do ap_id = "https://example.com/users/lain"