ensure local follow activities are purged on undo
ci/woodpecker/push/woodpecker Pipeline is pending Details

This commit is contained in:
FloatingGhost 2022-08-31 18:28:30 +01:00
parent decbca0c91
commit 98288fab53
4 changed files with 50 additions and 18 deletions

View File

@ -331,9 +331,9 @@ defmodule Pleroma.Web.ActivityPub.ActivityPub do
defp do_unfollow(follower, followed, activity_id, local) when local == true do
with %Activity{} = follow_activity <- fetch_latest_follow(follower, followed),
{:ok, follow_activity} <- update_follow_state(follow_activity, "cancelled"),
unfollow_data <- make_unfollow_data(follower, followed, follow_activity, activity_id),
{:ok, activity} <- insert(unfollow_data, local),
{:ok, _activity} <- Repo.delete(follow_activity),
_ <- notify_and_stream(activity),
:ok <- maybe_federate(activity) do
{:ok, activity}
@ -349,7 +349,7 @@ defmodule Pleroma.Web.ActivityPub.ActivityPub do
with %Activity{} = follow_activity <- fetch_latest_follow(follower, followed),
{:ok, _activity} <- Repo.delete(follow_activity),
unfollow_data <- make_unfollow_data(follower, followed, follow_activity, activity_id),
unfollow_activity <- remote_unfollow_data(unfollow_data),
unfollow_activity <- make_unfollow_activity(unfollow_data, false),
_ <- notify_and_stream(unfollow_activity) do
{:ok, unfollow_activity}
else
@ -358,12 +358,12 @@ defmodule Pleroma.Web.ActivityPub.ActivityPub do
end
end
defp remote_unfollow_data(data) do
defp make_unfollow_activity(data, local) do
{recipients, _, _} = get_recipients(data)
%Activity{
data: data,
local: false,
local: local,
actor: data["actor"],
recipients: recipients
}

View File

@ -472,18 +472,6 @@ defmodule Pleroma.Web.ActivityPub.Utils do
{:ok, activity}
end
def update_follow_state(
%Activity{} = activity,
state
) do
new_data = Map.put(activity.data, "state", state)
changeset = Changeset.change(activity, data: new_data)
with {:ok, activity} <- Repo.update(changeset) do
{:ok, activity}
end
end
@doc """
Makes a follow activity data for the given follower and followed
"""

View File

@ -0,0 +1,22 @@
defmodule Pleroma.Repo.Migrations.RemoveLocalCancelledFollows do
use Ecto.Migration
def up do
statement = """
DELETE FROM
activities
WHERE
(data->>'type') = 'Follow'
AND
(data->>'state') = 'cancelled'
AND
local = true;
"""
execute(statement)
end
def down do
:ok
end
end

View File

@ -1373,6 +1373,25 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubTest do
assert embedded_object["id"] == follow_activity.data["id"]
end
test "it removes the follow activity if it was local" do
follower = insert(:user, local: true)
followed = insert(:user)
{:ok, _, _, follow_activity} = CommonAPI.follow(follower, followed)
{:ok, activity} = ActivityPub.unfollow(follower, followed, nil, true)
assert activity.data["type"] == "Undo"
assert activity.data["actor"] == follower.ap_id
follow_activity = Activity.get_by_id(follow_activity.id)
assert is_nil(follow_activity)
assert is_nil(Utils.fetch_latest_follow(follower, followed))
# We need to keep our own undo
undo_activity = Activity.get_by_ap_id(activity.data["id"])
refute is_nil(undo_activity)
end
test "it removes the follow activity if it was remote" do
follower = insert(:user, local: false)
followed = insert(:user)
@ -1383,9 +1402,12 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubTest do
assert activity.data["type"] == "Undo"
assert activity.data["actor"] == follower.ap_id
activity = Activity.get_by_id(follow_activity.id)
assert is_nil(activity)
follow_activity = Activity.get_by_id(follow_activity.id)
assert is_nil(follow_activity)
assert is_nil(Utils.fetch_latest_follow(follower, followed))
undo_activity = Activity.get_by_ap_id(activity.data["id"])
assert is_nil(undo_activity)
end
end