Repository: meilisearch/meilisearch
File: meilisearch/tests/auth/authorization.rs (Rust)

Code before:
            ("GET",     "/version") =>                                         hashset!{"version", "*"},
            ("GET",     "/metrics") =>                                         hashset!{"metrics.get", "metrics.*", "*"},
            ("PATCH",   "/keys/mykey/") =>                                     hashset!{"keys.update", "*"},
            ("GET",     "/keys/mykey/") =>                                     hashset!{"keys.get", "*"},
            ("DELETE",  "/keys/mykey/") =>                                     hashset!{"keys.delete", "*"},
            ("POST",    "/keys") =>                                            hashset!{"keys.create", "*"},
            ("GET",     "/keys") =>                                            hashset!{"keys.get", "*"},
        };

        authorizations
    });

pub static ALL_ACTIONS: Lazy<HashSet<&'static str>> = Lazy::new(|| {
    AUTHORIZATIONS.values().cloned().reduce(|l, r| l.union(&r).cloned().collect()).unwrap()
});

static INVALID_RESPONSE: Lazy<Value> = Lazy::new(|| {
    json!({"message": "The provided API key is invalid.",
        "code": "invalid_api_key",
        "type": "auth",
        "link": "https://docs.meilisearch.com/errors#invalid_api_key"
    })
});

static INVALID_METRICS_RESPONSE: Lazy<Value> = Lazy::new(|| {
    json!({"message": "The provided API key is invalid. The API key for the `/metrics` route must have no limitation on the indexes.",
        "code": "invalid_api_key",
        "type": "auth",
        "link": "https://docs.meilisearch.com/errors#invalid_api_key"
    })
});

const MASTER_KEY: &str = "MASTER_KEY";

#[actix_rt::test]
async fn error_access_expired_key() {
    use std::{thread, time};

    let mut server = Server::new_auth().await;
    server.use_api_key(MASTER_KEY);

    let content = json!({
        "indexes": ["products"],
        "actions": ALL_ACTIONS.clone(),
        "expiresAt": (OffsetDateTime::now_utc() + Duration::seconds(1)).format(&Rfc3339).unwrap(),
    });

    let (response, code) = server.add_api_key(content).await;
    assert_eq!(201, code, "{:?}", &response);
    assert!(response["key"].is_string());


Review comment (suggestion):
```suggestion
    json!({"message": "The provided API key is invalid. The API key for the `/metrics` route must allow access to all indexes.",
```

Code after:
            ("GET",     "/version") =>                                         hashset!{"version", "*"},
            ("GET",     "/metrics") =>                                         hashset!{"metrics.get", "metrics.*", "*"},
            ("PATCH",   "/keys/mykey/") =>                                     hashset!{"keys.update", "*"},
            ("GET",     "/keys/mykey/") =>                                     hashset!{"keys.get", "*"},
            ("DELETE",  "/keys/mykey/") =>                                     hashset!{"keys.delete", "*"},
            ("POST",    "/keys") =>                                            hashset!{"keys.create", "*"},
            ("GET",     "/keys") =>                                            hashset!{"keys.get", "*"},
        };

        authorizations
    });

pub static ALL_ACTIONS: Lazy<HashSet<&'static str>> = Lazy::new(|| {
    AUTHORIZATIONS.values().cloned().reduce(|l, r| l.union(&r).cloned().collect()).unwrap()
});

static INVALID_RESPONSE: Lazy<Value> = Lazy::new(|| {
    json!({"message": "The provided API key is invalid.",
        "code": "invalid_api_key",
        "type": "auth",
        "link": "https://docs.meilisearch.com/errors#invalid_api_key"
    })
});

static INVALID_METRICS_RESPONSE: Lazy<Value> = Lazy::new(|| {
    json!({"message": "The provided API key is invalid. The API key for the `/metrics` route must allow access to all indexes.",
        "code": "invalid_api_key",
        "type": "auth",
        "link": "https://docs.meilisearch.com/errors#invalid_api_key"
    })
});

const MASTER_KEY: &str = "MASTER_KEY";

#[actix_rt::test]
async fn error_access_expired_key() {
    use std::{thread, time};

    let mut server = Server::new_auth().await;
    server.use_api_key(MASTER_KEY);

    let content = json!({
        "indexes": ["products"],
        "actions": ALL_ACTIONS.clone(),
        "expiresAt": (OffsetDateTime::now_utc() + Duration::seconds(1)).format(&Rfc3339).unwrap(),
    });

    let (response, code) = server.add_api_key(content).await;
    assert_eq!(201, code, "{:?}", &response);
    assert!(response["key"].is_string());