From c60a5405db7c0bdb4f837e14088a495c1b741bc6 Mon Sep 17 00:00:00 2001 From: csaurus Date: Thu, 10 May 2018 22:17:59 -0400 Subject: Detect and try to stream incoming "direct" messages --- lib/pleroma/web/activity_pub/activity_pub.ex | 15 ++++++++++----- lib/pleroma/web/mastodon_api/mastodon_socket.ex | 2 +- 2 files changed, 11 insertions(+), 6 deletions(-) (limited to 'lib') diff --git a/lib/pleroma/web/activity_pub/activity_pub.ex b/lib/pleroma/web/activity_pub/activity_pub.ex index fde6e12d7..38e3a84fb 100644 --- a/lib/pleroma/web/activity_pub/activity_pub.ex +++ b/lib/pleroma/web/activity_pub/activity_pub.ex @@ -42,13 +42,18 @@ defmodule Pleroma.Web.ActivityPub.ActivityPub do def stream_out(activity) do if activity.data["type"] in ["Create", "Announce"] do Pleroma.Web.Streamer.stream("user", activity) + direct? = activity.data["object"]["visibility"] == "direct" - if Enum.member?(activity.data["to"], "https://www.w3.org/ns/activitystreams#Public") do - Pleroma.Web.Streamer.stream("public", activity) + cond do + direct? -> + Pleroma.Web.Streamer.stream("direct", activity) - if activity.local do - Pleroma.Web.Streamer.stream("public:local", activity) - end + Enum.member?(activity.data["to"], "https://www.w3.org/ns/activitystreams#Public") -> + Pleroma.Web.Streamer.stream("public", activity) + + if activity.local do + Pleroma.Web.Streamer.stream("public:local", activity) + end end end end diff --git a/lib/pleroma/web/mastodon_api/mastodon_socket.ex b/lib/pleroma/web/mastodon_api/mastodon_socket.ex index f3e062941..080f62b31 100644 --- a/lib/pleroma/web/mastodon_api/mastodon_socket.ex +++ b/lib/pleroma/web/mastodon_api/mastodon_socket.ex @@ -15,7 +15,7 @@ defmodule Pleroma.Web.MastodonAPI.MastodonSocket do with token when not is_nil(token) <- params["access_token"], %Token{user_id: user_id} <- Repo.get_by(Token, token: token), %User{} = user <- Repo.get(User, user_id), - stream when stream in ["public", "public:local", "user"] <- params["stream"] do + stream when stream in ["public", "public:local", "user", "direct"] <- params["stream"] do socket = socket |> assign(:topic, params["stream"]) -- cgit v1.2.3 From 392bd9ef562a98bb026d49ddd83f108cbe9fdb19 Mon Sep 17 00:00:00 2001 From: csaurus Date: Thu, 10 May 2018 22:15:42 -0400 Subject: Stream function to handle direct messages. --- lib/pleroma/web/activity_pub/activity_pub.ex | 14 ++++++-------- lib/pleroma/web/streamer.ex | 17 +++++++++++++++-- 2 files changed, 21 insertions(+), 10 deletions(-) (limited to 'lib') diff --git a/lib/pleroma/web/activity_pub/activity_pub.ex b/lib/pleroma/web/activity_pub/activity_pub.ex index 38e3a84fb..8c1ba1ea3 100644 --- a/lib/pleroma/web/activity_pub/activity_pub.ex +++ b/lib/pleroma/web/activity_pub/activity_pub.ex @@ -42,18 +42,16 @@ defmodule Pleroma.Web.ActivityPub.ActivityPub do def stream_out(activity) do if activity.data["type"] in ["Create", "Announce"] do Pleroma.Web.Streamer.stream("user", activity) - direct? = activity.data["object"]["visibility"] == "direct" - cond do - direct? -> - Pleroma.Web.Streamer.stream("direct", activity) + visibility = Pleroma.Web.MastodonAPI.StatusView.get_visibility(activity.data["object"]) - Enum.member?(activity.data["to"], "https://www.w3.org/ns/activitystreams#Public") -> + case visibility do + "public" -> Pleroma.Web.Streamer.stream("public", activity) + if activity.local, do: Pleroma.Web.Streamer.stream("public:local", activity) - if activity.local do - Pleroma.Web.Streamer.stream("public:local", activity) - end + "direct" -> + Pleroma.Web.Streamer.stream("direct", activity) end end end diff --git a/lib/pleroma/web/streamer.ex b/lib/pleroma/web/streamer.ex index 33041ec12..6aac472dc 100644 --- a/lib/pleroma/web/streamer.ex +++ b/lib/pleroma/web/streamer.ex @@ -46,6 +46,19 @@ defmodule Pleroma.Web.Streamer do {:noreply, topics} end + def handle_cast(%{action: :stream, topic: "direct", item: item}, topics) do + recipient_topics = + User.get_recipients_from_activity(item) + |> Enum.map(fn %{id: id} -> "direct:#{id}" end) + + Enum.each(recipient_topics || [], fn user_topic -> + Logger.debug("Trying to push direct message to #{user_topic}\n\n") + push_to_socket(topics, user_topic, item) + end) + + {:noreply, topics} + end + def handle_cast(%{action: :stream, topic: "user", item: %Notification{} = item}, topics) do topic = "user:#{item.user_id}" @@ -137,8 +150,8 @@ defmodule Pleroma.Web.Streamer do end) end - defp internal_topic("user", socket) do - "user:#{socket.assigns[:user].id}" + defp internal_topic(topic, socket) when topic in ~w[user, direct] do + "#{topic}:#{socket.assigns[:user].id}" end defp internal_topic(topic, _), do: topic -- cgit v1.2.3 From c8d418acddd72e628caad9a6b11ff6debd3386e9 Mon Sep 17 00:00:00 2001 From: csaurus Date: Thu, 10 May 2018 22:17:33 -0400 Subject: api/v1/timelines/direct implementation --- lib/pleroma/web/activity_pub/activity_pub.ex | 23 ++++++++++++++++++++++ .../web/mastodon_api/mastodon_api_controller.ex | 9 +++++++++ lib/pleroma/web/router.ex | 2 ++ 3 files changed, 34 insertions(+) (limited to 'lib') diff --git a/lib/pleroma/web/activity_pub/activity_pub.ex b/lib/pleroma/web/activity_pub/activity_pub.ex index 8c1ba1ea3..d5d00d4a2 100644 --- a/lib/pleroma/web/activity_pub/activity_pub.ex +++ b/lib/pleroma/web/activity_pub/activity_pub.ex @@ -224,6 +224,28 @@ defmodule Pleroma.Web.ActivityPub.ActivityPub do |> Enum.reverse() end + @valid_visibilities ~w[direct unlisted public private] + + defp restrict_visibility(query, %{visibility: "direct"}) do + public = "https://www.w3.org/ns/activitystreams#Public" + + from( + activity in query, + join: sender in User, + on: sender.ap_id == activity.actor, + where: + fragment("not data->'to' \\? ?", ^public) and fragment("not data->'cc' \\? ?", ^public) and + fragment("not data->'to' \\? ?", sender.follower_address) + ) + end + + defp restrict_visibility(_query, %{visibility: visibility}) + when visibility not in @valid_visibilities do + Logger.error("Could not restrict visibility to #{visibility}") + end + + defp restrict_visibility(query, _visibility), do: query + defp restrict_since(query, %{"since_id" => since_id}) do from(activity in query, where: activity.id > ^since_id) end @@ -347,6 +369,7 @@ defmodule Pleroma.Web.ActivityPub.ActivityPub do |> restrict_recent(opts) |> restrict_blocked(opts) |> restrict_media(opts) + |> restrict_visibility(opts) end def fetch_activities(recipients, opts \\ %{}) do diff --git a/lib/pleroma/web/mastodon_api/mastodon_api_controller.ex b/lib/pleroma/web/mastodon_api/mastodon_api_controller.ex index 9f4261143..d190cdc3f 100644 --- a/lib/pleroma/web/mastodon_api/mastodon_api_controller.ex +++ b/lib/pleroma/web/mastodon_api/mastodon_api_controller.ex @@ -227,6 +227,15 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIController do end end + def dm_timeline(%{assigns: %{user: user}} = conn, params) do + query = ActivityPub.fetch_activities_query([user.ap_id], %{visibility: "direct"}) + activities = Repo.all(query) + + conn + |> add_link_headers(:user_statuses, activities, user.ap_id) + |> render(StatusView, "index.json", %{activities: activities, for: user, as: :activity}) + end + 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 diff --git a/lib/pleroma/web/router.ex b/lib/pleroma/web/router.ex index c025dea33..dbef19d44 100644 --- a/lib/pleroma/web/router.ex +++ b/lib/pleroma/web/router.ex @@ -106,6 +106,8 @@ defmodule Pleroma.Web.Router do get("/timelines/home", MastodonAPIController, :home_timeline) + get("/timelines/direct", MastodonAPIController, :dm_timeline) + get("/favourites", MastodonAPIController, :favourites) post("/statuses", MastodonAPIController, :post_status) -- cgit v1.2.3 From 9aabff48835d55cf284229298ad86c07fa1fce30 Mon Sep 17 00:00:00 2001 From: csaurus Date: Sun, 13 May 2018 15:33:59 -0400 Subject: Fix tests. --- lib/pleroma/web/activity_pub/activity_pub.ex | 21 +++++++++++++-------- lib/pleroma/web/mastodon_api/views/status_view.ex | 1 + 2 files changed, 14 insertions(+), 8 deletions(-) (limited to 'lib') diff --git a/lib/pleroma/web/activity_pub/activity_pub.ex b/lib/pleroma/web/activity_pub/activity_pub.ex index d5d00d4a2..4b2ecfa3c 100644 --- a/lib/pleroma/web/activity_pub/activity_pub.ex +++ b/lib/pleroma/web/activity_pub/activity_pub.ex @@ -40,18 +40,23 @@ defmodule Pleroma.Web.ActivityPub.ActivityPub do end def stream_out(activity) do + public = "https://www.w3.org/ns/activitystreams#Public" + if activity.data["type"] in ["Create", "Announce"] do Pleroma.Web.Streamer.stream("user", activity) - visibility = Pleroma.Web.MastodonAPI.StatusView.get_visibility(activity.data["object"]) + if Enum.member?(activity.data["to"], public) do + Pleroma.Web.Streamer.stream("public", activity) - case visibility do - "public" -> - Pleroma.Web.Streamer.stream("public", activity) - if activity.local, do: Pleroma.Web.Streamer.stream("public:local", activity) - - "direct" -> - Pleroma.Web.Streamer.stream("direct", activity) + if activity.local do + Pleroma.Web.Streamer.stream("public:local", activity) + end + else + if !Enum.member?(activity.data["cc"] || [], public) && + !Enum.member?( + activity.data["to"], + User.get_by_ap_id(activity.data["actor"]).follower_address + ), do: Pleroma.Web.Streamer.stream("direct", activity) end 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 5c6fd05f3..301234412 100644 --- a/lib/pleroma/web/mastodon_api/views/status_view.ex +++ b/lib/pleroma/web/mastodon_api/views/status_view.ex @@ -195,6 +195,7 @@ defmodule Pleroma.Web.MastodonAPI.StatusView do cond do public in to -> "public" public in cc -> "unlisted" + # this should use the sql for the object's activity Enum.any?(to, &String.contains?(&1, "/followers")) -> "private" true -> "direct" end -- cgit v1.2.3 From 2ce48c1a42b0e61958b513df610a81bb89b4254a Mon Sep 17 00:00:00 2001 From: csaurus Date: Sun, 13 May 2018 15:36:41 -0400 Subject: Formatting --- lib/pleroma/web/activity_pub/activity_pub.ex | 3 ++- lib/pleroma/web/mastodon_api/views/status_view.ex | 17 ++++++++++++----- 2 files changed, 14 insertions(+), 6 deletions(-) (limited to 'lib') diff --git a/lib/pleroma/web/activity_pub/activity_pub.ex b/lib/pleroma/web/activity_pub/activity_pub.ex index 4b2ecfa3c..f7f6d047e 100644 --- a/lib/pleroma/web/activity_pub/activity_pub.ex +++ b/lib/pleroma/web/activity_pub/activity_pub.ex @@ -56,7 +56,8 @@ defmodule Pleroma.Web.ActivityPub.ActivityPub do !Enum.member?( activity.data["to"], User.get_by_ap_id(activity.data["actor"]).follower_address - ), do: Pleroma.Web.Streamer.stream("direct", activity) + ), + do: Pleroma.Web.Streamer.stream("direct", activity) end 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 301234412..d1d48cd0a 100644 --- a/lib/pleroma/web/mastodon_api/views/status_view.ex +++ b/lib/pleroma/web/mastodon_api/views/status_view.ex @@ -193,11 +193,18 @@ defmodule Pleroma.Web.MastodonAPI.StatusView do cc = object["cc"] || [] cond do - public in to -> "public" - public in cc -> "unlisted" - # this should use the sql for the object's activity - Enum.any?(to, &String.contains?(&1, "/followers")) -> "private" - true -> "direct" + public in to -> + "public" + + public in cc -> + "unlisted" + + # this should use the sql for the object's activity + Enum.any?(to, &String.contains?(&1, "/followers")) -> + "private" + + true -> + "direct" end end end -- cgit v1.2.3 From 4dfb40a5467f6206b2793bdafbd82a7ae4ee04bf Mon Sep 17 00:00:00 2001 From: csaurus Date: Mon, 14 May 2018 21:46:09 -0400 Subject: Handle cases where a to/cc field is absent on a status --- lib/pleroma/web/activity_pub/activity_pub.ex | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'lib') diff --git a/lib/pleroma/web/activity_pub/activity_pub.ex b/lib/pleroma/web/activity_pub/activity_pub.ex index f7f6d047e..4ce2e6052 100644 --- a/lib/pleroma/web/activity_pub/activity_pub.ex +++ b/lib/pleroma/web/activity_pub/activity_pub.ex @@ -239,9 +239,11 @@ defmodule Pleroma.Web.ActivityPub.ActivityPub do activity in query, join: sender in User, on: sender.ap_id == activity.actor, + # Are non-direct statuses with no to/cc possible? where: - fragment("not data->'to' \\? ?", ^public) and fragment("not data->'cc' \\? ?", ^public) and - fragment("not data->'to' \\? ?", sender.follower_address) + fragment("not coalesce(data->'to' \\? ?, false)", ^public) and + fragment("not coalesce(data->'cc' \\? ?, false)", ^public) and + fragment("not coalesce(data->'to' \\? ?, false)", sender.follower_address) ) end -- cgit v1.2.3 From 841ee8e3e4d31d4236a022d46fe18f7751605c74 Mon Sep 17 00:00:00 2001 From: lain Date: Sat, 26 May 2018 16:25:32 +0200 Subject: Simplify DM query. Should also use indexes better. --- lib/pleroma/web/activity_pub/activity_pub.ex | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) (limited to 'lib') diff --git a/lib/pleroma/web/activity_pub/activity_pub.ex b/lib/pleroma/web/activity_pub/activity_pub.ex index d54dc224d..4e0be5ba2 100644 --- a/lib/pleroma/web/activity_pub/activity_pub.ex +++ b/lib/pleroma/web/activity_pub/activity_pub.ex @@ -313,9 +313,11 @@ defmodule Pleroma.Web.ActivityPub.ActivityPub do on: sender.ap_id == activity.actor, # Are non-direct statuses with no to/cc possible? where: - fragment("not coalesce(data->'to' \\? ?, false)", ^public) and - fragment("not coalesce(data->'cc' \\? ?, false)", ^public) and - fragment("not coalesce(data->'to' \\? ?, false)", sender.follower_address) + fragment( + "not (? && ?)", + [^public, sender.follower_address], + activity.recipients + ) ) end -- cgit v1.2.3