aboutsummaryrefslogtreecommitdiff
path: root/lib/pleroma/web/websub/websub.ex
diff options
context:
space:
mode:
authorrinpatch <rinpatch@sdf.org>2019-04-17 12:22:32 +0300
committerrinpatch <rinpatch@sdf.org>2019-04-17 12:22:32 +0300
commit627e5a0a4992cc19fc65a7e93a09c470c8e2bf33 (patch)
tree0f38b475e8554863a1cbbd7750c19d4cd1336eb1 /lib/pleroma/web/websub/websub.ex
parentd6ab701a14f7c9fb4d59953648c425e04725fc62 (diff)
parent73df3046e014ae16e03f16a9c82921652cefcb54 (diff)
downloadpleroma-627e5a0a4992cc19fc65a7e93a09c470c8e2bf33.tar.gz
Merge branch 'develop' into feature/database-compaction
Diffstat (limited to 'lib/pleroma/web/websub/websub.ex')
-rw-r--r--lib/pleroma/web/websub/websub.ex80
1 files changed, 51 insertions, 29 deletions
diff --git a/lib/pleroma/web/websub/websub.ex b/lib/pleroma/web/websub/websub.ex
index 905d8d658..3ffa6b416 100644
--- a/lib/pleroma/web/websub/websub.ex
+++ b/lib/pleroma/web/websub/websub.ex
@@ -1,10 +1,19 @@
+# Pleroma: A lightweight social networking server
+# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/>
+# SPDX-License-Identifier: AGPL-3.0-only
+
defmodule Pleroma.Web.Websub do
alias Ecto.Changeset
+ alias Pleroma.Instances
alias Pleroma.Repo
- alias Pleroma.Web.Websub.{WebsubServerSubscription, WebsubClientSubscription}
+ alias Pleroma.Web.Endpoint
+ alias Pleroma.Web.Federator
+ alias Pleroma.Web.OStatus
alias Pleroma.Web.OStatus.FeedRepresenter
- alias Pleroma.Web.{XML, Endpoint, OStatus}
alias Pleroma.Web.Router.Helpers
+ alias Pleroma.Web.Websub.WebsubClientSubscription
+ alias Pleroma.Web.Websub.WebsubServerSubscription
+ alias Pleroma.Web.XML
require Logger
import Ecto.Query
@@ -49,31 +58,37 @@ defmodule Pleroma.Web.Websub do
]
def publish(topic, user, %{data: %{"type" => type}} = activity)
when type in @supported_activities do
- # TODO: Only send to still valid subscriptions.
+ response =
+ user
+ |> FeedRepresenter.to_simple_form([activity], [user])
+ |> :xmerl.export_simple(:xmerl_xml)
+ |> to_string
+
query =
from(
sub in WebsubServerSubscription,
where: sub.topic == ^topic and sub.state == "active",
- where: fragment("? > NOW()", sub.valid_until)
+ where: fragment("? > (NOW() at time zone 'UTC')", sub.valid_until)
)
subscriptions = Repo.all(query)
- Enum.each(subscriptions, fn sub ->
- response =
- user
- |> FeedRepresenter.to_simple_form([activity], [user])
- |> :xmerl.export_simple(:xmerl_xml)
- |> to_string
+ callbacks = Enum.map(subscriptions, & &1.callback)
+ reachable_callbacks_metadata = Instances.filter_reachable(callbacks)
+ reachable_callbacks = Map.keys(reachable_callbacks_metadata)
+ subscriptions
+ |> Enum.filter(&(&1.callback in reachable_callbacks))
+ |> Enum.each(fn sub ->
data = %{
xml: response,
topic: topic,
callback: sub.callback,
- secret: sub.secret
+ secret: sub.secret,
+ unreachable_since: reachable_callbacks_metadata[sub.callback]
}
- Pleroma.Web.Federator.enqueue(:publish_single_websub, data)
+ Federator.publish_single_websub(data)
end)
end
@@ -105,7 +120,7 @@ defmodule Pleroma.Web.Websub do
websub = Repo.update!(change)
- Pleroma.Web.Federator.enqueue(:verify_websub, websub)
+ Federator.verify_websub(websub)
{:ok, websub}
else
@@ -117,6 +132,12 @@ defmodule Pleroma.Web.Websub do
end
end
+ def incoming_subscription_request(user, params) do
+ Logger.info("Unhandled WebSub request for #{user.nickname}: #{inspect(params)}")
+
+ {:error, "Invalid WebSub request"}
+ end
+
defp get_subscription(topic, callback) do
Repo.get_by(WebsubServerSubscription, topic: topic, callback: callback) ||
%WebsubServerSubscription{}
@@ -173,14 +194,14 @@ defmodule Pleroma.Web.Websub do
def gather_feed_data(topic, getter \\ &@httpoison.get/1) do
with {:ok, response} <- getter.(topic),
- status_code when status_code in 200..299 <- response.status_code,
+ status when status in 200..299 <- response.status,
body <- response.body,
doc <- XML.parse_document(body),
uri when not is_nil(uri) <- XML.string_from_xpath("/feed/author[1]/uri", doc),
hub when not is_nil(hub) <- XML.string_from_xpath(~S{/feed/link[@rel="hub"]/@href}, doc) do
name = XML.string_from_xpath("/feed/author[1]/name", doc)
- preferredUsername = XML.string_from_xpath("/feed/author[1]/poco:preferredUsername", doc)
- displayName = XML.string_from_xpath("/feed/author[1]/poco:displayName", doc)
+ preferred_username = XML.string_from_xpath("/feed/author[1]/poco:preferredUsername", doc)
+ display_name = XML.string_from_xpath("/feed/author[1]/poco:displayName", doc)
avatar = OStatus.make_avatar_object(doc)
bio = XML.string_from_xpath("/feed/author[1]/summary", doc)
@@ -188,8 +209,8 @@ defmodule Pleroma.Web.Websub do
%{
"uri" => uri,
"hub" => hub,
- "nickname" => preferredUsername || name,
- "name" => displayName || name,
+ "nickname" => preferred_username || name,
+ "name" => display_name || name,
"host" => URI.parse(uri).host,
"avatar" => avatar,
"bio" => bio
@@ -221,7 +242,7 @@ defmodule Pleroma.Web.Websub do
task = Task.async(websub_checker)
- with {:ok, %{status_code: 202}} <-
+ with {:ok, %{status: 202}} <-
poster.(websub.hub, {:form, data}, "Content-type": "application/x-www-form-urlencoded"),
{:ok, websub} <- Task.yield(task, timeout) do
{:ok, websub}
@@ -249,32 +270,33 @@ defmodule Pleroma.Web.Websub do
subs = Repo.all(query)
Enum.each(subs, fn sub ->
- Pleroma.Web.Federator.enqueue(:request_subscription, sub)
+ Federator.request_subscription(sub)
end)
end
- def publish_one(%{xml: xml, topic: topic, callback: callback, secret: secret}) do
+ def publish_one(%{xml: xml, topic: topic, callback: callback, secret: secret} = params) do
signature = sign(secret || "", xml)
Logger.info(fn -> "Pushing #{topic} to #{callback}" end)
- with {:ok, %{status_code: code}} <-
+ with {:ok, %{status: code}} when code in 200..299 <-
@httpoison.post(
callback,
xml,
[
{"Content-Type", "application/atom+xml"},
{"X-Hub-Signature", "sha1=#{signature}"}
- ],
- timeout: 10000,
- recv_timeout: 20000,
- hackney: [pool: :default]
+ ]
) do
+ if !Map.has_key?(params, :unreachable_since) || params[:unreachable_since],
+ do: Instances.set_reachable(callback)
+
Logger.info(fn -> "Pushed to #{callback}, code #{code}" end)
{:ok, code}
else
- e ->
- Logger.debug(fn -> "Couldn't push to #{callback}, #{inspect(e)}" end)
- {:error, e}
+ {_post_result, response} ->
+ unless params[:unreachable_since], do: Instances.set_reachable(callback)
+ Logger.debug(fn -> "Couldn't push to #{callback}, #{inspect(response)}" end)
+ {:error, response}
end
end
end