From a36b1dbd7054de44af48af813c2823648d4b190c Mon Sep 17 00:00:00 2001 From: Kerollmops Date: Wed, 1 Feb 2023 18:21:45 +0100 Subject: [PATCH] Fix the tasks with the new patterns --- dump/src/reader/compat/v5_to_v6.rs | 6 ++-- dump/src/reader/v6/mod.rs | 1 - index-scheduler/src/lib.rs | 30 ++++++++++++++----- meilisearch-auth/src/lib.rs | 4 +-- meilisearch-auth/src/store.rs | 3 +- meilisearch-types/src/index_uid_pattern.rs | 5 ++++ meilisearch-types/src/keys.rs | 1 - .../src/extractors/authentication/mod.rs | 17 ++++++----- 8 files changed, 41 insertions(+), 26 deletions(-) diff --git a/dump/src/reader/compat/v5_to_v6.rs b/dump/src/reader/compat/v5_to_v6.rs index 51858450e..3b348492d 100644 --- a/dump/src/reader/compat/v5_to_v6.rs +++ b/dump/src/reader/compat/v5_to_v6.rs @@ -181,10 +181,8 @@ impl CompatV5ToV6 { .indexes .into_iter() .map(|index| match index { - v5::StarOr::Star => v6::StarOr::Star, - v5::StarOr::Other(uid) => { - v6::StarOr::Other(v6::IndexUidPattern::new_unchecked(uid.as_str())) - } + v5::StarOr::Star => v6::IndexUidPattern::all(), + v5::StarOr::Other(uid) => v6::IndexUidPattern::new_unchecked(uid.as_str()), }) .collect(), expires_at: key.expires_at, diff --git a/dump/src/reader/v6/mod.rs b/dump/src/reader/v6/mod.rs index 77d7a52bc..f0ad81116 100644 --- a/dump/src/reader/v6/mod.rs +++ b/dump/src/reader/v6/mod.rs @@ -34,7 +34,6 @@ pub type PaginationSettings = meilisearch_types::settings::PaginationSettings; // everything related to the api keys pub type Action = meilisearch_types::keys::Action; -pub type StarOr = meilisearch_types::star_or::StarOr; pub type IndexUidPattern = meilisearch_types::index_uid_pattern::IndexUidPattern; // everything related to the errors diff --git a/index-scheduler/src/lib.rs b/index-scheduler/src/lib.rs index 0b9e856d2..3599ac36a 100644 --- a/index-scheduler/src/lib.rs +++ b/index-scheduler/src/lib.rs @@ -43,6 +43,7 @@ use file_store::FileStore; use meilisearch_types::error::ResponseError; use meilisearch_types::heed::types::{OwnedType, SerdeBincode, SerdeJson, Str}; use meilisearch_types::heed::{self, Database, Env, RoTxn}; +use meilisearch_types::index_uid_pattern::IndexUidPattern; use meilisearch_types::milli; use meilisearch_types::milli::documents::DocumentsBatchBuilder; use meilisearch_types::milli::update::IndexerConfig; @@ -617,7 +618,7 @@ impl IndexScheduler { &self, rtxn: &RoTxn, query: &Query, - authorized_indexes: &Option>, + authorized_indexes: &Option>, ) -> Result { let mut tasks = self.get_task_ids(rtxn, query)?; @@ -635,7 +636,7 @@ impl IndexScheduler { let all_indexes_iter = self.index_tasks.iter(rtxn)?; for result in all_indexes_iter { let (index, index_tasks) = result?; - if !authorized_indexes.contains(&index.to_owned()) { + if !authorized_indexes.iter().any(|p| p.matches_str(index)) { tasks -= index_tasks; } } @@ -655,7 +656,7 @@ impl IndexScheduler { pub fn get_tasks_from_authorized_indexes( &self, query: Query, - authorized_indexes: Option>, + authorized_indexes: Option>, ) -> Result> { let rtxn = self.env.read_txn()?; @@ -2503,7 +2504,11 @@ mod tests { let query = Query { index_uids: Some(vec!["catto".to_owned()]), ..Default::default() }; let tasks = index_scheduler - .get_task_ids_from_authorized_indexes(&rtxn, &query, &Some(vec!["doggo".to_owned()])) + .get_task_ids_from_authorized_indexes( + &rtxn, + &query, + &Some(vec![IndexUidPattern::new_unchecked("doggo")]), + ) .unwrap(); // we have asked for only the tasks associated with catto, but are only authorized to retrieve the tasks // associated with doggo -> empty result @@ -2511,7 +2516,11 @@ mod tests { let query = Query::default(); let tasks = index_scheduler - .get_task_ids_from_authorized_indexes(&rtxn, &query, &Some(vec!["doggo".to_owned()])) + .get_task_ids_from_authorized_indexes( + &rtxn, + &query, + &Some(vec![IndexUidPattern::new_unchecked("doggo")]), + ) .unwrap(); // we asked for all the tasks, but we are only authorized to retrieve the doggo tasks // -> only the index creation of doggo should be returned @@ -2522,7 +2531,10 @@ mod tests { .get_task_ids_from_authorized_indexes( &rtxn, &query, - &Some(vec!["catto".to_owned(), "doggo".to_owned()]), + &Some(vec![ + IndexUidPattern::new_unchecked("catto"), + IndexUidPattern::new_unchecked("doggo"), + ]), ) .unwrap(); // we asked for all the tasks, but we are only authorized to retrieve the doggo and catto tasks @@ -2570,7 +2582,11 @@ mod tests { let query = Query { canceled_by: Some(vec![task_cancelation.uid]), ..Query::default() }; let tasks = index_scheduler - .get_task_ids_from_authorized_indexes(&rtxn, &query, &Some(vec!["doggo".to_string()])) + .get_task_ids_from_authorized_indexes( + &rtxn, + &query, + &Some(vec![IndexUidPattern::new_unchecked("doggo")]), + ) .unwrap(); // Return only 1 because the user is not authorized to see task 2 snapshot!(snapshot_bitmap(&tasks), @"[1,]"); diff --git a/meilisearch-auth/src/lib.rs b/meilisearch-auth/src/lib.rs index 287dda0ce..6b8b6ef9e 100644 --- a/meilisearch-auth/src/lib.rs +++ b/meilisearch-auth/src/lib.rs @@ -3,7 +3,6 @@ pub mod error; mod store; use std::collections::{HashMap, HashSet}; -use std::ops::Deref; use std::path::Path; use std::sync::Arc; @@ -11,7 +10,6 @@ use error::{AuthControllerError, Result}; use maplit::hashset; use meilisearch_types::index_uid_pattern::IndexUidPattern; use meilisearch_types::keys::{Action, CreateApiKey, Key, PatchApiKey}; -use meilisearch_types::star_or::StarOr; use serde::{Deserialize, Serialize}; pub use store::open_auth_store_env; use store::{generate_key_as_hexa, HeedAuthStore}; @@ -192,7 +190,7 @@ impl SearchRules { pub fn get_index_search_rules(&self, index: &str) -> Option { match self { - Self::Set(set) => { + Self::Set(_) => { if self.is_index_authorized(index) { Some(IndexSearchRules::default()) } else { diff --git a/meilisearch-auth/src/store.rs b/meilisearch-auth/src/store.rs index d1c2562c1..79a1631a4 100644 --- a/meilisearch-auth/src/store.rs +++ b/meilisearch-auth/src/store.rs @@ -14,7 +14,6 @@ use meilisearch_types::keys::KeyId; use meilisearch_types::milli; use meilisearch_types::milli::heed::types::{ByteSlice, DecodeIgnore, SerdeJson}; use meilisearch_types::milli::heed::{Database, Env, EnvOpenOptions, RwTxn}; -use meilisearch_types::star_or::StarOr; use sha2::Sha256; use time::OffsetDateTime; use uuid::fmt::Hyphenated; @@ -126,7 +125,7 @@ impl HeedAuthStore { } } - let no_index_restriction = key.indexes.contains(&StarOr::Star); + let no_index_restriction = key.indexes.iter().any(|p| p.matches_all()); for action in actions { if no_index_restriction { // If there is no index restriction we put None. diff --git a/meilisearch-types/src/index_uid_pattern.rs b/meilisearch-types/src/index_uid_pattern.rs index bc12da351..88e0292f2 100644 --- a/meilisearch-types/src/index_uid_pattern.rs +++ b/meilisearch-types/src/index_uid_pattern.rs @@ -26,6 +26,11 @@ impl IndexUidPattern { IndexUidPattern::from_str("*").unwrap() } + /// Returns `true` if it matches any index. + pub fn matches_all(&self) -> bool { + self.0 == "*" + } + /// Returns `true` if the pattern matches a specific index name. pub fn is_exact(&self) -> bool { !self.0.ends_with('*') diff --git a/meilisearch-types/src/keys.rs b/meilisearch-types/src/keys.rs index a9e2e0889..f594640d9 100644 --- a/meilisearch-types/src/keys.rs +++ b/meilisearch-types/src/keys.rs @@ -13,7 +13,6 @@ use uuid::Uuid; use crate::error::deserr_codes::*; use crate::error::{unwrap_any, Code, DeserrError, ErrorCode, TakeErrorMessage}; use crate::index_uid_pattern::{IndexUidPattern, IndexUidPatternFormatError}; -use crate::star_or::StarOr; pub type KeyId = Uuid; diff --git a/meilisearch/src/extractors/authentication/mod.rs b/meilisearch/src/extractors/authentication/mod.rs index f1efdf9aa..4836679a9 100644 --- a/meilisearch/src/extractors/authentication/mod.rs +++ b/meilisearch/src/extractors/authentication/mod.rs @@ -199,6 +199,9 @@ pub mod policies { token: &str, index: Option<&str>, ) -> Option { + // Tenant token will always define an index. + let index = index?; + // Only search action can be accessed by a tenant token. if A != actions::SEARCH { return None; @@ -206,7 +209,7 @@ pub mod policies { let uid = extract_key_id(token)?; // check if parent key is authorized to do the action. - if auth.is_key_authorized(uid, Action::Search, index).ok()? { + if auth.is_key_authorized(uid, Action::Search, Some(index)).ok()? { // Check if tenant token is valid. let key = auth.generate_key(uid)?; let data = decode::( @@ -217,10 +220,8 @@ pub mod policies { .ok()?; // Check index access if an index restriction is provided. - if let Some(index) = index { - if !data.claims.search_rules.is_index_authorized(index) { - return None; - } + if !data.claims.search_rules.is_index_authorized(index) { + return None; } // Check if token is expired. @@ -230,10 +231,10 @@ pub mod policies { } } - match auth.get_key_filters(uid, Some(data.claims.search_rules)) { - Ok(auth) if auth.search_rules.is_index_authorized() => Some(auth), + return match auth.get_key_filters(uid, Some(data.claims.search_rules)) { + Ok(auth) if auth.search_rules.is_index_authorized(index) => Some(auth), _ => None, - } + }; } None