akkoma/lib/pleroma/signature.ex
Oneric 7cd3954152 Remove superfluous actor key suffix
Fragments are already always stripped anyway
so listing one specific fragment here is
unnecessary and potentially confusing.

This effectively reverts
4457928e32
but keeps the added bridgy testcase.
2024-06-27 18:29:45 +02:00

81 lines
2.2 KiB
Elixir

# Pleroma: A lightweight social networking server
# Copyright © 2017-2021 Pleroma Authors <https://pleroma.social/>
# SPDX-License-Identifier: AGPL-3.0-only
defmodule Pleroma.Signature do
@behaviour HTTPSignatures.Adapter
alias Pleroma.EctoType.ActivityPub.ObjectValidators
alias Pleroma.Keys
alias Pleroma.User
alias Pleroma.Web.ActivityPub.ActivityPub
@known_suffixes ["/publickey", "/main-key"]
def key_id_to_actor_id(key_id) do
uri =
key_id
|> URI.parse()
|> Map.put(:fragment, nil)
|> Map.put(:query, nil)
|> remove_suffix(@known_suffixes)
maybe_ap_id = URI.to_string(uri)
case ObjectValidators.ObjectID.cast(maybe_ap_id) do
{:ok, ap_id} ->
{:ok, ap_id}
_ ->
case Pleroma.Web.WebFinger.finger(maybe_ap_id) do
{:ok, %{"ap_id" => ap_id}} -> {:ok, ap_id}
_ -> {:error, maybe_ap_id}
end
end
end
defp remove_suffix(uri, [test | rest]) do
if not is_nil(uri.path) and String.ends_with?(uri.path, test) do
Map.put(uri, :path, String.replace(uri.path, test, ""))
else
remove_suffix(uri, rest)
end
end
defp remove_suffix(uri, []), do: uri
def fetch_public_key(conn) do
with %{"keyId" => kid} <- HTTPSignatures.signature_for_conn(conn),
{:ok, actor_id} <- key_id_to_actor_id(kid),
{:ok, public_key} <- User.get_public_key_for_ap_id(actor_id) do
{:ok, public_key}
else
e ->
{:error, e}
end
end
def refetch_public_key(conn) do
with %{"keyId" => kid} <- HTTPSignatures.signature_for_conn(conn),
{:ok, actor_id} <- key_id_to_actor_id(kid),
{:ok, _user} <- ActivityPub.make_user_from_ap_id(actor_id),
{:ok, public_key} <- User.get_public_key_for_ap_id(actor_id) do
{:ok, public_key}
else
e ->
{:error, e}
end
end
def sign(%User{keys: keys} = user, headers) do
with {:ok, private_key, _} <- Keys.keys_from_pem(keys) do
HTTPSignatures.sign(private_key, user.ap_id <> "#main-key", headers)
end
end
def signed_date, do: signed_date(NaiveDateTime.utc_now())
def signed_date(%NaiveDateTime{} = date) do
Timex.lformat!(date, "{WDshort}, {0D} {Mshort} {YYYY} {h24}:{m}:{s} GMT", "en")
end
end