forked from AkkomaGang/akkoma
Oneric
7cd3954152
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.
81 lines
2.2 KiB
Elixir
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
|