akkoma/lib/pleroma/web/plugs/mapped_signature_to_identity_plug.ex
2025-06-07 20:27:58 +02:00

84 lines
2.7 KiB
Elixir
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# Pleroma: A lightweight social networking server
# Copyright © 2017-2021 Pleroma Authors <https://pleroma.social/>
# SPDX-License-Identifier: AGPL-3.0-only
defmodule Pleroma.Web.Plugs.MappedSignatureToIdentityPlug do
alias Pleroma.Helpers.AuthHelper
alias Pleroma.User
alias Pleroma.Web.ActivityPub.Utils
import Plug.Conn
require Logger
def init(options), do: options
def call(%{assigns: %{user: %User{}}} = conn, _opts), do: conn
# if this has payload make sure it is signed by the same actor that made it
def call(
%{
assigns: %{valid_signature: true, signature_user: signature_user},
params: %{"actor" => actor}
} = conn,
_opts
) do
with actor_id <- Utils.get_ap_id(actor),
{:federate, true} <- {:federate, should_federate?(signature_user)},
{:user_match, true} <- {:user_match, signature_user.ap_id == actor_id} do
conn
|> assign(:user, signature_user)
|> AuthHelper.skip_oauth()
else
{:user_match, false} ->
Logger.debug("Failed to map identity from signature (payload actor mismatch)")
Logger.debug(
"key_user=#{signature_user.id}(#{signature_user.ap_id}), actor=#{inspect(actor)}"
)
assign(conn, :valid_signature, false)
error ->
handle_common_errors(conn, actor, signature_user, error)
end
end
# no payload, probably a signed fetch
def call(%{assigns: %{valid_signature: true, signature_user: signature_user}} = conn, _opts) do
with {:federate, true} <- {:federate, should_federate?(signature_user)} do
conn
|> assign(:user, signature_user)
|> AuthHelper.skip_oauth()
else
error -> handle_common_errors(conn, nil, signature_user, error)
end
end
# supposedly valid signature but no user (this isnt supposed to happen)
def call(%{assigns: %{valid_signature: true}} = conn, _opts),
do: assign(conn, :valid_signature, false)
# no signature at all
def call(conn, _opts), do: conn
def handle_common_errors(conn, actor, signature_user, error) do
actor_str = if actor == nil, do: "", else: " actor=#{inspect(actor)}"
case error do
{:federate, false} ->
Logger.debug("Identity from signature is instance blocked")
Logger.debug("key_user=#{signature_user.nickname}(#{signature_user.id})#{actor_str}")
assign(conn, :valid_signature, false)
end
end
defp should_federate?(%User{ap_id: ap_id}), do: should_federate?(ap_id)
defp should_federate?(ap_id) do
if Pleroma.Config.get([:activitypub, :authorized_fetch_mode], false) do
Pleroma.Web.ActivityPub.Publisher.should_federate?(ap_id)
else
true
end
end
end