Refactor HTTP signatures

Signed-off-by: Thomas Citharel <tcit@tcit.fr>
This commit is contained in:
Thomas Citharel 2021-09-30 15:50:52 +02:00
parent 74145dc520
commit 98b840190d
No known key found for this signature in database
GPG key ID: A061B9DDE0CA0773

View file

@ -54,19 +54,19 @@ defmodule Mobilizon.Federation.HTTPSignatures.Signature do
{:ok, String.t()} {:ok, String.t()}
| {:error, :actor_fetch_error | :pem_decode_error | :actor_not_fetchable} | {:error, :actor_fetch_error | :pem_decode_error | :actor_not_fetchable}
defp get_public_key_for_url(url) do defp get_public_key_for_url(url) do
with {:ok, %Actor{keys: keys}} <- ActivityPubActor.get_or_fetch_actor_by_url(url), case ActivityPubActor.get_or_fetch_actor_by_url(url) do
{:ok, public_key} <- prepare_public_key(keys) do {:ok, %Actor{keys: keys}} ->
case prepare_public_key(keys) do
{:ok, public_key} ->
{:ok, public_key} {:ok, public_key}
else
{:error, :pem_decode_error} -> {:error, :pem_decode_error} ->
Logger.error("Error while decoding PEM") Logger.error("Error while decoding PEM")
{:error, :pem_decode_error} {:error, :pem_decode_error}
end
{:error, "Could not fetch by AP id"} -> {:error, err} ->
{:error, :actor_not_fetchable}
err ->
Sentry.capture_message("Unable to fetch actor, so no keys for you", Sentry.capture_message("Unable to fetch actor, so no keys for you",
extra: %{url: url} extra: %{url: url}
) )
@ -80,16 +80,17 @@ defmodule Mobilizon.Federation.HTTPSignatures.Signature do
@spec fetch_public_key(Plug.Conn.t()) :: @spec fetch_public_key(Plug.Conn.t()) ::
{:ok, String.t()} {:ok, String.t()}
| {:error, :actor_fetch_error | :actor_not_fetchable | :pem_decode_error} | {:error,
:actor_fetch_error | :actor_not_fetchable | :pem_decode_error | :no_signature_in_conn}
def fetch_public_key(conn) do def fetch_public_key(conn) do
with %{"keyId" => kid} <- HTTPSignatures.signature_for_conn(conn), case HTTPSignatures.signature_for_conn(conn) do
actor_id <- key_id_to_actor_url(kid), %{"keyId" => kid} ->
:ok <- Logger.debug("Fetching public key for #{actor_id}"), actor_id = key_id_to_actor_url(kid)
{:ok, public_key} <- get_public_key_for_url(actor_id) do Logger.debug("Fetching public key for #{actor_id}")
{:ok, public_key} get_public_key_for_url(actor_id)
else
{:error, err} -> _ ->
{:error, err} {:error, :no_signature_in_conn}
end end
end end
@ -98,15 +99,12 @@ defmodule Mobilizon.Federation.HTTPSignatures.Signature do
| {:error, :actor_fetch_error | :actor_not_fetchable | :pem_decode_error, | {:error, :actor_fetch_error | :actor_not_fetchable | :pem_decode_error,
:actor_is_local} :actor_is_local}
def refetch_public_key(conn) do def refetch_public_key(conn) do
with %{"keyId" => kid} <- HTTPSignatures.signature_for_conn(conn), %{"keyId" => kid} = HTTPSignatures.signature_for_conn(conn)
actor_id <- key_id_to_actor_url(kid), actor_id = key_id_to_actor_url(kid)
:ok <- Logger.debug("Refetching public key for #{actor_id}"), Logger.debug("Refetching public key for #{actor_id}")
{:ok, _actor} <- ActivityPubActor.make_actor_from_url(actor_id),
{:ok, public_key} <- get_public_key_for_url(actor_id) do with {:ok, _actor} <- ActivityPubActor.make_actor_from_url(actor_id) do
{:ok, public_key} get_public_key_for_url(actor_id)
else
{:error, err} ->
{:error, err}
end end
end end
@ -129,6 +127,7 @@ defmodule Mobilizon.Federation.HTTPSignatures.Signature do
@spec generate_date_header :: String.t() @spec generate_date_header :: String.t()
def generate_date_header, do: generate_date_header(NaiveDateTime.utc_now()) def generate_date_header, do: generate_date_header(NaiveDateTime.utc_now())
@spec generate_date_header(NaiveDateTime.t()) :: String.t()
def generate_date_header(%NaiveDateTime{} = date) do def generate_date_header(%NaiveDateTime{} = date) do
Timex.format!(date, "{WDshort}, {0D} {Mshort} {YYYY} {h24}:{m}:{s} GMT") Timex.format!(date, "{WDshort}, {0D} {Mshort} {YYYY} {h24}:{m}:{s} GMT")
end end