mirror of
https://github.com/meilisearch/MeiliSearch
synced 2024-11-29 16:24:26 +01:00
Fix the tasks with the new patterns
This commit is contained in:
parent
d563ed8a39
commit
a36b1dbd70
@ -181,10 +181,8 @@ impl CompatV5ToV6 {
|
|||||||
.indexes
|
.indexes
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.map(|index| match index {
|
.map(|index| match index {
|
||||||
v5::StarOr::Star => v6::StarOr::Star,
|
v5::StarOr::Star => v6::IndexUidPattern::all(),
|
||||||
v5::StarOr::Other(uid) => {
|
v5::StarOr::Other(uid) => v6::IndexUidPattern::new_unchecked(uid.as_str()),
|
||||||
v6::StarOr::Other(v6::IndexUidPattern::new_unchecked(uid.as_str()))
|
|
||||||
}
|
|
||||||
})
|
})
|
||||||
.collect(),
|
.collect(),
|
||||||
expires_at: key.expires_at,
|
expires_at: key.expires_at,
|
||||||
|
@ -34,7 +34,6 @@ pub type PaginationSettings = meilisearch_types::settings::PaginationSettings;
|
|||||||
|
|
||||||
// everything related to the api keys
|
// everything related to the api keys
|
||||||
pub type Action = meilisearch_types::keys::Action;
|
pub type Action = meilisearch_types::keys::Action;
|
||||||
pub type StarOr<T> = meilisearch_types::star_or::StarOr<T>;
|
|
||||||
pub type IndexUidPattern = meilisearch_types::index_uid_pattern::IndexUidPattern;
|
pub type IndexUidPattern = meilisearch_types::index_uid_pattern::IndexUidPattern;
|
||||||
|
|
||||||
// everything related to the errors
|
// everything related to the errors
|
||||||
|
@ -43,6 +43,7 @@ use file_store::FileStore;
|
|||||||
use meilisearch_types::error::ResponseError;
|
use meilisearch_types::error::ResponseError;
|
||||||
use meilisearch_types::heed::types::{OwnedType, SerdeBincode, SerdeJson, Str};
|
use meilisearch_types::heed::types::{OwnedType, SerdeBincode, SerdeJson, Str};
|
||||||
use meilisearch_types::heed::{self, Database, Env, RoTxn};
|
use meilisearch_types::heed::{self, Database, Env, RoTxn};
|
||||||
|
use meilisearch_types::index_uid_pattern::IndexUidPattern;
|
||||||
use meilisearch_types::milli;
|
use meilisearch_types::milli;
|
||||||
use meilisearch_types::milli::documents::DocumentsBatchBuilder;
|
use meilisearch_types::milli::documents::DocumentsBatchBuilder;
|
||||||
use meilisearch_types::milli::update::IndexerConfig;
|
use meilisearch_types::milli::update::IndexerConfig;
|
||||||
@ -617,7 +618,7 @@ impl IndexScheduler {
|
|||||||
&self,
|
&self,
|
||||||
rtxn: &RoTxn,
|
rtxn: &RoTxn,
|
||||||
query: &Query,
|
query: &Query,
|
||||||
authorized_indexes: &Option<Vec<String>>,
|
authorized_indexes: &Option<Vec<IndexUidPattern>>,
|
||||||
) -> Result<RoaringBitmap> {
|
) -> Result<RoaringBitmap> {
|
||||||
let mut tasks = self.get_task_ids(rtxn, query)?;
|
let mut tasks = self.get_task_ids(rtxn, query)?;
|
||||||
|
|
||||||
@ -635,7 +636,7 @@ impl IndexScheduler {
|
|||||||
let all_indexes_iter = self.index_tasks.iter(rtxn)?;
|
let all_indexes_iter = self.index_tasks.iter(rtxn)?;
|
||||||
for result in all_indexes_iter {
|
for result in all_indexes_iter {
|
||||||
let (index, index_tasks) = result?;
|
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;
|
tasks -= index_tasks;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -655,7 +656,7 @@ impl IndexScheduler {
|
|||||||
pub fn get_tasks_from_authorized_indexes(
|
pub fn get_tasks_from_authorized_indexes(
|
||||||
&self,
|
&self,
|
||||||
query: Query,
|
query: Query,
|
||||||
authorized_indexes: Option<Vec<String>>,
|
authorized_indexes: Option<Vec<IndexUidPattern>>,
|
||||||
) -> Result<Vec<Task>> {
|
) -> Result<Vec<Task>> {
|
||||||
let rtxn = self.env.read_txn()?;
|
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 query = Query { index_uids: Some(vec!["catto".to_owned()]), ..Default::default() };
|
||||||
let tasks = index_scheduler
|
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();
|
.unwrap();
|
||||||
// we have asked for only the tasks associated with catto, but are only authorized to retrieve the tasks
|
// we have asked for only the tasks associated with catto, but are only authorized to retrieve the tasks
|
||||||
// associated with doggo -> empty result
|
// associated with doggo -> empty result
|
||||||
@ -2511,7 +2516,11 @@ mod tests {
|
|||||||
|
|
||||||
let query = Query::default();
|
let query = Query::default();
|
||||||
let tasks = index_scheduler
|
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();
|
.unwrap();
|
||||||
// we asked for all the tasks, but we are only authorized to retrieve the doggo tasks
|
// 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
|
// -> only the index creation of doggo should be returned
|
||||||
@ -2522,7 +2531,10 @@ mod tests {
|
|||||||
.get_task_ids_from_authorized_indexes(
|
.get_task_ids_from_authorized_indexes(
|
||||||
&rtxn,
|
&rtxn,
|
||||||
&query,
|
&query,
|
||||||
&Some(vec!["catto".to_owned(), "doggo".to_owned()]),
|
&Some(vec![
|
||||||
|
IndexUidPattern::new_unchecked("catto"),
|
||||||
|
IndexUidPattern::new_unchecked("doggo"),
|
||||||
|
]),
|
||||||
)
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
// we asked for all the tasks, but we are only authorized to retrieve the doggo and catto tasks
|
// 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 query = Query { canceled_by: Some(vec![task_cancelation.uid]), ..Query::default() };
|
||||||
let tasks = index_scheduler
|
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();
|
.unwrap();
|
||||||
// Return only 1 because the user is not authorized to see task 2
|
// Return only 1 because the user is not authorized to see task 2
|
||||||
snapshot!(snapshot_bitmap(&tasks), @"[1,]");
|
snapshot!(snapshot_bitmap(&tasks), @"[1,]");
|
||||||
|
@ -3,7 +3,6 @@ pub mod error;
|
|||||||
mod store;
|
mod store;
|
||||||
|
|
||||||
use std::collections::{HashMap, HashSet};
|
use std::collections::{HashMap, HashSet};
|
||||||
use std::ops::Deref;
|
|
||||||
use std::path::Path;
|
use std::path::Path;
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
|
||||||
@ -11,7 +10,6 @@ use error::{AuthControllerError, Result};
|
|||||||
use maplit::hashset;
|
use maplit::hashset;
|
||||||
use meilisearch_types::index_uid_pattern::IndexUidPattern;
|
use meilisearch_types::index_uid_pattern::IndexUidPattern;
|
||||||
use meilisearch_types::keys::{Action, CreateApiKey, Key, PatchApiKey};
|
use meilisearch_types::keys::{Action, CreateApiKey, Key, PatchApiKey};
|
||||||
use meilisearch_types::star_or::StarOr;
|
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
pub use store::open_auth_store_env;
|
pub use store::open_auth_store_env;
|
||||||
use store::{generate_key_as_hexa, HeedAuthStore};
|
use store::{generate_key_as_hexa, HeedAuthStore};
|
||||||
@ -192,7 +190,7 @@ impl SearchRules {
|
|||||||
|
|
||||||
pub fn get_index_search_rules(&self, index: &str) -> Option<IndexSearchRules> {
|
pub fn get_index_search_rules(&self, index: &str) -> Option<IndexSearchRules> {
|
||||||
match self {
|
match self {
|
||||||
Self::Set(set) => {
|
Self::Set(_) => {
|
||||||
if self.is_index_authorized(index) {
|
if self.is_index_authorized(index) {
|
||||||
Some(IndexSearchRules::default())
|
Some(IndexSearchRules::default())
|
||||||
} else {
|
} else {
|
||||||
|
@ -14,7 +14,6 @@ use meilisearch_types::keys::KeyId;
|
|||||||
use meilisearch_types::milli;
|
use meilisearch_types::milli;
|
||||||
use meilisearch_types::milli::heed::types::{ByteSlice, DecodeIgnore, SerdeJson};
|
use meilisearch_types::milli::heed::types::{ByteSlice, DecodeIgnore, SerdeJson};
|
||||||
use meilisearch_types::milli::heed::{Database, Env, EnvOpenOptions, RwTxn};
|
use meilisearch_types::milli::heed::{Database, Env, EnvOpenOptions, RwTxn};
|
||||||
use meilisearch_types::star_or::StarOr;
|
|
||||||
use sha2::Sha256;
|
use sha2::Sha256;
|
||||||
use time::OffsetDateTime;
|
use time::OffsetDateTime;
|
||||||
use uuid::fmt::Hyphenated;
|
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 {
|
for action in actions {
|
||||||
if no_index_restriction {
|
if no_index_restriction {
|
||||||
// If there is no index restriction we put None.
|
// If there is no index restriction we put None.
|
||||||
|
@ -26,6 +26,11 @@ impl IndexUidPattern {
|
|||||||
IndexUidPattern::from_str("*").unwrap()
|
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.
|
/// Returns `true` if the pattern matches a specific index name.
|
||||||
pub fn is_exact(&self) -> bool {
|
pub fn is_exact(&self) -> bool {
|
||||||
!self.0.ends_with('*')
|
!self.0.ends_with('*')
|
||||||
|
@ -13,7 +13,6 @@ use uuid::Uuid;
|
|||||||
use crate::error::deserr_codes::*;
|
use crate::error::deserr_codes::*;
|
||||||
use crate::error::{unwrap_any, Code, DeserrError, ErrorCode, TakeErrorMessage};
|
use crate::error::{unwrap_any, Code, DeserrError, ErrorCode, TakeErrorMessage};
|
||||||
use crate::index_uid_pattern::{IndexUidPattern, IndexUidPatternFormatError};
|
use crate::index_uid_pattern::{IndexUidPattern, IndexUidPatternFormatError};
|
||||||
use crate::star_or::StarOr;
|
|
||||||
|
|
||||||
pub type KeyId = Uuid;
|
pub type KeyId = Uuid;
|
||||||
|
|
||||||
|
@ -199,6 +199,9 @@ pub mod policies {
|
|||||||
token: &str,
|
token: &str,
|
||||||
index: Option<&str>,
|
index: Option<&str>,
|
||||||
) -> Option<AuthFilter> {
|
) -> Option<AuthFilter> {
|
||||||
|
// Tenant token will always define an index.
|
||||||
|
let index = index?;
|
||||||
|
|
||||||
// Only search action can be accessed by a tenant token.
|
// Only search action can be accessed by a tenant token.
|
||||||
if A != actions::SEARCH {
|
if A != actions::SEARCH {
|
||||||
return None;
|
return None;
|
||||||
@ -206,7 +209,7 @@ pub mod policies {
|
|||||||
|
|
||||||
let uid = extract_key_id(token)?;
|
let uid = extract_key_id(token)?;
|
||||||
// check if parent key is authorized to do the action.
|
// 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.
|
// Check if tenant token is valid.
|
||||||
let key = auth.generate_key(uid)?;
|
let key = auth.generate_key(uid)?;
|
||||||
let data = decode::<Claims>(
|
let data = decode::<Claims>(
|
||||||
@ -217,11 +220,9 @@ pub mod policies {
|
|||||||
.ok()?;
|
.ok()?;
|
||||||
|
|
||||||
// Check index access if an index restriction is provided.
|
// Check index access if an index restriction is provided.
|
||||||
if let Some(index) = index {
|
|
||||||
if !data.claims.search_rules.is_index_authorized(index) {
|
if !data.claims.search_rules.is_index_authorized(index) {
|
||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
// Check if token is expired.
|
// Check if token is expired.
|
||||||
if let Some(exp) = data.claims.exp {
|
if let Some(exp) = data.claims.exp {
|
||||||
@ -230,10 +231,10 @@ pub mod policies {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
match auth.get_key_filters(uid, Some(data.claims.search_rules)) {
|
return match auth.get_key_filters(uid, Some(data.claims.search_rules)) {
|
||||||
Ok(auth) if auth.search_rules.is_index_authorized() => Some(auth),
|
Ok(auth) if auth.search_rules.is_index_authorized(index) => Some(auth),
|
||||||
_ => None,
|
_ => None,
|
||||||
}
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
None
|
None
|
||||||
|
Loading…
Reference in New Issue
Block a user