From 5599c5920c293ac993146e21a73520213bbe2a8a Mon Sep 17 00:00:00 2001 From: Roger Braun Date: Mon, 11 Dec 2017 10:37:22 +0100 Subject: [PATCH] Basic incoming AP support. --- config/config.exs | 3 +- .../activity_pub/activity_pub_controller.ex | 17 +++++++ .../web/activity_pub/views/user_view.ex | 51 +++++++++++++++++++ lib/pleroma/web/ostatus/ostatus_controller.ex | 4 +- lib/pleroma/web/router.ex | 10 +++- 5 files changed, 82 insertions(+), 3 deletions(-) create mode 100644 lib/pleroma/web/activity_pub/activity_pub_controller.ex create mode 100644 lib/pleroma/web/activity_pub/views/user_view.ex diff --git a/config/config.exs b/config/config.exs index c4f89c40c..f26f9ecdf 100644 --- a/config/config.exs +++ b/config/config.exs @@ -27,7 +27,8 @@ metadata: [:request_id] config :mime, :types, %{ - "application/xrd+xml" => ["xrd+xml"] + "application/xrd+xml" => ["xrd+xml"], + "application/activity+json" => ["activity+json"] } config :pleroma, :websub, Pleroma.Web.Websub diff --git a/lib/pleroma/web/activity_pub/activity_pub_controller.ex b/lib/pleroma/web/activity_pub/activity_pub_controller.ex new file mode 100644 index 000000000..738e4ba33 --- /dev/null +++ b/lib/pleroma/web/activity_pub/activity_pub_controller.ex @@ -0,0 +1,17 @@ +defmodule Pleroma.Web.ActivityPub.ActivityPubController do + use Pleroma.Web, :controller + alias Pleroma.{User, Repo} + alias Pleroma.Web.ActivityPub.UserView + alias Pleroma.Web.ActivityPub.ActivityPub + + def user(conn, %{"nickname" => nickname}) do + with %User{} = user <- User.get_cached_by_nickname(nickname) do + json(conn, UserView.render("user.json", %{user: user})) + end + end + + def inbox(conn, params) do + {:ok, activity} = ActivityPub.insert(params, false) + json(conn, "ok") + end +end diff --git a/lib/pleroma/web/activity_pub/views/user_view.ex b/lib/pleroma/web/activity_pub/views/user_view.ex new file mode 100644 index 000000000..5303455a8 --- /dev/null +++ b/lib/pleroma/web/activity_pub/views/user_view.ex @@ -0,0 +1,51 @@ +defmodule Pleroma.Web.ActivityPub.UserView do + use Pleroma.Web, :view + alias Pleroma.Web.Salmon + alias Pleroma.User + + def render("user.json", %{user: user}) do + {:ok, _, public_key} = Salmon.keys_from_pem(user.info["keys"]) + public_key = :public_key.pem_entry_encode(:RSAPublicKey, public_key) + public_key = :public_key.pem_encode([public_key]) + %{ + "@context": [ + "https://www.w3.org/ns/activitystreams", + "https://w3id.org/security/v1", + %{ + "manuallyApprovesFollowers": "as:manuallyApprovesFollowers", + "sensitive": "as:sensitive", + "Hashtag": "as:Hashtag", + "ostatus": "http://ostatus.org#", + "atomUri": "ostatus:atomUri", + "inReplyToAtomUri": "ostatus:inReplyToAtomUri", + "conversation": "ostatus:conversation", + "toot": "http://joinmastodon.org/ns#", + "Emoji": "toot:Emoji" + } + ], + "id": user.ap_id, + "type": "Person", + "following": "#{user.ap_id}/following", + "followers": "#{user.ap_id}/followers", + "inbox": "#{user.ap_id}/inbox", + "outbox": "#{user.ap_id}/outbox", + "preferredUsername": user.nickname, + "name": user.name, + "summary": user.bio, + "url": user.ap_id, + "manuallyApprovesFollowers": false, + "publicKey": %{ + "id": "#{user.ap_id}#main-key", + "owner": user.ap_id, + "publicKeyPem": public_key + }, + "endpoints": %{ + "sharedInbox": "#{Pleroma.Web.Endpoint.url}/inbox" + }, + "icon": %{ + "type": "Image", + "url": User.avatar_url(user) + } + } + end +end diff --git a/lib/pleroma/web/ostatus/ostatus_controller.ex b/lib/pleroma/web/ostatus/ostatus_controller.ex index d442d16fd..778495a3e 100644 --- a/lib/pleroma/web/ostatus/ostatus_controller.ex +++ b/lib/pleroma/web/ostatus/ostatus_controller.ex @@ -6,13 +6,15 @@ defmodule Pleroma.Web.OStatus.OStatusController do alias Pleroma.Repo alias Pleroma.Web.{OStatus, Federator} alias Pleroma.Web.XML + alias Pleroma.Web.ActivityPub.ActivityPubController import Ecto.Query - def feed_redirect(conn, %{"nickname" => nickname}) do + def feed_redirect(conn, %{"nickname" => nickname} = params) do user = User.get_cached_by_nickname(nickname) case get_format(conn) do "html" -> Fallback.RedirectController.redirector(conn, nil) + "activity+json" -> ActivityPubController.user(conn, params) _ -> redirect conn, external: OStatus.feed_path(user) end end diff --git a/lib/pleroma/web/router.ex b/lib/pleroma/web/router.ex index 6806e8a75..4803a6370 100644 --- a/lib/pleroma/web/router.ex +++ b/lib/pleroma/web/router.ex @@ -199,7 +199,7 @@ def user_fetcher(username) do end pipeline :ostatus do - plug :accepts, ["xml", "atom", "html"] + plug :accepts, ["xml", "atom", "html", "activity+json"] end scope "/", Pleroma.Web do @@ -217,6 +217,14 @@ def user_fetcher(username) do post "/push/subscriptions/:id", Websub.WebsubController, :websub_incoming end + pipeline :activitypub do + plug :accepts, ["activity+json"] + end + + scope "/", Pleroma.Web.ActivityPub do + post "/users/:nickname/inbox", ActivityPubController, :inbox + end + scope "/.well-known", Pleroma.Web do pipe_through :well_known