untested implementation
This commit is contained in:
parent
249ae3619b
commit
c34f74aaae
|
@ -1,10 +1,67 @@
|
||||||
defmodule Vonbraun.ActivityPub.Handler.Accept do
|
defmodule Vonbraun.ActivityPub.Handler.Accept do
|
||||||
@behaviour Vonbraun.ActivityPub.HandlerBehaviour
|
@behaviour Vonbraun.ActivityPub.HandlerBehaviour
|
||||||
|
|
||||||
|
require Logger
|
||||||
|
alias Vonbraun.Ecto.Schema.Actor
|
||||||
|
alias Vonbraun.ActivityPub.Object
|
||||||
|
|
||||||
def type, do: "Accept"
|
def type, do: "Accept"
|
||||||
|
|
||||||
# Lots of kinds of things can be accepted.
|
def extract_follow_object_actor(%{"type" => "Follow", "actor" => actor_id})
|
||||||
def handle(_activity = %{"type" => "Accept"}) do
|
when is_binary(actor_id) do
|
||||||
:ok
|
{:ok, actor_id}
|
||||||
|
end
|
||||||
|
|
||||||
|
def 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
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def extract_follow_object_actor(_) do
|
||||||
|
{:error, :notfound}
|
||||||
|
end
|
||||||
|
|
||||||
|
# Lots of kinds of things can be accepted but for right now only follows.
|
||||||
|
def handle(%{
|
||||||
|
"type" => "Accept",
|
||||||
|
"actor" => actor_id,
|
||||||
|
"object" => object = %{"type" => "Follow"}
|
||||||
|
}) do
|
||||||
|
with {:actor, {:ok, follow_actor_id}} <- {:actor, extract_follow_object_actor(object)},
|
||||||
|
{:match, true} <- {:match, follow_actor_id == Object.my_id()},
|
||||||
|
{:asked, {:ok, %Actor{:blocked => nil, :following_state => "accepted"}}} <-
|
||||||
|
{:asked, Actor.mark_pending_follow(actor_id, "accepted", force: true)} 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
|
||||||
|
|
||||||
|
def handle(%{}), do: {:error, :match}
|
||||||
|
end
|
||||||
|
|
|
@ -1,9 +1,76 @@
|
||||||
defmodule Vonbraun.ActivityPub.Handler.Follow do
|
defmodule Vonbraun.ActivityPub.Handler.Follow do
|
||||||
@behaviour Vonbraun.ActivityPub.HandlerBehaviour
|
@behaviour Vonbraun.ActivityPub.HandlerBehaviour
|
||||||
|
|
||||||
|
require Logger
|
||||||
|
alias Vonbraun.ActivityPubReq
|
||||||
|
alias Vonbraun.Ecto.Schema.Actor
|
||||||
|
alias Vonbraun.ActivityPub.Object
|
||||||
|
|
||||||
def type, do: "Follow"
|
def type, do: "Follow"
|
||||||
|
|
||||||
def handle(_activity = %{"type" => "Follow"}) do
|
def handle(%{"type" => "Follow", "actor" => follow_requester_id, "object" => follow_target}) when is_binary(follow_requester_id) and is_binary(follow_target) do
|
||||||
:ok
|
with {:valid_target, true} <- {:valid_target, Object.my_id() == follow_target},
|
||||||
|
{:actor, {:ok, actor}} <- {:actor, ActivityPubReq.get_actor(follow_requester_id)},
|
||||||
|
{:add, {:ok, %Actor{:blocked => nil, :follows_me_state => follows_me_state}}}
|
||||||
|
when not is_nil(follows_me_state) <-
|
||||||
|
{:add, Actor.maybe_add_follower(follow_requester_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(follow_requester_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}
|
||||||
|
|
||||||
|
{:actor, {:error, error}} ->
|
||||||
|
{:error, {:actor, error}}
|
||||||
|
|
||||||
|
{: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
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def handle(%{}), do: {:error, :match}
|
||||||
|
end
|
||||||
|
|
|
@ -1,10 +1,48 @@
|
||||||
defmodule Vonbraun.ActivityPub.Handler.Reject do
|
defmodule Vonbraun.ActivityPub.Handler.Reject do
|
||||||
@behaviour Vonbraun.ActivityPub.HandlerBehaviour
|
@behaviour Vonbraun.ActivityPub.HandlerBehaviour
|
||||||
|
|
||||||
|
require Logger
|
||||||
|
alias Vonbraun.Ecto.Schema.Actor
|
||||||
|
alias Vonbraun.ActivityPub.Object
|
||||||
|
import Vonbraun.ActivityPub.Handler.Accept, only: [extract_follow_object_actor: 1]
|
||||||
|
|
||||||
def type, do: "Reject"
|
def type, do: "Reject"
|
||||||
|
|
||||||
# Lots of kinds of things can be accepted.
|
# Lots of kinds of things can be rejected but for right now only follows.
|
||||||
def handle(_activity = %{"type" => "Reject"}) do
|
def handle(
|
||||||
:ok
|
%{
|
||||||
|
"type" => "Reject",
|
||||||
|
"actor" => actor_id,
|
||||||
|
"object" => object = %{"type" => "Follow"}
|
||||||
|
}
|
||||||
|
) do
|
||||||
|
with {:actor, {:ok, follow_actor_id}} <- {:actor, extract_follow_object_actor(object)},
|
||||||
|
{:match, true} <- {:match, follow_actor_id == Object.my_id()},
|
||||||
|
{:asked, {:ok, %Actor{:blocked => nil, :following_state => "accepted"}}} <-
|
||||||
|
{:asked, Actor.mark_pending_follow(actor_id, "rejected", force: true)} 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
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def handle(%{}), do: {:error, :match}
|
||||||
|
end
|
||||||
|
|
|
@ -5,6 +5,6 @@ defmodule Vonbraun.ActivityPub.Handler.Undo do
|
||||||
|
|
||||||
# Lots of different kinds of things can be undone.
|
# Lots of different kinds of things can be undone.
|
||||||
def handle(_activity = %{"type" => "Undo"}) do
|
def handle(_activity = %{"type" => "Undo"}) do
|
||||||
:ok
|
{:ok, :unknown}
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
Loading…
Reference in New Issue