diff --git a/config/config.exs b/config/config.exs index 0dde1fc85..9c4eb70a3 100644 --- a/config/config.exs +++ b/config/config.exs @@ -599,6 +599,7 @@ config :http_signatures, config :pleroma, :rate_limit, authentication: {60_000, 15}, + timeline: {500, 3}, search: [{1000, 10}, {1000, 30}], app_account_creation: {1_800_000, 25}, relations_actions: {10_000, 10}, diff --git a/config/description.exs b/config/description.exs index bcb69bc41..9fdcfcd96 100644 --- a/config/description.exs +++ b/config/description.exs @@ -2465,6 +2465,12 @@ config :pleroma, :config_description, [ description: "For the search requests (account & status search etc.)", suggestions: [{1000, 10}, [{10_000, 10}, {10_000, 50}]] }, + %{ + key: :timeline, + type: [:tuple, {:list, :tuple}], + description: "For requests to timelines (each timeline has it's own limiter)", + suggestions: [{1000, 10}, [{10_000, 10}, {10_000, 50}]] + }, %{ key: :app_account_creation, type: [:tuple, {:list, :tuple}], diff --git a/docs/configuration/cheatsheet.md b/docs/configuration/cheatsheet.md index ac55a0b32..1cffae977 100644 --- a/docs/configuration/cheatsheet.md +++ b/docs/configuration/cheatsheet.md @@ -343,6 +343,7 @@ Means that: Supported rate limiters: * `:search` - Account/Status search. +* `:timeline` - Timeline requests (each timeline has it's own limiter). * `:app_account_creation` - Account registration from the API. * `:relations_actions` - Following/Unfollowing in general. * `:relation_id_action` - Following/Unfollowing for a specific user. diff --git a/lib/pleroma/web/mastodon_api/controllers/timeline_controller.ex b/lib/pleroma/web/mastodon_api/controllers/timeline_controller.ex index 29964a1d4..f58c1f93c 100644 --- a/lib/pleroma/web/mastodon_api/controllers/timeline_controller.ex +++ b/lib/pleroma/web/mastodon_api/controllers/timeline_controller.ex @@ -10,9 +10,20 @@ defmodule Pleroma.Web.MastodonAPI.TimelineController do alias Pleroma.Pagination alias Pleroma.Plugs.OAuthScopesPlug + alias Pleroma.Plugs.RateLimiter alias Pleroma.User alias Pleroma.Web.ActivityPub.ActivityPub + # XXX: Ideally these would be generated instead of copypasted, + # but I haven't been able to overcome an issue with guards when + # trying to generate these. + # See: https://elixirforum.com/t/trouble-plugging-plugs-with-generated-options-in-guards-in-a-phoenix-controller/29465 + plug(RateLimiter, [name: :timeline, bucket_name: :direct_timeline] when action == :direct) + plug(RateLimiter, [name: :timeline, bucket_name: :public_timeline] when action == :public) + plug(RateLimiter, [name: :timeline, bucket_name: :home_timeline] when action == :home) + plug(RateLimiter, [name: :timeline, bucket_name: :hashtag_timeline] when action == :hashtag) + plug(RateLimiter, [name: :timeline, bucket_name: :list_timeline] when action == :list) + plug(OAuthScopesPlug, %{scopes: ["read:statuses"]} when action in [:home, :direct]) plug(OAuthScopesPlug, %{scopes: ["read:lists"]} when action == :list)