Merge pull request 'Akkoma fixes: context, polls, media proxy, ConfigDB, API params' (#8047) from lambadalambda/pleroma:fix/akkoma-tier2 into develop

Reviewed-on: https://git.pleroma.social/pleroma/pleroma/pulls/8047
This commit is contained in:
lain 2026-11-01 09:11:11 +00:00
commit 23f9484a76
19 changed files with 211 additions and 54 deletions

View file

@ -48,6 +48,7 @@ defmodule Pleroma.Config.TransferTask do
settings =
(Repo.all(ConfigDB) ++ deleted_settings)
|> Enum.reject(&ConfigDB.static?/1)
|> Enum.reject(&(&1.group == :invalid_atom or &1.key == :invalid_atom))
|> Enum.map(&merge_with_default/1)
started_applications = Application.started_applications()

View file

@ -5,6 +5,8 @@
defmodule Pleroma.EctoType.Config.Atom do
use Ecto.Type
require Logger
def type, do: :atom
def cast(key) when is_atom(key) do
@ -17,8 +19,17 @@ defmodule Pleroma.EctoType.Config.Atom do
def cast(_), do: :error
# A key or group naming a module that no longer exists (e.g. a removed uploader)
# must not crash loading
def load(key) do
{:ok, Pleroma.ConfigDB.string_to_elixir_types(key)}
rescue
ArgumentError ->
Logger.warning(
"ConfigDB: unknown module #{key} in a setting key or group, the setting is not applied"
)
{:ok, :invalid_atom}
end
def dump(key) when is_atom(key), do: {:ok, inspect(key)}

View file

@ -466,21 +466,28 @@ defmodule Pleroma.Web.ActivityPub.ActivityPub do
end
def fetch_activities_for_context_query(context, opts) do
public = [Constants.as_public()]
user = opts[:user]
recipients =
if opts[:user],
do: [opts[:user].ap_id | User.following(opts[:user])] ++ public,
else: public
cond do
user && user.local ->
[Constants.as_public(), as_local_public(), user.ap_id | User.following(user)]
user ->
[Constants.as_public(), user.ap_id | User.following(user)]
true ->
[Constants.as_public()]
end
from(activity in Activity)
|> maybe_preload_objects(opts)
|> maybe_preload_bookmarks(opts)
|> maybe_set_thread_muted_field(opts)
|> restrict_unauthenticated(opts[:user])
|> restrict_unauthenticated(user)
|> restrict_blocked(opts)
|> restrict_blockers_visibility(opts)
|> restrict_recipients(recipients, opts[:user])
|> restrict_recipients(recipients, user)
|> restrict_filtered(opts)
|> where(
[activity],

View file

@ -213,7 +213,7 @@ defmodule Pleroma.Web.ActivityPub.ObjectValidators.ArticleNotePageValidator do
defp fix_misskey_content(object), do: object
defp fix(data) do
def fix(data) do
data
|> CommonFixes.fix_actor()
|> CommonFixes.fix_object_defaults()

View file

@ -6,10 +6,9 @@ defmodule Pleroma.Web.ActivityPub.ObjectValidators.QuestionValidator do
use Ecto.Schema
alias Pleroma.EctoType.ActivityPub.ObjectValidators
alias Pleroma.Web.ActivityPub.ObjectValidators.CommonFixes
alias Pleroma.Web.ActivityPub.ObjectValidators.ArticleNotePageValidator
alias Pleroma.Web.ActivityPub.ObjectValidators.CommonValidations
alias Pleroma.Web.ActivityPub.ObjectValidators.QuestionOptionsValidator
alias Pleroma.Web.ActivityPub.Transmogrifier
import Ecto.Changeset
@ -62,11 +61,7 @@ defmodule Pleroma.Web.ActivityPub.ObjectValidators.QuestionValidator do
defp fix(data) do
data
|> CommonFixes.fix_actor()
|> CommonFixes.fix_object_defaults()
|> CommonFixes.fix_quote_url()
|> CommonFixes.fix_likes()
|> Transmogrifier.fix_emoji()
|> ArticleNotePageValidator.fix()
|> fix_closed()
end

View file

@ -20,6 +20,9 @@ defmodule Pleroma.Web.ApiSpec.CastAndValidate do
require Logger
# How often to drop offending query params and retry in permissive mode
@max_retries 20
@impl Plug
def init(opts) do
opts
@ -114,34 +117,49 @@ defmodule Pleroma.Web.ApiSpec.CastAndValidate do
false = _strict,
cast_opts
) do
case OpenApiSpex.cast_and_validate(spec, operation, conn, content_type, cast_opts) do
{:ok, conn} ->
{:ok, conn}
permissive_cast_and_validate(spec, operation, conn, content_type, cast_opts, @max_retries)
end
# Remove unexpected query params and cast/validate again
{:error, errors} ->
query_params =
Enum.reduce(errors, conn.query_params, fn
%{reason: :unexpected_field, name: name, path: [name]}, params ->
Map.delete(params, name)
# OpenApiSpex reports one offending param at a time, so drop it and cast/validate again
defp permissive_cast_and_validate(
spec,
operation,
%Conn{} = conn,
content_type,
cast_opts,
retries
) do
with {:error, errors} = error <-
OpenApiSpex.cast_and_validate(spec, operation, conn, content_type, cast_opts) do
query_params = drop_invalid_query_params(errors, conn.query_params)
# Filter out empty params
%{reason: :invalid_type, path: [name_atom], value: ""}, params ->
Map.delete(params, to_string(name_atom))
%{reason: :invalid_enum, name: nil, path: path, value: value}, params ->
path = path |> Enum.reverse() |> tl() |> Enum.reverse() |> list_items_to_string()
update_in(params, path, &List.delete(&1, value))
_, params ->
params
end)
conn = %Conn{conn | query_params: query_params}
OpenApiSpex.cast_and_validate(spec, operation, conn, content_type, cast_opts)
if retries > 0 and query_params != conn.query_params do
conn = %{conn | query_params: query_params}
permissive_cast_and_validate(spec, operation, conn, content_type, cast_opts, retries - 1)
else
error
end
end
end
defp drop_invalid_query_params(errors, query_params) do
Enum.reduce(errors, query_params, fn
%{reason: :unexpected_field, name: name, path: [name]}, params ->
Map.delete(params, name)
# Filter out empty params
%{reason: :invalid_type, path: [name_atom], value: ""}, params ->
Map.delete(params, to_string(name_atom))
%{reason: :invalid_enum, name: nil, path: path, value: value}, params ->
path = path |> Enum.reverse() |> tl() |> Enum.reverse() |> list_items_to_string()
update_in(params, path, &List.delete(&1, value))
_, params ->
params
end)
end
defp list_items_to_string(list) do
Enum.map(list, fn
i when is_atom(i) -> to_string(i)

View file

@ -7,7 +7,6 @@ defmodule Pleroma.Web.MediaProxy.MediaProxyController do
alias Pleroma.Config
alias Pleroma.Helpers.MediaHelper
alias Pleroma.Helpers.UriHelper
alias Pleroma.ReverseProxy
alias Pleroma.Web.MediaProxy
alias Plug.Conn
@ -67,9 +66,6 @@ defmodule Pleroma.Web.MediaProxy.MediaProxyController do
static and content_type == "image/gif" ->
handle_jpeg_preview(conn, media_proxy_url)
static ->
drop_static_param_and_redirect(conn)
content_type == "image/gif" ->
conn
|> put_status(301)
@ -166,15 +162,6 @@ defmodule Pleroma.Web.MediaProxy.MediaProxyController do
end
end
defp drop_static_param_and_redirect(conn) do
uri_without_static_param =
conn
|> current_url()
|> UriHelper.modify_uri_params(%{}, ["static"])
redirect(conn, external: uri_without_static_param)
end
defp fallback_on_preview_error(conn, media_proxy_url) do
redirect(conn, external: media_proxy_url)
end