fix(activitypub): refetch a stale Move target once
A Move usually follows right after the alias was added, and the cached remote target may not have it yet. Refetch the target when the alias is missing instead of rejecting the Move. Same issue as Akkoma f18e2ba42.
This commit is contained in:
parent
3e9dc477c9
commit
3cd201c365
3 changed files with 65 additions and 1 deletions
1
changelog.d/move-refetch-target.fix
Normal file
1
changelog.d/move-refetch-target.fix
Normal file
|
|
@ -0,0 +1 @@
|
|||
Accept a Move when the cached remote target does not list the alias yet, by refetching the target once
|
||||
|
|
@ -799,7 +799,7 @@ defmodule Pleroma.Web.ActivityPub.Transmogrifier do
|
|||
) do
|
||||
with %User{} = origin_user <- User.get_cached_by_ap_id(origin_actor),
|
||||
{:ok, %User{} = target_user} <- User.get_or_fetch_by_ap_id(target_actor),
|
||||
true <- origin_actor in target_user.also_known_as do
|
||||
{:ok, %User{} = target_user} <- refetch_unless_aliased(target_user, origin_actor) do
|
||||
ActivityPub.move(origin_user, target_user, false)
|
||||
else
|
||||
_e -> :error
|
||||
|
|
@ -1204,4 +1204,20 @@ defmodule Pleroma.Web.ActivityPub.Transmogrifier do
|
|||
def maybe_fix_user_url(data), do: data
|
||||
|
||||
def maybe_fix_user_object(data), do: maybe_fix_user_url(data)
|
||||
|
||||
# A Move usually follows right after the alias was added, which the cached
|
||||
# remote target may not have yet.
|
||||
defp refetch_unless_aliased(%User{} = target, origin_ap_id, refetch? \\ true) do
|
||||
cond do
|
||||
origin_ap_id in target.also_known_as ->
|
||||
{:ok, target}
|
||||
|
||||
refetch? and not target.local ->
|
||||
with {:ok, %User{} = target} <- User.fetch_by_ap_id(target.ap_id),
|
||||
do: refetch_unless_aliased(target, origin_ap_id, false)
|
||||
|
||||
true ->
|
||||
:error
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -147,6 +147,53 @@ defmodule Pleroma.Web.ActivityPub.TransmogrifierTest do
|
|||
assert activity.data["type"] == "Move"
|
||||
end
|
||||
|
||||
test "it refetches a cached remote Move target that lacks the alias" do
|
||||
old_user = insert(:user, local: false, ap_id: "https://old.example/users/old")
|
||||
|
||||
new_user =
|
||||
insert(:user,
|
||||
local: false,
|
||||
ap_id: "https://new.example/users/new",
|
||||
nickname: "new@new.example",
|
||||
last_refreshed_at: NaiveDateTime.utc_now()
|
||||
)
|
||||
|
||||
actor = %{
|
||||
"@context" => "https://www.w3.org/ns/activitystreams",
|
||||
"id" => new_user.ap_id,
|
||||
"type" => "Person",
|
||||
"preferredUsername" => "new",
|
||||
"inbox" => new_user.ap_id <> "/inbox",
|
||||
"outbox" => new_user.ap_id <> "/outbox",
|
||||
"followers" => new_user.ap_id <> "/followers",
|
||||
"following" => new_user.ap_id <> "/following",
|
||||
"alsoKnownAs" => [old_user.ap_id]
|
||||
}
|
||||
|
||||
Tesla.Mock.mock(fn
|
||||
%{method: :get, url: "https://new.example/users/new"} ->
|
||||
%Tesla.Env{
|
||||
status: 200,
|
||||
headers: [{"content-type", "application/activity+json"}],
|
||||
body: Jason.encode!(actor)
|
||||
}
|
||||
|
||||
_ ->
|
||||
%Tesla.Env{status: 404}
|
||||
end)
|
||||
|
||||
message = %{
|
||||
"@context" => "https://www.w3.org/ns/activitystreams",
|
||||
"type" => "Move",
|
||||
"actor" => old_user.ap_id,
|
||||
"object" => old_user.ap_id,
|
||||
"target" => new_user.ap_id
|
||||
}
|
||||
|
||||
assert {:ok, %Activity{data: %{"type" => "Move"}}} = Transmogrifier.handle_incoming(message)
|
||||
assert old_user.ap_id in User.get_cached_by_ap_id(new_user.ap_id).also_known_as
|
||||
end
|
||||
|
||||
test "it fixes both the Create and object contexts in a reply" do
|
||||
insert(:user, ap_id: "https://mk.absturztau.be/users/8ozbzjs3o8")
|
||||
insert(:user, ap_id: "https://p.helene.moe/users/helene")
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue