This commit is contained in:
Thomas Citharel
2018-11-12 09:05:31 +01:00
parent 6e691640de
commit 5721c5fe05
16 changed files with 289 additions and 228 deletions

View File

@@ -1,6 +1,7 @@
defmodule MobilizonWeb.ActivityPubController do
use MobilizonWeb, :controller
alias Mobilizon.{Actors, Actors.Actor, Events, Events.Event}
alias Mobilizon.{Actors, Actors.Actor, Events}
alias Mobilizon.Events.{Event, Comment}
alias MobilizonWeb.ActivityPub.{ObjectView, ActorView}
alias Mobilizon.Service.ActivityPub
alias Mobilizon.Service.Federator
@@ -9,16 +10,18 @@ defmodule MobilizonWeb.ActivityPubController do
action_fallback(:errors)
@activity_pub_headers [
"application/activity+json",
"application/activity+json, application/ld+json"
]
def actor(conn, %{"name" => name}) do
with %Actor{} = actor <- Actors.get_local_actor_by_name(name) do
case get_req_header(conn, "accept") do
["application/activity+json"] ->
cond do
conn |> get_req_header("accept") |> is_ap_header() ->
conn |> render_ap_actor(actor)
["application/activity+json, application/ld+json"] ->
conn |> render_ap_actor(actor)
_ ->
true ->
conn
|> put_resp_content_type("text/html")
|> send_file(200, "priv/static/index.html")
@@ -28,6 +31,10 @@ defmodule MobilizonWeb.ActivityPubController do
end
end
defp is_ap_header(ap_headers) do
length(@activity_pub_headers -- ap_headers) < 2
end
defp render_ap_actor(conn, %Actor{} = actor) do
conn
|> put_resp_header("content-type", "application/activity+json")
@@ -41,7 +48,21 @@ defmodule MobilizonWeb.ActivityPubController do
|> put_resp_header("content-type", "application/activity+json")
|> json(ObjectView.render("event.json", %{event: event}))
else
false ->
_ ->
{:error, :not_found}
end
end
def comment(conn, %{"uuid" => uuid}) do
with %Comment{} = comment <- Events.get_comment_full_from_uuid(uuid) do
# Comments are always public for now
# TODO : Make comments maybe restricted
# true <- comment.public do
conn
|> put_resp_header("content-type", "application/activity+json")
|> json(ObjectView.render("comment.json", %{comment: comment}))
else
_ ->
{:error, :not_found}
end
end

View File

@@ -14,7 +14,7 @@ defmodule MobilizonWeb.Router do
end
pipeline :activity_pub do
plug(:accepts, ["activity-json", "text/html"])
plug(:accepts, ["activity-json", "html"])
plug(MobilizonWeb.HTTPSignaturePlug)
end
@@ -55,7 +55,7 @@ defmodule MobilizonWeb.Router do
get("/@:name/following", ActivityPubController, :following)
get("/@:name/followers", ActivityPubController, :followers)
get("/events/:uuid", ActivityPubController, :event)
get("/comments/:uuid", ActivityPubController, :event)
get("/comments/:uuid", ActivityPubController, :comment)
post("/@:name/inbox", ActivityPubController, :inbox)
post("/inbox", ActivityPubController, :inbox)
end

View File

@@ -32,6 +32,8 @@ defmodule MobilizonWeb.ActivityPub.ActorView do
"owner" => actor.url,
"publicKeyPem" => public_key
},
# TODO : Make have actors have an uuid
# "uuid" => actor.uuid
"endpoints" => %{
"sharedInbox" => actor.shared_inbox_url
}
@@ -135,6 +137,7 @@ defmodule MobilizonWeb.ActivityPub.ActorView do
"Announce"
end,
"actor" => activity.actor,
# Not sure if needed since this is used into outbox
"published" => Timex.now(),
"to" => ["https://www.w3.org/ns/activitystreams#Public"],
"object" =>
@@ -143,9 +146,10 @@ defmodule MobilizonWeb.ActivityPub.ActorView do
render_one(activity.data, ObjectView, "event.json", as: :event)
:Comment ->
render_one(activity.data, ObjectView, "note.json", as: :note)
render_one(activity.data, ObjectView, "comment.json", as: :comment)
end
}
|> Map.merge(Utils.make_json_ld_header())
end
def collection(collection, iri, page, total \\ nil) do

View File

@@ -2,20 +2,7 @@ defmodule MobilizonWeb.ActivityPub.ObjectView do
use MobilizonWeb, :view
alias MobilizonWeb.ActivityPub.ObjectView
alias Mobilizon.Service.ActivityPub.Transmogrifier
@base %{
"@context" => [
"https://www.w3.org/ns/activitystreams",
"https://w3id.org/security/v1",
%{
"manuallyApprovesFollowers" => "as:manuallyApprovesFollowers",
"sensitive" => "as:sensitive",
"Hashtag" => "as:Hashtag",
"toot" => "http://joinmastodon.org/ns#",
"Emoji" => "toot:Emoji"
}
]
}
alias Mobilizon.Service.ActivityPub.Utils
def render("event.json", %{event: event}) do
event = %{
@@ -24,29 +11,36 @@ defmodule MobilizonWeb.ActivityPub.ObjectView do
"name" => event.title,
"category" => render_one(event.category, ObjectView, "category.json", as: :category),
"content" => event.description,
"mediaType" => "text/markdown",
"mediaType" => "text/html",
"published" => Timex.format!(event.inserted_at, "{ISO:Extended}"),
"updated" => Timex.format!(event.updated_at, "{ISO:Extended}")
}
Map.merge(event, @base)
Map.merge(event, Utils.make_json_ld_header())
end
def render("note.json", %{note: note}) do
event = %{
def render("comment.json", %{comment: comment}) do
comment = %{
"actor" => comment.actor.url,
"uuid" => comment.uuid,
# The activity should have attributedTo, not the comment itself
# "attributedTo" => comment.attributed_to,
"type" => "Note",
"id" => note.url,
"content" => note.text,
"mediaType" => "text/markdown",
"published" => Timex.format!(note.inserted_at, "{ISO:Extended}"),
"updated" => Timex.format!(note.updated_at, "{ISO:Extended}")
"id" => comment.url,
"content" => comment.text,
"mediaType" => "text/html",
"published" => Timex.format!(comment.inserted_at, "{ISO:Extended}"),
"updated" => Timex.format!(comment.updated_at, "{ISO:Extended}")
}
Map.merge(event, @base)
Map.merge(comment, Utils.make_json_ld_header())
end
def render("category.json", %{category: category}) do
%{"title" => category.title}
%{
"identifier" => category.id,
"name" => category.title
}
end
def render("category.json", %{category: nil}) do