diff options
Diffstat (limited to 'lib/pleroma/web')
-rw-r--r-- | lib/pleroma/web/activity_pub/activity_pub_controller.ex | 31 | ||||
-rw-r--r-- | lib/pleroma/web/activity_pub/views/user_view.ex | 57 | ||||
-rw-r--r-- | lib/pleroma/web/router.ex | 1 |
3 files changed, 69 insertions, 20 deletions
diff --git a/lib/pleroma/web/activity_pub/activity_pub_controller.ex b/lib/pleroma/web/activity_pub/activity_pub_controller.ex index 732c44271..07692221a 100644 --- a/lib/pleroma/web/activity_pub/activity_pub_controller.ex +++ b/lib/pleroma/web/activity_pub/activity_pub_controller.ex @@ -42,7 +42,7 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubController do # Note: :following and :followers must be served even without authentication (as via :api) plug( EnsureAuthenticatedPlug - when action in [:read_inbox, :update_outbox, :whoami, :upload_media] + when action in [:read_inbox, :update_outbox, :whoami, :upload_media, :proxy_url] ) plug( @@ -550,4 +550,33 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubController do |> json(object.data) end end + + def proxy_url(%{assigns: %{user: %User{}}} = conn, %{"id" => id}) when is_binary(id) do + cond do + object = Object.normalize(id, true) -> + conn + |> maybe_set_tracking_data(object) + |> set_cache_ttl_for(object) + |> put_resp_content_type("application/activity+json") + |> put_view(ObjectView) + |> render("object.json", object: object) + + object = Activity.get_by_ap_id_with_object(id) -> + conn + |> maybe_set_tracking_data(object) + |> set_cache_ttl_for(object) + |> put_resp_content_type("application/activity+json") + |> put_view(ObjectView) + |> render("object.json", object: object) + + user = User.get_or_fetch_by_ap_id!(id) -> + conn + |> put_resp_content_type("application/activity+json") + |> put_view(UserView) + |> render("user.json", %{user: user}) + + true -> + {:error, :not_found} + end + end end diff --git a/lib/pleroma/web/activity_pub/views/user_view.ex b/lib/pleroma/web/activity_pub/views/user_view.ex index 3a4564912..715dc4c62 100644 --- a/lib/pleroma/web/activity_pub/views/user_view.ex +++ b/lib/pleroma/web/activity_pub/views/user_view.ex @@ -6,6 +6,7 @@ defmodule Pleroma.Web.ActivityPub.UserView do use Pleroma.Web, :view alias Pleroma.Keys + alias Pleroma.Maps alias Pleroma.Repo alias Pleroma.User alias Pleroma.Web.ActivityPub.Transmogrifier @@ -15,21 +16,27 @@ defmodule Pleroma.Web.ActivityPub.UserView do import Ecto.Query - def render("endpoints.json", %{user: %User{nickname: nil, local: true} = _user}) do + def render("endpoints.json", %{user: %User{nickname: nil, local: true}}) do %{"sharedInbox" => Helpers.activity_pub_url(Endpoint, :inbox)} end - def render("endpoints.json", %{user: %User{local: true} = _user}) do + def render("endpoints.json", %{user: %User{local: true}}) do %{ "oauthAuthorizationEndpoint" => Helpers.o_auth_url(Endpoint, :authorize), "oauthRegistrationEndpoint" => Helpers.app_url(Endpoint, :create), "oauthTokenEndpoint" => Helpers.o_auth_url(Endpoint, :token_exchange), "sharedInbox" => Helpers.activity_pub_url(Endpoint, :inbox), - "uploadMedia" => Helpers.activity_pub_url(Endpoint, :upload_media) + "uploadMedia" => Helpers.activity_pub_url(Endpoint, :upload_media), + "proxyUrl" => Helpers.activity_pub_url(Endpoint, :proxy_url) } end - def render("endpoints.json", _), do: %{} + def render("endpoints.json", %{user: %User{shared_inbox: shared_inbox}}) + when is_binary(shared_inbox) do + %{"sharedInbox" => shared_inbox} + end + + def render("endpoints.json", _), do: nil def render("service.json", %{user: user}) do {:ok, user} = User.ensure_keys_present(user) @@ -59,6 +66,7 @@ defmodule Pleroma.Web.ActivityPub.UserView do "invisible" => User.invisible?(user) } |> Map.merge(Utils.make_json_ld_header()) + |> Maps.put_if_present("endpoints", endpoints) end # the instance itself is not a Person, but instead an Application @@ -68,11 +76,22 @@ defmodule Pleroma.Web.ActivityPub.UserView do def render("user.json", %{user: %User{nickname: "internal." <> _} = user}), do: render("service.json", %{user: user}) |> Map.put("preferredUsername", user.nickname) - def render("user.json", %{user: user}) do - {:ok, user} = User.ensure_keys_present(user) - {:ok, _, public_key} = Keys.keys_from_pem(user.keys) - public_key = :public_key.pem_entry_encode(:SubjectPublicKeyInfo, public_key) - public_key = :public_key.pem_encode([public_key]) + def render("user.json", %{user: %User{} = user}) do + public_key = + with {:ok, user} <- User.ensure_keys_present(user) do + {:ok, _, public_key} = Keys.keys_from_pem(user.keys) + public_key = :public_key.pem_entry_encode(:SubjectPublicKeyInfo, public_key) + public_key = :public_key.pem_encode([public_key]) + + %{ + "id" => "#{user.ap_id}#main-key", + "owner" => user.ap_id, + "publicKeyPem" => public_key + } + else + _ -> nil + end + user = User.sanitize_html(user) endpoints = render("endpoints.json", %{user: user}) @@ -90,24 +109,22 @@ defmodule Pleroma.Web.ActivityPub.UserView do %{} end + # FIXME: user.outbox + inbox = if user.local, do: "#{user.ap_id}/inbox", else: user.inbox + outbox = if user.local, do: "#{user.ap_id}/outbox", else: nil + %{ "id" => user.ap_id, "type" => user.actor_type, - "following" => "#{user.ap_id}/following", - "followers" => "#{user.ap_id}/followers", - "inbox" => "#{user.ap_id}/inbox", - "outbox" => "#{user.ap_id}/outbox", + "following" => User.ap_following(user), + "followers" => User.ap_followers(user), + "inbox" => inbox, + "outbox" => outbox, "preferredUsername" => user.nickname, "name" => user.name, "summary" => user.bio, "url" => user.ap_id, "manuallyApprovesFollowers" => user.locked, - "publicKey" => %{ - "id" => "#{user.ap_id}#main-key", - "owner" => user.ap_id, - "publicKeyPem" => public_key - }, - "endpoints" => endpoints, "attachment" => fields, "tag" => emoji_tags, "discoverable" => user.discoverable, @@ -116,6 +133,8 @@ defmodule Pleroma.Web.ActivityPub.UserView do |> Map.merge(maybe_make_image(&User.avatar_url/2, "icon", user)) |> Map.merge(maybe_make_image(&User.banner_url/2, "image", user)) |> Map.merge(Utils.make_json_ld_header()) + |> Maps.put_if_present("endpoints", endpoints) + |> Maps.put_if_present("publicKey", public_key) end def render("following.json", %{user: user, page: page} = opts) do diff --git a/lib/pleroma/web/router.ex b/lib/pleroma/web/router.ex index e22b31b4c..2a435c38c 100644 --- a/lib/pleroma/web/router.ex +++ b/lib/pleroma/web/router.ex @@ -625,6 +625,7 @@ defmodule Pleroma.Web.Router do get("/users/:nickname/outbox", ActivityPubController, :outbox) post("/users/:nickname/outbox", ActivityPubController, :update_outbox) post("/api/ap/upload_media", ActivityPubController, :upload_media) + post("/api/ap/proxy_url", ActivityPubController, :proxy_url) # The following two are S2S as well, see `ActivityPub.fetch_follow_information_for_user/1`: get("/users/:nickname/followers", ActivityPubController, :followers) |