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:
Many the fish 2022-09-06 15:13:09 +02:00 committed by GitHub
parent 4e37427de8
commit 37dc6537c3
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 104 additions and 39 deletions

View File

@ -110,10 +110,7 @@ impl AuthController {
filters.search_rules = search_rules; filters.search_rules = search_rules;
} }
filters.allow_index_creation = key filters.allow_index_creation = self.is_key_authorized(uid, Action::IndexesAdd, None)?;
.actions
.iter()
.any(|&action| action == Action::IndexesAdd || action == Action::All);
Ok(filters) Ok(filters)
} }

View File

@ -5,7 +5,7 @@ use std::ops::Deref;
use std::pin::Pin; use std::pin::Pin;
use actix_web::FromRequest; use actix_web::FromRequest;
use error::AuthenticationError; pub use error::AuthenticationError;
use futures::future::err; use futures::future::err;
use futures::Future; use futures::Future;
use meilisearch_auth::{AuthController, AuthFilter}; use meilisearch_auth::{AuthController, AuthFilter};

View File

@ -8,7 +8,7 @@ use serde_json::json;
use time::OffsetDateTime; use time::OffsetDateTime;
use crate::analytics::Analytics; 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::extractors::sequential_extractor::SeqHandler;
use crate::task::SummarizedTaskView; use crate::task::SummarizedTaskView;
@ -74,6 +74,8 @@ pub async fn create_index(
primary_key, uid, .. primary_key, uid, ..
} = body.into_inner(); } = body.into_inner();
let allow_index_creation = meilisearch.filters().search_rules.is_index_authorized(&uid);
if allow_index_creation {
analytics.publish( analytics.publish(
"Index Created".to_string(), "Index Created".to_string(),
json!({ "primary_key": primary_key }), json!({ "primary_key": primary_key }),
@ -84,6 +86,9 @@ pub async fn create_index(
let task: SummarizedTaskView = meilisearch.register_update(uid, update).await?.into(); 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)] #[derive(Debug, Deserialize)]

View File

@ -597,15 +597,28 @@ async fn error_creating_index_without_action() {
#[actix_rt::test] #[actix_rt::test]
async fn lazy_create_index() { async fn lazy_create_index() {
let mut server = Server::new_auth().await; let mut server = Server::new_auth().await;
server.use_api_key("MASTER_KEY");
// create key with access on all indexes. // create key with access on all indexes.
let content = json!({ let contents = vec![
json!({
"indexes": ["*"], "indexes": ["*"],
"actions": ["*"], "actions": ["*"],
"expiresAt": "2050-11-13T00:00:00Z" "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; let (response, code) = server.add_api_key(content).await;
assert_eq!(201, code, "{:?}", &response); assert_eq!(201, code, "{:?}", &response);
assert!(response["key"].is_string()); assert!(response["key"].is_string());
@ -658,4 +671,54 @@ async fn lazy_create_index() {
let (response, code) = index.get_task(task_id).await; let (response, code) = index.get_task(task_id).await;
assert_eq!(200, code, "{:?}", &response); assert_eq!(200, code, "{:?}", &response);
assert_eq!(response["status"], "succeeded"); 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": ["unexpected"],
"actions": ["*"],
"expiresAt": "2050-11-13T00:00:00Z"
});
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!(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!(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!(403, code, "{:?}", &response);
// 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);
} }