feat: Send follow requests
This commit is contained in:
parent
1259d3202d
commit
90a158c380
5 changed files with 73 additions and 7 deletions
|
|
@ -1,2 +1,15 @@
|
|||
defmodule ActivityPub do
|
||||
def fetch_actor(actor_id) do
|
||||
request =
|
||||
Req.new(url: actor_id)
|
||||
|> Req.Request.put_header("accept", "application/json")
|
||||
|
||||
case Req.get(request) do
|
||||
{:ok, result} ->
|
||||
{:ok, result.body}
|
||||
|
||||
error ->
|
||||
error
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -85,13 +85,9 @@ defmodule ActivityPub.Headers do
|
|||
end
|
||||
|
||||
def fetch_actor_key(key_id) do
|
||||
request =
|
||||
Req.new(url: key_id)
|
||||
|> Req.Request.put_header("accept", "application/json")
|
||||
|
||||
case Req.get(request) do
|
||||
{:ok, result} ->
|
||||
key_map = result.body["publicKey"]
|
||||
case ActivityPub.fetch_actor(key_id) do
|
||||
{:ok, body} ->
|
||||
key_map = body["publicKey"]
|
||||
|
||||
if key_map["id"] == key_id do
|
||||
[public_key | _] =
|
||||
|
|
|
|||
|
|
@ -1,8 +1,11 @@
|
|||
defmodule Postland.Activities do
|
||||
use Phoenix.VerifiedRoutes, endpoint: PostlandWeb.Endpoint, router: PostlandWeb.Router
|
||||
|
||||
require Logger
|
||||
|
||||
alias Postland.Activity
|
||||
alias Postland.Repo
|
||||
alias Postland.Follows
|
||||
|
||||
def process_activity(params) do
|
||||
case record_activity(params) do
|
||||
|
|
@ -20,6 +23,20 @@ defmodule Postland.Activities do
|
|||
|> Repo.insert()
|
||||
end
|
||||
|
||||
def cause_effects(%Activity{actor_id: actor_id, type: "Accept", data: %{"object" => %{"type" => "Follow"}}} = activity) do
|
||||
case Follows.get(Postland.my_actor_id(), actor_id) do
|
||||
nil ->
|
||||
Logger.warning("Got accept for a follow we don't have in the db: #{actor_id}")
|
||||
|
||||
{:ok, activity}
|
||||
|
||||
request ->
|
||||
Follows.confirm_request(request)
|
||||
end
|
||||
|
||||
{:ok, activity}
|
||||
end
|
||||
|
||||
def cause_effects(%Activity{actor_id: actor_id, type: "Follow", data: %{"object" => object}} = activity) do
|
||||
if object == Postland.my_actor_id() do
|
||||
case Postland.Follows.record_inbound_request(actor_id) do
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@ defmodule Postland.Follow do
|
|||
|
||||
import Ecto.Changeset
|
||||
|
||||
@primary_key false
|
||||
schema "follows" do
|
||||
field :follower, :string, primary_key: true
|
||||
field :followee, :string, primary_key: true
|
||||
|
|
|
|||
|
|
@ -1,8 +1,47 @@
|
|||
defmodule Postland.Follows do
|
||||
use Phoenix.VerifiedRoutes, endpoint: PostlandWeb.Endpoint, router: PostlandWeb.Router
|
||||
|
||||
import Ecto.Query, warn: false
|
||||
|
||||
alias Postland.Accounts
|
||||
alias Postland.Follow
|
||||
alias Postland.Repo
|
||||
alias ActivityPub.Headers
|
||||
|
||||
alias Ecto.Multi
|
||||
|
||||
def record_and_send_follow_request(to_actor_id) do
|
||||
Multi.new()
|
||||
|> Multi.run(:follow_record, fn _data, _repo -> record_outbound_request(to_actor_id) end)
|
||||
|> Multi.run(:send_request, fn _data, _repo ->
|
||||
send_follow_request(to_actor_id)
|
||||
end)
|
||||
|> Repo.transaction()
|
||||
end
|
||||
|
||||
def send_follow_request(to_actor_id) do
|
||||
encoded_followee = Base.url_encode64(to_actor_id)
|
||||
encoded_follower = Base.url_encode64(Postland.my_actor_id())
|
||||
|
||||
actor = ActivityPub.fetch_actor(to_actor_id)
|
||||
inbox = Map.get(actor, "inbox")
|
||||
follow_request = %{
|
||||
"@context" => "https://www.w3.org/ns/activitystreams",
|
||||
"id" => url(~p"/follows/#{encoded_followee}/#{encoded_follower}"),
|
||||
"type" => "Follow",
|
||||
"actor" => Postland.my_actor_id(),
|
||||
"object" => to_actor_id
|
||||
}
|
||||
|> Jason.encode!()
|
||||
|
||||
headers = Headers.signing_headers("POST", inbox, follow_request, Postland.my_actor_id(), Accounts.solo_user().private_key)
|
||||
|
||||
Req.post(inbox, headers: headers, body: follow_request)
|
||||
end
|
||||
|
||||
def get(follower, followee) do
|
||||
from(f in Follow, where: f.followee == ^followee, where: f.follower == ^follower) |> Repo.one()
|
||||
end
|
||||
|
||||
def pending_inbound_requests() do
|
||||
my_actor_id = Postland.my_actor_id()
|
||||
|
|
|
|||
Loading…
Reference in a new issue