diff --git a/changelog.d/status-id-action-rate-limit.fix b/changelog.d/status-id-action-rate-limit.fix new file mode 100644 index 000000000..030eeb0df --- /dev/null +++ b/changelog.d/status-id-action-rate-limit.fix @@ -0,0 +1 @@ +Rate limit favourites and reblogs per status, not across all statuses diff --git a/lib/pleroma/web/mastodon_api/controllers/status_controller.ex b/lib/pleroma/web/mastodon_api/controllers/status_controller.ex index 6cd7469f9..c5210d588 100644 --- a/lib/pleroma/web/mastodon_api/controllers/status_controller.ex +++ b/lib/pleroma/web/mastodon_api/controllers/status_controller.ex @@ -92,13 +92,13 @@ defmodule Pleroma.Web.MastodonAPI.StatusController do plug( RateLimiter, - [name: :status_id_action, bucket_name: "status_id_action:reblog_unreblog", params: [:id]] + [name: :status_id_action, bucket_name: "status_id_action:reblog_unreblog", params: ["id"]] when action in ~w(reblog unreblog)a ) plug( RateLimiter, - [name: :status_id_action, bucket_name: "status_id_action:fav_unfav", params: [:id]] + [name: :status_id_action, bucket_name: "status_id_action:fav_unfav", params: ["id"]] when action in ~w(favourite unfavourite)a ) 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 6ee79689d..1b8a3b626 100644 --- a/test/pleroma/web/mastodon_api/controllers/status_controller_test.exs +++ b/test/pleroma/web/mastodon_api/controllers/status_controller_test.exs @@ -2243,6 +2243,29 @@ defmodule Pleroma.Web.MastodonAPI.StatusControllerTest do |> json_response_and_validate_schema(404) == %{"error" => "Record not found"} end + describe "status_id_action rate limit" do + setup do: clear_config([:rate_limit, :status_id_action], {60_000, 2}) + 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 + conn = put_req_header(conn, "content-type", "application/json") + statuses = insert_list(3, :note_activity) + + assert Enum.map( + statuses, + &post(conn, "/api/v1/statuses/#{&1.id}/#{unquote(action)}").status + ) == + [200, 200, 200] + + status = hd(statuses) + assert post(conn, "/api/v1/statuses/#{status.id}/#{unquote(undo)}").status == 200 + assert post(conn, "/api/v1/statuses/#{status.id}/#{unquote(action)}").status == 429 + end + end + end + describe "pinned statuses" do setup do: oauth_access(["write:accounts"])