logo

pleroma

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

websub_controller.ex (2748B)


      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.Websub.WebsubController do
      6   use Pleroma.Web, :controller
      7 
      8   alias Pleroma.Repo
      9   alias Pleroma.User
     10   alias Pleroma.Web.Federator
     11   alias Pleroma.Web.Websub
     12   alias Pleroma.Web.Websub.WebsubClientSubscription
     13 
     14   require Logger
     15 
     16   plug(
     17     Pleroma.Web.FederatingPlug
     18     when action in [
     19            :websub_subscription_request,
     20            :websub_subscription_confirmation,
     21            :websub_incoming
     22          ]
     23   )
     24 
     25   def websub_subscription_request(conn, %{"nickname" => nickname} = params) do
     26     user = User.get_cached_by_nickname(nickname)
     27 
     28     with {:ok, _websub} <- Websub.incoming_subscription_request(user, params) do
     29       conn
     30       |> send_resp(202, "Accepted")
     31     else
     32       {:error, reason} ->
     33         conn
     34         |> send_resp(500, reason)
     35     end
     36   end
     37 
     38   # TODO: Extract this into the Websub module
     39   def websub_subscription_confirmation(
     40         conn,
     41         %{
     42           "id" => id,
     43           "hub.mode" => "subscribe",
     44           "hub.challenge" => challenge,
     45           "hub.topic" => topic
     46         } = params
     47       ) do
     48     Logger.debug("Got WebSub confirmation")
     49     Logger.debug(inspect(params))
     50 
     51     lease_seconds =
     52       if params["hub.lease_seconds"] do
     53         String.to_integer(params["hub.lease_seconds"])
     54       else
     55         # Guess 3 days
     56         60 * 60 * 24 * 3
     57       end
     58 
     59     with %WebsubClientSubscription{} = websub <-
     60            Repo.get_by(WebsubClientSubscription, id: id, topic: topic) do
     61       valid_until = NaiveDateTime.add(NaiveDateTime.utc_now(), lease_seconds)
     62       change = Ecto.Changeset.change(websub, %{state: "accepted", valid_until: valid_until})
     63       {:ok, _websub} = Repo.update(change)
     64 
     65       conn
     66       |> send_resp(200, challenge)
     67     else
     68       _e ->
     69         conn
     70         |> send_resp(500, "Error")
     71     end
     72   end
     73 
     74   def websub_subscription_confirmation(conn, params) do
     75     Logger.info("Invalid WebSub confirmation request: #{inspect(params)}")
     76 
     77     conn
     78     |> send_resp(500, "Invalid parameters")
     79   end
     80 
     81   def websub_incoming(conn, %{"id" => id}) do
     82     with "sha1=" <> signature <- hd(get_req_header(conn, "x-hub-signature")),
     83          signature <- String.downcase(signature),
     84          %WebsubClientSubscription{} = websub <- Repo.get(WebsubClientSubscription, id),
     85          {:ok, body, _conn} = read_body(conn),
     86          ^signature <- Websub.sign(websub.secret, body) do
     87       Federator.incoming_doc(body)
     88 
     89       conn
     90       |> send_resp(200, "OK")
     91     else
     92       _e ->
     93         Logger.debug("Can't handle incoming subscription post")
     94 
     95         conn
     96         |> send_resp(500, "Error")
     97     end
     98   end
     99 end