Add Websub verification.
authorRoger Braun <roger@rogerbraun.net>
Fri, 21 Apr 2017 01:59:11 +0000 (03:59 +0200)
committerRoger Braun <roger@rogerbraun.net>
Fri, 21 Apr 2017 01:59:11 +0000 (03:59 +0200)
lib/pleroma/web/websub/websub.ex [new file with mode: 0644]
mix.exs
mix.lock
test/support/factory.ex
test/web/websub/websub_test.exs [new file with mode: 0644]

diff --git a/lib/pleroma/web/websub/websub.ex b/lib/pleroma/web/websub/websub.ex
new file mode 100644 (file)
index 0000000..c775248
--- /dev/null
@@ -0,0 +1,23 @@
+defmodule Pleroma.Web.Websub do
+  alias Pleroma.Repo
+
+  def verify(subscription, getter \\ &HTTPoison.get/3 ) do
+    challenge = Base.encode16(:crypto.strong_rand_bytes(8))
+    lease_seconds = NaiveDateTime.diff(subscription.inserted_at, subscription.valid_until)
+    with {:ok, response} <- getter.(subscription.callback, [], [params: %{
+                                                              "hub.challenge": challenge,
+                                                              "hub.lease_seconds": lease_seconds,
+                                                              "hub.topic": subscription.topic,
+                                                              "hub.mode": "subscribe"
+                                                                }]),
+         ^challenge <- response.body
+    do
+      changeset = Ecto.Changeset.change(subscription, %{state: "active"})
+      Repo.update(changeset)
+    else _e ->
+      changeset = Ecto.Changeset.change(subscription, %{state: "rejected"})
+      {:ok, subscription } = Repo.update(changeset)
+      {:error, subscription}
+    end
+  end
+end
diff --git a/mix.exs b/mix.exs
index f6831550bf13f30a41e344a14f20bbbdd694b045..0e54f0246adf30d45551f3d466ffa0720eeb885b 100644 (file)
--- a/mix.exs
+++ b/mix.exs
@@ -39,6 +39,7 @@ defmodule Pleroma.Mixfile do
      {:html_sanitize_ex, "~> 1.0.0"},
      {:calendar, "~> 0.16.1"},
      {:cachex, "~> 2.1"},
+     {:httpoison, "~> 0.11.1"},
      {:ex_machina, "~> 2.0", only: :test},
      {:mix_test_watch, "~> 0.2", only: :dev}]
   end
index a44ffa8d02c13c2935008c5f1640f0adefe2efbf..225a62f7a612b643b3684385ed072cf3f873a9b7 100644 (file)
--- a/mix.lock
+++ b/mix.lock
@@ -18,6 +18,7 @@
   "gettext": {:hex, :gettext, "0.13.1", "5e0daf4e7636d771c4c71ad5f3f53ba09a9ae5c250e1ab9c42ba9edccc476263", [:mix], []},
   "hackney": {:hex, :hackney, "1.7.1", "e238c52c5df3c3b16ce613d3a51c7220a784d734879b1e231c9babd433ac1cb4", [:rebar3], [{:certifi, "1.0.0", [hex: :certifi, optional: false]}, {:idna, "4.0.0", [hex: :idna, optional: false]}, {:metrics, "1.0.1", [hex: :metrics, optional: false]}, {:mimerl, "1.0.2", [hex: :mimerl, optional: false]}, {:ssl_verify_fun, "1.1.1", [hex: :ssl_verify_fun, optional: false]}]},
   "html_sanitize_ex": {:hex, :html_sanitize_ex, "1.0.1", "2572e7122c78ab7e57b613e7c7f5e42bf9b3c25e430e32f23f1413d86db8a0af", [:mix], [{:mochiweb, "~> 2.12.2", [hex: :mochiweb, optional: false]}]},
+  "httpoison": {:hex, :httpoison, "0.11.1", "d06c571274c0e77b6cc50e548db3fd7779f611fbed6681fd60a331f66c143a0b", [:mix], [{:hackney, "~> 1.7.0", [hex: :hackney, optional: false]}]},
   "idna": {:hex, :idna, "4.0.0", "10aaa9f79d0b12cf0def53038547855b91144f1bfcc0ec73494f38bb7b9c4961", [:rebar3], []},
   "metrics": {:hex, :metrics, "1.0.1", "25f094dea2cda98213cecc3aeff09e940299d950904393b2a29d191c346a8486", [:rebar3], []},
   "mime": {:hex, :mime, "1.1.0", "01c1d6f4083d8aa5c7b8c246ade95139620ef8effb009edde934e0ec3b28090a", [:mix], []},
index 3fc9cf710e5b8b117329b229ff38f3fc89e8bb09..401fdfda3d725320b2c5ac16ec7bc4f781380c0f 100644 (file)
@@ -64,4 +64,14 @@ defmodule Pleroma.Factory do
       data: data
     }
   end
+
+  def websub_subscription_factory do
+    %Pleroma.Web.Websub.WebsubServerSubscription{
+      topic: "http://example.org",
+      callback: "http://example/org/callback",
+      secret: "here's a secret",
+      valid_until: NaiveDateTime.add(NaiveDateTime.utc_now, 100),
+      state: "requested"
+    }
+  end
 end
diff --git a/test/web/websub/websub_test.exs b/test/web/websub/websub_test.exs
new file mode 100644 (file)
index 0000000..93a44fe
--- /dev/null
@@ -0,0 +1,44 @@
+defmodule Pleroma.Web.WebsubTest do
+  use Pleroma.DataCase
+  alias Pleroma.Web.Websub
+  import Pleroma.Factory
+
+  test "a verification of a request that is accepted" do
+    sub = insert(:websub_subscription)
+    topic = sub.topic
+
+    getter = fn (_path, _headers, options) ->
+      %{
+        "hub.challenge": challenge,
+        "hub.lease_seconds": seconds,
+        "hub.topic": ^topic,
+        "hub.mode": "subscribe"
+      } = Keyword.get(options, :params)
+
+      assert is_number(seconds)
+
+      {:ok, %HTTPoison.Response{
+        status_code: 200,
+        body: challenge
+      }}
+    end
+
+    {:ok, sub} = Websub.verify(sub, getter)
+    assert sub.state == "active"
+  end
+
+  test "a verification of a request that doesn't return 200" do
+    sub = insert(:websub_subscription)
+    topic = sub.topic
+
+    getter = fn (_path, _headers, _options) ->
+      {:ok, %HTTPoison.Response{
+        status_code: 500,
+        body: ""
+      }}
+    end
+
+    {:error, sub} = Websub.verify(sub, getter)
+    assert sub.state == "rejected"
+  end
+end