diff --git a/CHANGELOG.md b/CHANGELOG.md index ee1e1765a..7a81aad09 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,10 +6,17 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). ## Unreleased +## Added + - Added a new configuration option to the MediaProxy feature that allows the blocking of specific domains from using the media proxy or being explicitly allowed by the Content-Security-Policy. - Please make sure instances you wanted to block media from are not in the MediaProxy `whitelist`, and instead use `blocklist`. - `OnlyMedia` Upload Filter to simplify restricting uploads to audio, image, and video types +## Fixed + +- Deactivated users can no longer show up in the emoji reaction list +- Embedded posts can no longer bypass `:restrict\_unauthenticated` + ## 2023.05 ## Added diff --git a/lib/pleroma/web/embed_controller.ex b/lib/pleroma/web/embed_controller.ex index c7912bb1f..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.is_public?(activity.object) 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/media_proxy.ex b/lib/pleroma/web/media_proxy.ex index 9a5f47716..44f927dba 100644 --- a/lib/pleroma/web/media_proxy.ex +++ b/lib/pleroma/web/media_proxy.ex @@ -84,8 +84,13 @@ def whitelisted?(url) do end def blocked?(url) do - %{host: domain} = URI.parse(url) - domain in Config.get([:media_proxy, :whitelist]) + %{scheme: scheme, host: domain} = URI.parse(url) + # Block either the bare domain or the scheme-domain combo + scheme_domain = "#{scheme}://#{domain}" + blocklist = Config.get([:media_proxy, :blocklist]) + + Enum.member?(blocklist, domain) || + Enum.member?(blocklist, scheme_domain) end defp maybe_get_domain_from_url("http" <> _ = url) do diff --git a/lib/pleroma/web/pleroma_api/controllers/emoji_reaction_controller.ex b/lib/pleroma/web/pleroma_api/controllers/emoji_reaction_controller.ex index 0933363a6..e762fcad8 100644 --- a/lib/pleroma/web/pleroma_api/controllers/emoji_reaction_controller.ex +++ b/lib/pleroma/web/pleroma_api/controllers/emoji_reaction_controller.ex @@ -41,6 +41,17 @@ def index(%{assigns: %{user: user}} = conn, %{id: activity_id} = params) do end end + defp filter_allowed_user_by_ap_id(ap_ids, excluded_ap_ids) do + Enum.reject(ap_ids, fn ap_id -> + with false <- ap_id in excluded_ap_ids, + %{is_active: true} <- User.get_cached_by_ap_id(ap_id) do + false + else + _ -> true + end + end) + end + def filter_allowed_users(reactions, user, with_muted) do exclude_ap_ids = if is_nil(user) do @@ -51,7 +62,7 @@ def filter_allowed_users(reactions, user, with_muted) do end filter_emoji = fn emoji, users, url -> - case Enum.reject(users, &(&1 in exclude_ap_ids)) do + case filter_allowed_user_by_ap_id(users, exclude_ap_ids) do [] -> nil users -> {emoji, users, url} 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 diff --git a/test/pleroma/web/mastodon_api/controllers/status_controller_test.exs b/test/pleroma/web/mastodon_api/controllers/status_controller_test.exs index 6f04975b8..30be34007 100644 --- a/test/pleroma/web/mastodon_api/controllers/status_controller_test.exs +++ b/test/pleroma/web/mastodon_api/controllers/status_controller_test.exs @@ -1960,6 +1960,10 @@ test "index" do {:ok, _} = CommonAPI.react_with_emoji(activity.id, other_user, "🎅") User.mute(user, other_user) + deactivated_user = insert(:user) + {:ok, _} = CommonAPI.react_with_emoji(activity.id, deactivated_user, "🎅") + User.set_activation(deactivated_user, false) + result = conn |> get("/api/v1/statuses/?ids[]=#{activity.id}") @@ -1967,6 +1971,7 @@ test "index" do assert [ %{ + "emoji_reactions" => [], "pleroma" => %{ "emoji_reactions" => [] }