diff --git a/lib/pleroma/web/embed_controller.ex b/lib/pleroma/web/embed_controller.ex index 91bd79766..cffd6e29f 100644 --- a/lib/pleroma/web/embed_controller.ex +++ b/lib/pleroma/web/embed_controller.ex @@ -11,22 +11,31 @@ defmodule Pleroma.Web.EmbedController do alias Pleroma.Web.ActivityPub.Visibility - plug(:put_layout, :embed) - def show(conn, %{"id" => id}) do - with %Activity{local: true} = activity <- - Activity.get_by_id_with_object(id), - true <- Visibility.visible_for_user?(activity.object, nil) do + with {:activity, %Activity{} = activity} <- + {:activity, Activity.get_by_id_with_object(id)}, + {:local, true} <- {:local, activity.local}, + {:visible, true} <- {:visible, Visibility.visible_for_user?(activity, nil)} do {:ok, author} = User.get_or_fetch(activity.object.data["actor"]) conn |> delete_resp_header("x-frame-options") |> delete_resp_header("content-security-policy") + |> put_view(Pleroma.Web.EmbedView) |> render("show.html", activity: activity, author: User.sanitize_html(author), counts: get_counts(activity) ) + else + {:activity, _} -> + render_error(conn, :not_found, "Post not found") + + {:local, false} -> + render_error(conn, :unauthorized, "Federated posts cannot be embedded") + + {:visible, false} -> + render_error(conn, :unauthorized, "Not authorized to view this post") end end diff --git a/lib/pleroma/web/views/embed_view.ex b/lib/pleroma/web/views/embed_view.ex index 81e196730..913d717be 100644 --- a/lib/pleroma/web/views/embed_view.ex +++ b/lib/pleroma/web/views/embed_view.ex @@ -15,7 +15,7 @@ defmodule Pleroma.Web.EmbedView do alias Pleroma.Web.Metadata.Utils alias Pleroma.Web.Router.Helpers - use Phoenix.HTML + import Phoenix.HTML defdelegate full_nickname(user), to: User @@ -55,10 +55,13 @@ defp activity_url(%User{local: false}, %Activity{object: %Object{data: data}}) d data["url"] || data["external_url"] || data["id"] end - defp attachments(%Activity{object: %Object{data: %{"attachment" => attachments}}}) do + defp attachments(%Activity{object: %Object{data: %{"attachment" => attachments}}}) + when is_list(attachments) do attachments end + defp attachments(_), do: [] + defp sensitive?(%Activity{object: %Object{data: %{"sensitive" => sensitive}}}) do sensitive end diff --git a/test/pleroma/web/embed_controller_test.exs b/test/pleroma/web/embed_controller_test.exs new file mode 100644 index 000000000..caf328cc5 --- /dev/null +++ b/test/pleroma/web/embed_controller_test.exs @@ -0,0 +1,44 @@ +# Pleroma: A lightweight social networking server +# Copyright © 2017-2021 Pleroma Authors +# SPDX-License-Identifier: AGPL-3.0-only + +defmodule Pleroma.Web.EmbedControllerTest do + use Pleroma.Web.ConnCase, async: true + import Pleroma.Factory + + test "/embed", %{conn: conn} do + activity = insert(:note_activity) + + resp = + conn + |> get("/embed/#{activity.id}") + |> response(200) + + object = Pleroma.Object.get_by_ap_id(activity.data["object"]) + + assert String.contains?(resp, object.data["content"]) + end + + test "/embed with a restricted post", %{conn: conn} do + activity = insert(:note_activity) + clear_config([:restrict_unauthenticated, :activities, :local], true) + + conn + |> get("/embed/#{activity.id}") + |> response(401) + end + + test "/embed with a private post", %{conn: conn} do + user = insert(:user) + + {:ok, activity} = + Pleroma.Web.CommonAPI.post(user, %{ + status: "Mega ultra chicken status: #fried", + visibility: "private" + }) + + conn + |> get("/embed/#{activity.id}") + |> response(401) + end +end