logo

pleroma

My custom branche(s) on git.pleroma.social/pleroma/pleroma

websub_test.exs (7263B)


      1 # Pleroma: A lightweight social networking server
      2 # Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/>
      3 # SPDX-License-Identifier: AGPL-3.0-only
      4 
      5 defmodule Pleroma.Web.WebsubTest do
      6   use Pleroma.DataCase
      7   use Oban.Testing, repo: Pleroma.Repo
      8 
      9   alias Pleroma.Tests.ObanHelpers
     10   alias Pleroma.Web.Router.Helpers
     11   alias Pleroma.Web.Websub
     12   alias Pleroma.Web.Websub.WebsubClientSubscription
     13   alias Pleroma.Web.Websub.WebsubServerSubscription
     14   alias Pleroma.Workers.SubscriberWorker
     15 
     16   import Pleroma.Factory
     17   import Tesla.Mock
     18 
     19   setup do
     20     mock(fn env -> apply(HttpRequestMock, :request, [env]) end)
     21     :ok
     22   end
     23 
     24   test "a verification of a request that is accepted" do
     25     sub = insert(:websub_subscription)
     26     topic = sub.topic
     27 
     28     getter = fn _path, _headers, options ->
     29       %{
     30         "hub.challenge": challenge,
     31         "hub.lease_seconds": seconds,
     32         "hub.topic": ^topic,
     33         "hub.mode": "subscribe"
     34       } = Keyword.get(options, :params)
     35 
     36       assert String.to_integer(seconds) > 0
     37 
     38       {:ok,
     39        %Tesla.Env{
     40          status: 200,
     41          body: challenge
     42        }}
     43     end
     44 
     45     {:ok, sub} = Websub.verify(sub, getter)
     46     assert sub.state == "active"
     47   end
     48 
     49   test "a verification of a request that doesn't return 200" do
     50     sub = insert(:websub_subscription)
     51 
     52     getter = fn _path, _headers, _options ->
     53       {:ok,
     54        %Tesla.Env{
     55          status: 500,
     56          body: ""
     57        }}
     58     end
     59 
     60     {:error, sub} = Websub.verify(sub, getter)
     61     # Keep the current state.
     62     assert sub.state == "requested"
     63   end
     64 
     65   test "an incoming subscription request" do
     66     user = insert(:user)
     67 
     68     data = %{
     69       "hub.callback" => "http://example.org/sub",
     70       "hub.mode" => "subscribe",
     71       "hub.topic" => Pleroma.Web.OStatus.feed_path(user),
     72       "hub.secret" => "a random secret",
     73       "hub.lease_seconds" => "100"
     74     }
     75 
     76     {:ok, subscription} = Websub.incoming_subscription_request(user, data)
     77     assert subscription.topic == Pleroma.Web.OStatus.feed_path(user)
     78     assert subscription.state == "requested"
     79     assert subscription.secret == "a random secret"
     80     assert subscription.callback == "http://example.org/sub"
     81   end
     82 
     83   test "an incoming subscription request for an existing subscription" do
     84     user = insert(:user)
     85 
     86     sub =
     87       insert(:websub_subscription, state: "accepted", topic: Pleroma.Web.OStatus.feed_path(user))
     88 
     89     data = %{
     90       "hub.callback" => sub.callback,
     91       "hub.mode" => "subscribe",
     92       "hub.topic" => Pleroma.Web.OStatus.feed_path(user),
     93       "hub.secret" => "a random secret",
     94       "hub.lease_seconds" => "100"
     95     }
     96 
     97     {:ok, subscription} = Websub.incoming_subscription_request(user, data)
     98     assert subscription.topic == Pleroma.Web.OStatus.feed_path(user)
     99     assert subscription.state == sub.state
    100     assert subscription.secret == "a random secret"
    101     assert subscription.callback == sub.callback
    102     assert length(Repo.all(WebsubServerSubscription)) == 1
    103     assert subscription.id == sub.id
    104   end
    105 
    106   def accepting_verifier(subscription) do
    107     {:ok, %{subscription | state: "accepted"}}
    108   end
    109 
    110   test "initiate a subscription for a given user and topic" do
    111     subscriber = insert(:user)
    112     user = insert(:user, %{info: %Pleroma.User.Info{topic: "some_topic", hub: "some_hub"}})
    113 
    114     {:ok, websub} = Websub.subscribe(subscriber, user, &accepting_verifier/1)
    115     assert websub.subscribers == [subscriber.ap_id]
    116     assert websub.topic == "some_topic"
    117     assert websub.hub == "some_hub"
    118     assert is_binary(websub.secret)
    119     assert websub.user == user
    120     assert websub.state == "accepted"
    121   end
    122 
    123   test "discovers the hub and canonical url" do
    124     topic = "https://mastodon.social/users/lambadalambda.atom"
    125 
    126     {:ok, discovered} = Websub.gather_feed_data(topic)
    127 
    128     expected = %{
    129       "hub" => "https://mastodon.social/api/push",
    130       "uri" => "https://mastodon.social/users/lambadalambda",
    131       "nickname" => "lambadalambda",
    132       "name" => "Critical Value",
    133       "host" => "mastodon.social",
    134       "bio" => "a cool dude.",
    135       "avatar" => %{
    136         "type" => "Image",
    137         "url" => [
    138           %{
    139             "href" =>
    140               "https://files.mastodon.social/accounts/avatars/000/000/264/original/1429214160519.gif?1492379244",
    141             "mediaType" => "image/gif",
    142             "type" => "Link"
    143           }
    144         ]
    145       }
    146     }
    147 
    148     assert expected == discovered
    149   end
    150 
    151   test "calls the hub, requests topic" do
    152     hub = "https://social.heldscal.la/main/push/hub"
    153     topic = "https://social.heldscal.la/api/statuses/user_timeline/23211.atom"
    154     websub = insert(:websub_client_subscription, %{hub: hub, topic: topic})
    155 
    156     poster = fn ^hub, {:form, data}, _headers ->
    157       assert Keyword.get(data, :"hub.mode") == "subscribe"
    158 
    159       assert Keyword.get(data, :"hub.callback") ==
    160                Helpers.websub_url(
    161                  Pleroma.Web.Endpoint,
    162                  :websub_subscription_confirmation,
    163                  websub.id
    164                )
    165 
    166       {:ok, %{status: 202}}
    167     end
    168 
    169     task = Task.async(fn -> Websub.request_subscription(websub, poster) end)
    170 
    171     change = Ecto.Changeset.change(websub, %{state: "accepted"})
    172     {:ok, _} = Repo.update(change)
    173 
    174     {:ok, websub} = Task.await(task)
    175 
    176     assert websub.state == "accepted"
    177   end
    178 
    179   test "rejects the subscription if it can't be accepted" do
    180     hub = "https://social.heldscal.la/main/push/hub"
    181     topic = "https://social.heldscal.la/api/statuses/user_timeline/23211.atom"
    182     websub = insert(:websub_client_subscription, %{hub: hub, topic: topic})
    183 
    184     poster = fn ^hub, {:form, _data}, _headers ->
    185       {:ok, %{status: 202}}
    186     end
    187 
    188     {:error, websub} = Websub.request_subscription(websub, poster, 1000)
    189     assert websub.state == "rejected"
    190 
    191     websub = insert(:websub_client_subscription, %{hub: hub, topic: topic})
    192 
    193     poster = fn ^hub, {:form, _data}, _headers ->
    194       {:ok, %{status: 400}}
    195     end
    196 
    197     {:error, websub} = Websub.request_subscription(websub, poster, 1000)
    198     assert websub.state == "rejected"
    199   end
    200 
    201   test "sign a text" do
    202     signed = Websub.sign("secret", "text")
    203     assert signed == "B8392C23690CCF871F37EC270BE1582DEC57A503" |> String.downcase()
    204 
    205     _signed = Websub.sign("secret", [["て"], ['す']])
    206   end
    207 
    208   describe "renewing subscriptions" do
    209     test "it renews subscriptions that have less than a day of time left" do
    210       day = 60 * 60 * 24
    211       now = NaiveDateTime.utc_now()
    212 
    213       still_good =
    214         insert(:websub_client_subscription, %{
    215           valid_until: NaiveDateTime.add(now, 2 * day),
    216           topic: "http://example.org/still_good",
    217           hub: "http://example.org/still_good",
    218           state: "accepted"
    219         })
    220 
    221       needs_refresh =
    222         insert(:websub_client_subscription, %{
    223           valid_until: NaiveDateTime.add(now, day - 100),
    224           topic: "http://example.org/needs_refresh",
    225           hub: "http://example.org/needs_refresh",
    226           state: "accepted"
    227         })
    228 
    229       _refresh = Websub.refresh_subscriptions()
    230       ObanHelpers.perform(all_enqueued(worker: SubscriberWorker))
    231 
    232       assert still_good == Repo.get(WebsubClientSubscription, still_good.id)
    233       refute needs_refresh == Repo.get(WebsubClientSubscription, needs_refresh.id)
    234     end
    235   end
    236 end