Handle user gone and fix more public key stuff
Signed-off-by: Thomas Citharel <tcit@tcit.fr>
This commit is contained in:
parent
04e342c897
commit
c7ccbf1c47
@ -22,7 +22,7 @@ defmodule Mobilizon.Actors.Actor do
|
|||||||
import Ecto.Query
|
import Ecto.Query
|
||||||
alias Mobilizon.Repo
|
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}
|
# @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()}
|
@spec get_public_key_for_url(String.t()) :: {:ok, String.t()}
|
||||||
def get_public_key_for_url(url) do
|
def get_public_key_for_url(url) do
|
||||||
with {:ok, %Actor{} = actor} <- Actors.get_or_fetch_by_url(url) do
|
with {:ok, %Actor{} = actor} <- Actors.get_or_fetch_by_url(url) do
|
||||||
actor.keys
|
{:ok, actor.keys}
|
||||||
else
|
else
|
||||||
_ -> :error
|
_ ->
|
||||||
|
Logger.error("Unable to fetch actor, so no keys for you")
|
||||||
|
{:error, :actor_fetch_error}
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -203,6 +203,10 @@ defmodule Mobilizon.Service.ActivityPub do
|
|||||||
with {:ok, data} <- fetch_and_prepare_user_from_url(url) do
|
with {:ok, data} <- fetch_and_prepare_user_from_url(url) do
|
||||||
Actors.insert_or_update_actor(data)
|
Actors.insert_or_update_actor(data)
|
||||||
else
|
else
|
||||||
|
# Request returned 410
|
||||||
|
{:error, :actor_deleted} ->
|
||||||
|
{:error, :actor_deleted}
|
||||||
|
|
||||||
e ->
|
e ->
|
||||||
Logger.error("Failed to make actor from url")
|
Logger.error("Failed to make actor from url")
|
||||||
Logger.error(inspect(e))
|
Logger.error(inspect(e))
|
||||||
@ -283,12 +287,18 @@ defmodule Mobilizon.Service.ActivityPub do
|
|||||||
def fetch_and_prepare_user_from_url(url) do
|
def fetch_and_prepare_user_from_url(url) do
|
||||||
Logger.debug("Fetching and preparing user from url")
|
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),
|
HTTPoison.get(url, [Accept: "application/activity+json"], follow_redirect: true),
|
||||||
{:ok, data} <- Jason.decode(body) do
|
{:ok, data} <- Jason.decode(body) do
|
||||||
user_data_from_user_object(data)
|
user_data_from_user_object(data)
|
||||||
else
|
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
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -44,14 +44,17 @@ defmodule Mobilizon.Service.HTTPSignatures do
|
|||||||
defp prepare_public_key(public_key_code) do
|
defp prepare_public_key(public_key_code) do
|
||||||
with [public_key_entry] <- :public_key.pem_decode(public_key_code) do
|
with [public_key_entry] <- :public_key.pem_decode(public_key_code) do
|
||||||
:public_key.pem_entry_decode(public_key_entry)
|
:public_key.pem_entry_decode(public_key_entry)
|
||||||
|
else
|
||||||
|
_err ->
|
||||||
|
{:error, :pem_decode_error}
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def validate_conn(conn) do
|
def validate_conn(conn) do
|
||||||
# TODO: How to get the right key and see if it is actually valid for that request.
|
# 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.
|
# For now, fetch the key for the actor.
|
||||||
with public_key <-
|
with {:ok, public_key} <- conn.params["actor"] |> Actor.get_public_key_for_url(),
|
||||||
conn.params["actor"] |> Actor.get_public_key_for_url() |> prepare_public_key() do
|
{:ok, public_key} <- prepare_public_key(public_key) do
|
||||||
if validate_conn(conn, public_key) do
|
if validate_conn(conn, public_key) do
|
||||||
true
|
true
|
||||||
else
|
else
|
||||||
@ -59,7 +62,8 @@ defmodule Mobilizon.Service.HTTPSignatures do
|
|||||||
# Fetch user anew and try one more time
|
# Fetch user anew and try one more time
|
||||||
with actor_id <- conn.params["actor"],
|
with actor_id <- conn.params["actor"],
|
||||||
{:ok, _actor} <- ActivityPub.make_actor_from_url(actor_id),
|
{: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)
|
validate_conn(conn, public_key)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
Loading…
Reference in New Issue
Block a user