diff --git a/lib/mobilizon/actors/actor.ex b/lib/mobilizon/actors/actor.ex index 52fdc590f..f0b5ebaac 100644 --- a/lib/mobilizon/actors/actor.ex +++ b/lib/mobilizon/actors/actor.ex @@ -22,7 +22,7 @@ defmodule Mobilizon.Actors.Actor do import Ecto.Query alias Mobilizon.Repo - import Logger + require Logger # @type t :: %Actor{description: String.t, id: integer(), inserted_at: DateTime.t, updated_at: DateTime.t, display_name: String.t, domain: String.t, keys: String.t, suspended: boolean(), url: String.t, username: String.t, organized_events: list(), groups: list(), group_request: list(), user: User.t, field: ActorTypeEnum.t} @@ -182,9 +182,11 @@ defmodule Mobilizon.Actors.Actor do @spec get_public_key_for_url(String.t()) :: {:ok, String.t()} def get_public_key_for_url(url) do with {:ok, %Actor{} = actor} <- Actors.get_or_fetch_by_url(url) do - actor.keys + {:ok, actor.keys} else - _ -> :error + _ -> + Logger.error("Unable to fetch actor, so no keys for you") + {:error, :actor_fetch_error} end end diff --git a/lib/service/activity_pub/activity_pub.ex b/lib/service/activity_pub/activity_pub.ex index f140d7484..803021e7c 100644 --- a/lib/service/activity_pub/activity_pub.ex +++ b/lib/service/activity_pub/activity_pub.ex @@ -203,6 +203,10 @@ defmodule Mobilizon.Service.ActivityPub do with {:ok, data} <- fetch_and_prepare_user_from_url(url) do Actors.insert_or_update_actor(data) else + # Request returned 410 + {:error, :actor_deleted} -> + {:error, :actor_deleted} + e -> Logger.error("Failed to make actor from url") Logger.error(inspect(e)) @@ -283,12 +287,18 @@ defmodule Mobilizon.Service.ActivityPub do def fetch_and_prepare_user_from_url(url) do Logger.debug("Fetching and preparing user from url") - with {:ok, %{status_code: 200, body: body}} <- + with {:ok, %HTTPoison.Response{status_code: 200, body: body}} <- HTTPoison.get(url, [Accept: "application/activity+json"], follow_redirect: true), {:ok, data} <- Jason.decode(body) do user_data_from_user_object(data) else - e -> Logger.error("Could not decode user at fetch #{url}, #{inspect(e)}") + # User is gone, probably deleted + {:ok, %HTTPoison.Response{status_code: 410}} -> + {:error, :actor_deleted} + + e -> + Logger.error("Could not decode user at fetch #{url}, #{inspect(e)}") + e end end diff --git a/lib/service/http_signatures/http_signatures.ex b/lib/service/http_signatures/http_signatures.ex index efb688bdf..4327efcf7 100644 --- a/lib/service/http_signatures/http_signatures.ex +++ b/lib/service/http_signatures/http_signatures.ex @@ -44,14 +44,17 @@ defmodule Mobilizon.Service.HTTPSignatures do defp prepare_public_key(public_key_code) do with [public_key_entry] <- :public_key.pem_decode(public_key_code) do :public_key.pem_entry_decode(public_key_entry) + else + _err -> + {:error, :pem_decode_error} end end def validate_conn(conn) do # TODO: How to get the right key and see if it is actually valid for that request. # For now, fetch the key for the actor. - with public_key <- - conn.params["actor"] |> Actor.get_public_key_for_url() |> prepare_public_key() do + with {:ok, public_key} <- conn.params["actor"] |> Actor.get_public_key_for_url(), + {:ok, public_key} <- prepare_public_key(public_key) do if validate_conn(conn, public_key) do true else @@ -59,7 +62,8 @@ defmodule Mobilizon.Service.HTTPSignatures do # Fetch user anew and try one more time with actor_id <- conn.params["actor"], {:ok, _actor} <- ActivityPub.make_actor_from_url(actor_id), - public_key <- actor_id |> Actor.get_public_key_for_url() |> prepare_public_key() do + {:ok, public_key} <- actor_id |> Actor.get_public_key_for_url(), + {:ok, public_key} <- prepare_public_key(public_key) do validate_conn(conn, public_key) end end