forked from AkkomaGang/akkoma
[#534] Federation reachability filtering tests.
This commit is contained in:
parent
060d280e64
commit
d99650270b
5 changed files with 243 additions and 64 deletions
|
@ -193,7 +193,7 @@ def follow_activity_factory do
|
||||||
def websub_subscription_factory do
|
def websub_subscription_factory do
|
||||||
%Pleroma.Web.Websub.WebsubServerSubscription{
|
%Pleroma.Web.Websub.WebsubServerSubscription{
|
||||||
topic: "http://example.org",
|
topic: "http://example.org",
|
||||||
callback: "http://example/org/callback",
|
callback: "http://example.org/callback",
|
||||||
secret: "here's a secret",
|
secret: "here's a secret",
|
||||||
valid_until: NaiveDateTime.add(NaiveDateTime.utc_now(), 100),
|
valid_until: NaiveDateTime.add(NaiveDateTime.utc_now(), 100),
|
||||||
state: "requested"
|
state: "requested"
|
||||||
|
|
|
@ -6,8 +6,7 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubControllerTest do
|
||||||
use Pleroma.Web.ConnCase
|
use Pleroma.Web.ConnCase
|
||||||
import Pleroma.Factory
|
import Pleroma.Factory
|
||||||
alias Pleroma.Web.ActivityPub.{UserView, ObjectView}
|
alias Pleroma.Web.ActivityPub.{UserView, ObjectView}
|
||||||
alias Pleroma.{Object, Repo, User}
|
alias Pleroma.{Object, Repo, Activity, User, Instances}
|
||||||
alias Pleroma.Activity
|
|
||||||
|
|
||||||
setup_all do
|
setup_all do
|
||||||
Tesla.Mock.mock_global(fn env -> apply(HttpRequestMock, :request, [env]) end)
|
Tesla.Mock.mock_global(fn env -> apply(HttpRequestMock, :request, [env]) end)
|
||||||
|
@ -144,6 +143,24 @@ test "it inserts an incoming activity into the database", %{conn: conn} do
|
||||||
:timer.sleep(500)
|
:timer.sleep(500)
|
||||||
assert Activity.get_by_ap_id(data["id"])
|
assert Activity.get_by_ap_id(data["id"])
|
||||||
end
|
end
|
||||||
|
|
||||||
|
test "it clears `unreachable` federation status of the sender", %{conn: conn} do
|
||||||
|
sender_url = "https://pleroma.soykaf.com"
|
||||||
|
Instances.set_unreachable(sender_url, Instances.reachability_datetime_threshold())
|
||||||
|
refute Instances.reachable?(sender_url)
|
||||||
|
|
||||||
|
data = File.read!("test/fixtures/mastodon-post-activity.json") |> Poison.decode!()
|
||||||
|
|
||||||
|
conn =
|
||||||
|
conn
|
||||||
|
|> assign(:valid_signature, true)
|
||||||
|
|> put_req_header("content-type", "application/activity+json")
|
||||||
|
|> put_req_header("referer", sender_url)
|
||||||
|
|> post("/inbox", data)
|
||||||
|
|
||||||
|
assert "ok" == json_response(conn, 200)
|
||||||
|
assert Instances.reachable?(sender_url)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
describe "/users/:nickname/inbox" do
|
describe "/users/:nickname/inbox" do
|
||||||
|
@ -191,6 +208,29 @@ test "it returns a note activity in a collection", %{conn: conn} do
|
||||||
|
|
||||||
assert response(conn, 200) =~ note_activity.data["object"]["content"]
|
assert response(conn, 200) =~ note_activity.data["object"]["content"]
|
||||||
end
|
end
|
||||||
|
|
||||||
|
test "it clears `unreachable` federation status of the sender", %{conn: conn} do
|
||||||
|
sender_host = "pleroma.soykaf.com"
|
||||||
|
Instances.set_unreachable(sender_host, Instances.reachability_datetime_threshold())
|
||||||
|
refute Instances.reachable?(sender_host)
|
||||||
|
|
||||||
|
user = insert(:user)
|
||||||
|
|
||||||
|
data =
|
||||||
|
File.read!("test/fixtures/mastodon-post-activity.json")
|
||||||
|
|> Poison.decode!()
|
||||||
|
|> Map.put("bcc", [user.ap_id])
|
||||||
|
|
||||||
|
conn =
|
||||||
|
conn
|
||||||
|
|> assign(:valid_signature, true)
|
||||||
|
|> put_req_header("content-type", "application/activity+json")
|
||||||
|
|> put_req_header("referer", "https://#{sender_host}")
|
||||||
|
|> post("/users/#{user.nickname}/inbox", data)
|
||||||
|
|
||||||
|
assert "ok" == json_response(conn, 200)
|
||||||
|
assert Instances.reachable?(sender_host)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
describe "/users/:nickname/outbox" do
|
describe "/users/:nickname/outbox" do
|
||||||
|
|
|
@ -3,8 +3,8 @@
|
||||||
# SPDX-License-Identifier: AGPL-3.0-only
|
# SPDX-License-Identifier: AGPL-3.0-only
|
||||||
|
|
||||||
defmodule Pleroma.Web.FederatorTest do
|
defmodule Pleroma.Web.FederatorTest do
|
||||||
alias Pleroma.Web.Federator
|
alias Pleroma.Web.{CommonAPI, Federator}
|
||||||
alias Pleroma.Web.CommonAPI
|
alias Pleroma.Instances
|
||||||
use Pleroma.DataCase
|
use Pleroma.DataCase
|
||||||
import Pleroma.Factory
|
import Pleroma.Factory
|
||||||
import Mock
|
import Mock
|
||||||
|
@ -71,6 +71,103 @@ test "with relays deactivated, it does not publish to the relay", %{
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
describe "Targets reachability filtering in `publish`" do
|
||||||
|
test_with_mock "it federates only to reachable instances via AP",
|
||||||
|
Federator,
|
||||||
|
[:passthrough],
|
||||||
|
[] 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",
|
||||||
|
info: %{ap_enabled: true, source_data: %{"inbox" => inbox1}}
|
||||||
|
})
|
||||||
|
|
||||||
|
insert(:user, %{
|
||||||
|
local: false,
|
||||||
|
nickname: "nick2@domain2.com",
|
||||||
|
ap_id: "https://domain2.com/users/nick2",
|
||||||
|
info: %{ap_enabled: true, source_data: %{"inbox" => inbox2}}
|
||||||
|
})
|
||||||
|
|
||||||
|
Instances.set_unreachable(
|
||||||
|
URI.parse(inbox2).host,
|
||||||
|
Instances.reachability_datetime_threshold()
|
||||||
|
)
|
||||||
|
|
||||||
|
{:ok, _activity} =
|
||||||
|
CommonAPI.post(user, %{"status" => "HI @nick1@domain.com, @nick2@domain2.com!"})
|
||||||
|
|
||||||
|
assert called(Federator.enqueue(:publish_single_ap, %{inbox: inbox1}))
|
||||||
|
refute called(Federator.enqueue(:publish_single_ap, %{inbox: inbox2}))
|
||||||
|
end
|
||||||
|
|
||||||
|
test_with_mock "it federates only to reachable instances via Websub",
|
||||||
|
Federator,
|
||||||
|
[:passthrough],
|
||||||
|
[] do
|
||||||
|
user = insert(:user)
|
||||||
|
websub_topic = Pleroma.Web.OStatus.feed_path(user)
|
||||||
|
|
||||||
|
sub1 =
|
||||||
|
insert(:websub_subscription, %{
|
||||||
|
topic: websub_topic,
|
||||||
|
state: "active",
|
||||||
|
callback: "http://pleroma.soykaf.com/cb"
|
||||||
|
})
|
||||||
|
|
||||||
|
sub2 =
|
||||||
|
insert(:websub_subscription, %{
|
||||||
|
topic: websub_topic,
|
||||||
|
state: "active",
|
||||||
|
callback: "https://pleroma2.soykaf.com/cb"
|
||||||
|
})
|
||||||
|
|
||||||
|
Instances.set_unreachable(sub1.callback, Instances.reachability_datetime_threshold())
|
||||||
|
|
||||||
|
{:ok, _activity} = CommonAPI.post(user, %{"status" => "HI"})
|
||||||
|
|
||||||
|
assert called(Federator.enqueue(:publish_single_websub, %{callback: sub2.callback}))
|
||||||
|
refute called(Federator.enqueue(:publish_single_websub, %{callback: sub1.callback}))
|
||||||
|
end
|
||||||
|
|
||||||
|
test_with_mock "it federates only to reachable instances via Salmon",
|
||||||
|
Federator,
|
||||||
|
[:passthrough],
|
||||||
|
[] do
|
||||||
|
user = insert(:user)
|
||||||
|
|
||||||
|
remote_user1 =
|
||||||
|
insert(:user, %{
|
||||||
|
local: false,
|
||||||
|
nickname: "nick1@domain.com",
|
||||||
|
ap_id: "https://domain.com/users/nick1",
|
||||||
|
info: %{salmon: "https://domain.com/salmon"}
|
||||||
|
})
|
||||||
|
|
||||||
|
remote_user2 =
|
||||||
|
insert(:user, %{
|
||||||
|
local: false,
|
||||||
|
nickname: "nick2@domain2.com",
|
||||||
|
ap_id: "https://domain2.com/users/nick2",
|
||||||
|
info: %{salmon: "https://domain2.com/salmon"}
|
||||||
|
})
|
||||||
|
|
||||||
|
Instances.set_unreachable("domain.com", Instances.reachability_datetime_threshold())
|
||||||
|
|
||||||
|
{:ok, _activity} =
|
||||||
|
CommonAPI.post(user, %{"status" => "HI @nick1@domain.com, @nick2@domain2.com!"})
|
||||||
|
|
||||||
|
assert called(Federator.enqueue(:publish_single_salmon, {remote_user2, :_, :_}))
|
||||||
|
refute called(Federator.enqueue(:publish_single_websub, {remote_user1, :_, :_}))
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
describe "Receive an activity" do
|
describe "Receive an activity" do
|
||||||
test "successfully processes incoming AP docs with correct origin" do
|
test "successfully processes incoming AP docs with correct origin" do
|
||||||
params = %{
|
params = %{
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
defmodule Pleroma.Web.OStatus.OStatusControllerTest do
|
defmodule Pleroma.Web.OStatus.OStatusControllerTest do
|
||||||
use Pleroma.Web.ConnCase
|
use Pleroma.Web.ConnCase
|
||||||
import Pleroma.Factory
|
import Pleroma.Factory
|
||||||
alias Pleroma.{User, Repo, Object}
|
alias Pleroma.{User, Repo, Object, Instances}
|
||||||
alias Pleroma.Web.CommonAPI
|
alias Pleroma.Web.CommonAPI
|
||||||
alias Pleroma.Web.OStatus.ActivityRepresenter
|
alias Pleroma.Web.OStatus.ActivityRepresenter
|
||||||
|
|
||||||
|
@ -14,49 +14,69 @@ defmodule Pleroma.Web.OStatus.OStatusControllerTest do
|
||||||
:ok
|
:ok
|
||||||
end
|
end
|
||||||
|
|
||||||
test "decodes a salmon", %{conn: conn} do
|
describe "salmon_incoming" do
|
||||||
user = insert(:user)
|
test "decodes a salmon", %{conn: conn} do
|
||||||
salmon = File.read!("test/fixtures/salmon.xml")
|
user = insert(:user)
|
||||||
|
salmon = File.read!("test/fixtures/salmon.xml")
|
||||||
|
|
||||||
conn =
|
conn =
|
||||||
conn
|
conn
|
||||||
|> put_req_header("content-type", "application/atom+xml")
|
|> put_req_header("content-type", "application/atom+xml")
|
||||||
|> post("/users/#{user.nickname}/salmon", salmon)
|
|> post("/users/#{user.nickname}/salmon", salmon)
|
||||||
|
|
||||||
assert response(conn, 200)
|
assert response(conn, 200)
|
||||||
end
|
end
|
||||||
|
|
||||||
test "decodes a salmon with a changed magic key", %{conn: conn} do
|
test "decodes a salmon with a changed magic key", %{conn: conn} do
|
||||||
user = insert(:user)
|
user = insert(:user)
|
||||||
salmon = File.read!("test/fixtures/salmon.xml")
|
salmon = File.read!("test/fixtures/salmon.xml")
|
||||||
|
|
||||||
conn =
|
conn =
|
||||||
conn
|
conn
|
||||||
|> put_req_header("content-type", "application/atom+xml")
|
|> put_req_header("content-type", "application/atom+xml")
|
||||||
|> post("/users/#{user.nickname}/salmon", salmon)
|
|> post("/users/#{user.nickname}/salmon", salmon)
|
||||||
|
|
||||||
assert response(conn, 200)
|
assert response(conn, 200)
|
||||||
|
|
||||||
# Set a wrong magic-key for a user so it has to refetch
|
# Set a wrong magic-key for a user so it has to refetch
|
||||||
salmon_user = User.get_by_ap_id("http://gs.example.org:4040/index.php/user/1")
|
salmon_user = User.get_by_ap_id("http://gs.example.org:4040/index.php/user/1")
|
||||||
# Wrong key
|
# Wrong key
|
||||||
info_cng =
|
info_cng =
|
||||||
User.Info.remote_user_creation(salmon_user.info, %{
|
User.Info.remote_user_creation(salmon_user.info, %{
|
||||||
magic_key:
|
magic_key:
|
||||||
"RSA.pu0s-halox4tu7wmES1FVSx6u-4wc0YrUFXcqWXZG4-27UmbCOpMQftRCldNRfyA-qLbz-eqiwrong1EwUvjsD4cYbAHNGHwTvDOyx5AKthQUP44ykPv7kjKGh3DWKySJvcs9tlUG87hlo7AvnMo9pwRS_Zz2CacQ-MKaXyDepk=.AQAB"
|
"RSA.pu0s-halox4tu7wmES1FVSx6u-4wc0YrUFXcqWXZG4-27UmbCOpMQftRCldNRfyA-qLbz-eqiwrong1EwUvjsD4cYbAHNGHwTvDOyx5AKthQUP44ykPv7kjKGh3DWKySJvcs9tlUG87hlo7AvnMo9pwRS_Zz2CacQ-MKaXyDepk=.AQAB"
|
||||||
})
|
})
|
||||||
|
|
||||||
salmon_user
|
salmon_user
|
||||||
|> Ecto.Changeset.change()
|
|> Ecto.Changeset.change()
|
||||||
|> Ecto.Changeset.put_embed(:info, info_cng)
|
|> Ecto.Changeset.put_embed(:info, info_cng)
|
||||||
|> Repo.update()
|
|> Repo.update()
|
||||||
|
|
||||||
conn =
|
conn =
|
||||||
build_conn()
|
build_conn()
|
||||||
|> put_req_header("content-type", "application/atom+xml")
|
|> put_req_header("content-type", "application/atom+xml")
|
||||||
|> post("/users/#{user.nickname}/salmon", salmon)
|
|> post("/users/#{user.nickname}/salmon", salmon)
|
||||||
|
|
||||||
assert response(conn, 200)
|
assert response(conn, 200)
|
||||||
|
end
|
||||||
|
|
||||||
|
test "it clears `unreachable` federation status of the sender", %{conn: conn} do
|
||||||
|
sender_url = "https://pleroma.soykaf.com"
|
||||||
|
Instances.set_unreachable(sender_url, Instances.reachability_datetime_threshold())
|
||||||
|
refute Instances.reachable?(sender_url)
|
||||||
|
|
||||||
|
user = insert(:user)
|
||||||
|
salmon = File.read!("test/fixtures/salmon.xml")
|
||||||
|
|
||||||
|
conn =
|
||||||
|
conn
|
||||||
|
|> put_req_header("content-type", "application/atom+xml")
|
||||||
|
|> put_req_header("referer", sender_url)
|
||||||
|
|> post("/users/#{user.nickname}/salmon", salmon)
|
||||||
|
|
||||||
|
assert response(conn, 200)
|
||||||
|
assert Instances.reachable?(sender_url)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
test "gets a feed", %{conn: conn} do
|
test "gets a feed", %{conn: conn} do
|
||||||
|
|
|
@ -6,7 +6,7 @@ defmodule Pleroma.Web.Websub.WebsubControllerTest do
|
||||||
use Pleroma.Web.ConnCase
|
use Pleroma.Web.ConnCase
|
||||||
import Pleroma.Factory
|
import Pleroma.Factory
|
||||||
alias Pleroma.Web.Websub.WebsubClientSubscription
|
alias Pleroma.Web.Websub.WebsubClientSubscription
|
||||||
alias Pleroma.{Repo, Activity}
|
alias Pleroma.{Repo, Activity, Instances}
|
||||||
alias Pleroma.Web.Websub
|
alias Pleroma.Web.Websub
|
||||||
|
|
||||||
test "websub subscription request", %{conn: conn} do
|
test "websub subscription request", %{conn: conn} do
|
||||||
|
@ -50,35 +50,57 @@ test "websub subscription confirmation", %{conn: conn} do
|
||||||
assert_in_delta NaiveDateTime.diff(websub.valid_until, NaiveDateTime.utc_now()), 100, 5
|
assert_in_delta NaiveDateTime.diff(websub.valid_until, NaiveDateTime.utc_now()), 100, 5
|
||||||
end
|
end
|
||||||
|
|
||||||
test "handles incoming feed updates", %{conn: conn} do
|
describe "websub_incoming" do
|
||||||
websub = insert(:websub_client_subscription)
|
test "handles incoming feed updates", %{conn: conn} do
|
||||||
doc = "some stuff"
|
websub = insert(:websub_client_subscription)
|
||||||
signature = Websub.sign(websub.secret, doc)
|
doc = "some stuff"
|
||||||
|
signature = Websub.sign(websub.secret, doc)
|
||||||
|
|
||||||
conn =
|
conn =
|
||||||
conn
|
conn
|
||||||
|> put_req_header("x-hub-signature", "sha1=" <> signature)
|
|> put_req_header("x-hub-signature", "sha1=" <> signature)
|
||||||
|> put_req_header("content-type", "application/atom+xml")
|
|> put_req_header("content-type", "application/atom+xml")
|
||||||
|> post("/push/subscriptions/#{websub.id}", doc)
|
|> post("/push/subscriptions/#{websub.id}", doc)
|
||||||
|
|
||||||
assert response(conn, 200) == "OK"
|
assert response(conn, 200) == "OK"
|
||||||
|
|
||||||
assert length(Repo.all(Activity)) == 1
|
assert length(Repo.all(Activity)) == 1
|
||||||
end
|
end
|
||||||
|
|
||||||
test "rejects incoming feed updates with the wrong signature", %{conn: conn} do
|
test "rejects incoming feed updates with the wrong signature", %{conn: conn} do
|
||||||
websub = insert(:websub_client_subscription)
|
websub = insert(:websub_client_subscription)
|
||||||
doc = "some stuff"
|
doc = "some stuff"
|
||||||
signature = Websub.sign("wrong secret", doc)
|
signature = Websub.sign("wrong secret", doc)
|
||||||
|
|
||||||
conn =
|
conn =
|
||||||
conn
|
conn
|
||||||
|> put_req_header("x-hub-signature", "sha1=" <> signature)
|
|> put_req_header("x-hub-signature", "sha1=" <> signature)
|
||||||
|> put_req_header("content-type", "application/atom+xml")
|
|> put_req_header("content-type", "application/atom+xml")
|
||||||
|> post("/push/subscriptions/#{websub.id}", doc)
|
|> post("/push/subscriptions/#{websub.id}", doc)
|
||||||
|
|
||||||
assert response(conn, 500) == "Error"
|
assert response(conn, 500) == "Error"
|
||||||
|
|
||||||
assert length(Repo.all(Activity)) == 0
|
assert length(Repo.all(Activity)) == 0
|
||||||
|
end
|
||||||
|
|
||||||
|
test "it clears `unreachable` federation status of the sender", %{conn: conn} do
|
||||||
|
sender_url = "https://pleroma.soykaf.com"
|
||||||
|
Instances.set_unreachable(sender_url, Instances.reachability_datetime_threshold())
|
||||||
|
refute Instances.reachable?(sender_url)
|
||||||
|
|
||||||
|
websub = insert(:websub_client_subscription)
|
||||||
|
doc = "some stuff"
|
||||||
|
signature = Websub.sign(websub.secret, doc)
|
||||||
|
|
||||||
|
conn =
|
||||||
|
conn
|
||||||
|
|> put_req_header("x-hub-signature", "sha1=" <> signature)
|
||||||
|
|> put_req_header("content-type", "application/atom+xml")
|
||||||
|
|> put_req_header("referer", sender_url)
|
||||||
|
|> post("/push/subscriptions/#{websub.id}", doc)
|
||||||
|
|
||||||
|
assert response(conn, 200) == "OK"
|
||||||
|
assert Instances.reachable?(sender_url)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
Loading…
Reference in a new issue