Add Websub verification.
This commit is contained in:
parent
1b9cc721a0
commit
424e0e7779
23
lib/pleroma/web/websub/websub.ex
Normal file
23
lib/pleroma/web/websub/websub.ex
Normal file
|
@ -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
|
1
mix.exs
1
mix.exs
|
@ -39,6 +39,7 @@ defp deps do
|
||||||
{:html_sanitize_ex, "~> 1.0.0"},
|
{:html_sanitize_ex, "~> 1.0.0"},
|
||||||
{:calendar, "~> 0.16.1"},
|
{:calendar, "~> 0.16.1"},
|
||||||
{:cachex, "~> 2.1"},
|
{:cachex, "~> 2.1"},
|
||||||
|
{:httpoison, "~> 0.11.1"},
|
||||||
{:ex_machina, "~> 2.0", only: :test},
|
{:ex_machina, "~> 2.0", only: :test},
|
||||||
{:mix_test_watch, "~> 0.2", only: :dev}]
|
{:mix_test_watch, "~> 0.2", only: :dev}]
|
||||||
end
|
end
|
||||||
|
|
1
mix.lock
1
mix.lock
|
@ -18,6 +18,7 @@
|
||||||
"gettext": {:hex, :gettext, "0.13.1", "5e0daf4e7636d771c4c71ad5f3f53ba09a9ae5c250e1ab9c42ba9edccc476263", [:mix], []},
|
"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]}]},
|
"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]}]},
|
"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], []},
|
"idna": {:hex, :idna, "4.0.0", "10aaa9f79d0b12cf0def53038547855b91144f1bfcc0ec73494f38bb7b9c4961", [:rebar3], []},
|
||||||
"metrics": {:hex, :metrics, "1.0.1", "25f094dea2cda98213cecc3aeff09e940299d950904393b2a29d191c346a8486", [:rebar3], []},
|
"metrics": {:hex, :metrics, "1.0.1", "25f094dea2cda98213cecc3aeff09e940299d950904393b2a29d191c346a8486", [:rebar3], []},
|
||||||
"mime": {:hex, :mime, "1.1.0", "01c1d6f4083d8aa5c7b8c246ade95139620ef8effb009edde934e0ec3b28090a", [:mix], []},
|
"mime": {:hex, :mime, "1.1.0", "01c1d6f4083d8aa5c7b8c246ade95139620ef8effb009edde934e0ec3b28090a", [:mix], []},
|
||||||
|
|
|
@ -64,4 +64,14 @@ def like_activity_factory do
|
||||||
data: data
|
data: data
|
||||||
}
|
}
|
||||||
end
|
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
|
end
|
||||||
|
|
44
test/web/websub/websub_test.exs
Normal file
44
test/web/websub/websub_test.exs
Normal file
|
@ -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
|
Loading…
Reference in a new issue