From 977e711e22dd5171cbff241c7e763de8d34eef26 Mon Sep 17 00:00:00 2001 From: Thibaut Girka Date: Wed, 2 Oct 2019 13:18:51 +0200 Subject: [PATCH] Import object from self-Announce whenever possible --- .../web/activity_pub/transmogrifier.ex | 25 ++++++++++++- test/fixtures/mastodon-announce-private.json | 35 +++++++++++++++++++ test/support/http_request_mock.ex | 8 +++++ test/web/activity_pub/transmogrifier_test.exs | 20 ++++++++++- 4 files changed, 86 insertions(+), 2 deletions(-) create mode 100644 test/fixtures/mastodon-announce-private.json diff --git a/lib/pleroma/web/activity_pub/transmogrifier.ex b/lib/pleroma/web/activity_pub/transmogrifier.ex index 64c470fc8..8f9bf5525 100644 --- a/lib/pleroma/web/activity_pub/transmogrifier.ex +++ b/lib/pleroma/web/activity_pub/transmogrifier.ex @@ -580,7 +580,7 @@ def handle_incoming( ) do with actor <- Containment.get_actor(data), {:ok, %User{} = actor} <- User.get_or_fetch_by_ap_id(actor), - {:ok, object} <- get_obj_helper(object_id), + {:ok, object} <- get_embedded_obj_helper(object_id, actor), public <- Visibility.is_public?(data), {:ok, activity, _object} <- ActivityPub.announce(actor, object, id, false, public) do {:ok, activity} @@ -781,6 +781,29 @@ def get_obj_helper(id, options \\ []) do end end + @spec get_embedded_obj_helper(String.t() | Object.t(), User.t()) :: {:ok, Object.t()} | nil + def get_embedded_obj_helper(%{"attributedTo" => attributedTo, "id" => object_id} = data, %User{ + ap_id: ap_id + }) + when attributedTo == ap_id do + with {:ok, activity} <- + handle_incoming(%{ + "type" => "Create", + "to" => data["to"], + "cc" => data["cc"], + "actor" => data["attributedTo"], + "object" => data + }) do + {:ok, Object.normalize(activity)} + else + _ -> get_obj_helper(object_id) + end + end + + def get_embedded_obj_helper(object_id, _) do + get_obj_helper(object_id) + end + def set_reply_to_uri(%{"inReplyTo" => in_reply_to} = object) when is_binary(in_reply_to) do with false <- String.starts_with?(in_reply_to, "http"), {:ok, %{data: replied_to_object}} <- get_obj_helper(in_reply_to) do diff --git a/test/fixtures/mastodon-announce-private.json b/test/fixtures/mastodon-announce-private.json new file mode 100644 index 000000000..9b868b13d --- /dev/null +++ b/test/fixtures/mastodon-announce-private.json @@ -0,0 +1,35 @@ +{ + "type": "Announce", + "to": [ + "http://mastodon.example.org/users/admin/followers" + ], + "published": "2018-02-17T19:39:15Z", + "object": { + "type": "Note", + "id": "http://mastodon.example.org/@admin/99541947525187368", + "attributedTo": "http://mastodon.example.org/users/admin", + "content": "this is a private toot", + "to": [ + "http://mastodon.example.org/users/admin/followers" + ] + }, + "id": "http://mastodon.example.org/users/admin/statuses/99542391527669785/activity", + "atomUri": "http://mastodon.example.org/users/admin/statuses/99542391527669785/activity", + "actor": "http://mastodon.example.org/users/admin", + "@context": [ + "https://www.w3.org/ns/activitystreams", + "https://w3id.org/security/v1", + { + "toot": "http://joinmastodon.org/ns#", + "sensitive": "as:sensitive", + "ostatus": "http://ostatus.org#", + "movedTo": "as:movedTo", + "manuallyApprovesFollowers": "as:manuallyApprovesFollowers", + "inReplyToAtomUri": "ostatus:inReplyToAtomUri", + "conversation": "ostatus:conversation", + "atomUri": "ostatus:atomUri", + "Hashtag": "as:Hashtag", + "Emoji": "toot:Emoji" + } + ] +} diff --git a/test/support/http_request_mock.ex b/test/support/http_request_mock.ex index 5506c0626..7a87a2b35 100644 --- a/test/support/http_request_mock.ex +++ b/test/support/http_request_mock.ex @@ -349,6 +349,14 @@ def get( }} end + def get("http://mastodon.example.org/@admin/99541947525187368", _, _, _) do + {:ok, + %Tesla.Env{ + status: 404, + body: "" + }} + end + def get("https://shitposter.club/notice/7369654", _, _, _) do {:ok, %Tesla.Env{ diff --git a/test/web/activity_pub/transmogrifier_test.exs b/test/web/activity_pub/transmogrifier_test.exs index b995f0224..d25334104 100644 --- a/test/web/activity_pub/transmogrifier_test.exs +++ b/test/web/activity_pub/transmogrifier_test.exs @@ -442,6 +442,25 @@ test "it works for incoming announces with an existing activity" do assert Activity.get_create_by_object_ap_id(data["object"]).id == activity.id end + test "it works for incoming announces with an inlined activity" do + data = + File.read!("test/fixtures/mastodon-announce-private.json") + |> Poison.decode!() + + {:ok, %Activity{data: data, local: false}} = Transmogrifier.handle_incoming(data) + + assert data["actor"] == "http://mastodon.example.org/users/admin" + assert data["type"] == "Announce" + + assert data["id"] == + "http://mastodon.example.org/users/admin/statuses/99542391527669785/activity" + + object = Object.normalize(data["object"]) + + assert object.data["id"] == "http://mastodon.example.org/@admin/99541947525187368" + assert object.data["content"] == "this is a private toot" + end + test "it does not clobber the addressing on announce activities" do user = insert(:user) {:ok, activity} = CommonAPI.post(user, %{"status" => "hey"}) @@ -1084,7 +1103,6 @@ test "it inlines private announced objects" do {:ok, announce_activity, _} = CommonAPI.repeat(activity.id, user) {:ok, modified} = Transmogrifier.prepare_outgoing(announce_activity.data) - object = modified["object"] assert modified["object"]["content"] == "hey" assert modified["object"]["actor"] == modified["object"]["attributedTo"]