refactor(activitypub): handle failure finding public key in actor keys

Signed-off-by: Thomas Citharel <tcit@tcit.fr>
This commit is contained in:
Thomas Citharel 2023-12-06 08:25:02 +01:00
parent 3a55baeffd
commit 5b337f952a
No known key found for this signature in database
GPG key ID: A061B9DDE0CA0773
2 changed files with 36 additions and 19 deletions

View file

@ -680,19 +680,22 @@ defmodule Mobilizon.Federation.ActivityPub.Utils do
@doc """ @doc """
Converts PEM encoded keys to a public key representation Converts PEM encoded keys to a public key representation
""" """
@spec pem_to_public_key_pem(String.t()) :: String.t() @spec pem_to_public_key_pem(String.t()) :: String.t() | {:error, :no_publickey_found}
def pem_to_public_key_pem(pem) do def pem_to_public_key_pem(pem) do
public_key = pem_to_public_key(pem) case :public_key.pem_decode(pem) do
[key_code] ->
public_key = pem_to_public_key(key_code)
public_key = :public_key.pem_entry_encode(:RSAPublicKey, public_key) public_key = :public_key.pem_entry_encode(:RSAPublicKey, public_key)
:public_key.pem_encode([public_key]) :public_key.pem_encode([public_key])
_ ->
{:error, :no_publickey_found}
end
end end
@spec pem_to_public_key(String.t()) :: {:RSAPublicKey, any(), any()} @spec pem_to_public_key(String.t()) :: {:RSAPublicKey, any(), any()}
defp pem_to_public_key(pem) do defp pem_to_public_key(key_code) do
[key_code] = :public_key.pem_decode(pem) case :public_key.pem_entry_decode(key_code) do
key = :public_key.pem_entry_decode(key_code)
case key do
{:RSAPrivateKey, _, modulus, exponent, _, _, _, _, _, _, _} -> {:RSAPrivateKey, _, modulus, exponent, _, _, _, _, _, _, _} ->
{:RSAPublicKey, modulus, exponent} {:RSAPublicKey, modulus, exponent}

View file

@ -112,19 +112,11 @@ defmodule Mobilizon.Federation.ActivityStream.Converter.Actor do
}, },
"discoverable" => actor.visibility == :public, "discoverable" => actor.visibility == :public,
"openness" => actor.openness, "openness" => actor.openness,
"manuallyApprovesFollowers" => actor.manually_approves_followers, "manuallyApprovesFollowers" => actor.manually_approves_followers
"publicKey" => %{
"id" => "#{actor.url}#main-key",
"owner" => actor.url,
"publicKeyPem" =>
if(is_nil(actor.domain) and not is_nil(actor.keys),
do: Utils.pem_to_public_key_pem(actor.keys),
else: actor.keys
)
}
} }
actor_data actor_data
|> add_keys(actor)
|> add_endpoints(actor) |> add_endpoints(actor)
|> maybe_add_members(actor) |> maybe_add_members(actor)
|> maybe_add_avatar_picture(actor) |> maybe_add_avatar_picture(actor)
@ -132,6 +124,28 @@ defmodule Mobilizon.Federation.ActivityStream.Converter.Actor do
|> maybe_add_physical_address(actor) |> maybe_add_physical_address(actor)
end end
@spec add_keys(map(), ActorModel.t()) :: map()
defp add_keys(actor_data, %ActorModel{} = actor) do
keys =
if is_nil(actor.domain) and not is_nil(actor.keys) do
case Utils.pem_to_public_key_pem(actor.keys) do
{:error, :no_publickey_found} ->
raise "No publickey found in private keys"
public_key when is_binary(public_key) ->
public_key
end
else
actor.keys
end
Map.put(actor_data, "publicKey", %{
"id" => "#{actor.url}#main-key",
"owner" => actor.url,
"publicKeyPem" => keys
})
end
defp add_endpoints(%{"endpoints" => endpoints} = actor_data, %ActorModel{} = actor) do defp add_endpoints(%{"endpoints" => endpoints} = actor_data, %ActorModel{} = actor) do
new_endpoints = %{ new_endpoints = %{
"members" => actor.members_url, "members" => actor.members_url,