b0a46c1e2e
Due to JSON-LD compaction the full address of public scope may also occur in shorter forms and the spec requires us to treat them all equivalently. To save us the pain of repeatedly checking for all variants internally, normalise inbound data to just one form. See note at: https://www.w3.org/TR/activitypub/#public-addressing This needs to happen very early, even before the other addressing fixes else an earlier validator will reject the object. This in turn required to move the list-tpye normalisation earlier as well, but since I was unsure about putting empty lists into the data when no such field existed before, I excluded this case and thus the later fixing had to be kept as well. Fixes: https://akkoma.dev/AkkomaGang/akkoma/issues/670
207 lines
6.4 KiB
Elixir
207 lines
6.4 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.FederatorTest do
|
|
alias Pleroma.Instances
|
|
alias Pleroma.Tests.ObanHelpers
|
|
alias Pleroma.Web.CommonAPI
|
|
alias Pleroma.Web.Federator
|
|
alias Pleroma.Workers.PublisherWorker
|
|
|
|
use Pleroma.DataCase, async: false
|
|
@moduletag :mocked
|
|
use Oban.Testing, repo: Pleroma.Repo
|
|
|
|
import Pleroma.Factory
|
|
import Mock
|
|
|
|
setup_all do
|
|
Tesla.Mock.mock_global(fn env -> apply(HttpRequestMock, :request, [env]) end)
|
|
|
|
:ok
|
|
end
|
|
|
|
setup_all do: clear_config([:instance, :federating], true)
|
|
setup do: clear_config([:instance, :allow_relay], true)
|
|
setup do: clear_config([:mrf, :policies])
|
|
setup do: clear_config([:mrf_keyword])
|
|
|
|
describe "Publish an activity" do
|
|
setup do
|
|
user = insert(:user)
|
|
{:ok, activity} = CommonAPI.post(user, %{status: "HI"})
|
|
|
|
relay_mock = {
|
|
Pleroma.Web.ActivityPub.Relay,
|
|
[],
|
|
[publish: fn _activity -> send(self(), :relay_publish) end]
|
|
}
|
|
|
|
%{activity: activity, relay_mock: relay_mock}
|
|
end
|
|
|
|
test "with relays active, it publishes to the relay", %{
|
|
activity: activity,
|
|
relay_mock: relay_mock
|
|
} do
|
|
with_mocks([relay_mock]) do
|
|
Federator.publish(activity)
|
|
ObanHelpers.perform(all_enqueued(worker: PublisherWorker))
|
|
end
|
|
|
|
assert_receive :relay_publish
|
|
end
|
|
|
|
test "with relays deactivated, it does not publish to the relay", %{
|
|
activity: activity,
|
|
relay_mock: relay_mock
|
|
} do
|
|
clear_config([:instance, :allow_relay], false)
|
|
|
|
with_mocks([relay_mock]) do
|
|
Federator.publish(activity)
|
|
ObanHelpers.perform(all_enqueued(worker: PublisherWorker))
|
|
end
|
|
|
|
refute_received :relay_publish
|
|
end
|
|
end
|
|
|
|
describe "Targets reachability filtering in `publish`" do
|
|
test "it federates only to reachable instances via AP" do
|
|
user = insert(:user)
|
|
|
|
{inbox1, inbox2} =
|
|
{"https://domain.com/users/nick1/inbox", "https://domain2.com/users/nick2/inbox"}
|
|
|
|
insert(:user, %{
|
|
local: false,
|
|
nickname: "nick1@domain.com",
|
|
ap_id: "https://domain.com/users/nick1",
|
|
inbox: inbox1,
|
|
ap_enabled: true
|
|
})
|
|
|
|
insert(:user, %{
|
|
local: false,
|
|
nickname: "nick2@domain2.com",
|
|
ap_id: "https://domain2.com/users/nick2",
|
|
inbox: inbox2,
|
|
ap_enabled: true
|
|
})
|
|
|
|
dt = NaiveDateTime.utc_now()
|
|
Instances.set_unreachable(inbox1, dt)
|
|
|
|
Instances.set_consistently_unreachable(URI.parse(inbox2).host)
|
|
|
|
{:ok, _activity} =
|
|
CommonAPI.post(user, %{status: "HI @nick1@domain.com, @nick2@domain2.com!"})
|
|
|
|
expected_dt = NaiveDateTime.to_iso8601(dt)
|
|
|
|
ObanHelpers.perform(all_enqueued(worker: PublisherWorker))
|
|
|
|
assert ObanHelpers.member?(
|
|
%{
|
|
"op" => "publish_one",
|
|
"params" => %{"inbox" => inbox1, "unreachable_since" => expected_dt}
|
|
},
|
|
all_enqueued(worker: PublisherWorker)
|
|
)
|
|
end
|
|
end
|
|
|
|
describe "Receive an activity" do
|
|
test "successfully processes incoming AP docs with correct origin" do
|
|
params = %{
|
|
"@context" => "https://www.w3.org/ns/activitystreams",
|
|
"actor" => "http://mastodon.example.org/users/admin",
|
|
"type" => "Create",
|
|
"id" => "http://mastodon.example.org/users/admin/activities/1",
|
|
"object" => %{
|
|
"type" => "Note",
|
|
"content" => "hi world!",
|
|
"id" => "http://mastodon.example.org/users/admin/objects/1",
|
|
"attributedTo" => "http://mastodon.example.org/users/admin",
|
|
"to" => ["https://www.w3.org/ns/activitystreams#Public"]
|
|
},
|
|
"to" => ["https://www.w3.org/ns/activitystreams#Public"]
|
|
}
|
|
|
|
assert {:ok, job} = Federator.incoming_ap_doc(params)
|
|
assert {:ok, _activity} = ObanHelpers.perform(job)
|
|
|
|
assert {:ok, job} = Federator.incoming_ap_doc(params)
|
|
assert {:error, :already_present} = ObanHelpers.perform(job)
|
|
end
|
|
|
|
test "successfully normalises public scope descriptors" do
|
|
params = %{
|
|
"@context" => "https://www.w3.org/ns/activitystreams",
|
|
"actor" => "http://mastodon.example.org/users/admin",
|
|
"type" => "Create",
|
|
"id" => "http://mastodon.example.org/users/admin/activities/1",
|
|
"object" => %{
|
|
"type" => "Note",
|
|
"content" => "hi world!",
|
|
"id" => "http://mastodon.example.org/users/admin/objects/1",
|
|
"attributedTo" => "http://mastodon.example.org/users/admin",
|
|
"to" => ["Public"]
|
|
},
|
|
"to" => ["as:Public"]
|
|
}
|
|
|
|
assert {:ok, job} = Federator.incoming_ap_doc(params)
|
|
assert {:ok, activity} = ObanHelpers.perform(job)
|
|
assert activity.data["to"] == ["https://www.w3.org/ns/activitystreams#Public"]
|
|
|
|
object =
|
|
from(
|
|
object in Pleroma.Object,
|
|
where: fragment("(?)->>'id' = ?", object.data, ^activity.data["object"]),
|
|
limit: 1
|
|
)
|
|
|> Repo.one()
|
|
|
|
assert object.data["to"] == ["https://www.w3.org/ns/activitystreams#Public"]
|
|
end
|
|
|
|
test "rejects incoming AP docs with incorrect origin" do
|
|
params = %{
|
|
"@context" => "https://www.w3.org/ns/activitystreams",
|
|
"actor" => "https://niu.moe/users/rye",
|
|
"type" => "Create",
|
|
"id" => "http://mastodon.example.org/users/admin/activities/1",
|
|
"object" => %{
|
|
"type" => "Note",
|
|
"content" => "hi world!",
|
|
"id" => "http://mastodon.example.org/users/admin/objects/1",
|
|
"attributedTo" => "http://mastodon.example.org/users/admin",
|
|
"to" => ["https://www.w3.org/ns/activitystreams#Public"]
|
|
},
|
|
"to" => ["https://www.w3.org/ns/activitystreams#Public"]
|
|
}
|
|
|
|
assert {:ok, job} = Federator.incoming_ap_doc(params)
|
|
assert {:discard, :origin_containment_failed} = ObanHelpers.perform(job)
|
|
end
|
|
|
|
test "it does not crash if MRF rejects the post" do
|
|
clear_config([:mrf_keyword, :reject], ["lain"])
|
|
|
|
clear_config(
|
|
[:mrf, :policies],
|
|
Pleroma.Web.ActivityPub.MRF.KeywordPolicy
|
|
)
|
|
|
|
params =
|
|
File.read!("test/fixtures/mastodon-post-activity.json")
|
|
|> Jason.decode!()
|
|
|
|
assert {:ok, job} = Federator.incoming_ap_doc(params)
|
|
assert {:discard, _} = ObanHelpers.perform(job)
|
|
end
|
|
end
|
|
end
|