micromegas_telemetry_sink/
api_key_decorator.rs

1//! API Key request decorator for HttpEventSink authentication
2//!
3//! Adds Bearer token authentication header to HTTP requests sent to the ingestion service.
4
5use crate::request_decorator::{RequestDecorator, RequestDecoratorError, Result};
6use async_trait::async_trait;
7
8/// Request decorator that adds API key as Bearer token
9///
10/// Reads API key from environment variable `MICROMEGAS_INGESTION_API_KEY`
11/// and adds it as an Authorization header to all requests.
12pub struct ApiKeyRequestDecorator {
13    api_key: String,
14}
15
16impl ApiKeyRequestDecorator {
17    /// Create a new API key decorator from environment variable
18    ///
19    /// Reads `MICROMEGAS_INGESTION_API_KEY` environment variable.
20    /// Returns error if environment variable is not set.
21    pub fn from_env() -> Result<Self> {
22        let api_key = std::env::var("MICROMEGAS_INGESTION_API_KEY").map_err(|_| {
23            RequestDecoratorError::Permanent(
24                "MICROMEGAS_INGESTION_API_KEY environment variable not set".to_string(),
25            )
26        })?;
27
28        if api_key.is_empty() {
29            return Err(RequestDecoratorError::Permanent(
30                "MICROMEGAS_INGESTION_API_KEY is empty".to_string(),
31            ));
32        }
33
34        Ok(Self { api_key })
35    }
36
37    /// Create a new API key decorator with explicit key
38    ///
39    /// # Arguments
40    /// * `api_key` - The API key to use for authentication
41    pub fn new(api_key: String) -> Self {
42        Self { api_key }
43    }
44}
45
46#[async_trait]
47impl RequestDecorator for ApiKeyRequestDecorator {
48    async fn decorate(&self, request: &mut reqwest::Request) -> Result<()> {
49        // Add Authorization header with Bearer token
50        let auth_value = format!("Bearer {}", self.api_key);
51        request.headers_mut().insert(
52            reqwest::header::AUTHORIZATION,
53            reqwest::header::HeaderValue::from_str(&auth_value).map_err(|e| {
54                RequestDecoratorError::Permanent(format!("Invalid API key format: {}", e))
55            })?,
56        );
57        Ok(())
58    }
59}