defmodule Clacks.SignatureAdapter do alias Clacks.{Actor, Keys} @behaviour HTTPSignatures.Adapter def fetch_public_key(conn) do get_key(conn, false) end def refetch_public_key(conn) do get_key(conn, true) end defp get_key(conn, force_refetch) do actor_id = get_actor_id(conn) case actor_id do nil -> {:error, "couldn't get actor id"} _ -> case Actor.get_by_ap_id(actor_id, force_refetch) do %Actor{data: %{"publicKey" => %{"publicKeyPem" => pem}}} -> Keys.key_from_pem(pem) _ -> {:error, "couldn't get pem from actor #{actor_id}"} end end end defp get_actor_id(conn) do case HTTPSignatures.signature_for_conn(conn) do %{"keyId" => key_id} -> key_id_to_actor_id(key_id) _ -> case conn.body_params do %{"actor" => actor} when is_binary(actor) -> actor _ -> nil end end end defp key_id_to_actor_id(key_id) do %URI{URI.parse(key_id) | fragment: nil} |> URI.to_string() end end