[#534] Federation reachability filtering tests.

This commit is contained in:
Ivan Tashkinov 2019-01-25 20:38:54 +03:00
parent 060d280e64
commit d99650270b
5 changed files with 243 additions and 64 deletions

View File

@ -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"

View File

@ -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

View File

@ -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 = %{

View File

@ -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,6 +14,7 @@ defmodule Pleroma.Web.OStatus.OStatusControllerTest do
:ok :ok
end end
describe "salmon_incoming" do
test "decodes a salmon", %{conn: conn} do test "decodes a salmon", %{conn: conn} do
user = insert(:user) user = insert(:user)
salmon = File.read!("test/fixtures/salmon.xml") salmon = File.read!("test/fixtures/salmon.xml")
@ -59,6 +60,25 @@ test "decodes a salmon with a changed magic key", %{conn: conn} do
assert response(conn, 200) assert response(conn, 200)
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)
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
test "gets a feed", %{conn: conn} do test "gets a feed", %{conn: conn} do
note_activity = insert(:note_activity) note_activity = insert(:note_activity)
user = User.get_cached_by_ap_id(note_activity.data["actor"]) user = User.get_cached_by_ap_id(note_activity.data["actor"])

View File

@ -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,6 +50,7 @@ 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
describe "websub_incoming" do
test "handles incoming feed updates", %{conn: conn} do test "handles incoming feed updates", %{conn: conn} do
websub = insert(:websub_client_subscription) websub = insert(:websub_client_subscription)
doc = "some stuff" doc = "some stuff"
@ -81,4 +82,25 @@ test "rejects incoming feed updates with the wrong signature", %{conn: conn} do
assert length(Repo.all(Activity)) == 0 assert length(Repo.all(Activity)) == 0
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)
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