diff --git a/lib/federation/activity_pub/utils.ex b/lib/federation/activity_pub/utils.ex index 51441fc05..38c9a574e 100644 --- a/lib/federation/activity_pub/utils.ex +++ b/lib/federation/activity_pub/utils.ex @@ -680,19 +680,22 @@ defmodule Mobilizon.Federation.ActivityPub.Utils do @doc """ 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 - public_key = pem_to_public_key(pem) - public_key = :public_key.pem_entry_encode(:RSAPublicKey, public_key) - :public_key.pem_encode([public_key]) + 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.pem_encode([public_key]) + + _ -> + {:error, :no_publickey_found} + end end @spec pem_to_public_key(String.t()) :: {:RSAPublicKey, any(), any()} - defp pem_to_public_key(pem) do - [key_code] = :public_key.pem_decode(pem) - key = :public_key.pem_entry_decode(key_code) - - case key do + defp pem_to_public_key(key_code) do + case :public_key.pem_entry_decode(key_code) do {:RSAPrivateKey, _, modulus, exponent, _, _, _, _, _, _, _} -> {:RSAPublicKey, modulus, exponent} diff --git a/lib/federation/activity_stream/converter/actor.ex b/lib/federation/activity_stream/converter/actor.ex index db9a4b91a..c44216116 100644 --- a/lib/federation/activity_stream/converter/actor.ex +++ b/lib/federation/activity_stream/converter/actor.ex @@ -112,19 +112,11 @@ defmodule Mobilizon.Federation.ActivityStream.Converter.Actor do }, "discoverable" => actor.visibility == :public, "openness" => actor.openness, - "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 - ) - } + "manuallyApprovesFollowers" => actor.manually_approves_followers } actor_data + |> add_keys(actor) |> add_endpoints(actor) |> maybe_add_members(actor) |> maybe_add_avatar_picture(actor) @@ -132,6 +124,28 @@ defmodule Mobilizon.Federation.ActivityStream.Converter.Actor do |> maybe_add_physical_address(actor) 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 new_endpoints = %{ "members" => actor.members_url,