From 5346fabf142c19c8442b4421ad3f827ad050ec92 Mon Sep 17 00:00:00 2001 From: "Haelwenn (lanodan) Monnier" Date: Sat, 24 Nov 2018 06:13:36 +0100 Subject: [PATCH 1/4] Web.MastodonAPI.MastodonSocket: Add unauthentified websocket endpoints reported by soka on CRTNet --- .../web/mastodon_api/mastodon_socket.ex | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/lib/pleroma/web/mastodon_api/mastodon_socket.ex b/lib/pleroma/web/mastodon_api/mastodon_socket.ex index 0f3d5ff7c..46ec5ecd2 100644 --- a/lib/pleroma/web/mastodon_api/mastodon_socket.ex +++ b/lib/pleroma/web/mastodon_api/mastodon_socket.ex @@ -45,6 +45,24 @@ defmodule Pleroma.Web.MastodonAPI.MastodonSocket do end end + def connect(%{"stream" => stream} = params, socket) + when stream in ["public", "public:local", "hashtag"] do + topic = + case stream do + "hashtag" -> "hashtag:#{params["tag"]}" + _ -> stream + end + + with socket = + socket + |> assign(:topic, topic) do + Pleroma.Web.Streamer.add_socket(topic, socket) + {:ok, socket} + else + _e -> :error + end + end + def id(_), do: nil def handle(:text, message, _state) do From d388a991433151eb8d4fd07ad732d2f166ac295b Mon Sep 17 00:00:00 2001 From: "Haelwenn (lanodan) Monnier" Date: Sat, 24 Nov 2018 06:43:03 +0100 Subject: [PATCH 2/4] Web.MastodonAPI.MastodonSocket: Put access_token at function-level --- lib/pleroma/web/mastodon_api/mastodon_socket.ex | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/lib/pleroma/web/mastodon_api/mastodon_socket.ex b/lib/pleroma/web/mastodon_api/mastodon_socket.ex index 46ec5ecd2..f3c13d1aa 100644 --- a/lib/pleroma/web/mastodon_api/mastodon_socket.ex +++ b/lib/pleroma/web/mastodon_api/mastodon_socket.ex @@ -11,9 +11,8 @@ defmodule Pleroma.Web.MastodonAPI.MastodonSocket do timeout: :infinity ) - def connect(params, socket) do - with token when not is_nil(token) <- params["access_token"], - %Token{user_id: user_id} <- Repo.get_by(Token, token: token), + def connect(%{"access_token" => token} = params, socket) do + with %Token{user_id: user_id} <- Repo.get_by(Token, token: token), %User{} = user <- Repo.get(User, user_id), stream when stream in [ From ca029f0b693891fbe21dc58fb379c2319cf05f17 Mon Sep 17 00:00:00 2001 From: "Haelwenn (lanodan) Monnier" Date: Sat, 24 Nov 2018 08:45:45 +0100 Subject: [PATCH 3/4] Web.Streamer: Get unauthenticated statuses representation --- lib/pleroma/web/streamer.ex | 39 ++++++++++++++++++++++++++++--------- 1 file changed, 30 insertions(+), 9 deletions(-) diff --git a/lib/pleroma/web/streamer.ex b/lib/pleroma/web/streamer.ex index 6b6d40346..5cab62c85 100644 --- a/lib/pleroma/web/streamer.ex +++ b/lib/pleroma/web/streamer.ex @@ -169,16 +169,33 @@ defmodule Pleroma.Web.Streamer do |> Jason.encode!() end + defp represent_update(%Activity{} = activity) do + %{ + event: "update", + payload: + Pleroma.Web.MastodonAPI.StatusView.render( + "status.json", + activity: activity + ) + |> Jason.encode!() + } + |> Jason.encode!() + end + def push_to_socket(topics, topic, %Activity{data: %{"type" => "Announce"}} = item) do Enum.each(topics[topic] || [], fn socket -> # Get the current user so we have up-to-date blocks etc. - user = User.get_cached_by_ap_id(socket.assigns[:user].ap_id) - blocks = user.info["blocks"] || [] + if socket.assigns[:user] do + user = User.get_cached_by_ap_id(socket.assigns[:user].ap_id) + blocks = user.info["blocks"] || [] - parent = Object.normalize(item.data["object"]) + parent = Object.normalize(item.data["object"]) - unless is_nil(parent) or item.actor in blocks or parent.data["actor"] in blocks do - send(socket.transport_pid, {:text, represent_update(item, user)}) + unless is_nil(parent) or item.actor in blocks or parent.data["actor"] in blocks do + send(socket.transport_pid, {:text, represent_update(item, user)}) + end + else + send(socket.transport_pid, {:text, represent_update(item)}) end end) end @@ -186,11 +203,15 @@ defmodule Pleroma.Web.Streamer do def push_to_socket(topics, topic, item) do Enum.each(topics[topic] || [], fn socket -> # Get the current user so we have up-to-date blocks etc. - user = User.get_cached_by_ap_id(socket.assigns[:user].ap_id) - blocks = user.info["blocks"] || [] + if socket.assigns[:user] do + user = User.get_cached_by_ap_id(socket.assigns[:user].ap_id) + blocks = user.info["blocks"] || [] - unless item.actor in blocks do - send(socket.transport_pid, {:text, represent_update(item, user)}) + unless item.actor in blocks do + send(socket.transport_pid, {:text, represent_update(item, user)}) + end + else + send(socket.transport_pid, {:text, represent_update(item)}) end end) end From cc8952b45fc9c8d77f1d7c83674d4194b032c5fd Mon Sep 17 00:00:00 2001 From: "Haelwenn (lanodan) Monnier" Date: Sat, 24 Nov 2018 08:47:35 +0100 Subject: [PATCH 4/4] Web.MastodonApi.MastodonSocketTest: Add test for unauthenticated websocket --- .../web/mastodon_api/mastodon_socket_test.exs | 33 +++++++++++++++++++ 1 file changed, 33 insertions(+) create mode 100644 test/web/mastodon_api/mastodon_socket_test.exs diff --git a/test/web/mastodon_api/mastodon_socket_test.exs b/test/web/mastodon_api/mastodon_socket_test.exs new file mode 100644 index 000000000..c7d71defc --- /dev/null +++ b/test/web/mastodon_api/mastodon_socket_test.exs @@ -0,0 +1,33 @@ +defmodule Pleroma.Web.MastodonApi.MastodonSocketTest do + use Pleroma.DataCase + + alias Pleroma.Web.MastodonApi.MastodonSocket + alias Pleroma.Web.{Streamer, CommonAPI} + alias Pleroma.User + + import Pleroma.Factory + + test "public is working when non-authenticated" do + user = insert(:user) + + task = + Task.async(fn -> + assert_receive {:text, _}, 4_000 + end) + + fake_socket = %{ + transport_pid: task.pid, + assigns: %{} + } + + topics = %{ + "public" => [fake_socket] + } + + {:ok, activity} = CommonAPI.post(user, %{"status" => "Test"}) + + Streamer.push_to_socket(topics, "public", activity) + + Task.await(task) + end +end