faucet_stream/auth/mod.rs
1//! Authentication strategies for REST APIs.
2
3pub mod api_key;
4pub mod basic;
5pub mod bearer;
6pub mod custom;
7pub mod oauth2;
8
9use crate::error::FaucetError;
10use reqwest::header::HeaderMap;
11
12/// Supported authentication methods.
13#[derive(Debug, Clone)]
14pub enum Auth {
15 None,
16 Bearer(String),
17 Basic {
18 username: String,
19 password: String,
20 },
21 /// API key sent in a request header.
22 ApiKey {
23 header: String,
24 value: String,
25 },
26 /// API key sent as a query parameter (e.g. `?api_key=secret`).
27 ///
28 /// Some APIs require the key in the URL rather than a header. The `param`
29 /// field is the query parameter name, and `value` is the key itself.
30 ApiKeyQuery {
31 param: String,
32 value: String,
33 },
34 OAuth2 {
35 token_url: String,
36 client_id: String,
37 client_secret: String,
38 scopes: Vec<String>,
39 /// Fraction of `expires_in` after which the cached token is considered
40 /// expired and a new one is fetched. Must be in `(0.0, 1.0]`.
41 /// Defaults to `0.9` (refresh after 90 % of the token lifetime).
42 expiry_ratio: f64,
43 },
44 Custom(HeaderMap),
45}
46
47impl Auth {
48 /// Apply header-based auth to the request headers.
49 ///
50 /// `ApiKeyQuery` is a no-op here — it is applied as a query parameter by
51 /// `RestStream::execute_request` instead.
52 pub fn apply(&self, headers: &mut HeaderMap) -> Result<(), FaucetError> {
53 match self {
54 Auth::None | Auth::ApiKeyQuery { .. } => Ok(()),
55 Auth::Bearer(token) => bearer::apply(headers, token),
56 Auth::Basic { username, password } => basic::apply(headers, username, password),
57 Auth::ApiKey { header, value } => api_key::apply(headers, header, value),
58 // OAuth2 is resolved to Auth::Bearer by RestStream before apply() is called.
59 // If apply() is reached with an OAuth2 variant, it means the caller bypassed
60 // RestStream — return a clear error rather than silently sending no auth.
61 Auth::OAuth2 { .. } => Err(FaucetError::Auth(
62 "OAuth2 auth must be resolved to a bearer token before applying; \
63 use RestStream (which resolves it automatically) or call \
64 fetch_oauth2_token() and use Auth::Bearer"
65 .into(),
66 )),
67 Auth::Custom(h) => {
68 custom::apply(headers, h);
69 Ok(())
70 }
71 }
72 }
73}
74
75pub use oauth2::fetch_oauth2_token;