aboutsummaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
Diffstat (limited to 'lib')
-rw-r--r--lib/pleroma/activity.ex6
-rw-r--r--lib/pleroma/user.ex4
-rw-r--r--lib/pleroma/web/activity_pub/activity_pub_controller.ex11
-rw-r--r--lib/pleroma/web/activity_pub/transmogrifier.ex2
-rw-r--r--lib/pleroma/web/activity_pub/utils.ex42
-rw-r--r--lib/pleroma/web/mastodon_api/mastodon_api_controller.ex31
-rw-r--r--lib/pleroma/web/mastodon_api/views/status_view.ex5
-rw-r--r--lib/pleroma/web/twitter_api/representers/activity_representer.ex8
-rw-r--r--lib/pleroma/web/twitter_api/views/activity_view.ex8
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,