Exclude deactivated users from emoji reaction lists #592
7 changed files with 94 additions and 10 deletions
|
@ -6,10 +6,17 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
|
||||||
|
|
||||||
## Unreleased
|
## 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.
|
- 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`.
|
- 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
|
- `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
|
## 2023.05
|
||||||
|
|
||||||
## Added
|
## Added
|
||||||
|
|
|
@ -11,22 +11,31 @@ defmodule Pleroma.Web.EmbedController do
|
||||||
|
|
||||||
alias Pleroma.Web.ActivityPub.Visibility
|
alias Pleroma.Web.ActivityPub.Visibility
|
||||||
|
|
||||||
plug(:put_layout, :embed)
|
|
||||||
|
|
||||||
def show(conn, %{"id" => id}) do
|
def show(conn, %{"id" => id}) do
|
||||||
with %Activity{local: true} = activity <-
|
with {:activity, %Activity{} = activity} <-
|
||||||
Activity.get_by_id_with_object(id),
|
{:activity, Activity.get_by_id_with_object(id)},
|
||||||
true <- Visibility.is_public?(activity.object) do
|
{: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"])
|
{:ok, author} = User.get_or_fetch(activity.object.data["actor"])
|
||||||
|
|
||||||
conn
|
conn
|
||||||
|> delete_resp_header("x-frame-options")
|
|> delete_resp_header("x-frame-options")
|
||||||
|> delete_resp_header("content-security-policy")
|
|> delete_resp_header("content-security-policy")
|
||||||
|
|> put_view(Pleroma.Web.EmbedView)
|
||||||
|> render("show.html",
|
|> render("show.html",
|
||||||
activity: activity,
|
activity: activity,
|
||||||
author: User.sanitize_html(author),
|
author: User.sanitize_html(author),
|
||||||
counts: get_counts(activity)
|
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
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -84,8 +84,13 @@ def whitelisted?(url) do
|
||||||
end
|
end
|
||||||
|
|
||||||
def blocked?(url) do
|
def blocked?(url) do
|
||||||
%{host: domain} = URI.parse(url)
|
%{scheme: scheme, host: domain} = URI.parse(url)
|
||||||
domain in Config.get([:media_proxy, :whitelist])
|
# 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
|
end
|
||||||
|
|
||||||
defp maybe_get_domain_from_url("http" <> _ = url) do
|
defp maybe_get_domain_from_url("http" <> _ = url) do
|
||||||
|
|
|
@ -41,6 +41,17 @@ def index(%{assigns: %{user: user}} = conn, %{id: activity_id} = params) do
|
||||||
end
|
end
|
||||||
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
|
def filter_allowed_users(reactions, user, with_muted) do
|
||||||
exclude_ap_ids =
|
exclude_ap_ids =
|
||||||
if is_nil(user) do
|
if is_nil(user) do
|
||||||
|
@ -51,7 +62,7 @@ def filter_allowed_users(reactions, user, with_muted) do
|
||||||
end
|
end
|
||||||
|
|
||||||
filter_emoji = fn emoji, users, url ->
|
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
|
[] -> nil
|
||||||
users -> {emoji, users, url}
|
users -> {emoji, users, url}
|
||||||
end
|
end
|
||||||
|
|
|
@ -15,7 +15,7 @@ defmodule Pleroma.Web.EmbedView do
|
||||||
alias Pleroma.Web.Metadata.Utils
|
alias Pleroma.Web.Metadata.Utils
|
||||||
alias Pleroma.Web.Router.Helpers
|
alias Pleroma.Web.Router.Helpers
|
||||||
|
|
||||||
use Phoenix.HTML
|
import Phoenix.HTML
|
||||||
|
|
||||||
defdelegate full_nickname(user), to: User
|
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"]
|
data["url"] || data["external_url"] || data["id"]
|
||||||
end
|
end
|
||||||
|
|
||||||
defp attachments(%Activity{object: %Object{data: %{"attachment" => attachments}}}) do
|
defp attachments(%Activity{object: %Object{data: %{"attachment" => attachments}}})
|
||||||
|
when is_list(attachments) do
|
||||||
attachments
|
attachments
|
||||||
end
|
end
|
||||||
|
|
||||||
|
defp attachments(_), do: []
|
||||||
|
|
||||||
defp sensitive?(%Activity{object: %Object{data: %{"sensitive" => sensitive}}}) do
|
defp sensitive?(%Activity{object: %Object{data: %{"sensitive" => sensitive}}}) do
|
||||||
sensitive
|
sensitive
|
||||||
end
|
end
|
||||||
|
|
44
test/pleroma/web/embed_controller_test.exs
Normal file
44
test/pleroma/web/embed_controller_test.exs
Normal file
|
@ -0,0 +1,44 @@
|
||||||
|
# Pleroma: A lightweight social networking server
|
||||||
|
# Copyright © 2017-2021 Pleroma Authors <https://pleroma.social/>
|
||||||
|
# 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
|
|
@ -1960,6 +1960,10 @@ test "index" do
|
||||||
{:ok, _} = CommonAPI.react_with_emoji(activity.id, other_user, "🎅")
|
{:ok, _} = CommonAPI.react_with_emoji(activity.id, other_user, "🎅")
|
||||||
User.mute(user, 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 =
|
result =
|
||||||
conn
|
conn
|
||||||
|> get("/api/v1/statuses/?ids[]=#{activity.id}")
|
|> get("/api/v1/statuses/?ids[]=#{activity.id}")
|
||||||
|
@ -1967,6 +1971,7 @@ test "index" do
|
||||||
|
|
||||||
assert [
|
assert [
|
||||||
%{
|
%{
|
||||||
|
"emoji_reactions" => [],
|
||||||
"pleroma" => %{
|
"pleroma" => %{
|
||||||
"emoji_reactions" => []
|
"emoji_reactions" => []
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue