diff options
Diffstat (limited to 'lib')
| -rw-r--r-- | lib/pleroma/user.ex | 2 | ||||
| -rw-r--r-- | lib/pleroma/web/activity_pub/activity_pub_controller.ex | 7 | ||||
| -rw-r--r-- | lib/pleroma/web/federator.ex | 11 | ||||
| -rw-r--r-- | lib/pleroma/web/router.ex | 2 | ||||
| -rw-r--r-- | lib/pleroma/web/twitter_api/controllers/remote_follow_controller.ex | 7 | ||||
| -rw-r--r-- | lib/pleroma/workers/receiver_worker.ex | 38 | 
6 files changed, 59 insertions, 8 deletions
| diff --git a/lib/pleroma/user.ex b/lib/pleroma/user.ex index ce125d608..0706f5607 100644 --- a/lib/pleroma/user.ex +++ b/lib/pleroma/user.ex @@ -2136,7 +2136,7 @@ defmodule Pleroma.User do    def public_key(_), do: {:error, "key not found"}    def get_public_key_for_ap_id(ap_id) do -    with {:ok, %User{} = user} <- get_or_fetch_by_ap_id(ap_id), +    with %User{} = user <- get_cached_by_ap_id(ap_id),           {:ok, public_key} <- public_key(user) do        {:ok, public_key}      else diff --git a/lib/pleroma/web/activity_pub/activity_pub_controller.ex b/lib/pleroma/web/activity_pub/activity_pub_controller.ex index 1357c379c..3b2193ca3 100644 --- a/lib/pleroma/web/activity_pub/activity_pub_controller.ex +++ b/lib/pleroma/web/activity_pub/activity_pub_controller.ex @@ -287,10 +287,9 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubController do      json(conn, "ok")    end -  def inbox(%{assigns: %{valid_signature: false}} = conn, _params) do -    conn -    |> put_status(:bad_request) -    |> json("Invalid HTTP Signature") +  def inbox(%{assigns: %{valid_signature: false}, req_headers: req_headers} = conn, params) do +    Federator.incoming_ap_doc(%{req_headers: req_headers, params: params}) +    json(conn, "ok")    end    # POST /relay/inbox -or- POST /internal/fetch/inbox diff --git a/lib/pleroma/web/federator.ex b/lib/pleroma/web/federator.ex index 84b77cda1..8621d984c 100644 --- a/lib/pleroma/web/federator.ex +++ b/lib/pleroma/web/federator.ex @@ -35,6 +35,17 @@ defmodule Pleroma.Web.Federator do    end    # Client API +  def incoming_ap_doc(%{params: params, req_headers: req_headers}) do +    ReceiverWorker.enqueue( +      "incoming_ap_doc", +      %{"req_headers" => req_headers, "params" => params, "timeout" => :timer.seconds(20)}, +      priority: 2 +    ) +  end + +  def incoming_ap_doc(%{"type" => "Delete"} = params) do +    ReceiverWorker.enqueue("incoming_ap_doc", %{"params" => params}, priority: 3) +  end    def incoming_ap_doc(params) do      ReceiverWorker.enqueue("incoming_ap_doc", %{"params" => params}) diff --git a/lib/pleroma/web/router.ex b/lib/pleroma/web/router.ex index eb8576b02..38391cc8f 100644 --- a/lib/pleroma/web/router.ex +++ b/lib/pleroma/web/router.ex @@ -471,6 +471,8 @@ defmodule Pleroma.Web.Router do      get("/main/ostatus", UtilController, :show_subscribe_form)      get("/ostatus_subscribe", RemoteFollowController, :follow)      post("/ostatus_subscribe", RemoteFollowController, :do_follow) + +    get("/authorize_interaction", RemoteFollowController, :authorize_interaction)    end    scope "/api/pleroma", Pleroma.Web.TwitterAPI do diff --git a/lib/pleroma/web/twitter_api/controllers/remote_follow_controller.ex b/lib/pleroma/web/twitter_api/controllers/remote_follow_controller.ex index 6229d5d05..178ad2b43 100644 --- a/lib/pleroma/web/twitter_api/controllers/remote_follow_controller.ex +++ b/lib/pleroma/web/twitter_api/controllers/remote_follow_controller.ex @@ -121,6 +121,13 @@ defmodule Pleroma.Web.TwitterAPI.RemoteFollowController do      render(conn, "followed.html", %{error: "Insufficient permissions: follow | write:follows."})    end +  # GET /authorize_interaction +  # +  def authorize_interaction(conn, %{"uri" => uri}) do +    conn +    |> redirect(to: Routes.remote_follow_path(conn, :follow, %{acct: uri})) +  end +    defp handle_follow_error(conn, {:mfa_token, followee, _} = _) do      render(conn, "follow_login.html", %{error: "Wrong username or password", followee: followee})    end diff --git a/lib/pleroma/workers/receiver_worker.ex b/lib/pleroma/workers/receiver_worker.ex index cf1bb62b4..1dddd8d2e 100644 --- a/lib/pleroma/workers/receiver_worker.ex +++ b/lib/pleroma/workers/receiver_worker.ex @@ -3,24 +3,56 @@  # SPDX-License-Identifier: AGPL-3.0-only  defmodule Pleroma.Workers.ReceiverWorker do +  alias Pleroma.Signature +  alias Pleroma.User    alias Pleroma.Web.Federator    use Pleroma.Workers.WorkerHelper, queue: "federator_incoming"    @impl Oban.Worker + +  def perform(%Job{ +        args: %{"op" => "incoming_ap_doc", "req_headers" => req_headers, "params" => params} +      }) do +    # Oban's serialization converts our tuple headers to lists. +    # Revert it for the signature validation. +    req_headers = Enum.into(req_headers, [], &List.to_tuple(&1)) + +    conn_data = %{params: params, req_headers: req_headers} + +    with {:ok, %User{} = _actor} <- User.get_or_fetch_by_ap_id(conn_data.params["actor"]), +         {:ok, _public_key} <- Signature.refetch_public_key(conn_data), +         {:signature, true} <- {:signature, HTTPSignatures.validate_conn(conn_data)}, +         {:ok, res} <- Federator.perform(:incoming_ap_doc, params) do +      {:ok, res} +    else +      e -> process_errors(e) +    end +  end +    def perform(%Job{args: %{"op" => "incoming_ap_doc", "params" => params}}) do      with {:ok, res} <- Federator.perform(:incoming_ap_doc, params) do        {:ok, res}      else +      e -> process_errors(e) +    end +  end + +  @impl Oban.Worker +  def timeout(%_{args: %{"timeout" => timeout}}), do: timeout + +  def timeout(_job), do: :timer.seconds(5) + +  defp process_errors(errors) do +    case errors do        {:error, :origin_containment_failed} -> {:cancel, :origin_containment_failed}        {:error, :already_present} -> {:cancel, :already_present}        {:error, {:validate_object, reason}} -> {:cancel, reason}        {:error, {:error, {:validate, reason}}} -> {:cancel, reason}        {:error, {:reject, reason}} -> {:cancel, reason} +      {:signature, false} -> {:cancel, :invalid_signature} +      {:error, {:error, reason = "Object has been deleted"}} -> {:cancel, reason}        e -> e      end    end - -  @impl Oban.Worker -  def timeout(_job), do: :timer.seconds(5)  end | 
