move things around
This commit is contained in:
parent
1c0d0fcd8d
commit
97cedc73b6
|
@ -2,8 +2,8 @@ defmodule Vonbraun.ActivityPub.Handler.Accept do
|
|||
@behaviour Vonbraun.ActivityPub.HandlerBehaviour
|
||||
|
||||
require Logger
|
||||
alias Vonbraun.Util
|
||||
alias Vonbraun.Ecto.Schema.Actor
|
||||
alias Vonbraun.ActivityPub.Object
|
||||
|
||||
@verb "Accept"
|
||||
|
||||
|
@ -41,7 +41,7 @@ defmodule Vonbraun.ActivityPub.Handler.Accept do
|
|||
%{}
|
||||
) do
|
||||
with {:actor, {:ok, follow_actor_id}} <- {:actor, extract_follow_object_actor(object)},
|
||||
{:match, true} <- {:match, follow_actor_id == Object.my_id()},
|
||||
{:match, true} <- {:match, follow_actor_id == Util.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}")
|
||||
|
|
|
@ -5,6 +5,7 @@ defmodule Vonbraun.ActivityPub.Handler.Follow do
|
|||
alias Vonbraun.ActivityPubReq
|
||||
alias Vonbraun.Ecto.Schema.Actor
|
||||
alias Vonbraun.ActivityPub.Object
|
||||
alias Vonbraun.Util
|
||||
|
||||
@verb "Follow"
|
||||
|
||||
|
@ -20,7 +21,7 @@ defmodule Vonbraun.ActivityPub.Handler.Follow do
|
|||
actor = %{}
|
||||
)
|
||||
when is_binary(follow_requester_id) and is_binary(follow_target) and is_binary(activity_id) do
|
||||
with {:valid_target, true} <- {:valid_target, Object.my_id() == follow_target},
|
||||
with {:valid_target, true} <- {:valid_target, Util.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(follow_requester_id)} do
|
||||
|
|
|
@ -3,7 +3,7 @@ defmodule Vonbraun.ActivityPub.Handler.Reject do
|
|||
|
||||
require Logger
|
||||
alias Vonbraun.Ecto.Schema.Actor
|
||||
alias Vonbraun.ActivityPub.Object
|
||||
alias Vonbraun.Util
|
||||
import Vonbraun.ActivityPub.Handler.Accept, only: [extract_follow_object_actor: 1]
|
||||
|
||||
@verb "Reject"
|
||||
|
@ -16,7 +16,7 @@ defmodule Vonbraun.ActivityPub.Handler.Reject do
|
|||
"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()},
|
||||
{:match, true} <- {:match, follow_actor_id == Util.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}")
|
||||
|
|
|
@ -3,7 +3,7 @@ defmodule Vonbraun.ActivityPub.Handler.Undo do
|
|||
|
||||
require Logger
|
||||
alias Vonbraun.Ecto.Schema.Actor
|
||||
alias Vonbraun.ActivityPub.Object
|
||||
alias Vonbraun.Util
|
||||
import Vonbraun.ActivityPub.Handler.Accept, only: [extract_follow_object_actor: 1]
|
||||
|
||||
@verb "Undo"
|
||||
|
@ -14,7 +14,7 @@ defmodule Vonbraun.ActivityPub.Handler.Undo do
|
|||
|
||||
def handle(%{"type" => @verb, "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()},
|
||||
{:match, true} <- {:match, follow_actor_id == Util.my_id()},
|
||||
{:asked, {:ok, %Actor{:following_state => nil}}} <-
|
||||
{:asked, Actor.remove_follower(actor_id)} do
|
||||
{:ok, :removed_follower}
|
||||
|
|
|
@ -2,17 +2,7 @@ defmodule Vonbraun.ActivityPub.Object do
|
|||
@context "https://www.w3.org/ns/activitystreams"
|
||||
@public_to "https://www.w3.org/ns/activitystreams#Public"
|
||||
|
||||
@spec my_id() :: String.t()
|
||||
def my_id() do
|
||||
domain = Application.fetch_env!(:vonbraun, :domain)
|
||||
nickname = Application.fetch_env!(:vonbraun, :nickname)
|
||||
"https://#{domain}/users/#{nickname}"
|
||||
end
|
||||
|
||||
@spec my_key_id() :: String.t()
|
||||
def my_key_id() do
|
||||
"#{my_id()}#main-key"
|
||||
end
|
||||
import Vonbraun.Util, only: [my_id: 0]
|
||||
|
||||
def add_context(object = %{"@context" => context})
|
||||
when is_list(context) or is_binary(context) do
|
||||
|
@ -112,6 +102,9 @@ defmodule Vonbraun.ActivityPub.Object do
|
|||
to: to_follow_id
|
||||
)
|
||||
|
||||
@spec accept_follow_activity(binary(), binary(), :accept | :reject) :: %{
|
||||
optional(<<_::16, _::_*8>>) => any()
|
||||
}
|
||||
def accept_follow_activity(followee_id, activity_id, type \\ :accept)
|
||||
when is_binary(followee_id) and is_binary(activity_id) and type in [:accept, :reject] do
|
||||
activity_type =
|
||||
|
@ -132,4 +125,102 @@ defmodule Vonbraun.ActivityPub.Object do
|
|||
|
||||
activity(activity_type, accept_activity_id, object, to: followee_id)
|
||||
end
|
||||
|
||||
def is_maybe_activitypub?(%{"@context" => @context}), do: true
|
||||
|
||||
def is_maybe_activitypub?(%{"@context" => context_list}) when is_list(context_list) do
|
||||
Enum.reduce_while(context_list, false, fn
|
||||
@context, _ ->
|
||||
{:halt, true}
|
||||
|
||||
context = %{}, _ ->
|
||||
if Enum.find(context, fn item -> elem(item, 1) == @context end) do
|
||||
{:halt, true}
|
||||
else
|
||||
{:cont, false}
|
||||
end
|
||||
|
||||
_, _ ->
|
||||
{:cont, false}
|
||||
end)
|
||||
end
|
||||
|
||||
def is_maybe_activitypub?(_), do: false
|
||||
|
||||
@spec fix_ld_properties(any()) ::
|
||||
{:error, :child_id | :child_type | :id | :list | :type | :unknown}
|
||||
| {:ok, list(list() | map()) | map()}
|
||||
@doc """
|
||||
If an object has type or id convert them to "@type" and "@id" respectively.
|
||||
This is so that AP objects conform to JSON-LD for our purposes even though
|
||||
they don't have to in the outside world. If the properties don't exist, they
|
||||
are not added. Also fixes the properties of an "object" value, if present.
|
||||
"""
|
||||
def fix_ld_properties(object = %{}) do
|
||||
has_unadorned_id? = Map.has_key?(object, "id")
|
||||
has_id? = Map.has_key?(object, "@id")
|
||||
has_unadored_type? = Map.has_key?(object, "type")
|
||||
has_type? = Map.has_key?(object, "@type")
|
||||
|
||||
cond do
|
||||
has_unadorned_id? && has_id? ->
|
||||
{:error, :id}
|
||||
|
||||
has_unadored_type? && has_type? ->
|
||||
{:error, :type}
|
||||
|
||||
true ->
|
||||
object =
|
||||
if has_unadorned_id? do
|
||||
id = Map.get(object, "id")
|
||||
object |> Map.delete("id") |> Map.put("@id", id)
|
||||
else
|
||||
object
|
||||
end
|
||||
|
||||
if has_unadored_type? do
|
||||
type = Map.get(object, "type")
|
||||
object |> Map.delete("type") |> Map.put("@type", type)
|
||||
else
|
||||
object
|
||||
end
|
||||
|
||||
# I am just assuming here the object is a JSON-LD object, not sure yet
|
||||
# if this is a valid assumption.
|
||||
with {:object, child_object = %{}} <- {:object, Map.get(object, "object")},
|
||||
{:valid, {:ok, child_object}} <- {:valid, fix_ld_properties(child_object)} do
|
||||
{:ok, Map.put(object, "object", child_object)}
|
||||
else
|
||||
{:object, child_object} when is_nil(child_object) or is_binary(child_object) ->
|
||||
{:ok, Map.put(object, "object", child_object)}
|
||||
|
||||
{:valid, {:error, :type}} ->
|
||||
{:error, :child_type}
|
||||
|
||||
{:valid, {:error, :id}} ->
|
||||
{:error, :child_id}
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
# I forgot why I wrote this lol.
|
||||
def fix_ld_properties(list) when is_list(list) do
|
||||
fixed_objects =
|
||||
Enum.reduce_while(list, {:ok, []}, fn object, objects ->
|
||||
case fix_ld_properties(object) do
|
||||
{:ok, fixed_object} -> {:cont, [fixed_object | objects]}
|
||||
{:error, _error} -> {:halt, :error}
|
||||
end
|
||||
end)
|
||||
|
||||
case fixed_objects do
|
||||
:error ->
|
||||
{:error, :list}
|
||||
|
||||
_ ->
|
||||
{:ok, Enum.reverse(fixed_objects)}
|
||||
end
|
||||
end
|
||||
|
||||
def fix_ld_properties(_), do: {:error, :unknown}
|
||||
end
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
defmodule Vonbraun.ActivityPubReq do
|
||||
require Logger
|
||||
alias Vonbraun.Cache
|
||||
alias Vonbraun.Util
|
||||
alias Vonbraun.HTTPSignature
|
||||
alias Vonbraun.ActivityPub.Object
|
||||
|
||||
@ttl :timer.minutes(1)
|
||||
|
||||
|
@ -19,7 +19,7 @@ defmodule Vonbraun.ActivityPubReq do
|
|||
path
|
||||
end
|
||||
|
||||
headers = HTTPSignature.add_get_signature(headers, Object.my_key_id(), target)
|
||||
headers = HTTPSignature.add_get_signature(headers, Util.my_key_id(), target)
|
||||
|
||||
Req.get(url, headers: headers)
|
||||
end
|
||||
|
@ -39,7 +39,7 @@ defmodule Vonbraun.ActivityPubReq do
|
|||
path
|
||||
end
|
||||
|
||||
headers = HTTPSignature.add_post_signature(headers, Object.my_key_id(), target, body)
|
||||
headers = HTTPSignature.add_post_signature(headers, Util.my_key_id(), target, body)
|
||||
|
||||
Logger.debug("POST payload is: `#{body}`")
|
||||
|
||||
|
|
|
@ -0,0 +1,13 @@
|
|||
defmodule Vonbraun.Util do
|
||||
@spec my_id() :: String.t()
|
||||
def my_id() do
|
||||
domain = Application.fetch_env!(:vonbraun, :domain)
|
||||
nickname = Application.fetch_env!(:vonbraun, :nickname)
|
||||
"https://#{domain}/users/#{nickname}"
|
||||
end
|
||||
|
||||
@spec my_key_id() :: String.t()
|
||||
def my_key_id() do
|
||||
"#{my_id()}#main-key"
|
||||
end
|
||||
end
|
Loading…
Reference in New Issue