From 4f44fd32eae100d5ce74b3c9bd5457858f145198 Mon Sep 17 00:00:00 2001 From: Tusooa Zhu Date: Sun, 12 Sep 2021 21:52:44 -0400 Subject: [PATCH] Federate unfollow activity in move_following properly 0: Use the CommonAPI unfollow function to make sure the unfollow activity is federated. 1: Limit the follow and unfollow to local followers only, while let the romote servers decide whether to move their followers. Ref: emit-move --- lib/pleroma/following_relationship.ex | 3 +- .../web/activity_pub/activity_pub_test.exs | 36 +++++++++++++++++++ 2 files changed, 38 insertions(+), 1 deletion(-) diff --git a/lib/pleroma/following_relationship.ex b/lib/pleroma/following_relationship.ex index a0c7e6e39..61d36ce93 100644 --- a/lib/pleroma/following_relationship.ex +++ b/lib/pleroma/following_relationship.ex @@ -194,11 +194,12 @@ def move_following(origin, target) do |> join(:inner, [r], f in assoc(r, :follower)) |> where(following_id: ^origin.id) |> where([r, f], f.allow_following_move == true) + |> where([r, f], f.local == true) |> limit(50) |> preload([:follower]) |> Repo.all() |> Enum.map(fn following_relationship -> - Repo.delete(following_relationship) + Pleroma.Web.CommonAPI.unfollow(following_relationship.follower, origin) Pleroma.Web.CommonAPI.follow(following_relationship.follower, target) end) |> case do diff --git a/test/pleroma/web/activity_pub/activity_pub_test.exs b/test/pleroma/web/activity_pub/activity_pub_test.exs index 3021f2995..dec28f81b 100644 --- a/test/pleroma/web/activity_pub/activity_pub_test.exs +++ b/test/pleroma/web/activity_pub/activity_pub_test.exs @@ -1775,6 +1775,42 @@ test "old user must be in the new user's `also_known_as` list" do assert {:error, "Target account must have the origin in `alsoKnownAs`"} = ActivityPub.move(old_user, new_user) end + + test "do not move remote user following relationships" do + %{ap_id: old_ap_id} = old_user = insert(:user) + %{ap_id: new_ap_id} = new_user = insert(:user, also_known_as: [old_ap_id]) + follower_remote = insert(:user, local: false) + + User.follow(follower_remote, old_user) + + assert User.following?(follower_remote, old_user) + + assert {:ok, activity} = ActivityPub.move(old_user, new_user) + + assert %Activity{ + actor: ^old_ap_id, + data: %{ + "actor" => ^old_ap_id, + "object" => ^old_ap_id, + "target" => ^new_ap_id, + "type" => "Move" + }, + local: true + } = activity + + params = %{ + "op" => "move_following", + "origin_id" => old_user.id, + "target_id" => new_user.id + } + + assert_enqueued(worker: Pleroma.Workers.BackgroundWorker, args: params) + + Pleroma.Workers.BackgroundWorker.perform(%Oban.Job{args: params}) + + assert User.following?(follower_remote, old_user) + refute User.following?(follower_remote, new_user) + end end test "doesn't retrieve replies activities with exclude_replies" do