diff --git a/lib/pleroma/web/activity_pub/activity_pub.ex b/lib/pleroma/web/activity_pub/activity_pub.ex index b6a2d6c5e..8e15fde4a 100644 --- a/lib/pleroma/web/activity_pub/activity_pub.ex +++ b/lib/pleroma/web/activity_pub/activity_pub.ex @@ -1,5 +1,6 @@ defmodule Pleroma.Web.ActivityPub.ActivityPub do alias Pleroma.{Activity, Repo, Object, Upload, User, Notification} + alias Pleroma.Web.ActivityPub.Transmogrifier import Ecto.Query import Pleroma.Web.ActivityPub.Utils require Logger @@ -242,15 +243,9 @@ def make_user_from_ap_id(ap_id) do end end - # TODO: Extract to own module, align as close to Mastodon format as possible. - def sanitize_outgoing_activity_data(data) do - data - |> Map.put("@context", "https://www.w3.org/ns/activitystreams") - end - def publish(actor, activity) do remote_users = Pleroma.Web.Salmon.remote_users(activity) - data = sanitize_outgoing_activity_data(activity.data) + {:ok, data} = Transmogrifier.prepare_outgoing(activity.data) Enum.each remote_users, fn(user) -> if user.info["ap_enabled"] do inbox = user.info["source_data"]["inbox"] diff --git a/lib/pleroma/web/activity_pub/transmogrifier.ex b/lib/pleroma/web/activity_pub/transmogrifier.ex index 3e302f5b2..74d25786f 100644 --- a/lib/pleroma/web/activity_pub/transmogrifier.ex +++ b/lib/pleroma/web/activity_pub/transmogrifier.ex @@ -38,7 +38,38 @@ def handle_incoming(%{"type" => "Create", "object" => %{"type" => "Note"} = obje end end - def prepare_incoming(_) do - :error + @doc + """ + internal -> Mastodon + """ + def prepare_outgoing(%{"type" => "Create", "object" => %{"type" => "Note"} = object} = data) do + object = object + |> add_mention_tags + |> add_attributed_to + + data = data + |> Map.put("object", object) + |> Map.put("@context", "https://www.w3.org/ns/activitystreams") + + {:ok, data} + end + + def add_mention_tags(object) do + mentions = object["to"] + |> Enum.map(fn (ap_id) -> User.get_cached_by_ap_id(ap_id) end) + |> Enum.filter(&(&1)) + |> Enum.map(fn(user) -> %{"type" => "mention", "href" => user.ap_id, "name" => "@#{user.nickname}"} end) + + tags = object["tags"] || [] + + object + |> Map.put("tags", tags ++ mentions) + end + + def add_attributed_to(object) do + attributedTo = object["attributedTo"] || object["actor"] + + object + |> Map.put("attributedTo", attributedTo) end end diff --git a/lib/pleroma/web/common_api/common_api.ex b/lib/pleroma/web/common_api/common_api.ex index f3060bd89..bc1bb1892 100644 --- a/lib/pleroma/web/common_api/common_api.ex +++ b/lib/pleroma/web/common_api/common_api.ex @@ -61,7 +61,7 @@ def post(user, %{"status" => status} = data) do cw <- data["spoiler_text"], object <- make_note_data(user.ap_id, to, context, content_html, attachments, inReplyTo, tags, cw), object <- Map.put(object, "emoji", Formatter.get_emoji(status) |> Enum.reduce(%{}, fn({name, file}, acc) -> Map.put(acc, name, "#{Pleroma.Web.Endpoint.static_url}#{file}") end)) do - res = ActivityPub.create(%{to: to, actor: user, context: context, object: object}) + res = ActivityPub.create(%{to: to, actor: user, context: context, object: object, additional: %{"cc" => to}}) User.increase_note_count(user) res end diff --git a/test/web/activity_pub/transmogrifier_test.exs b/test/web/activity_pub/transmogrifier_test.exs index 269429359..76dc6d4ad 100644 --- a/test/web/activity_pub/transmogrifier_test.exs +++ b/test/web/activity_pub/transmogrifier_test.exs @@ -2,6 +2,8 @@ defmodule Pleroma.Web.ActivityPub.TransmogrifierTest do use Pleroma.DataCase alias Pleroma.Web.ActivityPub.Transmogrifier alias Pleroma.Activity + import Pleroma.Factory + alias Pleroma.Web.CommonAPI describe "handle_incoming" do test "it works for incoming notices" do @@ -29,4 +31,42 @@ test "it works for incoming notices" do assert object["attributedTo"] == "http://mastodon.example.org/users/admin" end end + + describe "prepare outgoing" do + test "it turns mentions into tags" do + user = insert(:user) + other_user = insert(:user) + + {:ok, activity} = CommonAPI.post(user, %{"status" => "hey, @#{other_user.nickname}, how are ya?"}) + + {:ok, modified} = Transmogrifier.prepare_outgoing(activity.data) + object = modified["object"] + + expected_tag = %{ + "href" => other_user.ap_id, + "name" => "@#{other_user.nickname}", + "type" => "mention" + } + + assert Enum.member?(object["tags"], expected_tag) + end + + test "it adds the json-ld context" do + user = insert(:user) + + {:ok, activity} = CommonAPI.post(user, %{"status" => "hey"}) + {:ok, modified} = Transmogrifier.prepare_outgoing(activity.data) + + assert modified["@context"] == "https://www.w3.org/ns/activitystreams" + end + + test "it sets the 'attributedTo' property to the actor of the object if it doesn't have one" do + user = insert(:user) + + {:ok, activity} = CommonAPI.post(user, %{"status" => "hey"}) + {:ok, modified} = Transmogrifier.prepare_outgoing(activity.data) + + assert modified["object"]["actor"] == modified["object"]["attributedTo"] + end + end end