[#534] Made federation push sender be determined basing on content instead of `referer` header. Updated tests.

This commit is contained in:
Ivan Tashkinov 2019-01-29 13:12:28 +03:00
parent d3f9e6f6fe
commit 92753b0cd9
15 changed files with 68 additions and 80 deletions

View File

@ -1,16 +0,0 @@
# Pleroma: A lightweight social networking server
# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/>
# SPDX-License-Identifier: AGPL-3.0-only
defmodule Pleroma.Web.Plugs.SetRequesterReachablePlug do
import Plug.Conn
def init(_), do: []
def call(%Plug.Conn{} = conn, _) do
with [referer] <- get_req_header(conn, "referer"),
do: Pleroma.Instances.set_reachable(referer)
conn
end
end

View File

@ -3,8 +3,7 @@
# SPDX-License-Identifier: AGPL-3.0-only # SPDX-License-Identifier: AGPL-3.0-only
defmodule Pleroma.ReverseProxy do defmodule Pleroma.ReverseProxy do
@keep_req_headers ~w(accept user-agent accept-encoding cache-control if-modified-since if-unmodified-since) ++ @keep_req_headers ~w(accept user-agent accept-encoding cache-control if-modified-since if-unmodified-since if-none-match if-range range)
~w(if-none-match if-range range referer)
@resp_cache_headers ~w(etag date last-modified cache-control) @resp_cache_headers ~w(etag date last-modified cache-control)
@keep_resp_headers @resp_cache_headers ++ @keep_resp_headers @resp_cache_headers ++
~w(content-type content-disposition content-encoding content-range accept-ranges vary) ~w(content-type content-disposition content-encoding content-range accept-ranges vary)

View File

@ -784,8 +784,7 @@ def publish_one(%{inbox: inbox, json: json, actor: actor, id: id}) do
[ [
{"Content-Type", "application/activity+json"}, {"Content-Type", "application/activity+json"},
{"signature", signature}, {"signature", signature},
{"digest", digest}, {"digest", digest}
{"referer", Pleroma.Web.Endpoint.url()}
] ]
) do ) do
Instances.set_reachable(inbox) Instances.set_reachable(inbox)

View File

@ -18,7 +18,7 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubController do
action_fallback(:errors) action_fallback(:errors)
plug(Pleroma.Web.FederatingPlug when action in [:inbox, :relay]) plug(Pleroma.Web.FederatingPlug when action in [:inbox, :relay])
plug(Pleroma.Web.Plugs.SetRequesterReachablePlug when action in [:inbox]) plug(:set_requester_reachable when action in [:inbox])
plug(:relay_active? when action in [:relay]) plug(:relay_active? when action in [:relay])
def relay_active?(conn, _) do def relay_active?(conn, _) do
@ -291,4 +291,13 @@ def errors(conn, _e) do
|> put_status(500) |> put_status(500)
|> json("error") |> json("error")
end end
defp set_requester_reachable(%Plug.Conn{} = conn, _) do
with actor <- conn.params["actor"],
true <- is_binary(actor) do
Pleroma.Instances.set_reachable(actor)
end
conn
end
end end

View File

@ -48,6 +48,9 @@ def remote_follow_path do
def handle_incoming(xml_string) do def handle_incoming(xml_string) do
with doc when doc != :error <- parse_document(xml_string) do with doc when doc != :error <- parse_document(xml_string) do
with {:ok, actor_user} <- find_make_or_update_user(doc),
do: Pleroma.Instances.set_reachable(actor_user.ap_id)
entries = :xmerl_xpath.string('//entry', doc) entries = :xmerl_xpath.string('//entry', doc)
activities = activities =

View File

@ -14,7 +14,6 @@ defmodule Pleroma.Web.OStatus.OStatusController do
alias Pleroma.Web.ActivityPub.ActivityPub alias Pleroma.Web.ActivityPub.ActivityPub
plug(Pleroma.Web.FederatingPlug when action in [:salmon_incoming]) plug(Pleroma.Web.FederatingPlug when action in [:salmon_incoming])
plug(Pleroma.Web.Plugs.SetRequesterReachablePlug when action in [:salmon_incoming])
action_fallback(:errors) action_fallback(:errors)

View File

@ -172,10 +172,7 @@ def send_to_user(url, feed, poster) when is_binary(url) do
poster.( poster.(
url, url,
feed, feed,
[ [{"Content-Type", "application/magic-envelope+xml"}]
{"Content-Type", "application/magic-envelope+xml"},
{"referer", Pleroma.Web.Endpoint.url()}
]
) do ) do
Instances.set_reachable(url) Instances.set_reachable(url)
Logger.debug(fn -> "Pushed to #{url}, code #{code}" end) Logger.debug(fn -> "Pushed to #{url}, code #{code}" end)

View File

@ -278,8 +278,7 @@ def publish_one(%{xml: xml, topic: topic, callback: callback, secret: secret}) d
xml, xml,
[ [
{"Content-Type", "application/atom+xml"}, {"Content-Type", "application/atom+xml"},
{"X-Hub-Signature", "sha1=#{signature}"}, {"X-Hub-Signature", "sha1=#{signature}"}
{"referer", Pleroma.Web.Endpoint.url()}
] ]
) do ) do
Instances.set_reachable(callback) Instances.set_reachable(callback)

View File

@ -20,8 +20,6 @@ defmodule Pleroma.Web.Websub.WebsubController do
] ]
) )
plug(Pleroma.Web.Plugs.SetRequesterReachablePlug when action in [:websub_incoming])
def websub_subscription_request(conn, %{"nickname" => nickname} = params) do def websub_subscription_request(conn, %{"nickname" => nickname} = params) do
user = User.get_cached_by_nickname(nickname) user = User.get_cached_by_nickname(nickname)

View File

@ -145,17 +145,16 @@ test "it inserts an incoming activity into the database", %{conn: conn} do
end end
test "it clears `unreachable` federation status of the sender", %{conn: conn} do test "it clears `unreachable` federation status of the sender", %{conn: conn} do
sender_url = "https://pleroma.soykaf.com" data = File.read!("test/fixtures/mastodon-post-activity.json") |> Poison.decode!()
sender_url = data["actor"]
Instances.set_consistently_unreachable(sender_url) Instances.set_consistently_unreachable(sender_url)
refute Instances.reachable?(sender_url) refute Instances.reachable?(sender_url)
data = File.read!("test/fixtures/mastodon-post-activity.json") |> Poison.decode!()
conn = conn =
conn conn
|> assign(:valid_signature, true) |> assign(:valid_signature, true)
|> put_req_header("content-type", "application/activity+json") |> put_req_header("content-type", "application/activity+json")
|> put_req_header("referer", sender_url)
|> post("/inbox", data) |> post("/inbox", data)
assert "ok" == json_response(conn, 200) assert "ok" == json_response(conn, 200)
@ -210,10 +209,6 @@ test "it returns a note activity in a collection", %{conn: conn} do
end end
test "it clears `unreachable` federation status of the sender", %{conn: conn} do test "it clears `unreachable` federation status of the sender", %{conn: conn} do
sender_host = "pleroma.soykaf.com"
Instances.set_consistently_unreachable(sender_host)
refute Instances.reachable?(sender_host)
user = insert(:user) user = insert(:user)
data = data =
@ -221,11 +216,14 @@ test "it clears `unreachable` federation status of the sender", %{conn: conn} do
|> Poison.decode!() |> Poison.decode!()
|> Map.put("bcc", [user.ap_id]) |> Map.put("bcc", [user.ap_id])
sender_host = URI.parse(data["actor"]).host
Instances.set_consistently_unreachable(sender_host)
refute Instances.reachable?(sender_host)
conn = conn =
conn conn
|> assign(:valid_signature, true) |> assign(:valid_signature, true)
|> put_req_header("content-type", "application/activity+json") |> put_req_header("content-type", "application/activity+json")
|> put_req_header("referer", "https://#{sender_host}")
|> post("/users/#{user.nickname}/inbox", data) |> post("/users/#{user.nickname}/inbox", data)
assert "ok" == json_response(conn, 200) assert "ok" == json_response(conn, 200)

View File

@ -39,6 +39,11 @@ test "returns `true` for host / url marked unreachable for less than `reachabili
assert Instances.reachable?(url) assert Instances.reachable?(url)
assert Instances.reachable?(URI.parse(url).host) assert Instances.reachable?(URI.parse(url).host)
end end
test "returns true on non-binary input" do
assert Instances.reachable?(nil)
assert Instances.reachable?(1)
end
end end
describe "filter_reachable/1" do describe "filter_reachable/1" do
@ -71,6 +76,19 @@ test "keeps reachable url or host reachable" do
Instances.set_reachable(url) Instances.set_reachable(url)
assert Instances.reachable?(url) assert Instances.reachable?(url)
end end
test "returns error status on non-binary input" do
assert {:error, _} = Instances.set_reachable(nil)
assert {:error, _} = Instances.set_reachable(1)
end
end
# Note: implementation-specific (e.g. Instance) details of set_unreachable/1 should be tested in implementation-specific tests
describe "set_unreachable/1" do
test "returns error status on non-binary input" do
assert {:error, _} = Instances.set_unreachable(nil)
assert {:error, _} = Instances.set_unreachable(1)
end
end end
describe "set_consistently_unreachable/1" do describe "set_consistently_unreachable/1" do

View File

@ -2,9 +2,16 @@ defmodule Pleroma.Web.OStatus.DeleteHandlingTest do
use Pleroma.DataCase use Pleroma.DataCase
import Pleroma.Factory import Pleroma.Factory
import Tesla.Mock
alias Pleroma.{Repo, Activity, Object} alias Pleroma.{Repo, Activity, Object}
alias Pleroma.Web.OStatus alias Pleroma.Web.OStatus
setup do
mock(fn env -> apply(HttpRequestMock, :request, [env]) end)
:ok
end
describe "deletions" do describe "deletions" do
test "it removes the mentioned activity" do test "it removes the mentioned activity" do
note = insert(:note_activity) note = insert(:note_activity)

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, Instances} alias Pleroma.{User, Repo, Object}
alias Pleroma.Web.CommonAPI alias Pleroma.Web.CommonAPI
alias Pleroma.Web.OStatus.ActivityRepresenter alias Pleroma.Web.OStatus.ActivityRepresenter
@ -59,24 +59,6 @@ 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_consistently_unreachable(sender_url)
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

View File

@ -6,7 +6,7 @@ defmodule Pleroma.Web.OStatusTest do
use Pleroma.DataCase use Pleroma.DataCase
alias Pleroma.Web.OStatus alias Pleroma.Web.OStatus
alias Pleroma.Web.XML alias Pleroma.Web.XML
alias Pleroma.{Object, Repo, User, Activity} alias Pleroma.{Object, Repo, User, Activity, Instances}
import Pleroma.Factory import Pleroma.Factory
import ExUnit.CaptureLog import ExUnit.CaptureLog
@ -311,6 +311,22 @@ test "handle incoming unfollows with existing follow" do
refute User.following?(follower, followed) refute User.following?(follower, followed)
end end
test "it clears `unreachable` federation status of the sender" do
incoming_reaction_xml = File.read!("test/fixtures/share-gs.xml")
doc = XML.parse_document(incoming_reaction_xml)
actor_uri = XML.string_from_xpath("//author/uri[1]", doc)
reacted_to_author_uri = XML.string_from_xpath("//author/uri[2]", doc)
Instances.set_consistently_unreachable(actor_uri)
Instances.set_consistently_unreachable(reacted_to_author_uri)
refute Instances.reachable?(actor_uri)
refute Instances.reachable?(reacted_to_author_uri)
{:ok, _} = OStatus.handle_incoming(incoming_reaction_xml)
assert Instances.reachable?(actor_uri)
refute Instances.reachable?(reacted_to_author_uri)
end
describe "new remote user creation" do describe "new remote user creation" do
test "returns local users" do test "returns local users" do
local_user = insert(:user) local_user = insert(:user)

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, Instances} alias Pleroma.{Repo, Activity}
alias Pleroma.Web.Websub alias Pleroma.Web.Websub
test "websub subscription request", %{conn: conn} do test "websub subscription request", %{conn: conn} do
@ -82,25 +82,5 @@ 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_consistently_unreachable(sender_url)
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