From 8654a591f08c7d8d5d61f075906f0c6907e877bb Mon Sep 17 00:00:00 2001 From: Ivan Tashkinov Date: Thu, 24 Jan 2019 17:37:23 +0300 Subject: [PATCH] [#534] Updating external instances reachability on incoming federation. --- lib/pleroma/instances/instance.ex | 14 +++++++++++--- lib/pleroma/reverse_proxy.ex | 3 ++- lib/pleroma/web/activity_pub/activity_pub.ex | 3 ++- .../web/activity_pub/activity_pub_controller.ex | 7 +++++++ lib/pleroma/web/controller_helper.ex | 5 +++++ lib/pleroma/web/ostatus/ostatus_controller.ex | 7 +++++++ lib/pleroma/web/salmon/salmon.ex | 5 ++++- lib/pleroma/web/websub/websub.ex | 3 ++- lib/pleroma/web/websub/websub_controller.ex | 9 +++++++++ 9 files changed, 49 insertions(+), 7 deletions(-) diff --git a/lib/pleroma/instances/instance.ex b/lib/pleroma/instances/instance.ex index 4507ef6d5..fe52331a3 100644 --- a/lib/pleroma/instances/instance.ex +++ b/lib/pleroma/instances/instance.ex @@ -24,7 +24,7 @@ def update_changeset(struct, params \\ %{}) do |> unique_constraint(:host) end - def reachable?(url) do + def reachable?(url) when is_binary(url) do !Repo.one( from(i in Instance, where: @@ -34,7 +34,9 @@ def reachable?(url) do ) end - def set_reachable(url) do + def reachable?(_), do: true + + def set_reachable(url) when is_binary(url) do Repo.update_all( from(i in Instance, where: i.host == ^host(url)), set: [ @@ -44,7 +46,11 @@ def set_reachable(url) do ) end - def set_unreachable(url, unreachable_since \\ nil) do + def set_reachable(_), do: {0, :noop} + + def set_unreachable(url, unreachable_since \\ nil) + + def set_unreachable(url, unreachable_since) when is_binary(url) do unreachable_since = unreachable_since || DateTime.utc_now() host = host(url) existing_record = Repo.get_by(Instance, %{host: host}) @@ -67,6 +73,8 @@ def set_unreachable(url, unreachable_since \\ nil) do end end + def set_unreachable(_, _), do: {0, :noop} + defp host(url_or_host) do if url_or_host =~ ~r/^http/i do URI.parse(url_or_host).host diff --git a/lib/pleroma/reverse_proxy.ex b/lib/pleroma/reverse_proxy.ex index a25b5ea4e..d8b17212b 100644 --- a/lib/pleroma/reverse_proxy.ex +++ b/lib/pleroma/reverse_proxy.ex @@ -3,7 +3,8 @@ # SPDX-License-Identifier: AGPL-3.0-only defmodule Pleroma.ReverseProxy do - @keep_req_headers ~w(accept user-agent accept-encoding cache-control if-modified-since if-unmodified-since if-none-match if-range range) + @keep_req_headers ~w(accept user-agent accept-encoding cache-control if-modified-since if-unmodified-since) ++ + ~w(if-none-match if-range range referer) @resp_cache_headers ~w(etag date last-modified cache-control) @keep_resp_headers @resp_cache_headers ++ ~w(content-type content-disposition content-encoding content-range accept-ranges vary) diff --git a/lib/pleroma/web/activity_pub/activity_pub.ex b/lib/pleroma/web/activity_pub/activity_pub.ex index 10155ff5a..44c295d65 100644 --- a/lib/pleroma/web/activity_pub/activity_pub.ex +++ b/lib/pleroma/web/activity_pub/activity_pub.ex @@ -750,7 +750,8 @@ defp do_publish_one(%{inbox: inbox, json: json, actor: actor, id: id}) do [ {"Content-Type", "application/activity+json"}, {"signature", signature}, - {"digest", digest} + {"digest", digest}, + {"referer", Pleroma.Web.Endpoint.url()} ] ) do Instances.set_reachable(inbox) diff --git a/lib/pleroma/web/activity_pub/activity_pub_controller.ex b/lib/pleroma/web/activity_pub/activity_pub_controller.ex index 7eed0a600..dc353dff0 100644 --- a/lib/pleroma/web/activity_pub/activity_pub_controller.ex +++ b/lib/pleroma/web/activity_pub/activity_pub_controller.ex @@ -4,6 +4,7 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubController do use Pleroma.Web, :controller + alias Pleroma.{Activity, User, Object} alias Pleroma.Web.ActivityPub.{ObjectView, UserView} alias Pleroma.Web.ActivityPub.ActivityPub @@ -18,6 +19,7 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubController do plug(Pleroma.Web.FederatingPlug when action in [:inbox, :relay]) plug(:relay_active? when action in [:relay]) + plug(:set_requester_reachable when action in [:inbox]) def relay_active?(conn, _) do if Keyword.get(Application.get_env(:pleroma, :instance), :allow_relay) do @@ -289,4 +291,9 @@ def errors(conn, _e) do |> put_status(500) |> json("error") end + + defp set_requester_reachable(conn, _) do + Pleroma.Web.ControllerHelper.set_requester_reachable(conn) + conn + end end diff --git a/lib/pleroma/web/controller_helper.ex b/lib/pleroma/web/controller_helper.ex index 14e3d19fd..13cf1877f 100644 --- a/lib/pleroma/web/controller_helper.ex +++ b/lib/pleroma/web/controller_helper.ex @@ -10,4 +10,9 @@ def json_response(conn, status, json) do |> put_status(status) |> json(json) end + + def set_requester_reachable(conn) do + with [referer] <- get_req_header(conn, "referer"), + do: Pleroma.Instances.set_reachable(referer) + end end diff --git a/lib/pleroma/web/ostatus/ostatus_controller.ex b/lib/pleroma/web/ostatus/ostatus_controller.ex index ce022bcc1..a89f16b94 100644 --- a/lib/pleroma/web/ostatus/ostatus_controller.ex +++ b/lib/pleroma/web/ostatus/ostatus_controller.ex @@ -15,6 +15,8 @@ defmodule Pleroma.Web.OStatus.OStatusController do alias Pleroma.Web.ActivityPub.ActivityPub plug(Pleroma.Web.FederatingPlug when action in [:salmon_incoming]) + plug(:set_requester_reachable when action in [:salmon_incoming]) + action_fallback(:errors) def feed_redirect(conn, %{"nickname" => nickname}) do @@ -201,4 +203,9 @@ def errors(conn, _) do |> put_status(500) |> text("Something went wrong") end + + defp set_requester_reachable(conn, _) do + Pleroma.Web.ControllerHelper.set_requester_reachable(conn) + conn + end end diff --git a/lib/pleroma/web/salmon/salmon.ex b/lib/pleroma/web/salmon/salmon.ex index 0423ccee0..e4d2d9517 100644 --- a/lib/pleroma/web/salmon/salmon.ex +++ b/lib/pleroma/web/salmon/salmon.ex @@ -173,7 +173,10 @@ defp send_to_user(url, feed, poster) when is_binary(url) do poster.( url, feed, - [{"Content-Type", "application/magic-envelope+xml"}] + [ + {"Content-Type", "application/magic-envelope+xml"}, + {"referer", Pleroma.Web.Endpoint.url()} + ] ) do Instances.set_reachable(url) Logger.debug(fn -> "Pushed to #{url}, code #{code}" end) diff --git a/lib/pleroma/web/websub/websub.ex b/lib/pleroma/web/websub/websub.ex index 9ceb5fbf7..ac8903913 100644 --- a/lib/pleroma/web/websub/websub.ex +++ b/lib/pleroma/web/websub/websub.ex @@ -275,7 +275,8 @@ def publish_one(%{xml: xml, topic: topic, callback: callback, secret: secret}) d xml, [ {"Content-Type", "application/atom+xml"}, - {"X-Hub-Signature", "sha1=#{signature}"} + {"X-Hub-Signature", "sha1=#{signature}"}, + {"referer", Pleroma.Web.Endpoint.url()} ] ) do Instances.set_reachable(callback) diff --git a/lib/pleroma/web/websub/websub_controller.ex b/lib/pleroma/web/websub/websub_controller.ex index e58f144e5..02fe075d7 100644 --- a/lib/pleroma/web/websub/websub_controller.ex +++ b/lib/pleroma/web/websub/websub_controller.ex @@ -4,9 +4,11 @@ defmodule Pleroma.Web.Websub.WebsubController do use Pleroma.Web, :controller + alias Pleroma.{Repo, User} alias Pleroma.Web.{Websub, Federator} alias Pleroma.Web.Websub.WebsubClientSubscription + require Logger plug( @@ -18,6 +20,8 @@ defmodule Pleroma.Web.Websub.WebsubController do ] ) + plug(:set_requester_reachable when action in [:websub_incoming]) + def websub_subscription_request(conn, %{"nickname" => nickname} = params) do user = User.get_cached_by_nickname(nickname) @@ -92,4 +96,9 @@ def websub_incoming(conn, %{"id" => id}) do |> send_resp(500, "Error") end end + + defp set_requester_reachable(conn, _) do + Pleroma.Web.ControllerHelper.set_requester_reachable(conn) + conn + end end