Browse Source

Handle follow activities

master
Shadowfacts 2 years ago
parent
commit
2316c5d41d
Signed by: shadowfacts GPG Key ID: 94A5AB95422746E5
3 changed files with 64 additions and 14 deletions
  1. +11
    -0
      lib/clacks/activitypub.ex
  2. +39
    -10
      lib/clacks/inbox.ex
  3. +14
    -4
      lib/clacks_web/controllers/inbox_controller.ex

+ 11
- 0
lib/clacks/activitypub.ex View File

@ -95,6 +95,17 @@ defmodule Clacks.ActivityPub do
}
end
@spec accept_follow(follow_activity :: map()) :: map()
def accept_follow(%{"type" => "Follow", "object" => followed} = follow_activity) do
%{
"@context" => @context,
"type" => "Accept",
"id" => activity_id(Ecto.UUID.generate()),
"actor" => followed,
"object" => follow_activity
}
end
@spec object_id(id :: String.t()) :: String.t()
def object_id(id) do
url = Application.get_env(:clacks, ClacksWeb.Endpoint)[:url]


+ 39
- 10
lib/clacks/inbox.ex View File

@ -1,24 +1,53 @@
defmodule Clacks.Inbox do
alias Clacks.{Repo, Activity, Object, Actor}
def handle_create(%{"type" => "Create", "object" => object, "actor" => actor} = activity) do
changeset = Object.changeset(%Object{}, %{data: object})
{:ok, _object} = Repo.insert(changeset)
require Logger
alias Clacks.{Repo, Activity, Object, Actor, ActivityPub}
defp store_activity(%{"actor" => actor} = activity, local \\ false) when is_binary(actor) do
changeset =
Activity.changeset(%Activity{}, %{
data: activity,
local: false,
local: local,
actor: actor
})
{:ok, _activity} = Repo.insert(changeset)
Repo.insert(changeset)
end
def handle_create(%{"type" => "Create", "object" => object} = activity) do
changeset = Object.changeset(%Object{}, %{data: object})
{:ok, _object} = Repo.insert(changeset)
{:ok, _activity} = store_activity(activity)
end
def handle_follow(%{"type" => "Follow", "object" => followed_id, "actor" => follower})
@spec handle_follow(activity :: map()) :: :ok | {:error, reason :: any()}
def handle_follow(
%{"type" => "Follow", "object" => followed_id, "actor" => follower_id} = activity
)
when is_binary(followed_id) do
followed = Actor.get_by_ap_id(followed_id)
changeset = Actor.changeset(followed, %{followers: [follower | followed.followers]})
{:ok, _followed} = Repo.update(changeset)
follower = Actor.get_by_ap_id(follower_id)
store_activity(activity)
changeset = Actor.changeset(followed, %{followers: [follower_id | followed.followers]})
case Repo.update(changeset) do
{:error, changeset} ->
Logger.error("Couldn't store Follow activity: #{inspect(changeset)}")
{:error, "Couldn't store Follow activity"}
{:ok, _followed} ->
accept = ActivityPub.accept_follow(activity)
case store_activity(accept, true) do
{:error, changeset} ->
Logger.error("Couldn't store Accept activity: #{inspect(changeset)}")
{:error, "Couldn't store Accept activity"}
{:ok, _accept} ->
ActivityPub.Federator.federate(accept, follower.data["inbox"])
end
end
end
end

+ 14
- 4
lib/clacks_web/controllers/inbox_controller.ex View File

@ -1,4 +1,5 @@
defmodule ClacksWeb.InboxController do
require Logger
use ClacksWeb, :controller
alias Clacks.Inbox
@ -18,13 +19,22 @@ defmodule ClacksWeb.InboxController do
conn
|> put_status(200)
|> json(%{})
end
def handle(conn, %{"type" => "Follow", "object" => object} = activity) when is_binary(object) do
Inbox.handle_follow(activity)
conn
|> put_status(200)
case Inbox.handle_follow(activity) do
:ok ->
conn
|> put_status(200)
{:error, reason} ->
Logger.error("Could not handle incoming follow: #{inspect(reason)}")
conn
|> put_status(500)
end
|> json(%{})
end
# def handle(conn, _) do


Loading…
Cancel
Save