From 144dc048b8c5f71b41f9f14b6cc4315de4dca707 Mon Sep 17 00:00:00 2001 From: William Pitcock Date: Thu, 8 Nov 2018 18:55:50 +0000 Subject: [PATCH 01/15] user: only consider `to` recipients as mention targets --- lib/pleroma/user.ex | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/lib/pleroma/user.ex b/lib/pleroma/user.ex index b2f59ab6b..0d11101a3 100644 --- a/lib/pleroma/user.ex +++ b/lib/pleroma/user.ex @@ -472,7 +472,7 @@ def get_notified_from_activity_query(to) do ) end - def get_notified_from_activity(%Activity{recipients: to, data: %{"type" => "Announce"} = data}) do + def get_notified_from_activity(%Activity{data: %{"type" => "Announce", "to" => to} = data}) do object = Object.normalize(data["object"]) actor = User.get_cached_by_ap_id(data["actor"]) @@ -490,12 +490,14 @@ def get_notified_from_activity(%Activity{recipients: to, data: %{"type" => "Anno Repo.all(query) end - def get_notified_from_activity(%Activity{recipients: to}) do + def get_notified_from_activity(%Activity{data: %{"to" => to}}) do query = get_notified_from_activity_query(to) Repo.all(query) end + def get_notified_from_activity(_), do: [] + def get_recipients_from_activity(%Activity{recipients: to}) do query = from( From 3e33479c05c315e04b0947136f1429c79c85c63c Mon Sep 17 00:00:00 2001 From: William Pitcock Date: Thu, 8 Nov 2018 18:56:14 +0000 Subject: [PATCH 02/15] activitypub: transmogrifier: only consider `to` users as mention targets --- lib/pleroma/web/activity_pub/transmogrifier.ex | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/pleroma/web/activity_pub/transmogrifier.ex b/lib/pleroma/web/activity_pub/transmogrifier.ex index a112d4ced..1471c9416 100644 --- a/lib/pleroma/web/activity_pub/transmogrifier.ex +++ b/lib/pleroma/web/activity_pub/transmogrifier.ex @@ -693,7 +693,7 @@ def add_hashtags(object) do end def add_mention_tags(object) do - recipients = object["to"] ++ (object["cc"] || []) + recipients = object["to"] || [] mentions = recipients From 4e93d6ae14fc2e4829769e58e66b6fb95e661e7f Mon Sep 17 00:00:00 2001 From: William Pitcock Date: Thu, 8 Nov 2018 19:17:01 +0000 Subject: [PATCH 03/15] common api: utils: flip to/cc for mentions --- lib/pleroma/web/common_api/utils.ex | 20 ++++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) diff --git a/lib/pleroma/web/common_api/utils.ex b/lib/pleroma/web/common_api/utils.ex index b22c4cc03..728f24c7e 100644 --- a/lib/pleroma/web/common_api/utils.ex +++ b/lib/pleroma/web/common_api/utils.ex @@ -34,21 +34,29 @@ def attachments_from_ids(ids) do end def to_for_user_and_mentions(user, mentions, inReplyTo, "public") do - to = ["https://www.w3.org/ns/activitystreams#Public"] - mentioned_users = Enum.map(mentions, fn {_, %{ap_id: ap_id}} -> ap_id end) - cc = [user.follower_address | mentioned_users] + + to = ["https://www.w3.org/ns/activitystreams#Public" | mentioned_users] + cc = [user.follower_address] if inReplyTo do - {to, Enum.uniq([inReplyTo.data["actor"] | cc])} + {Enum.uniq([inReplyTo.data["actor"] | to]), cc} else {to, cc} end end def to_for_user_and_mentions(user, mentions, inReplyTo, "unlisted") do - {to, cc} = to_for_user_and_mentions(user, mentions, inReplyTo, "public") - {cc, to} + mentioned_users = Enum.map(mentions, fn {_, %{ap_id: ap_id}} -> ap_id end) + + to = [user.follower_address | mentioned_users] + cc = ["https://www.w3.org/ns/activitystreams#Public"] + + if inReplyTo do + {Enum.uniq([inReplyTo.data["actor"] | to]), cc} + else + {to, cc} + end end def to_for_user_and_mentions(user, mentions, inReplyTo, "private") do From 719a8a1f826972a43b80f100d3cbe65e75891366 Mon Sep 17 00:00:00 2001 From: William Pitcock Date: Thu, 8 Nov 2018 19:17:15 +0000 Subject: [PATCH 04/15] tests: flip testing to/cc for mentions --- test/web/twitter_api/twitter_api_test.exs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/web/twitter_api/twitter_api_test.exs b/test/web/twitter_api/twitter_api_test.exs index 6486540f8..8b9920bd9 100644 --- a/test/web/twitter_api/twitter_api_test.exs +++ b/test/web/twitter_api/twitter_api_test.exs @@ -48,7 +48,7 @@ test "create a status" do "https://www.w3.org/ns/activitystreams#Public" ) - assert Enum.member?(get_in(activity.data, ["cc"]), "shp") + assert Enum.member?(get_in(activity.data, ["to"]), "shp") assert activity.local == true assert %{"moominmamma" => "http://localhost:4001/finmoji/128px/moominmamma-128.png"} = From 0a2c1a3419d6b5aaf078609063d355f3d6ea046a Mon Sep 17 00:00:00 2001 From: William Pitcock Date: Thu, 8 Nov 2018 19:30:55 +0000 Subject: [PATCH 05/15] user: add optional local_only param to get_notified_from_activity() --- lib/pleroma/user.ex | 24 +++++++++++++++++------- 1 file changed, 17 insertions(+), 7 deletions(-) diff --git a/lib/pleroma/user.ex b/lib/pleroma/user.ex index 0d11101a3..acb355a05 100644 --- a/lib/pleroma/user.ex +++ b/lib/pleroma/user.ex @@ -464,15 +464,25 @@ def update_follower_count(%User{} = user) do update_and_set_cache(cs) end - def get_notified_from_activity_query(to) do + def get_notified_from_activity_query(to, false) do from( u in User, - where: u.ap_id in ^to, + where: u.ap_id in ^to + ) + end + + def get_notified_from_activity_query(to, true) do + query = get_notified_from_activity_query(to, false) + + from( + u in query, where: u.local == true ) end - def get_notified_from_activity(%Activity{data: %{"type" => "Announce", "to" => to} = data}) do + def get_notified_from_activity(activity, local_only \\ true) + + def get_notified_from_activity(%Activity{data: %{"type" => "Announce", "to" => to} = data}, local_only) do object = Object.normalize(data["object"]) actor = User.get_cached_by_ap_id(data["actor"]) @@ -485,18 +495,18 @@ def get_notified_from_activity(%Activity{data: %{"type" => "Announce", "to" => t end |> Enum.uniq() - query = get_notified_from_activity_query(to) + query = get_notified_from_activity_query(to, local_only) Repo.all(query) end - def get_notified_from_activity(%Activity{data: %{"to" => to}}) do - query = get_notified_from_activity_query(to) + def get_notified_from_activity(%Activity{data: %{"to" => to}}, local_only) do + query = get_notified_from_activity_query(to, local_only) Repo.all(query) end - def get_notified_from_activity(_), do: [] + def get_notified_from_activity(_, _), do: [] def get_recipients_from_activity(%Activity{recipients: to}) do query = From 6b4064fa5ddd8396faf7d6afef891d70e7a2e881 Mon Sep 17 00:00:00 2001 From: William Pitcock Date: Thu, 8 Nov 2018 19:31:59 +0000 Subject: [PATCH 06/15] activitypub: transmogrifier: unify mention extraction --- lib/pleroma/user.ex | 5 ++++- lib/pleroma/web/activity_pub/transmogrifier.ex | 7 ++----- lib/pleroma/web/activity_pub/utils.ex | 4 ++++ 3 files changed, 10 insertions(+), 6 deletions(-) diff --git a/lib/pleroma/user.ex b/lib/pleroma/user.ex index acb355a05..260d904bc 100644 --- a/lib/pleroma/user.ex +++ b/lib/pleroma/user.ex @@ -482,7 +482,10 @@ def get_notified_from_activity_query(to, true) do def get_notified_from_activity(activity, local_only \\ true) - def get_notified_from_activity(%Activity{data: %{"type" => "Announce", "to" => to} = data}, local_only) do + def get_notified_from_activity( + %Activity{data: %{"type" => "Announce", "to" => to} = data}, + local_only + ) do object = Object.normalize(data["object"]) actor = User.get_cached_by_ap_id(data["actor"]) diff --git a/lib/pleroma/web/activity_pub/transmogrifier.ex b/lib/pleroma/web/activity_pub/transmogrifier.ex index 1471c9416..6a0fdb433 100644 --- a/lib/pleroma/web/activity_pub/transmogrifier.ex +++ b/lib/pleroma/web/activity_pub/transmogrifier.ex @@ -693,12 +693,9 @@ def add_hashtags(object) do end def add_mention_tags(object) do - recipients = object["to"] || [] - mentions = - recipients - |> Enum.map(fn ap_id -> User.get_cached_by_ap_id(ap_id) end) - |> Enum.filter(& &1) + object + |> Utils.get_notified_from_object() |> Enum.map(fn user -> %{"type" => "Mention", "href" => user.ap_id, "name" => "@#{user.nickname}"} end) diff --git a/lib/pleroma/web/activity_pub/utils.ex b/lib/pleroma/web/activity_pub/utils.ex index d81c824f0..fd9c5eb59 100644 --- a/lib/pleroma/web/activity_pub/utils.ex +++ b/lib/pleroma/web/activity_pub/utils.ex @@ -95,6 +95,10 @@ def generate_id(type) do "#{Web.base_url()}/#{type}/#{UUID.generate()}" end + def get_notified_from_object(object) do + User.get_notified_from_activity(%Activity{data: object}, false) + end + def create_context(context) do context = context || generate_id("contexts") changeset = Object.context_mapping(context) From 81d6ca17830538aea2815a0381f3a287d68c454f Mon Sep 17 00:00:00 2001 From: William Pitcock Date: Thu, 8 Nov 2018 20:01:42 +0000 Subject: [PATCH 07/15] user: implement AS2 mention extraction + unify Announce handling --- lib/pleroma/user.ex | 41 +++++++++++++++++++++++++---------------- 1 file changed, 25 insertions(+), 16 deletions(-) diff --git a/lib/pleroma/user.ex b/lib/pleroma/user.ex index 260d904bc..71bdbebee 100644 --- a/lib/pleroma/user.ex +++ b/lib/pleroma/user.ex @@ -482,20 +482,35 @@ def get_notified_from_activity_query(to, true) do def get_notified_from_activity(activity, local_only \\ true) - def get_notified_from_activity( - %Activity{data: %{"type" => "Announce", "to" => to} = data}, - local_only - ) do + def get_notified_from_activity(%Activity{data: %{"to" => to} = data}, local_only) do object = Object.normalize(data["object"]) - actor = User.get_cached_by_ap_id(data["actor"]) - # ensure that the actor who published the announced object appears only once - to = - if actor.nickname != nil do - to ++ [object.data["actor"]] + # somehow, get an AS2 object, preferring the normalized object if we have one + object_data = + if object do + object.data else - to + if is_map(data["object"]) do + data["object"] + else + %{} + end end + + # finally extract AS2 mentions from this object + tagged_mentions = + if object_data["tag"] do + object_data["tag"] + |> Enum.filter(fn x -> is_map(x) end) + |> Enum.filter(fn x -> x["type"] == "Mention" end) + |> Enum.map(fn x -> x["href"] end) + else + [] + end + + # ensure all mentioned users are unique + to = + (to ++ tagged_mentions) |> Enum.uniq() query = get_notified_from_activity_query(to, local_only) @@ -503,12 +518,6 @@ def get_notified_from_activity( Repo.all(query) end - def get_notified_from_activity(%Activity{data: %{"to" => to}}, local_only) do - query = get_notified_from_activity_query(to, local_only) - - Repo.all(query) - end - def get_notified_from_activity(_, _), do: [] def get_recipients_from_activity(%Activity{recipients: to}) do From d26cd6c1bfe1d493b9443f2bd181ce90f22b36a2 Mon Sep 17 00:00:00 2001 From: William Pitcock Date: Fri, 9 Nov 2018 08:23:45 +0000 Subject: [PATCH 08/15] user: factor out user set fetching from User.get_notified_from_activity() --- lib/pleroma/user.ex | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/lib/pleroma/user.ex b/lib/pleroma/user.ex index 71bdbebee..0e4aa0903 100644 --- a/lib/pleroma/user.ex +++ b/lib/pleroma/user.ex @@ -464,15 +464,15 @@ def update_follower_count(%User{} = user) do update_and_set_cache(cs) end - def get_notified_from_activity_query(to, false) do + def get_users_from_set_query(ap_ids, false) do from( u in User, - where: u.ap_id in ^to + where: u.ap_id in ^ap_ids ) end - def get_notified_from_activity_query(to, true) do - query = get_notified_from_activity_query(to, false) + def get_users_from_set_query(ap_ids, true) do + query = get_users_from_set_query(ap_ids, false) from( u in query, @@ -480,6 +480,11 @@ def get_notified_from_activity_query(to, true) do ) end + def get_users_from_set(ap_ids, local_only \\ true) do + get_users_from_set_query(ap_ids, local_only) + |> Repo.all() + end + def get_notified_from_activity(activity, local_only \\ true) def get_notified_from_activity(%Activity{data: %{"to" => to} = data}, local_only) do @@ -513,9 +518,7 @@ def get_notified_from_activity(%Activity{data: %{"to" => to} = data}, local_only (to ++ tagged_mentions) |> Enum.uniq() - query = get_notified_from_activity_query(to, local_only) - - Repo.all(query) + get_users_from_set(to, local_only) end def get_notified_from_activity(_, _), do: [] From cdfdd77e30eb7d83b68d932148cc24a3fbcd5967 Mon Sep 17 00:00:00 2001 From: William Pitcock Date: Fri, 9 Nov 2018 08:41:26 +0000 Subject: [PATCH 09/15] notification: implement new Notification.get_notified_from_activity() --- lib/pleroma/notification.ex | 60 +++++++++++++++++++++++++++++++++++-- 1 file changed, 58 insertions(+), 2 deletions(-) diff --git a/lib/pleroma/notification.ex b/lib/pleroma/notification.ex index 75d7461e4..ca4113d31 100644 --- a/lib/pleroma/notification.ex +++ b/lib/pleroma/notification.ex @@ -1,6 +1,6 @@ defmodule Pleroma.Notification do use Ecto.Schema - alias Pleroma.{User, Activity, Notification, Repo} + alias Pleroma.{User, Activity, Notification, Repo, Object} import Ecto.Query schema "notifications" do @@ -95,7 +95,7 @@ def dismiss(%{id: user_id} = _user, id) do def create_notifications(%Activity{id: _, data: %{"to" => _, "type" => type}} = activity) when type in ["Create", "Like", "Announce", "Follow"] do - users = User.get_notified_from_activity(activity) + users = get_notified_from_activity(activity) notifications = Enum.map(users, fn user -> create_notification(activity, user) end) {:ok, notifications} @@ -113,4 +113,60 @@ def create_notification(%Activity{} = activity, %User{} = user) do notification end end + + def get_notified_from_activity( + %Activity{data: %{"to" => _, "type" => type} = data} = activity, + local_only \\ true + ) + when type in ["Create", "Like", "Announce", "Follow"] do + recipients = + [] + |> maybe_notify_to_recipients(activity) + |> maybe_notify_mentioned_recipients(activity) + |> Enum.uniq() + + User.get_users_from_set(recipients, local_only) + end + + defp maybe_notify_to_recipients( + recipients, + %Activity{data: %{"to" => to, "type" => type}} = activity + ) do + recipients ++ to + end + + defp maybe_notify_mentioned_recipients( + recipients, + %Activity{data: %{"to" => to, "type" => type} = data} = activity + ) + when type == "Create" do + object = Object.normalize(data["object"]) + + object_data = + cond do + !is_nil(object) -> + object.data + + is_map(data["object"]) -> + data["object"] + + true -> + %{} + end + + tagged_mentions = maybe_extract_mentions(object_data) + + recipients ++ tagged_mentions + end + + defp maybe_notify_mentioned_recipients(recipients, _), do: recipients + + defp maybe_extract_mentions(%{"tag" => tag}) do + tag + |> Enum.filter(fn x -> is_map(x) end) + |> Enum.filter(fn x -> x["type"] == "Mention" end) + |> Enum.map(fn x -> x["href"] end) + end + + defp maybe_extract_mentions(_), do: [] end From 6cadfcb21eb58de3d4c635fb563cd4bcebffd3e2 Mon Sep 17 00:00:00 2001 From: William Pitcock Date: Fri, 9 Nov 2018 08:42:33 +0000 Subject: [PATCH 10/15] activitypub: utils: switch to using new Notification.get_notified_from_activity(). --- lib/pleroma/web/activity_pub/utils.ex | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/pleroma/web/activity_pub/utils.ex b/lib/pleroma/web/activity_pub/utils.ex index fd9c5eb59..a9a4c895b 100644 --- a/lib/pleroma/web/activity_pub/utils.ex +++ b/lib/pleroma/web/activity_pub/utils.ex @@ -1,5 +1,5 @@ defmodule Pleroma.Web.ActivityPub.Utils do - alias Pleroma.{Repo, Web, Object, Activity, User} + alias Pleroma.{Repo, Web, Object, Activity, User, Notification} alias Pleroma.Web.Router.Helpers alias Pleroma.Web.Endpoint alias Ecto.{Changeset, UUID} @@ -96,7 +96,7 @@ def generate_id(type) do end def get_notified_from_object(object) do - User.get_notified_from_activity(%Activity{data: object}, false) + Notification.get_notified_from_activity(%Activity{data: object}, false) end def create_context(context) do From 8c805ada32ced1e33c5f1c9171f8032c0bf7597d Mon Sep 17 00:00:00 2001 From: William Pitcock Date: Fri, 9 Nov 2018 08:42:49 +0000 Subject: [PATCH 11/15] user: remove obsolete User.get_notified_from_activity(). --- lib/pleroma/user.ex | 38 -------------------------------------- 1 file changed, 38 deletions(-) diff --git a/lib/pleroma/user.ex b/lib/pleroma/user.ex index 0e4aa0903..be634a8e1 100644 --- a/lib/pleroma/user.ex +++ b/lib/pleroma/user.ex @@ -485,44 +485,6 @@ def get_users_from_set(ap_ids, local_only \\ true) do |> Repo.all() end - def get_notified_from_activity(activity, local_only \\ true) - - def get_notified_from_activity(%Activity{data: %{"to" => to} = data}, local_only) do - object = Object.normalize(data["object"]) - - # somehow, get an AS2 object, preferring the normalized object if we have one - object_data = - if object do - object.data - else - if is_map(data["object"]) do - data["object"] - else - %{} - end - end - - # finally extract AS2 mentions from this object - tagged_mentions = - if object_data["tag"] do - object_data["tag"] - |> Enum.filter(fn x -> is_map(x) end) - |> Enum.filter(fn x -> x["type"] == "Mention" end) - |> Enum.map(fn x -> x["href"] end) - else - [] - end - - # ensure all mentioned users are unique - to = - (to ++ tagged_mentions) - |> Enum.uniq() - - get_users_from_set(to, local_only) - end - - def get_notified_from_activity(_, _), do: [] - def get_recipients_from_activity(%Activity{recipients: to}) do query = from( From b9871e7e5aaf59e92d0fe00e8dfe0de2855a3c12 Mon Sep 17 00:00:00 2001 From: William Pitcock Date: Fri, 9 Nov 2018 08:55:52 +0000 Subject: [PATCH 12/15] activitypub: utils: wrap Note objects in a Create when extracting mentions --- lib/pleroma/web/activity_pub/utils.ex | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/lib/pleroma/web/activity_pub/utils.ex b/lib/pleroma/web/activity_pub/utils.ex index a9a4c895b..d438236c7 100644 --- a/lib/pleroma/web/activity_pub/utils.ex +++ b/lib/pleroma/web/activity_pub/utils.ex @@ -95,6 +95,17 @@ def generate_id(type) do "#{Web.base_url()}/#{type}/#{UUID.generate()}" end + def get_notified_from_object(%{"type" => type} = object) when type == "Note" do + fake_create_activity = %{ + "to" => object["to"], + "cc" => object["cc"], + "type" => "Create", + "object" => object + } + + Notification.get_notified_from_activity(%Activity{data: fake_create_activity}, false) + end + def get_notified_from_object(object) do Notification.get_notified_from_activity(%Activity{data: object}, false) end From b3c360ce2c846bfcd89af347382b8d62762c9ceb Mon Sep 17 00:00:00 2001 From: William Pitcock Date: Fri, 9 Nov 2018 09:07:40 +0000 Subject: [PATCH 13/15] notification: add fallback get_notified_from_activity() --- lib/pleroma/notification.ex | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/lib/pleroma/notification.ex b/lib/pleroma/notification.ex index ca4113d31..a3aeb1221 100644 --- a/lib/pleroma/notification.ex +++ b/lib/pleroma/notification.ex @@ -114,9 +114,11 @@ def create_notification(%Activity{} = activity, %User{} = user) do end end + def get_notified_from_activity(activity, local_only \\ true) + def get_notified_from_activity( %Activity{data: %{"to" => _, "type" => type} = data} = activity, - local_only \\ true + local_only ) when type in ["Create", "Like", "Announce", "Follow"] do recipients = @@ -128,6 +130,8 @@ def get_notified_from_activity( User.get_users_from_set(recipients, local_only) end + def get_notified_from_activity(_, local_only), do: [] + defp maybe_notify_to_recipients( recipients, %Activity{data: %{"to" => to, "type" => type}} = activity From dfc26d0fdd0bff8b2571a722fcddb37a757513d9 Mon Sep 17 00:00:00 2001 From: William Pitcock Date: Fri, 9 Nov 2018 09:33:12 +0000 Subject: [PATCH 14/15] tests: add testing for new notification behavior --- test/notification_test.exs | 95 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 95 insertions(+) diff --git a/test/notification_test.exs b/test/notification_test.exs index 79290ac78..a36ed5bb8 100644 --- a/test/notification_test.exs +++ b/test/notification_test.exs @@ -3,6 +3,7 @@ defmodule Pleroma.NotificationTest do alias Pleroma.Web.TwitterAPI.TwitterAPI alias Pleroma.Web.CommonAPI alias Pleroma.{User, Notification} + alias Pleroma.Web.ActivityPub.Transmogrifier import Pleroma.Factory describe "create_notifications" do @@ -156,6 +157,100 @@ test "it sets all notifications as read up to a specified notification ID" do end end + describe "notification target determination" do + test "it sends notifications to addressed users in new messages" do + user = insert(:user) + other_user = insert(:user) + + {:ok, activity} = + CommonAPI.post(user, %{ + "status" => "hey @#{other_user.nickname}!" + }) + + assert other_user in Notification.get_notified_from_activity(activity) + end + + test "it sends notifications to mentioned users in new messages" do + user = insert(:user) + other_user = insert(:user) + + create_activity = %{ + "@context" => "https://www.w3.org/ns/activitystreams", + "type" => "Create", + "to" => ["https://www.w3.org/ns/activitystreams#Public"], + "actor" => user.ap_id, + "object" => %{ + "type" => "Note", + "content" => "message with a Mention tag, but no explicit tagging", + "tag" => [ + %{ + "type" => "Mention", + "href" => other_user.ap_id, + "name" => other_user.nickname + } + ], + "attributedTo" => user.ap_id + } + } + + {:ok, activity} = Transmogrifier.handle_incoming(create_activity) + + assert other_user in Notification.get_notified_from_activity(activity) + end + + test "it does not send notifications to users who are only cc in new messages" do + user = insert(:user) + other_user = insert(:user) + + create_activity = %{ + "@context" => "https://www.w3.org/ns/activitystreams", + "type" => "Create", + "to" => ["https://www.w3.org/ns/activitystreams#Public"], + "cc" => [other_user.ap_id], + "actor" => user.ap_id, + "object" => %{ + "type" => "Note", + "content" => "hi everyone", + "attributedTo" => user.ap_id + } + } + + {:ok, activity} = Transmogrifier.handle_incoming(create_activity) + + assert other_user not in Notification.get_notified_from_activity(activity) + end + + test "it does not send notification to mentioned users in likes" do + user = insert(:user) + other_user = insert(:user) + third_user = insert(:user) + + {:ok, activity_one} = + CommonAPI.post(user, %{ + "status" => "hey @#{other_user.nickname}!" + }) + + {:ok, activity_two, _} = CommonAPI.favorite(activity_one.id, third_user) + + assert other_user not in Notification.get_notified_from_activity(activity_two) + end + + test "it does not send notification to mentioned users in announces" do + user = insert(:user) + other_user = insert(:user) + third_user = insert(:user) + + {:ok, activity_one} = + CommonAPI.post(user, %{ + "status" => "hey @#{other_user.nickname}!" + }) + + {:ok, activity_two, _} = CommonAPI.repeat(activity_one.id, third_user) + + assert other_user not in Notification.get_notified_from_activity(activity_two) + end + end + describe "notification lifecycle" do test "liking an activity results in 1 notification, then 0 if the activity is deleted" do user = insert(:user) From e4971553c74436b7060f410fe6cbd4f7a9c13b80 Mon Sep 17 00:00:00 2001 From: William Pitcock Date: Fri, 9 Nov 2018 13:39:44 +0000 Subject: [PATCH 15/15] activitypub: utils: use same object type list for mention extraction as insertion --- lib/pleroma/web/activity_pub/utils.ex | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/lib/pleroma/web/activity_pub/utils.ex b/lib/pleroma/web/activity_pub/utils.ex index d438236c7..fac91830a 100644 --- a/lib/pleroma/web/activity_pub/utils.ex +++ b/lib/pleroma/web/activity_pub/utils.ex @@ -6,6 +6,8 @@ defmodule Pleroma.Web.ActivityPub.Utils do import Ecto.Query require Logger + @supported_object_types ["Article", "Note", "Video", "Page"] + # Some implementations send the actor URI as the actor field, others send the entire actor object, # so figure out what the actor's URI is based on what we have. def get_ap_id(object) do @@ -95,7 +97,7 @@ def generate_id(type) do "#{Web.base_url()}/#{type}/#{UUID.generate()}" end - def get_notified_from_object(%{"type" => type} = object) when type == "Note" do + def get_notified_from_object(%{"type" => type} = object) when type in @supported_object_types do fake_create_activity = %{ "to" => object["to"], "cc" => object["cc"], @@ -179,7 +181,7 @@ def lazy_put_object_defaults(map, activity \\ %{}) do Inserts a full object if it is contained in an activity. """ def insert_full_object(%{"object" => %{"type" => type} = object_data}) - when is_map(object_data) and type in ["Article", "Note", "Video", "Page"] do + when is_map(object_data) and type in @supported_object_types do with {:ok, _} <- Object.create(object_data) do :ok end