From 1b9cc721a0d49d786b4864c2b8aceaf49b9ff088 Mon Sep 17 00:00:00 2001 From: Roger Braun Date: Thu, 20 Apr 2017 17:47:33 +0200 Subject: [PATCH] Websub controller beginnings. --- lib/pleroma/web/ostatus/feed_representer.ex | 2 +- lib/pleroma/web/ostatus/ostatus.ex | 4 +- lib/pleroma/web/router.ex | 2 +- lib/pleroma/web/websub/websub_controller.ex | 48 +++++++++++++++++++ .../web/websub/websub_server_subscription.ex | 2 + test/web/ostatus/feed_representer_test.exs | 2 +- test/web/websub/websub_controller_test.exs | 30 ++++++++++++ 7 files changed, 85 insertions(+), 5 deletions(-) create mode 100644 lib/pleroma/web/websub/websub_controller.ex create mode 100644 test/web/websub/websub_controller_test.exs diff --git a/lib/pleroma/web/ostatus/feed_representer.ex b/lib/pleroma/web/ostatus/feed_representer.ex index def684405..1576b4710 100644 --- a/lib/pleroma/web/ostatus/feed_representer.ex +++ b/lib/pleroma/web/ostatus/feed_representer.ex @@ -20,7 +20,7 @@ def to_simple_form(user, activities, users) do {:id, h.(OStatus.feed_path(user))}, {:title, ['#{user.nickname}\'s timeline']}, {:updated, h.(most_recent_update)}, - {:link, [rel: 'hub', href: h.(OStatus.pubsub_path)], []}, + {:link, [rel: 'hub', href: h.(OStatus.pubsub_path(user))], []}, {:author, UserRepresenter.to_simple_form(user)} ] ++ entries }] diff --git a/lib/pleroma/web/ostatus/ostatus.ex b/lib/pleroma/web/ostatus/ostatus.ex index 9fcbe6cb0..d21b9078f 100644 --- a/lib/pleroma/web/ostatus/ostatus.ex +++ b/lib/pleroma/web/ostatus/ostatus.ex @@ -5,8 +5,8 @@ def feed_path(user) do "#{user.ap_id}/feed.atom" end - def pubsub_path() do - "#{Web.base_url}/push/hub" + def pubsub_path(user) do + "#{Web.base_url}/push/hub/#{user.nickname}" end def user_path(user) do diff --git a/lib/pleroma/web/router.ex b/lib/pleroma/web/router.ex index 0264d8d3f..33e395218 100644 --- a/lib/pleroma/web/router.ex +++ b/lib/pleroma/web/router.ex @@ -62,7 +62,7 @@ def user_fetcher(username) do pipe_through :ostatus get "/users/:nickname/feed", OStatus.OStatusController, :feed - post "/push/hub", OStatus.OStatusController, :temp + post "/push/hub/:nickname", Websub.WebsubController, :websub_subscription_request end scope "/.well-known", Pleroma.Web do diff --git a/lib/pleroma/web/websub/websub_controller.ex b/lib/pleroma/web/websub/websub_controller.ex new file mode 100644 index 000000000..09305c337 --- /dev/null +++ b/lib/pleroma/web/websub/websub_controller.ex @@ -0,0 +1,48 @@ +defmodule Pleroma.Web.Websub.WebsubController do + use Pleroma.Web, :controller + alias Pleroma.Web.Websub.WebsubServerSubscription + alias Pleroma.{Repo, User} + alias Pleroma.Web.OStatus + def websub_subscription_request(conn, %{"nickname" => nickname} = params) do + user = User.get_cached_by_nickname(nickname) + + with {:ok, topic} <- valid_topic(params, user), + {:ok, lease_time} <- lease_time(params), + secret <- params["hub.secret"] + do + data = %{ + state: "requested", + topic: topic, + secret: secret + } + + change = Ecto.Changeset.change(%WebsubServerSubscription{}, data) + websub = Repo.insert!(change) + + change = Ecto.Changeset.change(websub, %{valid_until: NaiveDateTime.add(websub.inserted_at, lease_time)}) + websub = Repo.update!(change) + + conn + |> send_resp(202, "Accepted") + else {:error, reason} -> + conn + |> send_resp(500, reason) + end + end + + defp lease_time(%{"hub.lease_seconds" => lease_seconds}) do + {:ok, lease_seconds} + end + + defp lease_time(_) do + {:ok, 60 * 60 * 24 * 3} # three days + end + + defp valid_topic(%{"hub.topic" => topic}, user) do + if topic == OStatus.feed_path(user) do + {:ok, topic} + else + {:error, "Wrong topic requested, expected #{OStatus.feed_path(user)}, got #{topic}"} + end + end +end diff --git a/lib/pleroma/web/websub/websub_server_subscription.ex b/lib/pleroma/web/websub/websub_server_subscription.ex index 2562239ad..a29dd5860 100644 --- a/lib/pleroma/web/websub/websub_server_subscription.ex +++ b/lib/pleroma/web/websub/websub_server_subscription.ex @@ -7,5 +7,7 @@ defmodule Pleroma.Web.Websub.WebsubServerSubscription do field :secret, :string field :valid_until, :naive_datetime field :state, :string + + timestamps() end end diff --git a/test/web/ostatus/feed_representer_test.exs b/test/web/ostatus/feed_representer_test.exs index dddc63ebf..3d8eaac6e 100644 --- a/test/web/ostatus/feed_representer_test.exs +++ b/test/web/ostatus/feed_representer_test.exs @@ -26,7 +26,7 @@ test "returns a feed of the last 20 items of the user" do #{OStatus.feed_path(user)} #{user.nickname}'s timeline #{most_recent_update} - + #{user_xml} diff --git a/test/web/websub/websub_controller_test.exs b/test/web/websub/websub_controller_test.exs new file mode 100644 index 000000000..4eff598d6 --- /dev/null +++ b/test/web/websub/websub_controller_test.exs @@ -0,0 +1,30 @@ +defmodule Pleroma.Web.Websub.WebsubControllerTest do + use Pleroma.Web.ConnCase + import Pleroma.Factory + alias Pleroma.Repo + alias Pleroma.Web.Websub.WebsubServerSubscription + + test "websub subscription request", %{conn: conn} do + user = insert(:user) + + path = Pleroma.Web.OStatus.pubsub_path(user) + + data = %{ + "hub.callback": "http://example.org/sub", + "hub.mode": "subscription", + "hub.topic": Pleroma.Web.OStatus.feed_path(user), + "hub.secret": "a random secret", + "hub.lease_seconds": 100 + } + + conn = conn + |> post(path, data) + + assert response(conn, 202) == "Accepted" + subscription = Repo.one!(WebsubServerSubscription) + assert subscription.topic == Pleroma.Web.OStatus.feed_path(user) + assert subscription.state == "requested" + assert subscription.secret == "a random secret" + assert subscription.valid_until == NaiveDateTime.add(subscription.inserted_at, 100) + end +end