From 5a924f62c1c6b51176a84aa0f163462d3a62ec0b Mon Sep 17 00:00:00 2001 From: Paul Masurel Date: Wed, 30 Oct 2024 17:41:00 +0900 Subject: [PATCH 1/6] authorization layer --- quickwit/Cargo.lock | 17 + quickwit/Cargo.toml | 8 +- quickwit/quickwit-codegen/example/Cargo.toml | 1 + .../example/src/authorization.rs | 26 ++ .../example/src/codegen/hello.rs | 36 +- quickwit/quickwit-codegen/example/src/lib.rs | 1 + quickwit/quickwit-codegen/src/codegen.rs | 28 +- quickwit/quickwit-ingest/Cargo.toml | 1 + quickwit/quickwit-ingest/src/authorize.rs | 25 ++ .../src/codegen/ingest_service.rs | 33 +- quickwit/quickwit-ingest/src/lib.rs | 1 + quickwit/quickwit-proto/Cargo.toml | 2 + quickwit/quickwit-proto/src/authorization.rs | 326 +++++++++++++++++ .../src/codegen/quickwit/quickwit.cluster.rs | 11 +- .../quickwit/quickwit.control_plane.rs | 99 ++++-- .../codegen/quickwit/quickwit.developer.rs | 11 +- .../src/codegen/quickwit/quickwit.indexing.rs | 11 +- .../quickwit/quickwit.ingest.ingester.rs | 102 ++++-- .../quickwit/quickwit.ingest.router.rs | 11 +- .../codegen/quickwit/quickwit.metastore.rs | 330 +++++++++++++----- quickwit/quickwit-proto/src/lib.rs | 1 + 21 files changed, 894 insertions(+), 187 deletions(-) create mode 100644 quickwit/quickwit-codegen/example/src/authorization.rs create mode 100644 quickwit/quickwit-ingest/src/authorize.rs create mode 100644 quickwit/quickwit-proto/src/authorization.rs diff --git a/quickwit/Cargo.lock b/quickwit/Cargo.lock index 558fe3bdede..f1851bba250 100644 --- a/quickwit/Cargo.lock +++ b/quickwit/Cargo.lock @@ -5947,6 +5947,19 @@ dependencies = [ "tracing", ] +[[package]] +name = "quickwit-auth" +version = "0.8.0" +dependencies = [ + "biscuit-auth", + "http 0.2.12", + "serde", + "thiserror", + "tokio", + "tonic", + "tracing", +] + [[package]] name = "quickwit-aws" version = "0.8.0" @@ -6072,6 +6085,7 @@ dependencies = [ "mockall", "prost 0.11.9", "quickwit-actors", + "quickwit-auth", "quickwit-codegen", "quickwit-common", "quickwit-proto", @@ -6350,6 +6364,7 @@ dependencies = [ "once_cell", "prost 0.11.9", "quickwit-actors", + "quickwit-auth", "quickwit-cluster", "quickwit-codegen", "quickwit-common", @@ -6601,6 +6616,7 @@ version = "0.8.0" dependencies = [ "anyhow", "async-trait", + "biscuit-auth", "bytes", "bytesize", "bytestring", @@ -6613,6 +6629,7 @@ dependencies = [ "prost-build", "prost-types 0.11.9", "quickwit-actors", + "quickwit-auth", "quickwit-codegen", "quickwit-common", "sea-query", diff --git a/quickwit/Cargo.toml b/quickwit/Cargo.toml index b91068fe5a3..082748687a8 100644 --- a/quickwit/Cargo.toml +++ b/quickwit/Cargo.toml @@ -2,6 +2,7 @@ resolver = "2" members = [ "quickwit-actors", + "quickwit-auth", "quickwit-aws", "quickwit-cli", "quickwit-cluster", @@ -20,6 +21,7 @@ members = [ "quickwit-jaeger", "quickwit-janitor", "quickwit-lambda", + "quickwit-license", "quickwit-macros", "quickwit-metastore", @@ -34,13 +36,14 @@ members = [ "quickwit-serve", "quickwit-storage", "quickwit-telemetry", - "quickwit-license", + "quickwit-telemetry", ] # The following list excludes `quickwit-metastore-utils` and `quickwit-lambda` # from the default member to ease build/deps. default-members = [ "quickwit-actors", + "quickwit-auth", "quickwit-aws", "quickwit-cli", "quickwit-cluster", @@ -52,6 +55,7 @@ default-members = [ "quickwit-datetime", "quickwit-directories", "quickwit-doc-mapper", + "quickwit-license", "quickwit-index-management", "quickwit-indexing", "quickwit-ingest", @@ -89,7 +93,6 @@ async-trait = "0.1" base64 = "0.22" binggan = { version = "0.14" } biscuit-auth = "5.0.0" - bytes = { version = "1", features = ["serde"] } bytesize = { version = "1.3.0", features = ["serde"] } bytestring = "1.3.0" @@ -303,6 +306,7 @@ opendal = { version = "0.44", default-features = false } reqsign = { version = "0.14", default-features = false } quickwit-actors = { path = "quickwit-actors" } +quickwit-auth = { path = "quickwit-auth" } quickwit-aws = { path = "quickwit-aws" } quickwit-cli = { path = "quickwit-cli" } quickwit-cluster = { path = "quickwit-cluster" } diff --git a/quickwit/quickwit-codegen/example/Cargo.toml b/quickwit/quickwit-codegen/example/Cargo.toml index e6380b1fb20..69617d20d8f 100644 --- a/quickwit/quickwit-codegen/example/Cargo.toml +++ b/quickwit/quickwit-codegen/example/Cargo.toml @@ -27,6 +27,7 @@ tower = { workspace = true } utoipa = { workspace = true } quickwit-actors = { workspace = true } +quickwit-auth = { workspace = true } quickwit-common = { workspace = true } quickwit-proto = { workspace = true } diff --git a/quickwit/quickwit-codegen/example/src/authorization.rs b/quickwit/quickwit-codegen/example/src/authorization.rs new file mode 100644 index 00000000000..fa4e0bf0f3d --- /dev/null +++ b/quickwit/quickwit-codegen/example/src/authorization.rs @@ -0,0 +1,26 @@ +use quickwit_auth::Authorization; +use quickwit_auth::AuthorizationError; +use quickwit_auth::AuthorizationToken; +use quickwit_auth::StreamAuthorization; + +use crate::GoodbyeRequest; +use crate::HelloRequest; +use crate::PingRequest; + +impl Authorization for HelloRequest { + fn attenuate(&self, auth_token: quickwit_auth::AuthorizationToken) -> Result { + Ok(auth_token) + } +} + +impl Authorization for GoodbyeRequest { + fn attenuate(&self, auth_token: quickwit_auth::AuthorizationToken) -> Result { + Ok(auth_token) + } +} + +impl StreamAuthorization for PingRequest { + fn attenuate(auth_token: quickwit_auth::AuthorizationToken) -> Result { + Ok(auth_token) + } +} diff --git a/quickwit/quickwit-codegen/example/src/codegen/hello.rs b/quickwit/quickwit-codegen/example/src/codegen/hello.rs index 93b9b634ce7..38dee0dc214 100644 --- a/quickwit/quickwit-codegen/example/src/codegen/hello.rs +++ b/quickwit/quickwit-codegen/example/src/codegen/hello.rs @@ -805,9 +805,14 @@ impl hello_grpc_server::HelloGrpc for HelloGrpcServerAdapter { &self, request: tonic::Request, ) -> Result, tonic::Status> { - self.inner - .0 - .hello(request.into_inner()) + let auth_token = quickwit_auth::get_auth_token(request.metadata())?; + let req = { + let req = request.into_inner(); + req + }; + quickwit_auth::authorize(&req, &auth_token)?; + quickwit_auth::AUTHORIZATION_TOKEN + .scope(auth_token, self.inner.0.hello(req)) .await .map(tonic::Response::new) .map_err(crate::error::grpc_error_to_grpc_status) @@ -816,9 +821,14 @@ impl hello_grpc_server::HelloGrpc for HelloGrpcServerAdapter { &self, request: tonic::Request, ) -> Result, tonic::Status> { - self.inner - .0 - .goodbye(request.into_inner()) + let auth_token = quickwit_auth::get_auth_token(request.metadata())?; + let req = { + let req = request.into_inner(); + req + }; + quickwit_auth::authorize(&req, &auth_token)?; + quickwit_auth::AUTHORIZATION_TOKEN + .scope(auth_token, self.inner.0.goodbye(req)) .await .map(tonic::Response::new) .map_err(crate::error::grpc_error_to_grpc_status) @@ -828,12 +838,14 @@ impl hello_grpc_server::HelloGrpc for HelloGrpcServerAdapter { &self, request: tonic::Request>, ) -> Result, tonic::Status> { - self.inner - .0 - .ping({ - let streaming: tonic::Streaming<_> = request.into_inner(); - quickwit_common::ServiceStream::from(streaming) - }) + let auth_token = quickwit_auth::get_auth_token(request.metadata())?; + let req = { + let streaming: tonic::Streaming<_> = request.into_inner(); + quickwit_common::ServiceStream::from(streaming) + }; + quickwit_auth::authorize_stream::(&auth_token)?; + quickwit_auth::AUTHORIZATION_TOKEN + .scope(auth_token, self.inner.0.ping(req)) .await .map(|stream| tonic::Response::new( stream.map_err(crate::error::grpc_error_to_grpc_status), diff --git a/quickwit/quickwit-codegen/example/src/lib.rs b/quickwit/quickwit-codegen/example/src/lib.rs index 31572dafd94..6ff2bd41fac 100644 --- a/quickwit/quickwit-codegen/example/src/lib.rs +++ b/quickwit/quickwit-codegen/example/src/lib.rs @@ -21,6 +21,7 @@ mod error; #[path = "codegen/hello.rs"] mod hello; +mod authorization; use std::sync::atomic::{AtomicUsize, Ordering}; use std::sync::Arc; diff --git a/quickwit/quickwit-codegen/src/codegen.rs b/quickwit/quickwit-codegen/src/codegen.rs index 2775d712b1c..198ab048b14 100644 --- a/quickwit/quickwit-codegen/src/codegen.rs +++ b/quickwit/quickwit-codegen/src/codegen.rs @@ -1231,7 +1231,12 @@ fn generate_grpc_server_adapter_methods(context: &CodegenContext) -> TokenStream } } } else { - quote! { request.into_inner() } + quote! { + { + let req = request.into_inner(); + req + } + } }; let response_type = if syn_method.server_streaming { let associated_type_name = quote::format_ident!("{}Stream", syn_method.proto_name); @@ -1253,14 +1258,25 @@ fn generate_grpc_server_adapter_methods(context: &CodegenContext) -> TokenStream } else { quote! { tonic::Response::new } }; + + let authorize_block = if syn_method.client_streaming { + let stream_item = &syn_method.request_type; + quote! { + quickwit_auth::authorize_stream::<#stream_item>(&auth_token)?; + } + } else { + quote! { + quickwit_auth::authorize(&req, &auth_token)?; + } + }; let method = quote! { #associated_type async fn #method_name(&self, request: tonic::Request<#request_type>) -> Result, tonic::Status> { - self.inner - .0 - .#method_name(#method_arg) - .await + let auth_token = quickwit_auth::get_auth_token(request.metadata())?; + let req = #method_arg; + #authorize_block; + quickwit_auth::AUTHORIZATION_TOKEN.scope(auth_token, self.inner.0.#method_name(req)).await .map(#into_response_type) .map_err(crate::error::grpc_error_to_grpc_status) } @@ -1270,6 +1286,8 @@ fn generate_grpc_server_adapter_methods(context: &CodegenContext) -> TokenStream stream } + + /// A [`ServiceGenerator`] wrapper that appends a suffix to the name of the wrapped service. It is /// used to add a `Grpc` suffix to the service, client, and server generated by tonic. struct WithSuffixServiceGenerator { diff --git a/quickwit/quickwit-ingest/Cargo.toml b/quickwit/quickwit-ingest/Cargo.toml index 5ac233859f8..3577addff50 100644 --- a/quickwit/quickwit-ingest/Cargo.toml +++ b/quickwit/quickwit-ingest/Cargo.toml @@ -36,6 +36,7 @@ ulid = { workspace = true } utoipa = { workspace = true } quickwit-actors = { workspace = true } +quickwit-auth = { workspace = true } quickwit-cluster = { workspace = true } quickwit-common = { workspace = true, features = ["testsuite"] } quickwit-config = { workspace = true } diff --git a/quickwit/quickwit-ingest/src/authorize.rs b/quickwit/quickwit-ingest/src/authorize.rs new file mode 100644 index 00000000000..c739f2adb1a --- /dev/null +++ b/quickwit/quickwit-ingest/src/authorize.rs @@ -0,0 +1,25 @@ +use quickwit_auth::Authorization; +use quickwit_auth::AuthorizationError; +use quickwit_auth::AuthorizationToken; + +use crate::FetchRequest; +use crate::IngestRequest; +use crate::TailRequest; + +impl Authorization for TailRequest { + fn attenuate(&self, auth_token: AuthorizationToken) -> Result { + Ok(auth_token) + } +} + +impl Authorization for IngestRequest { + fn attenuate(&self, auth_token: AuthorizationToken) -> Result { + Ok(auth_token) + } +} + +impl Authorization for FetchRequest { + fn attenuate(&self, auth_token: AuthorizationToken) -> Result { + Ok(auth_token) + } +} diff --git a/quickwit/quickwit-ingest/src/codegen/ingest_service.rs b/quickwit/quickwit-ingest/src/codegen/ingest_service.rs index ac03fd52faf..8aeec3f2e86 100644 --- a/quickwit/quickwit-ingest/src/codegen/ingest_service.rs +++ b/quickwit/quickwit-ingest/src/codegen/ingest_service.rs @@ -872,9 +872,14 @@ impl ingest_service_grpc_server::IngestServiceGrpc for IngestServiceGrpcServerAd &self, request: tonic::Request, ) -> Result, tonic::Status> { - self.inner - .0 - .ingest(request.into_inner()) + let auth_token = quickwit_auth::get_auth_token(request.metadata())?; + let req = { + let req = request.into_inner(); + req + }; + quickwit_auth::authorize(&req, &auth_token)?; + quickwit_auth::AUTHORIZATION_TOKEN + .scope(auth_token, self.inner.0.ingest(req)) .await .map(tonic::Response::new) .map_err(crate::error::grpc_error_to_grpc_status) @@ -883,9 +888,14 @@ impl ingest_service_grpc_server::IngestServiceGrpc for IngestServiceGrpcServerAd &self, request: tonic::Request, ) -> Result, tonic::Status> { - self.inner - .0 - .fetch(request.into_inner()) + let auth_token = quickwit_auth::get_auth_token(request.metadata())?; + let req = { + let req = request.into_inner(); + req + }; + quickwit_auth::authorize(&req, &auth_token)?; + quickwit_auth::AUTHORIZATION_TOKEN + .scope(auth_token, self.inner.0.fetch(req)) .await .map(tonic::Response::new) .map_err(crate::error::grpc_error_to_grpc_status) @@ -894,9 +904,14 @@ impl ingest_service_grpc_server::IngestServiceGrpc for IngestServiceGrpcServerAd &self, request: tonic::Request, ) -> Result, tonic::Status> { - self.inner - .0 - .tail(request.into_inner()) + let auth_token = quickwit_auth::get_auth_token(request.metadata())?; + let req = { + let req = request.into_inner(); + req + }; + quickwit_auth::authorize(&req, &auth_token)?; + quickwit_auth::AUTHORIZATION_TOKEN + .scope(auth_token, self.inner.0.tail(req)) .await .map(tonic::Response::new) .map_err(crate::error::grpc_error_to_grpc_status) diff --git a/quickwit/quickwit-ingest/src/lib.rs b/quickwit/quickwit-ingest/src/lib.rs index 12807f637b6..3bed1dd7833 100644 --- a/quickwit/quickwit-ingest/src/lib.rs +++ b/quickwit/quickwit-ingest/src/lib.rs @@ -31,6 +31,7 @@ mod mrecordlog_async; mod notifications; mod position; mod queue; +mod authorize; use std::collections::HashMap; use std::path::{Path, PathBuf}; diff --git a/quickwit/quickwit-proto/Cargo.toml b/quickwit/quickwit-proto/Cargo.toml index 8ba844df054..088235e9c28 100644 --- a/quickwit/quickwit-proto/Cargo.toml +++ b/quickwit/quickwit-proto/Cargo.toml @@ -12,6 +12,7 @@ license.workspace = true [dependencies] anyhow = { workspace = true } async-trait = { workspace = true } +biscuit-auth = { workspace = true } bytes = { workspace = true } bytesize = { workspace = true } bytestring = { workspace = true } @@ -36,6 +37,7 @@ utoipa = { workspace = true } zstd = { workspace = true } quickwit-actors = { workspace = true } +quickwit-auth = { workspace = true } quickwit-common = { workspace = true } [dev-dependencies] diff --git a/quickwit/quickwit-proto/src/authorization.rs b/quickwit/quickwit-proto/src/authorization.rs new file mode 100644 index 00000000000..6316aaac9e8 --- /dev/null +++ b/quickwit/quickwit-proto/src/authorization.rs @@ -0,0 +1,326 @@ +use std::time::Duration; +use std::time::SystemTime; + +use biscuit_auth::builder_ext::BuilderExt; +use quickwit_auth::Authorization; +use quickwit_auth::AuthorizationError; +use quickwit_auth::AuthorizationToken; +use quickwit_auth::StreamAuthorization; +use crate::cluster::FetchClusterStateRequest; +use crate::control_plane::AdviseResetShardsRequest; +use crate::control_plane::GetOrCreateOpenShardsRequest; +use crate::developer::GetDebugInfoRequest; +use crate::indexing::ApplyIndexingPlanRequest; +use crate::ingest::ingester::CloseShardsRequest; +use crate::ingest::ingester::DecommissionRequest; +use crate::ingest::ingester::InitShardsRequest; +use crate::ingest::ingester::OpenFetchStreamRequest; +use crate::ingest::ingester::OpenObservationStreamRequest; +use crate::ingest::ingester::PersistRequest; +use crate::ingest::ingester::RetainShardsRequest; +use crate::ingest::ingester::SynReplicationMessage; +use crate::ingest::ingester::TruncateShardsRequest; +use crate::ingest::router::IngestRequestV2; +use crate::metastore::DeleteQuery; +use crate::metastore::GetIndexTemplateRequest; +use crate::metastore::IndexMetadataRequest; +use crate::metastore::LastDeleteOpstampRequest; +use crate::metastore::ListDeleteTasksRequest; +use crate::metastore::ListIndexTemplatesRequest; +use crate::metastore::ListIndexesMetadataRequest; +use crate::metastore::ListShardsRequest; +use crate::metastore::ListSplitsRequest; +use crate::metastore::ListStaleSplitsRequest; +use crate::metastore::OpenShardsRequest; +use crate::metastore::PruneShardsRequest; +use crate::metastore::PublishSplitsRequest; +use crate::metastore::StageSplitsRequest; +use crate::metastore::UpdateSplitsDeleteOpstampRequest; +use biscuit_auth::macros::*; + +impl Authorization for crate::metastore::AcquireShardsRequest { + fn attenuate(&self, auth_token: AuthorizationToken) -> Result { + Ok(auth_token) + } +} + +impl Authorization for crate::metastore::AddSourceRequest { + fn attenuate(&self, auth_token: AuthorizationToken) -> Result { + Ok(auth_token) + } +} + + + +impl Authorization for crate::metastore::CreateIndexRequest { + fn attenuate(&self, auth_token: AuthorizationToken) -> Result { + let mut builder = block!(r#"check if operation("create_index");"#); + builder.check_expiration_date(SystemTime::now() + Duration::from_secs(60)); + let new_auth_token = auth_token.append(builder)?; + Ok(new_auth_token) + } +} + +impl Authorization for crate::metastore::CreateIndexTemplateRequest { + fn attenuate(&self, auth_token: AuthorizationToken) -> Result { + Ok(auth_token) + } +} + +impl Authorization for crate::metastore::DeleteIndexRequest { + fn attenuate(&self, auth_token: AuthorizationToken) -> Result { + Ok(auth_token) + } +} + +impl Authorization for crate::metastore::DeleteIndexTemplatesRequest { + fn attenuate(&self, auth_token: AuthorizationToken) -> Result { + Ok(auth_token) + } +} + +impl Authorization for crate::metastore::DeleteShardsRequest { + fn attenuate(&self, auth_token: AuthorizationToken) -> Result { + Ok(auth_token) + } +} + +impl Authorization for crate::metastore::DeleteSourceRequest { + fn attenuate(&self, auth_token: AuthorizationToken) -> Result { + Ok(auth_token) + } +} + +impl Authorization for crate::metastore::DeleteSplitsRequest { + fn attenuate(&self, auth_token: AuthorizationToken) -> Result { + Ok(auth_token) + } +} + +impl Authorization for crate::metastore::FindIndexTemplateMatchesRequest { + fn attenuate(&self, auth_token: AuthorizationToken) -> Result { + Ok(auth_token) + } +} + +impl Authorization for crate::metastore::IndexesMetadataRequest { + fn attenuate(&self, auth_token: AuthorizationToken) -> Result { + Ok(auth_token) + } +} + +impl Authorization for crate::metastore::ToggleSourceRequest { + fn attenuate(&self, auth_token: AuthorizationToken) -> Result { + Ok(auth_token) + } +} + +impl Authorization for crate::metastore::MarkSplitsForDeletionRequest { + fn attenuate(&self, auth_token: AuthorizationToken) -> Result { + Ok(auth_token) + } +} + +impl Authorization for crate::metastore::ResetSourceCheckpointRequest { + fn attenuate(&self, auth_token: AuthorizationToken) -> Result { + Ok(auth_token) + } +} + +impl Authorization for crate::metastore::UpdateIndexRequest { + fn attenuate(&self, auth_token: AuthorizationToken) -> Result { + Ok(auth_token) + } +} + +impl Authorization for OpenObservationStreamRequest { + fn attenuate(&self, auth_token: AuthorizationToken) -> Result { + Ok(auth_token) + } +} + +impl Authorization for InitShardsRequest { + fn attenuate(&self, auth_token: AuthorizationToken) -> Result { + Ok(auth_token) + } +} + +impl Authorization for OpenShardsRequest { + fn attenuate(&self, auth_token: AuthorizationToken) -> Result { + Ok(auth_token) + } +} + +impl Authorization for FetchClusterStateRequest { + fn attenuate(&self, auth_token: AuthorizationToken) -> Result { + Ok(auth_token) + } +} + +impl Authorization for GetIndexTemplateRequest { + fn attenuate(&self, auth_token: AuthorizationToken) -> Result { + Ok(auth_token) + } +} + +impl Authorization for ListIndexTemplatesRequest { + fn attenuate(&self, auth_token: AuthorizationToken) -> Result { + Ok(auth_token) + } +} + +impl Authorization for PruneShardsRequest { + fn attenuate(&self, auth_token: AuthorizationToken) -> Result { + Ok(auth_token) + } +} + +impl Authorization for ListShardsRequest { + fn attenuate(&self, auth_token: AuthorizationToken) -> Result { + Ok(auth_token) + } +} + +impl Authorization for ListStaleSplitsRequest { + fn attenuate(&self, auth_token: AuthorizationToken) -> Result { + Ok(auth_token) + } +} + +impl Authorization for ListDeleteTasksRequest { + fn attenuate(&self, auth_token: AuthorizationToken) -> Result { + Ok(auth_token) + } +} + +impl Authorization for UpdateSplitsDeleteOpstampRequest { + fn attenuate(&self, auth_token: AuthorizationToken) -> Result { + Ok(auth_token) + } +} + + +impl Authorization for LastDeleteOpstampRequest { + fn attenuate(&self, auth_token: AuthorizationToken) -> Result { + Ok(auth_token) + } +} + + +impl Authorization for DeleteQuery { + fn attenuate(&self, auth_token: AuthorizationToken) -> Result { + Ok(auth_token) + } +} + + +impl Authorization for GetOrCreateOpenShardsRequest { + fn attenuate(&self, auth_token: AuthorizationToken) -> Result { + Ok(auth_token) + } +} + + +impl Authorization for AdviseResetShardsRequest { + fn attenuate(&self, auth_token: AuthorizationToken) -> Result { + Ok(auth_token) + } +} + + +impl Authorization for GetDebugInfoRequest { + fn attenuate(&self, auth_token: AuthorizationToken) -> Result { + Ok(auth_token) + } +} + + +impl Authorization for StageSplitsRequest { + fn attenuate(&self, auth_token: AuthorizationToken) -> Result { + Ok(auth_token) + } +} + + +impl Authorization for ListSplitsRequest { + fn attenuate(&self, auth_token: AuthorizationToken) -> Result { + Ok(auth_token) + } +} + + +impl Authorization for PublishSplitsRequest { + fn attenuate(&self, auth_token: AuthorizationToken) -> Result { + Ok(auth_token) + } +} + + +impl Authorization for ListIndexesMetadataRequest { + fn attenuate(&self, auth_token: AuthorizationToken) -> Result { + Ok(auth_token) + } +} + +impl Authorization for TruncateShardsRequest { + fn attenuate(&self, auth_token: AuthorizationToken) -> Result { + Ok(auth_token) + } +} + + +impl Authorization for CloseShardsRequest { + fn attenuate(&self, auth_token: AuthorizationToken) -> Result { + Ok(auth_token) + } +} + + +impl Authorization for RetainShardsRequest { + fn attenuate(&self, auth_token: AuthorizationToken) -> Result { + Ok(auth_token) + } +} + +impl Authorization for ApplyIndexingPlanRequest { + fn attenuate(&self, auth_token: AuthorizationToken) -> Result { + Ok(auth_token) + } +} + +impl Authorization for PersistRequest { + fn attenuate(&self, auth_token: AuthorizationToken) -> Result { + Ok(auth_token) + } +} + +impl Authorization for IndexMetadataRequest { + fn attenuate(&self, auth_token: AuthorizationToken) -> Result { + Ok(auth_token) + } +} + +impl StreamAuthorization for SynReplicationMessage { + fn attenuate(auth_token: AuthorizationToken) -> Result { + Ok(auth_token) + } +} + +impl Authorization for IngestRequestV2 { + fn attenuate(&self, auth_token: AuthorizationToken) -> Result { + Ok(auth_token) + } +} + +impl Authorization for OpenFetchStreamRequest { + fn attenuate(&self, auth_token: AuthorizationToken) -> Result { + Ok(auth_token) + } +} + + +impl Authorization for DecommissionRequest { + fn attenuate(&self, auth_token: AuthorizationToken) -> Result { + Ok(auth_token) + } +} diff --git a/quickwit/quickwit-proto/src/codegen/quickwit/quickwit.cluster.rs b/quickwit/quickwit-proto/src/codegen/quickwit/quickwit.cluster.rs index 38471f0ad7b..2b54c972f75 100644 --- a/quickwit/quickwit-proto/src/codegen/quickwit/quickwit.cluster.rs +++ b/quickwit/quickwit-proto/src/codegen/quickwit/quickwit.cluster.rs @@ -542,9 +542,14 @@ for ClusterServiceGrpcServerAdapter { &self, request: tonic::Request, ) -> Result, tonic::Status> { - self.inner - .0 - .fetch_cluster_state(request.into_inner()) + let auth_token = quickwit_auth::get_auth_token(request.metadata())?; + let req = { + let req = request.into_inner(); + req + }; + quickwit_auth::authorize(&req, &auth_token)?; + quickwit_auth::AUTHORIZATION_TOKEN + .scope(auth_token, self.inner.0.fetch_cluster_state(req)) .await .map(tonic::Response::new) .map_err(crate::error::grpc_error_to_grpc_status) diff --git a/quickwit/quickwit-proto/src/codegen/quickwit/quickwit.control_plane.rs b/quickwit/quickwit-proto/src/codegen/quickwit/quickwit.control_plane.rs index c14ef724de0..5de613c9a05 100644 --- a/quickwit/quickwit-proto/src/codegen/quickwit/quickwit.control_plane.rs +++ b/quickwit/quickwit-proto/src/codegen/quickwit/quickwit.control_plane.rs @@ -1779,9 +1779,14 @@ for ControlPlaneServiceGrpcServerAdapter { &self, request: tonic::Request, ) -> Result, tonic::Status> { - self.inner - .0 - .create_index(request.into_inner()) + let auth_token = quickwit_auth::get_auth_token(request.metadata())?; + let req = { + let req = request.into_inner(); + req + }; + quickwit_auth::authorize(&req, &auth_token)?; + quickwit_auth::AUTHORIZATION_TOKEN + .scope(auth_token, self.inner.0.create_index(req)) .await .map(tonic::Response::new) .map_err(crate::error::grpc_error_to_grpc_status) @@ -1793,9 +1798,14 @@ for ControlPlaneServiceGrpcServerAdapter { tonic::Response, tonic::Status, > { - self.inner - .0 - .update_index(request.into_inner()) + let auth_token = quickwit_auth::get_auth_token(request.metadata())?; + let req = { + let req = request.into_inner(); + req + }; + quickwit_auth::authorize(&req, &auth_token)?; + quickwit_auth::AUTHORIZATION_TOKEN + .scope(auth_token, self.inner.0.update_index(req)) .await .map(tonic::Response::new) .map_err(crate::error::grpc_error_to_grpc_status) @@ -1804,9 +1814,14 @@ for ControlPlaneServiceGrpcServerAdapter { &self, request: tonic::Request, ) -> Result, tonic::Status> { - self.inner - .0 - .delete_index(request.into_inner()) + let auth_token = quickwit_auth::get_auth_token(request.metadata())?; + let req = { + let req = request.into_inner(); + req + }; + quickwit_auth::authorize(&req, &auth_token)?; + quickwit_auth::AUTHORIZATION_TOKEN + .scope(auth_token, self.inner.0.delete_index(req)) .await .map(tonic::Response::new) .map_err(crate::error::grpc_error_to_grpc_status) @@ -1815,9 +1830,14 @@ for ControlPlaneServiceGrpcServerAdapter { &self, request: tonic::Request, ) -> Result, tonic::Status> { - self.inner - .0 - .add_source(request.into_inner()) + let auth_token = quickwit_auth::get_auth_token(request.metadata())?; + let req = { + let req = request.into_inner(); + req + }; + quickwit_auth::authorize(&req, &auth_token)?; + quickwit_auth::AUTHORIZATION_TOKEN + .scope(auth_token, self.inner.0.add_source(req)) .await .map(tonic::Response::new) .map_err(crate::error::grpc_error_to_grpc_status) @@ -1826,9 +1846,14 @@ for ControlPlaneServiceGrpcServerAdapter { &self, request: tonic::Request, ) -> Result, tonic::Status> { - self.inner - .0 - .toggle_source(request.into_inner()) + let auth_token = quickwit_auth::get_auth_token(request.metadata())?; + let req = { + let req = request.into_inner(); + req + }; + quickwit_auth::authorize(&req, &auth_token)?; + quickwit_auth::AUTHORIZATION_TOKEN + .scope(auth_token, self.inner.0.toggle_source(req)) .await .map(tonic::Response::new) .map_err(crate::error::grpc_error_to_grpc_status) @@ -1837,9 +1862,14 @@ for ControlPlaneServiceGrpcServerAdapter { &self, request: tonic::Request, ) -> Result, tonic::Status> { - self.inner - .0 - .delete_source(request.into_inner()) + let auth_token = quickwit_auth::get_auth_token(request.metadata())?; + let req = { + let req = request.into_inner(); + req + }; + quickwit_auth::authorize(&req, &auth_token)?; + quickwit_auth::AUTHORIZATION_TOKEN + .scope(auth_token, self.inner.0.delete_source(req)) .await .map(tonic::Response::new) .map_err(crate::error::grpc_error_to_grpc_status) @@ -1848,9 +1878,14 @@ for ControlPlaneServiceGrpcServerAdapter { &self, request: tonic::Request, ) -> Result, tonic::Status> { - self.inner - .0 - .get_or_create_open_shards(request.into_inner()) + let auth_token = quickwit_auth::get_auth_token(request.metadata())?; + let req = { + let req = request.into_inner(); + req + }; + quickwit_auth::authorize(&req, &auth_token)?; + quickwit_auth::AUTHORIZATION_TOKEN + .scope(auth_token, self.inner.0.get_or_create_open_shards(req)) .await .map(tonic::Response::new) .map_err(crate::error::grpc_error_to_grpc_status) @@ -1859,9 +1894,14 @@ for ControlPlaneServiceGrpcServerAdapter { &self, request: tonic::Request, ) -> Result, tonic::Status> { - self.inner - .0 - .advise_reset_shards(request.into_inner()) + let auth_token = quickwit_auth::get_auth_token(request.metadata())?; + let req = { + let req = request.into_inner(); + req + }; + quickwit_auth::authorize(&req, &auth_token)?; + quickwit_auth::AUTHORIZATION_TOKEN + .scope(auth_token, self.inner.0.advise_reset_shards(req)) .await .map(tonic::Response::new) .map_err(crate::error::grpc_error_to_grpc_status) @@ -1870,9 +1910,14 @@ for ControlPlaneServiceGrpcServerAdapter { &self, request: tonic::Request, ) -> Result, tonic::Status> { - self.inner - .0 - .prune_shards(request.into_inner()) + let auth_token = quickwit_auth::get_auth_token(request.metadata())?; + let req = { + let req = request.into_inner(); + req + }; + quickwit_auth::authorize(&req, &auth_token)?; + quickwit_auth::AUTHORIZATION_TOKEN + .scope(auth_token, self.inner.0.prune_shards(req)) .await .map(tonic::Response::new) .map_err(crate::error::grpc_error_to_grpc_status) diff --git a/quickwit/quickwit-proto/src/codegen/quickwit/quickwit.developer.rs b/quickwit/quickwit-proto/src/codegen/quickwit/quickwit.developer.rs index b05cc01aef8..cbe28bd2eb2 100644 --- a/quickwit/quickwit-proto/src/codegen/quickwit/quickwit.developer.rs +++ b/quickwit/quickwit-proto/src/codegen/quickwit/quickwit.developer.rs @@ -478,9 +478,14 @@ for DeveloperServiceGrpcServerAdapter { &self, request: tonic::Request, ) -> Result, tonic::Status> { - self.inner - .0 - .get_debug_info(request.into_inner()) + let auth_token = quickwit_auth::get_auth_token(request.metadata())?; + let req = { + let req = request.into_inner(); + req + }; + quickwit_auth::authorize(&req, &auth_token)?; + quickwit_auth::AUTHORIZATION_TOKEN + .scope(auth_token, self.inner.0.get_debug_info(req)) .await .map(tonic::Response::new) .map_err(crate::error::grpc_error_to_grpc_status) diff --git a/quickwit/quickwit-proto/src/codegen/quickwit/quickwit.indexing.rs b/quickwit/quickwit-proto/src/codegen/quickwit/quickwit.indexing.rs index ae0ef465968..42514ba5003 100644 --- a/quickwit/quickwit-proto/src/codegen/quickwit/quickwit.indexing.rs +++ b/quickwit/quickwit-proto/src/codegen/quickwit/quickwit.indexing.rs @@ -491,9 +491,14 @@ for IndexingServiceGrpcServerAdapter { &self, request: tonic::Request, ) -> Result, tonic::Status> { - self.inner - .0 - .apply_indexing_plan(request.into_inner()) + let auth_token = quickwit_auth::get_auth_token(request.metadata())?; + let req = { + let req = request.into_inner(); + req + }; + quickwit_auth::authorize(&req, &auth_token)?; + quickwit_auth::AUTHORIZATION_TOKEN + .scope(auth_token, self.inner.0.apply_indexing_plan(req)) .await .map(tonic::Response::new) .map_err(crate::error::grpc_error_to_grpc_status) diff --git a/quickwit/quickwit-proto/src/codegen/quickwit/quickwit.ingest.ingester.rs b/quickwit/quickwit-proto/src/codegen/quickwit/quickwit.ingest.ingester.rs index ccb13a5e44d..e18cc626151 100644 --- a/quickwit/quickwit-proto/src/codegen/quickwit/quickwit.ingest.ingester.rs +++ b/quickwit/quickwit-proto/src/codegen/quickwit/quickwit.ingest.ingester.rs @@ -2209,9 +2209,14 @@ for IngesterServiceGrpcServerAdapter { &self, request: tonic::Request, ) -> Result, tonic::Status> { - self.inner - .0 - .persist(request.into_inner()) + let auth_token = quickwit_auth::get_auth_token(request.metadata())?; + let req = { + let req = request.into_inner(); + req + }; + quickwit_auth::authorize(&req, &auth_token)?; + quickwit_auth::AUTHORIZATION_TOKEN + .scope(auth_token, self.inner.0.persist(req)) .await .map(tonic::Response::new) .map_err(crate::error::grpc_error_to_grpc_status) @@ -2223,12 +2228,14 @@ for IngesterServiceGrpcServerAdapter { &self, request: tonic::Request>, ) -> Result, tonic::Status> { - self.inner - .0 - .open_replication_stream({ - let streaming: tonic::Streaming<_> = request.into_inner(); - quickwit_common::ServiceStream::from(streaming) - }) + let auth_token = quickwit_auth::get_auth_token(request.metadata())?; + let req = { + let streaming: tonic::Streaming<_> = request.into_inner(); + quickwit_common::ServiceStream::from(streaming) + }; + quickwit_auth::authorize_stream::(&auth_token)?; + quickwit_auth::AUTHORIZATION_TOKEN + .scope(auth_token, self.inner.0.open_replication_stream(req)) .await .map(|stream| tonic::Response::new( stream.map_err(crate::error::grpc_error_to_grpc_status), @@ -2242,9 +2249,14 @@ for IngesterServiceGrpcServerAdapter { &self, request: tonic::Request, ) -> Result, tonic::Status> { - self.inner - .0 - .open_fetch_stream(request.into_inner()) + let auth_token = quickwit_auth::get_auth_token(request.metadata())?; + let req = { + let req = request.into_inner(); + req + }; + quickwit_auth::authorize(&req, &auth_token)?; + quickwit_auth::AUTHORIZATION_TOKEN + .scope(auth_token, self.inner.0.open_fetch_stream(req)) .await .map(|stream| tonic::Response::new( stream.map_err(crate::error::grpc_error_to_grpc_status), @@ -2258,9 +2270,14 @@ for IngesterServiceGrpcServerAdapter { &self, request: tonic::Request, ) -> Result, tonic::Status> { - self.inner - .0 - .open_observation_stream(request.into_inner()) + let auth_token = quickwit_auth::get_auth_token(request.metadata())?; + let req = { + let req = request.into_inner(); + req + }; + quickwit_auth::authorize(&req, &auth_token)?; + quickwit_auth::AUTHORIZATION_TOKEN + .scope(auth_token, self.inner.0.open_observation_stream(req)) .await .map(|stream| tonic::Response::new( stream.map_err(crate::error::grpc_error_to_grpc_status), @@ -2271,9 +2288,14 @@ for IngesterServiceGrpcServerAdapter { &self, request: tonic::Request, ) -> Result, tonic::Status> { - self.inner - .0 - .init_shards(request.into_inner()) + let auth_token = quickwit_auth::get_auth_token(request.metadata())?; + let req = { + let req = request.into_inner(); + req + }; + quickwit_auth::authorize(&req, &auth_token)?; + quickwit_auth::AUTHORIZATION_TOKEN + .scope(auth_token, self.inner.0.init_shards(req)) .await .map(tonic::Response::new) .map_err(crate::error::grpc_error_to_grpc_status) @@ -2282,9 +2304,14 @@ for IngesterServiceGrpcServerAdapter { &self, request: tonic::Request, ) -> Result, tonic::Status> { - self.inner - .0 - .retain_shards(request.into_inner()) + let auth_token = quickwit_auth::get_auth_token(request.metadata())?; + let req = { + let req = request.into_inner(); + req + }; + quickwit_auth::authorize(&req, &auth_token)?; + quickwit_auth::AUTHORIZATION_TOKEN + .scope(auth_token, self.inner.0.retain_shards(req)) .await .map(tonic::Response::new) .map_err(crate::error::grpc_error_to_grpc_status) @@ -2293,9 +2320,14 @@ for IngesterServiceGrpcServerAdapter { &self, request: tonic::Request, ) -> Result, tonic::Status> { - self.inner - .0 - .truncate_shards(request.into_inner()) + let auth_token = quickwit_auth::get_auth_token(request.metadata())?; + let req = { + let req = request.into_inner(); + req + }; + quickwit_auth::authorize(&req, &auth_token)?; + quickwit_auth::AUTHORIZATION_TOKEN + .scope(auth_token, self.inner.0.truncate_shards(req)) .await .map(tonic::Response::new) .map_err(crate::error::grpc_error_to_grpc_status) @@ -2304,9 +2336,14 @@ for IngesterServiceGrpcServerAdapter { &self, request: tonic::Request, ) -> Result, tonic::Status> { - self.inner - .0 - .close_shards(request.into_inner()) + let auth_token = quickwit_auth::get_auth_token(request.metadata())?; + let req = { + let req = request.into_inner(); + req + }; + quickwit_auth::authorize(&req, &auth_token)?; + quickwit_auth::AUTHORIZATION_TOKEN + .scope(auth_token, self.inner.0.close_shards(req)) .await .map(tonic::Response::new) .map_err(crate::error::grpc_error_to_grpc_status) @@ -2315,9 +2352,14 @@ for IngesterServiceGrpcServerAdapter { &self, request: tonic::Request, ) -> Result, tonic::Status> { - self.inner - .0 - .decommission(request.into_inner()) + let auth_token = quickwit_auth::get_auth_token(request.metadata())?; + let req = { + let req = request.into_inner(); + req + }; + quickwit_auth::authorize(&req, &auth_token)?; + quickwit_auth::AUTHORIZATION_TOKEN + .scope(auth_token, self.inner.0.decommission(req)) .await .map(tonic::Response::new) .map_err(crate::error::grpc_error_to_grpc_status) diff --git a/quickwit/quickwit-proto/src/codegen/quickwit/quickwit.ingest.router.rs b/quickwit/quickwit-proto/src/codegen/quickwit/quickwit.ingest.router.rs index 1f43bd342ca..16a078d360a 100644 --- a/quickwit/quickwit-proto/src/codegen/quickwit/quickwit.ingest.router.rs +++ b/quickwit/quickwit-proto/src/codegen/quickwit/quickwit.ingest.router.rs @@ -601,9 +601,14 @@ for IngestRouterServiceGrpcServerAdapter { &self, request: tonic::Request, ) -> Result, tonic::Status> { - self.inner - .0 - .ingest(request.into_inner()) + let auth_token = quickwit_auth::get_auth_token(request.metadata())?; + let req = { + let req = request.into_inner(); + req + }; + quickwit_auth::authorize(&req, &auth_token)?; + quickwit_auth::AUTHORIZATION_TOKEN + .scope(auth_token, self.inner.0.ingest(req)) .await .map(tonic::Response::new) .map_err(crate::error::grpc_error_to_grpc_status) diff --git a/quickwit/quickwit-proto/src/codegen/quickwit/quickwit.metastore.rs b/quickwit/quickwit-proto/src/codegen/quickwit/quickwit.metastore.rs index 08b12006db3..1ca889eaf00 100644 --- a/quickwit/quickwit-proto/src/codegen/quickwit/quickwit.metastore.rs +++ b/quickwit/quickwit-proto/src/codegen/quickwit/quickwit.metastore.rs @@ -5327,9 +5327,14 @@ for MetastoreServiceGrpcServerAdapter { &self, request: tonic::Request, ) -> Result, tonic::Status> { - self.inner - .0 - .create_index(request.into_inner()) + let auth_token = quickwit_auth::get_auth_token(request.metadata())?; + let req = { + let req = request.into_inner(); + req + }; + quickwit_auth::authorize(&req, &auth_token)?; + quickwit_auth::AUTHORIZATION_TOKEN + .scope(auth_token, self.inner.0.create_index(req)) .await .map(tonic::Response::new) .map_err(crate::error::grpc_error_to_grpc_status) @@ -5338,9 +5343,14 @@ for MetastoreServiceGrpcServerAdapter { &self, request: tonic::Request, ) -> Result, tonic::Status> { - self.inner - .0 - .update_index(request.into_inner()) + let auth_token = quickwit_auth::get_auth_token(request.metadata())?; + let req = { + let req = request.into_inner(); + req + }; + quickwit_auth::authorize(&req, &auth_token)?; + quickwit_auth::AUTHORIZATION_TOKEN + .scope(auth_token, self.inner.0.update_index(req)) .await .map(tonic::Response::new) .map_err(crate::error::grpc_error_to_grpc_status) @@ -5349,9 +5359,14 @@ for MetastoreServiceGrpcServerAdapter { &self, request: tonic::Request, ) -> Result, tonic::Status> { - self.inner - .0 - .index_metadata(request.into_inner()) + let auth_token = quickwit_auth::get_auth_token(request.metadata())?; + let req = { + let req = request.into_inner(); + req + }; + quickwit_auth::authorize(&req, &auth_token)?; + quickwit_auth::AUTHORIZATION_TOKEN + .scope(auth_token, self.inner.0.index_metadata(req)) .await .map(tonic::Response::new) .map_err(crate::error::grpc_error_to_grpc_status) @@ -5360,9 +5375,14 @@ for MetastoreServiceGrpcServerAdapter { &self, request: tonic::Request, ) -> Result, tonic::Status> { - self.inner - .0 - .indexes_metadata(request.into_inner()) + let auth_token = quickwit_auth::get_auth_token(request.metadata())?; + let req = { + let req = request.into_inner(); + req + }; + quickwit_auth::authorize(&req, &auth_token)?; + quickwit_auth::AUTHORIZATION_TOKEN + .scope(auth_token, self.inner.0.indexes_metadata(req)) .await .map(tonic::Response::new) .map_err(crate::error::grpc_error_to_grpc_status) @@ -5371,9 +5391,14 @@ for MetastoreServiceGrpcServerAdapter { &self, request: tonic::Request, ) -> Result, tonic::Status> { - self.inner - .0 - .list_indexes_metadata(request.into_inner()) + let auth_token = quickwit_auth::get_auth_token(request.metadata())?; + let req = { + let req = request.into_inner(); + req + }; + quickwit_auth::authorize(&req, &auth_token)?; + quickwit_auth::AUTHORIZATION_TOKEN + .scope(auth_token, self.inner.0.list_indexes_metadata(req)) .await .map(tonic::Response::new) .map_err(crate::error::grpc_error_to_grpc_status) @@ -5382,9 +5407,14 @@ for MetastoreServiceGrpcServerAdapter { &self, request: tonic::Request, ) -> Result, tonic::Status> { - self.inner - .0 - .delete_index(request.into_inner()) + let auth_token = quickwit_auth::get_auth_token(request.metadata())?; + let req = { + let req = request.into_inner(); + req + }; + quickwit_auth::authorize(&req, &auth_token)?; + quickwit_auth::AUTHORIZATION_TOKEN + .scope(auth_token, self.inner.0.delete_index(req)) .await .map(tonic::Response::new) .map_err(crate::error::grpc_error_to_grpc_status) @@ -5396,9 +5426,14 @@ for MetastoreServiceGrpcServerAdapter { &self, request: tonic::Request, ) -> Result, tonic::Status> { - self.inner - .0 - .list_splits(request.into_inner()) + let auth_token = quickwit_auth::get_auth_token(request.metadata())?; + let req = { + let req = request.into_inner(); + req + }; + quickwit_auth::authorize(&req, &auth_token)?; + quickwit_auth::AUTHORIZATION_TOKEN + .scope(auth_token, self.inner.0.list_splits(req)) .await .map(|stream| tonic::Response::new( stream.map_err(crate::error::grpc_error_to_grpc_status), @@ -5409,9 +5444,14 @@ for MetastoreServiceGrpcServerAdapter { &self, request: tonic::Request, ) -> Result, tonic::Status> { - self.inner - .0 - .stage_splits(request.into_inner()) + let auth_token = quickwit_auth::get_auth_token(request.metadata())?; + let req = { + let req = request.into_inner(); + req + }; + quickwit_auth::authorize(&req, &auth_token)?; + quickwit_auth::AUTHORIZATION_TOKEN + .scope(auth_token, self.inner.0.stage_splits(req)) .await .map(tonic::Response::new) .map_err(crate::error::grpc_error_to_grpc_status) @@ -5420,9 +5460,14 @@ for MetastoreServiceGrpcServerAdapter { &self, request: tonic::Request, ) -> Result, tonic::Status> { - self.inner - .0 - .publish_splits(request.into_inner()) + let auth_token = quickwit_auth::get_auth_token(request.metadata())?; + let req = { + let req = request.into_inner(); + req + }; + quickwit_auth::authorize(&req, &auth_token)?; + quickwit_auth::AUTHORIZATION_TOKEN + .scope(auth_token, self.inner.0.publish_splits(req)) .await .map(tonic::Response::new) .map_err(crate::error::grpc_error_to_grpc_status) @@ -5431,9 +5476,14 @@ for MetastoreServiceGrpcServerAdapter { &self, request: tonic::Request, ) -> Result, tonic::Status> { - self.inner - .0 - .mark_splits_for_deletion(request.into_inner()) + let auth_token = quickwit_auth::get_auth_token(request.metadata())?; + let req = { + let req = request.into_inner(); + req + }; + quickwit_auth::authorize(&req, &auth_token)?; + quickwit_auth::AUTHORIZATION_TOKEN + .scope(auth_token, self.inner.0.mark_splits_for_deletion(req)) .await .map(tonic::Response::new) .map_err(crate::error::grpc_error_to_grpc_status) @@ -5442,9 +5492,14 @@ for MetastoreServiceGrpcServerAdapter { &self, request: tonic::Request, ) -> Result, tonic::Status> { - self.inner - .0 - .delete_splits(request.into_inner()) + let auth_token = quickwit_auth::get_auth_token(request.metadata())?; + let req = { + let req = request.into_inner(); + req + }; + quickwit_auth::authorize(&req, &auth_token)?; + quickwit_auth::AUTHORIZATION_TOKEN + .scope(auth_token, self.inner.0.delete_splits(req)) .await .map(tonic::Response::new) .map_err(crate::error::grpc_error_to_grpc_status) @@ -5453,9 +5508,14 @@ for MetastoreServiceGrpcServerAdapter { &self, request: tonic::Request, ) -> Result, tonic::Status> { - self.inner - .0 - .add_source(request.into_inner()) + let auth_token = quickwit_auth::get_auth_token(request.metadata())?; + let req = { + let req = request.into_inner(); + req + }; + quickwit_auth::authorize(&req, &auth_token)?; + quickwit_auth::AUTHORIZATION_TOKEN + .scope(auth_token, self.inner.0.add_source(req)) .await .map(tonic::Response::new) .map_err(crate::error::grpc_error_to_grpc_status) @@ -5464,9 +5524,14 @@ for MetastoreServiceGrpcServerAdapter { &self, request: tonic::Request, ) -> Result, tonic::Status> { - self.inner - .0 - .toggle_source(request.into_inner()) + let auth_token = quickwit_auth::get_auth_token(request.metadata())?; + let req = { + let req = request.into_inner(); + req + }; + quickwit_auth::authorize(&req, &auth_token)?; + quickwit_auth::AUTHORIZATION_TOKEN + .scope(auth_token, self.inner.0.toggle_source(req)) .await .map(tonic::Response::new) .map_err(crate::error::grpc_error_to_grpc_status) @@ -5475,9 +5540,14 @@ for MetastoreServiceGrpcServerAdapter { &self, request: tonic::Request, ) -> Result, tonic::Status> { - self.inner - .0 - .delete_source(request.into_inner()) + let auth_token = quickwit_auth::get_auth_token(request.metadata())?; + let req = { + let req = request.into_inner(); + req + }; + quickwit_auth::authorize(&req, &auth_token)?; + quickwit_auth::AUTHORIZATION_TOKEN + .scope(auth_token, self.inner.0.delete_source(req)) .await .map(tonic::Response::new) .map_err(crate::error::grpc_error_to_grpc_status) @@ -5486,9 +5556,14 @@ for MetastoreServiceGrpcServerAdapter { &self, request: tonic::Request, ) -> Result, tonic::Status> { - self.inner - .0 - .reset_source_checkpoint(request.into_inner()) + let auth_token = quickwit_auth::get_auth_token(request.metadata())?; + let req = { + let req = request.into_inner(); + req + }; + quickwit_auth::authorize(&req, &auth_token)?; + quickwit_auth::AUTHORIZATION_TOKEN + .scope(auth_token, self.inner.0.reset_source_checkpoint(req)) .await .map(tonic::Response::new) .map_err(crate::error::grpc_error_to_grpc_status) @@ -5497,9 +5572,14 @@ for MetastoreServiceGrpcServerAdapter { &self, request: tonic::Request, ) -> Result, tonic::Status> { - self.inner - .0 - .last_delete_opstamp(request.into_inner()) + let auth_token = quickwit_auth::get_auth_token(request.metadata())?; + let req = { + let req = request.into_inner(); + req + }; + quickwit_auth::authorize(&req, &auth_token)?; + quickwit_auth::AUTHORIZATION_TOKEN + .scope(auth_token, self.inner.0.last_delete_opstamp(req)) .await .map(tonic::Response::new) .map_err(crate::error::grpc_error_to_grpc_status) @@ -5508,9 +5588,14 @@ for MetastoreServiceGrpcServerAdapter { &self, request: tonic::Request, ) -> Result, tonic::Status> { - self.inner - .0 - .create_delete_task(request.into_inner()) + let auth_token = quickwit_auth::get_auth_token(request.metadata())?; + let req = { + let req = request.into_inner(); + req + }; + quickwit_auth::authorize(&req, &auth_token)?; + quickwit_auth::AUTHORIZATION_TOKEN + .scope(auth_token, self.inner.0.create_delete_task(req)) .await .map(tonic::Response::new) .map_err(crate::error::grpc_error_to_grpc_status) @@ -5519,9 +5604,14 @@ for MetastoreServiceGrpcServerAdapter { &self, request: tonic::Request, ) -> Result, tonic::Status> { - self.inner - .0 - .update_splits_delete_opstamp(request.into_inner()) + let auth_token = quickwit_auth::get_auth_token(request.metadata())?; + let req = { + let req = request.into_inner(); + req + }; + quickwit_auth::authorize(&req, &auth_token)?; + quickwit_auth::AUTHORIZATION_TOKEN + .scope(auth_token, self.inner.0.update_splits_delete_opstamp(req)) .await .map(tonic::Response::new) .map_err(crate::error::grpc_error_to_grpc_status) @@ -5530,9 +5620,14 @@ for MetastoreServiceGrpcServerAdapter { &self, request: tonic::Request, ) -> Result, tonic::Status> { - self.inner - .0 - .list_delete_tasks(request.into_inner()) + let auth_token = quickwit_auth::get_auth_token(request.metadata())?; + let req = { + let req = request.into_inner(); + req + }; + quickwit_auth::authorize(&req, &auth_token)?; + quickwit_auth::AUTHORIZATION_TOKEN + .scope(auth_token, self.inner.0.list_delete_tasks(req)) .await .map(tonic::Response::new) .map_err(crate::error::grpc_error_to_grpc_status) @@ -5541,9 +5636,14 @@ for MetastoreServiceGrpcServerAdapter { &self, request: tonic::Request, ) -> Result, tonic::Status> { - self.inner - .0 - .list_stale_splits(request.into_inner()) + let auth_token = quickwit_auth::get_auth_token(request.metadata())?; + let req = { + let req = request.into_inner(); + req + }; + quickwit_auth::authorize(&req, &auth_token)?; + quickwit_auth::AUTHORIZATION_TOKEN + .scope(auth_token, self.inner.0.list_stale_splits(req)) .await .map(tonic::Response::new) .map_err(crate::error::grpc_error_to_grpc_status) @@ -5552,9 +5652,14 @@ for MetastoreServiceGrpcServerAdapter { &self, request: tonic::Request, ) -> Result, tonic::Status> { - self.inner - .0 - .open_shards(request.into_inner()) + let auth_token = quickwit_auth::get_auth_token(request.metadata())?; + let req = { + let req = request.into_inner(); + req + }; + quickwit_auth::authorize(&req, &auth_token)?; + quickwit_auth::AUTHORIZATION_TOKEN + .scope(auth_token, self.inner.0.open_shards(req)) .await .map(tonic::Response::new) .map_err(crate::error::grpc_error_to_grpc_status) @@ -5563,9 +5668,14 @@ for MetastoreServiceGrpcServerAdapter { &self, request: tonic::Request, ) -> Result, tonic::Status> { - self.inner - .0 - .acquire_shards(request.into_inner()) + let auth_token = quickwit_auth::get_auth_token(request.metadata())?; + let req = { + let req = request.into_inner(); + req + }; + quickwit_auth::authorize(&req, &auth_token)?; + quickwit_auth::AUTHORIZATION_TOKEN + .scope(auth_token, self.inner.0.acquire_shards(req)) .await .map(tonic::Response::new) .map_err(crate::error::grpc_error_to_grpc_status) @@ -5574,9 +5684,14 @@ for MetastoreServiceGrpcServerAdapter { &self, request: tonic::Request, ) -> Result, tonic::Status> { - self.inner - .0 - .delete_shards(request.into_inner()) + let auth_token = quickwit_auth::get_auth_token(request.metadata())?; + let req = { + let req = request.into_inner(); + req + }; + quickwit_auth::authorize(&req, &auth_token)?; + quickwit_auth::AUTHORIZATION_TOKEN + .scope(auth_token, self.inner.0.delete_shards(req)) .await .map(tonic::Response::new) .map_err(crate::error::grpc_error_to_grpc_status) @@ -5585,9 +5700,14 @@ for MetastoreServiceGrpcServerAdapter { &self, request: tonic::Request, ) -> Result, tonic::Status> { - self.inner - .0 - .prune_shards(request.into_inner()) + let auth_token = quickwit_auth::get_auth_token(request.metadata())?; + let req = { + let req = request.into_inner(); + req + }; + quickwit_auth::authorize(&req, &auth_token)?; + quickwit_auth::AUTHORIZATION_TOKEN + .scope(auth_token, self.inner.0.prune_shards(req)) .await .map(tonic::Response::new) .map_err(crate::error::grpc_error_to_grpc_status) @@ -5596,9 +5716,14 @@ for MetastoreServiceGrpcServerAdapter { &self, request: tonic::Request, ) -> Result, tonic::Status> { - self.inner - .0 - .list_shards(request.into_inner()) + let auth_token = quickwit_auth::get_auth_token(request.metadata())?; + let req = { + let req = request.into_inner(); + req + }; + quickwit_auth::authorize(&req, &auth_token)?; + quickwit_auth::AUTHORIZATION_TOKEN + .scope(auth_token, self.inner.0.list_shards(req)) .await .map(tonic::Response::new) .map_err(crate::error::grpc_error_to_grpc_status) @@ -5607,9 +5732,14 @@ for MetastoreServiceGrpcServerAdapter { &self, request: tonic::Request, ) -> Result, tonic::Status> { - self.inner - .0 - .create_index_template(request.into_inner()) + let auth_token = quickwit_auth::get_auth_token(request.metadata())?; + let req = { + let req = request.into_inner(); + req + }; + quickwit_auth::authorize(&req, &auth_token)?; + quickwit_auth::AUTHORIZATION_TOKEN + .scope(auth_token, self.inner.0.create_index_template(req)) .await .map(tonic::Response::new) .map_err(crate::error::grpc_error_to_grpc_status) @@ -5618,9 +5748,14 @@ for MetastoreServiceGrpcServerAdapter { &self, request: tonic::Request, ) -> Result, tonic::Status> { - self.inner - .0 - .get_index_template(request.into_inner()) + let auth_token = quickwit_auth::get_auth_token(request.metadata())?; + let req = { + let req = request.into_inner(); + req + }; + quickwit_auth::authorize(&req, &auth_token)?; + quickwit_auth::AUTHORIZATION_TOKEN + .scope(auth_token, self.inner.0.get_index_template(req)) .await .map(tonic::Response::new) .map_err(crate::error::grpc_error_to_grpc_status) @@ -5629,9 +5764,14 @@ for MetastoreServiceGrpcServerAdapter { &self, request: tonic::Request, ) -> Result, tonic::Status> { - self.inner - .0 - .find_index_template_matches(request.into_inner()) + let auth_token = quickwit_auth::get_auth_token(request.metadata())?; + let req = { + let req = request.into_inner(); + req + }; + quickwit_auth::authorize(&req, &auth_token)?; + quickwit_auth::AUTHORIZATION_TOKEN + .scope(auth_token, self.inner.0.find_index_template_matches(req)) .await .map(tonic::Response::new) .map_err(crate::error::grpc_error_to_grpc_status) @@ -5640,9 +5780,14 @@ for MetastoreServiceGrpcServerAdapter { &self, request: tonic::Request, ) -> Result, tonic::Status> { - self.inner - .0 - .list_index_templates(request.into_inner()) + let auth_token = quickwit_auth::get_auth_token(request.metadata())?; + let req = { + let req = request.into_inner(); + req + }; + quickwit_auth::authorize(&req, &auth_token)?; + quickwit_auth::AUTHORIZATION_TOKEN + .scope(auth_token, self.inner.0.list_index_templates(req)) .await .map(tonic::Response::new) .map_err(crate::error::grpc_error_to_grpc_status) @@ -5651,9 +5796,14 @@ for MetastoreServiceGrpcServerAdapter { &self, request: tonic::Request, ) -> Result, tonic::Status> { - self.inner - .0 - .delete_index_templates(request.into_inner()) + let auth_token = quickwit_auth::get_auth_token(request.metadata())?; + let req = { + let req = request.into_inner(); + req + }; + quickwit_auth::authorize(&req, &auth_token)?; + quickwit_auth::AUTHORIZATION_TOKEN + .scope(auth_token, self.inner.0.delete_index_templates(req)) .await .map(tonic::Response::new) .map_err(crate::error::grpc_error_to_grpc_status) diff --git a/quickwit/quickwit-proto/src/lib.rs b/quickwit/quickwit-proto/src/lib.rs index c5a2aa5034d..14d1969c573 100644 --- a/quickwit/quickwit-proto/src/lib.rs +++ b/quickwit/quickwit-proto/src/lib.rs @@ -32,6 +32,7 @@ use tracing_opentelemetry::OpenTelemetrySpanExt; pub mod cluster; pub mod control_plane; +mod authorization; pub use {bytes, tonic}; pub mod developer; pub mod error; From afa80fb082ded91d449b8a4c2b1127870fd81deb Mon Sep 17 00:00:00 2001 From: Paul Masurel Date: Thu, 31 Oct 2024 10:49:15 +0900 Subject: [PATCH 2/6] added check --- quickwit/Cargo.lock | 1 + quickwit/Cargo.toml | 1 - quickwit/quickwit-auth/Cargo.toml | 21 + quickwit/quickwit-auth/src/community.rs | 87 ++++ quickwit/quickwit-auth/src/enterprise.rs | 262 +++++++++++ quickwit/quickwit-auth/src/lib.rs | 56 +++ quickwit/quickwit-cli/Cargo.toml | 2 +- quickwit/quickwit-codegen/example/Cargo.toml | 1 + .../example/src/authorization.rs | 40 +- .../example/src/codegen/hello.rs | 30 +- .../quickwit-codegen/example/src/error.rs | 4 + quickwit/quickwit-codegen/example/src/lib.rs | 4 +- quickwit/quickwit-codegen/src/codegen.rs | 32 +- quickwit/quickwit-ingest/Cargo.toml | 1 + quickwit/quickwit-ingest/src/authorize.rs | 40 +- .../src/codegen/ingest_service.rs | 33 +- quickwit/quickwit-ingest/src/error.rs | 13 + .../quickwit-ingest/src/ingest_v2/metrics.rs | 2 + .../quickwit-ingest/src/ingest_v2/router.rs | 4 + .../src/ingest_v2/workbench.rs | 6 + quickwit/quickwit-ingest/src/lib.rs | 4 +- quickwit/quickwit-license/src/lib.rs | 4 - quickwit/quickwit-metastore/Cargo.toml | 1 + quickwit/quickwit-metastore/src/error.rs | 4 + quickwit/quickwit-proto/Cargo.toml | 1 + .../protos/quickwit/ingester.proto | 1 + .../protos/quickwit/router.proto | 1 + quickwit/quickwit-proto/src/authorization.rs | 337 +++----------- quickwit/quickwit-proto/src/cluster/mod.rs | 3 + .../src/codegen/quickwit/quickwit.cluster.rs | 14 +- .../quickwit/quickwit.control_plane.rs | 126 +++--- .../codegen/quickwit/quickwit.developer.rs | 14 +- .../src/codegen/quickwit/quickwit.indexing.rs | 14 +- .../quickwit/quickwit.ingest.ingester.rs | 123 ++--- .../quickwit/quickwit.ingest.router.rs | 14 +- .../codegen/quickwit/quickwit.metastore.rs | 420 +++++++++--------- .../quickwit-proto/src/control_plane/mod.rs | 4 + quickwit/quickwit-proto/src/developer/mod.rs | 3 + quickwit/quickwit-proto/src/error.rs | 10 + quickwit/quickwit-proto/src/indexing/mod.rs | 4 + quickwit/quickwit-proto/src/ingest/mod.rs | 4 + quickwit/quickwit-proto/src/lib.rs | 4 +- quickwit/quickwit-proto/src/metastore/mod.rs | 7 +- .../model/bulk_query_params.rs | 2 +- quickwit/scripts/.ee.license_header.txt | 6 +- quickwit/scripts/check_license_headers.sh | 2 +- 46 files changed, 1052 insertions(+), 715 deletions(-) create mode 100644 quickwit/quickwit-auth/Cargo.toml create mode 100644 quickwit/quickwit-auth/src/community.rs create mode 100644 quickwit/quickwit-auth/src/enterprise.rs create mode 100644 quickwit/quickwit-auth/src/lib.rs diff --git a/quickwit/Cargo.lock b/quickwit/Cargo.lock index f1851bba250..5a90536790e 100644 --- a/quickwit/Cargo.lock +++ b/quickwit/Cargo.lock @@ -6559,6 +6559,7 @@ dependencies = [ "mockall", "once_cell", "ouroboros", + "quickwit-auth", "quickwit-common", "quickwit-config", "quickwit-doc-mapper", diff --git a/quickwit/Cargo.toml b/quickwit/Cargo.toml index 082748687a8..12bdd18eae4 100644 --- a/quickwit/Cargo.toml +++ b/quickwit/Cargo.toml @@ -36,7 +36,6 @@ members = [ "quickwit-serve", "quickwit-storage", "quickwit-telemetry", - "quickwit-telemetry", ] # The following list excludes `quickwit-metastore-utils` and `quickwit-lambda` diff --git a/quickwit/quickwit-auth/Cargo.toml b/quickwit/quickwit-auth/Cargo.toml new file mode 100644 index 00000000000..ea2013777c5 --- /dev/null +++ b/quickwit/quickwit-auth/Cargo.toml @@ -0,0 +1,21 @@ +[package] +name = "quickwit-auth" +version.workspace = true +edition.workspace = true +homepage.workspace = true +documentation.workspace = true +repository.workspace = true +authors.workspace = true +license.workspace = true + +[dependencies] +biscuit-auth = { workspace = true, optional=true } +http = { workspace = true } +serde = { workspace = true } +thiserror = { workspace = true } +tonic = { workspace = true } +tokio = { workspace = true } +tracing = { workspace = true } + +[features] +enterprise = ["biscuit-auth"] diff --git a/quickwit/quickwit-auth/src/community.rs b/quickwit/quickwit-auth/src/community.rs new file mode 100644 index 00000000000..7be01328fde --- /dev/null +++ b/quickwit/quickwit-auth/src/community.rs @@ -0,0 +1,87 @@ +// Copyright (C) 2024 Quickwit, Inc. +// +// Quickwit is offered under the AGPL v3.0 and as commercial software. +// For commercial licensing, contact us at hello@quickwit.io. +// +// AGPL: +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as +// published by the Free Software Foundation, either version 3 of the +// License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + +use std::future::Future; + +use crate::AuthorizationError; + +pub type AuthorizationToken = (); + +pub trait Authorization { + fn attenuate( + &self, + _auth_token: AuthorizationToken, + ) -> Result { + Ok(()) + } +} + +impl Authorization for T {} + +pub trait StreamAuthorization { + fn attenuate( + _auth_token: AuthorizationToken, + ) -> std::result::Result { + Ok(()) + } +} + +impl StreamAuthorization for T {} + +pub fn get_auth_token( + _req_metadata: &tonic::metadata::MetadataMap, +) -> Result { + Ok(()) +} + +pub fn set_auth_token( + _auth_token: &AuthorizationToken, + _req_metadata: &mut tonic::metadata::MetadataMap, +) { +} + +pub fn authorize( + _req: &R, + _auth_token: &AuthorizationToken, +) -> Result<(), AuthorizationError> { + Ok(()) +} + +pub fn build_tonic_stream_request_with_auth_token( + req: R, +) -> Result, AuthorizationError> { + Ok(tonic::Request::new(req)) +} + +pub fn build_tonic_request_with_auth_token( + req: R, +) -> Result, AuthorizationError> { + Ok(tonic::Request::new(req)) +} + +pub fn authorize_stream( + _auth_token: &AuthorizationToken, +) -> Result<(), AuthorizationError> { + Ok(()) +} + +pub fn execute_with_authorization(_: AuthorizationToken, f: F) -> impl Future +where F: Future { + f +} diff --git a/quickwit/quickwit-auth/src/enterprise.rs b/quickwit/quickwit-auth/src/enterprise.rs new file mode 100644 index 00000000000..fd81ab73e49 --- /dev/null +++ b/quickwit/quickwit-auth/src/enterprise.rs @@ -0,0 +1,262 @@ +// The Quickwit Enterprise Edition (EE) license +// Copyright (c) 2024-present Quickwit Inc. +// +// With regard to the Quickwit Software: +// +// This software and associated documentation files (the "Software") may only be +// used in production, if you (and any entity that you represent) hold a valid +// Quickwit Enterprise license corresponding to your usage. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. +// +// For all third party components incorporated into the Quickwit Software, those +// components are licensed under the original license provided by the owner of the +// applicable component. + +use std::future::Future; +use std::str::FromStr; +use std::sync::{Arc, OnceLock}; + +use biscuit_auth::macros::authorizer; +use biscuit_auth::{Authorizer, Biscuit, RootKeyProvider}; + +use crate::AuthorizationError; + +pub struct AuthorizationToken(Biscuit); + +impl AuthorizationToken { + pub fn into_biscuit(self) -> Biscuit { + self.0 + } +} + +impl From for AuthorizationToken { + fn from(biscuit: Biscuit) -> Self { + AuthorizationToken(biscuit) + } +} + +impl std::fmt::Display for AuthorizationToken { + fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { + self.0.fmt(f) + } +} + +impl std::fmt::Debug for AuthorizationToken { + fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { + write!(f, "AuthorizationToken({})", &self.0) + } +} + +static ROOT_KEY_PROVIDER: OnceLock> = OnceLock::new(); + +pub fn set_root_key_provider(key_provider: Arc) { + if ROOT_KEY_PROVIDER.set(key_provider).is_err() { + tracing::error!("root key provider was already initialized"); + } +} + +fn get_root_key_provider() -> Arc { + ROOT_KEY_PROVIDER + .get() + .expect("root key provider should have been initialized beforehand") + .clone() +} + +impl FromStr for AuthorizationToken { + type Err = AuthorizationError; + + fn from_str(token_base64: &str) -> Result { + let root_key_provider = get_root_key_provider(); + let biscuit = Biscuit::from_base64(token_base64, root_key_provider)?; + Ok(AuthorizationToken(biscuit)) + } +} + +tokio::task_local! { + pub static AUTHORIZATION_TOKEN: AuthorizationToken; +} + +const AUTHORIZATION_VALUE_PREFIX: &str = "Bearer "; + +fn default_operation_authorizer( + auth_token: &AuthorizationToken, +) -> Result { + let request_type = std::any::type_name::(); + let operation: &str = request_type.strip_suffix("Request").unwrap(); + let mut authorizer: Authorizer = authorizer!( + r#" + operation({operation}); + + // We generate the actual user role, by doing an union of the rights granted via roles. + user_right($operation) <- role($role), right($role, $operation); + user_right($operation, $resource) <- role($role), right($role, $operation, $resource); + user_right($operation) <- role("root"), operation($operation); + user_right($operation, $resource) <- role("root"), operation($operation), resource($resource); + + // Finally we check that we have access to index1 and index2. + check all operation($operation), right($operation); + + allow if true; + "# + ); + authorizer.set_time(); + authorizer.add_token(&auth_token.0)?; + Ok(authorizer) +} + +pub trait Authorization { + fn attenuate( + &self, + auth_token: AuthorizationToken, + ) -> Result { + Ok(auth_token) + } + + fn authorizer( + &self, + auth_token: &AuthorizationToken, + ) -> Result { + default_operation_authorizer::(auth_token) + } +} + +pub trait StreamAuthorization { + fn attenuate( + auth_token: AuthorizationToken, + ) -> std::result::Result { + Ok(auth_token) + } + fn authorizer( + auth_token: &AuthorizationToken, + ) -> std::result::Result { + default_operation_authorizer::(&auth_token) + } +} + +impl From for AuthorizationError { + fn from(_token_error: biscuit_auth::error::Token) -> AuthorizationError { + AuthorizationError::InvalidToken + } +} + +pub fn get_auth_token( + req_metadata: &tonic::metadata::MetadataMap, +) -> Result { + let authorization_header_value: &str = req_metadata + .get(http::header::AUTHORIZATION.as_str()) + .ok_or(AuthorizationError::AuthorizationTokenMissing)? + .to_str() + .map_err(|_| AuthorizationError::InvalidToken)?; + let authorization_token_str: &str = authorization_header_value + .strip_prefix(AUTHORIZATION_VALUE_PREFIX) + .ok_or(AuthorizationError::InvalidToken)?; + let biscuit: Biscuit = Biscuit::from_base64(authorization_token_str, get_root_key_provider())?; + Ok(AuthorizationToken(biscuit)) +} + +pub fn set_auth_token( + auth_token: &AuthorizationToken, + req_metadata: &mut tonic::metadata::MetadataMap, +) { + let authorization_header_value = format!("{AUTHORIZATION_VALUE_PREFIX}{auth_token}"); + req_metadata.insert( + http::header::AUTHORIZATION.as_str(), + authorization_header_value.parse().unwrap(), + ); +} + +pub fn authorize( + req: &R, + auth_token: &AuthorizationToken, +) -> Result<(), AuthorizationError> { + let mut authorizer = req.authorizer(auth_token)?; + authorizer.add_token(&auth_token.0)?; + authorizer.authorize()?; + Ok(()) +} + +pub fn build_tonic_stream_request_with_auth_token( + req: R, +) -> Result, AuthorizationError> { + AUTHORIZATION_TOKEN + .try_with(|token| { + let mut request = tonic::Request::new(req); + set_auth_token(token, request.metadata_mut()); + Ok(request) + }) + .unwrap_or(Err(AuthorizationError::AuthorizationTokenMissing)) +} + +pub fn build_tonic_request_with_auth_token( + req: R, +) -> Result, AuthorizationError> { + AUTHORIZATION_TOKEN + .try_with(|token| { + let mut request = tonic::Request::new(req); + set_auth_token(token, request.metadata_mut()); + Ok(request) + }) + .unwrap_or(Err(AuthorizationError::AuthorizationTokenMissing)) +} + +pub fn authorize_stream( + auth_token: &AuthorizationToken, +) -> Result<(), AuthorizationError> { + let mut authorizer = R::authorizer(auth_token)?; + authorizer.add_token(&auth_token.0)?; + authorizer.authorize()?; + Ok(()) +} + +pub fn execute_with_authorization( + token: AuthorizationToken, + f: F, +) -> impl Future +where + F: Future, +{ + AUTHORIZATION_TOKEN.scope(token, f) +} + +#[cfg(test)] +mod tests { + use super::*; + + // #[test] + // fn test_auth_token() { + // let mut req_metadata = tonic::metadata::MetadataMap::new(); + // let token = + // let auth_token = "test_token".to_string(); + // set_auth_token(&auth_token, &mut req_metadata); + // let auth_token_retrieved = get_auth_token(&req_metadata).unwrap(); + // assert_eq!(auth_token_retrieved, auth_token); + // } + + #[test] + fn test_auth_token_missing() { + let req_metadata = tonic::metadata::MetadataMap::new(); + let missing_error = get_auth_token(&req_metadata).unwrap_err(); + assert!(matches!( + missing_error, + AuthorizationError::AuthorizationTokenMissing + )); + } + + #[test] + fn test_auth_token_invalid() { + let mut req_metadata = tonic::metadata::MetadataMap::new(); + req_metadata.insert( + http::header::AUTHORIZATION.as_str(), + "some_token".parse().unwrap(), + ); + let missing_error = get_auth_token(&req_metadata).unwrap_err(); + assert!(matches!(missing_error, AuthorizationError::InvalidToken)); + } +} diff --git a/quickwit/quickwit-auth/src/lib.rs b/quickwit/quickwit-auth/src/lib.rs new file mode 100644 index 00000000000..cccaf68989a --- /dev/null +++ b/quickwit/quickwit-auth/src/lib.rs @@ -0,0 +1,56 @@ +// Copyright (C) 2024 Quickwit, Inc. +// +// Quickwit is offered under the AGPL v3.0 and as commercial software. +// For commercial licensing, contact us at hello@quickwit.io. +// +// AGPL: +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as +// published by the Free Software Foundation, either version 3 of the +// License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + +use serde::{Deserialize, Serialize}; + +#[cfg(not(feature = "enterprise"))] +#[path = "community.rs"] +mod implementation; + +#[cfg(feature = "enterprise")] +#[path = "enterprise.rs"] +mod implementation; + +pub use implementation::*; + +#[derive(thiserror::Error, Debug, Clone, Copy, Serialize, Deserialize, Eq, PartialEq)] +pub enum AuthorizationError { + #[error("authorization token missing")] + AuthorizationTokenMissing, + #[error("invalid token")] + InvalidToken, + #[error("permission denied")] + PermissionDenied, +} + +impl From for tonic::Status { + fn from(authorization_error: AuthorizationError) -> tonic::Status { + match authorization_error { + AuthorizationError::AuthorizationTokenMissing => { + tonic::Status::unauthenticated("Authorization token missing") + } + AuthorizationError::InvalidToken => { + tonic::Status::unauthenticated("Invalid authorization token") + } + AuthorizationError::PermissionDenied => { + tonic::Status::permission_denied("Permission denied") + } + } + } +} diff --git a/quickwit/quickwit-cli/Cargo.toml b/quickwit/quickwit-cli/Cargo.toml index 6542536aca1..64bf88dabda 100644 --- a/quickwit/quickwit-cli/Cargo.toml +++ b/quickwit/quickwit-cli/Cargo.toml @@ -79,7 +79,7 @@ quickwit-metastore = { workspace = true, features = ["testsuite"] } quickwit-storage = { workspace = true, features = ["testsuite"] } [features] -enterprise = ["quickwit-config/enterprise"] +enterprise = ["quickwit-config/enterprise", "quickwit-ingest/enterprise", "quickwit-proto/enterprise"] jemalloc = ["dep:tikv-jemalloc-ctl", "dep:tikv-jemallocator"] ci-test = [] pprof = ["quickwit-serve/pprof"] diff --git a/quickwit/quickwit-codegen/example/Cargo.toml b/quickwit/quickwit-codegen/example/Cargo.toml index 69617d20d8f..f678d0cadc2 100644 --- a/quickwit/quickwit-codegen/example/Cargo.toml +++ b/quickwit/quickwit-codegen/example/Cargo.toml @@ -41,3 +41,4 @@ quickwit-codegen = { workspace = true } [features] testsuite = ["mockall"] +enterprise = [ "quickwit-auth/enterprise" ] diff --git a/quickwit/quickwit-codegen/example/src/authorization.rs b/quickwit/quickwit-codegen/example/src/authorization.rs index fa4e0bf0f3d..b58c6bea026 100644 --- a/quickwit/quickwit-codegen/example/src/authorization.rs +++ b/quickwit/quickwit-codegen/example/src/authorization.rs @@ -1,26 +1,46 @@ -use quickwit_auth::Authorization; -use quickwit_auth::AuthorizationError; -use quickwit_auth::AuthorizationToken; -use quickwit_auth::StreamAuthorization; +// The Quickwit Enterprise Edition (EE) license +// Copyright (c) 2024-present Quickwit Inc. +// +// With regard to the Quickwit Software: +// +// This software and associated documentation files (the "Software") may only be +// used in production, if you (and any entity that you represent) hold a valid +// Quickwit Enterprise license corresponding to your usage. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. -use crate::GoodbyeRequest; -use crate::HelloRequest; -use crate::PingRequest; +use quickwit_auth::{Authorization, AuthorizationError, AuthorizationToken, StreamAuthorization}; + +use crate::{GoodbyeRequest, HelloRequest, PingRequest}; impl Authorization for HelloRequest { - fn attenuate(&self, auth_token: quickwit_auth::AuthorizationToken) -> Result { + fn attenuate( + &self, + auth_token: quickwit_auth::AuthorizationToken, + ) -> Result { Ok(auth_token) } } impl Authorization for GoodbyeRequest { - fn attenuate(&self, auth_token: quickwit_auth::AuthorizationToken) -> Result { + fn attenuate( + &self, + auth_token: quickwit_auth::AuthorizationToken, + ) -> Result { Ok(auth_token) } } impl StreamAuthorization for PingRequest { - fn attenuate(auth_token: quickwit_auth::AuthorizationToken) -> Result { + fn attenuate( + auth_token: quickwit_auth::AuthorizationToken, + ) -> Result { Ok(auth_token) } } diff --git a/quickwit/quickwit-codegen/example/src/codegen/hello.rs b/quickwit/quickwit-codegen/example/src/codegen/hello.rs index 38dee0dc214..83b8cb40bb0 100644 --- a/quickwit/quickwit-codegen/example/src/codegen/hello.rs +++ b/quickwit/quickwit-codegen/example/src/codegen/hello.rs @@ -723,9 +723,10 @@ where T::Future: Send, { async fn hello(&self, request: HelloRequest) -> crate::HelloResult { + let tonic_request = quickwit_auth::build_tonic_request_with_auth_token(request)?; self.inner .clone() - .hello(request) + .hello(tonic_request) .await .map(|response| response.into_inner()) .map_err(|status| crate::error::grpc_status_to_service_error( @@ -737,9 +738,10 @@ where &self, request: GoodbyeRequest, ) -> crate::HelloResult { + let tonic_request = quickwit_auth::build_tonic_request_with_auth_token(request)?; self.inner .clone() - .goodbye(request) + .goodbye(tonic_request) .await .map(|response| response.into_inner()) .map_err(|status| crate::error::grpc_status_to_service_error( @@ -751,9 +753,12 @@ where &self, request: quickwit_common::ServiceStream, ) -> crate::HelloResult> { + let tonic_request = quickwit_auth::build_tonic_stream_request_with_auth_token( + request, + )?; self.inner .clone() - .ping(request) + .ping(tonic_request) .await .map(|response| { let streaming: tonic::Streaming<_> = response.into_inner(); @@ -806,13 +811,9 @@ impl hello_grpc_server::HelloGrpc for HelloGrpcServerAdapter { request: tonic::Request, ) -> Result, tonic::Status> { let auth_token = quickwit_auth::get_auth_token(request.metadata())?; - let req = { - let req = request.into_inner(); - req - }; + let req = request.into_inner(); quickwit_auth::authorize(&req, &auth_token)?; - quickwit_auth::AUTHORIZATION_TOKEN - .scope(auth_token, self.inner.0.hello(req)) + quickwit_auth::execute_with_authorization(auth_token, self.inner.0.hello(req)) .await .map(tonic::Response::new) .map_err(crate::error::grpc_error_to_grpc_status) @@ -822,13 +823,9 @@ impl hello_grpc_server::HelloGrpc for HelloGrpcServerAdapter { request: tonic::Request, ) -> Result, tonic::Status> { let auth_token = quickwit_auth::get_auth_token(request.metadata())?; - let req = { - let req = request.into_inner(); - req - }; + let req = request.into_inner(); quickwit_auth::authorize(&req, &auth_token)?; - quickwit_auth::AUTHORIZATION_TOKEN - .scope(auth_token, self.inner.0.goodbye(req)) + quickwit_auth::execute_with_authorization(auth_token, self.inner.0.goodbye(req)) .await .map(tonic::Response::new) .map_err(crate::error::grpc_error_to_grpc_status) @@ -844,8 +841,7 @@ impl hello_grpc_server::HelloGrpc for HelloGrpcServerAdapter { quickwit_common::ServiceStream::from(streaming) }; quickwit_auth::authorize_stream::(&auth_token)?; - quickwit_auth::AUTHORIZATION_TOKEN - .scope(auth_token, self.inner.0.ping(req)) + quickwit_auth::execute_with_authorization(auth_token, self.inner.0.ping(req)) .await .map(|stream| tonic::Response::new( stream.map_err(crate::error::grpc_error_to_grpc_status), diff --git a/quickwit/quickwit-codegen/example/src/error.rs b/quickwit/quickwit-codegen/example/src/error.rs index ab35bf53dd9..9d3a9dbde19 100644 --- a/quickwit/quickwit-codegen/example/src/error.rs +++ b/quickwit/quickwit-codegen/example/src/error.rs @@ -20,6 +20,7 @@ use std::fmt; use quickwit_actors::AskError; +use quickwit_auth::AuthorizationError; use quickwit_proto::error::GrpcServiceError; pub use quickwit_proto::error::{grpc_error_to_grpc_status, grpc_status_to_service_error}; use quickwit_proto::{ServiceError, ServiceErrorCode}; @@ -38,6 +39,8 @@ pub enum HelloError { TooManyRequests, #[error("service unavailable: {0}")] Unavailable(String), + #[error("unauthorized: {0}")] + Unauthorized(#[from] AuthorizationError), } impl ServiceError for HelloError { @@ -48,6 +51,7 @@ impl ServiceError for HelloError { Self::Timeout(_) => ServiceErrorCode::Timeout, Self::TooManyRequests => ServiceErrorCode::TooManyRequests, Self::Unavailable(_) => ServiceErrorCode::Unavailable, + Self::Unauthorized(_) => ServiceErrorCode::Unauthorized, } } } diff --git a/quickwit/quickwit-codegen/example/src/lib.rs b/quickwit/quickwit-codegen/example/src/lib.rs index 6ff2bd41fac..7e4da88ed55 100644 --- a/quickwit/quickwit-codegen/example/src/lib.rs +++ b/quickwit/quickwit-codegen/example/src/lib.rs @@ -19,9 +19,11 @@ mod error; +#[cfg(feature = "enterprise")] +mod authorization; + #[path = "codegen/hello.rs"] mod hello; -mod authorization; use std::sync::atomic::{AtomicUsize, Ordering}; use std::sync::Arc; diff --git a/quickwit/quickwit-codegen/src/codegen.rs b/quickwit/quickwit-codegen/src/codegen.rs index 198ab048b14..26d284e54ba 100644 --- a/quickwit/quickwit-codegen/src/codegen.rs +++ b/quickwit/quickwit-codegen/src/codegen.rs @@ -1167,14 +1167,29 @@ fn generate_grpc_client_adapter_methods(context: &CodegenContext) -> TokenStream } else { quote! { |response| response.into_inner() } }; - let method = quote! { - async fn #method_name(&self, request: #request_type) -> #result_type<#response_type> { - self.inner + let method = if syn_method.client_streaming { + quote! { + async fn #method_name(&self, request: #request_type) -> #result_type<#response_type> { + let tonic_request = quickwit_auth::build_tonic_stream_request_with_auth_token(request)?; + self.inner .clone() - .#method_name(request) + .#method_name(tonic_request) .await .map(#into_response_type) .map_err(|status| crate::error::grpc_status_to_service_error(status, #rpc_name)) + } + } + } else { + quote! { + async fn #method_name(&self, request: #request_type) -> #result_type<#response_type> { + let tonic_request = quickwit_auth::build_tonic_request_with_auth_token(request)?; + self.inner + .clone() + .#method_name(tonic_request) + .await + .map(#into_response_type) + .map_err(|status| crate::error::grpc_status_to_service_error(status, #rpc_name)) + } } }; stream.extend(method); @@ -1232,10 +1247,7 @@ fn generate_grpc_server_adapter_methods(context: &CodegenContext) -> TokenStream } } else { quote! { - { - let req = request.into_inner(); - req - } + request.into_inner() } }; let response_type = if syn_method.server_streaming { @@ -1276,7 +1288,7 @@ fn generate_grpc_server_adapter_methods(context: &CodegenContext) -> TokenStream let auth_token = quickwit_auth::get_auth_token(request.metadata())?; let req = #method_arg; #authorize_block; - quickwit_auth::AUTHORIZATION_TOKEN.scope(auth_token, self.inner.0.#method_name(req)).await + quickwit_auth::execute_with_authorization(auth_token, self.inner.0.#method_name(req)).await .map(#into_response_type) .map_err(crate::error::grpc_error_to_grpc_status) } @@ -1286,8 +1298,6 @@ fn generate_grpc_server_adapter_methods(context: &CodegenContext) -> TokenStream stream } - - /// A [`ServiceGenerator`] wrapper that appends a suffix to the name of the wrapped service. It is /// used to add a `Grpc` suffix to the service, client, and server generated by tonic. struct WithSuffixServiceGenerator { diff --git a/quickwit/quickwit-ingest/Cargo.toml b/quickwit/quickwit-ingest/Cargo.toml index 3577addff50..2fdb7195555 100644 --- a/quickwit/quickwit-ingest/Cargo.toml +++ b/quickwit/quickwit-ingest/Cargo.toml @@ -63,3 +63,4 @@ quickwit-codegen = { workspace = true } failpoints = ["fail/failpoints"] no-failpoints = [] testsuite = ["mockall"] +enterprise = ["quickwit-auth/enterprise"] diff --git a/quickwit/quickwit-ingest/src/authorize.rs b/quickwit/quickwit-ingest/src/authorize.rs index c739f2adb1a..8b1b9287ce0 100644 --- a/quickwit/quickwit-ingest/src/authorize.rs +++ b/quickwit/quickwit-ingest/src/authorize.rs @@ -1,25 +1,47 @@ -use quickwit_auth::Authorization; -use quickwit_auth::AuthorizationError; -use quickwit_auth::AuthorizationToken; +// The Quickwit Enterprise Edition (EE) license +// Copyright (c) 2024-present Quickwit Inc. +// +// With regard to the Quickwit Software: +// +// This software and associated documentation files (the "Software") may only be +// used in production, if you (and any entity that you represent) hold a valid +// Quickwit Enterprise license corresponding to your usage. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. -use crate::FetchRequest; -use crate::IngestRequest; -use crate::TailRequest; +use quickwit_auth::{Authorization, AuthorizationError, AuthorizationToken}; + +use crate::{FetchRequest, IngestRequest, TailRequest}; impl Authorization for TailRequest { - fn attenuate(&self, auth_token: AuthorizationToken) -> Result { + fn attenuate( + &self, + auth_token: AuthorizationToken, + ) -> Result { Ok(auth_token) } } impl Authorization for IngestRequest { - fn attenuate(&self, auth_token: AuthorizationToken) -> Result { + fn attenuate( + &self, + auth_token: AuthorizationToken, + ) -> Result { Ok(auth_token) } } impl Authorization for FetchRequest { - fn attenuate(&self, auth_token: AuthorizationToken) -> Result { + fn attenuate( + &self, + auth_token: AuthorizationToken, + ) -> Result { Ok(auth_token) } } diff --git a/quickwit/quickwit-ingest/src/codegen/ingest_service.rs b/quickwit/quickwit-ingest/src/codegen/ingest_service.rs index 8aeec3f2e86..49e20a534be 100644 --- a/quickwit/quickwit-ingest/src/codegen/ingest_service.rs +++ b/quickwit/quickwit-ingest/src/codegen/ingest_service.rs @@ -819,9 +819,10 @@ where T::Future: Send, { async fn ingest(&self, request: IngestRequest) -> crate::Result { + let tonic_request = quickwit_auth::build_tonic_request_with_auth_token(request)?; self.inner .clone() - .ingest(request) + .ingest(tonic_request) .await .map(|response| response.into_inner()) .map_err(|status| crate::error::grpc_status_to_service_error( @@ -830,9 +831,10 @@ where )) } async fn fetch(&self, request: FetchRequest) -> crate::Result { + let tonic_request = quickwit_auth::build_tonic_request_with_auth_token(request)?; self.inner .clone() - .fetch(request) + .fetch(tonic_request) .await .map(|response| response.into_inner()) .map_err(|status| crate::error::grpc_status_to_service_error( @@ -841,9 +843,10 @@ where )) } async fn tail(&self, request: TailRequest) -> crate::Result { + let tonic_request = quickwit_auth::build_tonic_request_with_auth_token(request)?; self.inner .clone() - .tail(request) + .tail(tonic_request) .await .map(|response| response.into_inner()) .map_err(|status| crate::error::grpc_status_to_service_error( @@ -873,13 +876,9 @@ impl ingest_service_grpc_server::IngestServiceGrpc for IngestServiceGrpcServerAd request: tonic::Request, ) -> Result, tonic::Status> { let auth_token = quickwit_auth::get_auth_token(request.metadata())?; - let req = { - let req = request.into_inner(); - req - }; + let req = request.into_inner(); quickwit_auth::authorize(&req, &auth_token)?; - quickwit_auth::AUTHORIZATION_TOKEN - .scope(auth_token, self.inner.0.ingest(req)) + quickwit_auth::execute_with_authorization(auth_token, self.inner.0.ingest(req)) .await .map(tonic::Response::new) .map_err(crate::error::grpc_error_to_grpc_status) @@ -889,13 +888,9 @@ impl ingest_service_grpc_server::IngestServiceGrpc for IngestServiceGrpcServerAd request: tonic::Request, ) -> Result, tonic::Status> { let auth_token = quickwit_auth::get_auth_token(request.metadata())?; - let req = { - let req = request.into_inner(); - req - }; + let req = request.into_inner(); quickwit_auth::authorize(&req, &auth_token)?; - quickwit_auth::AUTHORIZATION_TOKEN - .scope(auth_token, self.inner.0.fetch(req)) + quickwit_auth::execute_with_authorization(auth_token, self.inner.0.fetch(req)) .await .map(tonic::Response::new) .map_err(crate::error::grpc_error_to_grpc_status) @@ -905,13 +900,9 @@ impl ingest_service_grpc_server::IngestServiceGrpc for IngestServiceGrpcServerAd request: tonic::Request, ) -> Result, tonic::Status> { let auth_token = quickwit_auth::get_auth_token(request.metadata())?; - let req = { - let req = request.into_inner(); - req - }; + let req = request.into_inner(); quickwit_auth::authorize(&req, &auth_token)?; - quickwit_auth::AUTHORIZATION_TOKEN - .scope(auth_token, self.inner.0.tail(req)) + quickwit_auth::execute_with_authorization(auth_token, self.inner.0.tail(req)) .await .map(tonic::Response::new) .map_err(crate::error::grpc_error_to_grpc_status) diff --git a/quickwit/quickwit-ingest/src/error.rs b/quickwit/quickwit-ingest/src/error.rs index ab2c282db36..0b99ba27c95 100644 --- a/quickwit/quickwit-ingest/src/error.rs +++ b/quickwit/quickwit-ingest/src/error.rs @@ -21,6 +21,7 @@ use std::io; use mrecordlog::error::*; use quickwit_actors::AskError; +use quickwit_auth::AuthorizationError; use quickwit_common::rate_limited_error; use quickwit_common::tower::BufferError; pub(crate) use quickwit_proto::error::{grpc_error_to_grpc_status, grpc_status_to_service_error}; @@ -48,6 +49,8 @@ pub enum IngestServiceError { RateLimited(RateLimitingCause), #[error("ingest service is unavailable ({0})")] Unavailable(String), + #[error("unauthorized: {0}")] + Unauthorized(#[from] AuthorizationError), } impl From> for IngestServiceError { @@ -93,6 +96,9 @@ impl From for IngestServiceError { IngestV2Error::TooManyRequests(rate_limiting_cause) => { IngestServiceError::RateLimited(rate_limiting_cause) } + IngestV2Error::Unauthorized(authorization_error) => { + IngestServiceError::Unauthorized(authorization_error) + } } } } @@ -134,6 +140,9 @@ impl From for IngestServiceError { IngestFailureReason::CircuitBreaker => { IngestServiceError::RateLimited(RateLimitingCause::CircuitBreaker) } + IngestFailureReason::Unauthorized => { + IngestServiceError::Unauthorized(AuthorizationError::PermissionDenied) + } } } } @@ -161,6 +170,7 @@ impl ServiceError for IngestServiceError { } Self::RateLimited(_) => ServiceErrorCode::TooManyRequests, Self::Unavailable(_) => ServiceErrorCode::Unavailable, + Self::Unauthorized(_) => ServiceErrorCode::Unauthorized, } } } @@ -204,6 +214,9 @@ impl From for tonic::Status { IngestServiceError::IoError { .. } => tonic::Code::Internal, IngestServiceError::RateLimited(_) => tonic::Code::ResourceExhausted, IngestServiceError::Unavailable(_) => tonic::Code::Unavailable, + IngestServiceError::Unauthorized(authorized_error) => { + return (*authorized_error).into(); + } }; let message = error.to_string(); tonic::Status::new(code, message) diff --git a/quickwit/quickwit-ingest/src/ingest_v2/metrics.rs b/quickwit/quickwit-ingest/src/ingest_v2/metrics.rs index 8fc6a75b9f4..a5ae312faef 100644 --- a/quickwit/quickwit-ingest/src/ingest_v2/metrics.rs +++ b/quickwit/quickwit-ingest/src/ingest_v2/metrics.rs @@ -44,6 +44,7 @@ pub(crate) struct IngestResultMetrics { pub load_shedding: IntCounter, pub shard_not_found: IntCounter, pub unavailable: IntCounter, + pub unauthorized: IntCounter, } impl Default for IngestResultMetrics { @@ -72,6 +73,7 @@ impl Default for IngestResultMetrics { load_shedding: ingest_result_total_vec.with_label_values(["load_shedding"]), unavailable: ingest_result_total_vec.with_label_values(["unavailable"]), shard_not_found: ingest_result_total_vec.with_label_values(["shard_not_found"]), + unauthorized: ingest_result_total_vec.with_label_values(["unauthorized"]), } } } diff --git a/quickwit/quickwit-ingest/src/ingest_v2/router.rs b/quickwit/quickwit-ingest/src/ingest_v2/router.rs index d20d5c2e74c..0f18bf53d6b 100644 --- a/quickwit/quickwit-ingest/src/ingest_v2/router.rs +++ b/quickwit/quickwit-ingest/src/ingest_v2/router.rs @@ -542,6 +542,7 @@ fn update_ingest_metrics(ingest_result: &IngestV2Result, num_s ingest_results_metrics.router_load_shedding.inc() } IngestFailureReason::LoadShedding => ingest_results_metrics.load_shedding.inc(), + IngestFailureReason::Unauthorized => ingest_results_metrics.unauthorized.inc(), } } } @@ -588,6 +589,9 @@ fn update_ingest_metrics(ingest_result: &IngestV2Result, num_s IngestV2Error::Internal(_) => { ingest_results_metrics.internal.inc_by(num_subrequests); } + IngestV2Error::Unauthorized(_) => { + ingest_results_metrics.unauthorized.inc_by(num_subrequests); + } }, } } diff --git a/quickwit/quickwit-ingest/src/ingest_v2/workbench.rs b/quickwit/quickwit-ingest/src/ingest_v2/workbench.rs index 7dab68c5485..8717b959373 100644 --- a/quickwit/quickwit-ingest/src/ingest_v2/workbench.rs +++ b/quickwit/quickwit-ingest/src/ingest_v2/workbench.rs @@ -224,6 +224,12 @@ impl IngestWorkbench { self.record_too_many_requests(subrequest_id, rate_limiting_cause); } } + IngestV2Error::Unauthorized(_) => { + for subrequest_id in persist_summary.subrequest_ids { + let failure = SubworkbenchFailure::Persist(PersistFailureReason::Unauthorized); + self.record_failure(subrequest_id, failure); + } + } } } diff --git a/quickwit/quickwit-ingest/src/lib.rs b/quickwit/quickwit-ingest/src/lib.rs index 3bed1dd7833..33e23055ccd 100644 --- a/quickwit/quickwit-ingest/src/lib.rs +++ b/quickwit/quickwit-ingest/src/lib.rs @@ -19,6 +19,9 @@ #![deny(clippy::disallowed_methods)] +#[cfg(feature = "enterprise")] +mod authorize; + mod doc_batch; pub mod error; mod ingest_api_service; @@ -31,7 +34,6 @@ mod mrecordlog_async; mod notifications; mod position; mod queue; -mod authorize; use std::collections::HashMap; use std::path::{Path, PathBuf}; diff --git a/quickwit/quickwit-license/src/lib.rs b/quickwit/quickwit-license/src/lib.rs index 8cd89f3dad3..4c38b3adc9b 100644 --- a/quickwit/quickwit-license/src/lib.rs +++ b/quickwit/quickwit-license/src/lib.rs @@ -15,10 +15,6 @@ // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. -// For all third party components incorporated into the Quickwit Software, those -// components are licensed under the original license provided by the owner of the -// applicable component. - use std::str::FromStr; use std::sync::OnceLock; use std::time::SystemTime; diff --git a/quickwit/quickwit-metastore/Cargo.toml b/quickwit/quickwit-metastore/Cargo.toml index a2ff2470cbc..4e4c7ec98aa 100644 --- a/quickwit/quickwit-metastore/Cargo.toml +++ b/quickwit/quickwit-metastore/Cargo.toml @@ -39,6 +39,7 @@ tracing = { workspace = true } ulid = { workspace = true, features = ["serde"] } utoipa = { workspace = true } +quickwit-auth = { workspace = true } quickwit-common = { workspace = true } quickwit-config = { workspace = true } quickwit-doc-mapper = { workspace = true } diff --git a/quickwit/quickwit-metastore/src/error.rs b/quickwit/quickwit-metastore/src/error.rs index 3e02d2cbed4..43c7f4b6ec9 100644 --- a/quickwit/quickwit-metastore/src/error.rs +++ b/quickwit/quickwit-metastore/src/error.rs @@ -39,4 +39,8 @@ pub enum MetastoreResolverError { /// error, incompatible version, internal error in a third party, etc. #[error("failed to connect to metastore: `{0}`")] Initialization(#[from] MetastoreError), + + /// The requested operation is not authorized. + #[error("unauthorized: `{0}`")] + Unauthorized(#[from] quickwit_auth::AuthorizationError), } diff --git a/quickwit/quickwit-proto/Cargo.toml b/quickwit/quickwit-proto/Cargo.toml index 088235e9c28..a5e90f751ae 100644 --- a/quickwit/quickwit-proto/Cargo.toml +++ b/quickwit/quickwit-proto/Cargo.toml @@ -54,3 +54,4 @@ quickwit-codegen = { workspace = true } [features] postgres = ["sea-query", "sqlx"] testsuite = ["mockall", "futures"] +enterprise = [ "quickwit-auth/enterprise"] diff --git a/quickwit/quickwit-proto/protos/quickwit/ingester.proto b/quickwit/quickwit-proto/protos/quickwit/ingester.proto index 8874176b941..2e9e8c75e9a 100644 --- a/quickwit/quickwit-proto/protos/quickwit/ingester.proto +++ b/quickwit/quickwit-proto/protos/quickwit/ingester.proto @@ -106,6 +106,7 @@ enum PersistFailureReason { PERSIST_FAILURE_REASON_SHARD_RATE_LIMITED = 3; PERSIST_FAILURE_REASON_WAL_FULL = 4; PERSIST_FAILURE_REASON_TIMEOUT = 5; + PERSIST_FAILURE_REASON_UNAUTHORIZED = 6; } message PersistFailure { diff --git a/quickwit/quickwit-proto/protos/quickwit/router.proto b/quickwit/quickwit-proto/protos/quickwit/router.proto index 8db31d7bf15..9f13db2c4b8 100644 --- a/quickwit/quickwit-proto/protos/quickwit/router.proto +++ b/quickwit/quickwit-proto/protos/quickwit/router.proto @@ -73,6 +73,7 @@ enum IngestFailureReason { INGEST_FAILURE_REASON_ROUTER_LOAD_SHEDDING = 8; INGEST_FAILURE_REASON_LOAD_SHEDDING = 9; INGEST_FAILURE_REASON_CIRCUIT_BREAKER = 10; + INGEST_FAILURE_REASON_UNAUTHORIZED = 11; } message IngestFailure { diff --git a/quickwit/quickwit-proto/src/authorization.rs b/quickwit/quickwit-proto/src/authorization.rs index 6316aaac9e8..a7887ab339d 100644 --- a/quickwit/quickwit-proto/src/authorization.rs +++ b/quickwit/quickwit-proto/src/authorization.rs @@ -1,326 +1,123 @@ -use std::time::Duration; -use std::time::SystemTime; +use std::time::{Duration, SystemTime}; use biscuit_auth::builder_ext::BuilderExt; -use quickwit_auth::Authorization; -use quickwit_auth::AuthorizationError; -use quickwit_auth::AuthorizationToken; -use quickwit_auth::StreamAuthorization; +use biscuit_auth::macros::*; +use quickwit_auth::{Authorization, AuthorizationError, AuthorizationToken, StreamAuthorization}; + use crate::cluster::FetchClusterStateRequest; -use crate::control_plane::AdviseResetShardsRequest; -use crate::control_plane::GetOrCreateOpenShardsRequest; +use crate::control_plane::{AdviseResetShardsRequest, GetOrCreateOpenShardsRequest}; use crate::developer::GetDebugInfoRequest; use crate::indexing::ApplyIndexingPlanRequest; -use crate::ingest::ingester::CloseShardsRequest; -use crate::ingest::ingester::DecommissionRequest; -use crate::ingest::ingester::InitShardsRequest; -use crate::ingest::ingester::OpenFetchStreamRequest; -use crate::ingest::ingester::OpenObservationStreamRequest; -use crate::ingest::ingester::PersistRequest; -use crate::ingest::ingester::RetainShardsRequest; -use crate::ingest::ingester::SynReplicationMessage; -use crate::ingest::ingester::TruncateShardsRequest; +use crate::ingest::ingester::{ + CloseShardsRequest, DecommissionRequest, InitShardsRequest, OpenFetchStreamRequest, + OpenObservationStreamRequest, PersistRequest, RetainShardsRequest, SynReplicationMessage, + TruncateShardsRequest, +}; use crate::ingest::router::IngestRequestV2; -use crate::metastore::DeleteQuery; -use crate::metastore::GetIndexTemplateRequest; -use crate::metastore::IndexMetadataRequest; -use crate::metastore::LastDeleteOpstampRequest; -use crate::metastore::ListDeleteTasksRequest; -use crate::metastore::ListIndexTemplatesRequest; -use crate::metastore::ListIndexesMetadataRequest; -use crate::metastore::ListShardsRequest; -use crate::metastore::ListSplitsRequest; -use crate::metastore::ListStaleSplitsRequest; -use crate::metastore::OpenShardsRequest; -use crate::metastore::PruneShardsRequest; -use crate::metastore::PublishSplitsRequest; -use crate::metastore::StageSplitsRequest; -use crate::metastore::UpdateSplitsDeleteOpstampRequest; -use biscuit_auth::macros::*; - -impl Authorization for crate::metastore::AcquireShardsRequest { - fn attenuate(&self, auth_token: AuthorizationToken) -> Result { - Ok(auth_token) - } -} - -impl Authorization for crate::metastore::AddSourceRequest { - fn attenuate(&self, auth_token: AuthorizationToken) -> Result { - Ok(auth_token) - } -} +use crate::metastore::{ + DeleteQuery, GetIndexTemplateRequest, IndexMetadataRequest, LastDeleteOpstampRequest, + ListDeleteTasksRequest, ListIndexTemplatesRequest, ListIndexesMetadataRequest, + ListShardsRequest, ListSplitsRequest, ListStaleSplitsRequest, OpenShardsRequest, + PruneShardsRequest, PublishSplitsRequest, StageSplitsRequest, UpdateSplitsDeleteOpstampRequest, +}; +impl Authorization for crate::metastore::AcquireShardsRequest {} +impl Authorization for crate::metastore::AddSourceRequest {} impl Authorization for crate::metastore::CreateIndexRequest { - fn attenuate(&self, auth_token: AuthorizationToken) -> Result { + fn attenuate( + &self, + auth_token: AuthorizationToken, + ) -> Result { let mut builder = block!(r#"check if operation("create_index");"#); builder.check_expiration_date(SystemTime::now() + Duration::from_secs(60)); - let new_auth_token = auth_token.append(builder)?; - Ok(new_auth_token) + let biscuit = auth_token.into_biscuit(); + let new_auth_token = biscuit.append(builder)?; + Ok(AuthorizationToken::from(new_auth_token)) } } -impl Authorization for crate::metastore::CreateIndexTemplateRequest { - fn attenuate(&self, auth_token: AuthorizationToken) -> Result { - Ok(auth_token) - } -} +impl Authorization for crate::metastore::CreateIndexTemplateRequest {} -impl Authorization for crate::metastore::DeleteIndexRequest { - fn attenuate(&self, auth_token: AuthorizationToken) -> Result { - Ok(auth_token) - } -} +impl Authorization for crate::metastore::DeleteIndexRequest {} -impl Authorization for crate::metastore::DeleteIndexTemplatesRequest { - fn attenuate(&self, auth_token: AuthorizationToken) -> Result { - Ok(auth_token) - } -} +impl Authorization for crate::metastore::DeleteIndexTemplatesRequest {} -impl Authorization for crate::metastore::DeleteShardsRequest { - fn attenuate(&self, auth_token: AuthorizationToken) -> Result { - Ok(auth_token) - } -} +impl Authorization for crate::metastore::DeleteShardsRequest {} -impl Authorization for crate::metastore::DeleteSourceRequest { - fn attenuate(&self, auth_token: AuthorizationToken) -> Result { - Ok(auth_token) - } -} +impl Authorization for crate::metastore::DeleteSourceRequest {} -impl Authorization for crate::metastore::DeleteSplitsRequest { - fn attenuate(&self, auth_token: AuthorizationToken) -> Result { - Ok(auth_token) - } -} +impl Authorization for crate::metastore::DeleteSplitsRequest {} -impl Authorization for crate::metastore::FindIndexTemplateMatchesRequest { - fn attenuate(&self, auth_token: AuthorizationToken) -> Result { - Ok(auth_token) - } -} +impl Authorization for crate::metastore::FindIndexTemplateMatchesRequest {} -impl Authorization for crate::metastore::IndexesMetadataRequest { - fn attenuate(&self, auth_token: AuthorizationToken) -> Result { - Ok(auth_token) - } -} +impl Authorization for crate::metastore::IndexesMetadataRequest {} -impl Authorization for crate::metastore::ToggleSourceRequest { - fn attenuate(&self, auth_token: AuthorizationToken) -> Result { - Ok(auth_token) - } -} +impl Authorization for crate::metastore::ToggleSourceRequest {} -impl Authorization for crate::metastore::MarkSplitsForDeletionRequest { - fn attenuate(&self, auth_token: AuthorizationToken) -> Result { - Ok(auth_token) - } -} +impl Authorization for crate::metastore::MarkSplitsForDeletionRequest {} -impl Authorization for crate::metastore::ResetSourceCheckpointRequest { - fn attenuate(&self, auth_token: AuthorizationToken) -> Result { - Ok(auth_token) - } -} +impl Authorization for crate::metastore::ResetSourceCheckpointRequest {} -impl Authorization for crate::metastore::UpdateIndexRequest { - fn attenuate(&self, auth_token: AuthorizationToken) -> Result { - Ok(auth_token) - } -} +impl Authorization for crate::metastore::UpdateIndexRequest {} -impl Authorization for OpenObservationStreamRequest { - fn attenuate(&self, auth_token: AuthorizationToken) -> Result { - Ok(auth_token) - } -} +impl Authorization for OpenObservationStreamRequest {} -impl Authorization for InitShardsRequest { - fn attenuate(&self, auth_token: AuthorizationToken) -> Result { - Ok(auth_token) - } -} +impl Authorization for InitShardsRequest {} -impl Authorization for OpenShardsRequest { - fn attenuate(&self, auth_token: AuthorizationToken) -> Result { - Ok(auth_token) - } -} +impl Authorization for OpenShardsRequest {} -impl Authorization for FetchClusterStateRequest { - fn attenuate(&self, auth_token: AuthorizationToken) -> Result { - Ok(auth_token) - } -} +impl Authorization for FetchClusterStateRequest {} -impl Authorization for GetIndexTemplateRequest { - fn attenuate(&self, auth_token: AuthorizationToken) -> Result { - Ok(auth_token) - } -} +impl Authorization for GetIndexTemplateRequest {} -impl Authorization for ListIndexTemplatesRequest { - fn attenuate(&self, auth_token: AuthorizationToken) -> Result { - Ok(auth_token) - } -} +impl Authorization for ListIndexTemplatesRequest {} -impl Authorization for PruneShardsRequest { - fn attenuate(&self, auth_token: AuthorizationToken) -> Result { - Ok(auth_token) - } -} +impl Authorization for PruneShardsRequest {} -impl Authorization for ListShardsRequest { - fn attenuate(&self, auth_token: AuthorizationToken) -> Result { - Ok(auth_token) - } -} +impl Authorization for ListShardsRequest {} -impl Authorization for ListStaleSplitsRequest { - fn attenuate(&self, auth_token: AuthorizationToken) -> Result { - Ok(auth_token) - } -} +impl Authorization for ListStaleSplitsRequest {} -impl Authorization for ListDeleteTasksRequest { - fn attenuate(&self, auth_token: AuthorizationToken) -> Result { - Ok(auth_token) - } -} +impl Authorization for ListDeleteTasksRequest {} -impl Authorization for UpdateSplitsDeleteOpstampRequest { - fn attenuate(&self, auth_token: AuthorizationToken) -> Result { - Ok(auth_token) - } -} - - -impl Authorization for LastDeleteOpstampRequest { - fn attenuate(&self, auth_token: AuthorizationToken) -> Result { - Ok(auth_token) - } -} - - -impl Authorization for DeleteQuery { - fn attenuate(&self, auth_token: AuthorizationToken) -> Result { - Ok(auth_token) - } -} - - -impl Authorization for GetOrCreateOpenShardsRequest { - fn attenuate(&self, auth_token: AuthorizationToken) -> Result { - Ok(auth_token) - } -} - - -impl Authorization for AdviseResetShardsRequest { - fn attenuate(&self, auth_token: AuthorizationToken) -> Result { - Ok(auth_token) - } -} - - -impl Authorization for GetDebugInfoRequest { - fn attenuate(&self, auth_token: AuthorizationToken) -> Result { - Ok(auth_token) - } -} - - -impl Authorization for StageSplitsRequest { - fn attenuate(&self, auth_token: AuthorizationToken) -> Result { - Ok(auth_token) - } -} +impl Authorization for UpdateSplitsDeleteOpstampRequest {} +impl Authorization for LastDeleteOpstampRequest {} -impl Authorization for ListSplitsRequest { - fn attenuate(&self, auth_token: AuthorizationToken) -> Result { - Ok(auth_token) - } -} +impl Authorization for DeleteQuery {} +impl Authorization for GetOrCreateOpenShardsRequest {} -impl Authorization for PublishSplitsRequest { - fn attenuate(&self, auth_token: AuthorizationToken) -> Result { - Ok(auth_token) - } -} +impl Authorization for AdviseResetShardsRequest {} +impl Authorization for GetDebugInfoRequest {} -impl Authorization for ListIndexesMetadataRequest { - fn attenuate(&self, auth_token: AuthorizationToken) -> Result { - Ok(auth_token) - } -} +impl Authorization for StageSplitsRequest {} -impl Authorization for TruncateShardsRequest { - fn attenuate(&self, auth_token: AuthorizationToken) -> Result { - Ok(auth_token) - } -} +impl Authorization for ListSplitsRequest {} +impl Authorization for PublishSplitsRequest {} -impl Authorization for CloseShardsRequest { - fn attenuate(&self, auth_token: AuthorizationToken) -> Result { - Ok(auth_token) - } -} +impl Authorization for ListIndexesMetadataRequest {} +impl Authorization for TruncateShardsRequest {} -impl Authorization for RetainShardsRequest { - fn attenuate(&self, auth_token: AuthorizationToken) -> Result { - Ok(auth_token) - } -} +impl Authorization for CloseShardsRequest {} -impl Authorization for ApplyIndexingPlanRequest { - fn attenuate(&self, auth_token: AuthorizationToken) -> Result { - Ok(auth_token) - } -} +impl Authorization for RetainShardsRequest {} -impl Authorization for PersistRequest { - fn attenuate(&self, auth_token: AuthorizationToken) -> Result { - Ok(auth_token) - } -} +impl Authorization for ApplyIndexingPlanRequest {} -impl Authorization for IndexMetadataRequest { - fn attenuate(&self, auth_token: AuthorizationToken) -> Result { - Ok(auth_token) - } -} +impl Authorization for PersistRequest {} -impl StreamAuthorization for SynReplicationMessage { - fn attenuate(auth_token: AuthorizationToken) -> Result { - Ok(auth_token) - } -} +impl Authorization for IndexMetadataRequest {} -impl Authorization for IngestRequestV2 { - fn attenuate(&self, auth_token: AuthorizationToken) -> Result { - Ok(auth_token) - } -} +impl StreamAuthorization for SynReplicationMessage {} -impl Authorization for OpenFetchStreamRequest { - fn attenuate(&self, auth_token: AuthorizationToken) -> Result { - Ok(auth_token) - } -} +impl Authorization for IngestRequestV2 {} +impl Authorization for OpenFetchStreamRequest {} -impl Authorization for DecommissionRequest { - fn attenuate(&self, auth_token: AuthorizationToken) -> Result { - Ok(auth_token) - } -} +impl Authorization for DecommissionRequest {} diff --git a/quickwit/quickwit-proto/src/cluster/mod.rs b/quickwit/quickwit-proto/src/cluster/mod.rs index 48ee9dc0554..7f0a25ecf7a 100644 --- a/quickwit/quickwit-proto/src/cluster/mod.rs +++ b/quickwit/quickwit-proto/src/cluster/mod.rs @@ -39,6 +39,8 @@ pub enum ClusterError { TooManyRequests, #[error("service unavailable: {0}")] Unavailable(String), + #[error("unauthorized: {0}")] + Unauthorized(#[from] quickwit_auth::AuthorizationError), } impl ServiceError for ClusterError { @@ -51,6 +53,7 @@ impl ServiceError for ClusterError { Self::Timeout(_) => ServiceErrorCode::Timeout, Self::TooManyRequests => ServiceErrorCode::TooManyRequests, Self::Unavailable(_) => ServiceErrorCode::Unavailable, + Self::Unauthorized(authorization_error) => (*authorization_error).into(), } } } diff --git a/quickwit/quickwit-proto/src/codegen/quickwit/quickwit.cluster.rs b/quickwit/quickwit-proto/src/codegen/quickwit/quickwit.cluster.rs index 2b54c972f75..07ec4928ec1 100644 --- a/quickwit/quickwit-proto/src/codegen/quickwit/quickwit.cluster.rs +++ b/quickwit/quickwit-proto/src/codegen/quickwit/quickwit.cluster.rs @@ -510,9 +510,10 @@ where &self, request: FetchClusterStateRequest, ) -> crate::cluster::ClusterResult { + let tonic_request = quickwit_auth::build_tonic_request_with_auth_token(request)?; self.inner .clone() - .fetch_cluster_state(request) + .fetch_cluster_state(tonic_request) .await .map(|response| response.into_inner()) .map_err(|status| crate::error::grpc_status_to_service_error( @@ -543,13 +544,12 @@ for ClusterServiceGrpcServerAdapter { request: tonic::Request, ) -> Result, tonic::Status> { let auth_token = quickwit_auth::get_auth_token(request.metadata())?; - let req = { - let req = request.into_inner(); - req - }; + let req = request.into_inner(); quickwit_auth::authorize(&req, &auth_token)?; - quickwit_auth::AUTHORIZATION_TOKEN - .scope(auth_token, self.inner.0.fetch_cluster_state(req)) + quickwit_auth::execute_with_authorization( + auth_token, + self.inner.0.fetch_cluster_state(req), + ) .await .map(tonic::Response::new) .map_err(crate::error::grpc_error_to_grpc_status) diff --git a/quickwit/quickwit-proto/src/codegen/quickwit/quickwit.control_plane.rs b/quickwit/quickwit-proto/src/codegen/quickwit/quickwit.control_plane.rs index 5de613c9a05..780edd4b9ae 100644 --- a/quickwit/quickwit-proto/src/codegen/quickwit/quickwit.control_plane.rs +++ b/quickwit/quickwit-proto/src/codegen/quickwit/quickwit.control_plane.rs @@ -1633,9 +1633,10 @@ where ) -> crate::control_plane::ControlPlaneResult< super::metastore::CreateIndexResponse, > { + let tonic_request = quickwit_auth::build_tonic_request_with_auth_token(request)?; self.inner .clone() - .create_index(request) + .create_index(tonic_request) .await .map(|response| response.into_inner()) .map_err(|status| crate::error::grpc_status_to_service_error( @@ -1649,9 +1650,10 @@ where ) -> crate::control_plane::ControlPlaneResult< super::metastore::IndexMetadataResponse, > { + let tonic_request = quickwit_auth::build_tonic_request_with_auth_token(request)?; self.inner .clone() - .update_index(request) + .update_index(tonic_request) .await .map(|response| response.into_inner()) .map_err(|status| crate::error::grpc_status_to_service_error( @@ -1663,9 +1665,10 @@ where &self, request: super::metastore::DeleteIndexRequest, ) -> crate::control_plane::ControlPlaneResult { + let tonic_request = quickwit_auth::build_tonic_request_with_auth_token(request)?; self.inner .clone() - .delete_index(request) + .delete_index(tonic_request) .await .map(|response| response.into_inner()) .map_err(|status| crate::error::grpc_status_to_service_error( @@ -1677,9 +1680,10 @@ where &self, request: super::metastore::AddSourceRequest, ) -> crate::control_plane::ControlPlaneResult { + let tonic_request = quickwit_auth::build_tonic_request_with_auth_token(request)?; self.inner .clone() - .add_source(request) + .add_source(tonic_request) .await .map(|response| response.into_inner()) .map_err(|status| crate::error::grpc_status_to_service_error( @@ -1691,9 +1695,10 @@ where &self, request: super::metastore::ToggleSourceRequest, ) -> crate::control_plane::ControlPlaneResult { + let tonic_request = quickwit_auth::build_tonic_request_with_auth_token(request)?; self.inner .clone() - .toggle_source(request) + .toggle_source(tonic_request) .await .map(|response| response.into_inner()) .map_err(|status| crate::error::grpc_status_to_service_error( @@ -1705,9 +1710,10 @@ where &self, request: super::metastore::DeleteSourceRequest, ) -> crate::control_plane::ControlPlaneResult { + let tonic_request = quickwit_auth::build_tonic_request_with_auth_token(request)?; self.inner .clone() - .delete_source(request) + .delete_source(tonic_request) .await .map(|response| response.into_inner()) .map_err(|status| crate::error::grpc_status_to_service_error( @@ -1719,9 +1725,10 @@ where &self, request: GetOrCreateOpenShardsRequest, ) -> crate::control_plane::ControlPlaneResult { + let tonic_request = quickwit_auth::build_tonic_request_with_auth_token(request)?; self.inner .clone() - .get_or_create_open_shards(request) + .get_or_create_open_shards(tonic_request) .await .map(|response| response.into_inner()) .map_err(|status| crate::error::grpc_status_to_service_error( @@ -1733,9 +1740,10 @@ where &self, request: AdviseResetShardsRequest, ) -> crate::control_plane::ControlPlaneResult { + let tonic_request = quickwit_auth::build_tonic_request_with_auth_token(request)?; self.inner .clone() - .advise_reset_shards(request) + .advise_reset_shards(tonic_request) .await .map(|response| response.into_inner()) .map_err(|status| crate::error::grpc_status_to_service_error( @@ -1747,9 +1755,10 @@ where &self, request: super::metastore::PruneShardsRequest, ) -> crate::control_plane::ControlPlaneResult { + let tonic_request = quickwit_auth::build_tonic_request_with_auth_token(request)?; self.inner .clone() - .prune_shards(request) + .prune_shards(tonic_request) .await .map(|response| response.into_inner()) .map_err(|status| crate::error::grpc_status_to_service_error( @@ -1780,13 +1789,12 @@ for ControlPlaneServiceGrpcServerAdapter { request: tonic::Request, ) -> Result, tonic::Status> { let auth_token = quickwit_auth::get_auth_token(request.metadata())?; - let req = { - let req = request.into_inner(); - req - }; + let req = request.into_inner(); quickwit_auth::authorize(&req, &auth_token)?; - quickwit_auth::AUTHORIZATION_TOKEN - .scope(auth_token, self.inner.0.create_index(req)) + quickwit_auth::execute_with_authorization( + auth_token, + self.inner.0.create_index(req), + ) .await .map(tonic::Response::new) .map_err(crate::error::grpc_error_to_grpc_status) @@ -1799,13 +1807,12 @@ for ControlPlaneServiceGrpcServerAdapter { tonic::Status, > { let auth_token = quickwit_auth::get_auth_token(request.metadata())?; - let req = { - let req = request.into_inner(); - req - }; + let req = request.into_inner(); quickwit_auth::authorize(&req, &auth_token)?; - quickwit_auth::AUTHORIZATION_TOKEN - .scope(auth_token, self.inner.0.update_index(req)) + quickwit_auth::execute_with_authorization( + auth_token, + self.inner.0.update_index(req), + ) .await .map(tonic::Response::new) .map_err(crate::error::grpc_error_to_grpc_status) @@ -1815,13 +1822,12 @@ for ControlPlaneServiceGrpcServerAdapter { request: tonic::Request, ) -> Result, tonic::Status> { let auth_token = quickwit_auth::get_auth_token(request.metadata())?; - let req = { - let req = request.into_inner(); - req - }; + let req = request.into_inner(); quickwit_auth::authorize(&req, &auth_token)?; - quickwit_auth::AUTHORIZATION_TOKEN - .scope(auth_token, self.inner.0.delete_index(req)) + quickwit_auth::execute_with_authorization( + auth_token, + self.inner.0.delete_index(req), + ) .await .map(tonic::Response::new) .map_err(crate::error::grpc_error_to_grpc_status) @@ -1831,13 +1837,12 @@ for ControlPlaneServiceGrpcServerAdapter { request: tonic::Request, ) -> Result, tonic::Status> { let auth_token = quickwit_auth::get_auth_token(request.metadata())?; - let req = { - let req = request.into_inner(); - req - }; + let req = request.into_inner(); quickwit_auth::authorize(&req, &auth_token)?; - quickwit_auth::AUTHORIZATION_TOKEN - .scope(auth_token, self.inner.0.add_source(req)) + quickwit_auth::execute_with_authorization( + auth_token, + self.inner.0.add_source(req), + ) .await .map(tonic::Response::new) .map_err(crate::error::grpc_error_to_grpc_status) @@ -1847,13 +1852,12 @@ for ControlPlaneServiceGrpcServerAdapter { request: tonic::Request, ) -> Result, tonic::Status> { let auth_token = quickwit_auth::get_auth_token(request.metadata())?; - let req = { - let req = request.into_inner(); - req - }; + let req = request.into_inner(); quickwit_auth::authorize(&req, &auth_token)?; - quickwit_auth::AUTHORIZATION_TOKEN - .scope(auth_token, self.inner.0.toggle_source(req)) + quickwit_auth::execute_with_authorization( + auth_token, + self.inner.0.toggle_source(req), + ) .await .map(tonic::Response::new) .map_err(crate::error::grpc_error_to_grpc_status) @@ -1863,13 +1867,12 @@ for ControlPlaneServiceGrpcServerAdapter { request: tonic::Request, ) -> Result, tonic::Status> { let auth_token = quickwit_auth::get_auth_token(request.metadata())?; - let req = { - let req = request.into_inner(); - req - }; + let req = request.into_inner(); quickwit_auth::authorize(&req, &auth_token)?; - quickwit_auth::AUTHORIZATION_TOKEN - .scope(auth_token, self.inner.0.delete_source(req)) + quickwit_auth::execute_with_authorization( + auth_token, + self.inner.0.delete_source(req), + ) .await .map(tonic::Response::new) .map_err(crate::error::grpc_error_to_grpc_status) @@ -1879,13 +1882,12 @@ for ControlPlaneServiceGrpcServerAdapter { request: tonic::Request, ) -> Result, tonic::Status> { let auth_token = quickwit_auth::get_auth_token(request.metadata())?; - let req = { - let req = request.into_inner(); - req - }; + let req = request.into_inner(); quickwit_auth::authorize(&req, &auth_token)?; - quickwit_auth::AUTHORIZATION_TOKEN - .scope(auth_token, self.inner.0.get_or_create_open_shards(req)) + quickwit_auth::execute_with_authorization( + auth_token, + self.inner.0.get_or_create_open_shards(req), + ) .await .map(tonic::Response::new) .map_err(crate::error::grpc_error_to_grpc_status) @@ -1895,13 +1897,12 @@ for ControlPlaneServiceGrpcServerAdapter { request: tonic::Request, ) -> Result, tonic::Status> { let auth_token = quickwit_auth::get_auth_token(request.metadata())?; - let req = { - let req = request.into_inner(); - req - }; + let req = request.into_inner(); quickwit_auth::authorize(&req, &auth_token)?; - quickwit_auth::AUTHORIZATION_TOKEN - .scope(auth_token, self.inner.0.advise_reset_shards(req)) + quickwit_auth::execute_with_authorization( + auth_token, + self.inner.0.advise_reset_shards(req), + ) .await .map(tonic::Response::new) .map_err(crate::error::grpc_error_to_grpc_status) @@ -1911,13 +1912,12 @@ for ControlPlaneServiceGrpcServerAdapter { request: tonic::Request, ) -> Result, tonic::Status> { let auth_token = quickwit_auth::get_auth_token(request.metadata())?; - let req = { - let req = request.into_inner(); - req - }; + let req = request.into_inner(); quickwit_auth::authorize(&req, &auth_token)?; - quickwit_auth::AUTHORIZATION_TOKEN - .scope(auth_token, self.inner.0.prune_shards(req)) + quickwit_auth::execute_with_authorization( + auth_token, + self.inner.0.prune_shards(req), + ) .await .map(tonic::Response::new) .map_err(crate::error::grpc_error_to_grpc_status) diff --git a/quickwit/quickwit-proto/src/codegen/quickwit/quickwit.developer.rs b/quickwit/quickwit-proto/src/codegen/quickwit/quickwit.developer.rs index cbe28bd2eb2..ec25565eef2 100644 --- a/quickwit/quickwit-proto/src/codegen/quickwit/quickwit.developer.rs +++ b/quickwit/quickwit-proto/src/codegen/quickwit/quickwit.developer.rs @@ -446,9 +446,10 @@ where &self, request: GetDebugInfoRequest, ) -> crate::developer::DeveloperResult { + let tonic_request = quickwit_auth::build_tonic_request_with_auth_token(request)?; self.inner .clone() - .get_debug_info(request) + .get_debug_info(tonic_request) .await .map(|response| response.into_inner()) .map_err(|status| crate::error::grpc_status_to_service_error( @@ -479,13 +480,12 @@ for DeveloperServiceGrpcServerAdapter { request: tonic::Request, ) -> Result, tonic::Status> { let auth_token = quickwit_auth::get_auth_token(request.metadata())?; - let req = { - let req = request.into_inner(); - req - }; + let req = request.into_inner(); quickwit_auth::authorize(&req, &auth_token)?; - quickwit_auth::AUTHORIZATION_TOKEN - .scope(auth_token, self.inner.0.get_debug_info(req)) + quickwit_auth::execute_with_authorization( + auth_token, + self.inner.0.get_debug_info(req), + ) .await .map(tonic::Response::new) .map_err(crate::error::grpc_error_to_grpc_status) diff --git a/quickwit/quickwit-proto/src/codegen/quickwit/quickwit.indexing.rs b/quickwit/quickwit-proto/src/codegen/quickwit/quickwit.indexing.rs index 42514ba5003..a6b7a2a0aee 100644 --- a/quickwit/quickwit-proto/src/codegen/quickwit/quickwit.indexing.rs +++ b/quickwit/quickwit-proto/src/codegen/quickwit/quickwit.indexing.rs @@ -459,9 +459,10 @@ where &self, request: ApplyIndexingPlanRequest, ) -> crate::indexing::IndexingResult { + let tonic_request = quickwit_auth::build_tonic_request_with_auth_token(request)?; self.inner .clone() - .apply_indexing_plan(request) + .apply_indexing_plan(tonic_request) .await .map(|response| response.into_inner()) .map_err(|status| crate::error::grpc_status_to_service_error( @@ -492,13 +493,12 @@ for IndexingServiceGrpcServerAdapter { request: tonic::Request, ) -> Result, tonic::Status> { let auth_token = quickwit_auth::get_auth_token(request.metadata())?; - let req = { - let req = request.into_inner(); - req - }; + let req = request.into_inner(); quickwit_auth::authorize(&req, &auth_token)?; - quickwit_auth::AUTHORIZATION_TOKEN - .scope(auth_token, self.inner.0.apply_indexing_plan(req)) + quickwit_auth::execute_with_authorization( + auth_token, + self.inner.0.apply_indexing_plan(req), + ) .await .map(tonic::Response::new) .map_err(crate::error::grpc_error_to_grpc_status) diff --git a/quickwit/quickwit-proto/src/codegen/quickwit/quickwit.ingest.ingester.rs b/quickwit/quickwit-proto/src/codegen/quickwit/quickwit.ingest.ingester.rs index e18cc626151..c5a230b7d09 100644 --- a/quickwit/quickwit-proto/src/codegen/quickwit/quickwit.ingest.ingester.rs +++ b/quickwit/quickwit-proto/src/codegen/quickwit/quickwit.ingest.ingester.rs @@ -441,6 +441,7 @@ pub enum PersistFailureReason { ShardRateLimited = 3, WalFull = 4, Timeout = 5, + Unauthorized = 6, } impl PersistFailureReason { /// String value of the enum field names used in the ProtoBuf definition. @@ -459,6 +460,7 @@ impl PersistFailureReason { } PersistFailureReason::WalFull => "PERSIST_FAILURE_REASON_WAL_FULL", PersistFailureReason::Timeout => "PERSIST_FAILURE_REASON_TIMEOUT", + PersistFailureReason::Unauthorized => "PERSIST_FAILURE_REASON_UNAUTHORIZED", } } /// Creates an enum from field names used in the ProtoBuf definition. @@ -470,6 +472,7 @@ impl PersistFailureReason { "PERSIST_FAILURE_REASON_SHARD_RATE_LIMITED" => Some(Self::ShardRateLimited), "PERSIST_FAILURE_REASON_WAL_FULL" => Some(Self::WalFull), "PERSIST_FAILURE_REASON_TIMEOUT" => Some(Self::Timeout), + "PERSIST_FAILURE_REASON_UNAUTHORIZED" => Some(Self::Unauthorized), _ => None, } } @@ -2041,9 +2044,10 @@ where &self, request: PersistRequest, ) -> crate::ingest::IngestV2Result { + let tonic_request = quickwit_auth::build_tonic_request_with_auth_token(request)?; self.inner .clone() - .persist(request) + .persist(tonic_request) .await .map(|response| response.into_inner()) .map_err(|status| crate::error::grpc_status_to_service_error( @@ -2055,9 +2059,12 @@ where &self, request: quickwit_common::ServiceStream, ) -> crate::ingest::IngestV2Result> { + let tonic_request = quickwit_auth::build_tonic_stream_request_with_auth_token( + request, + )?; self.inner .clone() - .open_replication_stream(request) + .open_replication_stream(tonic_request) .await .map(|response| { let streaming: tonic::Streaming<_> = response.into_inner(); @@ -2077,9 +2084,10 @@ where &self, request: OpenFetchStreamRequest, ) -> crate::ingest::IngestV2Result> { + let tonic_request = quickwit_auth::build_tonic_request_with_auth_token(request)?; self.inner .clone() - .open_fetch_stream(request) + .open_fetch_stream(tonic_request) .await .map(|response| { let streaming: tonic::Streaming<_> = response.into_inner(); @@ -2099,9 +2107,10 @@ where &self, request: OpenObservationStreamRequest, ) -> crate::ingest::IngestV2Result> { + let tonic_request = quickwit_auth::build_tonic_request_with_auth_token(request)?; self.inner .clone() - .open_observation_stream(request) + .open_observation_stream(tonic_request) .await .map(|response| { let streaming: tonic::Streaming<_> = response.into_inner(); @@ -2121,9 +2130,10 @@ where &self, request: InitShardsRequest, ) -> crate::ingest::IngestV2Result { + let tonic_request = quickwit_auth::build_tonic_request_with_auth_token(request)?; self.inner .clone() - .init_shards(request) + .init_shards(tonic_request) .await .map(|response| response.into_inner()) .map_err(|status| crate::error::grpc_status_to_service_error( @@ -2135,9 +2145,10 @@ where &self, request: RetainShardsRequest, ) -> crate::ingest::IngestV2Result { + let tonic_request = quickwit_auth::build_tonic_request_with_auth_token(request)?; self.inner .clone() - .retain_shards(request) + .retain_shards(tonic_request) .await .map(|response| response.into_inner()) .map_err(|status| crate::error::grpc_status_to_service_error( @@ -2149,9 +2160,10 @@ where &self, request: TruncateShardsRequest, ) -> crate::ingest::IngestV2Result { + let tonic_request = quickwit_auth::build_tonic_request_with_auth_token(request)?; self.inner .clone() - .truncate_shards(request) + .truncate_shards(tonic_request) .await .map(|response| response.into_inner()) .map_err(|status| crate::error::grpc_status_to_service_error( @@ -2163,9 +2175,10 @@ where &self, request: CloseShardsRequest, ) -> crate::ingest::IngestV2Result { + let tonic_request = quickwit_auth::build_tonic_request_with_auth_token(request)?; self.inner .clone() - .close_shards(request) + .close_shards(tonic_request) .await .map(|response| response.into_inner()) .map_err(|status| crate::error::grpc_status_to_service_error( @@ -2177,9 +2190,10 @@ where &self, request: DecommissionRequest, ) -> crate::ingest::IngestV2Result { + let tonic_request = quickwit_auth::build_tonic_request_with_auth_token(request)?; self.inner .clone() - .decommission(request) + .decommission(tonic_request) .await .map(|response| response.into_inner()) .map_err(|status| crate::error::grpc_status_to_service_error( @@ -2210,13 +2224,9 @@ for IngesterServiceGrpcServerAdapter { request: tonic::Request, ) -> Result, tonic::Status> { let auth_token = quickwit_auth::get_auth_token(request.metadata())?; - let req = { - let req = request.into_inner(); - req - }; + let req = request.into_inner(); quickwit_auth::authorize(&req, &auth_token)?; - quickwit_auth::AUTHORIZATION_TOKEN - .scope(auth_token, self.inner.0.persist(req)) + quickwit_auth::execute_with_authorization(auth_token, self.inner.0.persist(req)) .await .map(tonic::Response::new) .map_err(crate::error::grpc_error_to_grpc_status) @@ -2234,8 +2244,10 @@ for IngesterServiceGrpcServerAdapter { quickwit_common::ServiceStream::from(streaming) }; quickwit_auth::authorize_stream::(&auth_token)?; - quickwit_auth::AUTHORIZATION_TOKEN - .scope(auth_token, self.inner.0.open_replication_stream(req)) + quickwit_auth::execute_with_authorization( + auth_token, + self.inner.0.open_replication_stream(req), + ) .await .map(|stream| tonic::Response::new( stream.map_err(crate::error::grpc_error_to_grpc_status), @@ -2250,13 +2262,12 @@ for IngesterServiceGrpcServerAdapter { request: tonic::Request, ) -> Result, tonic::Status> { let auth_token = quickwit_auth::get_auth_token(request.metadata())?; - let req = { - let req = request.into_inner(); - req - }; + let req = request.into_inner(); quickwit_auth::authorize(&req, &auth_token)?; - quickwit_auth::AUTHORIZATION_TOKEN - .scope(auth_token, self.inner.0.open_fetch_stream(req)) + quickwit_auth::execute_with_authorization( + auth_token, + self.inner.0.open_fetch_stream(req), + ) .await .map(|stream| tonic::Response::new( stream.map_err(crate::error::grpc_error_to_grpc_status), @@ -2271,13 +2282,12 @@ for IngesterServiceGrpcServerAdapter { request: tonic::Request, ) -> Result, tonic::Status> { let auth_token = quickwit_auth::get_auth_token(request.metadata())?; - let req = { - let req = request.into_inner(); - req - }; + let req = request.into_inner(); quickwit_auth::authorize(&req, &auth_token)?; - quickwit_auth::AUTHORIZATION_TOKEN - .scope(auth_token, self.inner.0.open_observation_stream(req)) + quickwit_auth::execute_with_authorization( + auth_token, + self.inner.0.open_observation_stream(req), + ) .await .map(|stream| tonic::Response::new( stream.map_err(crate::error::grpc_error_to_grpc_status), @@ -2289,13 +2299,12 @@ for IngesterServiceGrpcServerAdapter { request: tonic::Request, ) -> Result, tonic::Status> { let auth_token = quickwit_auth::get_auth_token(request.metadata())?; - let req = { - let req = request.into_inner(); - req - }; + let req = request.into_inner(); quickwit_auth::authorize(&req, &auth_token)?; - quickwit_auth::AUTHORIZATION_TOKEN - .scope(auth_token, self.inner.0.init_shards(req)) + quickwit_auth::execute_with_authorization( + auth_token, + self.inner.0.init_shards(req), + ) .await .map(tonic::Response::new) .map_err(crate::error::grpc_error_to_grpc_status) @@ -2305,13 +2314,12 @@ for IngesterServiceGrpcServerAdapter { request: tonic::Request, ) -> Result, tonic::Status> { let auth_token = quickwit_auth::get_auth_token(request.metadata())?; - let req = { - let req = request.into_inner(); - req - }; + let req = request.into_inner(); quickwit_auth::authorize(&req, &auth_token)?; - quickwit_auth::AUTHORIZATION_TOKEN - .scope(auth_token, self.inner.0.retain_shards(req)) + quickwit_auth::execute_with_authorization( + auth_token, + self.inner.0.retain_shards(req), + ) .await .map(tonic::Response::new) .map_err(crate::error::grpc_error_to_grpc_status) @@ -2321,13 +2329,12 @@ for IngesterServiceGrpcServerAdapter { request: tonic::Request, ) -> Result, tonic::Status> { let auth_token = quickwit_auth::get_auth_token(request.metadata())?; - let req = { - let req = request.into_inner(); - req - }; + let req = request.into_inner(); quickwit_auth::authorize(&req, &auth_token)?; - quickwit_auth::AUTHORIZATION_TOKEN - .scope(auth_token, self.inner.0.truncate_shards(req)) + quickwit_auth::execute_with_authorization( + auth_token, + self.inner.0.truncate_shards(req), + ) .await .map(tonic::Response::new) .map_err(crate::error::grpc_error_to_grpc_status) @@ -2337,13 +2344,12 @@ for IngesterServiceGrpcServerAdapter { request: tonic::Request, ) -> Result, tonic::Status> { let auth_token = quickwit_auth::get_auth_token(request.metadata())?; - let req = { - let req = request.into_inner(); - req - }; + let req = request.into_inner(); quickwit_auth::authorize(&req, &auth_token)?; - quickwit_auth::AUTHORIZATION_TOKEN - .scope(auth_token, self.inner.0.close_shards(req)) + quickwit_auth::execute_with_authorization( + auth_token, + self.inner.0.close_shards(req), + ) .await .map(tonic::Response::new) .map_err(crate::error::grpc_error_to_grpc_status) @@ -2353,13 +2359,12 @@ for IngesterServiceGrpcServerAdapter { request: tonic::Request, ) -> Result, tonic::Status> { let auth_token = quickwit_auth::get_auth_token(request.metadata())?; - let req = { - let req = request.into_inner(); - req - }; + let req = request.into_inner(); quickwit_auth::authorize(&req, &auth_token)?; - quickwit_auth::AUTHORIZATION_TOKEN - .scope(auth_token, self.inner.0.decommission(req)) + quickwit_auth::execute_with_authorization( + auth_token, + self.inner.0.decommission(req), + ) .await .map(tonic::Response::new) .map_err(crate::error::grpc_error_to_grpc_status) diff --git a/quickwit/quickwit-proto/src/codegen/quickwit/quickwit.ingest.router.rs b/quickwit/quickwit-proto/src/codegen/quickwit/quickwit.ingest.router.rs index 16a078d360a..405e9abe6f3 100644 --- a/quickwit/quickwit-proto/src/codegen/quickwit/quickwit.ingest.router.rs +++ b/quickwit/quickwit-proto/src/codegen/quickwit/quickwit.ingest.router.rs @@ -81,6 +81,7 @@ pub enum IngestFailureReason { RouterLoadShedding = 8, LoadShedding = 9, CircuitBreaker = 10, + Unauthorized = 11, } impl IngestFailureReason { /// String value of the enum field names used in the ProtoBuf definition. @@ -110,6 +111,7 @@ impl IngestFailureReason { IngestFailureReason::CircuitBreaker => { "INGEST_FAILURE_REASON_CIRCUIT_BREAKER" } + IngestFailureReason::Unauthorized => "INGEST_FAILURE_REASON_UNAUTHORIZED", } } /// Creates an enum from field names used in the ProtoBuf definition. @@ -128,6 +130,7 @@ impl IngestFailureReason { } "INGEST_FAILURE_REASON_LOAD_SHEDDING" => Some(Self::LoadShedding), "INGEST_FAILURE_REASON_CIRCUIT_BREAKER" => Some(Self::CircuitBreaker), + "INGEST_FAILURE_REASON_UNAUTHORIZED" => Some(Self::Unauthorized), _ => None, } } @@ -569,9 +572,10 @@ where &self, request: IngestRequestV2, ) -> crate::ingest::IngestV2Result { + let tonic_request = quickwit_auth::build_tonic_request_with_auth_token(request)?; self.inner .clone() - .ingest(request) + .ingest(tonic_request) .await .map(|response| response.into_inner()) .map_err(|status| crate::error::grpc_status_to_service_error( @@ -602,13 +606,9 @@ for IngestRouterServiceGrpcServerAdapter { request: tonic::Request, ) -> Result, tonic::Status> { let auth_token = quickwit_auth::get_auth_token(request.metadata())?; - let req = { - let req = request.into_inner(); - req - }; + let req = request.into_inner(); quickwit_auth::authorize(&req, &auth_token)?; - quickwit_auth::AUTHORIZATION_TOKEN - .scope(auth_token, self.inner.0.ingest(req)) + quickwit_auth::execute_with_authorization(auth_token, self.inner.0.ingest(req)) .await .map(tonic::Response::new) .map_err(crate::error::grpc_error_to_grpc_status) diff --git a/quickwit/quickwit-proto/src/codegen/quickwit/quickwit.metastore.rs b/quickwit/quickwit-proto/src/codegen/quickwit/quickwit.metastore.rs index 1ca889eaf00..b923d5261f7 100644 --- a/quickwit/quickwit-proto/src/codegen/quickwit/quickwit.metastore.rs +++ b/quickwit/quickwit-proto/src/codegen/quickwit/quickwit.metastore.rs @@ -4866,9 +4866,10 @@ where &self, request: CreateIndexRequest, ) -> crate::metastore::MetastoreResult { + let tonic_request = quickwit_auth::build_tonic_request_with_auth_token(request)?; self.inner .clone() - .create_index(request) + .create_index(tonic_request) .await .map(|response| response.into_inner()) .map_err(|status| crate::error::grpc_status_to_service_error( @@ -4880,9 +4881,10 @@ where &self, request: UpdateIndexRequest, ) -> crate::metastore::MetastoreResult { + let tonic_request = quickwit_auth::build_tonic_request_with_auth_token(request)?; self.inner .clone() - .update_index(request) + .update_index(tonic_request) .await .map(|response| response.into_inner()) .map_err(|status| crate::error::grpc_status_to_service_error( @@ -4894,9 +4896,10 @@ where &self, request: IndexMetadataRequest, ) -> crate::metastore::MetastoreResult { + let tonic_request = quickwit_auth::build_tonic_request_with_auth_token(request)?; self.inner .clone() - .index_metadata(request) + .index_metadata(tonic_request) .await .map(|response| response.into_inner()) .map_err(|status| crate::error::grpc_status_to_service_error( @@ -4908,9 +4911,10 @@ where &self, request: IndexesMetadataRequest, ) -> crate::metastore::MetastoreResult { + let tonic_request = quickwit_auth::build_tonic_request_with_auth_token(request)?; self.inner .clone() - .indexes_metadata(request) + .indexes_metadata(tonic_request) .await .map(|response| response.into_inner()) .map_err(|status| crate::error::grpc_status_to_service_error( @@ -4922,9 +4926,10 @@ where &self, request: ListIndexesMetadataRequest, ) -> crate::metastore::MetastoreResult { + let tonic_request = quickwit_auth::build_tonic_request_with_auth_token(request)?; self.inner .clone() - .list_indexes_metadata(request) + .list_indexes_metadata(tonic_request) .await .map(|response| response.into_inner()) .map_err(|status| crate::error::grpc_status_to_service_error( @@ -4936,9 +4941,10 @@ where &self, request: DeleteIndexRequest, ) -> crate::metastore::MetastoreResult { + let tonic_request = quickwit_auth::build_tonic_request_with_auth_token(request)?; self.inner .clone() - .delete_index(request) + .delete_index(tonic_request) .await .map(|response| response.into_inner()) .map_err(|status| crate::error::grpc_status_to_service_error( @@ -4950,9 +4956,10 @@ where &self, request: ListSplitsRequest, ) -> crate::metastore::MetastoreResult> { + let tonic_request = quickwit_auth::build_tonic_request_with_auth_token(request)?; self.inner .clone() - .list_splits(request) + .list_splits(tonic_request) .await .map(|response| { let streaming: tonic::Streaming<_> = response.into_inner(); @@ -4972,9 +4979,10 @@ where &self, request: StageSplitsRequest, ) -> crate::metastore::MetastoreResult { + let tonic_request = quickwit_auth::build_tonic_request_with_auth_token(request)?; self.inner .clone() - .stage_splits(request) + .stage_splits(tonic_request) .await .map(|response| response.into_inner()) .map_err(|status| crate::error::grpc_status_to_service_error( @@ -4986,9 +4994,10 @@ where &self, request: PublishSplitsRequest, ) -> crate::metastore::MetastoreResult { + let tonic_request = quickwit_auth::build_tonic_request_with_auth_token(request)?; self.inner .clone() - .publish_splits(request) + .publish_splits(tonic_request) .await .map(|response| response.into_inner()) .map_err(|status| crate::error::grpc_status_to_service_error( @@ -5000,9 +5009,10 @@ where &self, request: MarkSplitsForDeletionRequest, ) -> crate::metastore::MetastoreResult { + let tonic_request = quickwit_auth::build_tonic_request_with_auth_token(request)?; self.inner .clone() - .mark_splits_for_deletion(request) + .mark_splits_for_deletion(tonic_request) .await .map(|response| response.into_inner()) .map_err(|status| crate::error::grpc_status_to_service_error( @@ -5014,9 +5024,10 @@ where &self, request: DeleteSplitsRequest, ) -> crate::metastore::MetastoreResult { + let tonic_request = quickwit_auth::build_tonic_request_with_auth_token(request)?; self.inner .clone() - .delete_splits(request) + .delete_splits(tonic_request) .await .map(|response| response.into_inner()) .map_err(|status| crate::error::grpc_status_to_service_error( @@ -5028,9 +5039,10 @@ where &self, request: AddSourceRequest, ) -> crate::metastore::MetastoreResult { + let tonic_request = quickwit_auth::build_tonic_request_with_auth_token(request)?; self.inner .clone() - .add_source(request) + .add_source(tonic_request) .await .map(|response| response.into_inner()) .map_err(|status| crate::error::grpc_status_to_service_error( @@ -5042,9 +5054,10 @@ where &self, request: ToggleSourceRequest, ) -> crate::metastore::MetastoreResult { + let tonic_request = quickwit_auth::build_tonic_request_with_auth_token(request)?; self.inner .clone() - .toggle_source(request) + .toggle_source(tonic_request) .await .map(|response| response.into_inner()) .map_err(|status| crate::error::grpc_status_to_service_error( @@ -5056,9 +5069,10 @@ where &self, request: DeleteSourceRequest, ) -> crate::metastore::MetastoreResult { + let tonic_request = quickwit_auth::build_tonic_request_with_auth_token(request)?; self.inner .clone() - .delete_source(request) + .delete_source(tonic_request) .await .map(|response| response.into_inner()) .map_err(|status| crate::error::grpc_status_to_service_error( @@ -5070,9 +5084,10 @@ where &self, request: ResetSourceCheckpointRequest, ) -> crate::metastore::MetastoreResult { + let tonic_request = quickwit_auth::build_tonic_request_with_auth_token(request)?; self.inner .clone() - .reset_source_checkpoint(request) + .reset_source_checkpoint(tonic_request) .await .map(|response| response.into_inner()) .map_err(|status| crate::error::grpc_status_to_service_error( @@ -5084,9 +5099,10 @@ where &self, request: LastDeleteOpstampRequest, ) -> crate::metastore::MetastoreResult { + let tonic_request = quickwit_auth::build_tonic_request_with_auth_token(request)?; self.inner .clone() - .last_delete_opstamp(request) + .last_delete_opstamp(tonic_request) .await .map(|response| response.into_inner()) .map_err(|status| crate::error::grpc_status_to_service_error( @@ -5098,9 +5114,10 @@ where &self, request: DeleteQuery, ) -> crate::metastore::MetastoreResult { + let tonic_request = quickwit_auth::build_tonic_request_with_auth_token(request)?; self.inner .clone() - .create_delete_task(request) + .create_delete_task(tonic_request) .await .map(|response| response.into_inner()) .map_err(|status| crate::error::grpc_status_to_service_error( @@ -5112,9 +5129,10 @@ where &self, request: UpdateSplitsDeleteOpstampRequest, ) -> crate::metastore::MetastoreResult { + let tonic_request = quickwit_auth::build_tonic_request_with_auth_token(request)?; self.inner .clone() - .update_splits_delete_opstamp(request) + .update_splits_delete_opstamp(tonic_request) .await .map(|response| response.into_inner()) .map_err(|status| crate::error::grpc_status_to_service_error( @@ -5126,9 +5144,10 @@ where &self, request: ListDeleteTasksRequest, ) -> crate::metastore::MetastoreResult { + let tonic_request = quickwit_auth::build_tonic_request_with_auth_token(request)?; self.inner .clone() - .list_delete_tasks(request) + .list_delete_tasks(tonic_request) .await .map(|response| response.into_inner()) .map_err(|status| crate::error::grpc_status_to_service_error( @@ -5140,9 +5159,10 @@ where &self, request: ListStaleSplitsRequest, ) -> crate::metastore::MetastoreResult { + let tonic_request = quickwit_auth::build_tonic_request_with_auth_token(request)?; self.inner .clone() - .list_stale_splits(request) + .list_stale_splits(tonic_request) .await .map(|response| response.into_inner()) .map_err(|status| crate::error::grpc_status_to_service_error( @@ -5154,9 +5174,10 @@ where &self, request: OpenShardsRequest, ) -> crate::metastore::MetastoreResult { + let tonic_request = quickwit_auth::build_tonic_request_with_auth_token(request)?; self.inner .clone() - .open_shards(request) + .open_shards(tonic_request) .await .map(|response| response.into_inner()) .map_err(|status| crate::error::grpc_status_to_service_error( @@ -5168,9 +5189,10 @@ where &self, request: AcquireShardsRequest, ) -> crate::metastore::MetastoreResult { + let tonic_request = quickwit_auth::build_tonic_request_with_auth_token(request)?; self.inner .clone() - .acquire_shards(request) + .acquire_shards(tonic_request) .await .map(|response| response.into_inner()) .map_err(|status| crate::error::grpc_status_to_service_error( @@ -5182,9 +5204,10 @@ where &self, request: DeleteShardsRequest, ) -> crate::metastore::MetastoreResult { + let tonic_request = quickwit_auth::build_tonic_request_with_auth_token(request)?; self.inner .clone() - .delete_shards(request) + .delete_shards(tonic_request) .await .map(|response| response.into_inner()) .map_err(|status| crate::error::grpc_status_to_service_error( @@ -5196,9 +5219,10 @@ where &self, request: PruneShardsRequest, ) -> crate::metastore::MetastoreResult { + let tonic_request = quickwit_auth::build_tonic_request_with_auth_token(request)?; self.inner .clone() - .prune_shards(request) + .prune_shards(tonic_request) .await .map(|response| response.into_inner()) .map_err(|status| crate::error::grpc_status_to_service_error( @@ -5210,9 +5234,10 @@ where &self, request: ListShardsRequest, ) -> crate::metastore::MetastoreResult { + let tonic_request = quickwit_auth::build_tonic_request_with_auth_token(request)?; self.inner .clone() - .list_shards(request) + .list_shards(tonic_request) .await .map(|response| response.into_inner()) .map_err(|status| crate::error::grpc_status_to_service_error( @@ -5224,9 +5249,10 @@ where &self, request: CreateIndexTemplateRequest, ) -> crate::metastore::MetastoreResult { + let tonic_request = quickwit_auth::build_tonic_request_with_auth_token(request)?; self.inner .clone() - .create_index_template(request) + .create_index_template(tonic_request) .await .map(|response| response.into_inner()) .map_err(|status| crate::error::grpc_status_to_service_error( @@ -5238,9 +5264,10 @@ where &self, request: GetIndexTemplateRequest, ) -> crate::metastore::MetastoreResult { + let tonic_request = quickwit_auth::build_tonic_request_with_auth_token(request)?; self.inner .clone() - .get_index_template(request) + .get_index_template(tonic_request) .await .map(|response| response.into_inner()) .map_err(|status| crate::error::grpc_status_to_service_error( @@ -5252,9 +5279,10 @@ where &self, request: FindIndexTemplateMatchesRequest, ) -> crate::metastore::MetastoreResult { + let tonic_request = quickwit_auth::build_tonic_request_with_auth_token(request)?; self.inner .clone() - .find_index_template_matches(request) + .find_index_template_matches(tonic_request) .await .map(|response| response.into_inner()) .map_err(|status| crate::error::grpc_status_to_service_error( @@ -5266,9 +5294,10 @@ where &self, request: ListIndexTemplatesRequest, ) -> crate::metastore::MetastoreResult { + let tonic_request = quickwit_auth::build_tonic_request_with_auth_token(request)?; self.inner .clone() - .list_index_templates(request) + .list_index_templates(tonic_request) .await .map(|response| response.into_inner()) .map_err(|status| crate::error::grpc_status_to_service_error( @@ -5280,9 +5309,10 @@ where &self, request: DeleteIndexTemplatesRequest, ) -> crate::metastore::MetastoreResult { + let tonic_request = quickwit_auth::build_tonic_request_with_auth_token(request)?; self.inner .clone() - .delete_index_templates(request) + .delete_index_templates(tonic_request) .await .map(|response| response.into_inner()) .map_err(|status| crate::error::grpc_status_to_service_error( @@ -5328,13 +5358,12 @@ for MetastoreServiceGrpcServerAdapter { request: tonic::Request, ) -> Result, tonic::Status> { let auth_token = quickwit_auth::get_auth_token(request.metadata())?; - let req = { - let req = request.into_inner(); - req - }; + let req = request.into_inner(); quickwit_auth::authorize(&req, &auth_token)?; - quickwit_auth::AUTHORIZATION_TOKEN - .scope(auth_token, self.inner.0.create_index(req)) + quickwit_auth::execute_with_authorization( + auth_token, + self.inner.0.create_index(req), + ) .await .map(tonic::Response::new) .map_err(crate::error::grpc_error_to_grpc_status) @@ -5344,13 +5373,12 @@ for MetastoreServiceGrpcServerAdapter { request: tonic::Request, ) -> Result, tonic::Status> { let auth_token = quickwit_auth::get_auth_token(request.metadata())?; - let req = { - let req = request.into_inner(); - req - }; + let req = request.into_inner(); quickwit_auth::authorize(&req, &auth_token)?; - quickwit_auth::AUTHORIZATION_TOKEN - .scope(auth_token, self.inner.0.update_index(req)) + quickwit_auth::execute_with_authorization( + auth_token, + self.inner.0.update_index(req), + ) .await .map(tonic::Response::new) .map_err(crate::error::grpc_error_to_grpc_status) @@ -5360,13 +5388,12 @@ for MetastoreServiceGrpcServerAdapter { request: tonic::Request, ) -> Result, tonic::Status> { let auth_token = quickwit_auth::get_auth_token(request.metadata())?; - let req = { - let req = request.into_inner(); - req - }; + let req = request.into_inner(); quickwit_auth::authorize(&req, &auth_token)?; - quickwit_auth::AUTHORIZATION_TOKEN - .scope(auth_token, self.inner.0.index_metadata(req)) + quickwit_auth::execute_with_authorization( + auth_token, + self.inner.0.index_metadata(req), + ) .await .map(tonic::Response::new) .map_err(crate::error::grpc_error_to_grpc_status) @@ -5376,13 +5403,12 @@ for MetastoreServiceGrpcServerAdapter { request: tonic::Request, ) -> Result, tonic::Status> { let auth_token = quickwit_auth::get_auth_token(request.metadata())?; - let req = { - let req = request.into_inner(); - req - }; + let req = request.into_inner(); quickwit_auth::authorize(&req, &auth_token)?; - quickwit_auth::AUTHORIZATION_TOKEN - .scope(auth_token, self.inner.0.indexes_metadata(req)) + quickwit_auth::execute_with_authorization( + auth_token, + self.inner.0.indexes_metadata(req), + ) .await .map(tonic::Response::new) .map_err(crate::error::grpc_error_to_grpc_status) @@ -5392,13 +5418,12 @@ for MetastoreServiceGrpcServerAdapter { request: tonic::Request, ) -> Result, tonic::Status> { let auth_token = quickwit_auth::get_auth_token(request.metadata())?; - let req = { - let req = request.into_inner(); - req - }; + let req = request.into_inner(); quickwit_auth::authorize(&req, &auth_token)?; - quickwit_auth::AUTHORIZATION_TOKEN - .scope(auth_token, self.inner.0.list_indexes_metadata(req)) + quickwit_auth::execute_with_authorization( + auth_token, + self.inner.0.list_indexes_metadata(req), + ) .await .map(tonic::Response::new) .map_err(crate::error::grpc_error_to_grpc_status) @@ -5408,13 +5433,12 @@ for MetastoreServiceGrpcServerAdapter { request: tonic::Request, ) -> Result, tonic::Status> { let auth_token = quickwit_auth::get_auth_token(request.metadata())?; - let req = { - let req = request.into_inner(); - req - }; + let req = request.into_inner(); quickwit_auth::authorize(&req, &auth_token)?; - quickwit_auth::AUTHORIZATION_TOKEN - .scope(auth_token, self.inner.0.delete_index(req)) + quickwit_auth::execute_with_authorization( + auth_token, + self.inner.0.delete_index(req), + ) .await .map(tonic::Response::new) .map_err(crate::error::grpc_error_to_grpc_status) @@ -5427,13 +5451,12 @@ for MetastoreServiceGrpcServerAdapter { request: tonic::Request, ) -> Result, tonic::Status> { let auth_token = quickwit_auth::get_auth_token(request.metadata())?; - let req = { - let req = request.into_inner(); - req - }; + let req = request.into_inner(); quickwit_auth::authorize(&req, &auth_token)?; - quickwit_auth::AUTHORIZATION_TOKEN - .scope(auth_token, self.inner.0.list_splits(req)) + quickwit_auth::execute_with_authorization( + auth_token, + self.inner.0.list_splits(req), + ) .await .map(|stream| tonic::Response::new( stream.map_err(crate::error::grpc_error_to_grpc_status), @@ -5445,13 +5468,12 @@ for MetastoreServiceGrpcServerAdapter { request: tonic::Request, ) -> Result, tonic::Status> { let auth_token = quickwit_auth::get_auth_token(request.metadata())?; - let req = { - let req = request.into_inner(); - req - }; + let req = request.into_inner(); quickwit_auth::authorize(&req, &auth_token)?; - quickwit_auth::AUTHORIZATION_TOKEN - .scope(auth_token, self.inner.0.stage_splits(req)) + quickwit_auth::execute_with_authorization( + auth_token, + self.inner.0.stage_splits(req), + ) .await .map(tonic::Response::new) .map_err(crate::error::grpc_error_to_grpc_status) @@ -5461,13 +5483,12 @@ for MetastoreServiceGrpcServerAdapter { request: tonic::Request, ) -> Result, tonic::Status> { let auth_token = quickwit_auth::get_auth_token(request.metadata())?; - let req = { - let req = request.into_inner(); - req - }; + let req = request.into_inner(); quickwit_auth::authorize(&req, &auth_token)?; - quickwit_auth::AUTHORIZATION_TOKEN - .scope(auth_token, self.inner.0.publish_splits(req)) + quickwit_auth::execute_with_authorization( + auth_token, + self.inner.0.publish_splits(req), + ) .await .map(tonic::Response::new) .map_err(crate::error::grpc_error_to_grpc_status) @@ -5477,13 +5498,12 @@ for MetastoreServiceGrpcServerAdapter { request: tonic::Request, ) -> Result, tonic::Status> { let auth_token = quickwit_auth::get_auth_token(request.metadata())?; - let req = { - let req = request.into_inner(); - req - }; + let req = request.into_inner(); quickwit_auth::authorize(&req, &auth_token)?; - quickwit_auth::AUTHORIZATION_TOKEN - .scope(auth_token, self.inner.0.mark_splits_for_deletion(req)) + quickwit_auth::execute_with_authorization( + auth_token, + self.inner.0.mark_splits_for_deletion(req), + ) .await .map(tonic::Response::new) .map_err(crate::error::grpc_error_to_grpc_status) @@ -5493,13 +5513,12 @@ for MetastoreServiceGrpcServerAdapter { request: tonic::Request, ) -> Result, tonic::Status> { let auth_token = quickwit_auth::get_auth_token(request.metadata())?; - let req = { - let req = request.into_inner(); - req - }; + let req = request.into_inner(); quickwit_auth::authorize(&req, &auth_token)?; - quickwit_auth::AUTHORIZATION_TOKEN - .scope(auth_token, self.inner.0.delete_splits(req)) + quickwit_auth::execute_with_authorization( + auth_token, + self.inner.0.delete_splits(req), + ) .await .map(tonic::Response::new) .map_err(crate::error::grpc_error_to_grpc_status) @@ -5509,13 +5528,12 @@ for MetastoreServiceGrpcServerAdapter { request: tonic::Request, ) -> Result, tonic::Status> { let auth_token = quickwit_auth::get_auth_token(request.metadata())?; - let req = { - let req = request.into_inner(); - req - }; + let req = request.into_inner(); quickwit_auth::authorize(&req, &auth_token)?; - quickwit_auth::AUTHORIZATION_TOKEN - .scope(auth_token, self.inner.0.add_source(req)) + quickwit_auth::execute_with_authorization( + auth_token, + self.inner.0.add_source(req), + ) .await .map(tonic::Response::new) .map_err(crate::error::grpc_error_to_grpc_status) @@ -5525,13 +5543,12 @@ for MetastoreServiceGrpcServerAdapter { request: tonic::Request, ) -> Result, tonic::Status> { let auth_token = quickwit_auth::get_auth_token(request.metadata())?; - let req = { - let req = request.into_inner(); - req - }; + let req = request.into_inner(); quickwit_auth::authorize(&req, &auth_token)?; - quickwit_auth::AUTHORIZATION_TOKEN - .scope(auth_token, self.inner.0.toggle_source(req)) + quickwit_auth::execute_with_authorization( + auth_token, + self.inner.0.toggle_source(req), + ) .await .map(tonic::Response::new) .map_err(crate::error::grpc_error_to_grpc_status) @@ -5541,13 +5558,12 @@ for MetastoreServiceGrpcServerAdapter { request: tonic::Request, ) -> Result, tonic::Status> { let auth_token = quickwit_auth::get_auth_token(request.metadata())?; - let req = { - let req = request.into_inner(); - req - }; + let req = request.into_inner(); quickwit_auth::authorize(&req, &auth_token)?; - quickwit_auth::AUTHORIZATION_TOKEN - .scope(auth_token, self.inner.0.delete_source(req)) + quickwit_auth::execute_with_authorization( + auth_token, + self.inner.0.delete_source(req), + ) .await .map(tonic::Response::new) .map_err(crate::error::grpc_error_to_grpc_status) @@ -5557,13 +5573,12 @@ for MetastoreServiceGrpcServerAdapter { request: tonic::Request, ) -> Result, tonic::Status> { let auth_token = quickwit_auth::get_auth_token(request.metadata())?; - let req = { - let req = request.into_inner(); - req - }; + let req = request.into_inner(); quickwit_auth::authorize(&req, &auth_token)?; - quickwit_auth::AUTHORIZATION_TOKEN - .scope(auth_token, self.inner.0.reset_source_checkpoint(req)) + quickwit_auth::execute_with_authorization( + auth_token, + self.inner.0.reset_source_checkpoint(req), + ) .await .map(tonic::Response::new) .map_err(crate::error::grpc_error_to_grpc_status) @@ -5573,13 +5588,12 @@ for MetastoreServiceGrpcServerAdapter { request: tonic::Request, ) -> Result, tonic::Status> { let auth_token = quickwit_auth::get_auth_token(request.metadata())?; - let req = { - let req = request.into_inner(); - req - }; + let req = request.into_inner(); quickwit_auth::authorize(&req, &auth_token)?; - quickwit_auth::AUTHORIZATION_TOKEN - .scope(auth_token, self.inner.0.last_delete_opstamp(req)) + quickwit_auth::execute_with_authorization( + auth_token, + self.inner.0.last_delete_opstamp(req), + ) .await .map(tonic::Response::new) .map_err(crate::error::grpc_error_to_grpc_status) @@ -5589,13 +5603,12 @@ for MetastoreServiceGrpcServerAdapter { request: tonic::Request, ) -> Result, tonic::Status> { let auth_token = quickwit_auth::get_auth_token(request.metadata())?; - let req = { - let req = request.into_inner(); - req - }; + let req = request.into_inner(); quickwit_auth::authorize(&req, &auth_token)?; - quickwit_auth::AUTHORIZATION_TOKEN - .scope(auth_token, self.inner.0.create_delete_task(req)) + quickwit_auth::execute_with_authorization( + auth_token, + self.inner.0.create_delete_task(req), + ) .await .map(tonic::Response::new) .map_err(crate::error::grpc_error_to_grpc_status) @@ -5605,13 +5618,12 @@ for MetastoreServiceGrpcServerAdapter { request: tonic::Request, ) -> Result, tonic::Status> { let auth_token = quickwit_auth::get_auth_token(request.metadata())?; - let req = { - let req = request.into_inner(); - req - }; + let req = request.into_inner(); quickwit_auth::authorize(&req, &auth_token)?; - quickwit_auth::AUTHORIZATION_TOKEN - .scope(auth_token, self.inner.0.update_splits_delete_opstamp(req)) + quickwit_auth::execute_with_authorization( + auth_token, + self.inner.0.update_splits_delete_opstamp(req), + ) .await .map(tonic::Response::new) .map_err(crate::error::grpc_error_to_grpc_status) @@ -5621,13 +5633,12 @@ for MetastoreServiceGrpcServerAdapter { request: tonic::Request, ) -> Result, tonic::Status> { let auth_token = quickwit_auth::get_auth_token(request.metadata())?; - let req = { - let req = request.into_inner(); - req - }; + let req = request.into_inner(); quickwit_auth::authorize(&req, &auth_token)?; - quickwit_auth::AUTHORIZATION_TOKEN - .scope(auth_token, self.inner.0.list_delete_tasks(req)) + quickwit_auth::execute_with_authorization( + auth_token, + self.inner.0.list_delete_tasks(req), + ) .await .map(tonic::Response::new) .map_err(crate::error::grpc_error_to_grpc_status) @@ -5637,13 +5648,12 @@ for MetastoreServiceGrpcServerAdapter { request: tonic::Request, ) -> Result, tonic::Status> { let auth_token = quickwit_auth::get_auth_token(request.metadata())?; - let req = { - let req = request.into_inner(); - req - }; + let req = request.into_inner(); quickwit_auth::authorize(&req, &auth_token)?; - quickwit_auth::AUTHORIZATION_TOKEN - .scope(auth_token, self.inner.0.list_stale_splits(req)) + quickwit_auth::execute_with_authorization( + auth_token, + self.inner.0.list_stale_splits(req), + ) .await .map(tonic::Response::new) .map_err(crate::error::grpc_error_to_grpc_status) @@ -5653,13 +5663,12 @@ for MetastoreServiceGrpcServerAdapter { request: tonic::Request, ) -> Result, tonic::Status> { let auth_token = quickwit_auth::get_auth_token(request.metadata())?; - let req = { - let req = request.into_inner(); - req - }; + let req = request.into_inner(); quickwit_auth::authorize(&req, &auth_token)?; - quickwit_auth::AUTHORIZATION_TOKEN - .scope(auth_token, self.inner.0.open_shards(req)) + quickwit_auth::execute_with_authorization( + auth_token, + self.inner.0.open_shards(req), + ) .await .map(tonic::Response::new) .map_err(crate::error::grpc_error_to_grpc_status) @@ -5669,13 +5678,12 @@ for MetastoreServiceGrpcServerAdapter { request: tonic::Request, ) -> Result, tonic::Status> { let auth_token = quickwit_auth::get_auth_token(request.metadata())?; - let req = { - let req = request.into_inner(); - req - }; + let req = request.into_inner(); quickwit_auth::authorize(&req, &auth_token)?; - quickwit_auth::AUTHORIZATION_TOKEN - .scope(auth_token, self.inner.0.acquire_shards(req)) + quickwit_auth::execute_with_authorization( + auth_token, + self.inner.0.acquire_shards(req), + ) .await .map(tonic::Response::new) .map_err(crate::error::grpc_error_to_grpc_status) @@ -5685,13 +5693,12 @@ for MetastoreServiceGrpcServerAdapter { request: tonic::Request, ) -> Result, tonic::Status> { let auth_token = quickwit_auth::get_auth_token(request.metadata())?; - let req = { - let req = request.into_inner(); - req - }; + let req = request.into_inner(); quickwit_auth::authorize(&req, &auth_token)?; - quickwit_auth::AUTHORIZATION_TOKEN - .scope(auth_token, self.inner.0.delete_shards(req)) + quickwit_auth::execute_with_authorization( + auth_token, + self.inner.0.delete_shards(req), + ) .await .map(tonic::Response::new) .map_err(crate::error::grpc_error_to_grpc_status) @@ -5701,13 +5708,12 @@ for MetastoreServiceGrpcServerAdapter { request: tonic::Request, ) -> Result, tonic::Status> { let auth_token = quickwit_auth::get_auth_token(request.metadata())?; - let req = { - let req = request.into_inner(); - req - }; + let req = request.into_inner(); quickwit_auth::authorize(&req, &auth_token)?; - quickwit_auth::AUTHORIZATION_TOKEN - .scope(auth_token, self.inner.0.prune_shards(req)) + quickwit_auth::execute_with_authorization( + auth_token, + self.inner.0.prune_shards(req), + ) .await .map(tonic::Response::new) .map_err(crate::error::grpc_error_to_grpc_status) @@ -5717,13 +5723,12 @@ for MetastoreServiceGrpcServerAdapter { request: tonic::Request, ) -> Result, tonic::Status> { let auth_token = quickwit_auth::get_auth_token(request.metadata())?; - let req = { - let req = request.into_inner(); - req - }; + let req = request.into_inner(); quickwit_auth::authorize(&req, &auth_token)?; - quickwit_auth::AUTHORIZATION_TOKEN - .scope(auth_token, self.inner.0.list_shards(req)) + quickwit_auth::execute_with_authorization( + auth_token, + self.inner.0.list_shards(req), + ) .await .map(tonic::Response::new) .map_err(crate::error::grpc_error_to_grpc_status) @@ -5733,13 +5738,12 @@ for MetastoreServiceGrpcServerAdapter { request: tonic::Request, ) -> Result, tonic::Status> { let auth_token = quickwit_auth::get_auth_token(request.metadata())?; - let req = { - let req = request.into_inner(); - req - }; + let req = request.into_inner(); quickwit_auth::authorize(&req, &auth_token)?; - quickwit_auth::AUTHORIZATION_TOKEN - .scope(auth_token, self.inner.0.create_index_template(req)) + quickwit_auth::execute_with_authorization( + auth_token, + self.inner.0.create_index_template(req), + ) .await .map(tonic::Response::new) .map_err(crate::error::grpc_error_to_grpc_status) @@ -5749,13 +5753,12 @@ for MetastoreServiceGrpcServerAdapter { request: tonic::Request, ) -> Result, tonic::Status> { let auth_token = quickwit_auth::get_auth_token(request.metadata())?; - let req = { - let req = request.into_inner(); - req - }; + let req = request.into_inner(); quickwit_auth::authorize(&req, &auth_token)?; - quickwit_auth::AUTHORIZATION_TOKEN - .scope(auth_token, self.inner.0.get_index_template(req)) + quickwit_auth::execute_with_authorization( + auth_token, + self.inner.0.get_index_template(req), + ) .await .map(tonic::Response::new) .map_err(crate::error::grpc_error_to_grpc_status) @@ -5765,13 +5768,12 @@ for MetastoreServiceGrpcServerAdapter { request: tonic::Request, ) -> Result, tonic::Status> { let auth_token = quickwit_auth::get_auth_token(request.metadata())?; - let req = { - let req = request.into_inner(); - req - }; + let req = request.into_inner(); quickwit_auth::authorize(&req, &auth_token)?; - quickwit_auth::AUTHORIZATION_TOKEN - .scope(auth_token, self.inner.0.find_index_template_matches(req)) + quickwit_auth::execute_with_authorization( + auth_token, + self.inner.0.find_index_template_matches(req), + ) .await .map(tonic::Response::new) .map_err(crate::error::grpc_error_to_grpc_status) @@ -5781,13 +5783,12 @@ for MetastoreServiceGrpcServerAdapter { request: tonic::Request, ) -> Result, tonic::Status> { let auth_token = quickwit_auth::get_auth_token(request.metadata())?; - let req = { - let req = request.into_inner(); - req - }; + let req = request.into_inner(); quickwit_auth::authorize(&req, &auth_token)?; - quickwit_auth::AUTHORIZATION_TOKEN - .scope(auth_token, self.inner.0.list_index_templates(req)) + quickwit_auth::execute_with_authorization( + auth_token, + self.inner.0.list_index_templates(req), + ) .await .map(tonic::Response::new) .map_err(crate::error::grpc_error_to_grpc_status) @@ -5797,13 +5798,12 @@ for MetastoreServiceGrpcServerAdapter { request: tonic::Request, ) -> Result, tonic::Status> { let auth_token = quickwit_auth::get_auth_token(request.metadata())?; - let req = { - let req = request.into_inner(); - req - }; + let req = request.into_inner(); quickwit_auth::authorize(&req, &auth_token)?; - quickwit_auth::AUTHORIZATION_TOKEN - .scope(auth_token, self.inner.0.delete_index_templates(req)) + quickwit_auth::execute_with_authorization( + auth_token, + self.inner.0.delete_index_templates(req), + ) .await .map(tonic::Response::new) .map_err(crate::error::grpc_error_to_grpc_status) diff --git a/quickwit/quickwit-proto/src/control_plane/mod.rs b/quickwit/quickwit-proto/src/control_plane/mod.rs index 8184851845e..34306229a2a 100644 --- a/quickwit/quickwit-proto/src/control_plane/mod.rs +++ b/quickwit/quickwit-proto/src/control_plane/mod.rs @@ -42,6 +42,8 @@ pub enum ControlPlaneError { TooManyRequests, #[error("service unavailable: {0}")] Unavailable(String), + #[error("unauthorized: {0}")] + Unauthorized(#[from] quickwit_auth::AuthorizationError), } impl From for ControlPlaneError { @@ -70,6 +72,7 @@ impl ServiceError for ControlPlaneError { Self::Timeout(_) => ServiceErrorCode::Timeout, Self::TooManyRequests => ServiceErrorCode::TooManyRequests, Self::Unavailable(_) => ServiceErrorCode::Unavailable, + Self::Unauthorized(authorization_error) => (*authorization_error).into(), } } } @@ -109,6 +112,7 @@ impl From for MetastoreError { ControlPlaneError::Timeout(message) => MetastoreError::Timeout(message), ControlPlaneError::TooManyRequests => MetastoreError::TooManyRequests, ControlPlaneError::Unavailable(message) => MetastoreError::Unavailable(message), + ControlPlaneError::Unauthorized(authorization_error) => authorization_error.into(), } } } diff --git a/quickwit/quickwit-proto/src/developer/mod.rs b/quickwit/quickwit-proto/src/developer/mod.rs index 2ed98190b17..90595b6d60a 100644 --- a/quickwit/quickwit-proto/src/developer/mod.rs +++ b/quickwit/quickwit-proto/src/developer/mod.rs @@ -38,6 +38,8 @@ pub enum DeveloperError { TooManyRequests, #[error("service unavailable: {0}")] Unavailable(String), + #[error("unauthorized: {0}")] + Unauthorized(#[from] quickwit_auth::AuthorizationError), } impl ServiceError for DeveloperError { @@ -48,6 +50,7 @@ impl ServiceError for DeveloperError { Self::Timeout(_) => ServiceErrorCode::Timeout, Self::TooManyRequests => ServiceErrorCode::TooManyRequests, Self::Unavailable(_) => ServiceErrorCode::Unavailable, + Self::Unauthorized(authorization_error) => (*authorization_error).into(), } } } diff --git a/quickwit/quickwit-proto/src/error.rs b/quickwit/quickwit-proto/src/error.rs index 8fb11caac6e..828e33efe0a 100644 --- a/quickwit/quickwit-proto/src/error.rs +++ b/quickwit/quickwit-proto/src/error.rs @@ -23,6 +23,7 @@ use std::fmt::Debug; use anyhow::Context; use quickwit_actors::AskError; +use quickwit_auth::AuthorizationError; use serde::de::DeserializeOwned; use serde::Serialize; use tonic::metadata::BinaryMetadataValue; @@ -47,6 +48,13 @@ pub enum ServiceErrorCode { TooManyRequests, Unauthenticated, Unavailable, + Unauthorized, +} + +impl From for ServiceErrorCode { + fn from(_: AuthorizationError) -> Self { + ServiceErrorCode::Unauthorized + } } impl ServiceErrorCode { @@ -61,6 +69,7 @@ impl ServiceErrorCode { Self::TooManyRequests => tonic::Code::ResourceExhausted, Self::Unauthenticated => tonic::Code::Unauthenticated, Self::Unavailable => tonic::Code::Unavailable, + Self::Unauthorized => tonic::Code::PermissionDenied, } } @@ -75,6 +84,7 @@ impl ServiceErrorCode { Self::TooManyRequests => http::StatusCode::TOO_MANY_REQUESTS, Self::Unauthenticated => http::StatusCode::UNAUTHORIZED, Self::Unavailable => http::StatusCode::SERVICE_UNAVAILABLE, + Self::Unauthorized => http::StatusCode::UNAUTHORIZED, } } } diff --git a/quickwit/quickwit-proto/src/indexing/mod.rs b/quickwit/quickwit-proto/src/indexing/mod.rs index b621f447ef1..449d7f9efae 100644 --- a/quickwit/quickwit-proto/src/indexing/mod.rs +++ b/quickwit/quickwit-proto/src/indexing/mod.rs @@ -51,7 +51,10 @@ pub enum IndexingError { TooManyRequests, #[error("service unavailable: {0}")] Unavailable(String), + #[error("unauthorized: {0}")] + Unauthorized(#[from] quickwit_auth::AuthorizationError), } + impl From for IndexingError { fn from(_timeout_exceeded: TimeoutExceeded) -> Self { Self::Timeout("tower layer timeout".to_string()) @@ -69,6 +72,7 @@ impl ServiceError for IndexingError { Self::Timeout(_) => ServiceErrorCode::Timeout, Self::TooManyRequests => ServiceErrorCode::TooManyRequests, Self::Unavailable(_) => ServiceErrorCode::Unavailable, + Self::Unauthorized(authorization_error) => (*authorization_error).into(), } } } diff --git a/quickwit/quickwit-proto/src/ingest/mod.rs b/quickwit/quickwit-proto/src/ingest/mod.rs index 48a410cd5ba..3722c5fbd87 100644 --- a/quickwit/quickwit-proto/src/ingest/mod.rs +++ b/quickwit/quickwit-proto/src/ingest/mod.rs @@ -65,6 +65,8 @@ pub enum IngestV2Error { TooManyRequests(RateLimitingCause), #[error("service unavailable: {0}")] Unavailable(String), + #[error("unauthorized: {0}")] + Unauthorized(#[from] quickwit_auth::AuthorizationError), } impl From for IngestV2Error { @@ -90,6 +92,7 @@ impl ServiceError for IngestV2Error { Self::Timeout(_) => ServiceErrorCode::Timeout, Self::TooManyRequests(_) => ServiceErrorCode::TooManyRequests, Self::Unavailable(_) => ServiceErrorCode::Unavailable, + Self::Unauthorized(authorization_error) => (*authorization_error).into(), } } } @@ -318,6 +321,7 @@ impl From for IngestFailureReason { PersistFailureReason::WalFull => IngestFailureReason::WalFull, PersistFailureReason::ShardRateLimited => IngestFailureReason::ShardRateLimited, PersistFailureReason::Timeout => IngestFailureReason::Timeout, + PersistFailureReason::Unauthorized => IngestFailureReason::Unauthorized, } } } diff --git a/quickwit/quickwit-proto/src/lib.rs b/quickwit/quickwit-proto/src/lib.rs index 14d1969c573..3e0f44a3003 100644 --- a/quickwit/quickwit-proto/src/lib.rs +++ b/quickwit/quickwit-proto/src/lib.rs @@ -30,9 +30,11 @@ use tonic::Status; use tracing::Span; use tracing_opentelemetry::OpenTelemetrySpanExt; +#[cfg(feature = "enterprise")] +mod authorization; + pub mod cluster; pub mod control_plane; -mod authorization; pub use {bytes, tonic}; pub mod developer; pub mod error; diff --git a/quickwit/quickwit-proto/src/metastore/mod.rs b/quickwit/quickwit-proto/src/metastore/mod.rs index 4782dac03c2..530f5ec0c79 100644 --- a/quickwit/quickwit-proto/src/metastore/mod.rs +++ b/quickwit/quickwit-proto/src/metastore/mod.rs @@ -155,6 +155,9 @@ pub enum MetastoreError { #[error("service unavailable: {0}")] Unavailable(String), + + #[error("unauthorized: {0}")] + Unauthorized(#[from] quickwit_auth::AuthorizationError), } impl MetastoreError { @@ -169,7 +172,8 @@ impl MetastoreError { | MetastoreError::JsonDeserializeError { .. } | MetastoreError::JsonSerializeError { .. } | MetastoreError::NotFound(_) - | MetastoreError::TooManyRequests => true, + | MetastoreError::TooManyRequests + | MetastoreError::Unauthorized(_) => true, MetastoreError::Connection { .. } | MetastoreError::Db { .. } | MetastoreError::Internal { .. } @@ -242,6 +246,7 @@ impl ServiceError for MetastoreError { Self::Timeout(_) => ServiceErrorCode::Timeout, Self::TooManyRequests => ServiceErrorCode::TooManyRequests, Self::Unavailable(_) => ServiceErrorCode::Unavailable, + Self::Unauthorized(authorization_error) => (*authorization_error).into(), } } } diff --git a/quickwit/quickwit-serve/src/elasticsearch_api/model/bulk_query_params.rs b/quickwit/quickwit-serve/src/elasticsearch_api/model/bulk_query_params.rs index e9b415c8248..fbba0f739a6 100644 --- a/quickwit/quickwit-serve/src/elasticsearch_api/model/bulk_query_params.rs +++ b/quickwit/quickwit-serve/src/elasticsearch_api/model/bulk_query_params.rs @@ -114,7 +114,7 @@ mod tests { serde_qs::from_str::("refresh=wait") .unwrap_err() .to_string(), - "unknown variant `wait`, expected one of `false`, `true`, `wait_for`" + "unknown variant `wait`, expected one of `false`, ``, `true`, `wait_for`" ); } } diff --git a/quickwit/scripts/.ee.license_header.txt b/quickwit/scripts/.ee.license_header.txt index 9a1485ca763..2978b3cab09 100644 --- a/quickwit/scripts/.ee.license_header.txt +++ b/quickwit/scripts/.ee.license_header.txt @@ -1,5 +1,5 @@ // The Quickwit Enterprise Edition (EE) license -// Copyright (c) {\d+}-present Quickwit Inc. +// Copyright (c) 2024-present Quickwit Inc. // // With regard to the Quickwit Software: // @@ -14,7 +14,3 @@ // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. - -// For all third party components incorporated into the Quickwit Software, those -// components are licensed under the original license provided by the owner of the -// applicable component. diff --git a/quickwit/scripts/check_license_headers.sh b/quickwit/scripts/check_license_headers.sh index 6684b2023ba..9ff9861192b 100755 --- a/quickwit/scripts/check_license_headers.sh +++ b/quickwit/scripts/check_license_headers.sh @@ -15,7 +15,7 @@ do # echo "Checking $file"; diff <(sed 's/{\\d+}/2024/' "${SCRIPT_DIR}/.agpl.license_header.txt") <(head -n 18 $file) > /dev/null HAS_AGPL_LICENSE=$? - diff <(sed 's/{\\d+}/2024/' "${SCRIPT_DIR}/.ee.license_header.txt") <(head -n 20 $file) > /dev/null + diff <(sed 's/{\\d+}/2024/' "${SCRIPT_DIR}/.ee.license_header.txt") <(head -n 16 $file) > /dev/null HAS_EE_LICENSE=$? HAS_LICENSE_HEADER=$(( $HAS_AGPL_LICENSE ^ $HAS_EE_LICENSE )) if [ $HAS_LICENSE_HEADER -ne 1 ]; then From c67d25f1db092e2b52fe97d978b629c9f5e4ddd8 Mon Sep 17 00:00:00 2001 From: Paul Masurel Date: Mon, 4 Nov 2024 09:49:21 +0900 Subject: [PATCH 3/6] authorization as a layer --- quickwit/Cargo.lock | 5 +- quickwit/quickwit-auth/Cargo.toml | 5 + .../quickwit-auth/src/authorization_layer.rs | 51 ++++++++ quickwit/quickwit-auth/src/community.rs | 4 + quickwit/quickwit-auth/src/enterprise.rs | 6 + quickwit/quickwit-auth/src/lib.rs | 3 +- .../example/src/codegen/hello.rs | 30 +++-- quickwit/quickwit-codegen/src/codegen.rs | 18 +-- .../src/codegen/ingest_service.rs | 21 +-- quickwit/quickwit-proto/Cargo.toml | 1 - .../src/codegen/quickwit/quickwit.cluster.rs | 4 +- .../quickwit/quickwit.control_plane.rs | 36 ++---- .../codegen/quickwit/quickwit.developer.rs | 4 +- .../src/codegen/quickwit/quickwit.indexing.rs | 4 +- .../quickwit/quickwit.ingest.ingester.rs | 48 +++---- .../quickwit/quickwit.ingest.router.rs | 7 +- .../codegen/quickwit/quickwit.metastore.rs | 120 +++++------------- 17 files changed, 168 insertions(+), 199 deletions(-) create mode 100644 quickwit/quickwit-auth/src/authorization_layer.rs diff --git a/quickwit/Cargo.lock b/quickwit/Cargo.lock index 5a90536790e..5521cdc4ebf 100644 --- a/quickwit/Cargo.lock +++ b/quickwit/Cargo.lock @@ -5952,11 +5952,15 @@ name = "quickwit-auth" version = "0.8.0" dependencies = [ "biscuit-auth", + "futures", "http 0.2.12", + "pin-project", + "quickwit-common", "serde", "thiserror", "tokio", "tonic", + "tower", "tracing", ] @@ -6617,7 +6621,6 @@ version = "0.8.0" dependencies = [ "anyhow", "async-trait", - "biscuit-auth", "bytes", "bytesize", "bytestring", diff --git a/quickwit/quickwit-auth/Cargo.toml b/quickwit/quickwit-auth/Cargo.toml index ea2013777c5..3ffdef60696 100644 --- a/quickwit/quickwit-auth/Cargo.toml +++ b/quickwit/quickwit-auth/Cargo.toml @@ -9,13 +9,18 @@ authors.workspace = true license.workspace = true [dependencies] +tower = { workspace = true} biscuit-auth = { workspace = true, optional=true } +futures = { workspace = true } http = { workspace = true } serde = { workspace = true } thiserror = { workspace = true } tonic = { workspace = true } tokio = { workspace = true } tracing = { workspace = true } +pin-project = { workspace = true } + +quickwit-common = { workspace = true } [features] enterprise = ["biscuit-auth"] diff --git a/quickwit/quickwit-auth/src/authorization_layer.rs b/quickwit/quickwit-auth/src/authorization_layer.rs new file mode 100644 index 00000000000..3131bef4715 --- /dev/null +++ b/quickwit/quickwit-auth/src/authorization_layer.rs @@ -0,0 +1,51 @@ +use std::fmt; +use std::task::{Context, Poll}; + +use futures::future::Either; +use quickwit_common::tower::RpcName; +use tower::{Layer, Service}; + +use crate::AuthorizationError; + +pub struct AuthorizationLayer; + +impl Layer for AuthorizationLayer { + type Service = AuthorizationService; + + fn layer(&self, service: S) -> Self::Service { + AuthorizationService { service } + } +} + +#[derive(Clone)] +pub struct AuthorizationService { + service: S, +} + +impl Service for AuthorizationService +where + S: Service, + S::Future: Send + 'static, + S::Response: Send + 'static, + S::Error: From + Send + 'static, + Request: fmt::Debug + Send + RpcName + crate::Authorization + 'static, +{ + type Response = S::Response; + type Error = S::Error; + type Future = + futures::future::Either>, S::Future>; + + fn poll_ready(&mut self, cx: &mut Context<'_>) -> Poll> { + self.service.poll_ready(cx) + } + + fn call(&mut self, request: Request) -> Self::Future { + if let Err(authorization_err) = crate::authorize_request(&request) { + let err = S::Error::from(authorization_err); + let result: Result = Err(err); + return Either::Left(futures::future::ready(result)); + } + let service_fut = self.service.call(request); + Either::Right(service_fut) + } +} diff --git a/quickwit/quickwit-auth/src/community.rs b/quickwit/quickwit-auth/src/community.rs index 7be01328fde..48576639c7f 100644 --- a/quickwit/quickwit-auth/src/community.rs +++ b/quickwit/quickwit-auth/src/community.rs @@ -85,3 +85,7 @@ pub fn execute_with_authorization(_: AuthorizationToken, f: F) -> impl Fut where F: Future { f } + +pub fn authorize_request(_req: &R) -> Result<(), AuthorizationError> { + Ok(()) +} diff --git a/quickwit/quickwit-auth/src/enterprise.rs b/quickwit/quickwit-auth/src/enterprise.rs index fd81ab73e49..e1aa02e4436 100644 --- a/quickwit/quickwit-auth/src/enterprise.rs +++ b/quickwit/quickwit-auth/src/enterprise.rs @@ -215,6 +215,12 @@ pub fn authorize_stream( Ok(()) } +pub fn authorize_request(req: &R) -> Result<(), AuthorizationError> { + AUTHORIZATION_TOKEN + .try_with(|auth_token| authorize(req, auth_token)) + .unwrap_or(Err(AuthorizationError::AuthorizationTokenMissing)) +} + pub fn execute_with_authorization( token: AuthorizationToken, f: F, diff --git a/quickwit/quickwit-auth/src/lib.rs b/quickwit/quickwit-auth/src/lib.rs index cccaf68989a..23206c0b434 100644 --- a/quickwit/quickwit-auth/src/lib.rs +++ b/quickwit/quickwit-auth/src/lib.rs @@ -17,7 +17,7 @@ // You should have received a copy of the GNU Affero General Public License // along with this program. If not, see . -use serde::{Deserialize, Serialize}; +mod authorization_layer; #[cfg(not(feature = "enterprise"))] #[path = "community.rs"] @@ -28,6 +28,7 @@ mod implementation; mod implementation; pub use implementation::*; +use serde::{Deserialize, Serialize}; #[derive(thiserror::Error, Debug, Clone, Copy, Serialize, Deserialize, Eq, PartialEq)] pub enum AuthorizationError { diff --git a/quickwit/quickwit-codegen/example/src/codegen/hello.rs b/quickwit/quickwit-codegen/example/src/codegen/hello.rs index 83b8cb40bb0..c12d635e581 100644 --- a/quickwit/quickwit-codegen/example/src/codegen/hello.rs +++ b/quickwit/quickwit-codegen/example/src/codegen/hello.rs @@ -811,9 +811,10 @@ impl hello_grpc_server::HelloGrpc for HelloGrpcServerAdapter { request: tonic::Request, ) -> Result, tonic::Status> { let auth_token = quickwit_auth::get_auth_token(request.metadata())?; - let req = request.into_inner(); - quickwit_auth::authorize(&req, &auth_token)?; - quickwit_auth::execute_with_authorization(auth_token, self.inner.0.hello(req)) + quickwit_auth::execute_with_authorization( + auth_token, + self.inner.0.hello(request.into_inner()), + ) .await .map(tonic::Response::new) .map_err(crate::error::grpc_error_to_grpc_status) @@ -823,9 +824,10 @@ impl hello_grpc_server::HelloGrpc for HelloGrpcServerAdapter { request: tonic::Request, ) -> Result, tonic::Status> { let auth_token = quickwit_auth::get_auth_token(request.metadata())?; - let req = request.into_inner(); - quickwit_auth::authorize(&req, &auth_token)?; - quickwit_auth::execute_with_authorization(auth_token, self.inner.0.goodbye(req)) + quickwit_auth::execute_with_authorization( + auth_token, + self.inner.0.goodbye(request.into_inner()), + ) .await .map(tonic::Response::new) .map_err(crate::error::grpc_error_to_grpc_status) @@ -836,12 +838,16 @@ impl hello_grpc_server::HelloGrpc for HelloGrpcServerAdapter { request: tonic::Request>, ) -> Result, tonic::Status> { let auth_token = quickwit_auth::get_auth_token(request.metadata())?; - let req = { - let streaming: tonic::Streaming<_> = request.into_inner(); - quickwit_common::ServiceStream::from(streaming) - }; - quickwit_auth::authorize_stream::(&auth_token)?; - quickwit_auth::execute_with_authorization(auth_token, self.inner.0.ping(req)) + quickwit_auth::execute_with_authorization( + auth_token, + self + .inner + .0 + .ping({ + let streaming: tonic::Streaming<_> = request.into_inner(); + quickwit_common::ServiceStream::from(streaming) + }), + ) .await .map(|stream| tonic::Response::new( stream.map_err(crate::error::grpc_error_to_grpc_status), diff --git a/quickwit/quickwit-codegen/src/codegen.rs b/quickwit/quickwit-codegen/src/codegen.rs index 26d284e54ba..361cd21189b 100644 --- a/quickwit/quickwit-codegen/src/codegen.rs +++ b/quickwit/quickwit-codegen/src/codegen.rs @@ -1246,9 +1246,7 @@ fn generate_grpc_server_adapter_methods(context: &CodegenContext) -> TokenStream } } } else { - quote! { - request.into_inner() - } + quote! { request.into_inner() } }; let response_type = if syn_method.server_streaming { let associated_type_name = quote::format_ident!("{}Stream", syn_method.proto_name); @@ -1271,24 +1269,12 @@ fn generate_grpc_server_adapter_methods(context: &CodegenContext) -> TokenStream quote! { tonic::Response::new } }; - let authorize_block = if syn_method.client_streaming { - let stream_item = &syn_method.request_type; - quote! { - quickwit_auth::authorize_stream::<#stream_item>(&auth_token)?; - } - } else { - quote! { - quickwit_auth::authorize(&req, &auth_token)?; - } - }; let method = quote! { #associated_type async fn #method_name(&self, request: tonic::Request<#request_type>) -> Result, tonic::Status> { let auth_token = quickwit_auth::get_auth_token(request.metadata())?; - let req = #method_arg; - #authorize_block; - quickwit_auth::execute_with_authorization(auth_token, self.inner.0.#method_name(req)).await + quickwit_auth::execute_with_authorization(auth_token, self.inner.0.#method_name(#method_arg)).await .map(#into_response_type) .map_err(crate::error::grpc_error_to_grpc_status) } diff --git a/quickwit/quickwit-ingest/src/codegen/ingest_service.rs b/quickwit/quickwit-ingest/src/codegen/ingest_service.rs index 49e20a534be..65992ccaa2e 100644 --- a/quickwit/quickwit-ingest/src/codegen/ingest_service.rs +++ b/quickwit/quickwit-ingest/src/codegen/ingest_service.rs @@ -876,9 +876,10 @@ impl ingest_service_grpc_server::IngestServiceGrpc for IngestServiceGrpcServerAd request: tonic::Request, ) -> Result, tonic::Status> { let auth_token = quickwit_auth::get_auth_token(request.metadata())?; - let req = request.into_inner(); - quickwit_auth::authorize(&req, &auth_token)?; - quickwit_auth::execute_with_authorization(auth_token, self.inner.0.ingest(req)) + quickwit_auth::execute_with_authorization( + auth_token, + self.inner.0.ingest(request.into_inner()), + ) .await .map(tonic::Response::new) .map_err(crate::error::grpc_error_to_grpc_status) @@ -888,9 +889,10 @@ impl ingest_service_grpc_server::IngestServiceGrpc for IngestServiceGrpcServerAd request: tonic::Request, ) -> Result, tonic::Status> { let auth_token = quickwit_auth::get_auth_token(request.metadata())?; - let req = request.into_inner(); - quickwit_auth::authorize(&req, &auth_token)?; - quickwit_auth::execute_with_authorization(auth_token, self.inner.0.fetch(req)) + quickwit_auth::execute_with_authorization( + auth_token, + self.inner.0.fetch(request.into_inner()), + ) .await .map(tonic::Response::new) .map_err(crate::error::grpc_error_to_grpc_status) @@ -900,9 +902,10 @@ impl ingest_service_grpc_server::IngestServiceGrpc for IngestServiceGrpcServerAd request: tonic::Request, ) -> Result, tonic::Status> { let auth_token = quickwit_auth::get_auth_token(request.metadata())?; - let req = request.into_inner(); - quickwit_auth::authorize(&req, &auth_token)?; - quickwit_auth::execute_with_authorization(auth_token, self.inner.0.tail(req)) + quickwit_auth::execute_with_authorization( + auth_token, + self.inner.0.tail(request.into_inner()), + ) .await .map(tonic::Response::new) .map_err(crate::error::grpc_error_to_grpc_status) diff --git a/quickwit/quickwit-proto/Cargo.toml b/quickwit/quickwit-proto/Cargo.toml index a5e90f751ae..6f5aedb6724 100644 --- a/quickwit/quickwit-proto/Cargo.toml +++ b/quickwit/quickwit-proto/Cargo.toml @@ -12,7 +12,6 @@ license.workspace = true [dependencies] anyhow = { workspace = true } async-trait = { workspace = true } -biscuit-auth = { workspace = true } bytes = { workspace = true } bytesize = { workspace = true } bytestring = { workspace = true } diff --git a/quickwit/quickwit-proto/src/codegen/quickwit/quickwit.cluster.rs b/quickwit/quickwit-proto/src/codegen/quickwit/quickwit.cluster.rs index 07ec4928ec1..a7a4e2388d0 100644 --- a/quickwit/quickwit-proto/src/codegen/quickwit/quickwit.cluster.rs +++ b/quickwit/quickwit-proto/src/codegen/quickwit/quickwit.cluster.rs @@ -544,11 +544,9 @@ for ClusterServiceGrpcServerAdapter { request: tonic::Request, ) -> Result, tonic::Status> { let auth_token = quickwit_auth::get_auth_token(request.metadata())?; - let req = request.into_inner(); - quickwit_auth::authorize(&req, &auth_token)?; quickwit_auth::execute_with_authorization( auth_token, - self.inner.0.fetch_cluster_state(req), + self.inner.0.fetch_cluster_state(request.into_inner()), ) .await .map(tonic::Response::new) diff --git a/quickwit/quickwit-proto/src/codegen/quickwit/quickwit.control_plane.rs b/quickwit/quickwit-proto/src/codegen/quickwit/quickwit.control_plane.rs index 780edd4b9ae..b6449a8bd42 100644 --- a/quickwit/quickwit-proto/src/codegen/quickwit/quickwit.control_plane.rs +++ b/quickwit/quickwit-proto/src/codegen/quickwit/quickwit.control_plane.rs @@ -1789,11 +1789,9 @@ for ControlPlaneServiceGrpcServerAdapter { request: tonic::Request, ) -> Result, tonic::Status> { let auth_token = quickwit_auth::get_auth_token(request.metadata())?; - let req = request.into_inner(); - quickwit_auth::authorize(&req, &auth_token)?; quickwit_auth::execute_with_authorization( auth_token, - self.inner.0.create_index(req), + self.inner.0.create_index(request.into_inner()), ) .await .map(tonic::Response::new) @@ -1807,11 +1805,9 @@ for ControlPlaneServiceGrpcServerAdapter { tonic::Status, > { let auth_token = quickwit_auth::get_auth_token(request.metadata())?; - let req = request.into_inner(); - quickwit_auth::authorize(&req, &auth_token)?; quickwit_auth::execute_with_authorization( auth_token, - self.inner.0.update_index(req), + self.inner.0.update_index(request.into_inner()), ) .await .map(tonic::Response::new) @@ -1822,11 +1818,9 @@ for ControlPlaneServiceGrpcServerAdapter { request: tonic::Request, ) -> Result, tonic::Status> { let auth_token = quickwit_auth::get_auth_token(request.metadata())?; - let req = request.into_inner(); - quickwit_auth::authorize(&req, &auth_token)?; quickwit_auth::execute_with_authorization( auth_token, - self.inner.0.delete_index(req), + self.inner.0.delete_index(request.into_inner()), ) .await .map(tonic::Response::new) @@ -1837,11 +1831,9 @@ for ControlPlaneServiceGrpcServerAdapter { request: tonic::Request, ) -> Result, tonic::Status> { let auth_token = quickwit_auth::get_auth_token(request.metadata())?; - let req = request.into_inner(); - quickwit_auth::authorize(&req, &auth_token)?; quickwit_auth::execute_with_authorization( auth_token, - self.inner.0.add_source(req), + self.inner.0.add_source(request.into_inner()), ) .await .map(tonic::Response::new) @@ -1852,11 +1844,9 @@ for ControlPlaneServiceGrpcServerAdapter { request: tonic::Request, ) -> Result, tonic::Status> { let auth_token = quickwit_auth::get_auth_token(request.metadata())?; - let req = request.into_inner(); - quickwit_auth::authorize(&req, &auth_token)?; quickwit_auth::execute_with_authorization( auth_token, - self.inner.0.toggle_source(req), + self.inner.0.toggle_source(request.into_inner()), ) .await .map(tonic::Response::new) @@ -1867,11 +1857,9 @@ for ControlPlaneServiceGrpcServerAdapter { request: tonic::Request, ) -> Result, tonic::Status> { let auth_token = quickwit_auth::get_auth_token(request.metadata())?; - let req = request.into_inner(); - quickwit_auth::authorize(&req, &auth_token)?; quickwit_auth::execute_with_authorization( auth_token, - self.inner.0.delete_source(req), + self.inner.0.delete_source(request.into_inner()), ) .await .map(tonic::Response::new) @@ -1882,11 +1870,9 @@ for ControlPlaneServiceGrpcServerAdapter { request: tonic::Request, ) -> Result, tonic::Status> { let auth_token = quickwit_auth::get_auth_token(request.metadata())?; - let req = request.into_inner(); - quickwit_auth::authorize(&req, &auth_token)?; quickwit_auth::execute_with_authorization( auth_token, - self.inner.0.get_or_create_open_shards(req), + self.inner.0.get_or_create_open_shards(request.into_inner()), ) .await .map(tonic::Response::new) @@ -1897,11 +1883,9 @@ for ControlPlaneServiceGrpcServerAdapter { request: tonic::Request, ) -> Result, tonic::Status> { let auth_token = quickwit_auth::get_auth_token(request.metadata())?; - let req = request.into_inner(); - quickwit_auth::authorize(&req, &auth_token)?; quickwit_auth::execute_with_authorization( auth_token, - self.inner.0.advise_reset_shards(req), + self.inner.0.advise_reset_shards(request.into_inner()), ) .await .map(tonic::Response::new) @@ -1912,11 +1896,9 @@ for ControlPlaneServiceGrpcServerAdapter { request: tonic::Request, ) -> Result, tonic::Status> { let auth_token = quickwit_auth::get_auth_token(request.metadata())?; - let req = request.into_inner(); - quickwit_auth::authorize(&req, &auth_token)?; quickwit_auth::execute_with_authorization( auth_token, - self.inner.0.prune_shards(req), + self.inner.0.prune_shards(request.into_inner()), ) .await .map(tonic::Response::new) diff --git a/quickwit/quickwit-proto/src/codegen/quickwit/quickwit.developer.rs b/quickwit/quickwit-proto/src/codegen/quickwit/quickwit.developer.rs index ec25565eef2..1a98a47df7b 100644 --- a/quickwit/quickwit-proto/src/codegen/quickwit/quickwit.developer.rs +++ b/quickwit/quickwit-proto/src/codegen/quickwit/quickwit.developer.rs @@ -480,11 +480,9 @@ for DeveloperServiceGrpcServerAdapter { request: tonic::Request, ) -> Result, tonic::Status> { let auth_token = quickwit_auth::get_auth_token(request.metadata())?; - let req = request.into_inner(); - quickwit_auth::authorize(&req, &auth_token)?; quickwit_auth::execute_with_authorization( auth_token, - self.inner.0.get_debug_info(req), + self.inner.0.get_debug_info(request.into_inner()), ) .await .map(tonic::Response::new) diff --git a/quickwit/quickwit-proto/src/codegen/quickwit/quickwit.indexing.rs b/quickwit/quickwit-proto/src/codegen/quickwit/quickwit.indexing.rs index a6b7a2a0aee..793f4bffa72 100644 --- a/quickwit/quickwit-proto/src/codegen/quickwit/quickwit.indexing.rs +++ b/quickwit/quickwit-proto/src/codegen/quickwit/quickwit.indexing.rs @@ -493,11 +493,9 @@ for IndexingServiceGrpcServerAdapter { request: tonic::Request, ) -> Result, tonic::Status> { let auth_token = quickwit_auth::get_auth_token(request.metadata())?; - let req = request.into_inner(); - quickwit_auth::authorize(&req, &auth_token)?; quickwit_auth::execute_with_authorization( auth_token, - self.inner.0.apply_indexing_plan(req), + self.inner.0.apply_indexing_plan(request.into_inner()), ) .await .map(tonic::Response::new) diff --git a/quickwit/quickwit-proto/src/codegen/quickwit/quickwit.ingest.ingester.rs b/quickwit/quickwit-proto/src/codegen/quickwit/quickwit.ingest.ingester.rs index c5a230b7d09..bc5ae585cdf 100644 --- a/quickwit/quickwit-proto/src/codegen/quickwit/quickwit.ingest.ingester.rs +++ b/quickwit/quickwit-proto/src/codegen/quickwit/quickwit.ingest.ingester.rs @@ -2224,9 +2224,10 @@ for IngesterServiceGrpcServerAdapter { request: tonic::Request, ) -> Result, tonic::Status> { let auth_token = quickwit_auth::get_auth_token(request.metadata())?; - let req = request.into_inner(); - quickwit_auth::authorize(&req, &auth_token)?; - quickwit_auth::execute_with_authorization(auth_token, self.inner.0.persist(req)) + quickwit_auth::execute_with_authorization( + auth_token, + self.inner.0.persist(request.into_inner()), + ) .await .map(tonic::Response::new) .map_err(crate::error::grpc_error_to_grpc_status) @@ -2239,14 +2240,15 @@ for IngesterServiceGrpcServerAdapter { request: tonic::Request>, ) -> Result, tonic::Status> { let auth_token = quickwit_auth::get_auth_token(request.metadata())?; - let req = { - let streaming: tonic::Streaming<_> = request.into_inner(); - quickwit_common::ServiceStream::from(streaming) - }; - quickwit_auth::authorize_stream::(&auth_token)?; quickwit_auth::execute_with_authorization( auth_token, - self.inner.0.open_replication_stream(req), + self + .inner + .0 + .open_replication_stream({ + let streaming: tonic::Streaming<_> = request.into_inner(); + quickwit_common::ServiceStream::from(streaming) + }), ) .await .map(|stream| tonic::Response::new( @@ -2262,11 +2264,9 @@ for IngesterServiceGrpcServerAdapter { request: tonic::Request, ) -> Result, tonic::Status> { let auth_token = quickwit_auth::get_auth_token(request.metadata())?; - let req = request.into_inner(); - quickwit_auth::authorize(&req, &auth_token)?; quickwit_auth::execute_with_authorization( auth_token, - self.inner.0.open_fetch_stream(req), + self.inner.0.open_fetch_stream(request.into_inner()), ) .await .map(|stream| tonic::Response::new( @@ -2282,11 +2282,9 @@ for IngesterServiceGrpcServerAdapter { request: tonic::Request, ) -> Result, tonic::Status> { let auth_token = quickwit_auth::get_auth_token(request.metadata())?; - let req = request.into_inner(); - quickwit_auth::authorize(&req, &auth_token)?; quickwit_auth::execute_with_authorization( auth_token, - self.inner.0.open_observation_stream(req), + self.inner.0.open_observation_stream(request.into_inner()), ) .await .map(|stream| tonic::Response::new( @@ -2299,11 +2297,9 @@ for IngesterServiceGrpcServerAdapter { request: tonic::Request, ) -> Result, tonic::Status> { let auth_token = quickwit_auth::get_auth_token(request.metadata())?; - let req = request.into_inner(); - quickwit_auth::authorize(&req, &auth_token)?; quickwit_auth::execute_with_authorization( auth_token, - self.inner.0.init_shards(req), + self.inner.0.init_shards(request.into_inner()), ) .await .map(tonic::Response::new) @@ -2314,11 +2310,9 @@ for IngesterServiceGrpcServerAdapter { request: tonic::Request, ) -> Result, tonic::Status> { let auth_token = quickwit_auth::get_auth_token(request.metadata())?; - let req = request.into_inner(); - quickwit_auth::authorize(&req, &auth_token)?; quickwit_auth::execute_with_authorization( auth_token, - self.inner.0.retain_shards(req), + self.inner.0.retain_shards(request.into_inner()), ) .await .map(tonic::Response::new) @@ -2329,11 +2323,9 @@ for IngesterServiceGrpcServerAdapter { request: tonic::Request, ) -> Result, tonic::Status> { let auth_token = quickwit_auth::get_auth_token(request.metadata())?; - let req = request.into_inner(); - quickwit_auth::authorize(&req, &auth_token)?; quickwit_auth::execute_with_authorization( auth_token, - self.inner.0.truncate_shards(req), + self.inner.0.truncate_shards(request.into_inner()), ) .await .map(tonic::Response::new) @@ -2344,11 +2336,9 @@ for IngesterServiceGrpcServerAdapter { request: tonic::Request, ) -> Result, tonic::Status> { let auth_token = quickwit_auth::get_auth_token(request.metadata())?; - let req = request.into_inner(); - quickwit_auth::authorize(&req, &auth_token)?; quickwit_auth::execute_with_authorization( auth_token, - self.inner.0.close_shards(req), + self.inner.0.close_shards(request.into_inner()), ) .await .map(tonic::Response::new) @@ -2359,11 +2349,9 @@ for IngesterServiceGrpcServerAdapter { request: tonic::Request, ) -> Result, tonic::Status> { let auth_token = quickwit_auth::get_auth_token(request.metadata())?; - let req = request.into_inner(); - quickwit_auth::authorize(&req, &auth_token)?; quickwit_auth::execute_with_authorization( auth_token, - self.inner.0.decommission(req), + self.inner.0.decommission(request.into_inner()), ) .await .map(tonic::Response::new) diff --git a/quickwit/quickwit-proto/src/codegen/quickwit/quickwit.ingest.router.rs b/quickwit/quickwit-proto/src/codegen/quickwit/quickwit.ingest.router.rs index 405e9abe6f3..45440087454 100644 --- a/quickwit/quickwit-proto/src/codegen/quickwit/quickwit.ingest.router.rs +++ b/quickwit/quickwit-proto/src/codegen/quickwit/quickwit.ingest.router.rs @@ -606,9 +606,10 @@ for IngestRouterServiceGrpcServerAdapter { request: tonic::Request, ) -> Result, tonic::Status> { let auth_token = quickwit_auth::get_auth_token(request.metadata())?; - let req = request.into_inner(); - quickwit_auth::authorize(&req, &auth_token)?; - quickwit_auth::execute_with_authorization(auth_token, self.inner.0.ingest(req)) + quickwit_auth::execute_with_authorization( + auth_token, + self.inner.0.ingest(request.into_inner()), + ) .await .map(tonic::Response::new) .map_err(crate::error::grpc_error_to_grpc_status) diff --git a/quickwit/quickwit-proto/src/codegen/quickwit/quickwit.metastore.rs b/quickwit/quickwit-proto/src/codegen/quickwit/quickwit.metastore.rs index b923d5261f7..80ae0c04490 100644 --- a/quickwit/quickwit-proto/src/codegen/quickwit/quickwit.metastore.rs +++ b/quickwit/quickwit-proto/src/codegen/quickwit/quickwit.metastore.rs @@ -5358,11 +5358,9 @@ for MetastoreServiceGrpcServerAdapter { request: tonic::Request, ) -> Result, tonic::Status> { let auth_token = quickwit_auth::get_auth_token(request.metadata())?; - let req = request.into_inner(); - quickwit_auth::authorize(&req, &auth_token)?; quickwit_auth::execute_with_authorization( auth_token, - self.inner.0.create_index(req), + self.inner.0.create_index(request.into_inner()), ) .await .map(tonic::Response::new) @@ -5373,11 +5371,9 @@ for MetastoreServiceGrpcServerAdapter { request: tonic::Request, ) -> Result, tonic::Status> { let auth_token = quickwit_auth::get_auth_token(request.metadata())?; - let req = request.into_inner(); - quickwit_auth::authorize(&req, &auth_token)?; quickwit_auth::execute_with_authorization( auth_token, - self.inner.0.update_index(req), + self.inner.0.update_index(request.into_inner()), ) .await .map(tonic::Response::new) @@ -5388,11 +5384,9 @@ for MetastoreServiceGrpcServerAdapter { request: tonic::Request, ) -> Result, tonic::Status> { let auth_token = quickwit_auth::get_auth_token(request.metadata())?; - let req = request.into_inner(); - quickwit_auth::authorize(&req, &auth_token)?; quickwit_auth::execute_with_authorization( auth_token, - self.inner.0.index_metadata(req), + self.inner.0.index_metadata(request.into_inner()), ) .await .map(tonic::Response::new) @@ -5403,11 +5397,9 @@ for MetastoreServiceGrpcServerAdapter { request: tonic::Request, ) -> Result, tonic::Status> { let auth_token = quickwit_auth::get_auth_token(request.metadata())?; - let req = request.into_inner(); - quickwit_auth::authorize(&req, &auth_token)?; quickwit_auth::execute_with_authorization( auth_token, - self.inner.0.indexes_metadata(req), + self.inner.0.indexes_metadata(request.into_inner()), ) .await .map(tonic::Response::new) @@ -5418,11 +5410,9 @@ for MetastoreServiceGrpcServerAdapter { request: tonic::Request, ) -> Result, tonic::Status> { let auth_token = quickwit_auth::get_auth_token(request.metadata())?; - let req = request.into_inner(); - quickwit_auth::authorize(&req, &auth_token)?; quickwit_auth::execute_with_authorization( auth_token, - self.inner.0.list_indexes_metadata(req), + self.inner.0.list_indexes_metadata(request.into_inner()), ) .await .map(tonic::Response::new) @@ -5433,11 +5423,9 @@ for MetastoreServiceGrpcServerAdapter { request: tonic::Request, ) -> Result, tonic::Status> { let auth_token = quickwit_auth::get_auth_token(request.metadata())?; - let req = request.into_inner(); - quickwit_auth::authorize(&req, &auth_token)?; quickwit_auth::execute_with_authorization( auth_token, - self.inner.0.delete_index(req), + self.inner.0.delete_index(request.into_inner()), ) .await .map(tonic::Response::new) @@ -5451,11 +5439,9 @@ for MetastoreServiceGrpcServerAdapter { request: tonic::Request, ) -> Result, tonic::Status> { let auth_token = quickwit_auth::get_auth_token(request.metadata())?; - let req = request.into_inner(); - quickwit_auth::authorize(&req, &auth_token)?; quickwit_auth::execute_with_authorization( auth_token, - self.inner.0.list_splits(req), + self.inner.0.list_splits(request.into_inner()), ) .await .map(|stream| tonic::Response::new( @@ -5468,11 +5454,9 @@ for MetastoreServiceGrpcServerAdapter { request: tonic::Request, ) -> Result, tonic::Status> { let auth_token = quickwit_auth::get_auth_token(request.metadata())?; - let req = request.into_inner(); - quickwit_auth::authorize(&req, &auth_token)?; quickwit_auth::execute_with_authorization( auth_token, - self.inner.0.stage_splits(req), + self.inner.0.stage_splits(request.into_inner()), ) .await .map(tonic::Response::new) @@ -5483,11 +5467,9 @@ for MetastoreServiceGrpcServerAdapter { request: tonic::Request, ) -> Result, tonic::Status> { let auth_token = quickwit_auth::get_auth_token(request.metadata())?; - let req = request.into_inner(); - quickwit_auth::authorize(&req, &auth_token)?; quickwit_auth::execute_with_authorization( auth_token, - self.inner.0.publish_splits(req), + self.inner.0.publish_splits(request.into_inner()), ) .await .map(tonic::Response::new) @@ -5498,11 +5480,9 @@ for MetastoreServiceGrpcServerAdapter { request: tonic::Request, ) -> Result, tonic::Status> { let auth_token = quickwit_auth::get_auth_token(request.metadata())?; - let req = request.into_inner(); - quickwit_auth::authorize(&req, &auth_token)?; quickwit_auth::execute_with_authorization( auth_token, - self.inner.0.mark_splits_for_deletion(req), + self.inner.0.mark_splits_for_deletion(request.into_inner()), ) .await .map(tonic::Response::new) @@ -5513,11 +5493,9 @@ for MetastoreServiceGrpcServerAdapter { request: tonic::Request, ) -> Result, tonic::Status> { let auth_token = quickwit_auth::get_auth_token(request.metadata())?; - let req = request.into_inner(); - quickwit_auth::authorize(&req, &auth_token)?; quickwit_auth::execute_with_authorization( auth_token, - self.inner.0.delete_splits(req), + self.inner.0.delete_splits(request.into_inner()), ) .await .map(tonic::Response::new) @@ -5528,11 +5506,9 @@ for MetastoreServiceGrpcServerAdapter { request: tonic::Request, ) -> Result, tonic::Status> { let auth_token = quickwit_auth::get_auth_token(request.metadata())?; - let req = request.into_inner(); - quickwit_auth::authorize(&req, &auth_token)?; quickwit_auth::execute_with_authorization( auth_token, - self.inner.0.add_source(req), + self.inner.0.add_source(request.into_inner()), ) .await .map(tonic::Response::new) @@ -5543,11 +5519,9 @@ for MetastoreServiceGrpcServerAdapter { request: tonic::Request, ) -> Result, tonic::Status> { let auth_token = quickwit_auth::get_auth_token(request.metadata())?; - let req = request.into_inner(); - quickwit_auth::authorize(&req, &auth_token)?; quickwit_auth::execute_with_authorization( auth_token, - self.inner.0.toggle_source(req), + self.inner.0.toggle_source(request.into_inner()), ) .await .map(tonic::Response::new) @@ -5558,11 +5532,9 @@ for MetastoreServiceGrpcServerAdapter { request: tonic::Request, ) -> Result, tonic::Status> { let auth_token = quickwit_auth::get_auth_token(request.metadata())?; - let req = request.into_inner(); - quickwit_auth::authorize(&req, &auth_token)?; quickwit_auth::execute_with_authorization( auth_token, - self.inner.0.delete_source(req), + self.inner.0.delete_source(request.into_inner()), ) .await .map(tonic::Response::new) @@ -5573,11 +5545,9 @@ for MetastoreServiceGrpcServerAdapter { request: tonic::Request, ) -> Result, tonic::Status> { let auth_token = quickwit_auth::get_auth_token(request.metadata())?; - let req = request.into_inner(); - quickwit_auth::authorize(&req, &auth_token)?; quickwit_auth::execute_with_authorization( auth_token, - self.inner.0.reset_source_checkpoint(req), + self.inner.0.reset_source_checkpoint(request.into_inner()), ) .await .map(tonic::Response::new) @@ -5588,11 +5558,9 @@ for MetastoreServiceGrpcServerAdapter { request: tonic::Request, ) -> Result, tonic::Status> { let auth_token = quickwit_auth::get_auth_token(request.metadata())?; - let req = request.into_inner(); - quickwit_auth::authorize(&req, &auth_token)?; quickwit_auth::execute_with_authorization( auth_token, - self.inner.0.last_delete_opstamp(req), + self.inner.0.last_delete_opstamp(request.into_inner()), ) .await .map(tonic::Response::new) @@ -5603,11 +5571,9 @@ for MetastoreServiceGrpcServerAdapter { request: tonic::Request, ) -> Result, tonic::Status> { let auth_token = quickwit_auth::get_auth_token(request.metadata())?; - let req = request.into_inner(); - quickwit_auth::authorize(&req, &auth_token)?; quickwit_auth::execute_with_authorization( auth_token, - self.inner.0.create_delete_task(req), + self.inner.0.create_delete_task(request.into_inner()), ) .await .map(tonic::Response::new) @@ -5618,11 +5584,9 @@ for MetastoreServiceGrpcServerAdapter { request: tonic::Request, ) -> Result, tonic::Status> { let auth_token = quickwit_auth::get_auth_token(request.metadata())?; - let req = request.into_inner(); - quickwit_auth::authorize(&req, &auth_token)?; quickwit_auth::execute_with_authorization( auth_token, - self.inner.0.update_splits_delete_opstamp(req), + self.inner.0.update_splits_delete_opstamp(request.into_inner()), ) .await .map(tonic::Response::new) @@ -5633,11 +5597,9 @@ for MetastoreServiceGrpcServerAdapter { request: tonic::Request, ) -> Result, tonic::Status> { let auth_token = quickwit_auth::get_auth_token(request.metadata())?; - let req = request.into_inner(); - quickwit_auth::authorize(&req, &auth_token)?; quickwit_auth::execute_with_authorization( auth_token, - self.inner.0.list_delete_tasks(req), + self.inner.0.list_delete_tasks(request.into_inner()), ) .await .map(tonic::Response::new) @@ -5648,11 +5610,9 @@ for MetastoreServiceGrpcServerAdapter { request: tonic::Request, ) -> Result, tonic::Status> { let auth_token = quickwit_auth::get_auth_token(request.metadata())?; - let req = request.into_inner(); - quickwit_auth::authorize(&req, &auth_token)?; quickwit_auth::execute_with_authorization( auth_token, - self.inner.0.list_stale_splits(req), + self.inner.0.list_stale_splits(request.into_inner()), ) .await .map(tonic::Response::new) @@ -5663,11 +5623,9 @@ for MetastoreServiceGrpcServerAdapter { request: tonic::Request, ) -> Result, tonic::Status> { let auth_token = quickwit_auth::get_auth_token(request.metadata())?; - let req = request.into_inner(); - quickwit_auth::authorize(&req, &auth_token)?; quickwit_auth::execute_with_authorization( auth_token, - self.inner.0.open_shards(req), + self.inner.0.open_shards(request.into_inner()), ) .await .map(tonic::Response::new) @@ -5678,11 +5636,9 @@ for MetastoreServiceGrpcServerAdapter { request: tonic::Request, ) -> Result, tonic::Status> { let auth_token = quickwit_auth::get_auth_token(request.metadata())?; - let req = request.into_inner(); - quickwit_auth::authorize(&req, &auth_token)?; quickwit_auth::execute_with_authorization( auth_token, - self.inner.0.acquire_shards(req), + self.inner.0.acquire_shards(request.into_inner()), ) .await .map(tonic::Response::new) @@ -5693,11 +5649,9 @@ for MetastoreServiceGrpcServerAdapter { request: tonic::Request, ) -> Result, tonic::Status> { let auth_token = quickwit_auth::get_auth_token(request.metadata())?; - let req = request.into_inner(); - quickwit_auth::authorize(&req, &auth_token)?; quickwit_auth::execute_with_authorization( auth_token, - self.inner.0.delete_shards(req), + self.inner.0.delete_shards(request.into_inner()), ) .await .map(tonic::Response::new) @@ -5708,11 +5662,9 @@ for MetastoreServiceGrpcServerAdapter { request: tonic::Request, ) -> Result, tonic::Status> { let auth_token = quickwit_auth::get_auth_token(request.metadata())?; - let req = request.into_inner(); - quickwit_auth::authorize(&req, &auth_token)?; quickwit_auth::execute_with_authorization( auth_token, - self.inner.0.prune_shards(req), + self.inner.0.prune_shards(request.into_inner()), ) .await .map(tonic::Response::new) @@ -5723,11 +5675,9 @@ for MetastoreServiceGrpcServerAdapter { request: tonic::Request, ) -> Result, tonic::Status> { let auth_token = quickwit_auth::get_auth_token(request.metadata())?; - let req = request.into_inner(); - quickwit_auth::authorize(&req, &auth_token)?; quickwit_auth::execute_with_authorization( auth_token, - self.inner.0.list_shards(req), + self.inner.0.list_shards(request.into_inner()), ) .await .map(tonic::Response::new) @@ -5738,11 +5688,9 @@ for MetastoreServiceGrpcServerAdapter { request: tonic::Request, ) -> Result, tonic::Status> { let auth_token = quickwit_auth::get_auth_token(request.metadata())?; - let req = request.into_inner(); - quickwit_auth::authorize(&req, &auth_token)?; quickwit_auth::execute_with_authorization( auth_token, - self.inner.0.create_index_template(req), + self.inner.0.create_index_template(request.into_inner()), ) .await .map(tonic::Response::new) @@ -5753,11 +5701,9 @@ for MetastoreServiceGrpcServerAdapter { request: tonic::Request, ) -> Result, tonic::Status> { let auth_token = quickwit_auth::get_auth_token(request.metadata())?; - let req = request.into_inner(); - quickwit_auth::authorize(&req, &auth_token)?; quickwit_auth::execute_with_authorization( auth_token, - self.inner.0.get_index_template(req), + self.inner.0.get_index_template(request.into_inner()), ) .await .map(tonic::Response::new) @@ -5768,11 +5714,9 @@ for MetastoreServiceGrpcServerAdapter { request: tonic::Request, ) -> Result, tonic::Status> { let auth_token = quickwit_auth::get_auth_token(request.metadata())?; - let req = request.into_inner(); - quickwit_auth::authorize(&req, &auth_token)?; quickwit_auth::execute_with_authorization( auth_token, - self.inner.0.find_index_template_matches(req), + self.inner.0.find_index_template_matches(request.into_inner()), ) .await .map(tonic::Response::new) @@ -5783,11 +5727,9 @@ for MetastoreServiceGrpcServerAdapter { request: tonic::Request, ) -> Result, tonic::Status> { let auth_token = quickwit_auth::get_auth_token(request.metadata())?; - let req = request.into_inner(); - quickwit_auth::authorize(&req, &auth_token)?; quickwit_auth::execute_with_authorization( auth_token, - self.inner.0.list_index_templates(req), + self.inner.0.list_index_templates(request.into_inner()), ) .await .map(tonic::Response::new) @@ -5798,11 +5740,9 @@ for MetastoreServiceGrpcServerAdapter { request: tonic::Request, ) -> Result, tonic::Status> { let auth_token = quickwit_auth::get_auth_token(request.metadata())?; - let req = request.into_inner(); - quickwit_auth::authorize(&req, &auth_token)?; quickwit_auth::execute_with_authorization( auth_token, - self.inner.0.delete_index_templates(req), + self.inner.0.delete_index_templates(request.into_inner()), ) .await .map(tonic::Response::new) From 94b575a5d86274bdbcc5989e26420dacda89c0b2 Mon Sep 17 00:00:00 2001 From: Paul Masurel Date: Mon, 4 Nov 2024 11:06:57 +0900 Subject: [PATCH 4/6] renamed to authorization --- quickwit/Cargo.lock | 10 +- quickwit/Cargo.toml | 6 +- .../Cargo.toml | 2 +- .../src/authorization_layer.rs | 0 .../src/community.rs | 0 .../src/enterprise.rs | 0 .../src/lib.rs | 0 quickwit/quickwit-codegen/example/Cargo.toml | 4 +- .../example/src/authorization.rs | 10 +- .../example/src/codegen/hello.rs | 22 +- .../quickwit-codegen/example/src/error.rs | 2 +- quickwit/quickwit-codegen/src/codegen.rs | 8 +- quickwit/quickwit-ingest/Cargo.toml | 4 +- quickwit/quickwit-ingest/src/authorize.rs | 2 +- .../src/codegen/ingest_service.rs | 24 +- quickwit/quickwit-ingest/src/error.rs | 2 +- quickwit/quickwit-metastore/Cargo.toml | 2 +- quickwit/quickwit-metastore/src/error.rs | 2 +- quickwit/quickwit-proto/Cargo.toml | 4 +- quickwit/quickwit-proto/src/authorization.rs | 2 +- quickwit/quickwit-proto/src/cluster/mod.rs | 2 +- .../src/codegen/quickwit/quickwit.cluster.rs | 8 +- .../quickwit/quickwit.control_plane.rs | 72 ++++-- .../codegen/quickwit/quickwit.developer.rs | 8 +- .../src/codegen/quickwit/quickwit.indexing.rs | 8 +- .../quickwit/quickwit.ingest.ingester.rs | 70 +++-- .../quickwit/quickwit.ingest.router.rs | 8 +- .../codegen/quickwit/quickwit.metastore.rs | 240 +++++++++++------- .../quickwit-proto/src/control_plane/mod.rs | 2 +- quickwit/quickwit-proto/src/developer/mod.rs | 2 +- quickwit/quickwit-proto/src/error.rs | 2 +- quickwit/quickwit-proto/src/indexing/mod.rs | 2 +- quickwit/quickwit-proto/src/ingest/mod.rs | 2 +- quickwit/quickwit-proto/src/metastore/mod.rs | 2 +- 34 files changed, 323 insertions(+), 211 deletions(-) rename quickwit/{quickwit-auth => quickwit-authorize}/Cargo.toml (95%) rename quickwit/{quickwit-auth => quickwit-authorize}/src/authorization_layer.rs (100%) rename quickwit/{quickwit-auth => quickwit-authorize}/src/community.rs (100%) rename quickwit/{quickwit-auth => quickwit-authorize}/src/enterprise.rs (100%) rename quickwit/{quickwit-auth => quickwit-authorize}/src/lib.rs (100%) diff --git a/quickwit/Cargo.lock b/quickwit/Cargo.lock index 5521cdc4ebf..905e999110a 100644 --- a/quickwit/Cargo.lock +++ b/quickwit/Cargo.lock @@ -5948,7 +5948,7 @@ dependencies = [ ] [[package]] -name = "quickwit-auth" +name = "quickwit-authorize" version = "0.8.0" dependencies = [ "biscuit-auth", @@ -6089,7 +6089,7 @@ dependencies = [ "mockall", "prost 0.11.9", "quickwit-actors", - "quickwit-auth", + "quickwit-authorize", "quickwit-codegen", "quickwit-common", "quickwit-proto", @@ -6368,7 +6368,7 @@ dependencies = [ "once_cell", "prost 0.11.9", "quickwit-actors", - "quickwit-auth", + "quickwit-authorize", "quickwit-cluster", "quickwit-codegen", "quickwit-common", @@ -6563,7 +6563,7 @@ dependencies = [ "mockall", "once_cell", "ouroboros", - "quickwit-auth", + "quickwit-authorize", "quickwit-common", "quickwit-config", "quickwit-doc-mapper", @@ -6633,7 +6633,7 @@ dependencies = [ "prost-build", "prost-types 0.11.9", "quickwit-actors", - "quickwit-auth", + "quickwit-authorize", "quickwit-codegen", "quickwit-common", "sea-query", diff --git a/quickwit/Cargo.toml b/quickwit/Cargo.toml index 12bdd18eae4..c8878d3c515 100644 --- a/quickwit/Cargo.toml +++ b/quickwit/Cargo.toml @@ -2,7 +2,7 @@ resolver = "2" members = [ "quickwit-actors", - "quickwit-auth", + "quickwit-authorize", "quickwit-aws", "quickwit-cli", "quickwit-cluster", @@ -42,7 +42,7 @@ members = [ # from the default member to ease build/deps. default-members = [ "quickwit-actors", - "quickwit-auth", + "quickwit-authorize", "quickwit-aws", "quickwit-cli", "quickwit-cluster", @@ -305,7 +305,7 @@ opendal = { version = "0.44", default-features = false } reqsign = { version = "0.14", default-features = false } quickwit-actors = { path = "quickwit-actors" } -quickwit-auth = { path = "quickwit-auth" } +quickwit-authorize = { path = "quickwit-authorize" } quickwit-aws = { path = "quickwit-aws" } quickwit-cli = { path = "quickwit-cli" } quickwit-cluster = { path = "quickwit-cluster" } diff --git a/quickwit/quickwit-auth/Cargo.toml b/quickwit/quickwit-authorize/Cargo.toml similarity index 95% rename from quickwit/quickwit-auth/Cargo.toml rename to quickwit/quickwit-authorize/Cargo.toml index 3ffdef60696..4c3985fcff3 100644 --- a/quickwit/quickwit-auth/Cargo.toml +++ b/quickwit/quickwit-authorize/Cargo.toml @@ -1,5 +1,5 @@ [package] -name = "quickwit-auth" +name = "quickwit-authorize" version.workspace = true edition.workspace = true homepage.workspace = true diff --git a/quickwit/quickwit-auth/src/authorization_layer.rs b/quickwit/quickwit-authorize/src/authorization_layer.rs similarity index 100% rename from quickwit/quickwit-auth/src/authorization_layer.rs rename to quickwit/quickwit-authorize/src/authorization_layer.rs diff --git a/quickwit/quickwit-auth/src/community.rs b/quickwit/quickwit-authorize/src/community.rs similarity index 100% rename from quickwit/quickwit-auth/src/community.rs rename to quickwit/quickwit-authorize/src/community.rs diff --git a/quickwit/quickwit-auth/src/enterprise.rs b/quickwit/quickwit-authorize/src/enterprise.rs similarity index 100% rename from quickwit/quickwit-auth/src/enterprise.rs rename to quickwit/quickwit-authorize/src/enterprise.rs diff --git a/quickwit/quickwit-auth/src/lib.rs b/quickwit/quickwit-authorize/src/lib.rs similarity index 100% rename from quickwit/quickwit-auth/src/lib.rs rename to quickwit/quickwit-authorize/src/lib.rs diff --git a/quickwit/quickwit-codegen/example/Cargo.toml b/quickwit/quickwit-codegen/example/Cargo.toml index f678d0cadc2..b51d7456b5d 100644 --- a/quickwit/quickwit-codegen/example/Cargo.toml +++ b/quickwit/quickwit-codegen/example/Cargo.toml @@ -27,7 +27,7 @@ tower = { workspace = true } utoipa = { workspace = true } quickwit-actors = { workspace = true } -quickwit-auth = { workspace = true } +quickwit-authorize = { workspace = true } quickwit-common = { workspace = true } quickwit-proto = { workspace = true } @@ -41,4 +41,4 @@ quickwit-codegen = { workspace = true } [features] testsuite = ["mockall"] -enterprise = [ "quickwit-auth/enterprise" ] +enterprise = [ "quickwit-authorize/enterprise" ] diff --git a/quickwit/quickwit-codegen/example/src/authorization.rs b/quickwit/quickwit-codegen/example/src/authorization.rs index b58c6bea026..509fed82f0f 100644 --- a/quickwit/quickwit-codegen/example/src/authorization.rs +++ b/quickwit/quickwit-codegen/example/src/authorization.rs @@ -15,15 +15,15 @@ // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. -use quickwit_auth::{Authorization, AuthorizationError, AuthorizationToken, StreamAuthorization}; +use quickwit_authorize::{Authorization, AuthorizationError, AuthorizationToken, StreamAuthorization}; use crate::{GoodbyeRequest, HelloRequest, PingRequest}; impl Authorization for HelloRequest { fn attenuate( &self, - auth_token: quickwit_auth::AuthorizationToken, - ) -> Result { + auth_token: AuthorizationToken, + ) -> Result { Ok(auth_token) } } @@ -31,7 +31,7 @@ impl Authorization for HelloRequest { impl Authorization for GoodbyeRequest { fn attenuate( &self, - auth_token: quickwit_auth::AuthorizationToken, + auth_token: AuthorizationToken, ) -> Result { Ok(auth_token) } @@ -39,7 +39,7 @@ impl Authorization for GoodbyeRequest { impl StreamAuthorization for PingRequest { fn attenuate( - auth_token: quickwit_auth::AuthorizationToken, + auth_token: AuthorizationToken, ) -> Result { Ok(auth_token) } diff --git a/quickwit/quickwit-codegen/example/src/codegen/hello.rs b/quickwit/quickwit-codegen/example/src/codegen/hello.rs index c12d635e581..4eb3a2dc8c7 100644 --- a/quickwit/quickwit-codegen/example/src/codegen/hello.rs +++ b/quickwit/quickwit-codegen/example/src/codegen/hello.rs @@ -723,7 +723,9 @@ where T::Future: Send, { async fn hello(&self, request: HelloRequest) -> crate::HelloResult { - let tonic_request = quickwit_auth::build_tonic_request_with_auth_token(request)?; + let tonic_request = quickwit_authorize::build_tonic_request_with_auth_token( + request, + )?; self.inner .clone() .hello(tonic_request) @@ -738,7 +740,9 @@ where &self, request: GoodbyeRequest, ) -> crate::HelloResult { - let tonic_request = quickwit_auth::build_tonic_request_with_auth_token(request)?; + let tonic_request = quickwit_authorize::build_tonic_request_with_auth_token( + request, + )?; self.inner .clone() .goodbye(tonic_request) @@ -753,7 +757,7 @@ where &self, request: quickwit_common::ServiceStream, ) -> crate::HelloResult> { - let tonic_request = quickwit_auth::build_tonic_stream_request_with_auth_token( + let tonic_request = quickwit_authorize::build_tonic_stream_request_with_auth_token( request, )?; self.inner @@ -810,8 +814,8 @@ impl hello_grpc_server::HelloGrpc for HelloGrpcServerAdapter { &self, request: tonic::Request, ) -> Result, tonic::Status> { - let auth_token = quickwit_auth::get_auth_token(request.metadata())?; - quickwit_auth::execute_with_authorization( + let auth_token = quickwit_authorize::get_auth_token(request.metadata())?; + quickwit_authorize::execute_with_authorization( auth_token, self.inner.0.hello(request.into_inner()), ) @@ -823,8 +827,8 @@ impl hello_grpc_server::HelloGrpc for HelloGrpcServerAdapter { &self, request: tonic::Request, ) -> Result, tonic::Status> { - let auth_token = quickwit_auth::get_auth_token(request.metadata())?; - quickwit_auth::execute_with_authorization( + let auth_token = quickwit_authorize::get_auth_token(request.metadata())?; + quickwit_authorize::execute_with_authorization( auth_token, self.inner.0.goodbye(request.into_inner()), ) @@ -837,8 +841,8 @@ impl hello_grpc_server::HelloGrpc for HelloGrpcServerAdapter { &self, request: tonic::Request>, ) -> Result, tonic::Status> { - let auth_token = quickwit_auth::get_auth_token(request.metadata())?; - quickwit_auth::execute_with_authorization( + let auth_token = quickwit_authorize::get_auth_token(request.metadata())?; + quickwit_authorize::execute_with_authorization( auth_token, self .inner diff --git a/quickwit/quickwit-codegen/example/src/error.rs b/quickwit/quickwit-codegen/example/src/error.rs index 9d3a9dbde19..ec67efb3250 100644 --- a/quickwit/quickwit-codegen/example/src/error.rs +++ b/quickwit/quickwit-codegen/example/src/error.rs @@ -20,7 +20,7 @@ use std::fmt; use quickwit_actors::AskError; -use quickwit_auth::AuthorizationError; +use quickwit_authorize::AuthorizationError; use quickwit_proto::error::GrpcServiceError; pub use quickwit_proto::error::{grpc_error_to_grpc_status, grpc_status_to_service_error}; use quickwit_proto::{ServiceError, ServiceErrorCode}; diff --git a/quickwit/quickwit-codegen/src/codegen.rs b/quickwit/quickwit-codegen/src/codegen.rs index 361cd21189b..4143cafd15b 100644 --- a/quickwit/quickwit-codegen/src/codegen.rs +++ b/quickwit/quickwit-codegen/src/codegen.rs @@ -1170,7 +1170,7 @@ fn generate_grpc_client_adapter_methods(context: &CodegenContext) -> TokenStream let method = if syn_method.client_streaming { quote! { async fn #method_name(&self, request: #request_type) -> #result_type<#response_type> { - let tonic_request = quickwit_auth::build_tonic_stream_request_with_auth_token(request)?; + let tonic_request = quickwit_authorize::build_tonic_stream_request_with_auth_token(request)?; self.inner .clone() .#method_name(tonic_request) @@ -1182,7 +1182,7 @@ fn generate_grpc_client_adapter_methods(context: &CodegenContext) -> TokenStream } else { quote! { async fn #method_name(&self, request: #request_type) -> #result_type<#response_type> { - let tonic_request = quickwit_auth::build_tonic_request_with_auth_token(request)?; + let tonic_request = quickwit_authorize::build_tonic_request_with_auth_token(request)?; self.inner .clone() .#method_name(tonic_request) @@ -1273,8 +1273,8 @@ fn generate_grpc_server_adapter_methods(context: &CodegenContext) -> TokenStream #associated_type async fn #method_name(&self, request: tonic::Request<#request_type>) -> Result, tonic::Status> { - let auth_token = quickwit_auth::get_auth_token(request.metadata())?; - quickwit_auth::execute_with_authorization(auth_token, self.inner.0.#method_name(#method_arg)).await + let auth_token = quickwit_authorize::get_auth_token(request.metadata())?; + quickwit_authorize::execute_with_authorization(auth_token, self.inner.0.#method_name(#method_arg)).await .map(#into_response_type) .map_err(crate::error::grpc_error_to_grpc_status) } diff --git a/quickwit/quickwit-ingest/Cargo.toml b/quickwit/quickwit-ingest/Cargo.toml index 2fdb7195555..f1325278622 100644 --- a/quickwit/quickwit-ingest/Cargo.toml +++ b/quickwit/quickwit-ingest/Cargo.toml @@ -36,7 +36,7 @@ ulid = { workspace = true } utoipa = { workspace = true } quickwit-actors = { workspace = true } -quickwit-auth = { workspace = true } +quickwit-authorize = { workspace = true } quickwit-cluster = { workspace = true } quickwit-common = { workspace = true, features = ["testsuite"] } quickwit-config = { workspace = true } @@ -63,4 +63,4 @@ quickwit-codegen = { workspace = true } failpoints = ["fail/failpoints"] no-failpoints = [] testsuite = ["mockall"] -enterprise = ["quickwit-auth/enterprise"] +enterprise = ["quickwit-authorize/enterprise"] diff --git a/quickwit/quickwit-ingest/src/authorize.rs b/quickwit/quickwit-ingest/src/authorize.rs index 8b1b9287ce0..57ad079867a 100644 --- a/quickwit/quickwit-ingest/src/authorize.rs +++ b/quickwit/quickwit-ingest/src/authorize.rs @@ -15,7 +15,7 @@ // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. -use quickwit_auth::{Authorization, AuthorizationError, AuthorizationToken}; +use quickwit_authorize::::{Authorization, AuthorizationError, AuthorizationToken}; use crate::{FetchRequest, IngestRequest, TailRequest}; diff --git a/quickwit/quickwit-ingest/src/codegen/ingest_service.rs b/quickwit/quickwit-ingest/src/codegen/ingest_service.rs index 65992ccaa2e..8b7e4b4c7ea 100644 --- a/quickwit/quickwit-ingest/src/codegen/ingest_service.rs +++ b/quickwit/quickwit-ingest/src/codegen/ingest_service.rs @@ -819,7 +819,9 @@ where T::Future: Send, { async fn ingest(&self, request: IngestRequest) -> crate::Result { - let tonic_request = quickwit_auth::build_tonic_request_with_auth_token(request)?; + let tonic_request = quickwit_authorize::build_tonic_request_with_auth_token( + request, + )?; self.inner .clone() .ingest(tonic_request) @@ -831,7 +833,9 @@ where )) } async fn fetch(&self, request: FetchRequest) -> crate::Result { - let tonic_request = quickwit_auth::build_tonic_request_with_auth_token(request)?; + let tonic_request = quickwit_authorize::build_tonic_request_with_auth_token( + request, + )?; self.inner .clone() .fetch(tonic_request) @@ -843,7 +847,9 @@ where )) } async fn tail(&self, request: TailRequest) -> crate::Result { - let tonic_request = quickwit_auth::build_tonic_request_with_auth_token(request)?; + let tonic_request = quickwit_authorize::build_tonic_request_with_auth_token( + request, + )?; self.inner .clone() .tail(tonic_request) @@ -875,8 +881,8 @@ impl ingest_service_grpc_server::IngestServiceGrpc for IngestServiceGrpcServerAd &self, request: tonic::Request, ) -> Result, tonic::Status> { - let auth_token = quickwit_auth::get_auth_token(request.metadata())?; - quickwit_auth::execute_with_authorization( + let auth_token = quickwit_authorize::get_auth_token(request.metadata())?; + quickwit_authorize::execute_with_authorization( auth_token, self.inner.0.ingest(request.into_inner()), ) @@ -888,8 +894,8 @@ impl ingest_service_grpc_server::IngestServiceGrpc for IngestServiceGrpcServerAd &self, request: tonic::Request, ) -> Result, tonic::Status> { - let auth_token = quickwit_auth::get_auth_token(request.metadata())?; - quickwit_auth::execute_with_authorization( + let auth_token = quickwit_authorize::get_auth_token(request.metadata())?; + quickwit_authorize::execute_with_authorization( auth_token, self.inner.0.fetch(request.into_inner()), ) @@ -901,8 +907,8 @@ impl ingest_service_grpc_server::IngestServiceGrpc for IngestServiceGrpcServerAd &self, request: tonic::Request, ) -> Result, tonic::Status> { - let auth_token = quickwit_auth::get_auth_token(request.metadata())?; - quickwit_auth::execute_with_authorization( + let auth_token = quickwit_authorize::get_auth_token(request.metadata())?; + quickwit_authorize::execute_with_authorization( auth_token, self.inner.0.tail(request.into_inner()), ) diff --git a/quickwit/quickwit-ingest/src/error.rs b/quickwit/quickwit-ingest/src/error.rs index 0b99ba27c95..c951bdd6380 100644 --- a/quickwit/quickwit-ingest/src/error.rs +++ b/quickwit/quickwit-ingest/src/error.rs @@ -21,7 +21,7 @@ use std::io; use mrecordlog::error::*; use quickwit_actors::AskError; -use quickwit_auth::AuthorizationError; +use quickwit_authorize::AuthorizationError; use quickwit_common::rate_limited_error; use quickwit_common::tower::BufferError; pub(crate) use quickwit_proto::error::{grpc_error_to_grpc_status, grpc_status_to_service_error}; diff --git a/quickwit/quickwit-metastore/Cargo.toml b/quickwit/quickwit-metastore/Cargo.toml index 4e4c7ec98aa..82aa67af806 100644 --- a/quickwit/quickwit-metastore/Cargo.toml +++ b/quickwit/quickwit-metastore/Cargo.toml @@ -39,7 +39,7 @@ tracing = { workspace = true } ulid = { workspace = true, features = ["serde"] } utoipa = { workspace = true } -quickwit-auth = { workspace = true } +quickwit-authorize = { workspace = true } quickwit-common = { workspace = true } quickwit-config = { workspace = true } quickwit-doc-mapper = { workspace = true } diff --git a/quickwit/quickwit-metastore/src/error.rs b/quickwit/quickwit-metastore/src/error.rs index 43c7f4b6ec9..2f317d695b7 100644 --- a/quickwit/quickwit-metastore/src/error.rs +++ b/quickwit/quickwit-metastore/src/error.rs @@ -42,5 +42,5 @@ pub enum MetastoreResolverError { /// The requested operation is not authorized. #[error("unauthorized: `{0}`")] - Unauthorized(#[from] quickwit_auth::AuthorizationError), + Unauthorized(#[from] quickwit_authorize::AuthorizationError), } diff --git a/quickwit/quickwit-proto/Cargo.toml b/quickwit/quickwit-proto/Cargo.toml index 6f5aedb6724..e76a7a539af 100644 --- a/quickwit/quickwit-proto/Cargo.toml +++ b/quickwit/quickwit-proto/Cargo.toml @@ -36,7 +36,7 @@ utoipa = { workspace = true } zstd = { workspace = true } quickwit-actors = { workspace = true } -quickwit-auth = { workspace = true } +quickwit-authorize = { workspace = true } quickwit-common = { workspace = true } [dev-dependencies] @@ -53,4 +53,4 @@ quickwit-codegen = { workspace = true } [features] postgres = ["sea-query", "sqlx"] testsuite = ["mockall", "futures"] -enterprise = [ "quickwit-auth/enterprise"] +enterprise = [ "quickwit-authorize/enterprise"] diff --git a/quickwit/quickwit-proto/src/authorization.rs b/quickwit/quickwit-proto/src/authorization.rs index a7887ab339d..54882b7cfbc 100644 --- a/quickwit/quickwit-proto/src/authorization.rs +++ b/quickwit/quickwit-proto/src/authorization.rs @@ -2,7 +2,7 @@ use std::time::{Duration, SystemTime}; use biscuit_auth::builder_ext::BuilderExt; use biscuit_auth::macros::*; -use quickwit_auth::{Authorization, AuthorizationError, AuthorizationToken, StreamAuthorization}; +use quickwit_authorize::::{Authorization, AuthorizationError, AuthorizationToken, StreamAuthorization}; use crate::cluster::FetchClusterStateRequest; use crate::control_plane::{AdviseResetShardsRequest, GetOrCreateOpenShardsRequest}; diff --git a/quickwit/quickwit-proto/src/cluster/mod.rs b/quickwit/quickwit-proto/src/cluster/mod.rs index 7f0a25ecf7a..4bd227c8e1e 100644 --- a/quickwit/quickwit-proto/src/cluster/mod.rs +++ b/quickwit/quickwit-proto/src/cluster/mod.rs @@ -40,7 +40,7 @@ pub enum ClusterError { #[error("service unavailable: {0}")] Unavailable(String), #[error("unauthorized: {0}")] - Unauthorized(#[from] quickwit_auth::AuthorizationError), + Unauthorized(#[from] quickwit_authorize::AuthorizationError), } impl ServiceError for ClusterError { diff --git a/quickwit/quickwit-proto/src/codegen/quickwit/quickwit.cluster.rs b/quickwit/quickwit-proto/src/codegen/quickwit/quickwit.cluster.rs index a7a4e2388d0..28762ff59e5 100644 --- a/quickwit/quickwit-proto/src/codegen/quickwit/quickwit.cluster.rs +++ b/quickwit/quickwit-proto/src/codegen/quickwit/quickwit.cluster.rs @@ -510,7 +510,9 @@ where &self, request: FetchClusterStateRequest, ) -> crate::cluster::ClusterResult { - let tonic_request = quickwit_auth::build_tonic_request_with_auth_token(request)?; + let tonic_request = quickwit_authorize::build_tonic_request_with_auth_token( + request, + )?; self.inner .clone() .fetch_cluster_state(tonic_request) @@ -543,8 +545,8 @@ for ClusterServiceGrpcServerAdapter { &self, request: tonic::Request, ) -> Result, tonic::Status> { - let auth_token = quickwit_auth::get_auth_token(request.metadata())?; - quickwit_auth::execute_with_authorization( + let auth_token = quickwit_authorize::get_auth_token(request.metadata())?; + quickwit_authorize::execute_with_authorization( auth_token, self.inner.0.fetch_cluster_state(request.into_inner()), ) diff --git a/quickwit/quickwit-proto/src/codegen/quickwit/quickwit.control_plane.rs b/quickwit/quickwit-proto/src/codegen/quickwit/quickwit.control_plane.rs index b6449a8bd42..f1ddb3925fa 100644 --- a/quickwit/quickwit-proto/src/codegen/quickwit/quickwit.control_plane.rs +++ b/quickwit/quickwit-proto/src/codegen/quickwit/quickwit.control_plane.rs @@ -1633,7 +1633,9 @@ where ) -> crate::control_plane::ControlPlaneResult< super::metastore::CreateIndexResponse, > { - let tonic_request = quickwit_auth::build_tonic_request_with_auth_token(request)?; + let tonic_request = quickwit_authorize::build_tonic_request_with_auth_token( + request, + )?; self.inner .clone() .create_index(tonic_request) @@ -1650,7 +1652,9 @@ where ) -> crate::control_plane::ControlPlaneResult< super::metastore::IndexMetadataResponse, > { - let tonic_request = quickwit_auth::build_tonic_request_with_auth_token(request)?; + let tonic_request = quickwit_authorize::build_tonic_request_with_auth_token( + request, + )?; self.inner .clone() .update_index(tonic_request) @@ -1665,7 +1669,9 @@ where &self, request: super::metastore::DeleteIndexRequest, ) -> crate::control_plane::ControlPlaneResult { - let tonic_request = quickwit_auth::build_tonic_request_with_auth_token(request)?; + let tonic_request = quickwit_authorize::build_tonic_request_with_auth_token( + request, + )?; self.inner .clone() .delete_index(tonic_request) @@ -1680,7 +1686,9 @@ where &self, request: super::metastore::AddSourceRequest, ) -> crate::control_plane::ControlPlaneResult { - let tonic_request = quickwit_auth::build_tonic_request_with_auth_token(request)?; + let tonic_request = quickwit_authorize::build_tonic_request_with_auth_token( + request, + )?; self.inner .clone() .add_source(tonic_request) @@ -1695,7 +1703,9 @@ where &self, request: super::metastore::ToggleSourceRequest, ) -> crate::control_plane::ControlPlaneResult { - let tonic_request = quickwit_auth::build_tonic_request_with_auth_token(request)?; + let tonic_request = quickwit_authorize::build_tonic_request_with_auth_token( + request, + )?; self.inner .clone() .toggle_source(tonic_request) @@ -1710,7 +1720,9 @@ where &self, request: super::metastore::DeleteSourceRequest, ) -> crate::control_plane::ControlPlaneResult { - let tonic_request = quickwit_auth::build_tonic_request_with_auth_token(request)?; + let tonic_request = quickwit_authorize::build_tonic_request_with_auth_token( + request, + )?; self.inner .clone() .delete_source(tonic_request) @@ -1725,7 +1737,9 @@ where &self, request: GetOrCreateOpenShardsRequest, ) -> crate::control_plane::ControlPlaneResult { - let tonic_request = quickwit_auth::build_tonic_request_with_auth_token(request)?; + let tonic_request = quickwit_authorize::build_tonic_request_with_auth_token( + request, + )?; self.inner .clone() .get_or_create_open_shards(tonic_request) @@ -1740,7 +1754,9 @@ where &self, request: AdviseResetShardsRequest, ) -> crate::control_plane::ControlPlaneResult { - let tonic_request = quickwit_auth::build_tonic_request_with_auth_token(request)?; + let tonic_request = quickwit_authorize::build_tonic_request_with_auth_token( + request, + )?; self.inner .clone() .advise_reset_shards(tonic_request) @@ -1755,7 +1771,9 @@ where &self, request: super::metastore::PruneShardsRequest, ) -> crate::control_plane::ControlPlaneResult { - let tonic_request = quickwit_auth::build_tonic_request_with_auth_token(request)?; + let tonic_request = quickwit_authorize::build_tonic_request_with_auth_token( + request, + )?; self.inner .clone() .prune_shards(tonic_request) @@ -1788,8 +1806,8 @@ for ControlPlaneServiceGrpcServerAdapter { &self, request: tonic::Request, ) -> Result, tonic::Status> { - let auth_token = quickwit_auth::get_auth_token(request.metadata())?; - quickwit_auth::execute_with_authorization( + let auth_token = quickwit_authorize::get_auth_token(request.metadata())?; + quickwit_authorize::execute_with_authorization( auth_token, self.inner.0.create_index(request.into_inner()), ) @@ -1804,8 +1822,8 @@ for ControlPlaneServiceGrpcServerAdapter { tonic::Response, tonic::Status, > { - let auth_token = quickwit_auth::get_auth_token(request.metadata())?; - quickwit_auth::execute_with_authorization( + let auth_token = quickwit_authorize::get_auth_token(request.metadata())?; + quickwit_authorize::execute_with_authorization( auth_token, self.inner.0.update_index(request.into_inner()), ) @@ -1817,8 +1835,8 @@ for ControlPlaneServiceGrpcServerAdapter { &self, request: tonic::Request, ) -> Result, tonic::Status> { - let auth_token = quickwit_auth::get_auth_token(request.metadata())?; - quickwit_auth::execute_with_authorization( + let auth_token = quickwit_authorize::get_auth_token(request.metadata())?; + quickwit_authorize::execute_with_authorization( auth_token, self.inner.0.delete_index(request.into_inner()), ) @@ -1830,8 +1848,8 @@ for ControlPlaneServiceGrpcServerAdapter { &self, request: tonic::Request, ) -> Result, tonic::Status> { - let auth_token = quickwit_auth::get_auth_token(request.metadata())?; - quickwit_auth::execute_with_authorization( + let auth_token = quickwit_authorize::get_auth_token(request.metadata())?; + quickwit_authorize::execute_with_authorization( auth_token, self.inner.0.add_source(request.into_inner()), ) @@ -1843,8 +1861,8 @@ for ControlPlaneServiceGrpcServerAdapter { &self, request: tonic::Request, ) -> Result, tonic::Status> { - let auth_token = quickwit_auth::get_auth_token(request.metadata())?; - quickwit_auth::execute_with_authorization( + let auth_token = quickwit_authorize::get_auth_token(request.metadata())?; + quickwit_authorize::execute_with_authorization( auth_token, self.inner.0.toggle_source(request.into_inner()), ) @@ -1856,8 +1874,8 @@ for ControlPlaneServiceGrpcServerAdapter { &self, request: tonic::Request, ) -> Result, tonic::Status> { - let auth_token = quickwit_auth::get_auth_token(request.metadata())?; - quickwit_auth::execute_with_authorization( + let auth_token = quickwit_authorize::get_auth_token(request.metadata())?; + quickwit_authorize::execute_with_authorization( auth_token, self.inner.0.delete_source(request.into_inner()), ) @@ -1869,8 +1887,8 @@ for ControlPlaneServiceGrpcServerAdapter { &self, request: tonic::Request, ) -> Result, tonic::Status> { - let auth_token = quickwit_auth::get_auth_token(request.metadata())?; - quickwit_auth::execute_with_authorization( + let auth_token = quickwit_authorize::get_auth_token(request.metadata())?; + quickwit_authorize::execute_with_authorization( auth_token, self.inner.0.get_or_create_open_shards(request.into_inner()), ) @@ -1882,8 +1900,8 @@ for ControlPlaneServiceGrpcServerAdapter { &self, request: tonic::Request, ) -> Result, tonic::Status> { - let auth_token = quickwit_auth::get_auth_token(request.metadata())?; - quickwit_auth::execute_with_authorization( + let auth_token = quickwit_authorize::get_auth_token(request.metadata())?; + quickwit_authorize::execute_with_authorization( auth_token, self.inner.0.advise_reset_shards(request.into_inner()), ) @@ -1895,8 +1913,8 @@ for ControlPlaneServiceGrpcServerAdapter { &self, request: tonic::Request, ) -> Result, tonic::Status> { - let auth_token = quickwit_auth::get_auth_token(request.metadata())?; - quickwit_auth::execute_with_authorization( + let auth_token = quickwit_authorize::get_auth_token(request.metadata())?; + quickwit_authorize::execute_with_authorization( auth_token, self.inner.0.prune_shards(request.into_inner()), ) diff --git a/quickwit/quickwit-proto/src/codegen/quickwit/quickwit.developer.rs b/quickwit/quickwit-proto/src/codegen/quickwit/quickwit.developer.rs index 1a98a47df7b..5d99aaa7532 100644 --- a/quickwit/quickwit-proto/src/codegen/quickwit/quickwit.developer.rs +++ b/quickwit/quickwit-proto/src/codegen/quickwit/quickwit.developer.rs @@ -446,7 +446,9 @@ where &self, request: GetDebugInfoRequest, ) -> crate::developer::DeveloperResult { - let tonic_request = quickwit_auth::build_tonic_request_with_auth_token(request)?; + let tonic_request = quickwit_authorize::build_tonic_request_with_auth_token( + request, + )?; self.inner .clone() .get_debug_info(tonic_request) @@ -479,8 +481,8 @@ for DeveloperServiceGrpcServerAdapter { &self, request: tonic::Request, ) -> Result, tonic::Status> { - let auth_token = quickwit_auth::get_auth_token(request.metadata())?; - quickwit_auth::execute_with_authorization( + let auth_token = quickwit_authorize::get_auth_token(request.metadata())?; + quickwit_authorize::execute_with_authorization( auth_token, self.inner.0.get_debug_info(request.into_inner()), ) diff --git a/quickwit/quickwit-proto/src/codegen/quickwit/quickwit.indexing.rs b/quickwit/quickwit-proto/src/codegen/quickwit/quickwit.indexing.rs index 793f4bffa72..46c66feec09 100644 --- a/quickwit/quickwit-proto/src/codegen/quickwit/quickwit.indexing.rs +++ b/quickwit/quickwit-proto/src/codegen/quickwit/quickwit.indexing.rs @@ -459,7 +459,9 @@ where &self, request: ApplyIndexingPlanRequest, ) -> crate::indexing::IndexingResult { - let tonic_request = quickwit_auth::build_tonic_request_with_auth_token(request)?; + let tonic_request = quickwit_authorize::build_tonic_request_with_auth_token( + request, + )?; self.inner .clone() .apply_indexing_plan(tonic_request) @@ -492,8 +494,8 @@ for IndexingServiceGrpcServerAdapter { &self, request: tonic::Request, ) -> Result, tonic::Status> { - let auth_token = quickwit_auth::get_auth_token(request.metadata())?; - quickwit_auth::execute_with_authorization( + let auth_token = quickwit_authorize::get_auth_token(request.metadata())?; + quickwit_authorize::execute_with_authorization( auth_token, self.inner.0.apply_indexing_plan(request.into_inner()), ) diff --git a/quickwit/quickwit-proto/src/codegen/quickwit/quickwit.ingest.ingester.rs b/quickwit/quickwit-proto/src/codegen/quickwit/quickwit.ingest.ingester.rs index bc5ae585cdf..1d8294510ec 100644 --- a/quickwit/quickwit-proto/src/codegen/quickwit/quickwit.ingest.ingester.rs +++ b/quickwit/quickwit-proto/src/codegen/quickwit/quickwit.ingest.ingester.rs @@ -2044,7 +2044,9 @@ where &self, request: PersistRequest, ) -> crate::ingest::IngestV2Result { - let tonic_request = quickwit_auth::build_tonic_request_with_auth_token(request)?; + let tonic_request = quickwit_authorize::build_tonic_request_with_auth_token( + request, + )?; self.inner .clone() .persist(tonic_request) @@ -2059,7 +2061,7 @@ where &self, request: quickwit_common::ServiceStream, ) -> crate::ingest::IngestV2Result> { - let tonic_request = quickwit_auth::build_tonic_stream_request_with_auth_token( + let tonic_request = quickwit_authorize::build_tonic_stream_request_with_auth_token( request, )?; self.inner @@ -2084,7 +2086,9 @@ where &self, request: OpenFetchStreamRequest, ) -> crate::ingest::IngestV2Result> { - let tonic_request = quickwit_auth::build_tonic_request_with_auth_token(request)?; + let tonic_request = quickwit_authorize::build_tonic_request_with_auth_token( + request, + )?; self.inner .clone() .open_fetch_stream(tonic_request) @@ -2107,7 +2111,9 @@ where &self, request: OpenObservationStreamRequest, ) -> crate::ingest::IngestV2Result> { - let tonic_request = quickwit_auth::build_tonic_request_with_auth_token(request)?; + let tonic_request = quickwit_authorize::build_tonic_request_with_auth_token( + request, + )?; self.inner .clone() .open_observation_stream(tonic_request) @@ -2130,7 +2136,9 @@ where &self, request: InitShardsRequest, ) -> crate::ingest::IngestV2Result { - let tonic_request = quickwit_auth::build_tonic_request_with_auth_token(request)?; + let tonic_request = quickwit_authorize::build_tonic_request_with_auth_token( + request, + )?; self.inner .clone() .init_shards(tonic_request) @@ -2145,7 +2153,9 @@ where &self, request: RetainShardsRequest, ) -> crate::ingest::IngestV2Result { - let tonic_request = quickwit_auth::build_tonic_request_with_auth_token(request)?; + let tonic_request = quickwit_authorize::build_tonic_request_with_auth_token( + request, + )?; self.inner .clone() .retain_shards(tonic_request) @@ -2160,7 +2170,9 @@ where &self, request: TruncateShardsRequest, ) -> crate::ingest::IngestV2Result { - let tonic_request = quickwit_auth::build_tonic_request_with_auth_token(request)?; + let tonic_request = quickwit_authorize::build_tonic_request_with_auth_token( + request, + )?; self.inner .clone() .truncate_shards(tonic_request) @@ -2175,7 +2187,9 @@ where &self, request: CloseShardsRequest, ) -> crate::ingest::IngestV2Result { - let tonic_request = quickwit_auth::build_tonic_request_with_auth_token(request)?; + let tonic_request = quickwit_authorize::build_tonic_request_with_auth_token( + request, + )?; self.inner .clone() .close_shards(tonic_request) @@ -2190,7 +2204,9 @@ where &self, request: DecommissionRequest, ) -> crate::ingest::IngestV2Result { - let tonic_request = quickwit_auth::build_tonic_request_with_auth_token(request)?; + let tonic_request = quickwit_authorize::build_tonic_request_with_auth_token( + request, + )?; self.inner .clone() .decommission(tonic_request) @@ -2223,8 +2239,8 @@ for IngesterServiceGrpcServerAdapter { &self, request: tonic::Request, ) -> Result, tonic::Status> { - let auth_token = quickwit_auth::get_auth_token(request.metadata())?; - quickwit_auth::execute_with_authorization( + let auth_token = quickwit_authorize::get_auth_token(request.metadata())?; + quickwit_authorize::execute_with_authorization( auth_token, self.inner.0.persist(request.into_inner()), ) @@ -2239,8 +2255,8 @@ for IngesterServiceGrpcServerAdapter { &self, request: tonic::Request>, ) -> Result, tonic::Status> { - let auth_token = quickwit_auth::get_auth_token(request.metadata())?; - quickwit_auth::execute_with_authorization( + let auth_token = quickwit_authorize::get_auth_token(request.metadata())?; + quickwit_authorize::execute_with_authorization( auth_token, self .inner @@ -2263,8 +2279,8 @@ for IngesterServiceGrpcServerAdapter { &self, request: tonic::Request, ) -> Result, tonic::Status> { - let auth_token = quickwit_auth::get_auth_token(request.metadata())?; - quickwit_auth::execute_with_authorization( + let auth_token = quickwit_authorize::get_auth_token(request.metadata())?; + quickwit_authorize::execute_with_authorization( auth_token, self.inner.0.open_fetch_stream(request.into_inner()), ) @@ -2281,8 +2297,8 @@ for IngesterServiceGrpcServerAdapter { &self, request: tonic::Request, ) -> Result, tonic::Status> { - let auth_token = quickwit_auth::get_auth_token(request.metadata())?; - quickwit_auth::execute_with_authorization( + let auth_token = quickwit_authorize::get_auth_token(request.metadata())?; + quickwit_authorize::execute_with_authorization( auth_token, self.inner.0.open_observation_stream(request.into_inner()), ) @@ -2296,8 +2312,8 @@ for IngesterServiceGrpcServerAdapter { &self, request: tonic::Request, ) -> Result, tonic::Status> { - let auth_token = quickwit_auth::get_auth_token(request.metadata())?; - quickwit_auth::execute_with_authorization( + let auth_token = quickwit_authorize::get_auth_token(request.metadata())?; + quickwit_authorize::execute_with_authorization( auth_token, self.inner.0.init_shards(request.into_inner()), ) @@ -2309,8 +2325,8 @@ for IngesterServiceGrpcServerAdapter { &self, request: tonic::Request, ) -> Result, tonic::Status> { - let auth_token = quickwit_auth::get_auth_token(request.metadata())?; - quickwit_auth::execute_with_authorization( + let auth_token = quickwit_authorize::get_auth_token(request.metadata())?; + quickwit_authorize::execute_with_authorization( auth_token, self.inner.0.retain_shards(request.into_inner()), ) @@ -2322,8 +2338,8 @@ for IngesterServiceGrpcServerAdapter { &self, request: tonic::Request, ) -> Result, tonic::Status> { - let auth_token = quickwit_auth::get_auth_token(request.metadata())?; - quickwit_auth::execute_with_authorization( + let auth_token = quickwit_authorize::get_auth_token(request.metadata())?; + quickwit_authorize::execute_with_authorization( auth_token, self.inner.0.truncate_shards(request.into_inner()), ) @@ -2335,8 +2351,8 @@ for IngesterServiceGrpcServerAdapter { &self, request: tonic::Request, ) -> Result, tonic::Status> { - let auth_token = quickwit_auth::get_auth_token(request.metadata())?; - quickwit_auth::execute_with_authorization( + let auth_token = quickwit_authorize::get_auth_token(request.metadata())?; + quickwit_authorize::execute_with_authorization( auth_token, self.inner.0.close_shards(request.into_inner()), ) @@ -2348,8 +2364,8 @@ for IngesterServiceGrpcServerAdapter { &self, request: tonic::Request, ) -> Result, tonic::Status> { - let auth_token = quickwit_auth::get_auth_token(request.metadata())?; - quickwit_auth::execute_with_authorization( + let auth_token = quickwit_authorize::get_auth_token(request.metadata())?; + quickwit_authorize::execute_with_authorization( auth_token, self.inner.0.decommission(request.into_inner()), ) diff --git a/quickwit/quickwit-proto/src/codegen/quickwit/quickwit.ingest.router.rs b/quickwit/quickwit-proto/src/codegen/quickwit/quickwit.ingest.router.rs index 45440087454..3c99756ac7f 100644 --- a/quickwit/quickwit-proto/src/codegen/quickwit/quickwit.ingest.router.rs +++ b/quickwit/quickwit-proto/src/codegen/quickwit/quickwit.ingest.router.rs @@ -572,7 +572,9 @@ where &self, request: IngestRequestV2, ) -> crate::ingest::IngestV2Result { - let tonic_request = quickwit_auth::build_tonic_request_with_auth_token(request)?; + let tonic_request = quickwit_authorize::build_tonic_request_with_auth_token( + request, + )?; self.inner .clone() .ingest(tonic_request) @@ -605,8 +607,8 @@ for IngestRouterServiceGrpcServerAdapter { &self, request: tonic::Request, ) -> Result, tonic::Status> { - let auth_token = quickwit_auth::get_auth_token(request.metadata())?; - quickwit_auth::execute_with_authorization( + let auth_token = quickwit_authorize::get_auth_token(request.metadata())?; + quickwit_authorize::execute_with_authorization( auth_token, self.inner.0.ingest(request.into_inner()), ) diff --git a/quickwit/quickwit-proto/src/codegen/quickwit/quickwit.metastore.rs b/quickwit/quickwit-proto/src/codegen/quickwit/quickwit.metastore.rs index 80ae0c04490..9b32e28bd91 100644 --- a/quickwit/quickwit-proto/src/codegen/quickwit/quickwit.metastore.rs +++ b/quickwit/quickwit-proto/src/codegen/quickwit/quickwit.metastore.rs @@ -4866,7 +4866,9 @@ where &self, request: CreateIndexRequest, ) -> crate::metastore::MetastoreResult { - let tonic_request = quickwit_auth::build_tonic_request_with_auth_token(request)?; + let tonic_request = quickwit_authorize::build_tonic_request_with_auth_token( + request, + )?; self.inner .clone() .create_index(tonic_request) @@ -4881,7 +4883,9 @@ where &self, request: UpdateIndexRequest, ) -> crate::metastore::MetastoreResult { - let tonic_request = quickwit_auth::build_tonic_request_with_auth_token(request)?; + let tonic_request = quickwit_authorize::build_tonic_request_with_auth_token( + request, + )?; self.inner .clone() .update_index(tonic_request) @@ -4896,7 +4900,9 @@ where &self, request: IndexMetadataRequest, ) -> crate::metastore::MetastoreResult { - let tonic_request = quickwit_auth::build_tonic_request_with_auth_token(request)?; + let tonic_request = quickwit_authorize::build_tonic_request_with_auth_token( + request, + )?; self.inner .clone() .index_metadata(tonic_request) @@ -4911,7 +4917,9 @@ where &self, request: IndexesMetadataRequest, ) -> crate::metastore::MetastoreResult { - let tonic_request = quickwit_auth::build_tonic_request_with_auth_token(request)?; + let tonic_request = quickwit_authorize::build_tonic_request_with_auth_token( + request, + )?; self.inner .clone() .indexes_metadata(tonic_request) @@ -4926,7 +4934,9 @@ where &self, request: ListIndexesMetadataRequest, ) -> crate::metastore::MetastoreResult { - let tonic_request = quickwit_auth::build_tonic_request_with_auth_token(request)?; + let tonic_request = quickwit_authorize::build_tonic_request_with_auth_token( + request, + )?; self.inner .clone() .list_indexes_metadata(tonic_request) @@ -4941,7 +4951,9 @@ where &self, request: DeleteIndexRequest, ) -> crate::metastore::MetastoreResult { - let tonic_request = quickwit_auth::build_tonic_request_with_auth_token(request)?; + let tonic_request = quickwit_authorize::build_tonic_request_with_auth_token( + request, + )?; self.inner .clone() .delete_index(tonic_request) @@ -4956,7 +4968,9 @@ where &self, request: ListSplitsRequest, ) -> crate::metastore::MetastoreResult> { - let tonic_request = quickwit_auth::build_tonic_request_with_auth_token(request)?; + let tonic_request = quickwit_authorize::build_tonic_request_with_auth_token( + request, + )?; self.inner .clone() .list_splits(tonic_request) @@ -4979,7 +4993,9 @@ where &self, request: StageSplitsRequest, ) -> crate::metastore::MetastoreResult { - let tonic_request = quickwit_auth::build_tonic_request_with_auth_token(request)?; + let tonic_request = quickwit_authorize::build_tonic_request_with_auth_token( + request, + )?; self.inner .clone() .stage_splits(tonic_request) @@ -4994,7 +5010,9 @@ where &self, request: PublishSplitsRequest, ) -> crate::metastore::MetastoreResult { - let tonic_request = quickwit_auth::build_tonic_request_with_auth_token(request)?; + let tonic_request = quickwit_authorize::build_tonic_request_with_auth_token( + request, + )?; self.inner .clone() .publish_splits(tonic_request) @@ -5009,7 +5027,9 @@ where &self, request: MarkSplitsForDeletionRequest, ) -> crate::metastore::MetastoreResult { - let tonic_request = quickwit_auth::build_tonic_request_with_auth_token(request)?; + let tonic_request = quickwit_authorize::build_tonic_request_with_auth_token( + request, + )?; self.inner .clone() .mark_splits_for_deletion(tonic_request) @@ -5024,7 +5044,9 @@ where &self, request: DeleteSplitsRequest, ) -> crate::metastore::MetastoreResult { - let tonic_request = quickwit_auth::build_tonic_request_with_auth_token(request)?; + let tonic_request = quickwit_authorize::build_tonic_request_with_auth_token( + request, + )?; self.inner .clone() .delete_splits(tonic_request) @@ -5039,7 +5061,9 @@ where &self, request: AddSourceRequest, ) -> crate::metastore::MetastoreResult { - let tonic_request = quickwit_auth::build_tonic_request_with_auth_token(request)?; + let tonic_request = quickwit_authorize::build_tonic_request_with_auth_token( + request, + )?; self.inner .clone() .add_source(tonic_request) @@ -5054,7 +5078,9 @@ where &self, request: ToggleSourceRequest, ) -> crate::metastore::MetastoreResult { - let tonic_request = quickwit_auth::build_tonic_request_with_auth_token(request)?; + let tonic_request = quickwit_authorize::build_tonic_request_with_auth_token( + request, + )?; self.inner .clone() .toggle_source(tonic_request) @@ -5069,7 +5095,9 @@ where &self, request: DeleteSourceRequest, ) -> crate::metastore::MetastoreResult { - let tonic_request = quickwit_auth::build_tonic_request_with_auth_token(request)?; + let tonic_request = quickwit_authorize::build_tonic_request_with_auth_token( + request, + )?; self.inner .clone() .delete_source(tonic_request) @@ -5084,7 +5112,9 @@ where &self, request: ResetSourceCheckpointRequest, ) -> crate::metastore::MetastoreResult { - let tonic_request = quickwit_auth::build_tonic_request_with_auth_token(request)?; + let tonic_request = quickwit_authorize::build_tonic_request_with_auth_token( + request, + )?; self.inner .clone() .reset_source_checkpoint(tonic_request) @@ -5099,7 +5129,9 @@ where &self, request: LastDeleteOpstampRequest, ) -> crate::metastore::MetastoreResult { - let tonic_request = quickwit_auth::build_tonic_request_with_auth_token(request)?; + let tonic_request = quickwit_authorize::build_tonic_request_with_auth_token( + request, + )?; self.inner .clone() .last_delete_opstamp(tonic_request) @@ -5114,7 +5146,9 @@ where &self, request: DeleteQuery, ) -> crate::metastore::MetastoreResult { - let tonic_request = quickwit_auth::build_tonic_request_with_auth_token(request)?; + let tonic_request = quickwit_authorize::build_tonic_request_with_auth_token( + request, + )?; self.inner .clone() .create_delete_task(tonic_request) @@ -5129,7 +5163,9 @@ where &self, request: UpdateSplitsDeleteOpstampRequest, ) -> crate::metastore::MetastoreResult { - let tonic_request = quickwit_auth::build_tonic_request_with_auth_token(request)?; + let tonic_request = quickwit_authorize::build_tonic_request_with_auth_token( + request, + )?; self.inner .clone() .update_splits_delete_opstamp(tonic_request) @@ -5144,7 +5180,9 @@ where &self, request: ListDeleteTasksRequest, ) -> crate::metastore::MetastoreResult { - let tonic_request = quickwit_auth::build_tonic_request_with_auth_token(request)?; + let tonic_request = quickwit_authorize::build_tonic_request_with_auth_token( + request, + )?; self.inner .clone() .list_delete_tasks(tonic_request) @@ -5159,7 +5197,9 @@ where &self, request: ListStaleSplitsRequest, ) -> crate::metastore::MetastoreResult { - let tonic_request = quickwit_auth::build_tonic_request_with_auth_token(request)?; + let tonic_request = quickwit_authorize::build_tonic_request_with_auth_token( + request, + )?; self.inner .clone() .list_stale_splits(tonic_request) @@ -5174,7 +5214,9 @@ where &self, request: OpenShardsRequest, ) -> crate::metastore::MetastoreResult { - let tonic_request = quickwit_auth::build_tonic_request_with_auth_token(request)?; + let tonic_request = quickwit_authorize::build_tonic_request_with_auth_token( + request, + )?; self.inner .clone() .open_shards(tonic_request) @@ -5189,7 +5231,9 @@ where &self, request: AcquireShardsRequest, ) -> crate::metastore::MetastoreResult { - let tonic_request = quickwit_auth::build_tonic_request_with_auth_token(request)?; + let tonic_request = quickwit_authorize::build_tonic_request_with_auth_token( + request, + )?; self.inner .clone() .acquire_shards(tonic_request) @@ -5204,7 +5248,9 @@ where &self, request: DeleteShardsRequest, ) -> crate::metastore::MetastoreResult { - let tonic_request = quickwit_auth::build_tonic_request_with_auth_token(request)?; + let tonic_request = quickwit_authorize::build_tonic_request_with_auth_token( + request, + )?; self.inner .clone() .delete_shards(tonic_request) @@ -5219,7 +5265,9 @@ where &self, request: PruneShardsRequest, ) -> crate::metastore::MetastoreResult { - let tonic_request = quickwit_auth::build_tonic_request_with_auth_token(request)?; + let tonic_request = quickwit_authorize::build_tonic_request_with_auth_token( + request, + )?; self.inner .clone() .prune_shards(tonic_request) @@ -5234,7 +5282,9 @@ where &self, request: ListShardsRequest, ) -> crate::metastore::MetastoreResult { - let tonic_request = quickwit_auth::build_tonic_request_with_auth_token(request)?; + let tonic_request = quickwit_authorize::build_tonic_request_with_auth_token( + request, + )?; self.inner .clone() .list_shards(tonic_request) @@ -5249,7 +5299,9 @@ where &self, request: CreateIndexTemplateRequest, ) -> crate::metastore::MetastoreResult { - let tonic_request = quickwit_auth::build_tonic_request_with_auth_token(request)?; + let tonic_request = quickwit_authorize::build_tonic_request_with_auth_token( + request, + )?; self.inner .clone() .create_index_template(tonic_request) @@ -5264,7 +5316,9 @@ where &self, request: GetIndexTemplateRequest, ) -> crate::metastore::MetastoreResult { - let tonic_request = quickwit_auth::build_tonic_request_with_auth_token(request)?; + let tonic_request = quickwit_authorize::build_tonic_request_with_auth_token( + request, + )?; self.inner .clone() .get_index_template(tonic_request) @@ -5279,7 +5333,9 @@ where &self, request: FindIndexTemplateMatchesRequest, ) -> crate::metastore::MetastoreResult { - let tonic_request = quickwit_auth::build_tonic_request_with_auth_token(request)?; + let tonic_request = quickwit_authorize::build_tonic_request_with_auth_token( + request, + )?; self.inner .clone() .find_index_template_matches(tonic_request) @@ -5294,7 +5350,9 @@ where &self, request: ListIndexTemplatesRequest, ) -> crate::metastore::MetastoreResult { - let tonic_request = quickwit_auth::build_tonic_request_with_auth_token(request)?; + let tonic_request = quickwit_authorize::build_tonic_request_with_auth_token( + request, + )?; self.inner .clone() .list_index_templates(tonic_request) @@ -5309,7 +5367,9 @@ where &self, request: DeleteIndexTemplatesRequest, ) -> crate::metastore::MetastoreResult { - let tonic_request = quickwit_auth::build_tonic_request_with_auth_token(request)?; + let tonic_request = quickwit_authorize::build_tonic_request_with_auth_token( + request, + )?; self.inner .clone() .delete_index_templates(tonic_request) @@ -5357,8 +5417,8 @@ for MetastoreServiceGrpcServerAdapter { &self, request: tonic::Request, ) -> Result, tonic::Status> { - let auth_token = quickwit_auth::get_auth_token(request.metadata())?; - quickwit_auth::execute_with_authorization( + let auth_token = quickwit_authorize::get_auth_token(request.metadata())?; + quickwit_authorize::execute_with_authorization( auth_token, self.inner.0.create_index(request.into_inner()), ) @@ -5370,8 +5430,8 @@ for MetastoreServiceGrpcServerAdapter { &self, request: tonic::Request, ) -> Result, tonic::Status> { - let auth_token = quickwit_auth::get_auth_token(request.metadata())?; - quickwit_auth::execute_with_authorization( + let auth_token = quickwit_authorize::get_auth_token(request.metadata())?; + quickwit_authorize::execute_with_authorization( auth_token, self.inner.0.update_index(request.into_inner()), ) @@ -5383,8 +5443,8 @@ for MetastoreServiceGrpcServerAdapter { &self, request: tonic::Request, ) -> Result, tonic::Status> { - let auth_token = quickwit_auth::get_auth_token(request.metadata())?; - quickwit_auth::execute_with_authorization( + let auth_token = quickwit_authorize::get_auth_token(request.metadata())?; + quickwit_authorize::execute_with_authorization( auth_token, self.inner.0.index_metadata(request.into_inner()), ) @@ -5396,8 +5456,8 @@ for MetastoreServiceGrpcServerAdapter { &self, request: tonic::Request, ) -> Result, tonic::Status> { - let auth_token = quickwit_auth::get_auth_token(request.metadata())?; - quickwit_auth::execute_with_authorization( + let auth_token = quickwit_authorize::get_auth_token(request.metadata())?; + quickwit_authorize::execute_with_authorization( auth_token, self.inner.0.indexes_metadata(request.into_inner()), ) @@ -5409,8 +5469,8 @@ for MetastoreServiceGrpcServerAdapter { &self, request: tonic::Request, ) -> Result, tonic::Status> { - let auth_token = quickwit_auth::get_auth_token(request.metadata())?; - quickwit_auth::execute_with_authorization( + let auth_token = quickwit_authorize::get_auth_token(request.metadata())?; + quickwit_authorize::execute_with_authorization( auth_token, self.inner.0.list_indexes_metadata(request.into_inner()), ) @@ -5422,8 +5482,8 @@ for MetastoreServiceGrpcServerAdapter { &self, request: tonic::Request, ) -> Result, tonic::Status> { - let auth_token = quickwit_auth::get_auth_token(request.metadata())?; - quickwit_auth::execute_with_authorization( + let auth_token = quickwit_authorize::get_auth_token(request.metadata())?; + quickwit_authorize::execute_with_authorization( auth_token, self.inner.0.delete_index(request.into_inner()), ) @@ -5438,8 +5498,8 @@ for MetastoreServiceGrpcServerAdapter { &self, request: tonic::Request, ) -> Result, tonic::Status> { - let auth_token = quickwit_auth::get_auth_token(request.metadata())?; - quickwit_auth::execute_with_authorization( + let auth_token = quickwit_authorize::get_auth_token(request.metadata())?; + quickwit_authorize::execute_with_authorization( auth_token, self.inner.0.list_splits(request.into_inner()), ) @@ -5453,8 +5513,8 @@ for MetastoreServiceGrpcServerAdapter { &self, request: tonic::Request, ) -> Result, tonic::Status> { - let auth_token = quickwit_auth::get_auth_token(request.metadata())?; - quickwit_auth::execute_with_authorization( + let auth_token = quickwit_authorize::get_auth_token(request.metadata())?; + quickwit_authorize::execute_with_authorization( auth_token, self.inner.0.stage_splits(request.into_inner()), ) @@ -5466,8 +5526,8 @@ for MetastoreServiceGrpcServerAdapter { &self, request: tonic::Request, ) -> Result, tonic::Status> { - let auth_token = quickwit_auth::get_auth_token(request.metadata())?; - quickwit_auth::execute_with_authorization( + let auth_token = quickwit_authorize::get_auth_token(request.metadata())?; + quickwit_authorize::execute_with_authorization( auth_token, self.inner.0.publish_splits(request.into_inner()), ) @@ -5479,8 +5539,8 @@ for MetastoreServiceGrpcServerAdapter { &self, request: tonic::Request, ) -> Result, tonic::Status> { - let auth_token = quickwit_auth::get_auth_token(request.metadata())?; - quickwit_auth::execute_with_authorization( + let auth_token = quickwit_authorize::get_auth_token(request.metadata())?; + quickwit_authorize::execute_with_authorization( auth_token, self.inner.0.mark_splits_for_deletion(request.into_inner()), ) @@ -5492,8 +5552,8 @@ for MetastoreServiceGrpcServerAdapter { &self, request: tonic::Request, ) -> Result, tonic::Status> { - let auth_token = quickwit_auth::get_auth_token(request.metadata())?; - quickwit_auth::execute_with_authorization( + let auth_token = quickwit_authorize::get_auth_token(request.metadata())?; + quickwit_authorize::execute_with_authorization( auth_token, self.inner.0.delete_splits(request.into_inner()), ) @@ -5505,8 +5565,8 @@ for MetastoreServiceGrpcServerAdapter { &self, request: tonic::Request, ) -> Result, tonic::Status> { - let auth_token = quickwit_auth::get_auth_token(request.metadata())?; - quickwit_auth::execute_with_authorization( + let auth_token = quickwit_authorize::get_auth_token(request.metadata())?; + quickwit_authorize::execute_with_authorization( auth_token, self.inner.0.add_source(request.into_inner()), ) @@ -5518,8 +5578,8 @@ for MetastoreServiceGrpcServerAdapter { &self, request: tonic::Request, ) -> Result, tonic::Status> { - let auth_token = quickwit_auth::get_auth_token(request.metadata())?; - quickwit_auth::execute_with_authorization( + let auth_token = quickwit_authorize::get_auth_token(request.metadata())?; + quickwit_authorize::execute_with_authorization( auth_token, self.inner.0.toggle_source(request.into_inner()), ) @@ -5531,8 +5591,8 @@ for MetastoreServiceGrpcServerAdapter { &self, request: tonic::Request, ) -> Result, tonic::Status> { - let auth_token = quickwit_auth::get_auth_token(request.metadata())?; - quickwit_auth::execute_with_authorization( + let auth_token = quickwit_authorize::get_auth_token(request.metadata())?; + quickwit_authorize::execute_with_authorization( auth_token, self.inner.0.delete_source(request.into_inner()), ) @@ -5544,8 +5604,8 @@ for MetastoreServiceGrpcServerAdapter { &self, request: tonic::Request, ) -> Result, tonic::Status> { - let auth_token = quickwit_auth::get_auth_token(request.metadata())?; - quickwit_auth::execute_with_authorization( + let auth_token = quickwit_authorize::get_auth_token(request.metadata())?; + quickwit_authorize::execute_with_authorization( auth_token, self.inner.0.reset_source_checkpoint(request.into_inner()), ) @@ -5557,8 +5617,8 @@ for MetastoreServiceGrpcServerAdapter { &self, request: tonic::Request, ) -> Result, tonic::Status> { - let auth_token = quickwit_auth::get_auth_token(request.metadata())?; - quickwit_auth::execute_with_authorization( + let auth_token = quickwit_authorize::get_auth_token(request.metadata())?; + quickwit_authorize::execute_with_authorization( auth_token, self.inner.0.last_delete_opstamp(request.into_inner()), ) @@ -5570,8 +5630,8 @@ for MetastoreServiceGrpcServerAdapter { &self, request: tonic::Request, ) -> Result, tonic::Status> { - let auth_token = quickwit_auth::get_auth_token(request.metadata())?; - quickwit_auth::execute_with_authorization( + let auth_token = quickwit_authorize::get_auth_token(request.metadata())?; + quickwit_authorize::execute_with_authorization( auth_token, self.inner.0.create_delete_task(request.into_inner()), ) @@ -5583,8 +5643,8 @@ for MetastoreServiceGrpcServerAdapter { &self, request: tonic::Request, ) -> Result, tonic::Status> { - let auth_token = quickwit_auth::get_auth_token(request.metadata())?; - quickwit_auth::execute_with_authorization( + let auth_token = quickwit_authorize::get_auth_token(request.metadata())?; + quickwit_authorize::execute_with_authorization( auth_token, self.inner.0.update_splits_delete_opstamp(request.into_inner()), ) @@ -5596,8 +5656,8 @@ for MetastoreServiceGrpcServerAdapter { &self, request: tonic::Request, ) -> Result, tonic::Status> { - let auth_token = quickwit_auth::get_auth_token(request.metadata())?; - quickwit_auth::execute_with_authorization( + let auth_token = quickwit_authorize::get_auth_token(request.metadata())?; + quickwit_authorize::execute_with_authorization( auth_token, self.inner.0.list_delete_tasks(request.into_inner()), ) @@ -5609,8 +5669,8 @@ for MetastoreServiceGrpcServerAdapter { &self, request: tonic::Request, ) -> Result, tonic::Status> { - let auth_token = quickwit_auth::get_auth_token(request.metadata())?; - quickwit_auth::execute_with_authorization( + let auth_token = quickwit_authorize::get_auth_token(request.metadata())?; + quickwit_authorize::execute_with_authorization( auth_token, self.inner.0.list_stale_splits(request.into_inner()), ) @@ -5622,8 +5682,8 @@ for MetastoreServiceGrpcServerAdapter { &self, request: tonic::Request, ) -> Result, tonic::Status> { - let auth_token = quickwit_auth::get_auth_token(request.metadata())?; - quickwit_auth::execute_with_authorization( + let auth_token = quickwit_authorize::get_auth_token(request.metadata())?; + quickwit_authorize::execute_with_authorization( auth_token, self.inner.0.open_shards(request.into_inner()), ) @@ -5635,8 +5695,8 @@ for MetastoreServiceGrpcServerAdapter { &self, request: tonic::Request, ) -> Result, tonic::Status> { - let auth_token = quickwit_auth::get_auth_token(request.metadata())?; - quickwit_auth::execute_with_authorization( + let auth_token = quickwit_authorize::get_auth_token(request.metadata())?; + quickwit_authorize::execute_with_authorization( auth_token, self.inner.0.acquire_shards(request.into_inner()), ) @@ -5648,8 +5708,8 @@ for MetastoreServiceGrpcServerAdapter { &self, request: tonic::Request, ) -> Result, tonic::Status> { - let auth_token = quickwit_auth::get_auth_token(request.metadata())?; - quickwit_auth::execute_with_authorization( + let auth_token = quickwit_authorize::get_auth_token(request.metadata())?; + quickwit_authorize::execute_with_authorization( auth_token, self.inner.0.delete_shards(request.into_inner()), ) @@ -5661,8 +5721,8 @@ for MetastoreServiceGrpcServerAdapter { &self, request: tonic::Request, ) -> Result, tonic::Status> { - let auth_token = quickwit_auth::get_auth_token(request.metadata())?; - quickwit_auth::execute_with_authorization( + let auth_token = quickwit_authorize::get_auth_token(request.metadata())?; + quickwit_authorize::execute_with_authorization( auth_token, self.inner.0.prune_shards(request.into_inner()), ) @@ -5674,8 +5734,8 @@ for MetastoreServiceGrpcServerAdapter { &self, request: tonic::Request, ) -> Result, tonic::Status> { - let auth_token = quickwit_auth::get_auth_token(request.metadata())?; - quickwit_auth::execute_with_authorization( + let auth_token = quickwit_authorize::get_auth_token(request.metadata())?; + quickwit_authorize::execute_with_authorization( auth_token, self.inner.0.list_shards(request.into_inner()), ) @@ -5687,8 +5747,8 @@ for MetastoreServiceGrpcServerAdapter { &self, request: tonic::Request, ) -> Result, tonic::Status> { - let auth_token = quickwit_auth::get_auth_token(request.metadata())?; - quickwit_auth::execute_with_authorization( + let auth_token = quickwit_authorize::get_auth_token(request.metadata())?; + quickwit_authorize::execute_with_authorization( auth_token, self.inner.0.create_index_template(request.into_inner()), ) @@ -5700,8 +5760,8 @@ for MetastoreServiceGrpcServerAdapter { &self, request: tonic::Request, ) -> Result, tonic::Status> { - let auth_token = quickwit_auth::get_auth_token(request.metadata())?; - quickwit_auth::execute_with_authorization( + let auth_token = quickwit_authorize::get_auth_token(request.metadata())?; + quickwit_authorize::execute_with_authorization( auth_token, self.inner.0.get_index_template(request.into_inner()), ) @@ -5713,8 +5773,8 @@ for MetastoreServiceGrpcServerAdapter { &self, request: tonic::Request, ) -> Result, tonic::Status> { - let auth_token = quickwit_auth::get_auth_token(request.metadata())?; - quickwit_auth::execute_with_authorization( + let auth_token = quickwit_authorize::get_auth_token(request.metadata())?; + quickwit_authorize::execute_with_authorization( auth_token, self.inner.0.find_index_template_matches(request.into_inner()), ) @@ -5726,8 +5786,8 @@ for MetastoreServiceGrpcServerAdapter { &self, request: tonic::Request, ) -> Result, tonic::Status> { - let auth_token = quickwit_auth::get_auth_token(request.metadata())?; - quickwit_auth::execute_with_authorization( + let auth_token = quickwit_authorize::get_auth_token(request.metadata())?; + quickwit_authorize::execute_with_authorization( auth_token, self.inner.0.list_index_templates(request.into_inner()), ) @@ -5739,8 +5799,8 @@ for MetastoreServiceGrpcServerAdapter { &self, request: tonic::Request, ) -> Result, tonic::Status> { - let auth_token = quickwit_auth::get_auth_token(request.metadata())?; - quickwit_auth::execute_with_authorization( + let auth_token = quickwit_authorize::get_auth_token(request.metadata())?; + quickwit_authorize::execute_with_authorization( auth_token, self.inner.0.delete_index_templates(request.into_inner()), ) diff --git a/quickwit/quickwit-proto/src/control_plane/mod.rs b/quickwit/quickwit-proto/src/control_plane/mod.rs index 34306229a2a..5a72abea10f 100644 --- a/quickwit/quickwit-proto/src/control_plane/mod.rs +++ b/quickwit/quickwit-proto/src/control_plane/mod.rs @@ -43,7 +43,7 @@ pub enum ControlPlaneError { #[error("service unavailable: {0}")] Unavailable(String), #[error("unauthorized: {0}")] - Unauthorized(#[from] quickwit_auth::AuthorizationError), + Unauthorized(#[from] quickwit_authorize::AuthorizationError), } impl From for ControlPlaneError { diff --git a/quickwit/quickwit-proto/src/developer/mod.rs b/quickwit/quickwit-proto/src/developer/mod.rs index 90595b6d60a..0c1c7aa6273 100644 --- a/quickwit/quickwit-proto/src/developer/mod.rs +++ b/quickwit/quickwit-proto/src/developer/mod.rs @@ -39,7 +39,7 @@ pub enum DeveloperError { #[error("service unavailable: {0}")] Unavailable(String), #[error("unauthorized: {0}")] - Unauthorized(#[from] quickwit_auth::AuthorizationError), + Unauthorized(#[from] quickwit_authorize::AuthorizationError), } impl ServiceError for DeveloperError { diff --git a/quickwit/quickwit-proto/src/error.rs b/quickwit/quickwit-proto/src/error.rs index 828e33efe0a..08b2657b378 100644 --- a/quickwit/quickwit-proto/src/error.rs +++ b/quickwit/quickwit-proto/src/error.rs @@ -23,7 +23,7 @@ use std::fmt::Debug; use anyhow::Context; use quickwit_actors::AskError; -use quickwit_auth::AuthorizationError; +use quickwit_authorize::AuthorizationError; use serde::de::DeserializeOwned; use serde::Serialize; use tonic::metadata::BinaryMetadataValue; diff --git a/quickwit/quickwit-proto/src/indexing/mod.rs b/quickwit/quickwit-proto/src/indexing/mod.rs index 449d7f9efae..b57c7e9db8c 100644 --- a/quickwit/quickwit-proto/src/indexing/mod.rs +++ b/quickwit/quickwit-proto/src/indexing/mod.rs @@ -52,7 +52,7 @@ pub enum IndexingError { #[error("service unavailable: {0}")] Unavailable(String), #[error("unauthorized: {0}")] - Unauthorized(#[from] quickwit_auth::AuthorizationError), + Unauthorized(#[from] quickwit_authorize::AuthorizationError), } impl From for IndexingError { diff --git a/quickwit/quickwit-proto/src/ingest/mod.rs b/quickwit/quickwit-proto/src/ingest/mod.rs index 3722c5fbd87..ef01a705396 100644 --- a/quickwit/quickwit-proto/src/ingest/mod.rs +++ b/quickwit/quickwit-proto/src/ingest/mod.rs @@ -66,7 +66,7 @@ pub enum IngestV2Error { #[error("service unavailable: {0}")] Unavailable(String), #[error("unauthorized: {0}")] - Unauthorized(#[from] quickwit_auth::AuthorizationError), + Unauthorized(#[from] quickwit_authorize::AuthorizationError), } impl From for IngestV2Error { diff --git a/quickwit/quickwit-proto/src/metastore/mod.rs b/quickwit/quickwit-proto/src/metastore/mod.rs index 530f5ec0c79..0b795a91b9b 100644 --- a/quickwit/quickwit-proto/src/metastore/mod.rs +++ b/quickwit/quickwit-proto/src/metastore/mod.rs @@ -157,7 +157,7 @@ pub enum MetastoreError { Unavailable(String), #[error("unauthorized: {0}")] - Unauthorized(#[from] quickwit_auth::AuthorizationError), + Unauthorized(#[from] quickwit_authorize::AuthorizationError), } impl MetastoreError { From b65f2b5cbca53cb4b59a3c011972929da969642e Mon Sep 17 00:00:00 2001 From: Paul Masurel Date: Tue, 5 Nov 2024 10:21:18 +0900 Subject: [PATCH 5/6] blop --- config/quickwit.yaml | 6 + quickwit/Cargo.lock | 36 ++++++ quickwit/Cargo.toml | 1 + quickwit/quickwit-authorize/Cargo.toml | 4 +- .../src/{community.rs => community/mod.rs} | 8 +- .../{ => enterprise}/authorization_layer.rs | 20 ++++ .../authorization_token_extraction_layer.rs | 74 ++++++++++++ .../src/{enterprise.rs => enterprise/mod.rs} | 106 +++++++++++------- quickwit/quickwit-authorize/src/lib.rs | 6 +- quickwit/quickwit-cli/Cargo.toml | 2 +- .../example/src/authorization.rs | 8 +- .../example/src/codegen/hello.rs | 8 +- quickwit/quickwit-codegen/src/codegen.rs | 4 +- quickwit/quickwit-common/Cargo.toml | 1 + quickwit/quickwit-common/src/lib.rs | 9 ++ .../src/tower/one_task_per_call_layer.rs | 2 +- quickwit/quickwit-config/Cargo.toml | 3 +- .../quickwit-config/src/node_config/mod.rs | 7 ++ .../src/node_config/serialize.rs | 55 +++++++-- quickwit/quickwit-ingest/src/authorize.rs | 2 +- .../src/codegen/ingest_service.rs | 6 +- quickwit/quickwit-proto/Cargo.toml | 3 +- quickwit/quickwit-proto/src/authorization.rs | 9 +- .../src/codegen/quickwit/quickwit.cluster.rs | 2 +- .../quickwit/quickwit.control_plane.rs | 18 +-- .../codegen/quickwit/quickwit.developer.rs | 2 +- .../src/codegen/quickwit/quickwit.indexing.rs | 2 +- .../quickwit/quickwit.ingest.ingester.rs | 20 ++-- .../quickwit/quickwit.ingest.router.rs | 2 +- .../codegen/quickwit/quickwit.metastore.rs | 60 +++++----- quickwit/quickwit-serve/Cargo.toml | 2 + quickwit/quickwit-serve/src/lib.rs | 19 +++- quickwit/quickwit-serve/src/rest.rs | 19 +++- 33 files changed, 387 insertions(+), 139 deletions(-) rename quickwit/quickwit-authorize/src/{community.rs => community/mod.rs} (92%) rename quickwit/quickwit-authorize/src/{ => enterprise}/authorization_layer.rs (63%) create mode 100644 quickwit/quickwit-authorize/src/enterprise/authorization_token_extraction_layer.rs rename quickwit/quickwit-authorize/src/{enterprise.rs => enterprise/mod.rs} (76%) diff --git a/config/quickwit.yaml b/config/quickwit.yaml index 7072c569fc0..1d03988b737 100644 --- a/config/quickwit.yaml +++ b/config/quickwit.yaml @@ -150,3 +150,9 @@ indexer: jaeger: enable_endpoint: ${QW_ENABLE_JAEGER_ENDPOINT:-true} + +license: ${QW_LICENSE} + +# authorization: +# root_key: ${QW_ROOT_KEY} +# node_token: ${QW_NODE_TOKEN} diff --git a/quickwit/Cargo.lock b/quickwit/Cargo.lock index 905e999110a..d1df21bb5e7 100644 --- a/quickwit/Cargo.lock +++ b/quickwit/Cargo.lock @@ -1684,6 +1684,26 @@ version = "0.9.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c2459377285ad874054d797f3ccebf984978aa39129f6eafde5cdc8315b612f8" +[[package]] +name = "const-random" +version = "0.1.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "87e00182fe74b066627d63b85fd550ac2998d4b0bd86bfed477a0ae4c7c71359" +dependencies = [ + "const-random-macro", +] + +[[package]] +name = "const-random-macro" +version = "0.1.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f9d839f2a20b0aee515dc581a6172f2321f96cab76c1a38a4c584a194955390e" +dependencies = [ + "getrandom 0.2.15", + "once_cell", + "tiny-keccak", +] + [[package]] name = "constant_time_eq" version = "0.1.5" @@ -5951,6 +5971,7 @@ dependencies = [ name = "quickwit-authorize" version = "0.8.0" dependencies = [ + "anyhow", "biscuit-auth", "futures", "http 0.2.12", @@ -5959,6 +5980,7 @@ dependencies = [ "serde", "thiserror", "tokio", + "tokio-inherit-task-local", "tonic", "tower", "tracing", @@ -6134,6 +6156,7 @@ dependencies = [ "tempfile", "thiserror", "tokio", + "tokio-inherit-task-local", "tokio-metrics", "tokio-stream", "tonic", @@ -6158,6 +6181,7 @@ dependencies = [ "json_comments", "new_string_template", "once_cell", + "quickwit-authorize", "quickwit-common", "quickwit-doc-mapper", "quickwit-license", @@ -6621,6 +6645,7 @@ version = "0.8.0" dependencies = [ "anyhow", "async-trait", + "biscuit-auth", "bytes", "bytesize", "bytestring", @@ -6772,6 +6797,7 @@ dependencies = [ "prost 0.11.9", "prost-types 0.11.9", "quickwit-actors", + "quickwit-authorize", "quickwit-cluster", "quickwit-common", "quickwit-config", @@ -8888,6 +8914,16 @@ dependencies = [ "windows-sys 0.52.0", ] +[[package]] +name = "tokio-inherit-task-local" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d42db185acdff44279cff7f8765608129ae4a01a2f955008a4f96054c75e77ac" +dependencies = [ + "const-random", + "tokio", +] + [[package]] name = "tokio-io-timeout" version = "1.2.0" diff --git a/quickwit/Cargo.toml b/quickwit/Cargo.toml index c8878d3c515..f2578232b1e 100644 --- a/quickwit/Cargo.toml +++ b/quickwit/Cargo.toml @@ -240,6 +240,7 @@ tikv-jemalloc-ctl = "0.5" tikv-jemallocator = "0.5" time = { version = "0.3", features = ["std", "formatting", "macros"] } tokio = { version = "1.40", features = ["full"] } +tokio-inherit-task-local = "0.2" tokio-metrics = { version = "0.3.1", features = ["rt"] } tokio-stream = { version = "0.1", features = ["sync"] } tokio-util = { version = "0.7", features = ["full"] } diff --git a/quickwit/quickwit-authorize/Cargo.toml b/quickwit/quickwit-authorize/Cargo.toml index 4c3985fcff3..1b21761a408 100644 --- a/quickwit/quickwit-authorize/Cargo.toml +++ b/quickwit/quickwit-authorize/Cargo.toml @@ -9,10 +9,12 @@ authors.workspace = true license.workspace = true [dependencies] +anyhow = { workspace = true, optional = true } tower = { workspace = true} biscuit-auth = { workspace = true, optional=true } futures = { workspace = true } http = { workspace = true } +tokio-inherit-task-local = { workspace = true } serde = { workspace = true } thiserror = { workspace = true } tonic = { workspace = true } @@ -23,4 +25,4 @@ pin-project = { workspace = true } quickwit-common = { workspace = true } [features] -enterprise = ["biscuit-auth"] +enterprise = ["dep:biscuit-auth", "dep:anyhow"] diff --git a/quickwit/quickwit-authorize/src/community.rs b/quickwit/quickwit-authorize/src/community/mod.rs similarity index 92% rename from quickwit/quickwit-authorize/src/community.rs rename to quickwit/quickwit-authorize/src/community/mod.rs index 48576639c7f..0fd7c0b85ca 100644 --- a/quickwit/quickwit-authorize/src/community.rs +++ b/quickwit/quickwit-authorize/src/community/mod.rs @@ -44,7 +44,7 @@ pub trait StreamAuthorization { impl StreamAuthorization for T {} -pub fn get_auth_token( +pub fn extract_auth_token( _req_metadata: &tonic::metadata::MetadataMap, ) -> Result { Ok(()) @@ -63,12 +63,6 @@ pub fn authorize( Ok(()) } -pub fn build_tonic_stream_request_with_auth_token( - req: R, -) -> Result, AuthorizationError> { - Ok(tonic::Request::new(req)) -} - pub fn build_tonic_request_with_auth_token( req: R, ) -> Result, AuthorizationError> { diff --git a/quickwit/quickwit-authorize/src/authorization_layer.rs b/quickwit/quickwit-authorize/src/enterprise/authorization_layer.rs similarity index 63% rename from quickwit/quickwit-authorize/src/authorization_layer.rs rename to quickwit/quickwit-authorize/src/enterprise/authorization_layer.rs index 3131bef4715..ae29555ee02 100644 --- a/quickwit/quickwit-authorize/src/authorization_layer.rs +++ b/quickwit/quickwit-authorize/src/enterprise/authorization_layer.rs @@ -1,3 +1,22 @@ +// Copyright (C) 2024 Quickwit, Inc. +// +// Quickwit is offered under the AGPL v3.0 and as commercial software. +// For commercial licensing, contact us at hello@quickwit.io. +// +// AGPL: +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as +// published by the Free Software Foundation, either version 3 of the +// License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + use std::fmt; use std::task::{Context, Poll}; @@ -7,6 +26,7 @@ use tower::{Layer, Service}; use crate::AuthorizationError; +#[derive(Clone, Copy, Debug)] pub struct AuthorizationLayer; impl Layer for AuthorizationLayer { diff --git a/quickwit/quickwit-authorize/src/enterprise/authorization_token_extraction_layer.rs b/quickwit/quickwit-authorize/src/enterprise/authorization_token_extraction_layer.rs new file mode 100644 index 00000000000..a2a9b08bfef --- /dev/null +++ b/quickwit/quickwit-authorize/src/enterprise/authorization_token_extraction_layer.rs @@ -0,0 +1,74 @@ +// Copyright (C) 2024 Quickwit, Inc. +// +// Quickwit is offered under the AGPL v3.0 and as commercial software. +// For commercial licensing, contact us at hello@quickwit.io. +// +// AGPL: +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as +// published by the Free Software Foundation, either version 3 of the +// License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + +use std::task::{Context, Poll}; + +use futures::future::Either; +use http::Request; +use tokio::task::futures::TaskLocalFuture; +use tokio_inherit_task_local::TaskLocalInheritableTable; +use tower::{Layer, Service}; +use tracing::debug; + +use super::AuthorizationToken; + +#[derive(Clone, Copy, Debug)] +pub struct AuthorizationTokenExtractionLayer; + +impl Layer for AuthorizationTokenExtractionLayer { + type Service = AuthorizationTokenExtractionService; + + fn layer(&self, service: S) -> Self::Service { + AuthorizationTokenExtractionService { service } + } +} + +#[derive(Clone)] +pub struct AuthorizationTokenExtractionService { + service: S, +} + +fn get_authorization_token_opt(headers: &http::HeaderMap) -> Option { + let authorization_header_value = headers.get("Authorization")?; + let authorization_header_str = authorization_header_value.to_str().ok()?; + crate::get_auth_token_from_str(authorization_header_str).ok() +} + +impl Service> for AuthorizationTokenExtractionService +where S: Service> +{ + type Response = S::Response; + type Error = S::Error; + type Future = Either>; + + fn poll_ready(&mut self, cx: &mut Context<'_>) -> Poll> { + self.service.poll_ready(cx) + } + + fn call(&mut self, request: Request) -> Self::Future { + let authorization_token_opt = get_authorization_token_opt(request.headers()); + debug!(authorization_token_opt = ?authorization_token_opt, "Authorization token extracted"); + let fut = self.service.call(request); + if let Some(authorization_token) = authorization_token_opt { + Either::Right(crate::execute_with_authorization(authorization_token, fut)) + } else { + Either::Left(fut) + } + } +} diff --git a/quickwit/quickwit-authorize/src/enterprise.rs b/quickwit/quickwit-authorize/src/enterprise/mod.rs similarity index 76% rename from quickwit/quickwit-authorize/src/enterprise.rs rename to quickwit/quickwit-authorize/src/enterprise/mod.rs index e1aa02e4436..b8c64a5abf1 100644 --- a/quickwit/quickwit-authorize/src/enterprise.rs +++ b/quickwit/quickwit-authorize/src/enterprise/mod.rs @@ -19,26 +19,43 @@ // components are licensed under the original license provided by the owner of the // applicable component. +mod authorization_layer; +mod authorization_token_extraction_layer; + use std::future::Future; use std::str::FromStr; use std::sync::{Arc, OnceLock}; +use anyhow::Context; +pub use authorization_layer::AuthorizationLayer; +pub use authorization_token_extraction_layer::AuthorizationTokenExtractionLayer; use biscuit_auth::macros::authorizer; use biscuit_auth::{Authorizer, Biscuit, RootKeyProvider}; +use tokio::task::futures::TaskLocalFuture; +use tokio_inherit_task_local::TaskLocalInheritableTable; +use tracing::info; use crate::AuthorizationError; -pub struct AuthorizationToken(Biscuit); +tokio_inherit_task_local::inheritable_task_local! { + pub static AUTHORIZATION_TOKEN: AuthorizationToken; +} + +static ROOT_KEY_PROVIDER: OnceLock> = OnceLock::new(); +static NODE_TOKEN: OnceLock = OnceLock::new(); + +#[derive(Clone)] +pub struct AuthorizationToken(Arc); impl AuthorizationToken { - pub fn into_biscuit(self) -> Biscuit { - self.0 + pub fn into_biscuit(self) -> Arc { + self.0.clone() } } impl From for AuthorizationToken { fn from(biscuit: Biscuit) -> Self { - AuthorizationToken(biscuit) + AuthorizationToken(Arc::new(biscuit)) } } @@ -54,7 +71,22 @@ impl std::fmt::Debug for AuthorizationToken { } } -static ROOT_KEY_PROVIDER: OnceLock> = OnceLock::new(); +pub fn set_node_token_hex(node_token_hex: &str) -> anyhow::Result<()> { + let node_token = + AuthorizationToken::from_str(node_token_hex).context("failed to set node token")?; + if NODE_TOKEN.set(node_token).is_err() { + tracing::error!("node token was already initialized"); + } + Ok(()) +} + +pub fn set_root_public_key(root_key_hex: &str) -> anyhow::Result<()> { + let public_key = biscuit_auth::PublicKey::from_bytes_hex(root_key_hex) + .context("failed to parse root public key")?; + let key_provider: Arc = Arc::new(public_key); + set_root_key_provider(key_provider); + Ok(()) +} pub fn set_root_key_provider(key_provider: Arc) { if ROOT_KEY_PROVIDER.set(key_provider).is_err() { @@ -75,14 +107,10 @@ impl FromStr for AuthorizationToken { fn from_str(token_base64: &str) -> Result { let root_key_provider = get_root_key_provider(); let biscuit = Biscuit::from_base64(token_base64, root_key_provider)?; - Ok(AuthorizationToken(biscuit)) + Ok(AuthorizationToken::from(biscuit)) } } -tokio::task_local! { - pub static AUTHORIZATION_TOKEN: AuthorizationToken; -} - const AUTHORIZATION_VALUE_PREFIX: &str = "Bearer "; fn default_operation_authorizer( @@ -146,7 +174,17 @@ impl From for AuthorizationError { } } -pub fn get_auth_token( +pub fn get_auth_token_from_str( + authorization_header_value: &str, +) -> Result { + let authorization_token_str: &str = authorization_header_value + .strip_prefix(AUTHORIZATION_VALUE_PREFIX) + .ok_or(AuthorizationError::InvalidToken)?; + let biscuit: Biscuit = Biscuit::from_base64(authorization_token_str, get_root_key_provider())?; + Ok(AuthorizationToken::from(biscuit)) +} + +pub fn extract_auth_token( req_metadata: &tonic::metadata::MetadataMap, ) -> Result { let authorization_header_value: &str = req_metadata @@ -154,11 +192,7 @@ pub fn get_auth_token( .ok_or(AuthorizationError::AuthorizationTokenMissing)? .to_str() .map_err(|_| AuthorizationError::InvalidToken)?; - let authorization_token_str: &str = authorization_header_value - .strip_prefix(AUTHORIZATION_VALUE_PREFIX) - .ok_or(AuthorizationError::InvalidToken)?; - let biscuit: Biscuit = Biscuit::from_base64(authorization_token_str, get_root_key_provider())?; - Ok(AuthorizationToken(biscuit)) + get_auth_token_from_str(authorization_header_value) } pub fn set_auth_token( @@ -182,28 +216,22 @@ pub fn authorize( Ok(()) } -pub fn build_tonic_stream_request_with_auth_token( - req: R, -) -> Result, AuthorizationError> { +fn get_auth_token() -> Option { AUTHORIZATION_TOKEN - .try_with(|token| { - let mut request = tonic::Request::new(req); - set_auth_token(token, request.metadata_mut()); - Ok(request) - }) - .unwrap_or(Err(AuthorizationError::AuthorizationTokenMissing)) + .try_with(|auth_token| auth_token.clone()) + .ok() + .or_else(|| NODE_TOKEN.get().cloned()) } -pub fn build_tonic_request_with_auth_token( +pub fn build_tonic_request_with_auth_token( req: R, ) -> Result, AuthorizationError> { - AUTHORIZATION_TOKEN - .try_with(|token| { - let mut request = tonic::Request::new(req); - set_auth_token(token, request.metadata_mut()); - Ok(request) - }) - .unwrap_or(Err(AuthorizationError::AuthorizationTokenMissing)) + let Some(authorization_token) = get_auth_token() else { + return Err(AuthorizationError::AuthorizationTokenMissing); + }; + let mut tonic_request = tonic::Request::new(req); + set_auth_token(&authorization_token, tonic_request.metadata_mut()); + Ok(tonic_request) } pub fn authorize_stream( @@ -216,15 +244,17 @@ pub fn authorize_stream( } pub fn authorize_request(req: &R) -> Result<(), AuthorizationError> { - AUTHORIZATION_TOKEN + let res = AUTHORIZATION_TOKEN .try_with(|auth_token| authorize(req, auth_token)) - .unwrap_or(Err(AuthorizationError::AuthorizationTokenMissing)) + .unwrap_or(Err(AuthorizationError::AuthorizationTokenMissing)); + info!("request authorization"); + res } pub fn execute_with_authorization( token: AuthorizationToken, f: F, -) -> impl Future +) -> TaskLocalFuture where F: Future, { @@ -248,7 +278,7 @@ mod tests { #[test] fn test_auth_token_missing() { let req_metadata = tonic::metadata::MetadataMap::new(); - let missing_error = get_auth_token(&req_metadata).unwrap_err(); + let missing_error = extract_auth_token(&req_metadata).unwrap_err(); assert!(matches!( missing_error, AuthorizationError::AuthorizationTokenMissing @@ -262,7 +292,7 @@ mod tests { http::header::AUTHORIZATION.as_str(), "some_token".parse().unwrap(), ); - let missing_error = get_auth_token(&req_metadata).unwrap_err(); + let missing_error = extract_auth_token(&req_metadata).unwrap_err(); assert!(matches!(missing_error, AuthorizationError::InvalidToken)); } } diff --git a/quickwit/quickwit-authorize/src/lib.rs b/quickwit/quickwit-authorize/src/lib.rs index 23206c0b434..3e0a7bb5ca4 100644 --- a/quickwit/quickwit-authorize/src/lib.rs +++ b/quickwit/quickwit-authorize/src/lib.rs @@ -17,14 +17,12 @@ // You should have received a copy of the GNU Affero General Public License // along with this program. If not, see . -mod authorization_layer; - #[cfg(not(feature = "enterprise"))] -#[path = "community.rs"] +#[path = "community/mod.rs"] mod implementation; #[cfg(feature = "enterprise")] -#[path = "enterprise.rs"] +#[path = "enterprise/mod.rs"] mod implementation; pub use implementation::*; diff --git a/quickwit/quickwit-cli/Cargo.toml b/quickwit/quickwit-cli/Cargo.toml index 64bf88dabda..ec528e64ea9 100644 --- a/quickwit/quickwit-cli/Cargo.toml +++ b/quickwit/quickwit-cli/Cargo.toml @@ -79,7 +79,7 @@ quickwit-metastore = { workspace = true, features = ["testsuite"] } quickwit-storage = { workspace = true, features = ["testsuite"] } [features] -enterprise = ["quickwit-config/enterprise", "quickwit-ingest/enterprise", "quickwit-proto/enterprise"] +enterprise = ["quickwit-config/enterprise", "quickwit-ingest/enterprise", "quickwit-proto/enterprise", "quickwit-serve/enterprise"] jemalloc = ["dep:tikv-jemalloc-ctl", "dep:tikv-jemallocator"] ci-test = [] pprof = ["quickwit-serve/pprof"] diff --git a/quickwit/quickwit-codegen/example/src/authorization.rs b/quickwit/quickwit-codegen/example/src/authorization.rs index 509fed82f0f..1d0a000066a 100644 --- a/quickwit/quickwit-codegen/example/src/authorization.rs +++ b/quickwit/quickwit-codegen/example/src/authorization.rs @@ -15,7 +15,9 @@ // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. -use quickwit_authorize::{Authorization, AuthorizationError, AuthorizationToken, StreamAuthorization}; +use quickwit_authorize::{ + Authorization, AuthorizationError, AuthorizationToken, StreamAuthorization, +}; use crate::{GoodbyeRequest, HelloRequest, PingRequest}; @@ -38,9 +40,7 @@ impl Authorization for GoodbyeRequest { } impl StreamAuthorization for PingRequest { - fn attenuate( - auth_token: AuthorizationToken, - ) -> Result { + fn attenuate(auth_token: AuthorizationToken) -> Result { Ok(auth_token) } } diff --git a/quickwit/quickwit-codegen/example/src/codegen/hello.rs b/quickwit/quickwit-codegen/example/src/codegen/hello.rs index 4eb3a2dc8c7..04cf2d4dabf 100644 --- a/quickwit/quickwit-codegen/example/src/codegen/hello.rs +++ b/quickwit/quickwit-codegen/example/src/codegen/hello.rs @@ -757,7 +757,7 @@ where &self, request: quickwit_common::ServiceStream, ) -> crate::HelloResult> { - let tonic_request = quickwit_authorize::build_tonic_stream_request_with_auth_token( + let tonic_request = quickwit_authorize::build_tonic_request_with_auth_token( request, )?; self.inner @@ -814,7 +814,7 @@ impl hello_grpc_server::HelloGrpc for HelloGrpcServerAdapter { &self, request: tonic::Request, ) -> Result, tonic::Status> { - let auth_token = quickwit_authorize::get_auth_token(request.metadata())?; + let auth_token = quickwit_authorize::extract_auth_token(request.metadata())?; quickwit_authorize::execute_with_authorization( auth_token, self.inner.0.hello(request.into_inner()), @@ -827,7 +827,7 @@ impl hello_grpc_server::HelloGrpc for HelloGrpcServerAdapter { &self, request: tonic::Request, ) -> Result, tonic::Status> { - let auth_token = quickwit_authorize::get_auth_token(request.metadata())?; + let auth_token = quickwit_authorize::extract_auth_token(request.metadata())?; quickwit_authorize::execute_with_authorization( auth_token, self.inner.0.goodbye(request.into_inner()), @@ -841,7 +841,7 @@ impl hello_grpc_server::HelloGrpc for HelloGrpcServerAdapter { &self, request: tonic::Request>, ) -> Result, tonic::Status> { - let auth_token = quickwit_authorize::get_auth_token(request.metadata())?; + let auth_token = quickwit_authorize::extract_auth_token(request.metadata())?; quickwit_authorize::execute_with_authorization( auth_token, self diff --git a/quickwit/quickwit-codegen/src/codegen.rs b/quickwit/quickwit-codegen/src/codegen.rs index 4143cafd15b..5db1f10ac4b 100644 --- a/quickwit/quickwit-codegen/src/codegen.rs +++ b/quickwit/quickwit-codegen/src/codegen.rs @@ -1170,7 +1170,7 @@ fn generate_grpc_client_adapter_methods(context: &CodegenContext) -> TokenStream let method = if syn_method.client_streaming { quote! { async fn #method_name(&self, request: #request_type) -> #result_type<#response_type> { - let tonic_request = quickwit_authorize::build_tonic_stream_request_with_auth_token(request)?; + let tonic_request = quickwit_authorize::build_tonic_request_with_auth_token(request)?; self.inner .clone() .#method_name(tonic_request) @@ -1273,7 +1273,7 @@ fn generate_grpc_server_adapter_methods(context: &CodegenContext) -> TokenStream #associated_type async fn #method_name(&self, request: tonic::Request<#request_type>) -> Result, tonic::Status> { - let auth_token = quickwit_authorize::get_auth_token(request.metadata())?; + let auth_token = quickwit_authorize::extract_auth_token(request.metadata())?; quickwit_authorize::execute_with_authorization(auth_token, self.inner.0.#method_name(#method_arg)).await .map(#into_response_type) .map_err(crate::error::grpc_error_to_grpc_status) diff --git a/quickwit/quickwit-common/Cargo.toml b/quickwit/quickwit-common/Cargo.toml index 83170a8ec56..fc2d579e0f4 100644 --- a/quickwit/quickwit-common/Cargo.toml +++ b/quickwit/quickwit-common/Cargo.toml @@ -39,6 +39,7 @@ thiserror = { workspace = true } tokio = { workspace = true } tokio-metrics = { workspace = true } tokio-stream = { workspace = true } +tokio-inherit-task-local = { workspace = true } tonic = { workspace = true } tower = { workspace = true } tracing = { workspace = true } diff --git a/quickwit/quickwit-common/src/lib.rs b/quickwit/quickwit-common/src/lib.rs index dff26829584..a1712a4105e 100644 --- a/quickwit/quickwit-common/src/lib.rs +++ b/quickwit/quickwit-common/src/lib.rs @@ -213,6 +213,15 @@ pub fn num_cpus() -> usize { } } +pub fn spawn_inherit_task_local(future: F) -> tokio::task::JoinHandle +where + F: Future + Send + 'static, + F::Output: Send + 'static, +{ + use tokio_inherit_task_local::FutureInheritTaskLocal; + tokio::task::spawn(future.inherit_task_local()) +} + // The following are helpers to build named tasks. // // Named tasks require the tokio feature `tracing` to be enabled. diff --git a/quickwit/quickwit-common/src/tower/one_task_per_call_layer.rs b/quickwit/quickwit-common/src/tower/one_task_per_call_layer.rs index caf7ca3cdec..a4bfa33825c 100644 --- a/quickwit/quickwit-common/src/tower/one_task_per_call_layer.rs +++ b/quickwit/quickwit-common/src/tower/one_task_per_call_layer.rs @@ -77,7 +77,7 @@ where fn call(&mut self, request: Request) -> Self::Future { let request_name: &'static str = Request::rpc_name(); let future = self.service.call(request); - let join_handle = tokio::spawn(future); + let join_handle = crate::spawn_inherit_task_local(future); UnwrapOrElseFuture { request_name, join_handle, diff --git a/quickwit/quickwit-config/Cargo.toml b/quickwit/quickwit-config/Cargo.toml index 67309baf13c..0f51a309f9d 100644 --- a/quickwit/quickwit-config/Cargo.toml +++ b/quickwit/quickwit-config/Cargo.toml @@ -35,6 +35,7 @@ tracing = { workspace = true } utoipa = { workspace = true } vrl = { workspace = true, optional = true } +quickwit-authorize = { workspace = true, optional = true } quickwit-common = { workspace = true } quickwit-doc-mapper = { workspace = true } quickwit-license = { workspace = true, optional = true } @@ -49,4 +50,4 @@ quickwit-proto = { workspace = true, features = ["testsuite"] } [features] testsuite = [] vrl = ["dep:vrl"] -enterprise = ["quickwit-license"] +enterprise = ["dep:quickwit-authorize", "dep:quickwit-license", ] diff --git a/quickwit/quickwit-config/src/node_config/mod.rs b/quickwit/quickwit-config/src/node_config/mod.rs index 3eef1f10428..c9a8fab1e06 100644 --- a/quickwit/quickwit-config/src/node_config/mod.rs +++ b/quickwit/quickwit-config/src/node_config/mod.rs @@ -313,6 +313,13 @@ impl SearcherConfig { } } +#[derive(Clone, Debug, Eq, PartialEq, Serialize, Deserialize)] +#[serde(deny_unknown_fields)] +pub struct AuthorizationConfigBuilder { + pub root_key: String, + pub node_token: String, +} + #[derive(Clone, Debug, Eq, PartialEq, Serialize, Deserialize)] #[serde(deny_unknown_fields, default)] pub struct IngestApiConfig { diff --git a/quickwit/quickwit-config/src/node_config/serialize.rs b/quickwit/quickwit-config/src/node_config/serialize.rs index 2a435ebed01..b56026c0de2 100644 --- a/quickwit/quickwit-config/src/node_config/serialize.rs +++ b/quickwit/quickwit-config/src/node_config/serialize.rs @@ -164,6 +164,15 @@ impl From for NodeConfigBuilder { } } +#[derive(Clone, Debug, Eq, PartialEq, Serialize, Deserialize, Default)] +#[serde(deny_unknown_fields)] +pub struct AuthorizationConfigBuilder { + #[serde(default)] + pub root_public_key: Option, + #[serde(default)] + pub node_token: Option, +} + #[serde_with::serde_as] #[derive(Debug, Deserialize, PartialEq)] #[serde(deny_unknown_fields)] @@ -215,6 +224,8 @@ struct NodeConfigBuilder { jaeger_config: JaegerConfig, #[serde(default)] license: Option, + #[serde(default)] + authorization: AuthorizationConfigBuilder, } impl NodeConfigBuilder { @@ -222,6 +233,12 @@ impl NodeConfigBuilder { mut self, env_vars: &HashMap, ) -> anyhow::Result { + #[cfg(feature = "enterprise")] + { + self.set_license(env_vars)?; + self.set_authorization_keys(env_vars)?; + } + let node_id = self.node_id.resolve(env_vars).map(NodeId::new)?; let enabled_services = self @@ -307,15 +324,6 @@ impl NodeConfigBuilder { .map(|gossip_interval_ms| Duration::from_millis(gossip_interval_ms as u64)) .unwrap_or(DEFAULT_GOSSIP_INTERVAL); - // Environment variable takes precedence for license too. - #[cfg(feature = "enterprise")] - if let Some(license_str) = env_vars.get("QW_LICENSE").or(self.license.as_ref()) { - if let Err(error) = quickwit_license::set_license(license_str) { - tracing::error!(error=?error, "invalid license"); - std::process::exit(1); - } - } - let node_config = NodeConfig { cluster_id: self.cluster_id.resolve(env_vars)?, node_id, @@ -344,6 +352,35 @@ impl NodeConfigBuilder { } } +#[cfg(feature = "enterprise")] +impl NodeConfigBuilder { + fn set_license(&self, env_vars: &HashMap) -> anyhow::Result<()> { + // Environment variable takes precedence for license too. + let Some(license_str) = env_vars.get("QW_LICENSE").or(self.license.as_ref()) else { + return Ok(()); + }; + if let Err(error) = quickwit_license::set_license(license_str) { + tracing::error!(error=?error, "invalid license"); + std::process::exit(1); + } + Ok(()) + } + + fn set_authorization_keys(&self, env_vars: &HashMap) -> anyhow::Result<()> { + let root_public_key = env_vars + .get("QW_AUTH_ROOT_PUBLIC_KEY") + .or(self.authorization.root_public_key.as_ref()) + .context("root key undefined")?; + quickwit_authorize::set_root_public_key(root_public_key)?; + let node_token_hex = env_vars + .get("QW_AUTH_NODE_TOKEN") + .or(self.authorization.node_token.as_ref()) + .context("root key undefined")?; + quickwit_authorize::set_node_token_hex(node_token_hex)?; + Ok(()) + } +} + fn validate(node_config: &NodeConfig) -> anyhow::Result<()> { validate_identifier("cluster", &node_config.cluster_id)?; validate_node_id(&node_config.node_id)?; diff --git a/quickwit/quickwit-ingest/src/authorize.rs b/quickwit/quickwit-ingest/src/authorize.rs index 57ad079867a..5e4470b9ee1 100644 --- a/quickwit/quickwit-ingest/src/authorize.rs +++ b/quickwit/quickwit-ingest/src/authorize.rs @@ -15,7 +15,7 @@ // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. -use quickwit_authorize::::{Authorization, AuthorizationError, AuthorizationToken}; +use quickwit_authorize::{Authorization, AuthorizationError, AuthorizationToken}; use crate::{FetchRequest, IngestRequest, TailRequest}; diff --git a/quickwit/quickwit-ingest/src/codegen/ingest_service.rs b/quickwit/quickwit-ingest/src/codegen/ingest_service.rs index 8b7e4b4c7ea..87dee751452 100644 --- a/quickwit/quickwit-ingest/src/codegen/ingest_service.rs +++ b/quickwit/quickwit-ingest/src/codegen/ingest_service.rs @@ -881,7 +881,7 @@ impl ingest_service_grpc_server::IngestServiceGrpc for IngestServiceGrpcServerAd &self, request: tonic::Request, ) -> Result, tonic::Status> { - let auth_token = quickwit_authorize::get_auth_token(request.metadata())?; + let auth_token = quickwit_authorize::extract_auth_token(request.metadata())?; quickwit_authorize::execute_with_authorization( auth_token, self.inner.0.ingest(request.into_inner()), @@ -894,7 +894,7 @@ impl ingest_service_grpc_server::IngestServiceGrpc for IngestServiceGrpcServerAd &self, request: tonic::Request, ) -> Result, tonic::Status> { - let auth_token = quickwit_authorize::get_auth_token(request.metadata())?; + let auth_token = quickwit_authorize::extract_auth_token(request.metadata())?; quickwit_authorize::execute_with_authorization( auth_token, self.inner.0.fetch(request.into_inner()), @@ -907,7 +907,7 @@ impl ingest_service_grpc_server::IngestServiceGrpc for IngestServiceGrpcServerAd &self, request: tonic::Request, ) -> Result, tonic::Status> { - let auth_token = quickwit_authorize::get_auth_token(request.metadata())?; + let auth_token = quickwit_authorize::extract_auth_token(request.metadata())?; quickwit_authorize::execute_with_authorization( auth_token, self.inner.0.tail(request.into_inner()), diff --git a/quickwit/quickwit-proto/Cargo.toml b/quickwit/quickwit-proto/Cargo.toml index e76a7a539af..e6035ac7d55 100644 --- a/quickwit/quickwit-proto/Cargo.toml +++ b/quickwit/quickwit-proto/Cargo.toml @@ -12,6 +12,7 @@ license.workspace = true [dependencies] anyhow = { workspace = true } async-trait = { workspace = true } +biscuit-auth = { workspace = true, optional = true } bytes = { workspace = true } bytesize = { workspace = true } bytestring = { workspace = true } @@ -53,4 +54,4 @@ quickwit-codegen = { workspace = true } [features] postgres = ["sea-query", "sqlx"] testsuite = ["mockall", "futures"] -enterprise = [ "quickwit-authorize/enterprise"] +enterprise = [ "quickwit-authorize/enterprise", "dep:biscuit-auth"] diff --git a/quickwit/quickwit-proto/src/authorization.rs b/quickwit/quickwit-proto/src/authorization.rs index 54882b7cfbc..edf0ac68b7b 100644 --- a/quickwit/quickwit-proto/src/authorization.rs +++ b/quickwit/quickwit-proto/src/authorization.rs @@ -1,8 +1,11 @@ use std::time::{Duration, SystemTime}; -use biscuit_auth::builder_ext::BuilderExt; -use biscuit_auth::macros::*; -use quickwit_authorize::::{Authorization, AuthorizationError, AuthorizationToken, StreamAuthorization}; +pub use biscuit_auth; +pub use biscuit_auth::builder_ext::BuilderExt; +pub use biscuit_auth::macros::*; +use quickwit_authorize::{ + Authorization, AuthorizationError, AuthorizationToken, StreamAuthorization, +}; use crate::cluster::FetchClusterStateRequest; use crate::control_plane::{AdviseResetShardsRequest, GetOrCreateOpenShardsRequest}; diff --git a/quickwit/quickwit-proto/src/codegen/quickwit/quickwit.cluster.rs b/quickwit/quickwit-proto/src/codegen/quickwit/quickwit.cluster.rs index 28762ff59e5..1854e89acda 100644 --- a/quickwit/quickwit-proto/src/codegen/quickwit/quickwit.cluster.rs +++ b/quickwit/quickwit-proto/src/codegen/quickwit/quickwit.cluster.rs @@ -545,7 +545,7 @@ for ClusterServiceGrpcServerAdapter { &self, request: tonic::Request, ) -> Result, tonic::Status> { - let auth_token = quickwit_authorize::get_auth_token(request.metadata())?; + let auth_token = quickwit_authorize::extract_auth_token(request.metadata())?; quickwit_authorize::execute_with_authorization( auth_token, self.inner.0.fetch_cluster_state(request.into_inner()), diff --git a/quickwit/quickwit-proto/src/codegen/quickwit/quickwit.control_plane.rs b/quickwit/quickwit-proto/src/codegen/quickwit/quickwit.control_plane.rs index f1ddb3925fa..16cbae89527 100644 --- a/quickwit/quickwit-proto/src/codegen/quickwit/quickwit.control_plane.rs +++ b/quickwit/quickwit-proto/src/codegen/quickwit/quickwit.control_plane.rs @@ -1806,7 +1806,7 @@ for ControlPlaneServiceGrpcServerAdapter { &self, request: tonic::Request, ) -> Result, tonic::Status> { - let auth_token = quickwit_authorize::get_auth_token(request.metadata())?; + let auth_token = quickwit_authorize::extract_auth_token(request.metadata())?; quickwit_authorize::execute_with_authorization( auth_token, self.inner.0.create_index(request.into_inner()), @@ -1822,7 +1822,7 @@ for ControlPlaneServiceGrpcServerAdapter { tonic::Response, tonic::Status, > { - let auth_token = quickwit_authorize::get_auth_token(request.metadata())?; + let auth_token = quickwit_authorize::extract_auth_token(request.metadata())?; quickwit_authorize::execute_with_authorization( auth_token, self.inner.0.update_index(request.into_inner()), @@ -1835,7 +1835,7 @@ for ControlPlaneServiceGrpcServerAdapter { &self, request: tonic::Request, ) -> Result, tonic::Status> { - let auth_token = quickwit_authorize::get_auth_token(request.metadata())?; + let auth_token = quickwit_authorize::extract_auth_token(request.metadata())?; quickwit_authorize::execute_with_authorization( auth_token, self.inner.0.delete_index(request.into_inner()), @@ -1848,7 +1848,7 @@ for ControlPlaneServiceGrpcServerAdapter { &self, request: tonic::Request, ) -> Result, tonic::Status> { - let auth_token = quickwit_authorize::get_auth_token(request.metadata())?; + let auth_token = quickwit_authorize::extract_auth_token(request.metadata())?; quickwit_authorize::execute_with_authorization( auth_token, self.inner.0.add_source(request.into_inner()), @@ -1861,7 +1861,7 @@ for ControlPlaneServiceGrpcServerAdapter { &self, request: tonic::Request, ) -> Result, tonic::Status> { - let auth_token = quickwit_authorize::get_auth_token(request.metadata())?; + let auth_token = quickwit_authorize::extract_auth_token(request.metadata())?; quickwit_authorize::execute_with_authorization( auth_token, self.inner.0.toggle_source(request.into_inner()), @@ -1874,7 +1874,7 @@ for ControlPlaneServiceGrpcServerAdapter { &self, request: tonic::Request, ) -> Result, tonic::Status> { - let auth_token = quickwit_authorize::get_auth_token(request.metadata())?; + let auth_token = quickwit_authorize::extract_auth_token(request.metadata())?; quickwit_authorize::execute_with_authorization( auth_token, self.inner.0.delete_source(request.into_inner()), @@ -1887,7 +1887,7 @@ for ControlPlaneServiceGrpcServerAdapter { &self, request: tonic::Request, ) -> Result, tonic::Status> { - let auth_token = quickwit_authorize::get_auth_token(request.metadata())?; + let auth_token = quickwit_authorize::extract_auth_token(request.metadata())?; quickwit_authorize::execute_with_authorization( auth_token, self.inner.0.get_or_create_open_shards(request.into_inner()), @@ -1900,7 +1900,7 @@ for ControlPlaneServiceGrpcServerAdapter { &self, request: tonic::Request, ) -> Result, tonic::Status> { - let auth_token = quickwit_authorize::get_auth_token(request.metadata())?; + let auth_token = quickwit_authorize::extract_auth_token(request.metadata())?; quickwit_authorize::execute_with_authorization( auth_token, self.inner.0.advise_reset_shards(request.into_inner()), @@ -1913,7 +1913,7 @@ for ControlPlaneServiceGrpcServerAdapter { &self, request: tonic::Request, ) -> Result, tonic::Status> { - let auth_token = quickwit_authorize::get_auth_token(request.metadata())?; + let auth_token = quickwit_authorize::extract_auth_token(request.metadata())?; quickwit_authorize::execute_with_authorization( auth_token, self.inner.0.prune_shards(request.into_inner()), diff --git a/quickwit/quickwit-proto/src/codegen/quickwit/quickwit.developer.rs b/quickwit/quickwit-proto/src/codegen/quickwit/quickwit.developer.rs index 5d99aaa7532..8c63b430a84 100644 --- a/quickwit/quickwit-proto/src/codegen/quickwit/quickwit.developer.rs +++ b/quickwit/quickwit-proto/src/codegen/quickwit/quickwit.developer.rs @@ -481,7 +481,7 @@ for DeveloperServiceGrpcServerAdapter { &self, request: tonic::Request, ) -> Result, tonic::Status> { - let auth_token = quickwit_authorize::get_auth_token(request.metadata())?; + let auth_token = quickwit_authorize::extract_auth_token(request.metadata())?; quickwit_authorize::execute_with_authorization( auth_token, self.inner.0.get_debug_info(request.into_inner()), diff --git a/quickwit/quickwit-proto/src/codegen/quickwit/quickwit.indexing.rs b/quickwit/quickwit-proto/src/codegen/quickwit/quickwit.indexing.rs index 46c66feec09..f811651d007 100644 --- a/quickwit/quickwit-proto/src/codegen/quickwit/quickwit.indexing.rs +++ b/quickwit/quickwit-proto/src/codegen/quickwit/quickwit.indexing.rs @@ -494,7 +494,7 @@ for IndexingServiceGrpcServerAdapter { &self, request: tonic::Request, ) -> Result, tonic::Status> { - let auth_token = quickwit_authorize::get_auth_token(request.metadata())?; + let auth_token = quickwit_authorize::extract_auth_token(request.metadata())?; quickwit_authorize::execute_with_authorization( auth_token, self.inner.0.apply_indexing_plan(request.into_inner()), diff --git a/quickwit/quickwit-proto/src/codegen/quickwit/quickwit.ingest.ingester.rs b/quickwit/quickwit-proto/src/codegen/quickwit/quickwit.ingest.ingester.rs index 1d8294510ec..1058fc155f0 100644 --- a/quickwit/quickwit-proto/src/codegen/quickwit/quickwit.ingest.ingester.rs +++ b/quickwit/quickwit-proto/src/codegen/quickwit/quickwit.ingest.ingester.rs @@ -2061,7 +2061,7 @@ where &self, request: quickwit_common::ServiceStream, ) -> crate::ingest::IngestV2Result> { - let tonic_request = quickwit_authorize::build_tonic_stream_request_with_auth_token( + let tonic_request = quickwit_authorize::build_tonic_request_with_auth_token( request, )?; self.inner @@ -2239,7 +2239,7 @@ for IngesterServiceGrpcServerAdapter { &self, request: tonic::Request, ) -> Result, tonic::Status> { - let auth_token = quickwit_authorize::get_auth_token(request.metadata())?; + let auth_token = quickwit_authorize::extract_auth_token(request.metadata())?; quickwit_authorize::execute_with_authorization( auth_token, self.inner.0.persist(request.into_inner()), @@ -2255,7 +2255,7 @@ for IngesterServiceGrpcServerAdapter { &self, request: tonic::Request>, ) -> Result, tonic::Status> { - let auth_token = quickwit_authorize::get_auth_token(request.metadata())?; + let auth_token = quickwit_authorize::extract_auth_token(request.metadata())?; quickwit_authorize::execute_with_authorization( auth_token, self @@ -2279,7 +2279,7 @@ for IngesterServiceGrpcServerAdapter { &self, request: tonic::Request, ) -> Result, tonic::Status> { - let auth_token = quickwit_authorize::get_auth_token(request.metadata())?; + let auth_token = quickwit_authorize::extract_auth_token(request.metadata())?; quickwit_authorize::execute_with_authorization( auth_token, self.inner.0.open_fetch_stream(request.into_inner()), @@ -2297,7 +2297,7 @@ for IngesterServiceGrpcServerAdapter { &self, request: tonic::Request, ) -> Result, tonic::Status> { - let auth_token = quickwit_authorize::get_auth_token(request.metadata())?; + let auth_token = quickwit_authorize::extract_auth_token(request.metadata())?; quickwit_authorize::execute_with_authorization( auth_token, self.inner.0.open_observation_stream(request.into_inner()), @@ -2312,7 +2312,7 @@ for IngesterServiceGrpcServerAdapter { &self, request: tonic::Request, ) -> Result, tonic::Status> { - let auth_token = quickwit_authorize::get_auth_token(request.metadata())?; + let auth_token = quickwit_authorize::extract_auth_token(request.metadata())?; quickwit_authorize::execute_with_authorization( auth_token, self.inner.0.init_shards(request.into_inner()), @@ -2325,7 +2325,7 @@ for IngesterServiceGrpcServerAdapter { &self, request: tonic::Request, ) -> Result, tonic::Status> { - let auth_token = quickwit_authorize::get_auth_token(request.metadata())?; + let auth_token = quickwit_authorize::extract_auth_token(request.metadata())?; quickwit_authorize::execute_with_authorization( auth_token, self.inner.0.retain_shards(request.into_inner()), @@ -2338,7 +2338,7 @@ for IngesterServiceGrpcServerAdapter { &self, request: tonic::Request, ) -> Result, tonic::Status> { - let auth_token = quickwit_authorize::get_auth_token(request.metadata())?; + let auth_token = quickwit_authorize::extract_auth_token(request.metadata())?; quickwit_authorize::execute_with_authorization( auth_token, self.inner.0.truncate_shards(request.into_inner()), @@ -2351,7 +2351,7 @@ for IngesterServiceGrpcServerAdapter { &self, request: tonic::Request, ) -> Result, tonic::Status> { - let auth_token = quickwit_authorize::get_auth_token(request.metadata())?; + let auth_token = quickwit_authorize::extract_auth_token(request.metadata())?; quickwit_authorize::execute_with_authorization( auth_token, self.inner.0.close_shards(request.into_inner()), @@ -2364,7 +2364,7 @@ for IngesterServiceGrpcServerAdapter { &self, request: tonic::Request, ) -> Result, tonic::Status> { - let auth_token = quickwit_authorize::get_auth_token(request.metadata())?; + let auth_token = quickwit_authorize::extract_auth_token(request.metadata())?; quickwit_authorize::execute_with_authorization( auth_token, self.inner.0.decommission(request.into_inner()), diff --git a/quickwit/quickwit-proto/src/codegen/quickwit/quickwit.ingest.router.rs b/quickwit/quickwit-proto/src/codegen/quickwit/quickwit.ingest.router.rs index 3c99756ac7f..ddbe6ed5d6b 100644 --- a/quickwit/quickwit-proto/src/codegen/quickwit/quickwit.ingest.router.rs +++ b/quickwit/quickwit-proto/src/codegen/quickwit/quickwit.ingest.router.rs @@ -607,7 +607,7 @@ for IngestRouterServiceGrpcServerAdapter { &self, request: tonic::Request, ) -> Result, tonic::Status> { - let auth_token = quickwit_authorize::get_auth_token(request.metadata())?; + let auth_token = quickwit_authorize::extract_auth_token(request.metadata())?; quickwit_authorize::execute_with_authorization( auth_token, self.inner.0.ingest(request.into_inner()), diff --git a/quickwit/quickwit-proto/src/codegen/quickwit/quickwit.metastore.rs b/quickwit/quickwit-proto/src/codegen/quickwit/quickwit.metastore.rs index 9b32e28bd91..aadd37c961c 100644 --- a/quickwit/quickwit-proto/src/codegen/quickwit/quickwit.metastore.rs +++ b/quickwit/quickwit-proto/src/codegen/quickwit/quickwit.metastore.rs @@ -5417,7 +5417,7 @@ for MetastoreServiceGrpcServerAdapter { &self, request: tonic::Request, ) -> Result, tonic::Status> { - let auth_token = quickwit_authorize::get_auth_token(request.metadata())?; + let auth_token = quickwit_authorize::extract_auth_token(request.metadata())?; quickwit_authorize::execute_with_authorization( auth_token, self.inner.0.create_index(request.into_inner()), @@ -5430,7 +5430,7 @@ for MetastoreServiceGrpcServerAdapter { &self, request: tonic::Request, ) -> Result, tonic::Status> { - let auth_token = quickwit_authorize::get_auth_token(request.metadata())?; + let auth_token = quickwit_authorize::extract_auth_token(request.metadata())?; quickwit_authorize::execute_with_authorization( auth_token, self.inner.0.update_index(request.into_inner()), @@ -5443,7 +5443,7 @@ for MetastoreServiceGrpcServerAdapter { &self, request: tonic::Request, ) -> Result, tonic::Status> { - let auth_token = quickwit_authorize::get_auth_token(request.metadata())?; + let auth_token = quickwit_authorize::extract_auth_token(request.metadata())?; quickwit_authorize::execute_with_authorization( auth_token, self.inner.0.index_metadata(request.into_inner()), @@ -5456,7 +5456,7 @@ for MetastoreServiceGrpcServerAdapter { &self, request: tonic::Request, ) -> Result, tonic::Status> { - let auth_token = quickwit_authorize::get_auth_token(request.metadata())?; + let auth_token = quickwit_authorize::extract_auth_token(request.metadata())?; quickwit_authorize::execute_with_authorization( auth_token, self.inner.0.indexes_metadata(request.into_inner()), @@ -5469,7 +5469,7 @@ for MetastoreServiceGrpcServerAdapter { &self, request: tonic::Request, ) -> Result, tonic::Status> { - let auth_token = quickwit_authorize::get_auth_token(request.metadata())?; + let auth_token = quickwit_authorize::extract_auth_token(request.metadata())?; quickwit_authorize::execute_with_authorization( auth_token, self.inner.0.list_indexes_metadata(request.into_inner()), @@ -5482,7 +5482,7 @@ for MetastoreServiceGrpcServerAdapter { &self, request: tonic::Request, ) -> Result, tonic::Status> { - let auth_token = quickwit_authorize::get_auth_token(request.metadata())?; + let auth_token = quickwit_authorize::extract_auth_token(request.metadata())?; quickwit_authorize::execute_with_authorization( auth_token, self.inner.0.delete_index(request.into_inner()), @@ -5498,7 +5498,7 @@ for MetastoreServiceGrpcServerAdapter { &self, request: tonic::Request, ) -> Result, tonic::Status> { - let auth_token = quickwit_authorize::get_auth_token(request.metadata())?; + let auth_token = quickwit_authorize::extract_auth_token(request.metadata())?; quickwit_authorize::execute_with_authorization( auth_token, self.inner.0.list_splits(request.into_inner()), @@ -5513,7 +5513,7 @@ for MetastoreServiceGrpcServerAdapter { &self, request: tonic::Request, ) -> Result, tonic::Status> { - let auth_token = quickwit_authorize::get_auth_token(request.metadata())?; + let auth_token = quickwit_authorize::extract_auth_token(request.metadata())?; quickwit_authorize::execute_with_authorization( auth_token, self.inner.0.stage_splits(request.into_inner()), @@ -5526,7 +5526,7 @@ for MetastoreServiceGrpcServerAdapter { &self, request: tonic::Request, ) -> Result, tonic::Status> { - let auth_token = quickwit_authorize::get_auth_token(request.metadata())?; + let auth_token = quickwit_authorize::extract_auth_token(request.metadata())?; quickwit_authorize::execute_with_authorization( auth_token, self.inner.0.publish_splits(request.into_inner()), @@ -5539,7 +5539,7 @@ for MetastoreServiceGrpcServerAdapter { &self, request: tonic::Request, ) -> Result, tonic::Status> { - let auth_token = quickwit_authorize::get_auth_token(request.metadata())?; + let auth_token = quickwit_authorize::extract_auth_token(request.metadata())?; quickwit_authorize::execute_with_authorization( auth_token, self.inner.0.mark_splits_for_deletion(request.into_inner()), @@ -5552,7 +5552,7 @@ for MetastoreServiceGrpcServerAdapter { &self, request: tonic::Request, ) -> Result, tonic::Status> { - let auth_token = quickwit_authorize::get_auth_token(request.metadata())?; + let auth_token = quickwit_authorize::extract_auth_token(request.metadata())?; quickwit_authorize::execute_with_authorization( auth_token, self.inner.0.delete_splits(request.into_inner()), @@ -5565,7 +5565,7 @@ for MetastoreServiceGrpcServerAdapter { &self, request: tonic::Request, ) -> Result, tonic::Status> { - let auth_token = quickwit_authorize::get_auth_token(request.metadata())?; + let auth_token = quickwit_authorize::extract_auth_token(request.metadata())?; quickwit_authorize::execute_with_authorization( auth_token, self.inner.0.add_source(request.into_inner()), @@ -5578,7 +5578,7 @@ for MetastoreServiceGrpcServerAdapter { &self, request: tonic::Request, ) -> Result, tonic::Status> { - let auth_token = quickwit_authorize::get_auth_token(request.metadata())?; + let auth_token = quickwit_authorize::extract_auth_token(request.metadata())?; quickwit_authorize::execute_with_authorization( auth_token, self.inner.0.toggle_source(request.into_inner()), @@ -5591,7 +5591,7 @@ for MetastoreServiceGrpcServerAdapter { &self, request: tonic::Request, ) -> Result, tonic::Status> { - let auth_token = quickwit_authorize::get_auth_token(request.metadata())?; + let auth_token = quickwit_authorize::extract_auth_token(request.metadata())?; quickwit_authorize::execute_with_authorization( auth_token, self.inner.0.delete_source(request.into_inner()), @@ -5604,7 +5604,7 @@ for MetastoreServiceGrpcServerAdapter { &self, request: tonic::Request, ) -> Result, tonic::Status> { - let auth_token = quickwit_authorize::get_auth_token(request.metadata())?; + let auth_token = quickwit_authorize::extract_auth_token(request.metadata())?; quickwit_authorize::execute_with_authorization( auth_token, self.inner.0.reset_source_checkpoint(request.into_inner()), @@ -5617,7 +5617,7 @@ for MetastoreServiceGrpcServerAdapter { &self, request: tonic::Request, ) -> Result, tonic::Status> { - let auth_token = quickwit_authorize::get_auth_token(request.metadata())?; + let auth_token = quickwit_authorize::extract_auth_token(request.metadata())?; quickwit_authorize::execute_with_authorization( auth_token, self.inner.0.last_delete_opstamp(request.into_inner()), @@ -5630,7 +5630,7 @@ for MetastoreServiceGrpcServerAdapter { &self, request: tonic::Request, ) -> Result, tonic::Status> { - let auth_token = quickwit_authorize::get_auth_token(request.metadata())?; + let auth_token = quickwit_authorize::extract_auth_token(request.metadata())?; quickwit_authorize::execute_with_authorization( auth_token, self.inner.0.create_delete_task(request.into_inner()), @@ -5643,7 +5643,7 @@ for MetastoreServiceGrpcServerAdapter { &self, request: tonic::Request, ) -> Result, tonic::Status> { - let auth_token = quickwit_authorize::get_auth_token(request.metadata())?; + let auth_token = quickwit_authorize::extract_auth_token(request.metadata())?; quickwit_authorize::execute_with_authorization( auth_token, self.inner.0.update_splits_delete_opstamp(request.into_inner()), @@ -5656,7 +5656,7 @@ for MetastoreServiceGrpcServerAdapter { &self, request: tonic::Request, ) -> Result, tonic::Status> { - let auth_token = quickwit_authorize::get_auth_token(request.metadata())?; + let auth_token = quickwit_authorize::extract_auth_token(request.metadata())?; quickwit_authorize::execute_with_authorization( auth_token, self.inner.0.list_delete_tasks(request.into_inner()), @@ -5669,7 +5669,7 @@ for MetastoreServiceGrpcServerAdapter { &self, request: tonic::Request, ) -> Result, tonic::Status> { - let auth_token = quickwit_authorize::get_auth_token(request.metadata())?; + let auth_token = quickwit_authorize::extract_auth_token(request.metadata())?; quickwit_authorize::execute_with_authorization( auth_token, self.inner.0.list_stale_splits(request.into_inner()), @@ -5682,7 +5682,7 @@ for MetastoreServiceGrpcServerAdapter { &self, request: tonic::Request, ) -> Result, tonic::Status> { - let auth_token = quickwit_authorize::get_auth_token(request.metadata())?; + let auth_token = quickwit_authorize::extract_auth_token(request.metadata())?; quickwit_authorize::execute_with_authorization( auth_token, self.inner.0.open_shards(request.into_inner()), @@ -5695,7 +5695,7 @@ for MetastoreServiceGrpcServerAdapter { &self, request: tonic::Request, ) -> Result, tonic::Status> { - let auth_token = quickwit_authorize::get_auth_token(request.metadata())?; + let auth_token = quickwit_authorize::extract_auth_token(request.metadata())?; quickwit_authorize::execute_with_authorization( auth_token, self.inner.0.acquire_shards(request.into_inner()), @@ -5708,7 +5708,7 @@ for MetastoreServiceGrpcServerAdapter { &self, request: tonic::Request, ) -> Result, tonic::Status> { - let auth_token = quickwit_authorize::get_auth_token(request.metadata())?; + let auth_token = quickwit_authorize::extract_auth_token(request.metadata())?; quickwit_authorize::execute_with_authorization( auth_token, self.inner.0.delete_shards(request.into_inner()), @@ -5721,7 +5721,7 @@ for MetastoreServiceGrpcServerAdapter { &self, request: tonic::Request, ) -> Result, tonic::Status> { - let auth_token = quickwit_authorize::get_auth_token(request.metadata())?; + let auth_token = quickwit_authorize::extract_auth_token(request.metadata())?; quickwit_authorize::execute_with_authorization( auth_token, self.inner.0.prune_shards(request.into_inner()), @@ -5734,7 +5734,7 @@ for MetastoreServiceGrpcServerAdapter { &self, request: tonic::Request, ) -> Result, tonic::Status> { - let auth_token = quickwit_authorize::get_auth_token(request.metadata())?; + let auth_token = quickwit_authorize::extract_auth_token(request.metadata())?; quickwit_authorize::execute_with_authorization( auth_token, self.inner.0.list_shards(request.into_inner()), @@ -5747,7 +5747,7 @@ for MetastoreServiceGrpcServerAdapter { &self, request: tonic::Request, ) -> Result, tonic::Status> { - let auth_token = quickwit_authorize::get_auth_token(request.metadata())?; + let auth_token = quickwit_authorize::extract_auth_token(request.metadata())?; quickwit_authorize::execute_with_authorization( auth_token, self.inner.0.create_index_template(request.into_inner()), @@ -5760,7 +5760,7 @@ for MetastoreServiceGrpcServerAdapter { &self, request: tonic::Request, ) -> Result, tonic::Status> { - let auth_token = quickwit_authorize::get_auth_token(request.metadata())?; + let auth_token = quickwit_authorize::extract_auth_token(request.metadata())?; quickwit_authorize::execute_with_authorization( auth_token, self.inner.0.get_index_template(request.into_inner()), @@ -5773,7 +5773,7 @@ for MetastoreServiceGrpcServerAdapter { &self, request: tonic::Request, ) -> Result, tonic::Status> { - let auth_token = quickwit_authorize::get_auth_token(request.metadata())?; + let auth_token = quickwit_authorize::extract_auth_token(request.metadata())?; quickwit_authorize::execute_with_authorization( auth_token, self.inner.0.find_index_template_matches(request.into_inner()), @@ -5786,7 +5786,7 @@ for MetastoreServiceGrpcServerAdapter { &self, request: tonic::Request, ) -> Result, tonic::Status> { - let auth_token = quickwit_authorize::get_auth_token(request.metadata())?; + let auth_token = quickwit_authorize::extract_auth_token(request.metadata())?; quickwit_authorize::execute_with_authorization( auth_token, self.inner.0.list_index_templates(request.into_inner()), @@ -5799,7 +5799,7 @@ for MetastoreServiceGrpcServerAdapter { &self, request: tonic::Request, ) -> Result, tonic::Status> { - let auth_token = quickwit_authorize::get_auth_token(request.metadata())?; + let auth_token = quickwit_authorize::extract_auth_token(request.metadata())?; quickwit_authorize::execute_with_authorization( auth_token, self.inner.0.delete_index_templates(request.into_inner()), diff --git a/quickwit/quickwit-serve/Cargo.toml b/quickwit/quickwit-serve/Cargo.toml index b82db775761..f86ade32293 100644 --- a/quickwit/quickwit-serve/Cargo.toml +++ b/quickwit/quickwit-serve/Cargo.toml @@ -50,6 +50,7 @@ warp = { workspace = true } zstd = { workspace = true } quickwit-actors = { workspace = true } +quickwit-authorize = { workspace = true, features = ["enterprise"], optional = true } quickwit-cluster = { workspace = true } quickwit-common = { workspace = true } quickwit-config = { workspace = true } @@ -97,4 +98,5 @@ quickwit-storage = { workspace = true, features = ["testsuite"] } pprof = [ "dep:pprof" ] +enterprise = ["dep:quickwit-authorize"] testsuite = [] diff --git a/quickwit/quickwit-serve/src/lib.rs b/quickwit/quickwit-serve/src/lib.rs index 6a7a252a0cd..62a89fee7ab 100644 --- a/quickwit/quickwit-serve/src/lib.rs +++ b/quickwit/quickwit-serve/src/lib.rs @@ -429,10 +429,23 @@ pub async fn serve_quickwit( 100 }; // These layers apply to all the RPCs of the metastore. - let shared_layer = ServiceBuilder::new() + let shared_layer_builder = ServiceBuilder::new() .layer(METASTORE_GRPC_SERVER_METRICS_LAYER.clone()) - .layer(LoadShedLayer::new(max_in_flight_requests)) - .into_inner(); + .layer(LoadShedLayer::new(max_in_flight_requests)); + + let shared_layer; + + #[cfg(feature = "enterprise")] + { + use quickwit_authorize::AuthorizationLayer; + shared_layer = shared_layer_builder.layer(AuthorizationLayer).into_inner(); + } + + #[cfg(not(feature = "enterprise"))] + { + shared_layer = shared_layer_builder.into_inner(); + } + let broker_layer = EventListenerLayer::new(event_broker.clone()); let metastore = MetastoreServiceClient::tower() .stack_layer(shared_layer) diff --git a/quickwit/quickwit-serve/src/rest.rs b/quickwit/quickwit-serve/src/rest.rs index 3c83c2d84f1..2c79513e0f5 100644 --- a/quickwit/quickwit-serve/src/rest.rs +++ b/quickwit/quickwit-serve/src/rest.rs @@ -198,7 +198,7 @@ pub(crate) async fn start_rest_server( let compression_predicate = CompressionPredicate::from_env().and(NotForContentType::IMAGES); let cors = build_cors(&quickwit_services.node_config.rest_config.cors_allow_origins); - let service = ServiceBuilder::new() + let service_builder = ServiceBuilder::new() .layer( CompressionLayer::new() .zstd(true) @@ -206,8 +206,21 @@ pub(crate) async fn start_rest_server( .quality(tower_http::CompressionLevel::Fastest) .compress_when(compression_predicate), ) - .layer(cors) - .service(warp_service); + .layer(cors); + + let service; + + #[cfg(feature = "enterprise")] + { + service = service_builder + .layer(quickwit_authorize::AuthorizationTokenExtractionLayer) + .service(warp_service); + } + + #[cfg(not(feature = "enterprise"))] + { + service = service_builder.service(warp_service); + } let rest_listen_addr = tcp_listener.local_addr()?; info!( From 5c925f469eebbbdb7a8e144937d369462244cb3d Mon Sep 17 00:00:00 2001 From: Paul Masurel Date: Wed, 6 Nov 2024 09:25:19 +0900 Subject: [PATCH 6/6] moving quickwit service --- quickwit/Cargo.lock | 23 +-- quickwit/quickwit-authorize/Cargo.toml | 1 + .../src/enterprise/authorization_layer.rs | 30 ++-- .../authorization_token_extraction_layer.rs | 30 ++-- .../quickwit-authorize/src/enterprise/cli.rs | 92 ++++++++++++ .../quickwit-authorize/src/enterprise/mod.rs | 141 +++++++++++++---- quickwit/quickwit-cli/Cargo.toml | 3 +- quickwit/quickwit-cli/src/lib.rs | 2 +- quickwit/quickwit-cli/src/service.rs | 2 +- quickwit/quickwit-cli/src/tool.rs | 48 +++++- quickwit/quickwit-cluster/src/lib.rs | 2 +- quickwit/quickwit-cluster/src/node.rs | 2 +- quickwit/quickwit-common/src/lib.rs | 3 + .../src/service.rs | 16 +- quickwit/quickwit-config/Cargo.toml | 1 - quickwit/quickwit-config/src/lib.rs | 1 - .../quickwit-config/src/node_config/mod.rs | 2 +- .../src/node_config/serialize.rs | 8 +- .../src/control_plane.rs | 3 +- quickwit/quickwit-proto/src/authorization.rs | 142 +++++++++++++++--- .../quickwit-serve/src/developer_api/debug.rs | 2 +- .../src/developer_api/server.rs | 2 +- quickwit/quickwit-serve/src/grpc.rs | 2 +- quickwit/quickwit-serve/src/lib.rs | 3 +- 24 files changed, 431 insertions(+), 130 deletions(-) create mode 100644 quickwit/quickwit-authorize/src/enterprise/cli.rs rename quickwit/{quickwit-config => quickwit-common}/src/service.rs (85%) diff --git a/quickwit/Cargo.lock b/quickwit/Cargo.lock index d1df21bb5e7..d6ffd77c6f0 100644 --- a/quickwit/Cargo.lock +++ b/quickwit/Cargo.lock @@ -2459,26 +2459,6 @@ dependencies = [ "encoding_rs", ] -[[package]] -name = "enum-iterator" -version = "1.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9fd242f399be1da0a5354aa462d57b4ab2b4ee0683cc552f7c007d2d12d36e94" -dependencies = [ - "enum-iterator-derive", -] - -[[package]] -name = "enum-iterator-derive" -version = "1.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a1ab991c1362ac86c61ab6f556cff143daa22e5a15e4e189df818b2fd19fe65b" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.86", -] - [[package]] name = "env_logger" version = "0.10.2" @@ -5975,6 +5955,7 @@ dependencies = [ "biscuit-auth", "futures", "http 0.2.12", + "itertools 0.13.0", "pin-project", "quickwit-common", "serde", @@ -6027,6 +6008,7 @@ dependencies = [ "opentelemetry-otlp", "predicates 3.1.2", "quickwit-actors", + "quickwit-authorize", "quickwit-cluster", "quickwit-common", "quickwit-config", @@ -6173,7 +6155,6 @@ dependencies = [ "bytesize", "chrono", "cron", - "enum-iterator", "http 0.2.12", "http-serde 1.1.3", "humantime", diff --git a/quickwit/quickwit-authorize/Cargo.toml b/quickwit/quickwit-authorize/Cargo.toml index 1b21761a408..e74b105e00d 100644 --- a/quickwit/quickwit-authorize/Cargo.toml +++ b/quickwit/quickwit-authorize/Cargo.toml @@ -14,6 +14,7 @@ tower = { workspace = true} biscuit-auth = { workspace = true, optional=true } futures = { workspace = true } http = { workspace = true } +itertools = { workspace = true } tokio-inherit-task-local = { workspace = true } serde = { workspace = true } thiserror = { workspace = true } diff --git a/quickwit/quickwit-authorize/src/enterprise/authorization_layer.rs b/quickwit/quickwit-authorize/src/enterprise/authorization_layer.rs index ae29555ee02..891cf105203 100644 --- a/quickwit/quickwit-authorize/src/enterprise/authorization_layer.rs +++ b/quickwit/quickwit-authorize/src/enterprise/authorization_layer.rs @@ -1,21 +1,23 @@ -// Copyright (C) 2024 Quickwit, Inc. +// The Quickwit Enterprise Edition (EE) license +// Copyright (c) 2024-present Quickwit Inc. // -// Quickwit is offered under the AGPL v3.0 and as commercial software. -// For commercial licensing, contact us at hello@quickwit.io. +// With regard to the Quickwit Software: // -// AGPL: -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU Affero General Public License as -// published by the Free Software Foundation, either version 3 of the -// License, or (at your option) any later version. +// This software and associated documentation files (the "Software") may only be +// used in production, if you (and any entity that you represent) hold a valid +// Quickwit Enterprise license corresponding to your usage. // -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Affero General Public License for more details. +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. // -// You should have received a copy of the GNU Affero General Public License -// along with this program. If not, see . +// For all third party components incorporated into the Quickwit Software, those +// components are licensed under the original license provided by the owner of the +// applicable component. use std::fmt; use std::task::{Context, Poll}; diff --git a/quickwit/quickwit-authorize/src/enterprise/authorization_token_extraction_layer.rs b/quickwit/quickwit-authorize/src/enterprise/authorization_token_extraction_layer.rs index a2a9b08bfef..c32f1293200 100644 --- a/quickwit/quickwit-authorize/src/enterprise/authorization_token_extraction_layer.rs +++ b/quickwit/quickwit-authorize/src/enterprise/authorization_token_extraction_layer.rs @@ -1,21 +1,23 @@ -// Copyright (C) 2024 Quickwit, Inc. +// The Quickwit Enterprise Edition (EE) license +// Copyright (c) 2024-present Quickwit Inc. // -// Quickwit is offered under the AGPL v3.0 and as commercial software. -// For commercial licensing, contact us at hello@quickwit.io. +// With regard to the Quickwit Software: // -// AGPL: -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU Affero General Public License as -// published by the Free Software Foundation, either version 3 of the -// License, or (at your option) any later version. +// This software and associated documentation files (the "Software") may only be +// used in production, if you (and any entity that you represent) hold a valid +// Quickwit Enterprise license corresponding to your usage. // -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Affero General Public License for more details. +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. // -// You should have received a copy of the GNU Affero General Public License -// along with this program. If not, see . +// For all third party components incorporated into the Quickwit Software, those +// components are licensed under the original license provided by the owner of the +// applicable component. use std::task::{Context, Poll}; diff --git a/quickwit/quickwit-authorize/src/enterprise/cli.rs b/quickwit/quickwit-authorize/src/enterprise/cli.rs new file mode 100644 index 00000000000..aa311bfebe9 --- /dev/null +++ b/quickwit/quickwit-authorize/src/enterprise/cli.rs @@ -0,0 +1,92 @@ +// Copyright (C) 2024 Quickwit, Inc. +// +// Quickwit is offered under the AGPL v3.0 and as commercial software. +// For commercial licensing, contact us at hello@quickwit.io. +// +// AGPL: +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as +// published by the Free Software Foundation, either version 3 of the +// License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + +use std::str::FromStr; + +use anyhow::Context; +use biscuit_auth::builder::{fact, string}; +use biscuit_auth::KeyPair; +use quickwit_common::QuickwitService; + +use super::AuthorizationToken; + +#[derive(Debug, Eq, PartialEq)] +pub struct GenerateAuthTokensArgs { + pub root_private_key: Option, + pub services: Vec, +} + +impl GenerateAuthTokensArgs { + fn list_services(self) -> anyhow::Result>> { + if self.services.is_empty() { + let mut default_services_set: Vec> = + vec![QuickwitService::supported_services().into_iter().collect()]; + for individual_service in QuickwitService::supported_services() { + default_services_set.push(vec![individual_service]); + } + return Ok(default_services_set); + } else { + let mut services_set: Vec> = vec![]; + for services_str in self.services { + let services = services_str + .split(",") + .map(QuickwitService::from_str) + .collect::, _>>() + .context("failed to parse quickwit service name")?; + services_set.push(services); + } + return Ok(services_set); + } + } +} + +fn generate_token_for_services( + key_pair: &KeyPair, + services: &[QuickwitService], +) -> anyhow::Result { + let mut biscuit_builder = biscuit_auth::Biscuit::builder(); + for service in services { + biscuit_builder.add_fact(fact("service", &[string(service.as_str())]))?; + } + let biscuit = biscuit_builder + .build(&key_pair) + .context("failed ot generate token")?; + Ok(AuthorizationToken::from(biscuit)) +} + +pub async fn generate_auth_tokens_cli(args: GenerateAuthTokensArgs) -> anyhow::Result<()> { + let key_pair = if let Some(private_key_hex) = &args.root_private_key { + let private_key = biscuit_auth::PrivateKey::from_bytes_hex(private_key_hex) + .context("invalid root private key")?; + biscuit_auth::KeyPair::from(&private_key) + } else { + println!("generating keys"); + biscuit_auth::KeyPair::new() + }; + println!("Private root key: {}", key_pair.private().to_bytes_hex()); + println!("Public root key: {}", key_pair.public().to_bytes_hex()); + for services in args.list_services()? { + use itertools::Itertools; + let token = generate_token_for_services(&key_pair, &services)?; + let services_str = services.iter().map(QuickwitService::as_str).join(","); + println!("--\nService token for {services_str}\n{token}"); + } + + Ok(()) +} diff --git a/quickwit/quickwit-authorize/src/enterprise/mod.rs b/quickwit/quickwit-authorize/src/enterprise/mod.rs index b8c64a5abf1..fea7b192930 100644 --- a/quickwit/quickwit-authorize/src/enterprise/mod.rs +++ b/quickwit/quickwit-authorize/src/enterprise/mod.rs @@ -27,6 +27,7 @@ use std::str::FromStr; use std::sync::{Arc, OnceLock}; use anyhow::Context; +pub mod cli; pub use authorization_layer::AuthorizationLayer; pub use authorization_token_extraction_layer::AuthorizationTokenExtractionLayer; use biscuit_auth::macros::authorizer; @@ -51,6 +52,16 @@ impl AuthorizationToken { pub fn into_biscuit(self) -> Arc { self.0.clone() } + + pub fn print(&self) -> anyhow::Result<()> { + let biscuit = &self.0; + for i in 0..biscuit.block_count() { + let block = biscuit.print_block_source(i)?; + println!("--- Block #{} ---", i + 1); + println!("{block}\n"); + } + Ok(()) + } } impl From for AuthorizationToken { @@ -61,7 +72,8 @@ impl From for AuthorizationToken { impl std::fmt::Display for AuthorizationToken { fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { - self.0.fmt(f) + let token_base_64 = self.0.to_base64().map_err(|_err| std::fmt::Error)?; + token_base_64.fmt(f) } } @@ -71,17 +83,19 @@ impl std::fmt::Debug for AuthorizationToken { } } -pub fn set_node_token_hex(node_token_hex: &str) -> anyhow::Result<()> { +pub fn set_node_token_base64(node_token_base64: &str) -> anyhow::Result<()> { + info!("set node token hex: {node_token_base64}"); let node_token = - AuthorizationToken::from_str(node_token_hex).context("failed to set node token")?; + AuthorizationToken::from_str(node_token_base64).context("failed to set node token")?; if NODE_TOKEN.set(node_token).is_err() { tracing::error!("node token was already initialized"); } Ok(()) } -pub fn set_root_public_key(root_key_hex: &str) -> anyhow::Result<()> { - let public_key = biscuit_auth::PublicKey::from_bytes_hex(root_key_hex) +pub fn set_root_public_key(root_key_base64: &str) -> anyhow::Result<()> { + info!(root_key = root_key_base64, "setting root public key"); + let public_key = biscuit_auth::PublicKey::from_bytes_hex(root_key_base64) .context("failed to parse root public key")?; let key_provider: Arc = Arc::new(public_key); set_root_key_provider(key_provider); @@ -106,39 +120,84 @@ impl FromStr for AuthorizationToken { fn from_str(token_base64: &str) -> Result { let root_key_provider = get_root_key_provider(); - let biscuit = Biscuit::from_base64(token_base64, root_key_provider)?; + let biscuit = Biscuit::from_base64(token_base64, root_key_provider) + .map_err(|_| AuthorizationError::InvalidToken)?; Ok(AuthorizationToken::from(biscuit)) } } const AUTHORIZATION_VALUE_PREFIX: &str = "Bearer "; -fn default_operation_authorizer( +fn default_authorizer( + request_family: RequestFamily, auth_token: &AuthorizationToken, ) -> Result { - let request_type = std::any::type_name::(); - let operation: &str = request_type.strip_suffix("Request").unwrap(); + let request_family_str = request_family.as_str(); + info!(request = request_family_str, "authorize"); let mut authorizer: Authorizer = authorizer!( r#" - operation({operation}); + request({request_family_str}); + + right($request) <- role($role), role_right($role, $request); + right($request) <- service($service), service_right($service, $request); + + service_right("control_plane", "index:read"); + service_right("control_plane", "index:write"); + service_right("control_plane", "index:admin"); + service_right("control_plane", "cluster"); + + service_right("indexer", "index:write"); + service_right("indexer", "index:read"); + service_right("indexer", "cluster"); + + service_right("searcher", "cluster"); + + service_right("janitor", "index:read"); + service_right("janitor", "cluster"); + service_right("janitor", "index:write"); // We generate the actual user role, by doing an union of the rights granted via roles. - user_right($operation) <- role($role), right($role, $operation); - user_right($operation, $resource) <- role($role), right($role, $operation, $resource); - user_right($operation) <- role("root"), operation($operation); - user_right($operation, $resource) <- role("root"), operation($operation), resource($resource); + // right($request) <- role($role), role_right($role, $request); + // right($operation, $resource) <- role($role), role_right($role, $operation, $resource); + // right($operation) <- role("root"), operation($operation); + // right($operation, $resource) <- role("root"), operation($operation), resource($resource); + // Finally we check that we have access to index1 and index2. - check all operation($operation), right($operation); + check all request($operation), right($operation); allow if true; "# ); authorizer.set_time(); - authorizer.add_token(&auth_token.0)?; + auth_token.print().unwrap(); + println!("{}", authorizer.print_world()); + authorizer + .add_token(&auth_token.0) + .map_err(|_| AuthorizationError::PermissionDenied)?; Ok(authorizer) } +#[derive(Default, Debug, Copy, Clone)] +pub enum RequestFamily { + #[default] + IndexRead, + IndexWrite, + IndexAdmin, + Cluster, +} + +impl RequestFamily { + pub fn as_str(&self) -> &'static str { + match self { + Self::IndexRead => "index:read", + Self::IndexWrite => "index:write", + Self::IndexAdmin => "index:admin", + Self::Cluster => "cluster", + } + } +} + pub trait Authorization { fn attenuate( &self, @@ -151,7 +210,11 @@ pub trait Authorization { &self, auth_token: &AuthorizationToken, ) -> Result { - default_operation_authorizer::(auth_token) + default_authorizer(Self::request_family(), auth_token) + } + + fn request_family() -> RequestFamily { + RequestFamily::default() } } @@ -164,23 +227,29 @@ pub trait StreamAuthorization { fn authorizer( auth_token: &AuthorizationToken, ) -> std::result::Result { - default_operation_authorizer::(&auth_token) + default_authorizer(Self::request_family(), &auth_token) } -} -impl From for AuthorizationError { - fn from(_token_error: biscuit_auth::error::Token) -> AuthorizationError { - AuthorizationError::InvalidToken + fn request_family() -> RequestFamily { + RequestFamily::IndexRead } } +// impl From for AuthorizationError { +// fn from(token_error: biscuit_auth::error::Token) -> AuthorizationError { +// error!(token_error=?token_error); +// AuthorizationError::InvalidToken +// } +// } + pub fn get_auth_token_from_str( authorization_header_value: &str, ) -> Result { let authorization_token_str: &str = authorization_header_value .strip_prefix(AUTHORIZATION_VALUE_PREFIX) .ok_or(AuthorizationError::InvalidToken)?; - let biscuit: Biscuit = Biscuit::from_base64(authorization_token_str, get_root_key_provider())?; + let biscuit: Biscuit = Biscuit::from_base64(authorization_token_str, get_root_key_provider()) + .map_err(|_| AuthorizationError::InvalidToken)?; Ok(AuthorizationToken::from(biscuit)) } @@ -211,8 +280,11 @@ pub fn authorize( auth_token: &AuthorizationToken, ) -> Result<(), AuthorizationError> { let mut authorizer = req.authorizer(auth_token)?; - authorizer.add_token(&auth_token.0)?; - authorizer.authorize()?; + info!("authorizer"); + authorizer + .authorize() + .map_err(|_err| AuthorizationError::PermissionDenied)?; + info!("authorize done"); Ok(()) } @@ -238,17 +310,24 @@ pub fn authorize_stream( auth_token: &AuthorizationToken, ) -> Result<(), AuthorizationError> { let mut authorizer = R::authorizer(auth_token)?; - authorizer.add_token(&auth_token.0)?; - authorizer.authorize()?; + authorizer + .add_token(&auth_token.0) + .map_err(|_| AuthorizationError::PermissionDenied)?; + authorizer + .authorize() + .map_err(|_| AuthorizationError::PermissionDenied)?; Ok(()) } pub fn authorize_request(req: &R) -> Result<(), AuthorizationError> { - let res = AUTHORIZATION_TOKEN - .try_with(|auth_token| authorize(req, auth_token)) - .unwrap_or(Err(AuthorizationError::AuthorizationTokenMissing)); info!("request authorization"); - res + let auth_token: AuthorizationToken = AUTHORIZATION_TOKEN + .try_with(|auth_token| auth_token.clone()) + .ok() + .or_else(|| NODE_TOKEN.get().cloned()) + .ok_or(AuthorizationError::AuthorizationTokenMissing)?; + info!(token=%auth_token, "auth token"); + authorize(req, &auth_token) } pub fn execute_with_authorization( diff --git a/quickwit/quickwit-cli/Cargo.toml b/quickwit/quickwit-cli/Cargo.toml index ec528e64ea9..c632f61bc58 100644 --- a/quickwit/quickwit-cli/Cargo.toml +++ b/quickwit/quickwit-cli/Cargo.toml @@ -53,6 +53,7 @@ tracing-opentelemetry = { workspace = true } tracing-subscriber = { workspace = true } quickwit-actors = { workspace = true } +quickwit-authorize = { workspace = true, optional = true, features = ["enterprise"] } quickwit-cluster = { workspace = true } quickwit-common = { workspace = true } quickwit-config = { workspace = true } @@ -79,7 +80,7 @@ quickwit-metastore = { workspace = true, features = ["testsuite"] } quickwit-storage = { workspace = true, features = ["testsuite"] } [features] -enterprise = ["quickwit-config/enterprise", "quickwit-ingest/enterprise", "quickwit-proto/enterprise", "quickwit-serve/enterprise"] +enterprise = ["quickwit-config/enterprise", "quickwit-ingest/enterprise", "quickwit-proto/enterprise", "quickwit-serve/enterprise", "dep:quickwit-authorize"] jemalloc = ["dep:tikv-jemalloc-ctl", "dep:tikv-jemallocator"] ci-test = [] pprof = ["quickwit-serve/pprof"] diff --git a/quickwit/quickwit-cli/src/lib.rs b/quickwit/quickwit-cli/src/lib.rs index 98029541f05..93a09854e1d 100644 --- a/quickwit/quickwit-cli/src/lib.rs +++ b/quickwit/quickwit-cli/src/lib.rs @@ -28,7 +28,7 @@ use dialoguer::theme::ColorfulTheme; use dialoguer::Confirm; use quickwit_common::runtimes::RuntimesConfig; use quickwit_common::uri::Uri; -use quickwit_config::service::QuickwitService; +use quickwit_common::QuickwitService; use quickwit_config::{ ConfigFormat, MetastoreConfigs, NodeConfig, SourceConfig, StorageConfigs, DEFAULT_QW_CONFIG_PATH, diff --git a/quickwit/quickwit-cli/src/service.rs b/quickwit/quickwit-cli/src/service.rs index 7c6314c0d14..476ab772366 100644 --- a/quickwit/quickwit-cli/src/service.rs +++ b/quickwit/quickwit-cli/src/service.rs @@ -27,7 +27,7 @@ use futures::future::select; use itertools::Itertools; use quickwit_common::runtimes::RuntimesConfig; use quickwit_common::uri::{Protocol, Uri}; -use quickwit_config::service::QuickwitService; +use quickwit_common::QuickwitService; use quickwit_config::NodeConfig; use quickwit_serve::tcp_listener::DefaultTcpListenerResolver; use quickwit_serve::{serve_quickwit, BuildInfo, EnvFilterReloadFn}; diff --git a/quickwit/quickwit-cli/src/tool.rs b/quickwit/quickwit-cli/src/tool.rs index f5b2c512d33..41dd8167778 100644 --- a/quickwit/quickwit-cli/src/tool.rs +++ b/quickwit/quickwit-cli/src/tool.rs @@ -34,7 +34,7 @@ use quickwit_cluster::{ChannelTransport, Cluster, ClusterMember, FailureDetector use quickwit_common::pubsub::EventBroker; use quickwit_common::runtimes::RuntimesConfig; use quickwit_common::uri::Uri; -use quickwit_config::service::QuickwitService; +use quickwit_common::QuickwitService; use quickwit_config::{ IndexerConfig, NodeConfig, SourceConfig, SourceInputFormat, SourceParams, TransformConfig, VecSourceParams, CLI_SOURCE_ID, @@ -66,7 +66,7 @@ use crate::{ }; pub fn build_tool_command() -> Command { - Command::new("tool") + let command = Command::new("tool") .about("Performs utility operations. Requires a node config.") .arg(config_cli_arg()) .subcommand( @@ -165,8 +165,24 @@ pub fn build_tool_command() -> Command { .display_order(2) .required(true), ]) - ) + ); + if cfg!(feature = "enterprise") { + command.subcommand( + Command::new("generate-auth-tokens") + .display_order(11) + .about("Generate authorization keys/tokens") + .args(&[ + arg!(--root "Root private key. If absent, a key pair will generated") + .display_order(1), // .required(false), + arg!(--services "Comma-separated list of services for which to generate authorization tokens") + .num_args(0..) + .display_order(2) + ]) + ) .arg_required_else_help(true) + } else { + command.arg_required_else_help(true) + } } #[derive(Debug, Eq, PartialEq)] @@ -225,6 +241,8 @@ pub enum ToolCliCommand { LocalSearch(LocalSearchArgs), Merge(MergeArgs), ExtractSplit(ExtractSplitArgs), + #[cfg(feature = "enterprise")] + GenerateAuthTokens(quickwit_authorize::cli::GenerateAuthTokensArgs), } impl ToolCliCommand { @@ -238,6 +256,8 @@ impl ToolCliCommand { "local-search" => Self::parse_local_search_args(submatches), "merge" => Self::parse_merge_args(submatches), "extract-split" => Self::parse_extract_split_args(submatches), + #[cfg(feature = "enterprise")] + "generate-auth-tokens" => Self::parse_generate_auth_tokens_args(submatches), _ => bail!("unknown tool subcommand `{subcommand}`"), } } @@ -388,6 +408,24 @@ impl ToolCliCommand { })) } + #[cfg(feature = "enterprise")] + fn parse_generate_auth_tokens_args(mut matches: ArgMatches) -> anyhow::Result { + let root_private_key = matches.remove_one::("root"); + let services_opt = matches.remove_many::("services"); + let services = if let Some(services) = services_opt { + services.collect() + } else { + Vec::new() + }; + + Ok(Self::GenerateAuthTokens( + quickwit_authorize::cli::GenerateAuthTokensArgs { + root_private_key, + services, + }, + )) + } + pub async fn execute(self) -> anyhow::Result<()> { match self { Self::GarbageCollect(args) => garbage_collect_index_cli(args).await, @@ -395,6 +433,10 @@ impl ToolCliCommand { Self::LocalSearch(args) => local_search_cli(args).await, Self::Merge(args) => merge_cli(args).await, Self::ExtractSplit(args) => extract_split_cli(args).await, + #[cfg(feature = "enterprise")] + Self::GenerateAuthTokens(args) => { + quickwit_authorize::cli::generate_auth_tokens_cli(args).await + } } } } diff --git a/quickwit/quickwit-cluster/src/lib.rs b/quickwit/quickwit-cluster/src/lib.rs index 8077d0a229a..55a44fe6b0c 100644 --- a/quickwit/quickwit-cluster/src/lib.rs +++ b/quickwit/quickwit-cluster/src/lib.rs @@ -37,7 +37,7 @@ use chitchat::{ChitchatMessage, Serializable}; pub use chitchat::{FailureDetectorConfig, KeyChangeEvent, ListenerHandle}; pub use grpc_service::cluster_grpc_server; use quickwit_common::metrics::IntCounter; -use quickwit_config::service::QuickwitService; +use quickwit_common::QuickwitService; use quickwit_config::NodeConfig; use quickwit_proto::indexing::CpuCapacity; use time::OffsetDateTime; diff --git a/quickwit/quickwit-cluster/src/node.rs b/quickwit/quickwit-cluster/src/node.rs index 3378e9298fd..32e960c74a8 100644 --- a/quickwit/quickwit-cluster/src/node.rs +++ b/quickwit/quickwit-cluster/src/node.rs @@ -23,7 +23,7 @@ use std::net::SocketAddr; use std::sync::Arc; use chitchat::{ChitchatId, NodeState}; -use quickwit_config::service::QuickwitService; +use quickwit_common::QuickwitService; use quickwit_proto::indexing::{CpuCapacity, IndexingTask}; use quickwit_proto::types::NodeIdRef; use tonic::transport::Channel; diff --git a/quickwit/quickwit-common/src/lib.rs b/quickwit/quickwit-common/src/lib.rs index a1712a4105e..443cb7ffcfc 100644 --- a/quickwit/quickwit-common/src/lib.rs +++ b/quickwit/quickwit-common/src/lib.rs @@ -21,6 +21,9 @@ mod coolid; +mod service; + +pub use service::QuickwitService; pub mod binary_heap; pub mod fs; pub mod io; diff --git a/quickwit/quickwit-config/src/service.rs b/quickwit/quickwit-common/src/service.rs similarity index 85% rename from quickwit/quickwit-config/src/service.rs rename to quickwit/quickwit-common/src/service.rs index f18bc318613..8c1a5583035 100644 --- a/quickwit/quickwit-config/src/service.rs +++ b/quickwit/quickwit-common/src/service.rs @@ -22,11 +22,11 @@ use std::fmt::Display; use std::str::FromStr; use anyhow::bail; -use enum_iterator::{all, Sequence}; +// use enum_iterator::{all, Sequence}; use itertools::Itertools; use serde::Serialize; -#[derive(Clone, Copy, Debug, Eq, PartialEq, Hash, Serialize, Sequence)] +#[derive(Clone, Copy, Debug, Eq, PartialEq, Hash, Serialize)] #[serde(into = "&'static str")] pub enum QuickwitService { ControlPlane, @@ -55,12 +55,20 @@ impl QuickwitService { } pub fn supported_services() -> HashSet { - all::().collect() + [ + QuickwitService::ControlPlane, + QuickwitService::Indexer, + QuickwitService::Searcher, + QuickwitService::Janitor, + QuickwitService::Metastore, + ] + .into_iter() + .collect() } } impl Display for QuickwitService { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { write!(f, "{}", self.as_str()) } } diff --git a/quickwit/quickwit-config/Cargo.toml b/quickwit/quickwit-config/Cargo.toml index 0f51a309f9d..9fc913bfd2a 100644 --- a/quickwit/quickwit-config/Cargo.toml +++ b/quickwit/quickwit-config/Cargo.toml @@ -16,7 +16,6 @@ bytes = { workspace = true } bytesize = { workspace = true } chrono = { workspace = true } cron = { workspace = true } -enum-iterator = { workspace = true } http = { workspace = true } http-serde = { workspace = true } humantime = { workspace = true } diff --git a/quickwit/quickwit-config/src/lib.rs b/quickwit/quickwit-config/src/lib.rs index 2a2a6d4be60..13428b46504 100644 --- a/quickwit/quickwit-config/src/lib.rs +++ b/quickwit/quickwit-config/src/lib.rs @@ -38,7 +38,6 @@ pub mod merge_policy_config; mod metastore_config; mod node_config; mod qw_env_vars; -pub mod service; mod source_config; mod storage_config; mod templating; diff --git a/quickwit/quickwit-config/src/node_config/mod.rs b/quickwit/quickwit-config/src/node_config/mod.rs index c9a8fab1e06..53b675157b2 100644 --- a/quickwit/quickwit-config/src/node_config/mod.rs +++ b/quickwit/quickwit-config/src/node_config/mod.rs @@ -32,13 +32,13 @@ use http::HeaderMap; use quickwit_common::net::HostAddr; use quickwit_common::shared_consts::DEFAULT_SHARD_THROUGHPUT_LIMIT; use quickwit_common::uri::Uri; +use quickwit_common::QuickwitService; use quickwit_proto::indexing::CpuCapacity; use quickwit_proto::types::NodeId; use serde::{Deserialize, Serialize}; use tracing::{info, warn}; use crate::node_config::serialize::load_node_config_with_env; -use crate::service::QuickwitService; use crate::storage_config::StorageConfigs; use crate::{ConfigFormat, MetastoreConfigs}; diff --git a/quickwit/quickwit-config/src/node_config/serialize.rs b/quickwit/quickwit-config/src/node_config/serialize.rs index b56026c0de2..1fda681c9fb 100644 --- a/quickwit/quickwit-config/src/node_config/serialize.rs +++ b/quickwit/quickwit-config/src/node_config/serialize.rs @@ -25,8 +25,8 @@ use std::time::Duration; use anyhow::{bail, Context}; use http::HeaderMap; use quickwit_common::net::{find_private_ip, get_short_hostname, Host}; -use quickwit_common::new_coolid; use quickwit_common::uri::Uri; +use quickwit_common::{new_coolid, QuickwitService}; use quickwit_proto::types::NodeId; use serde::{Deserialize, Serialize}; use tracing::{info, warn}; @@ -34,7 +34,6 @@ use tracing::{info, warn}; use super::{GrpcConfig, RestConfig}; use crate::config_value::ConfigValue; use crate::qw_env_vars::*; -use crate::service::QuickwitService; use crate::storage_config::StorageConfigs; use crate::templating::render_config; use crate::{ @@ -372,11 +371,11 @@ impl NodeConfigBuilder { .or(self.authorization.root_public_key.as_ref()) .context("root key undefined")?; quickwit_authorize::set_root_public_key(root_public_key)?; - let node_token_hex = env_vars + let node_token_base64 = env_vars .get("QW_AUTH_NODE_TOKEN") .or(self.authorization.node_token.as_ref()) .context("root key undefined")?; - quickwit_authorize::set_node_token_hex(node_token_hex)?; + quickwit_authorize::set_node_token_base64(node_token_base64)?; Ok(()) } } @@ -435,6 +434,7 @@ impl Default for NodeConfigBuilder { ingest_api_config: IngestApiConfig::default(), jaeger_config: JaegerConfig::default(), license: license_opt, + authorization: AuthorizationConfigBuilder::default(), } } } diff --git a/quickwit/quickwit-control-plane/src/control_plane.rs b/quickwit/quickwit-control-plane/src/control_plane.rs index b24764c8ec9..f1e27c5c9b7 100644 --- a/quickwit/quickwit-control-plane/src/control_plane.rs +++ b/quickwit/quickwit-control-plane/src/control_plane.rs @@ -36,8 +36,7 @@ use quickwit_cluster::{ }; use quickwit_common::pubsub::EventSubscriber; use quickwit_common::uri::Uri; -use quickwit_common::{shared_consts, Progress}; -use quickwit_config::service::QuickwitService; +use quickwit_common::{shared_consts, Progress, QuickwitService}; use quickwit_config::{ClusterConfig, IndexConfig, IndexTemplate, SourceConfig}; use quickwit_ingest::{IngesterPool, LocalShardsUpdate}; use quickwit_metastore::{CreateIndexRequestExt, CreateIndexResponseExt, IndexMetadataResponseExt}; diff --git a/quickwit/quickwit-proto/src/authorization.rs b/quickwit/quickwit-proto/src/authorization.rs index edf0ac68b7b..df3d5f4004d 100644 --- a/quickwit/quickwit-proto/src/authorization.rs +++ b/quickwit/quickwit-proto/src/authorization.rs @@ -4,7 +4,7 @@ pub use biscuit_auth; pub use biscuit_auth::builder_ext::BuilderExt; pub use biscuit_auth::macros::*; use quickwit_authorize::{ - Authorization, AuthorizationError, AuthorizationToken, StreamAuthorization, + Authorization, AuthorizationError, AuthorizationToken, RequestFamily, StreamAuthorization, }; use crate::cluster::FetchClusterStateRequest; @@ -24,9 +24,17 @@ use crate::metastore::{ PruneShardsRequest, PublishSplitsRequest, StageSplitsRequest, UpdateSplitsDeleteOpstampRequest, }; -impl Authorization for crate::metastore::AcquireShardsRequest {} +impl Authorization for crate::metastore::AcquireShardsRequest { + fn request_family() -> RequestFamily { + RequestFamily::IndexWrite + } +} -impl Authorization for crate::metastore::AddSourceRequest {} +impl Authorization for crate::metastore::AddSourceRequest { + fn request_family() -> RequestFamily { + RequestFamily::IndexAdmin + } +} impl Authorization for crate::metastore::CreateIndexRequest { fn attenuate( @@ -36,50 +44,136 @@ impl Authorization for crate::metastore::CreateIndexRequest { let mut builder = block!(r#"check if operation("create_index");"#); builder.check_expiration_date(SystemTime::now() + Duration::from_secs(60)); let biscuit = auth_token.into_biscuit(); - let new_auth_token = biscuit.append(builder)?; + let new_auth_token = biscuit + .append(builder) + .map_err(|_| AuthorizationError::PermissionDenied)?; Ok(AuthorizationToken::from(new_auth_token)) } + + fn request_family() -> RequestFamily { + RequestFamily::IndexAdmin + } } -impl Authorization for crate::metastore::CreateIndexTemplateRequest {} +impl Authorization for crate::metastore::CreateIndexTemplateRequest { + fn request_family() -> RequestFamily { + RequestFamily::IndexAdmin + } +} -impl Authorization for crate::metastore::DeleteIndexRequest {} +impl Authorization for crate::metastore::DeleteIndexRequest { + fn request_family() -> RequestFamily { + RequestFamily::IndexAdmin + } +} -impl Authorization for crate::metastore::DeleteIndexTemplatesRequest {} +impl Authorization for crate::metastore::DeleteIndexTemplatesRequest { + fn request_family() -> RequestFamily { + RequestFamily::IndexAdmin + } +} -impl Authorization for crate::metastore::DeleteShardsRequest {} +impl Authorization for crate::metastore::DeleteShardsRequest { + fn request_family() -> RequestFamily { + RequestFamily::IndexAdmin + } +} -impl Authorization for crate::metastore::DeleteSourceRequest {} +impl Authorization for crate::metastore::DeleteSourceRequest { + fn request_family() -> RequestFamily { + RequestFamily::IndexAdmin + } +} -impl Authorization for crate::metastore::DeleteSplitsRequest {} +impl Authorization for crate::metastore::DeleteSplitsRequest { + fn request_family() -> RequestFamily { + RequestFamily::IndexAdmin + } +} -impl Authorization for crate::metastore::FindIndexTemplateMatchesRequest {} +impl Authorization for crate::metastore::FindIndexTemplateMatchesRequest { + fn request_family() -> RequestFamily { + RequestFamily::IndexRead + } +} -impl Authorization for crate::metastore::IndexesMetadataRequest {} +impl Authorization for crate::metastore::IndexesMetadataRequest { + fn request_family() -> RequestFamily { + RequestFamily::IndexRead + } +} -impl Authorization for crate::metastore::ToggleSourceRequest {} +impl Authorization for crate::metastore::ToggleSourceRequest { + fn request_family() -> RequestFamily { + RequestFamily::IndexAdmin + } +} -impl Authorization for crate::metastore::MarkSplitsForDeletionRequest {} +impl Authorization for crate::metastore::MarkSplitsForDeletionRequest { + fn request_family() -> RequestFamily { + RequestFamily::IndexWrite + } +} -impl Authorization for crate::metastore::ResetSourceCheckpointRequest {} +impl Authorization for crate::metastore::ResetSourceCheckpointRequest { + fn request_family() -> RequestFamily { + RequestFamily::IndexAdmin + } +} -impl Authorization for crate::metastore::UpdateIndexRequest {} +impl Authorization for crate::metastore::UpdateIndexRequest { + fn request_family() -> RequestFamily { + RequestFamily::IndexAdmin + } +} -impl Authorization for OpenObservationStreamRequest {} +impl Authorization for OpenObservationStreamRequest { + fn request_family() -> RequestFamily { + RequestFamily::IndexWrite + } +} -impl Authorization for InitShardsRequest {} +impl Authorization for InitShardsRequest { + fn request_family() -> RequestFamily { + RequestFamily::IndexWrite + } +} -impl Authorization for OpenShardsRequest {} +impl Authorization for OpenShardsRequest { + fn request_family() -> RequestFamily { + RequestFamily::IndexWrite + } +} -impl Authorization for FetchClusterStateRequest {} +impl Authorization for FetchClusterStateRequest { + fn request_family() -> RequestFamily { + RequestFamily::Cluster + } +} -impl Authorization for GetIndexTemplateRequest {} +impl Authorization for GetIndexTemplateRequest { + fn request_family() -> RequestFamily { + RequestFamily::IndexRead + } +} -impl Authorization for ListIndexTemplatesRequest {} +impl Authorization for ListIndexTemplatesRequest { + fn request_family() -> RequestFamily { + RequestFamily::IndexRead + } +} -impl Authorization for PruneShardsRequest {} +impl Authorization for PruneShardsRequest { + fn request_family() -> RequestFamily { + RequestFamily::IndexRead + } +} -impl Authorization for ListShardsRequest {} +impl Authorization for ListShardsRequest { + fn request_family() -> RequestFamily { + RequestFamily::IndexWrite + } +} impl Authorization for ListStaleSplitsRequest {} diff --git a/quickwit/quickwit-serve/src/developer_api/debug.rs b/quickwit/quickwit-serve/src/developer_api/debug.rs index 3a1c32fbbc3..58c3ca4dd18 100644 --- a/quickwit/quickwit-serve/src/developer_api/debug.rs +++ b/quickwit/quickwit-serve/src/developer_api/debug.rs @@ -25,7 +25,7 @@ use futures::StreamExt; use glob::{MatchOptions, Pattern as GlobPattern}; use hyper::StatusCode; use quickwit_cluster::Cluster; -use quickwit_config::service::QuickwitService; +use quickwit_common::QuickwitService; use quickwit_proto::developer::{DeveloperService, DeveloperServiceClient, GetDebugInfoRequest}; use quickwit_proto::types::{NodeId, NodeIdRef}; use serde::Deserialize; diff --git a/quickwit/quickwit-serve/src/developer_api/server.rs b/quickwit/quickwit-serve/src/developer_api/server.rs index a06465c7efe..241b9415432 100644 --- a/quickwit/quickwit-serve/src/developer_api/server.rs +++ b/quickwit/quickwit-serve/src/developer_api/server.rs @@ -26,7 +26,7 @@ use bytes::Bytes; use bytesize::ByteSize; use quickwit_actors::Mailbox; use quickwit_cluster::Cluster; -use quickwit_config::service::QuickwitService; +use quickwit_common::QuickwitService; use quickwit_config::NodeConfig; use quickwit_control_plane::control_plane::{ControlPlane, GetDebugInfo}; use quickwit_ingest::{IngestRouter, Ingester}; diff --git a/quickwit/quickwit-serve/src/grpc.rs b/quickwit/quickwit-serve/src/grpc.rs index 403ae46d853..251bbb16d0d 100644 --- a/quickwit/quickwit-serve/src/grpc.rs +++ b/quickwit/quickwit-serve/src/grpc.rs @@ -24,7 +24,7 @@ use std::sync::Arc; use bytesize::ByteSize; use quickwit_cluster::cluster_grpc_server; use quickwit_common::tower::BoxFutureInfaillible; -use quickwit_config::service::QuickwitService; +use quickwit_common::QuickwitService; use quickwit_proto::developer::DeveloperServiceClient; use quickwit_proto::indexing::IndexingServiceClient; use quickwit_proto::jaeger::storage::v1::span_reader_plugin_server::SpanReaderPluginServer; diff --git a/quickwit/quickwit-serve/src/lib.rs b/quickwit/quickwit-serve/src/lib.rs index 62a89fee7ab..058c04128f4 100644 --- a/quickwit/quickwit-serve/src/lib.rs +++ b/quickwit/quickwit-serve/src/lib.rs @@ -77,8 +77,7 @@ use quickwit_common::tower::{ RateLimitLayer, RetryLayer, RetryPolicy, SmaRateEstimator, TimeoutLayer, }; use quickwit_common::uri::Uri; -use quickwit_common::{get_bool_from_env, spawn_named_task}; -use quickwit_config::service::QuickwitService; +use quickwit_common::{get_bool_from_env, spawn_named_task, QuickwitService}; use quickwit_config::{ClusterConfig, IngestApiConfig, NodeConfig}; use quickwit_control_plane::control_plane::{ControlPlane, ControlPlaneEventSubscriber}; use quickwit_control_plane::{IndexerNodeInfo, IndexerPool};