diff options
Diffstat (limited to 'lib')
-rw-r--r-- | lib/pleroma/activity.ex | 6 | ||||
-rw-r--r-- | lib/pleroma/user.ex | 4 | ||||
-rw-r--r-- | lib/pleroma/web/activity_pub/activity_pub_controller.ex | 11 | ||||
-rw-r--r-- | lib/pleroma/web/activity_pub/transmogrifier.ex | 2 | ||||
-rw-r--r-- | lib/pleroma/web/activity_pub/utils.ex | 42 | ||||
-rw-r--r-- | lib/pleroma/web/mastodon_api/mastodon_api_controller.ex | 31 | ||||
-rw-r--r-- | lib/pleroma/web/mastodon_api/views/status_view.ex | 5 | ||||
-rw-r--r-- | lib/pleroma/web/twitter_api/representers/activity_representer.ex | 8 | ||||
-rw-r--r-- | lib/pleroma/web/twitter_api/views/activity_view.ex | 8 |
9 files changed, 110 insertions, 7 deletions
diff --git a/lib/pleroma/activity.ex b/lib/pleroma/activity.ex index bed96861f..c065f3b6c 100644 --- a/lib/pleroma/activity.ex +++ b/lib/pleroma/activity.ex @@ -82,4 +82,10 @@ defmodule Pleroma.Activity do def normalize(obj) when is_map(obj), do: Activity.get_by_ap_id(obj["id"]) def normalize(ap_id) when is_binary(ap_id), do: Activity.get_by_ap_id(ap_id) def normalize(_), do: nil + + def get_in_reply_to_activity(%Activity{data: %{"object" => %{"inReplyTo" => ap_id}}}) do + get_create_activity_by_object_ap_id(ap_id) + end + + def get_in_reply_to_activity(_), do: nil end diff --git a/lib/pleroma/user.ex b/lib/pleroma/user.ex index e97224731..0c9fa559a 100644 --- a/lib/pleroma/user.ex +++ b/lib/pleroma/user.ex @@ -42,6 +42,10 @@ defmodule Pleroma.User do end end + def profile_url(%User{info: %{"source_data" => %{"url" => url}}}), do: url + def profile_url(%User{ap_id: ap_id}), do: ap_id + def profile_url(_), do: nil + def ap_id(%User{nickname: nickname}) do "#{Web.base_url()}/users/#{nickname}" end diff --git a/lib/pleroma/web/activity_pub/activity_pub_controller.ex b/lib/pleroma/web/activity_pub/activity_pub_controller.ex index 2750add8b..a7b1c0079 100644 --- a/lib/pleroma/web/activity_pub/activity_pub_controller.ex +++ b/lib/pleroma/web/activity_pub/activity_pub_controller.ex @@ -4,6 +4,7 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubController do alias Pleroma.Web.ActivityPub.{ObjectView, UserView} alias Pleroma.Web.ActivityPub.ActivityPub alias Pleroma.Web.ActivityPub.Relay + alias Pleroma.Web.ActivityPub.Utils alias Pleroma.Web.Federator require Logger @@ -87,7 +88,15 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubController do outbox(conn, %{"nickname" => nickname, "max_id" => nil}) end - # TODO: Ensure that this inbox is a recipient of the message + def inbox(%{assigns: %{valid_signature: true}} = conn, %{"nickname" => nickname} = params) do + with %User{} = user <- User.get_cached_by_nickname(nickname), + true <- Utils.recipient_in_message(user.ap_id, params), + params <- Utils.maybe_splice_recipient(user.ap_id, params) do + Federator.enqueue(:incoming_ap_doc, params) + json(conn, "ok") + end + end + def inbox(%{assigns: %{valid_signature: true}} = conn, params) do Federator.enqueue(:incoming_ap_doc, params) json(conn, "ok") diff --git a/lib/pleroma/web/activity_pub/transmogrifier.ex b/lib/pleroma/web/activity_pub/transmogrifier.ex index 65ac07845..cbc800ad6 100644 --- a/lib/pleroma/web/activity_pub/transmogrifier.ex +++ b/lib/pleroma/web/activity_pub/transmogrifier.ex @@ -37,6 +37,8 @@ defmodule Pleroma.Web.ActivityPub.Transmogrifier do @doc """ Checks that an imported AP object's actor matches the domain it came from. """ + def contain_origin(id, %{"actor" => nil}), do: :error + def contain_origin(id, %{"actor" => actor} = params) do id_uri = URI.parse(id) actor_uri = URI.parse(get_actor(params)) diff --git a/lib/pleroma/web/activity_pub/utils.ex b/lib/pleroma/web/activity_pub/utils.ex index 43a1f432d..266667f81 100644 --- a/lib/pleroma/web/activity_pub/utils.ex +++ b/lib/pleroma/web/activity_pub/utils.ex @@ -19,6 +19,48 @@ defmodule Pleroma.Web.ActivityPub.Utils do Map.put(params, "actor", get_ap_id(params["actor"])) end + defp recipient_in_collection(ap_id, coll) when is_binary(coll), do: ap_id == coll + defp recipient_in_collection(ap_id, coll) when is_list(coll), do: ap_id in coll + defp recipient_in_collection(_, _), do: false + + def recipient_in_message(ap_id, params) do + cond do + recipient_in_collection(ap_id, params["to"]) -> + true + + recipient_in_collection(ap_id, params["cc"]) -> + true + + recipient_in_collection(ap_id, params["bto"]) -> + true + + recipient_in_collection(ap_id, params["bcc"]) -> + true + + true -> + false + end + end + + defp extract_list(target) when is_binary(target), do: [target] + defp extract_list(lst) when is_list(lst), do: lst + defp extract_list(_), do: [] + + def maybe_splice_recipient(ap_id, params) do + need_splice = + !recipient_in_collection(ap_id, params["to"]) && + !recipient_in_collection(ap_id, params["cc"]) + + cc_list = extract_list(params["cc"]) + + if need_splice do + params + |> Map.put("cc", [ap_id | cc_list]) + else + params + end + end + def make_json_ld_header do %{ "@context" => [ diff --git a/lib/pleroma/web/mastodon_api/mastodon_api_controller.ex b/lib/pleroma/web/mastodon_api/mastodon_api_controller.ex index cbda069df..751698ca8 100644 --- a/lib/pleroma/web/mastodon_api/mastodon_api_controller.ex +++ b/lib/pleroma/web/mastodon_api/mastodon_api_controller.ex @@ -282,7 +282,7 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIController do def get_status(%{assigns: %{user: user}} = conn, %{"id" => id}) do with %Activity{} = activity <- Repo.get(Activity, id), true <- ActivityPub.visible_for_user?(activity, user) do - render(conn, StatusView, "status.json", %{activity: activity, for: user}) + try_render(conn, StatusView, "status.json", %{activity: activity, for: user}) end end @@ -345,7 +345,7 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIController do {:ok, activity} = Cachex.fetch!(:idempotency_cache, idempotency_key, fn _ -> CommonAPI.post(user, params) end) - render(conn, StatusView, "status.json", %{activity: activity, for: user, as: :activity}) + try_render(conn, StatusView, "status.json", %{activity: activity, for: user, as: :activity}) end def delete_status(%{assigns: %{user: user}} = conn, %{"id" => id}) do @@ -361,28 +361,28 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIController do def reblog_status(%{assigns: %{user: user}} = conn, %{"id" => ap_id_or_id}) do with {:ok, announce, _activity} <- CommonAPI.repeat(ap_id_or_id, user) do - render(conn, StatusView, "status.json", %{activity: announce, for: user, as: :activity}) + try_render(conn, StatusView, "status.json", %{activity: announce, for: user, as: :activity}) end end def unreblog_status(%{assigns: %{user: user}} = conn, %{"id" => ap_id_or_id}) do with {:ok, _unannounce, %{data: %{"id" => id}}} <- CommonAPI.unrepeat(ap_id_or_id, user), %Activity{} = activity <- Activity.get_create_activity_by_object_ap_id(id) do - render(conn, StatusView, "status.json", %{activity: activity, for: user, as: :activity}) + try_render(conn, StatusView, "status.json", %{activity: activity, for: user, as: :activity}) end end def fav_status(%{assigns: %{user: user}} = conn, %{"id" => ap_id_or_id}) do with {:ok, _fav, %{data: %{"id" => id}}} <- CommonAPI.favorite(ap_id_or_id, user), %Activity{} = activity <- Activity.get_create_activity_by_object_ap_id(id) do - render(conn, StatusView, "status.json", %{activity: activity, for: user, as: :activity}) + try_render(conn, StatusView, "status.json", %{activity: activity, for: user, as: :activity}) end end def unfav_status(%{assigns: %{user: user}} = conn, %{"id" => ap_id_or_id}) do with {:ok, _, _, %{data: %{"id" => id}}} <- CommonAPI.unfavorite(ap_id_or_id, user), %Activity{} = activity <- Activity.get_create_activity_by_object_ap_id(id) do - render(conn, StatusView, "status.json", %{activity: activity, for: user, as: :activity}) + try_render(conn, StatusView, "status.json", %{activity: activity, for: user, as: :activity}) end end @@ -1202,4 +1202,23 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIController do json(conn, []) end end + + def try_render(conn, renderer, target, params) + when is_binary(target) do + res = render(conn, renderer, target, params) + + if res == nil do + conn + |> put_status(501) + |> json(%{error: "Can't display this activity"}) + else + res + end + end + + def try_render(conn, _, _, _) do + conn + |> put_status(501) + |> json(%{error: "Can't display this activity"}) + end end diff --git a/lib/pleroma/web/mastodon_api/views/status_view.ex b/lib/pleroma/web/mastodon_api/views/status_view.ex index ef46ba4fc..8ffaf8466 100644 --- a/lib/pleroma/web/mastodon_api/views/status_view.ex +++ b/lib/pleroma/web/mastodon_api/views/status_view.ex @@ -34,6 +34,7 @@ defmodule Pleroma.Web.MastodonAPI.StatusView do "status.json", Map.put(opts, :replied_to_activities, replied_to_activities) ) + |> Enum.filter(fn x -> not is_nil(x) end) end def render( @@ -158,6 +159,10 @@ defmodule Pleroma.Web.MastodonAPI.StatusView do } end + def render("status.json", _) do + nil + end + def render("attachment.json", %{attachment: attachment}) do [attachment_url | _] = attachment["url"] media_type = attachment_url["mediaType"] || attachment_url["mimeType"] || "image" diff --git a/lib/pleroma/web/twitter_api/representers/activity_representer.ex b/lib/pleroma/web/twitter_api/representers/activity_representer.ex index b21bbb205..fbd33f07e 100644 --- a/lib/pleroma/web/twitter_api/representers/activity_representer.ex +++ b/lib/pleroma/web/twitter_api/representers/activity_representer.ex @@ -180,6 +180,10 @@ defmodule Pleroma.Web.TwitterAPI.Representers.ActivityRepresenter do attachments = (object["attachment"] || []) ++ video + reply_parent = Activity.get_in_reply_to_activity(activity) + + reply_user = reply_parent && User.get_cached_by_ap_id(reply_parent.actor) + %{ "id" => activity.id, "uri" => activity.data["object"]["id"], @@ -190,6 +194,10 @@ defmodule Pleroma.Web.TwitterAPI.Representers.ActivityRepresenter do "is_post_verb" => true, "created_at" => created_at, "in_reply_to_status_id" => object["inReplyToStatusId"], + "in_reply_to_screen_name" => reply_user && reply_user.nickname, + "in_reply_to_profileurl" => User.profile_url(reply_user), + "in_reply_to_ostatus_uri" => reply_user && reply_user.ap_id, + "in_reply_to_user_id" => reply_user && reply_user.id, "statusnet_conversation_id" => conversation_id, "attachments" => attachments |> ObjectRepresenter.enum_to_list(opts), "attentions" => attentions, diff --git a/lib/pleroma/web/twitter_api/views/activity_view.ex b/lib/pleroma/web/twitter_api/views/activity_view.ex index b9fd062d6..fb97f199b 100644 --- a/lib/pleroma/web/twitter_api/views/activity_view.ex +++ b/lib/pleroma/web/twitter_api/views/activity_view.ex @@ -236,6 +236,10 @@ defmodule Pleroma.Web.TwitterAPI.ActivityView do HTML.filter_tags(content, User.html_filter_policy(opts[:for])) |> Formatter.emojify(object["emoji"]) + reply_parent = Activity.get_in_reply_to_activity(activity) + + reply_user = reply_parent && User.get_cached_by_ap_id(reply_parent.actor) + %{ "id" => activity.id, "uri" => activity.data["object"]["id"], @@ -246,6 +250,10 @@ defmodule Pleroma.Web.TwitterAPI.ActivityView do "is_post_verb" => true, "created_at" => created_at, "in_reply_to_status_id" => object["inReplyToStatusId"], + "in_reply_to_screen_name" => reply_user && reply_user.nickname, + "in_reply_to_profileurl" => User.profile_url(reply_user), + "in_reply_to_ostatus_uri" => reply_user && reply_user.ap_id, + "in_reply_to_user_id" => reply_user && reply_user.id, "statusnet_conversation_id" => conversation_id, "attachments" => (object["attachment"] || []) |> ObjectRepresenter.enum_to_list(opts), "attentions" => attentions, |