
CUrrently internal actors are supposed to be identified in the database by either a NULL nickname or a nickname prefixed by "internal.". For old installations this is true, but only if they were created over five years ago before70410dfafd
. Newer installations will use "relay" as the nickname of the realy actor causing ii to be treated as a regular user. In particular this means all installations in the last five years never made use of the reduced endpoint case, thus it is dropped. Simplify this distinction by properly marking internal actors asa an Application type in the database. This was already implemented before by ilja in https://akkoma.dev/AkkomaGang/akkoma/pulls/457 but accidentally reverted during a translation update ineba3cce77b
. This commit effectively restores this patch together with further changes. Also service actors unconditionally expose follow* collections atm, eventhough the internal fetch actor doesn't actually implement them. Since they are optional per spec and with Mastodon omitting them too for its instance actor proving the practical viability, we should just omit them. The relay actor however should continue to expose such collections and they are properly implemented here. Here too we now just use the values or their absence in the database. We do not have any other internal.* actors besides fetch atm. Fixes: https://akkoma.dev/AkkomaGang/akkoma/issues/855 Co-authored-by: ilja space <git@ilja.space>
180 lines
5.9 KiB
Elixir
180 lines
5.9 KiB
Elixir
# Pleroma: A lightweight social networking server
|
|
# Copyright © 2017-2021 Pleroma Authors <https://pleroma.social/>
|
|
# SPDX-License-Identifier: AGPL-3.0-only
|
|
|
|
defmodule Pleroma.Web.ActivityPub.RelayTest do
|
|
use Pleroma.DataCase, async: false
|
|
@moduletag :mocked
|
|
|
|
alias Pleroma.Activity
|
|
alias Pleroma.User
|
|
alias Pleroma.Web.ActivityPub.Relay
|
|
alias Pleroma.Web.CommonAPI
|
|
|
|
import ExUnit.CaptureLog
|
|
import Pleroma.Factory
|
|
import Mock
|
|
|
|
test "gets an actor for the relay" do
|
|
user = Relay.get_actor()
|
|
assert user.ap_id == "#{Pleroma.Web.Endpoint.url()}/relay"
|
|
end
|
|
|
|
test "relay actor is an application" do
|
|
# See <https://www.w3.org/TR/activitystreams-vocabulary/#dfn-application>
|
|
user = Relay.get_actor()
|
|
assert user.actor_type == "Application"
|
|
end
|
|
|
|
test "relay actor has follow* collections" do
|
|
user = Relay.get_actor()
|
|
assert user.follower_address
|
|
assert user.following_address
|
|
end
|
|
|
|
test "relay actor is invisible" do
|
|
user = Relay.get_actor()
|
|
assert User.invisible?(user)
|
|
end
|
|
|
|
describe "follow/1" do
|
|
test "returns errors when user not found" do
|
|
assert capture_log(fn ->
|
|
{:error, _} = Relay.follow("test-ap-id")
|
|
end) =~ "Could not fetch user test-ap-id,"
|
|
end
|
|
|
|
test "returns activity" do
|
|
user = insert(:user)
|
|
service_actor = Relay.get_actor()
|
|
assert {:ok, %Activity{} = activity} = Relay.follow(user.ap_id)
|
|
assert activity.actor == "#{Pleroma.Web.Endpoint.url()}/relay"
|
|
assert user.ap_id in activity.recipients
|
|
assert activity.data["type"] == "Follow"
|
|
assert activity.data["actor"] == service_actor.ap_id
|
|
assert activity.data["object"] == user.ap_id
|
|
end
|
|
end
|
|
|
|
describe "unfollow/1" do
|
|
test "returns errors when user not found" do
|
|
assert capture_log(fn ->
|
|
{:error, _} = Relay.unfollow("test-ap-id")
|
|
end) =~ "Could not fetch user test-ap-id,"
|
|
end
|
|
|
|
test "returns activity" do
|
|
user = insert(:user)
|
|
service_actor = Relay.get_actor()
|
|
CommonAPI.follow(service_actor, user)
|
|
assert "#{user.ap_id}/followers" in User.following(service_actor)
|
|
assert {:ok, %Activity{} = activity} = Relay.unfollow(user.ap_id)
|
|
assert activity.actor == "#{Pleroma.Web.Endpoint.url()}/relay"
|
|
assert user.ap_id in activity.recipients
|
|
assert activity.data["type"] == "Undo"
|
|
assert activity.data["actor"] == service_actor.ap_id
|
|
assert activity.data["to"] == [user.ap_id]
|
|
refute "#{user.ap_id}/followers" in User.following(service_actor)
|
|
end
|
|
|
|
test "force unfollow when target service is dead" do
|
|
user = insert(:user)
|
|
user_ap_id = user.ap_id
|
|
user_id = user.id
|
|
|
|
Tesla.Mock.mock(fn %{method: :get, url: ^user_ap_id} ->
|
|
%Tesla.Env{status: 404}
|
|
end)
|
|
|
|
service_actor = Relay.get_actor()
|
|
CommonAPI.follow(service_actor, user)
|
|
assert "#{user.ap_id}/followers" in User.following(service_actor)
|
|
|
|
assert Pleroma.Repo.get_by(
|
|
Pleroma.FollowingRelationship,
|
|
follower_id: service_actor.id,
|
|
following_id: user_id
|
|
)
|
|
|
|
Pleroma.Repo.delete(user)
|
|
User.invalidate_cache(user)
|
|
|
|
assert {:ok, %Activity{} = activity} = Relay.unfollow(user_ap_id, %{force: true})
|
|
|
|
assert refresh_record(service_actor).following_count == 0
|
|
|
|
refute Pleroma.Repo.get_by(
|
|
Pleroma.FollowingRelationship,
|
|
follower_id: service_actor.id,
|
|
following_id: user_id
|
|
)
|
|
|
|
assert activity.actor == "#{Pleroma.Web.Endpoint.url()}/relay"
|
|
assert user.ap_id in activity.recipients
|
|
assert activity.data["type"] == "Undo"
|
|
assert activity.data["actor"] == service_actor.ap_id
|
|
assert activity.data["to"] == [user_ap_id]
|
|
refute "#{user.ap_id}/followers" in User.following(service_actor)
|
|
end
|
|
end
|
|
|
|
describe "publish/1" do
|
|
setup do: clear_config([:instance, :federating])
|
|
|
|
test "returns error when activity not `Create` type" do
|
|
activity = insert(:like_activity)
|
|
assert Relay.publish(activity) == {:error, "Not implemented"}
|
|
end
|
|
|
|
test "returns error when activity not public" do
|
|
activity = insert(:direct_note_activity)
|
|
assert Relay.publish(activity) == {:error, false}
|
|
end
|
|
|
|
test "returns error when object is unknown" do
|
|
activity =
|
|
insert(:note_activity,
|
|
data: %{
|
|
"type" => "Create",
|
|
"object" => "http://mastodon.example.org/eee/99541947525187367"
|
|
}
|
|
)
|
|
|
|
Tesla.Mock.mock(fn
|
|
%{method: :get, url: "http://mastodon.example.org/eee/99541947525187367"} ->
|
|
%Tesla.Env{status: 500, body: ""}
|
|
end)
|
|
|
|
assert capture_log(fn ->
|
|
assert Relay.publish(activity) == {:error, false}
|
|
end) =~ "[error] error: false"
|
|
end
|
|
|
|
test_with_mock "returns announce activity and publish to federate",
|
|
Pleroma.Web.Federator,
|
|
[:passthrough],
|
|
[] do
|
|
clear_config([:instance, :federating], true)
|
|
service_actor = Relay.get_actor()
|
|
note = insert(:note_activity)
|
|
assert {:ok, %Activity{} = activity} = Relay.publish(note)
|
|
assert activity.data["type"] == "Announce"
|
|
assert activity.data["actor"] == service_actor.ap_id
|
|
assert service_actor.follower_address in activity.data["to"]
|
|
assert called(Pleroma.Web.Federator.publish(activity))
|
|
end
|
|
|
|
test_with_mock "returns announce activity and not publish to federate",
|
|
Pleroma.Web.Federator,
|
|
[:passthrough],
|
|
[] do
|
|
clear_config([:instance, :federating], false)
|
|
service_actor = Relay.get_actor()
|
|
note = insert(:note_activity)
|
|
assert {:ok, %Activity{} = activity} = Relay.publish(note)
|
|
assert activity.data["type"] == "Announce"
|
|
assert activity.data["actor"] == service_actor.ap_id
|
|
refute called(Pleroma.Web.Federator.publish(activity))
|
|
end
|
|
end
|
|
end
|