mirror of
				https://github.com/meilisearch/meilisearch.git
				synced 2025-10-31 16:06:31 +00:00 
			
		
		
		
	Fix api keys bugs (#2734)
* Add some tests * Disallow index creation when API key doesn't havec explicitelly the right on the creating index * Fix lazy index creation with `indexes.*` action
This commit is contained in:
		| @@ -110,10 +110,7 @@ impl AuthController { | ||||
|             filters.search_rules = search_rules; | ||||
|         } | ||||
|  | ||||
|         filters.allow_index_creation = key | ||||
|             .actions | ||||
|             .iter() | ||||
|             .any(|&action| action == Action::IndexesAdd || action == Action::All); | ||||
|         filters.allow_index_creation = self.is_key_authorized(uid, Action::IndexesAdd, None)?; | ||||
|  | ||||
|         Ok(filters) | ||||
|     } | ||||
|   | ||||
| @@ -5,7 +5,7 @@ use std::ops::Deref; | ||||
| use std::pin::Pin; | ||||
|  | ||||
| use actix_web::FromRequest; | ||||
| use error::AuthenticationError; | ||||
| pub use error::AuthenticationError; | ||||
| use futures::future::err; | ||||
| use futures::Future; | ||||
| use meilisearch_auth::{AuthController, AuthFilter}; | ||||
|   | ||||
| @@ -8,7 +8,7 @@ use serde_json::json; | ||||
| use time::OffsetDateTime; | ||||
|  | ||||
| use crate::analytics::Analytics; | ||||
| use crate::extractors::authentication::{policies::*, GuardedData}; | ||||
| use crate::extractors::authentication::{policies::*, AuthenticationError, GuardedData}; | ||||
| use crate::extractors::sequential_extractor::SeqHandler; | ||||
| use crate::task::SummarizedTaskView; | ||||
|  | ||||
| @@ -74,16 +74,21 @@ pub async fn create_index( | ||||
|         primary_key, uid, .. | ||||
|     } = body.into_inner(); | ||||
|  | ||||
|     analytics.publish( | ||||
|         "Index Created".to_string(), | ||||
|         json!({ "primary_key": primary_key }), | ||||
|         Some(&req), | ||||
|     ); | ||||
|     let allow_index_creation = meilisearch.filters().search_rules.is_index_authorized(&uid); | ||||
|     if allow_index_creation { | ||||
|         analytics.publish( | ||||
|             "Index Created".to_string(), | ||||
|             json!({ "primary_key": primary_key }), | ||||
|             Some(&req), | ||||
|         ); | ||||
|  | ||||
|     let update = Update::CreateIndex { primary_key }; | ||||
|     let task: SummarizedTaskView = meilisearch.register_update(uid, update).await?.into(); | ||||
|         let update = Update::CreateIndex { primary_key }; | ||||
|         let task: SummarizedTaskView = meilisearch.register_update(uid, update).await?.into(); | ||||
|  | ||||
|     Ok(HttpResponse::Accepted().json(task)) | ||||
|         Ok(HttpResponse::Accepted().json(task)) | ||||
|     } else { | ||||
|         Err(AuthenticationError::InvalidToken.into()) | ||||
|     } | ||||
| } | ||||
|  | ||||
| #[derive(Debug, Deserialize)] | ||||
|   | ||||
| @@ -597,11 +597,91 @@ async fn error_creating_index_without_action() { | ||||
| #[actix_rt::test] | ||||
| async fn lazy_create_index() { | ||||
|     let mut server = Server::new_auth().await; | ||||
|  | ||||
|     // create key with access on all indexes. | ||||
|     let contents = vec![ | ||||
|         json!({ | ||||
|             "indexes": ["*"], | ||||
|             "actions": ["*"], | ||||
|             "expiresAt": "2050-11-13T00:00:00Z" | ||||
|         }), | ||||
|         json!({ | ||||
|             "indexes": ["*"], | ||||
|             "actions": ["indexes.*", "documents.*", "settings.*", "tasks.*"], | ||||
|             "expiresAt": "2050-11-13T00:00:00Z" | ||||
|         }), | ||||
|         json!({ | ||||
|             "indexes": ["*"], | ||||
|             "actions": ["indexes.create", "documents.add", "settings.update", "tasks.get"], | ||||
|             "expiresAt": "2050-11-13T00:00:00Z" | ||||
|         }), | ||||
|     ]; | ||||
|  | ||||
|     for content in contents { | ||||
|         server.use_api_key("MASTER_KEY"); | ||||
|         let (response, code) = server.add_api_key(content).await; | ||||
|         assert_eq!(201, code, "{:?}", &response); | ||||
|         assert!(response["key"].is_string()); | ||||
|  | ||||
|         // use created key. | ||||
|         let key = response["key"].as_str().unwrap(); | ||||
|         server.use_api_key(&key); | ||||
|  | ||||
|         // try to create a index via add documents route | ||||
|         let index = server.index("test"); | ||||
|         let documents = json!([ | ||||
|             { | ||||
|                 "id": 1, | ||||
|                 "content": "foo", | ||||
|             } | ||||
|         ]); | ||||
|  | ||||
|         let (response, code) = index.add_documents(documents, None).await; | ||||
|         assert_eq!(202, code, "{:?}", &response); | ||||
|         let task_id = response["taskUid"].as_u64().unwrap(); | ||||
|  | ||||
|         index.wait_task(task_id).await; | ||||
|  | ||||
|         let (response, code) = index.get_task(task_id).await; | ||||
|         assert_eq!(200, code, "{:?}", &response); | ||||
|         assert_eq!(response["status"], "succeeded"); | ||||
|  | ||||
|         // try to create a index via add settings route | ||||
|         let index = server.index("test1"); | ||||
|         let settings = json!({ "distinctAttribute": "test"}); | ||||
|  | ||||
|         let (response, code) = index.update_settings(settings).await; | ||||
|         assert_eq!(202, code, "{:?}", &response); | ||||
|         let task_id = response["taskUid"].as_u64().unwrap(); | ||||
|  | ||||
|         index.wait_task(task_id).await; | ||||
|  | ||||
|         let (response, code) = index.get_task(task_id).await; | ||||
|         assert_eq!(200, code, "{:?}", &response); | ||||
|         assert_eq!(response["status"], "succeeded"); | ||||
|  | ||||
|         // try to create a index via add specialized settings route | ||||
|         let index = server.index("test2"); | ||||
|         let (response, code) = index.update_distinct_attribute(json!("test")).await; | ||||
|         assert_eq!(202, code, "{:?}", &response); | ||||
|         let task_id = response["taskUid"].as_u64().unwrap(); | ||||
|  | ||||
|         index.wait_task(task_id).await; | ||||
|  | ||||
|         let (response, code) = index.get_task(task_id).await; | ||||
|         assert_eq!(200, code, "{:?}", &response); | ||||
|         assert_eq!(response["status"], "succeeded"); | ||||
|     } | ||||
| } | ||||
|  | ||||
| #[actix_rt::test] | ||||
| async fn error_creating_index_without_index() { | ||||
|     let mut server = Server::new_auth().await; | ||||
|     server.use_api_key("MASTER_KEY"); | ||||
|  | ||||
|     // create key with access on all indexes. | ||||
|     let content = json!({ | ||||
|         "indexes": ["*"], | ||||
|         "indexes": ["unexpected"], | ||||
|         "actions": ["*"], | ||||
|         "expiresAt": "2050-11-13T00:00:00Z" | ||||
|     }); | ||||
| @@ -624,38 +704,21 @@ async fn lazy_create_index() { | ||||
|     ]); | ||||
|  | ||||
|     let (response, code) = index.add_documents(documents, None).await; | ||||
|     assert_eq!(202, code, "{:?}", &response); | ||||
|     let task_id = response["taskUid"].as_u64().unwrap(); | ||||
|  | ||||
|     index.wait_task(task_id).await; | ||||
|  | ||||
|     let (response, code) = index.get_task(task_id).await; | ||||
|     assert_eq!(200, code, "{:?}", &response); | ||||
|     assert_eq!(response["status"], "succeeded"); | ||||
|     assert_eq!(403, code, "{:?}", &response); | ||||
|  | ||||
|     // try to create a index via add settings route | ||||
|     let index = server.index("test1"); | ||||
|     let settings = json!({ "distinctAttribute": "test"}); | ||||
|  | ||||
|     let (response, code) = index.update_settings(settings).await; | ||||
|     assert_eq!(202, code, "{:?}", &response); | ||||
|     let task_id = response["taskUid"].as_u64().unwrap(); | ||||
|  | ||||
|     index.wait_task(task_id).await; | ||||
|  | ||||
|     let (response, code) = index.get_task(task_id).await; | ||||
|     assert_eq!(200, code, "{:?}", &response); | ||||
|     assert_eq!(response["status"], "succeeded"); | ||||
|     assert_eq!(403, code, "{:?}", &response); | ||||
|  | ||||
|     // try to create a index via add specialized settings route | ||||
|     let index = server.index("test2"); | ||||
|     let (response, code) = index.update_distinct_attribute(json!("test")).await; | ||||
|     assert_eq!(202, code, "{:?}", &response); | ||||
|     let task_id = response["taskUid"].as_u64().unwrap(); | ||||
|     assert_eq!(403, code, "{:?}", &response); | ||||
|  | ||||
|     index.wait_task(task_id).await; | ||||
|  | ||||
|     let (response, code) = index.get_task(task_id).await; | ||||
|     assert_eq!(200, code, "{:?}", &response); | ||||
|     assert_eq!(response["status"], "succeeded"); | ||||
|     // try to create a index via create index route | ||||
|     let index = server.index("test3"); | ||||
|     let (response, code) = index.create(None).await; | ||||
|     assert_eq!(403, code, "{:?}", &response); | ||||
| } | ||||
|   | ||||
		Reference in New Issue
	
	Block a user