Refactoring of Actors context

This commit is contained in:
miffigriffy
2019-09-09 00:52:49 +02:00
parent 3a4a006c44
commit 4418275223
36 changed files with 1145 additions and 1345 deletions

View File

@@ -7,20 +7,23 @@ defmodule Mobilizon.Service.HTTPSignatures.Signature do
@moduledoc """
Adapter for the `HTTPSignatures` lib that handles signing and providing public keys to verify HTTPSignatures
"""
@behaviour HTTPSignatures.Adapter
alias Mobilizon.Actors.Actor
alias Mobilizon.Service.ActivityPub
require Logger
def key_id_to_actor_url(key_id) do
uri =
URI.parse(key_id)
%{path: path} = uri =
key_id
|> URI.parse()
|> Map.put(:fragment, nil)
uri =
if not is_nil(uri.path) and String.ends_with?(uri.path, "/publickey") do
Map.put(uri, :path, String.replace(uri.path, "/publickey", ""))
if not is_nil(path) do
Map.put(uri, :path, String.trim_trailing(path, "/publickey"))
else
uri
end
@@ -28,11 +31,47 @@ defmodule Mobilizon.Service.HTTPSignatures.Signature do
URI.to_string(uri)
end
@doc """
Convert internal PEM encoded keys to public key format.
"""
@spec prepare_public_key(String.t()) :: {:ok, tuple} | {:error, :pem_decode_error}
def prepare_public_key(public_key_code) do
case :public_key.pem_decode(public_key_code) do
[public_key_entry] ->
{:ok, :public_key.pem_entry_decode(public_key_entry)}
_ ->
{:error, :pem_decode_error}
end
end
@doc """
Gets a public key for a given ActivityPub actor ID (url).
"""
@spec get_public_key_for_url(String.t()) ::
{:ok, String.t()} | {:error, :actor_fetch_error | :pem_decode_error}
def get_public_key_for_url(url) do
with {:ok, %Actor{keys: keys}} <- ActivityPub.get_or_fetch_by_url(url),
{:ok, public_key} <- prepare_public_key(keys) do
{:ok, public_key}
else
{:error, :pem_decode_error} ->
Logger.error("Error while decoding PEM")
{:error, :pem_decode_error}
_ ->
Logger.error("Unable to fetch actor, so no keys for you")
{:error, :actor_fetch_error}
end
end
def fetch_public_key(conn) do
with %{"keyId" => kid} <- HTTPSignatures.signature_for_conn(conn),
actor_id <- key_id_to_actor_url(kid),
:ok <- Logger.debug("Fetching public key for #{actor_id}"),
{:ok, public_key} <- Actor.get_public_key_for_url(actor_id) do
{:ok, public_key} <- get_public_key_for_url(actor_id) do
{:ok, public_key}
else
e ->
@@ -45,7 +84,7 @@ defmodule Mobilizon.Service.HTTPSignatures.Signature do
actor_id <- key_id_to_actor_url(kid),
:ok <- Logger.debug("Refetching public key for #{actor_id}"),
{:ok, _actor} <- ActivityPub.make_actor_from_url(actor_id),
{:ok, public_key} <- Actor.get_public_key_for_url(actor_id) do
{:ok, public_key} <- get_public_key_for_url(actor_id) do
{:ok, public_key}
else
e ->
@@ -53,12 +92,12 @@ defmodule Mobilizon.Service.HTTPSignatures.Signature do
end
end
def sign(%Actor{} = actor, headers) do
def sign(%Actor{keys: keys} = actor, headers) do
Logger.debug("Signing on behalf of #{actor.url}")
Logger.debug("headers")
Logger.debug(inspect(headers))
with {:ok, key} <- actor.keys |> Actor.prepare_public_key() do
with {:ok, key} <- prepare_public_key(keys) do
HTTPSignatures.sign(key, actor.url <> "#main-key", headers)
end
end