From fcb1f172c74fbbfbb2594cb94cdfc7cdbab7927d Mon Sep 17 00:00:00 2001 From: Gustavo Inacio Date: Tue, 19 Nov 2024 14:23:08 -0600 Subject: [PATCH 1/5] refactor: remove auth check inside route Signed-off-by: Gustavo Inacio --- crates/service/src/routes/static_subgraph.rs | 30 ++------------------ 1 file changed, 2 insertions(+), 28 deletions(-) diff --git a/crates/service/src/routes/static_subgraph.rs b/crates/service/src/routes/static_subgraph.rs index 61551cb31..a2051001b 100644 --- a/crates/service/src/routes/static_subgraph.rs +++ b/crates/service/src/routes/static_subgraph.rs @@ -1,7 +1,7 @@ // Copyright 2023-, Edge & Node, GraphOps, and Semiotic Labs. // SPDX-License-Identifier: Apache-2.0 -use axum::{body::Bytes, http::HeaderMap, response::IntoResponse, Extension, Json}; +use axum::{body::Bytes, response::IntoResponse, Extension, Json}; use reqwest::StatusCode; use serde_json::json; use tracing::warn; @@ -11,24 +11,8 @@ use indexer_common::SubgraphClient; #[autometrics::autometrics] pub async fn static_subgraph_request_handler( Extension(subgraph_client): Extension<&'static SubgraphClient>, - Extension(required_auth_token): Extension>, - headers: HeaderMap, body: Bytes, ) -> Result { - if let Some(required_auth_token) = required_auth_token { - let authorization = headers - .get("authorization") - .map(|value| value.to_str()) - .transpose() - .map_err(|_| StaticSubgraphError::Unauthorized)? - .ok_or_else(|| StaticSubgraphError::Unauthorized)? - .trim_start_matches("Bearer "); - - if authorization != required_auth_token { - return Err(StaticSubgraphError::Unauthorized); - } - } - let response = subgraph_client.query_raw(body).await?; Ok(( @@ -42,9 +26,6 @@ pub async fn static_subgraph_request_handler( #[derive(Debug, thiserror::Error)] pub enum StaticSubgraphError { - #[error("No valid receipt or free query auth token provided")] - Unauthorized, - #[error("Failed to query subgraph: {0}")] FailedToQuery(#[from] anyhow::Error), @@ -54,16 +35,9 @@ pub enum StaticSubgraphError { impl IntoResponse for StaticSubgraphError { fn into_response(self) -> axum::response::Response { - let status = match self { - StaticSubgraphError::Unauthorized => StatusCode::UNAUTHORIZED, - StaticSubgraphError::FailedToQuery(_) | StaticSubgraphError::FailedToParse(_) => { - StatusCode::INTERNAL_SERVER_ERROR - } - }; - tracing::error!(%self, "StaticSubgraphError occoured."); ( - status, + StatusCode::INTERNAL_SERVER_ERROR, Json(json! {{ "message": self.to_string(), }}), From a24c95cb6db3cfb15843d985f9bd9537c50048fc Mon Sep 17 00:00:00 2001 From: Gustavo Inacio Date: Tue, 19 Nov 2024 14:23:45 -0600 Subject: [PATCH 2/5] refactor: remove extension layer from indexer_service Signed-off-by: Gustavo Inacio --- crates/service/src/service/indexer_service.rs | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/crates/service/src/service/indexer_service.rs b/crates/service/src/service/indexer_service.rs index d94eca750..1f7af13a4 100644 --- a/crates/service/src/service/indexer_service.rs +++ b/crates/service/src/service/indexer_service.rs @@ -10,7 +10,7 @@ use axum::{ async_trait, response::{IntoResponse, Response}, routing::{get, post}, - Extension, Json, Router, + Json, Router, }; use axum::{serve, ServiceExt}; use build_info::BuildInfo; @@ -409,7 +409,6 @@ impl IndexerService { "/network", post(static_subgraph_request_handler) .route_layer(Extension(network_subgraph)) - .route_layer(Extension(options.config.service.serve_auth_token.clone())) .route_layer(static_subgraph_rate_limiter.clone()), ); } @@ -420,7 +419,6 @@ impl IndexerService { misc_routes = misc_routes .route("/escrow", post(static_subgraph_request_handler)) .route_layer(Extension(escrow_subgraph)) - .route_layer(Extension(options.config.service.serve_auth_token.clone())) .route_layer(static_subgraph_rate_limiter); } From ffccc0ffddc461b78d680c5766a92b06f6fe5f37 Mon Sep 17 00:00:00 2001 From: Gustavo Inacio Date: Tue, 19 Nov 2024 14:27:50 -0600 Subject: [PATCH 3/5] refactor: add validate request layer to escrow Signed-off-by: Gustavo Inacio --- Cargo.lock | 2 ++ crates/service/Cargo.toml | 1 + crates/service/src/service/indexer_service.rs | 23 ++++++++++++++----- 3 files changed, 20 insertions(+), 6 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index a953b4f74..e3342ff2b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -7060,11 +7060,13 @@ version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1e9cd434a998747dd2c4276bc96ee2e0c7a2eadf3cae88e52be55a05fa9053f5" dependencies = [ + "base64 0.21.7", "bitflags 2.6.0", "bytes", "http 1.1.0", "http-body 1.0.1", "http-body-util", + "mime", "pin-project-lite", "tower-layer", "tower-service", diff --git a/crates/service/Cargo.toml b/crates/service/Cargo.toml index 7c5162ea3..65a1c0a57 100644 --- a/crates/service/Cargo.toml +++ b/crates/service/Cargo.toml @@ -39,6 +39,7 @@ uuid.workspace = true alloy.workspace = true tower_governor = "0.4.0" tower-http = { version = "0.5.2", features = [ + "auth", "cors", "normalize-path", "trace", diff --git a/crates/service/src/service/indexer_service.rs b/crates/service/src/service/indexer_service.rs index 1f7af13a4..958ca37c1 100644 --- a/crates/service/src/service/indexer_service.rs +++ b/crates/service/src/service/indexer_service.rs @@ -36,7 +36,9 @@ use tokio::net::TcpListener; use tokio::signal; use tokio::sync::watch::Receiver; use tower_governor::{governor::GovernorConfigBuilder, GovernorLayer}; +use tower_http::validate_request::ValidateRequestHeaderLayer; use tower_http::{cors, cors::CorsLayer, normalize_path::NormalizePath, trace::TraceLayer}; +use tracing::warn; use tracing::{error, info, info_span}; use crate::routes::health; @@ -414,12 +416,21 @@ impl IndexerService { } if options.config.service.serve_escrow_subgraph { - info!("Serving escrow subgraph at /escrow"); - - misc_routes = misc_routes - .route("/escrow", post(static_subgraph_request_handler)) - .route_layer(Extension(escrow_subgraph)) - .route_layer(static_subgraph_rate_limiter); + if let Some(free_auth_token) = &options.config.service.serve_auth_token { + info!("Serving escrow subgraph at /escrow"); + + let auth_layer = ValidateRequestHeaderLayer::bearer(free_auth_token); + + misc_routes = misc_routes + .route( + "/escrow", + post(static_subgraph_request_handler).route_layer(auth_layer), + ) + .route_layer(Extension(escrow_subgraph)) + .route_layer(static_subgraph_rate_limiter); + } else { + warn!("`serve_escrow_subgraph` is enabled but no `serve_auth_token` provided. Disabling it."); + } } misc_routes = misc_routes.with_state(state.clone()); From 2fc04f711a9c8c92c8e0c392a37282435713d015 Mon Sep 17 00:00:00 2001 From: Gustavo Inacio Date: Tue, 19 Nov 2024 14:29:07 -0600 Subject: [PATCH 4/5] refactor: use validate request for network Signed-off-by: Gustavo Inacio --- crates/service/src/service/indexer_service.rs | 26 ++++++++++++------- 1 file changed, 17 insertions(+), 9 deletions(-) diff --git a/crates/service/src/service/indexer_service.rs b/crates/service/src/service/indexer_service.rs index 958ca37c1..f55fe8965 100644 --- a/crates/service/src/service/indexer_service.rs +++ b/crates/service/src/service/indexer_service.rs @@ -405,14 +405,21 @@ impl IndexerService { .layer(misc_rate_limiter); if options.config.service.serve_network_subgraph { - info!("Serving network subgraph at /network"); + if let Some(free_auth_token) = &options.config.service.serve_auth_token { + info!("Serving network subgraph at /network"); - misc_routes = misc_routes.route( - "/network", - post(static_subgraph_request_handler) - .route_layer(Extension(network_subgraph)) - .route_layer(static_subgraph_rate_limiter.clone()), - ); + let auth_layer = ValidateRequestHeaderLayer::bearer(free_auth_token); + + misc_routes = misc_routes.route( + "/network", + post(static_subgraph_request_handler) + .route_layer(auth_layer) + .route_layer(Extension(network_subgraph)) + .route_layer(static_subgraph_rate_limiter.clone()), + ); + } else { + warn!("`serve_network_subgraph` is enabled but no `serve_auth_token` provided. Disabling it."); + } } if options.config.service.serve_escrow_subgraph { @@ -424,9 +431,10 @@ impl IndexerService { misc_routes = misc_routes .route( "/escrow", - post(static_subgraph_request_handler).route_layer(auth_layer), + post(static_subgraph_request_handler) + .route_layer(auth_layer) + .route_layer(Extension(escrow_subgraph)), ) - .route_layer(Extension(escrow_subgraph)) .route_layer(static_subgraph_rate_limiter); } else { warn!("`serve_escrow_subgraph` is enabled but no `serve_auth_token` provided. Disabling it."); From 6a29e6e746dfe19ad6a48ccaaa0d648150a850bd Mon Sep 17 00:00:00 2001 From: Gustavo Inacio Date: Tue, 19 Nov 2024 14:30:49 -0600 Subject: [PATCH 5/5] refactor: use subgraph client as state Signed-off-by: Gustavo Inacio --- crates/service/src/routes/static_subgraph.rs | 4 ++-- crates/service/src/service/indexer_service.rs | 17 ++++++++--------- 2 files changed, 10 insertions(+), 11 deletions(-) diff --git a/crates/service/src/routes/static_subgraph.rs b/crates/service/src/routes/static_subgraph.rs index a2051001b..b2447b0ac 100644 --- a/crates/service/src/routes/static_subgraph.rs +++ b/crates/service/src/routes/static_subgraph.rs @@ -1,7 +1,7 @@ // Copyright 2023-, Edge & Node, GraphOps, and Semiotic Labs. // SPDX-License-Identifier: Apache-2.0 -use axum::{body::Bytes, response::IntoResponse, Extension, Json}; +use axum::{body::Bytes, extract::State, response::IntoResponse, Json}; use reqwest::StatusCode; use serde_json::json; use tracing::warn; @@ -10,7 +10,7 @@ use indexer_common::SubgraphClient; #[autometrics::autometrics] pub async fn static_subgraph_request_handler( - Extension(subgraph_client): Extension<&'static SubgraphClient>, + State(subgraph_client): State<&'static SubgraphClient>, body: Bytes, ) -> Result { let response = subgraph_client.query_raw(body).await?; diff --git a/crates/service/src/service/indexer_service.rs b/crates/service/src/service/indexer_service.rs index f55fe8965..a36bd2dff 100644 --- a/crates/service/src/service/indexer_service.rs +++ b/crates/service/src/service/indexer_service.rs @@ -414,7 +414,7 @@ impl IndexerService { "/network", post(static_subgraph_request_handler) .route_layer(auth_layer) - .route_layer(Extension(network_subgraph)) + .with_state(network_subgraph) .route_layer(static_subgraph_rate_limiter.clone()), ); } else { @@ -428,14 +428,13 @@ impl IndexerService { let auth_layer = ValidateRequestHeaderLayer::bearer(free_auth_token); - misc_routes = misc_routes - .route( - "/escrow", - post(static_subgraph_request_handler) - .route_layer(auth_layer) - .route_layer(Extension(escrow_subgraph)), - ) - .route_layer(static_subgraph_rate_limiter); + misc_routes = misc_routes.route( + "/escrow", + post(static_subgraph_request_handler) + .route_layer(auth_layer) + .with_state(escrow_subgraph) + .route_layer(static_subgraph_rate_limiter), + ) } else { warn!("`serve_escrow_subgraph` is enabled but no `serve_auth_token` provided. Disabling it."); }