@@ -193,7 +193,7 @@ defmodule Pleroma.Factory do | |||
def websub_subscription_factory do | |||
%Pleroma.Web.Websub.WebsubServerSubscription{ | |||
topic: "http://example.org", | |||
callback: "http://example/org/callback", | |||
callback: "http://example.org/callback", | |||
secret: "here's a secret", | |||
valid_until: NaiveDateTime.add(NaiveDateTime.utc_now(), 100), | |||
state: "requested" | |||
@@ -6,8 +6,7 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubControllerTest do | |||
use Pleroma.Web.ConnCase | |||
import Pleroma.Factory | |||
alias Pleroma.Web.ActivityPub.{UserView, ObjectView} | |||
alias Pleroma.{Object, Repo, User} | |||
alias Pleroma.Activity | |||
alias Pleroma.{Object, Repo, Activity, User, Instances} | |||
setup_all do | |||
Tesla.Mock.mock_global(fn env -> apply(HttpRequestMock, :request, [env]) end) | |||
@@ -144,6 +143,24 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubControllerTest do | |||
:timer.sleep(500) | |||
assert Activity.get_by_ap_id(data["id"]) | |||
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 | |||
describe "/users/:nickname/inbox" do | |||
@@ -191,6 +208,29 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubControllerTest do | |||
assert response(conn, 200) =~ note_activity.data["object"]["content"] | |||
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 | |||
describe "/users/:nickname/outbox" do | |||
@@ -3,8 +3,8 @@ | |||
# SPDX-License-Identifier: AGPL-3.0-only | |||
defmodule Pleroma.Web.FederatorTest do | |||
alias Pleroma.Web.Federator | |||
alias Pleroma.Web.CommonAPI | |||
alias Pleroma.Web.{CommonAPI, Federator} | |||
alias Pleroma.Instances | |||
use Pleroma.DataCase | |||
import Pleroma.Factory | |||
import Mock | |||
@@ -71,6 +71,103 @@ defmodule Pleroma.Web.FederatorTest do | |||
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 | |||
test "successfully processes incoming AP docs with correct origin" do | |||
params = %{ | |||
@@ -5,7 +5,7 @@ | |||
defmodule Pleroma.Web.OStatus.OStatusControllerTest do | |||
use Pleroma.Web.ConnCase | |||
import Pleroma.Factory | |||
alias Pleroma.{User, Repo, Object} | |||
alias Pleroma.{User, Repo, Object, Instances} | |||
alias Pleroma.Web.CommonAPI | |||
alias Pleroma.Web.OStatus.ActivityRepresenter | |||
@@ -14,49 +14,69 @@ defmodule Pleroma.Web.OStatus.OStatusControllerTest do | |||
:ok | |||
end | |||
test "decodes a salmon", %{conn: conn} do | |||
user = insert(:user) | |||
salmon = File.read!("test/fixtures/salmon.xml") | |||
conn = | |||
conn | |||
|> put_req_header("content-type", "application/atom+xml") | |||
|> post("/users/#{user.nickname}/salmon", salmon) | |||
assert response(conn, 200) | |||
end | |||
test "decodes a salmon with a changed magic key", %{conn: conn} do | |||
user = insert(:user) | |||
salmon = File.read!("test/fixtures/salmon.xml") | |||
conn = | |||
conn | |||
|> put_req_header("content-type", "application/atom+xml") | |||
|> post("/users/#{user.nickname}/salmon", salmon) | |||
assert response(conn, 200) | |||
# 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") | |||
# Wrong key | |||
info_cng = | |||
User.Info.remote_user_creation(salmon_user.info, %{ | |||
magic_key: | |||
"RSA.pu0s-halox4tu7wmES1FVSx6u-4wc0YrUFXcqWXZG4-27UmbCOpMQftRCldNRfyA-qLbz-eqiwrong1EwUvjsD4cYbAHNGHwTvDOyx5AKthQUP44ykPv7kjKGh3DWKySJvcs9tlUG87hlo7AvnMo9pwRS_Zz2CacQ-MKaXyDepk=.AQAB" | |||
}) | |||
salmon_user | |||
|> Ecto.Changeset.change() | |||
|> Ecto.Changeset.put_embed(:info, info_cng) | |||
|> Repo.update() | |||
conn = | |||
build_conn() | |||
|> put_req_header("content-type", "application/atom+xml") | |||
|> post("/users/#{user.nickname}/salmon", salmon) | |||
assert response(conn, 200) | |||
describe "salmon_incoming" do | |||
test "decodes a salmon", %{conn: conn} do | |||
user = insert(:user) | |||
salmon = File.read!("test/fixtures/salmon.xml") | |||
conn = | |||
conn | |||
|> put_req_header("content-type", "application/atom+xml") | |||
|> post("/users/#{user.nickname}/salmon", salmon) | |||
assert response(conn, 200) | |||
end | |||
test "decodes a salmon with a changed magic key", %{conn: conn} do | |||
user = insert(:user) | |||
salmon = File.read!("test/fixtures/salmon.xml") | |||
conn = | |||
conn | |||
|> put_req_header("content-type", "application/atom+xml") | |||
|> post("/users/#{user.nickname}/salmon", salmon) | |||
assert response(conn, 200) | |||
# 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") | |||
# Wrong key | |||
info_cng = | |||
User.Info.remote_user_creation(salmon_user.info, %{ | |||
magic_key: | |||
"RSA.pu0s-halox4tu7wmES1FVSx6u-4wc0YrUFXcqWXZG4-27UmbCOpMQftRCldNRfyA-qLbz-eqiwrong1EwUvjsD4cYbAHNGHwTvDOyx5AKthQUP44ykPv7kjKGh3DWKySJvcs9tlUG87hlo7AvnMo9pwRS_Zz2CacQ-MKaXyDepk=.AQAB" | |||
}) | |||
salmon_user | |||
|> Ecto.Changeset.change() | |||
|> Ecto.Changeset.put_embed(:info, info_cng) | |||
|> Repo.update() | |||
conn = | |||
build_conn() | |||
|> put_req_header("content-type", "application/atom+xml") | |||
|> post("/users/#{user.nickname}/salmon", salmon) | |||
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 | |||
test "gets a feed", %{conn: conn} do | |||
@@ -6,7 +6,7 @@ defmodule Pleroma.Web.Websub.WebsubControllerTest do | |||
use Pleroma.Web.ConnCase | |||
import Pleroma.Factory | |||
alias Pleroma.Web.Websub.WebsubClientSubscription | |||
alias Pleroma.{Repo, Activity} | |||
alias Pleroma.{Repo, Activity, Instances} | |||
alias Pleroma.Web.Websub | |||
test "websub subscription request", %{conn: conn} do | |||
@@ -50,35 +50,57 @@ defmodule Pleroma.Web.Websub.WebsubControllerTest do | |||
assert_in_delta NaiveDateTime.diff(websub.valid_until, NaiveDateTime.utc_now()), 100, 5 | |||
end | |||
test "handles incoming feed updates", %{conn: conn} do | |||
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") | |||
|> post("/push/subscriptions/#{websub.id}", doc) | |||
assert response(conn, 200) == "OK" | |||
assert length(Repo.all(Activity)) == 1 | |||
end | |||
test "rejects incoming feed updates with the wrong signature", %{conn: conn} do | |||
websub = insert(:websub_client_subscription) | |||
doc = "some stuff" | |||
signature = Websub.sign("wrong secret", doc) | |||
conn = | |||
conn | |||
|> put_req_header("x-hub-signature", "sha1=" <> signature) | |||
|> put_req_header("content-type", "application/atom+xml") | |||
|> post("/push/subscriptions/#{websub.id}", doc) | |||
assert response(conn, 500) == "Error" | |||
assert length(Repo.all(Activity)) == 0 | |||
describe "websub_incoming" do | |||
test "handles incoming feed updates", %{conn: conn} do | |||
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") | |||
|> post("/push/subscriptions/#{websub.id}", doc) | |||
assert response(conn, 200) == "OK" | |||
assert length(Repo.all(Activity)) == 1 | |||
end | |||
test "rejects incoming feed updates with the wrong signature", %{conn: conn} do | |||
websub = insert(:websub_client_subscription) | |||
doc = "some stuff" | |||
signature = Websub.sign("wrong secret", doc) | |||
conn = | |||
conn | |||
|> put_req_header("x-hub-signature", "sha1=" <> signature) | |||
|> put_req_header("content-type", "application/atom+xml") | |||
|> post("/push/subscriptions/#{websub.id}", doc) | |||
assert response(conn, 500) == "Error" | |||
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 |