forked from AkkomaGang/akkoma
Handle "Move" activity
This commit is contained in:
parent
4270861085
commit
61fc739ab8
7 changed files with 146 additions and 0 deletions
|
@ -107,4 +107,28 @@ def following(%User{} = user) do
|
||||||
[user.follower_address | following]
|
[user.follower_address | following]
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def move_following(origin, target) do
|
||||||
|
following_relationships =
|
||||||
|
__MODULE__
|
||||||
|
|> where(following_id: ^origin.id)
|
||||||
|
|> preload([:follower])
|
||||||
|
|> limit(50)
|
||||||
|
|> Repo.all()
|
||||||
|
|
||||||
|
case following_relationships do
|
||||||
|
[] ->
|
||||||
|
:ok
|
||||||
|
|
||||||
|
following_relationships ->
|
||||||
|
Enum.each(following_relationships, fn following_relationship ->
|
||||||
|
Repo.transaction(fn ->
|
||||||
|
Repo.delete(following_relationship)
|
||||||
|
User.follow(following_relationship.follower, target)
|
||||||
|
end)
|
||||||
|
end)
|
||||||
|
|
||||||
|
move_following(origin, target)
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -514,6 +514,30 @@ def flag(
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def move(%User{} = origin, %User{} = target, local \\ true) do
|
||||||
|
params = %{
|
||||||
|
"type" => "Move",
|
||||||
|
"actor" => origin.ap_id,
|
||||||
|
"object" => origin.ap_id,
|
||||||
|
"target" => target.ap_id
|
||||||
|
}
|
||||||
|
|
||||||
|
with true <- origin.ap_id in target.also_known_as,
|
||||||
|
{:ok, activity} <- insert(params, local) do
|
||||||
|
maybe_federate(activity)
|
||||||
|
|
||||||
|
BackgroundWorker.enqueue("move_following", %{
|
||||||
|
"origin_id" => origin.id,
|
||||||
|
"target_id" => target.id
|
||||||
|
})
|
||||||
|
|
||||||
|
{:ok, activity}
|
||||||
|
else
|
||||||
|
false -> {:error, "Target account must have the origin in `alsoKnownAs`"}
|
||||||
|
err -> err
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
defp fetch_activities_for_context_query(context, opts) do
|
defp fetch_activities_for_context_query(context, opts) do
|
||||||
public = [Pleroma.Constants.as_public()]
|
public = [Pleroma.Constants.as_public()]
|
||||||
|
|
||||||
|
|
|
@ -785,6 +785,24 @@ def handle_incoming(
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def handle_incoming(
|
||||||
|
%{
|
||||||
|
"type" => "Move",
|
||||||
|
"actor" => origin_actor,
|
||||||
|
"object" => origin_actor,
|
||||||
|
"target" => target_actor
|
||||||
|
},
|
||||||
|
_options
|
||||||
|
) 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
|
||||||
|
ActivityPub.move(origin_user, target_user, false)
|
||||||
|
else
|
||||||
|
_e -> :error
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
def handle_incoming(_, _), do: :error
|
def handle_incoming(_, _), do: :error
|
||||||
|
|
||||||
@spec get_obj_helper(String.t(), Keyword.t()) :: {:ok, Object.t()} | nil
|
@spec get_obj_helper(String.t(), Keyword.t()) :: {:ok, Object.t()} | nil
|
||||||
|
|
|
@ -14,6 +14,7 @@ defmodule Pleroma.Web.ActivityPub.Visibility do
|
||||||
@spec is_public?(Object.t() | Activity.t() | map()) :: boolean()
|
@spec is_public?(Object.t() | Activity.t() | map()) :: boolean()
|
||||||
def is_public?(%Object{data: %{"type" => "Tombstone"}}), do: false
|
def is_public?(%Object{data: %{"type" => "Tombstone"}}), do: false
|
||||||
def is_public?(%Object{data: data}), do: is_public?(data)
|
def is_public?(%Object{data: data}), do: is_public?(data)
|
||||||
|
def is_public?(%Activity{data: %{"type" => "Move"}}), do: true
|
||||||
def is_public?(%Activity{data: data}), do: is_public?(data)
|
def is_public?(%Activity{data: data}), do: is_public?(data)
|
||||||
def is_public?(%{"directMessage" => true}), do: false
|
def is_public?(%{"directMessage" => true}), do: false
|
||||||
def is_public?(data), do: Utils.label_in_message?(Pleroma.Constants.as_public(), data)
|
def is_public?(data), do: Utils.label_in_message?(Pleroma.Constants.as_public(), data)
|
||||||
|
|
|
@ -71,4 +71,11 @@ def perform(%{"op" => "fetch_data_for_activity", "activity_id" => activity_id},
|
||||||
activity = Activity.get_by_id(activity_id)
|
activity = Activity.get_by_id(activity_id)
|
||||||
Pleroma.Web.RichMedia.Helpers.perform(:fetch, activity)
|
Pleroma.Web.RichMedia.Helpers.perform(:fetch, activity)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def perform(%{"op" => "move_following", "origin_id" => origin_id, "target_id" => target_id}, _) do
|
||||||
|
origin = User.get_cached_by_id(origin_id)
|
||||||
|
target = User.get_cached_by_id(target_id)
|
||||||
|
|
||||||
|
Pleroma.FollowingRelationship.move_following(origin, target)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -4,6 +4,8 @@
|
||||||
|
|
||||||
defmodule Pleroma.Web.ActivityPub.ActivityPubTest do
|
defmodule Pleroma.Web.ActivityPub.ActivityPubTest do
|
||||||
use Pleroma.DataCase
|
use Pleroma.DataCase
|
||||||
|
use Oban.Testing, repo: Pleroma.Repo
|
||||||
|
|
||||||
alias Pleroma.Activity
|
alias Pleroma.Activity
|
||||||
alias Pleroma.Builders.ActivityBuilder
|
alias Pleroma.Builders.ActivityBuilder
|
||||||
alias Pleroma.Object
|
alias Pleroma.Object
|
||||||
|
@ -1420,4 +1422,50 @@ test "detects hidden follows" do
|
||||||
assert follow_info.hide_follows == true
|
assert follow_info.hide_follows == true
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
describe "Move activity" do
|
||||||
|
test "create" 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 = insert(:user)
|
||||||
|
|
||||||
|
User.follow(follower, old_user)
|
||||||
|
|
||||||
|
assert User.following?(follower, 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(params, nil)
|
||||||
|
|
||||||
|
refute User.following?(follower, old_user)
|
||||||
|
assert User.following?(follower, new_user)
|
||||||
|
end
|
||||||
|
|
||||||
|
test "old user must be in the new user's `also_known_as` list" do
|
||||||
|
old_user = insert(:user)
|
||||||
|
new_user = insert(:user)
|
||||||
|
|
||||||
|
assert {:error, "Target account must have the origin in `alsoKnownAs`"} =
|
||||||
|
ActivityPub.move(old_user, new_user)
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -1181,6 +1181,30 @@ test "it correctly processes messages with non-array cc field" do
|
||||||
assert ["https://www.w3.org/ns/activitystreams#Public"] == activity.data["cc"]
|
assert ["https://www.w3.org/ns/activitystreams#Public"] == activity.data["cc"]
|
||||||
assert [user.follower_address] == activity.data["to"]
|
assert [user.follower_address] == activity.data["to"]
|
||||||
end
|
end
|
||||||
|
|
||||||
|
test "it accepts Move activities" do
|
||||||
|
old_user = insert(:user)
|
||||||
|
new_user = insert(:user)
|
||||||
|
|
||||||
|
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 :error = Transmogrifier.handle_incoming(message)
|
||||||
|
|
||||||
|
{:ok, _new_user} = User.update_and_set_cache(new_user, %{also_known_as: [old_user.ap_id]})
|
||||||
|
|
||||||
|
assert {:ok, %Activity{} = activity} = Transmogrifier.handle_incoming(message)
|
||||||
|
assert activity.actor == old_user.ap_id
|
||||||
|
assert activity.data["actor"] == old_user.ap_id
|
||||||
|
assert activity.data["object"] == old_user.ap_id
|
||||||
|
assert activity.data["target"] == new_user.ap_id
|
||||||
|
assert activity.data["type"] == "Move"
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
describe "prepare outgoing" do
|
describe "prepare outgoing" do
|
||||||
|
|
Loading…
Reference in a new issue