refactor: use middleware to check if GraphQL API is enabled (#10772)

pull/10854/head
Fedor Ivanov 2 months ago committed by GitHub
parent 36e6f8307b
commit ea9e806bd5
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
  1. 19
      apps/block_scout_web/lib/block_scout_web/graphql/middleware/api_enabled.ex
  2. 25
      apps/block_scout_web/lib/block_scout_web/graphql/resolvers/address.ex
  3. 33
      apps/block_scout_web/lib/block_scout_web/graphql/resolvers/block.ex
  4. 9
      apps/block_scout_web/lib/block_scout_web/graphql/resolvers/helper.ex
  5. 21
      apps/block_scout_web/lib/block_scout_web/graphql/resolvers/internal_transaction.ex
  6. 13
      apps/block_scout_web/lib/block_scout_web/graphql/resolvers/token.ex
  7. 37
      apps/block_scout_web/lib/block_scout_web/graphql/resolvers/token_transfer.ex
  8. 39
      apps/block_scout_web/lib/block_scout_web/graphql/resolvers/transaction.ex
  9. 10
      apps/block_scout_web/lib/block_scout_web/graphql/schema.ex
  10. 17
      apps/explorer/lib/explorer/graphql.ex

@ -0,0 +1,19 @@
defmodule BlockScoutWeb.GraphQL.Middleware.ApiEnabled do
@moduledoc """
Middleware to check if the GraphQL API is enabled.
"""
alias Absinthe.Resolution
@behaviour Absinthe.Middleware
@api_is_disabled "GraphQL API is disabled."
def call(resolution, _config) do
if resolution.context.api_enabled do
resolution
else
resolution
|> Resolution.put_result({:error, @api_is_disabled})
end
end
end

@ -1,28 +1,19 @@
defmodule BlockScoutWeb.GraphQL.Resolvers.Address do
@moduledoc false
alias BlockScoutWeb.GraphQL.Resolvers.Helper
alias Explorer.Chain
def get_by(_, %{hashes: hashes}, resolution) do
if resolution.context.api_enabled do
case Chain.hashes_to_addresses(hashes) do
[] -> {:error, "Addresses not found."}
result -> {:ok, result}
end
else
{:error, Helper.api_is_disabled()}
def get_by(_, %{hashes: hashes}, _) do
case Chain.hashes_to_addresses(hashes) do
[] -> {:error, "Addresses not found."}
result -> {:ok, result}
end
end
def get_by(_, %{hash: hash}, resolution) do
if resolution.context.api_enabled do
case Chain.hash_to_address(hash) do
{:error, :not_found} -> {:error, "Address not found."}
{:ok, _} = result -> result
end
else
{:error, Helper.api_is_disabled()}
def get_by(_, %{hash: hash}, _) do
case Chain.hash_to_address(hash) do
{:error, :not_found} -> {:error, "Address not found."}
{:ok, _} = result -> result
end
end
end

@ -1,29 +1,32 @@
defmodule BlockScoutWeb.GraphQL.Resolvers.Block do
@moduledoc false
alias BlockScoutWeb.GraphQL.Resolvers.Helper
alias Explorer.Chain
alias Explorer.Chain.Transaction
@api_true [api?: true]
def get_by(_, %{number: number}, resolution) do
with {:api_enabled, true} <- {:api_enabled, resolution.context.api_enabled},
{:ok, _} = result <- Chain.number_to_block(number, @api_true) do
result
else
{:api_enabled, false} -> {:error, Helper.api_is_disabled()}
{:error, :not_found} -> {:error, "Block number #{number} was not found."}
def get_by(_, %{number: number}, _) do
number
|> Chain.number_to_block(@api_true)
|> case do
{:ok, _} = result ->
result
{:error, :not_found} ->
{:error, "Block number #{number} was not found."}
end
end
def get_by(%Transaction{block_hash: hash}, _, resolution) do
with {:api_enabled, true} <- {:api_enabled, resolution.context.api_enabled},
{:ok, _} = result <- Chain.hash_to_block(hash, @api_true) do
result
else
{:api_enabled, false} -> {:error, Helper.api_is_disabled()}
{:error, :not_found} -> {:error, "Block hash #{to_string(hash)} was not found."}
def get_by(%Transaction{block_hash: hash}, _, _) do
hash
|> Chain.hash_to_block(@api_true)
|> case do
{:ok, _} = result ->
result
{:error, :not_found} ->
{:error, "Block hash #{to_string(hash)} was not found."}
end
end
end

@ -1,9 +0,0 @@
defmodule BlockScoutWeb.GraphQL.Resolvers.Helper do
@moduledoc """
Helper functions for BlockScoutWeb.GraphQL.Resolvers modules
"""
@api_is_disabled "GraphQL API is disabled."
def api_is_disabled, do: @api_is_disabled
end

@ -2,26 +2,17 @@ defmodule BlockScoutWeb.GraphQL.Resolvers.InternalTransaction do
@moduledoc false
alias Absinthe.Relay.Connection
alias BlockScoutWeb.GraphQL.Resolvers.Helper
alias Explorer.Chain.Transaction
alias Explorer.{GraphQL, Repo}
def get_by(%{transaction_hash: _, index: _} = args, resolution) do
if resolution.context.api_enabled do
GraphQL.get_internal_transaction(args)
else
{:error, Helper.api_is_disabled()}
end
def get_by(%{transaction_hash: _, index: _} = args, _) do
GraphQL.get_internal_transaction(args)
end
def get_by(%Transaction{} = transaction, args, resolution) do
if resolution.context.api_enabled do
transaction
|> GraphQL.transaction_to_internal_transactions_query()
|> Connection.from_query(&Repo.all/1, args, options(args))
else
{:error, Helper.api_is_disabled()}
end
def get_by(%Transaction{} = transaction, args, _) do
transaction
|> GraphQL.transaction_to_internal_transactions_query()
|> Connection.from_query(&Repo.all/1, args, options(args))
end
defp options(%{before: _}), do: []

@ -1,19 +1,10 @@
defmodule BlockScoutWeb.GraphQL.Resolvers.Token do
@moduledoc false
alias BlockScoutWeb.GraphQL.Resolvers.Helper
alias Explorer.Chain.TokenTransfer
alias Explorer.GraphQL
def get_by(
%TokenTransfer{token_contract_address_hash: token_contract_address_hash},
_,
resolution
) do
if resolution.context.api_enabled do
GraphQL.get_token(%{contract_address_hash: token_contract_address_hash})
else
{:error, Helper.api_is_disabled()}
end
def get_by(%TokenTransfer{token_contract_address_hash: token_contract_address_hash}, _, _) do
GraphQL.get_token(%{contract_address_hash: token_contract_address_hash})
end
end

@ -2,40 +2,27 @@ defmodule BlockScoutWeb.GraphQL.Resolvers.TokenTransfer do
@moduledoc false
alias Absinthe.Relay.Connection
alias BlockScoutWeb.GraphQL.Resolvers.Helper
alias Explorer.Chain.{Address, TokenTransfer}
alias Explorer.{GraphQL, Repo}
def get_by(%{transaction_hash: _, log_index: _} = args, resolution) do
if resolution.context.api_enabled do
GraphQL.get_token_transfer(args)
else
{:error, Helper.api_is_disabled()}
end
def get_by(%{transaction_hash: _, log_index: _} = args, _) do
GraphQL.get_token_transfer(args)
end
def get_by(_, %{token_contract_address_hash: token_contract_address_hash} = args, resolution) do
if resolution.context.api_enabled do
connection_args = Map.take(args, [:after, :before, :first, :last])
def get_by(_, %{token_contract_address_hash: token_contract_address_hash} = args, _) do
connection_args = Map.take(args, [:after, :before, :first, :last])
token_contract_address_hash
|> GraphQL.list_token_transfers_query()
|> Connection.from_query(&Repo.replica().all/1, connection_args, options(args))
else
{:error, Helper.api_is_disabled()}
end
token_contract_address_hash
|> GraphQL.list_token_transfers_query()
|> Connection.from_query(&Repo.replica().all/1, connection_args, options(args))
end
def get_by(%Address{hash: address_hash}, args, resolution) do
if resolution.context.api_enabled do
connection_args = Map.take(args, [:after, :before, :first, :last])
def get_by(%Address{hash: address_hash}, args, _) do
connection_args = Map.take(args, [:after, :before, :first, :last])
address_hash
|> TokenTransfer.token_transfers_by_address_hash(nil, [], nil)
|> Connection.from_query(&Repo.replica().all/1, connection_args, options(args))
else
{:error, Helper.api_is_disabled()}
end
address_hash
|> TokenTransfer.token_transfers_by_address_hash(nil, [], nil)
|> Connection.from_query(&Repo.replica().all/1, connection_args, options(args))
end
defp options(%{before: _}), do: []

@ -2,43 +2,22 @@ defmodule BlockScoutWeb.GraphQL.Resolvers.Transaction do
@moduledoc false
alias Absinthe.Relay.Connection
alias BlockScoutWeb.GraphQL.Resolvers.Helper
alias Explorer.{Chain, GraphQL, Repo}
alias Explorer.{GraphQL, Repo}
alias Explorer.Chain.{Address, TokenTransfer}
@api_true [api?: true]
def get_by(_, %{hash: hash}, _),
do: GraphQL.get_transaction_by_hash(hash)
def get_by(_, %{hash: hash}, resolution) do
with {:api_enabled, true} <- {:api_enabled, resolution.context.api_enabled},
{:ok, transaction} <- Chain.hash_to_transaction(hash, @api_true) do
{:ok, transaction}
else
{:api_enabled, false} -> {:error, Helper.api_is_disabled()}
{:error, :not_found} -> {:error, "Transaction not found."}
end
end
def get_by(%Address{hash: address_hash}, args, resolution) do
def get_by(%Address{hash: address_hash}, args, _) do
connection_args = Map.take(args, [:after, :before, :first, :last])
if resolution.context.api_enabled do
address_hash
|> GraphQL.address_to_transactions_query(args.order)
|> Connection.from_query(&Repo.replica().all/1, connection_args, options(args))
else
{:error, Helper.api_is_disabled()}
end
address_hash
|> GraphQL.address_to_transactions_query(args.order)
|> Connection.from_query(&Repo.replica().all/1, connection_args, options(args))
end
def get_by(%TokenTransfer{transaction_hash: hash}, _, resolution) do
with {:api_enabled, true} <- {:api_enabled, resolution.context.api_enabled},
{:ok, transaction} <- Chain.hash_to_transaction(hash, @api_true) do
{:ok, transaction}
else
{:api_enabled, false} -> {:error, Helper.api_is_disabled()}
{:error, :not_found} -> {:error, "Transaction not found."}
end
end
def get_by(%TokenTransfer{transaction_hash: hash}, _, _),
do: GraphQL.get_transaction_by_hash(hash)
defp options(%{before: _}), do: []

@ -4,9 +4,11 @@ defmodule BlockScoutWeb.GraphQL.Schema do
use Absinthe.Schema
use Absinthe.Relay.Schema, :modern
alias Absinthe.Middleware.Dataloader, as: AbsintheMiddlewareDataloader
alias Absinthe.Middleware.Dataloader, as: AbsintheDataloaderMiddleware
alias Absinthe.Plugin, as: AbsinthePlugin
alias BlockScoutWeb.GraphQL.Middleware.ApiEnabled, as: ApiEnabledMiddleware
alias BlockScoutWeb.GraphQL.Resolvers.{
Address,
Block,
@ -136,7 +138,11 @@ defmodule BlockScoutWeb.GraphQL.Schema do
end
end
def middleware(middleware, _field, _object) do
[ApiEnabledMiddleware | middleware]
end
def plugins do
[AbsintheMiddlewareDataloader] ++ AbsinthePlugin.defaults()
[AbsintheDataloaderMiddleware] ++ AbsinthePlugin.defaults()
end
end

@ -11,6 +11,8 @@ defmodule Explorer.GraphQL do
where: 3
]
alias Explorer.{Chain, Repo}
alias Explorer.Chain.{
Hash,
InternalTransaction,
@ -19,7 +21,7 @@ defmodule Explorer.GraphQL do
Transaction
}
alias Explorer.Repo
@api_true [api?: true]
@doc """
Returns a query to fetch transactions with a matching `to_address_hash`,
@ -96,6 +98,19 @@ defmodule Explorer.GraphQL do
end
end
@doc """
Returns a transaction for a given hash.
"""
@spec get_transaction_by_hash(Hash.t()) :: {:ok, Transaction.t()} | {:error, String.t()}
def get_transaction_by_hash(hash) do
hash
|> Chain.hash_to_transaction(@api_true)
|> case do
{:ok, _} = result -> result
{:error, :not_found} -> {:error, "Transaction not found."}
end
end
@doc """
Returns a query to fetch token transfers for a token contract address hash.

Loading…
Cancel
Save