From 1742a0245378a7b107355881a35390f985133eca Mon Sep 17 00:00:00 2001 From: Viktor Baranov Date: Wed, 15 Feb 2023 23:32:23 +0300 Subject: [PATCH] Allow disable API rate limit --- .github/workflows/config.yml | 1 + CHANGELOG.md | 1 + .../block_scout_web/views/access_helpers.ex | 44 ++++++------------- config/runtime.exs | 1 + docker-compose/envs/common-blockscout.env | 1 + docker/Makefile | 3 ++ 6 files changed, 20 insertions(+), 31 deletions(-) diff --git a/.github/workflows/config.yml b/.github/workflows/config.yml index 3a2a60d39c..9fd04878c9 100644 --- a/.github/workflows/config.yml +++ b/.github/workflows/config.yml @@ -579,6 +579,7 @@ jobs: ETHEREUM_JSONRPC_CASE: "EthereumJSONRPC.Case.Nethermind.Mox" ETHEREUM_JSONRPC_WEB_SOCKET_CASE: "EthereumJSONRPC.WebSocket.Case.Mox" CHAIN_ID: "77" + API_RATE_LIMIT_DISABLED: "true" ADMIN_PANEL_ENABLED: "true" ACCOUNT_ENABLED: "true" ACCOUNT_REDIS_URL: "redis://localhost:6379" diff --git a/CHANGELOG.md b/CHANGELOG.md index 71fa5ffe37..1e128affc9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,7 @@ ### Features - [#6897](https://github.com/blockscout/blockscout/pull/6897) - Support basic auth in JSON RPC endpoint +- [#6908](https://github.com/blockscout/blockscout/pull/6908) - Allow disable API rate limit ### Fixes diff --git a/apps/block_scout_web/lib/block_scout_web/views/access_helpers.ex b/apps/block_scout_web/lib/block_scout_web/views/access_helpers.ex index ad89312b5f..9f0f70bce2 100644 --- a/apps/block_scout_web/lib/block_scout_web/views/access_helpers.ex +++ b/apps/block_scout_web/lib/block_scout_web/views/access_helpers.ex @@ -48,7 +48,7 @@ defmodule BlockScoutWeb.AccessHelpers do end def check_rate_limit(conn) do - if Mix.env() == :test do + if Application.get_env(:block_scout_web, :api_rate_limit)[:disabled] == true do :ok else global_api_rate_limit = Application.get_env(:block_scout_web, :api_rate_limit)[:global_limit] @@ -65,15 +65,15 @@ defmodule BlockScoutWeb.AccessHelpers do cond do check_api_key(conn) && get_api_key(conn) == static_api_key -> - rate_limit_by_key(static_api_key, api_rate_limit_by_key) + rate_limit_by_param(static_api_key, api_rate_limit_by_key) check_api_key(conn) && !is_nil(plan) -> conn |> get_api_key() - |> rate_limit_by_key(plan.max_req_per_second) + |> rate_limit_by_param(plan.max_req_per_second) Enum.member?(api_rate_limit_whitelisted_ips(), ip_string) -> - rate_limit_by_ip(ip_string, api_rate_limit_by_ip) + rate_limit(ip_string, api_rate_limit_by_ip) true -> global_rate_limit(global_api_rate_limit) @@ -81,13 +81,9 @@ defmodule BlockScoutWeb.AccessHelpers do end end - defp check_api_key(conn) do - conn.query_params && Map.has_key?(conn.query_params, "apikey") - end + defp check_api_key(conn), do: conn.query_params && Map.has_key?(conn.query_params, "apikey") - defp get_api_key(conn) do - Map.get(conn.query_params, "apikey") - end + defp get_api_key(conn), do: Map.get(conn.query_params, "apikey") defp get_plan(query_params) do with true <- query_params && Map.has_key?(query_params, "apikey"), @@ -101,28 +97,16 @@ defmodule BlockScoutWeb.AccessHelpers do end end - defp rate_limit_by_key(api_key, api_rate_limit_by_key) do - case Hammer.check_rate("api-#{api_key}", 1_000, api_rate_limit_by_key) do - {:allow, _count} -> - :ok - - {:deny, _limit} -> - :rate_limit_reached - end + defp rate_limit_by_param(key, value) do + rate_limit("api-#{key}", value) end - defp rate_limit_by_ip(ip_string, api_rate_limit_by_ip) do - case Hammer.check_rate("api-#{ip_string}", 1_000, api_rate_limit_by_ip) do - {:allow, _count} -> - :ok - - {:deny, _limit} -> - :rate_limit_reached - end + defp global_rate_limit(global_api_rate_limit) do + rate_limit("api", global_api_rate_limit) end - defp global_rate_limit(global_api_rate_limit) do - case Hammer.check_rate("api", 1_000, global_api_rate_limit) do + defp rate_limit(key, value) do + case Hammer.check_rate(key, 1_000, value) do {:allow, _count} -> :ok @@ -131,9 +115,7 @@ defmodule BlockScoutWeb.AccessHelpers do end end - defp get_restricted_key(%Phoenix.Socket{}) do - nil - end + defp get_restricted_key(%Phoenix.Socket{}), do: nil defp get_restricted_key(conn) do conn_with_params = Conn.fetch_query_params(conn) diff --git a/config/runtime.exs b/config/runtime.exs index 33f0f04165..478d652968 100644 --- a/config/runtime.exs +++ b/config/runtime.exs @@ -136,6 +136,7 @@ api_rate_limit_by_ip_value = end config :block_scout_web, :api_rate_limit, + disabled: System.get_env("API_RATE_LIMIT_DISABLED", "false") == "true", global_limit: global_api_rate_limit_value, limit_by_key: api_rate_limit_by_key_value, limit_by_ip: api_rate_limit_by_ip_value, diff --git a/docker-compose/envs/common-blockscout.env b/docker-compose/envs/common-blockscout.env index 30032211ef..9b5cc00c60 100644 --- a/docker-compose/envs/common-blockscout.env +++ b/docker-compose/envs/common-blockscout.env @@ -135,6 +135,7 @@ MAX_STRING_LENGTH_WITHOUT_TRIMMING=2040 RE_CAPTCHA_SECRET_KEY= RE_CAPTCHA_CLIENT_KEY= JSON_RPC= +#API_RATE_LIMIT_DISABLED=true API_RATE_LIMIT=50 API_RATE_LIMIT_BY_KEY=50 API_RATE_LIMIT_BY_IP=50 diff --git a/docker/Makefile b/docker/Makefile index 2d7ef55d13..9c1ba7123c 100644 --- a/docker/Makefile +++ b/docker/Makefile @@ -373,6 +373,9 @@ endif ifdef API_RATE_LIMIT_WHITELISTED_IPS BLOCKSCOUT_CONTAINER_PARAMS += -e 'API_RATE_LIMIT_WHITELISTED_IPS=$(API_RATE_LIMIT_WHITELISTED_IPS)' endif +ifdef API_RATE_LIMIT_DISABLED + BLOCKSCOUT_CONTAINER_PARAMS += -e 'API_RATE_LIMIT_DISABLED=$(API_RATE_LIMIT_DISABLED)' +endif ifdef TOKEN_BALANCE_ON_DEMAND_FETCHER_THRESHOLD_MINUTES BLOCKSCOUT_CONTAINER_PARAMS += -e 'TOKEN_BALANCE_ON_DEMAND_FETCHER_THRESHOLD_MINUTES=$(TOKEN_BALANCE_ON_DEMAND_FETCHER_THRESHOLD_MINUTES)' endif