From e1e0d5d75922c0e6738d97963f0df5ed4327d253 Mon Sep 17 00:00:00 2001 From: floatingghost Date: Fri, 18 Nov 2022 11:14:35 +0000 Subject: [PATCH] microblogpub federation fixes (#288) Co-authored-by: FloatingGhost Reviewed-on: https://akkoma.dev/AkkomaGang/akkoma/pulls/288 --- lib/pleroma/http/adapter_helper.ex | 1 + lib/pleroma/user.ex | 3 +- lib/pleroma/web/activity_pub/activity_pub.ex | 14 ++++- .../user_with_invalid_also_known_as.json | 57 +++++++++++++++++++ test/pleroma/object/fetcher_test.exs | 2 +- test/pleroma/user_test.exs | 19 +++++++ 6 files changed, 93 insertions(+), 3 deletions(-) create mode 100644 test/fixtures/microblogpub/user_with_invalid_also_known_as.json diff --git a/lib/pleroma/http/adapter_helper.ex b/lib/pleroma/http/adapter_helper.ex index 4949dd727..e837ac8d4 100644 --- a/lib/pleroma/http/adapter_helper.ex +++ b/lib/pleroma/http/adapter_helper.ex @@ -99,6 +99,7 @@ defp proxy_type(_), do: {:error, :unknown} | {:error, atom()} | nil def parse_proxy(nil), do: nil + def parse_proxy(""), do: nil def parse_proxy(proxy) when is_binary(proxy) do with %URI{} = uri <- URI.parse(proxy), diff --git a/lib/pleroma/user.ex b/lib/pleroma/user.ex index 700cab2b5..eb907a2d8 100644 --- a/lib/pleroma/user.ex +++ b/lib/pleroma/user.ex @@ -1910,7 +1910,8 @@ def get_or_fetch_by_ap_id(ap_id) do {%User{} = user, _} -> {:ok, user} - _ -> + e -> + Logger.error("Could not fetch user, #{inspect(e)}") {:error, :not_found} end end diff --git a/lib/pleroma/web/activity_pub/activity_pub.ex b/lib/pleroma/web/activity_pub/activity_pub.ex index dcdc7085f..254d91a7e 100644 --- a/lib/pleroma/web/activity_pub/activity_pub.ex +++ b/lib/pleroma/web/activity_pub/activity_pub.ex @@ -1530,6 +1530,18 @@ defp object_to_user_data(data, additional) do # we request WebFinger here nickname = additional[:nickname_from_acct] || generate_nickname(data) + # also_known_as must be a URL + also_known_as = + data + |> Map.get("alsoKnownAs", []) + |> Enum.filter(fn url -> + case URI.parse(url) do + %URI{scheme: "http"} -> true + %URI{scheme: "https"} -> true + _ -> false + end + end) + %{ ap_id: data["id"], uri: get_actor_url(data["url"]), @@ -1547,7 +1559,7 @@ defp object_to_user_data(data, additional) do featured_address: featured_address, bio: data["summary"] || "", actor_type: actor_type, - also_known_as: Map.get(data, "alsoKnownAs", []), + also_known_as: also_known_as, public_key: public_key, inbox: data["inbox"], shared_inbox: shared_inbox, diff --git a/test/fixtures/microblogpub/user_with_invalid_also_known_as.json b/test/fixtures/microblogpub/user_with_invalid_also_known_as.json new file mode 100644 index 000000000..a03076226 --- /dev/null +++ b/test/fixtures/microblogpub/user_with_invalid_also_known_as.json @@ -0,0 +1,57 @@ +{ + "@context": [ + "https://www.w3.org/ns/activitystreams", + "https://w3id.org/security/v1", + { + "Hashtag": "as:Hashtag", + "sensitive": "as:sensitive", + "manuallyApprovesFollowers": "as:manuallyApprovesFollowers", + "alsoKnownAs": { + "@id": "as:alsoKnownAs", + "@type": "@id" + }, + "movedTo": { + "@id": "as:movedTo", + "@type": "@id" + }, + "toot": "http://joinmastodon.org/ns#", + "featured": { + "@id": "toot:featured", + "@type": "@id" + }, + "Emoji": "toot:Emoji", + "blurhash": "toot:blurhash", + "votersCount": "toot:votersCount", + "schema": "http://schema.org#", + "PropertyValue": "schema:PropertyValue", + "value": "schema:value", + "ostatus": "http://ostatus.org#", + "conversation": "ostatus:conversation" + } + ], + "type": "Person", + "id": "https://mbp.example.com", + "following": "https://mbp.example.com/following", + "followers": "https://mbp.example.com/followers", + "featured": "https://mbp.example.com/featured", + "inbox": "https://mbp.example.com/inbox", + "outbox": "https://mbp.example.com/outbox", + "preferredUsername": "MBP", + "name": "MBP", + "summary": "wowee", + "endpoints": { + "sharedInbox": "https://mbp.example.com/inbox" + }, + "url": "https://mbp.example.com/", + "manuallyApprovesFollowers": false, + "attachment": [], + "icon": { + "mediaType": "image/jpeg", + "type": "Image", + "url": "https://beta.4201337.xyz/static/denise.jpg" + }, + "tag": [], + "alsoKnownAs": [ + "example@elsewhere.com" + ] +} diff --git a/test/pleroma/object/fetcher_test.exs b/test/pleroma/object/fetcher_test.exs index cd5437617..71306cdfe 100644 --- a/test/pleroma/object/fetcher_test.exs +++ b/test/pleroma/object/fetcher_test.exs @@ -166,7 +166,7 @@ test "it resets instance reachability on successful fetch" do Instances.set_consistently_unreachable(id) refute Instances.reachable?(id) - {:ok, object} = + {:ok, _object} = Fetcher.fetch_object_from_id("http://mastodon.example.org/@admin/99541947525187367") assert Instances.reachable?(id) diff --git a/test/pleroma/user_test.exs b/test/pleroma/user_test.exs index 195df2a03..44763daf7 100644 --- a/test/pleroma/user_test.exs +++ b/test/pleroma/user_test.exs @@ -968,6 +968,25 @@ test "it returns the old user if stale, but unfetchable" do assert user.last_refreshed_at == orig_user.last_refreshed_at end + + test "it doesn't fail on invalid alsoKnownAs entries" do + Tesla.Mock.mock(fn + %{url: "https://mbp.example.com/"} -> + %Tesla.Env{ + status: 200, + body: + "test/fixtures/microblogpub/user_with_invalid_also_known_as.json" + |> File.read!(), + headers: [{"content-type", "application/activity+json"}] + } + + _ -> + %Tesla.Env{status: 404} + end) + + assert {:ok, %User{also_known_as: []}} = + User.get_or_fetch_by_ap_id("https://mbp.example.com/") + end end test "returns an ap_id for a user" do