diff --git a/meilisearch/src/routes/metrics.rs b/meilisearch/src/routes/metrics.rs index 1d3fb834e..59cff9b58 100644 --- a/meilisearch/src/routes/metrics.rs +++ b/meilisearch/src/routes/metrics.rs @@ -2,13 +2,13 @@ use actix_web::http::header; use actix_web::web::{self, Data}; use actix_web::HttpResponse; use index_scheduler::IndexScheduler; -use meilisearch_auth::{AuthController, AuthFilter}; +use meilisearch_auth::AuthController; use meilisearch_types::error::ResponseError; use meilisearch_types::keys::actions; use prometheus::{Encoder, TextEncoder}; use crate::extractors::authentication::policies::ActionPolicy; -use crate::extractors::authentication::GuardedData; +use crate::extractors::authentication::{AuthenticationError, GuardedData}; use crate::routes::create_all_stats; pub fn configure(config: &mut web::ServiceConfig) { @@ -19,12 +19,17 @@ pub async fn get_metrics( index_scheduler: GuardedData, Data>, auth_controller: GuardedData, AuthController>, ) -> Result { - let response = create_all_stats( - (*index_scheduler).clone(), - (*auth_controller).clone(), - // we don't use the filters contained in the `ActionPolicy` because the metrics must have the right to access all the indexes. - &AuthFilter::default(), - )?; + let auth_filters = index_scheduler.filters(); + if !auth_filters.all_indexes_authorized() { + let mut error = ResponseError::from(AuthenticationError::InvalidToken); + error + .message + .push_str(" The API key for the `/metrics` route must allow access to all indexes."); + return Err(error); + } + + let response = + create_all_stats((*index_scheduler).clone(), (*auth_controller).clone(), auth_filters)?; crate::metrics::MEILISEARCH_DB_SIZE_BYTES.set(response.database_size as i64); crate::metrics::MEILISEARCH_INDEX_COUNT.set(response.indexes.len() as i64); diff --git a/meilisearch/tests/auth/authorization.rs b/meilisearch/tests/auth/authorization.rs index e92f41bcf..ef4a7eaa1 100644 --- a/meilisearch/tests/auth/authorization.rs +++ b/meilisearch/tests/auth/authorization.rs @@ -75,6 +75,14 @@ static INVALID_RESPONSE: Lazy = Lazy::new(|| { }) }); +static INVALID_METRICS_RESPONSE: Lazy = Lazy::new(|| { + json!({"message": "The provided API key is invalid. The API key for the `/metrics` route must allow access to all indexes.", + "code": "invalid_api_key", + "type": "auth", + "link": "https://docs.meilisearch.com/errors#invalid_api_key" + }) +}); + const MASTER_KEY: &str = "MASTER_KEY"; #[actix_rt::test] @@ -202,15 +210,28 @@ async fn access_authorized_restricted_index() { let (response, code) = server.dummy_request(method, route).await; - assert_ne!( - response, - INVALID_RESPONSE.clone(), - "on route: {:?} - {:?} with action: {:?}", - method, - route, - action - ); - assert_ne!(code, 403); + // The metrics route MUST have no limitation on the indexes + if *route == "/metrics" { + assert_eq!( + response, + INVALID_METRICS_RESPONSE.clone(), + "on route: {:?} - {:?} with action: {:?}", + method, + route, + action + ); + assert_eq!(code, 403); + } else { + assert_ne!( + response, + INVALID_RESPONSE.clone(), + "on route: {:?} - {:?} with action: {:?}", + method, + route, + action + ); + assert_ne!(code, 403); + } } } }