cat_gateway/service/common/auth/
api_key.rs

1//! API Key authorization scheme is used ONLY by internal endpoints.
2//!
3//! Its purpose is to prevent their use externally, if they were accidentally exposed.
4//!
5//! It is NOT to be used on any endpoint intended to be publicly facing.
6
7use anyhow::{bail, Result};
8use poem::{http::HeaderMap, Request};
9use poem_openapi::{auth::ApiKey, SecurityScheme};
10
11use crate::settings::Settings;
12
13/// The header name that holds the API Key
14pub(crate) const API_KEY_HEADER: &str = "X-API-Key";
15
16/// `ApiKey` authorization for Internal Endpoints
17#[derive(SecurityScheme)]
18#[oai(
19    ty = "api_key",
20    key_name = "X-API-Key", // MUST match the `API_KEY_HEADER` constant.
21    key_in = "header",
22    checker = "api_checker"
23)]
24#[allow(dead_code)]
25pub(crate) struct InternalApiKeyAuthorization(String);
26
27/// Check the provided API Key matches the API Key defined by for the deployment.
28#[allow(clippy::unused_async)]
29async fn api_checker(_req: &Request, api_key: ApiKey) -> Option<String> {
30    if Settings::check_internal_api_key(&api_key.key) {
31        Some(api_key.key)
32    } else {
33        None
34    }
35}
36
37/// Check if the API Key is correctly set.
38/// Returns an error if it is not.
39pub(crate) fn check_api_key(headers: &HeaderMap) -> Result<()> {
40    if let Some(key) = headers.get(API_KEY_HEADER) {
41        if Settings::check_internal_api_key(key.to_str()?) {
42            return Ok(());
43        }
44    }
45    bail!("Invalid API Key");
46}