This commit is contained in:
Moon Man 2024-08-29 12:08:45 +00:00
parent 90283a4ffd
commit b201e1ce95
1 changed files with 2 additions and 129 deletions

View File

@ -1,8 +1,7 @@
defmodule Vonbraun.InboxRouter do
alias Vonbraun.HTTPSignature
alias Vonbraun.ActivityPubReq
alias Vonbraun.Ecto.Schema.Actor
alias Vonbraun.ActivityPub.Object
import Vonbraun.ActivityPub.Handler, only: [handle: 2]
use Plug.Router
require Logger
@ -31,7 +30,7 @@ defmodule Vonbraun.InboxRouter do
{:actor, ActivityPubReq.get_actor(actor_url)},
{:load, {:ok, public_key}} <- {:load, ExPublicKey.loads(public_key_pem)},
{:verify, true} <- {:verify, HTTPSignature.verify_post_signature(conn, public_key)},
{:send, {:ok, response}} <- {:send, handle_activity(activity, actor)} do
{:send, {:ok, response}} <- {:send, handle(activity, actor)} do
status_code =
case response do
:ignored ->
@ -61,130 +60,4 @@ defmodule Vonbraun.InboxRouter do
send_resp(conn, 404, "fuck off")
end
end
defp extract_follow_object_actor(%{"type" => "Follow", "actor" => actor_id})
when is_binary(actor_id) do
{:ok, actor_id}
end
defp extract_follow_object_actor(%{"type" => "Follow", "id" => provided_follow_activity_id})
when is_binary(provided_follow_activity_id) do
domain = Application.fetch_env!(:vonbraun, :domain)
actual_activity_id_prefix = "https://#{domain}/id/follow:"
with ^actual_activity_id_prefix <> actor_id <- provided_follow_activity_id do
{:ok, actor_id}
else
_ ->
{:error, :notfound}
end
end
defp extract_follow_object_actor(_) do
{:error, :notfound}
end
defp handle_activity(
%{"type" => "Follow", "actor" => actor_id, "object" => follow_target},
actor = %{}
)
when is_binary(follow_target) do
with {:valid_target, true} <- {:valid_target, Object.my_id() == follow_target},
{:add, {:ok, %Actor{:blocked => nil, :follows_me_state => follows_me_state}}}
when not is_nil(follows_me_state) <- {:add, Actor.maybe_add_follower(actor_id)} do
activity_type =
case follows_me_state do
"accepted" ->
:accept
"rejected" ->
:reject
"pending" ->
nil
end
if activity_type do
payload = Object.accept_follow_activity(actor_id, activity_type) |> Jason.encode!()
Logger.debug("Replying to follow request with: #{activity_type}")
Logger.debug("And payload: `#{payload}`")
with {:inbox, {:ok, inbox}} <- {:inbox, ActivityPubReq.extract_actor_inbox(actor)},
{:inbox_uri, inbox = %URI{}} <- {:inbox_uri, URI.parse(inbox)} do
Task.start(fn ->
case ActivityPubReq.post(inbox, payload) do
{:ok, %{:status => status, :body => body}} ->
Logger.debug("Accept response status: #{status} body: #{inspect(body)}")
{:error, error} ->
Logger.error("Failed to Accept: #{inspect(error)}")
end
end)
{:ok, String.to_atom(follows_me_state)}
else
{:inbox, {:error, _}} ->
{:error, :inbox}
end
else
{:ok, :ignored}
end
else
{:valid_target, false} ->
{:ok, :unauthorized}
{:add, {:ok, %Actor{:blocked => blocked_ts}}} when not is_nil(blocked_ts) ->
{:ok, :unauthorized}
{:add, {:ok, %Actor{:follows_me_state => nil}}} ->
Logger.error("follows-me state was nil, this should never happen")
{:error, :impossible}
{:add, {:error, error}} ->
{:error, error}
end
end
defp handle_activity(
%{
"type" => "Accept",
"actor" => actor_id,
"object" => object = %{"type" => "Follow"}
},
_actor = %{}
)
when is_binary(actor_id) do
with {:asked, {:ok, %Actor{:blocked => nil, :following_state => "accepted"}}} <-
{:asked, Actor.mark_pending_follow(actor_id, "accepted", force: true)},
{:actor, {:ok, follow_actor_id}} <- {:actor, extract_follow_object_actor(object)},
{:match, true} <- {:match, follow_actor_id == Object.my_id()} do
Logger.info("Now following: #{actor_id}")
{:ok, :following}
else
{:asked, {:error, :blocked}} ->
{:ok, :blocked_user}
{:asked, {:error, error}} ->
{:error, error}
{:asked, {:ok, %Actor{:blocked => nil, :following_state => following_state}}} ->
Logger.error(
"Weird following state after received Accept: #{following_state} from actor: #{actor_id} this should not happen."
)
{:error, :following_state}
{:actor, {:error, _error}} ->
{:ok, :unauthorized}
{:match, false} ->
{:ok, :unauthorized}
end
end
defp handle_activity(activity = %{}, _) do
Logger.warning("I don't know what to do with it: #{inspect(activity)}")
{:ok, :ignored}
end
end