1 defmodule Pleroma.Web.ActivityPub.ActivityPubController do
2 use Pleroma.Web, :controller
3 alias Pleroma.{User, Object}
4 alias Pleroma.Web.ActivityPub.{ObjectView, UserView}
5 alias Pleroma.Web.ActivityPub.ActivityPub
6 alias Pleroma.Web.ActivityPub.Relay
7 alias Pleroma.Web.ActivityPub.Utils
8 alias Pleroma.Web.Federator
12 action_fallback(:errors)
14 def user(conn, %{"nickname" => nickname}) do
15 with %User{} = user <- User.get_cached_by_nickname(nickname),
16 {:ok, user} <- Pleroma.Web.WebFinger.ensure_keys_present(user) do
18 |> put_resp_header("content-type", "application/activity+json")
19 |> json(UserView.render("user.json", %{user: user}))
21 nil -> {:error, :not_found}
25 def object(conn, %{"uuid" => uuid}) do
26 with ap_id <- o_status_url(conn, :object, uuid),
27 %Object{} = object <- Object.get_cached_by_ap_id(ap_id),
28 {_, true} <- {:public?, ActivityPub.is_public?(object)} do
30 |> put_resp_header("content-type", "application/activity+json")
31 |> json(ObjectView.render("object.json", %{object: object}))
38 def following(conn, %{"nickname" => nickname, "page" => page}) do
39 with %User{} = user <- User.get_cached_by_nickname(nickname),
40 {:ok, user} <- Pleroma.Web.WebFinger.ensure_keys_present(user) do
41 {page, _} = Integer.parse(page)
44 |> put_resp_header("content-type", "application/activity+json")
45 |> json(UserView.render("following.json", %{user: user, page: page}))
49 def following(conn, %{"nickname" => nickname}) do
50 with %User{} = user <- User.get_cached_by_nickname(nickname),
51 {:ok, user} <- Pleroma.Web.WebFinger.ensure_keys_present(user) do
53 |> put_resp_header("content-type", "application/activity+json")
54 |> json(UserView.render("following.json", %{user: user}))
58 def followers(conn, %{"nickname" => nickname, "page" => page}) do
59 with %User{} = user <- User.get_cached_by_nickname(nickname),
60 {:ok, user} <- Pleroma.Web.WebFinger.ensure_keys_present(user) do
61 {page, _} = Integer.parse(page)
64 |> put_resp_header("content-type", "application/activity+json")
65 |> json(UserView.render("followers.json", %{user: user, page: page}))
69 def followers(conn, %{"nickname" => nickname}) do
70 with %User{} = user <- User.get_cached_by_nickname(nickname),
71 {:ok, user} <- Pleroma.Web.WebFinger.ensure_keys_present(user) do
73 |> put_resp_header("content-type", "application/activity+json")
74 |> json(UserView.render("followers.json", %{user: user}))
78 def outbox(conn, %{"nickname" => nickname, "max_id" => max_id}) do
79 with %User{} = user <- User.get_cached_by_nickname(nickname),
80 {:ok, user} <- Pleroma.Web.WebFinger.ensure_keys_present(user) do
82 |> put_resp_header("content-type", "application/activity+json")
83 |> json(UserView.render("outbox.json", %{user: user, max_id: max_id}))
87 def outbox(conn, %{"nickname" => nickname}) do
88 outbox(conn, %{"nickname" => nickname, "max_id" => nil})
91 def inbox(%{assigns: %{valid_signature: true}} = conn, %{"nickname" => nickname} = params) do
92 with %User{} = user <- User.get_cached_by_nickname(nickname),
93 true <- Utils.recipient_in_message(user.ap_id, params),
94 params <- Utils.maybe_splice_recipient(user.ap_id, params) do
95 Federator.enqueue(:incoming_ap_doc, params)
100 def inbox(%{assigns: %{valid_signature: true}} = conn, params) do
101 Federator.enqueue(:incoming_ap_doc, params)
105 # only accept relayed Creates
106 def inbox(conn, %{"type" => "Create"} = params) do
108 "Signature missing or not from author, relayed Create message, fetching object from source"
111 ActivityPub.fetch_object_from_id(params["object"]["id"])
116 def inbox(conn, params) do
117 headers = Enum.into(conn.req_headers, %{})
119 if String.contains?(headers["signature"], params["actor"]) do
121 "Signature validation error for: #{params["actor"]}, make sure you are forwarding the HTTP Host header!"
124 Logger.info(inspect(conn.req_headers))
130 def relay(conn, params) do
131 with %User{} = user <- Relay.get_actor(),
132 {:ok, user} <- Pleroma.Web.WebFinger.ensure_keys_present(user) do
134 |> put_resp_header("content-type", "application/activity+json")
135 |> json(UserView.render("user.json", %{user: user}))
137 nil -> {:error, :not_found}
141 def errors(conn, {:error, :not_found}) do
147 def errors(conn, _e) do