From 3da65292b389c1f1edeff03fd5097579721fb681 Mon Sep 17 00:00:00 2001 From: lain Date: Mon, 26 Aug 2019 14:34:52 -0500 Subject: [PATCH 1/2] Transmogrifier: Fix follow handling when the actor is an object. --- CHANGELOG.md | 1 + lib/pleroma/object.ex | 4 ++ lib/pleroma/web/activity_pub/transmogrifier.ex | 4 +- test/fixtures/osada-follow-activity.json | 56 ++++++++++++++++++++++ test/fixtures/tesla_mock/osada-user-indio.json | 1 + test/support/http_request_mock.ex | 5 ++ .../transmogrifier/follow_handling_test.exs | 19 ++++++++ 7 files changed, 88 insertions(+), 2 deletions(-) create mode 100644 test/fixtures/osada-follow-activity.json create mode 100644 test/fixtures/tesla_mock/osada-user-indio.json diff --git a/CHANGELOG.md b/CHANGELOG.md index 2fdcb014a..20af9badc 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -21,6 +21,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). - Improve digest email template ### Fixed +- Following from Osada - Not being able to pin unlisted posts - Objects being re-embedded to activities after being updated (e.g faved/reposted). Running 'mix pleroma.database prune_objects' again is advised. - Favorites timeline doing database-intensive queries diff --git a/lib/pleroma/object.ex b/lib/pleroma/object.ex index c8d339c19..468549c87 100644 --- a/lib/pleroma/object.ex +++ b/lib/pleroma/object.ex @@ -230,4 +230,8 @@ defmodule Pleroma.Object do _ -> :noop end end + + def get_ap_id(%{"id" => id}), do: id + def get_ap_id(id) when is_binary(id), do: id + def get_ap_id(_), do: {:error, "Object is not a string and has no id."} end diff --git a/lib/pleroma/web/activity_pub/transmogrifier.ex b/lib/pleroma/web/activity_pub/transmogrifier.ex index 36340a3a1..6c4259c02 100644 --- a/lib/pleroma/web/activity_pub/transmogrifier.ex +++ b/lib/pleroma/web/activity_pub/transmogrifier.ex @@ -464,8 +464,8 @@ defmodule Pleroma.Web.ActivityPub.Transmogrifier do %{"type" => "Follow", "object" => followed, "actor" => follower, "id" => id} = data, _options ) do - with %User{local: true} = followed <- User.get_cached_by_ap_id(followed), - {:ok, %User{} = follower} <- User.get_or_fetch_by_ap_id(follower), + with %User{local: true} = followed <- User.get_cached_by_ap_id(Object.get_ap_id(followed)), + {:ok, %User{} = follower} <- User.get_or_fetch_by_ap_id(Object.get_ap_id(follower)), {:ok, activity} <- ActivityPub.follow(follower, followed, id, false) do with deny_follow_blocked <- Pleroma.Config.get([:user, :deny_follow_blocked]), {_, false} <- {:user_blocked, User.blocks?(followed, follower) && deny_follow_blocked}, diff --git a/test/fixtures/osada-follow-activity.json b/test/fixtures/osada-follow-activity.json new file mode 100644 index 000000000..b991eea36 --- /dev/null +++ b/test/fixtures/osada-follow-activity.json @@ -0,0 +1,56 @@ +{ + "@context":[ + "https://www.w3.org/ns/activitystreams", + "https://w3id.org/security/v1", + "https://apfed.club/apschema/v1.4" + ], + "id":"https://apfed.club/follow/9", + "type":"Follow", + "actor":{ + "type":"Person", + "id":"https://apfed.club/channel/indio", + "preferredUsername":"indio", + "name":"Indio", + "updated":"2019-08-20T23:52:34Z", + "icon":{ + "type":"Image", + "mediaType":"image/jpeg", + "updated":"2019-08-20T23:53:37Z", + "url":"https://apfed.club/photo/profile/l/2", + "height":300, + "width":300 + }, + "url":"https://apfed.club/channel/indio", + "inbox":"https://apfed.club/inbox/indio", + "outbox":"https://apfed.club/outbox/indio", + "followers":"https://apfed.club/followers/indio", + "following":"https://apfed.club/following/indio", + "endpoints":{ + "sharedInbox":"https://apfed.club/inbox" + }, + "publicKey":{ + "id":"https://apfed.club/channel/indio", + "owner":"https://apfed.club/channel/indio", + "publicKeyPem":"-----BEGIN PUBLIC KEY-----\nMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEA77TIR1VuSYFnmDRFGHHb\n4vaGdx9ranzRX4bfOKAqa++Ch5L4EqJpPy08RuM+NrYCYiYl4QQFDSSDXAEgb5g9\nC1TgWTfI7q/E0UBX2Vr0mU6X4i1ztv0tuQvegRjcSJ7l1AvoBs8Ip4MEJ3OPEQhB\ngJqAACB3Gnps4zi2I0yavkxUfGVKr6zKT3BxWh5hTpKC7Do+ChIrVZC2EwxND9K6 +\nsAnQHThcb5EQuvuzUQZKeS7IEOsd0JpZDmJjbfMGrAWE81pLIfEeeA2joCJiBBTO\nglDsW+juvZ+lWqJpMr2hMWpvfrFjJeUawNJCIzsLdVIZR+aKj5yy6yqoS8hkN9Ha\n1MljZpsXl+EmwcwAIqim1YeLwERCEAQ/JWbSt8pQTQbzZ6ibwQ4mchCxacrRbIVR +\nnL59fWMBassJcbY0VwrTugm2SBsYbDjESd55UZV03Rwr8qseGTyi+hH8O7w2SIaY\nzjN6AdZiPmsh00YflzlCk8MSLOHMol1vqIUzXxU8CdXn9+KsuQdZGrTz0YKN/db4\naVwUGJatz2Tsvf7R1tJBjJfeQWOWbbn3pycLVH86LjZ83qngp9ZVnAveUnUqz0yS +\nhe+buZ6UMsfGzbIYon2bKNlz6gYTH0YPcr+cLe+29drtt0GZiXha1agbpo4RB8zE +\naNL2fucF5YT0yNpbd/5WoV0CAwEAAQ==\n-----END PUBLIC KEY-----\n" + } + }, + "object":"https://pleroma.site/users/kaniini", + "to":[ + "https://pleroma.site/users/kaniini" + ], + "signature":{ + "@context":[ + "https://www.w3.org/ns/activitystreams", + "https://w3id.org/security/v1" + ], + "type":"RsaSignature2017", + "nonce":"52c035e0a9e81dce8b486159204e97c22637e91f75cdfad5378de91de68e9117", + "creator":"https://apfed.club/channel/indio/public_key_pem", + "created":"2019-08-22T03:38:02Z", + "signatureValue":"oVliRCIqNIh6yUp851dYrF0y21aHp3Rz6VkIpW1pFMWfXuzExyWSfcELpyLseeRmsw5bUu9zJkH44B4G2LiJQKA9UoEQDjrDMZBmbeUpiQqq3DVUzkrBOI8bHZ7xyJ/CjSZcNHHh0MHhSKxswyxWMGi4zIqzkAZG3vRRgoPVHdjPm00sR3B8jBLw1cjoffv+KKeM/zEUpe13gqX9qHAWHHqZepxgSWmq+EKOkRvHUPBXiEJZfXzc5uW+vZ09F3WBYmaRoy8Y0e1P29fnRLqSy7EEINdrHaGclRqoUZyiawpkgy3lWWlynesV/HiLBR7EXT79eKstxf4wfTDaPKBCfTCsOWuMWHr7Genu37ew2/t7eiBGqCwwW12ylhml/OLHgNK3LOhmRABhtfpaFZSxfDVnlXfaLpY1xekVOj2oC0FpBtnoxVKLpIcyLw6dkfSil5ANd+hl59W/bpPA8KT90ii1fSNCo3+FcwQVx0YsPznJNA60XfFuVsme7zNcOst6393e1WriZxBanFpfB63zVQc9u1fjyfktx/yiUNxIlre+sz9OCc0AACn94iRhBYh4bbzdleUOTnM7lnD4Dj2FP+xeDIP8CA8wXUeq5+9kopSp2kAmlUEyFUdg4no7naIeu1SZnopfUg56PsVCp9JHiUK1SYAyWbdC+FbUECu5CvI=" + } +} diff --git a/test/fixtures/tesla_mock/osada-user-indio.json b/test/fixtures/tesla_mock/osada-user-indio.json new file mode 100644 index 000000000..c1d52c92a --- /dev/null +++ b/test/fixtures/tesla_mock/osada-user-indio.json @@ -0,0 +1 @@ +{"@context":["https://www.w3.org/ns/activitystreams","https://w3id.org/security/v1"],"type":"Person","id":"https://apfed.club/channel/indio","preferredUsername":"indio","name":"Indio","updated":"2019-08-20T23:52:34Z","icon":{"type":"Image","mediaType":"image/jpeg","updated":"2019-08-20T23:53:37Z","url":"https://apfed.club/photo/profile/l/2","height":300,"width":300},"url":"https://apfed.club/channel/indio","inbox":"https://apfed.club/inbox/indio","outbox":"https://apfed.club/outbox/indio","followers":"https://apfed.club/followers/indio","following":"https://apfed.club/following/indio","endpoints":{"sharedInbox":"https://apfed.club/inbox"},"publicKey":{"id":"https://apfed.club/channel/indio","owner":"https://apfed.club/channel/indio","publicKeyPem":"-----BEGIN PUBLIC KEY-----\nMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEA77TIR1VuSYFnmDRFGHHb\n4vaGdx9ranzRX4bfOKAqa++Ch5L4EqJpPy08RuM+NrYCYiYl4QQFDSSDXAEgb5g9\nC1TgWTfI7q/E0UBX2Vr0mU6X4i1ztv0tuQvegRjcSJ7l1AvoBs8Ip4MEJ3OPEQhB\ngJqAACB3Gnps4zi2I0yavkxUfGVKr6zKT3BxWh5hTpKC7Do+ChIrVZC2EwxND9K6\nsAnQHThcb5EQuvuzUQZKeS7IEOsd0JpZDmJjbfMGrAWE81pLIfEeeA2joCJiBBTO\nglDsW+juvZ+lWqJpMr2hMWpvfrFjJeUawNJCIzsLdVIZR+aKj5yy6yqoS8hkN9Ha\n1MljZpsXl+EmwcwAIqim1YeLwERCEAQ/JWbSt8pQTQbzZ6ibwQ4mchCxacrRbIVR\nnL59fWMBassJcbY0VwrTugm2SBsYbDjESd55UZV03Rwr8qseGTyi+hH8O7w2SIaY\nzjN6AdZiPmsh00YflzlCk8MSLOHMol1vqIUzXxU8CdXn9+KsuQdZGrTz0YKN/db4\naVwUGJatz2Tsvf7R1tJBjJfeQWOWbbn3pycLVH86LjZ83qngp9ZVnAveUnUqz0yS\nhe+buZ6UMsfGzbIYon2bKNlz6gYTH0YPcr+cLe+29drtt0GZiXha1agbpo4RB8zE\naNL2fucF5YT0yNpbd/5WoV0CAwEAAQ==\n-----END PUBLIC KEY-----\n"},"signature":{"@context":["https://www.w3.org/ns/activitystreams","https://w3id.org/security/v1"],"type":"RsaSignature2017","nonce":"c672a408d2e88b322b36a61bf0c25f586be9245d30293c55b8d653dcc867aaf7","creator":"https://apfed.club/channel/indio/public_key_pem","created":"2019-08-26T07:24:03Z","signatureValue":"MyAv5gnedu6L/DYFaE1TUYvp4LjI9ZUU0axwGYOhgD7qsjivMgwbOrjX/iH32xlcfF8nWOMh/ogu3+Qwr5sqLHkS2AimWmw1+Ubf2KccE58b8vI8zWfyu8QJnMuE92jtBPv8UTQUHw8ZebbExk3L99oXaeyVihKiMBmd63NpVTpGXZTg6m+H+KfWchVajPoyNKZtKMd3nH99x5j54Cqkz0BN5CSTwCSG0wP95G0VtZHtmhX+tsAPM3oAj0d+gtCZSCd8Nu8fvFAwCyTg1oKSfRqKb27EKHlskqK9X57x0jURH77CTAIQSejgGcKJ5GGLtvofubJkafadjagqrtqz6Mz6BZ642ssJ2KGkRAn79Q4F08goI6cfU5lLk2Tooe5A55XERnmE3SkYGyTvLpacZplxJdU0sa+deX9D7+alSGFJZSziaxpCxzrO6lEApe4b9kHXAzn9VaZt9trijkHq/kkq0i3NRcP7n8JG9q+Vv8jY9ddY6HcH89RNCBIA6MKLtAqc+vSc5G24qeZlw2MzlQWBp0KGuVG8DQR00AL6cXLBzF1WY8JZeEg6zqm+DMznbuNzgiS34BP+AehBSHlQ4MZebwDnK3ZPPqGSwioIWMxIFfZDaVDX9Pp1pXAARQMw0c/y4sDcf9FMzsr8jteEa7ZQcoqq5kXQTSCP56TEHnI="}} \ No newline at end of file diff --git a/test/support/http_request_mock.ex b/test/support/http_request_mock.ex index 55b141dd8..05eebbe9b 100644 --- a/test/support/http_request_mock.ex +++ b/test/support/http_request_mock.ex @@ -775,6 +775,11 @@ defmodule HttpRequestMock do {:ok, %Tesla.Env{status: 200, body: File.read!("test/fixtures/lambadalambda.json")}} end + def get("https://apfed.club/channel/indio", _, _, _) do + {:ok, + %Tesla.Env{status: 200, body: File.read!("test/fixtures/tesla_mock/osada-user-indio.json")}} + end + def get("https://social.heldscal.la/user/23211", _, _, Accept: "application/activity+json") do {:ok, Tesla.Mock.json(%{"id" => "https://social.heldscal.la/user/23211"}, status: 200)} end diff --git a/test/web/activity_pub/transmogrifier/follow_handling_test.exs b/test/web/activity_pub/transmogrifier/follow_handling_test.exs index 857d65564..fe89f7cb0 100644 --- a/test/web/activity_pub/transmogrifier/follow_handling_test.exs +++ b/test/web/activity_pub/transmogrifier/follow_handling_test.exs @@ -19,6 +19,25 @@ defmodule Pleroma.Web.ActivityPub.Transmogrifier.FollowHandlingTest do end describe "handle_incoming" do + test "it works for osada follow request" do + user = insert(:user) + + data = + File.read!("test/fixtures/osada-follow-activity.json") + |> Poison.decode!() + |> Map.put("object", user.ap_id) + + {:ok, %Activity{data: data, local: false} = activity} = Transmogrifier.handle_incoming(data) + + assert data["actor"] == "https://apfed.club/channel/indio" + assert data["type"] == "Follow" + assert data["id"] == "https://apfed.club/follow/9" + + activity = Repo.get(Activity, activity.id) + assert activity.data["state"] == "accept" + assert User.following?(User.get_cached_by_ap_id(data["actor"]), user) + end + test "it works for incoming follow requests" do user = insert(:user) From c30cc039e423e8f31d0222747e301514b7d0dd9e Mon Sep 17 00:00:00 2001 From: lain Date: Tue, 27 Aug 2019 12:22:30 -0500 Subject: [PATCH 2/2] Transmogrifier: Use Containment.get_actor to get actors. --- lib/pleroma/object.ex | 4 ---- lib/pleroma/web/activity_pub/transmogrifier.ex | 6 ++++-- 2 files changed, 4 insertions(+), 6 deletions(-) diff --git a/lib/pleroma/object.ex b/lib/pleroma/object.ex index 468549c87..c8d339c19 100644 --- a/lib/pleroma/object.ex +++ b/lib/pleroma/object.ex @@ -230,8 +230,4 @@ defmodule Pleroma.Object do _ -> :noop end end - - def get_ap_id(%{"id" => id}), do: id - def get_ap_id(id) when is_binary(id), do: id - def get_ap_id(_), do: {:error, "Object is not a string and has no id."} end diff --git a/lib/pleroma/web/activity_pub/transmogrifier.ex b/lib/pleroma/web/activity_pub/transmogrifier.ex index 6c4259c02..468961bd0 100644 --- a/lib/pleroma/web/activity_pub/transmogrifier.ex +++ b/lib/pleroma/web/activity_pub/transmogrifier.ex @@ -464,8 +464,10 @@ defmodule Pleroma.Web.ActivityPub.Transmogrifier do %{"type" => "Follow", "object" => followed, "actor" => follower, "id" => id} = data, _options ) do - with %User{local: true} = followed <- User.get_cached_by_ap_id(Object.get_ap_id(followed)), - {:ok, %User{} = follower} <- User.get_or_fetch_by_ap_id(Object.get_ap_id(follower)), + with %User{local: true} = followed <- + User.get_cached_by_ap_id(Containment.get_actor(%{"actor" => followed})), + {:ok, %User{} = follower} <- + User.get_or_fetch_by_ap_id(Containment.get_actor(%{"actor" => follower})), {:ok, activity} <- ActivityPub.follow(follower, followed, id, false) do with deny_follow_blocked <- Pleroma.Config.get([:user, :deny_follow_blocked]), {_, false} <- {:user_blocked, User.blocks?(followed, follower) && deny_follow_blocked},