From 163c49c649f5fb0af053ec2cbfa036c77b8205ff Mon Sep 17 00:00:00 2001 From: Lain Soykaf Date: Sat, 31 Oct 2026 13:12:15 +0400 Subject: [PATCH] fix(api_spec): pass cast options on the first permissive cast Without them replace_params: false was ignored when strict is off, so conn.params got atom keys and RateLimiter params: ["id"] buckets collapsed to one per user. --- changelog.d/cast-and-validate-cast-opts.fix | 1 + lib/pleroma/web/api_spec/cast_and_validate.ex | 2 +- .../web/mastodon_api/controllers/status_controller_test.exs | 6 ++++-- 3 files changed, 6 insertions(+), 3 deletions(-) create mode 100644 changelog.d/cast-and-validate-cast-opts.fix diff --git a/changelog.d/cast-and-validate-cast-opts.fix b/changelog.d/cast-and-validate-cast-opts.fix new file mode 100644 index 000000000..ba4ce2283 --- /dev/null +++ b/changelog.d/cast-and-validate-cast-opts.fix @@ -0,0 +1 @@ +Fix per-status and per-account rate limits when `Pleroma.Web.ApiSpec.CastAndValidate` `strict` is off (the production default) diff --git a/lib/pleroma/web/api_spec/cast_and_validate.ex b/lib/pleroma/web/api_spec/cast_and_validate.ex index 95bd4d9cf..92f1c5376 100644 --- a/lib/pleroma/web/api_spec/cast_and_validate.ex +++ b/lib/pleroma/web/api_spec/cast_and_validate.ex @@ -114,7 +114,7 @@ defmodule Pleroma.Web.ApiSpec.CastAndValidate do false = _strict, cast_opts ) do - case OpenApiSpex.cast_and_validate(spec, operation, conn, content_type) do + case OpenApiSpex.cast_and_validate(spec, operation, conn, content_type, cast_opts) do {:ok, conn} -> {:ok, conn} 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 1b8a3b626..bc859df48 100644 --- a/test/pleroma/web/mastodon_api/controllers/status_controller_test.exs +++ b/test/pleroma/web/mastodon_api/controllers/status_controller_test.exs @@ -2248,8 +2248,10 @@ defmodule Pleroma.Web.MastodonAPI.StatusControllerTest do setup do: clear_config([:rate_limit, :statuses_actions], {60_000, 100}) setup do: oauth_access(["write:statuses", "write:favourites"]) - for {action, undo} <- [{"favourite", "unfavourite"}, {"reblog", "unreblog"}] do - test "#{action} is limited per status, not per user", %{conn: conn} do + for {action, undo} <- [{"favourite", "unfavourite"}, {"reblog", "unreblog"}], + strict <- [true, false] do + test "#{action} is limited per status, not per user (strict: #{strict})", %{conn: conn} do + clear_config([Pleroma.Web.ApiSpec.CastAndValidate, :strict], unquote(strict)) conn = put_req_header(conn, "content-type", "application/json") statuses = insert_list(3, :note_activity)