|
|
@ -48,7 +48,7 @@ defmodule BlockScoutWeb.AccessHelpers do |
|
|
|
end |
|
|
|
end |
|
|
|
|
|
|
|
|
|
|
|
def check_rate_limit(conn) do |
|
|
|
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 |
|
|
|
:ok |
|
|
|
else |
|
|
|
else |
|
|
|
global_api_rate_limit = Application.get_env(:block_scout_web, :api_rate_limit)[:global_limit] |
|
|
|
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 |
|
|
|
cond do |
|
|
|
check_api_key(conn) && get_api_key(conn) == static_api_key -> |
|
|
|
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) -> |
|
|
|
check_api_key(conn) && !is_nil(plan) -> |
|
|
|
conn |
|
|
|
conn |
|
|
|
|> get_api_key() |
|
|
|
|> 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) -> |
|
|
|
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 -> |
|
|
|
true -> |
|
|
|
global_rate_limit(global_api_rate_limit) |
|
|
|
global_rate_limit(global_api_rate_limit) |
|
|
@ -81,13 +81,9 @@ defmodule BlockScoutWeb.AccessHelpers do |
|
|
|
end |
|
|
|
end |
|
|
|
end |
|
|
|
end |
|
|
|
|
|
|
|
|
|
|
|
defp check_api_key(conn) do |
|
|
|
defp check_api_key(conn), do: conn.query_params && Map.has_key?(conn.query_params, "apikey") |
|
|
|
conn.query_params && Map.has_key?(conn.query_params, "apikey") |
|
|
|
|
|
|
|
end |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
defp get_api_key(conn) do |
|
|
|
defp get_api_key(conn), do: Map.get(conn.query_params, "apikey") |
|
|
|
Map.get(conn.query_params, "apikey") |
|
|
|
|
|
|
|
end |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
defp get_plan(query_params) do |
|
|
|
defp get_plan(query_params) do |
|
|
|
with true <- query_params && Map.has_key?(query_params, "apikey"), |
|
|
|
with true <- query_params && Map.has_key?(query_params, "apikey"), |
|
|
@ -101,28 +97,16 @@ defmodule BlockScoutWeb.AccessHelpers do |
|
|
|
end |
|
|
|
end |
|
|
|
end |
|
|
|
end |
|
|
|
|
|
|
|
|
|
|
|
defp rate_limit_by_key(api_key, api_rate_limit_by_key) do |
|
|
|
defp rate_limit_by_param(key, value) do |
|
|
|
case Hammer.check_rate("api-#{api_key}", 1_000, api_rate_limit_by_key) do |
|
|
|
rate_limit("api-#{key}", value) |
|
|
|
{:allow, _count} -> |
|
|
|
|
|
|
|
:ok |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
{:deny, _limit} -> |
|
|
|
|
|
|
|
:rate_limit_reached |
|
|
|
|
|
|
|
end |
|
|
|
|
|
|
|
end |
|
|
|
end |
|
|
|
|
|
|
|
|
|
|
|
defp rate_limit_by_ip(ip_string, api_rate_limit_by_ip) do |
|
|
|
defp global_rate_limit(global_api_rate_limit) do |
|
|
|
case Hammer.check_rate("api-#{ip_string}", 1_000, api_rate_limit_by_ip) do |
|
|
|
rate_limit("api", global_api_rate_limit) |
|
|
|
{:allow, _count} -> |
|
|
|
|
|
|
|
:ok |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
{:deny, _limit} -> |
|
|
|
|
|
|
|
:rate_limit_reached |
|
|
|
|
|
|
|
end |
|
|
|
|
|
|
|
end |
|
|
|
end |
|
|
|
|
|
|
|
|
|
|
|
defp global_rate_limit(global_api_rate_limit) do |
|
|
|
defp rate_limit(key, value) do |
|
|
|
case Hammer.check_rate("api", 1_000, global_api_rate_limit) do |
|
|
|
case Hammer.check_rate(key, 1_000, value) do |
|
|
|
{:allow, _count} -> |
|
|
|
{:allow, _count} -> |
|
|
|
:ok |
|
|
|
:ok |
|
|
|
|
|
|
|
|
|
|
@ -131,9 +115,7 @@ defmodule BlockScoutWeb.AccessHelpers do |
|
|
|
end |
|
|
|
end |
|
|
|
end |
|
|
|
end |
|
|
|
|
|
|
|
|
|
|
|
defp get_restricted_key(%Phoenix.Socket{}) do |
|
|
|
defp get_restricted_key(%Phoenix.Socket{}), do: nil |
|
|
|
nil |
|
|
|
|
|
|
|
end |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
defp get_restricted_key(conn) do |
|
|
|
defp get_restricted_key(conn) do |
|
|
|
conn_with_params = Conn.fetch_query_params(conn) |
|
|
|
conn_with_params = Conn.fetch_query_params(conn) |
|
|
|