don't persist undo of follows (#149)

Reviewed-on: AkkomaGang/akkoma#149
This commit is contained in:
floatingghost 2022-08-05 13:28:56 +00:00
parent 2781faaa7b
commit 0ec3a11895
3 changed files with 79 additions and 1 deletions

View file

@ -327,7 +327,9 @@ def unfollow(follower, followed, activity_id \\ nil, local \\ true) do
end
end
defp do_unfollow(follower, followed, activity_id, local) do
defp do_unfollow(follower, followed, activity_id, local)
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),
@ -341,6 +343,32 @@ defp do_unfollow(follower, followed, activity_id, local) do
end
end
defp do_unfollow(follower, followed, activity_id, false) do
# On a remote unfollow, _remove_ their activity from the database, since some software (MISSKEEEEY)
# uses deterministic ids for follows.
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),
_ <- notify_and_stream(unfollow_activity) do
{:ok, unfollow_activity}
else
nil -> nil
{:error, error} -> Repo.rollback(error)
end
end
defp remote_unfollow_data(data) do
{recipients, _, _} = get_recipients(data)
%Activity{
data: data,
local: false,
actor: data["actor"],
recipients: recipients
}
end
@spec flag(map()) :: {:ok, Activity.t()} | {:error, any()}
def flag(params) do
with {:ok, result} <- Repo.transaction(fn -> do_flag(params) end) do

View file

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

View file

@ -1375,6 +1375,21 @@ test "creates an undo activity for a pending follow request" do
assert embedded_object["object"] == followed.ap_id
assert embedded_object["id"] == follow_activity.data["id"]
end
test "it removes the follow activity if it was remote" do
follower = insert(:user, local: false)
followed = insert(:user)
{:ok, _, _, follow_activity} = CommonAPI.follow(follower, followed)
{:ok, activity} = ActivityPub.unfollow(follower, followed, nil, false)
assert activity.data["type"] == "Undo"
assert activity.data["actor"] == follower.ap_id
activity = Activity.get_by_id(follow_activity.id)
assert is_nil(activity)
assert is_nil(Utils.fetch_latest_follow(follower, followed))
end
end
describe "timeline post-processing" do