mirror of
https://github.com/meilisearch/meilisearch.git
synced 2025-07-27 16:51:01 +00:00
introduce as many custom error message as possible
This commit is contained in:
@ -78,7 +78,7 @@ pub static ALL_ACTIONS: Lazy<HashSet<&'static str>> = Lazy::new(|| {
|
||||
});
|
||||
|
||||
static INVALID_RESPONSE: Lazy<Value> = Lazy::new(|| {
|
||||
json!({"message": "The provided API key is invalid.",
|
||||
json!({"message": null,
|
||||
"code": "invalid_api_key",
|
||||
"type": "auth",
|
||||
"link": "https://docs.meilisearch.com/errors#invalid_api_key"
|
||||
@ -119,7 +119,8 @@ async fn error_access_expired_key() {
|
||||
thread::sleep(time::Duration::new(1, 0));
|
||||
|
||||
for (method, route) in AUTHORIZATIONS.keys() {
|
||||
let (response, code) = server.dummy_request(method, route).await;
|
||||
let (mut response, code) = server.dummy_request(method, route).await;
|
||||
response["message"] = serde_json::json!(null);
|
||||
|
||||
assert_eq!(response, INVALID_RESPONSE.clone(), "on route: {:?} - {:?}", method, route);
|
||||
assert_eq!(403, code, "{:?}", &response);
|
||||
@ -149,7 +150,8 @@ async fn error_access_unauthorized_index() {
|
||||
// filter `products` index routes
|
||||
.filter(|(_, route)| route.starts_with("/indexes/products"))
|
||||
{
|
||||
let (response, code) = server.dummy_request(method, route).await;
|
||||
let (mut response, code) = server.dummy_request(method, route).await;
|
||||
response["message"] = serde_json::json!(null);
|
||||
|
||||
assert_eq!(response, INVALID_RESPONSE.clone(), "on route: {:?} - {:?}", method, route);
|
||||
assert_eq!(403, code, "{:?}", &response);
|
||||
@ -176,7 +178,8 @@ async fn error_access_unauthorized_action() {
|
||||
|
||||
let key = response["key"].as_str().unwrap();
|
||||
server.use_api_key(key);
|
||||
let (response, code) = server.dummy_request(method, route).await;
|
||||
let (mut response, code) = server.dummy_request(method, route).await;
|
||||
response["message"] = serde_json::json!(null);
|
||||
|
||||
assert_eq!(response, INVALID_RESPONSE.clone(), "on route: {:?} - {:?}", method, route);
|
||||
assert_eq!(403, code, "{:?}", &response);
|
||||
|
@ -478,6 +478,21 @@ async fn invalid_auth_format() {
|
||||
}
|
||||
"###);
|
||||
|
||||
let req = test::TestRequest::get().uri("/indexes/dog/documents").to_request();
|
||||
let res = test::call_service(&app, req).await;
|
||||
let status_code = res.status();
|
||||
let body = test::read_body(res).await;
|
||||
let response: Value = serde_json::from_slice(&body).unwrap_or_default();
|
||||
snapshot!(status_code, @"401 Unauthorized");
|
||||
snapshot!(response, @r###"
|
||||
{
|
||||
"message": "The Authorization header is missing. It must use the bearer authorization method.",
|
||||
"code": "missing_authorization_header",
|
||||
"type": "auth",
|
||||
"link": "https://docs.meilisearch.com/errors#missing_authorization_header"
|
||||
}
|
||||
"###);
|
||||
|
||||
let (response, status_code) =
|
||||
send_request_with_custom_auth(&app, "/indexes/dog/documents", "Bearer").await;
|
||||
snapshot!(status_code, @"403 Forbidden");
|
||||
@ -489,9 +504,15 @@ async fn invalid_auth_format() {
|
||||
"link": "https://docs.meilisearch.com/errors#invalid_api_key"
|
||||
}
|
||||
"###);
|
||||
}
|
||||
|
||||
#[actix_rt::test]
|
||||
async fn invalid_api_key() {
|
||||
let server = Server::new_auth().await;
|
||||
let app = server.init_web_app().await;
|
||||
|
||||
let (response, status_code) =
|
||||
send_request_with_custom_auth(&app, "/indexes/dog/documents", "Bearer kefir").await;
|
||||
send_request_with_custom_auth(&app, "/indexes/dog/search", "Bearer kefir").await;
|
||||
snapshot!(status_code, @"403 Forbidden");
|
||||
snapshot!(response, @r###"
|
||||
{
|
||||
@ -502,6 +523,54 @@ async fn invalid_auth_format() {
|
||||
}
|
||||
"###);
|
||||
|
||||
let uuid = Uuid::nil();
|
||||
let key = json!({ "actions": ["search"], "indexes": ["dog"], "expiresAt": null, "uid": uuid.to_string() });
|
||||
let req = test::TestRequest::post()
|
||||
.uri("/keys")
|
||||
.insert_header(("Authorization", "Bearer MASTER_KEY"))
|
||||
.set_json(&key)
|
||||
.to_request();
|
||||
let res = test::call_service(&app, req).await;
|
||||
let body = test::read_body(res).await;
|
||||
let response: Value = serde_json::from_slice(&body).unwrap_or_default();
|
||||
snapshot!(json_string!(response, { ".createdAt" => "[date]", ".updatedAt" => "[date]" }), @r###"
|
||||
{
|
||||
"name": null,
|
||||
"description": null,
|
||||
"key": "aeb94973e0b6e912d94165430bbe87dee91a7c4f891ce19050c3910ec96977e9",
|
||||
"uid": "00000000-0000-0000-0000-000000000000",
|
||||
"actions": [
|
||||
"search"
|
||||
],
|
||||
"indexes": [
|
||||
"dog"
|
||||
],
|
||||
"expiresAt": null,
|
||||
"createdAt": "[date]",
|
||||
"updatedAt": "[date]"
|
||||
}
|
||||
"###);
|
||||
let key = response["key"].as_str().unwrap();
|
||||
|
||||
let (response, status_code) =
|
||||
send_request_with_custom_auth(&app, "/indexes/doggo/search", &format!("Bearer {key}"))
|
||||
.await;
|
||||
snapshot!(status_code, @"403 Forbidden");
|
||||
snapshot!(response, @r###"
|
||||
{
|
||||
"message": "The API key cannot acces the index `doggo`, authorized indexes are [\"dog\"].",
|
||||
"code": "invalid_api_key",
|
||||
"type": "auth",
|
||||
"link": "https://docs.meilisearch.com/errors#invalid_api_key"
|
||||
}
|
||||
"###);
|
||||
}
|
||||
|
||||
#[actix_rt::test]
|
||||
async fn invalid_tenant_token() {
|
||||
let server = Server::new_auth().await;
|
||||
let app = server.init_web_app().await;
|
||||
|
||||
// The tenant token won't be recognized at all if we're not on a search route
|
||||
let claims = json!({ "tamo": "kefir" });
|
||||
let jwt = jsonwebtoken::encode(&Header::default(), &claims, &EncodingKey::from_secret(b"tamo"))
|
||||
@ -527,7 +596,7 @@ async fn invalid_auth_format() {
|
||||
snapshot!(status_code, @"403 Forbidden");
|
||||
snapshot!(response, @r###"
|
||||
{
|
||||
"message": "Could not decode tenant token, JSON error: missing field `searchRules` at line 1 column 16",
|
||||
"message": "Could not decode tenant token, JSON error: missing field `searchRules` at line 1 column 16.",
|
||||
"code": "invalid_api_key",
|
||||
"type": "auth",
|
||||
"link": "https://docs.meilisearch.com/errors#invalid_api_key"
|
||||
@ -543,7 +612,7 @@ async fn invalid_auth_format() {
|
||||
snapshot!(status_code, @"403 Forbidden");
|
||||
snapshot!(response, @r###"
|
||||
{
|
||||
"message": "Could not decode tenant token, JSON error: data did not match any variant of untagged enum SearchRules at line 1 column 23",
|
||||
"message": "Could not decode tenant token, JSON error: data did not match any variant of untagged enum SearchRules at line 1 column 23.",
|
||||
"code": "invalid_api_key",
|
||||
"type": "auth",
|
||||
"link": "https://docs.meilisearch.com/errors#invalid_api_key"
|
||||
@ -559,12 +628,73 @@ async fn invalid_auth_format() {
|
||||
snapshot!(status_code, @"403 Forbidden");
|
||||
snapshot!(response, @r###"
|
||||
{
|
||||
"message": "Could not decode tenant token, InvalidSignature",
|
||||
"message": "Could not decode tenant token, InvalidSignature.",
|
||||
"code": "invalid_api_key",
|
||||
"type": "auth",
|
||||
"link": "https://docs.meilisearch.com/errors#invalid_api_key"
|
||||
}
|
||||
"###);
|
||||
|
||||
// ~~ For the next tests we first need to retrieve an API key
|
||||
// ~~ For the next tests we first need a valid API key
|
||||
let key = json!({ "actions": ["search"], "indexes": ["dog"], "expiresAt": null, "uid": uuid.to_string() });
|
||||
let req = test::TestRequest::post()
|
||||
.uri("/keys")
|
||||
.insert_header(("Authorization", "Bearer MASTER_KEY"))
|
||||
.set_json(&key)
|
||||
.to_request();
|
||||
let res = test::call_service(&app, req).await;
|
||||
let body = test::read_body(res).await;
|
||||
let response: Value = serde_json::from_slice(&body).unwrap_or_default();
|
||||
snapshot!(json_string!(response, { ".createdAt" => "[date]", ".updatedAt" => "[date]" }), @r###"
|
||||
{
|
||||
"name": null,
|
||||
"description": null,
|
||||
"key": "aeb94973e0b6e912d94165430bbe87dee91a7c4f891ce19050c3910ec96977e9",
|
||||
"uid": "00000000-0000-0000-0000-000000000000",
|
||||
"actions": [
|
||||
"search"
|
||||
],
|
||||
"indexes": [
|
||||
"dog"
|
||||
],
|
||||
"expiresAt": null,
|
||||
"createdAt": "[date]",
|
||||
"updatedAt": "[date]"
|
||||
}
|
||||
"###);
|
||||
let key = response["key"].as_str().unwrap();
|
||||
|
||||
let claims = json!({ "searchRules": ["doggo", "catto"], "apiKeyUid": uuid.to_string() });
|
||||
let jwt = jsonwebtoken::encode(
|
||||
&Header::default(),
|
||||
&claims,
|
||||
&EncodingKey::from_secret(key.as_bytes()),
|
||||
)
|
||||
.unwrap();
|
||||
// Try to access an index that is not authorized by the tenant token
|
||||
let (response, status_code) =
|
||||
send_request_with_custom_auth(&app, "/indexes/dog/search", &format!("Bearer {jwt}")).await;
|
||||
snapshot!(status_code, @"403 Forbidden");
|
||||
snapshot!(response, @r###"
|
||||
{
|
||||
"message": "The provided tenant token cannot acces the index `dog`, allowed indexes are [\"catto\", \"doggo\"].",
|
||||
"code": "invalid_api_key",
|
||||
"type": "auth",
|
||||
"link": "https://docs.meilisearch.com/errors#invalid_api_key"
|
||||
}
|
||||
"###);
|
||||
|
||||
// Try to access an index that *is* authorized by the tenant token but not by the api key used to generate the tt
|
||||
let (response, status_code) =
|
||||
send_request_with_custom_auth(&app, "/indexes/doggo/search", &format!("Bearer {jwt}"))
|
||||
.await;
|
||||
snapshot!(status_code, @"403 Forbidden");
|
||||
snapshot!(response, @r###"
|
||||
{
|
||||
"message": "The API key used to generate this tenant token cannot acces the index `doggo`.",
|
||||
"code": "invalid_api_key",
|
||||
"type": "auth",
|
||||
"link": "https://docs.meilisearch.com/errors#invalid_api_key"
|
||||
}
|
||||
"###);
|
||||
}
|
||||
|
Reference in New Issue
Block a user