gcloud_sdk/
reqwest_auth_middleware.rs1use std::sync::Arc;
2
3use async_trait::async_trait;
4use reqwest_middleware::{Middleware, Next};
5
6use crate::GoogleAuthTokenGenerator;
7
8#[derive(Clone)]
13pub struct GoogleAuthReqwestMiddleware {
14 token_generator: Arc<GoogleAuthTokenGenerator>,
15}
16
17impl GoogleAuthReqwestMiddleware {
18 pub fn new(token_generator: impl Into<Arc<GoogleAuthTokenGenerator>>) -> Self {
19 Self {
20 token_generator: token_generator.into(),
21 }
22 }
23}
24
25#[async_trait]
26impl Middleware for GoogleAuthReqwestMiddleware {
27 async fn handle(
28 &self,
29 mut req: reqwest::Request,
30 extensions: &mut hyper::http::Extensions,
31 next: Next<'_>,
32 ) -> reqwest_middleware::Result<reqwest::Response> {
33 let authorization = self
34 .token_generator
35 .authorization_header()
36 .await
37 .map_err(reqwest_middleware::Error::middleware)?;
38 req.headers_mut()
39 .insert(reqwest::header::AUTHORIZATION, authorization);
40 next.run(req, extensions).await
41 }
42}
43
44#[cfg(test)]
45mod tests {
46 use super::*;
47 use crate::test_support::{StubResponse, StubServer};
48 use crate::token_source::{Source, Token};
49 use jiff::{SignedDuration, Timestamp};
50 use secret_vault_value::SecretValue;
51
52 struct FixedToken;
53
54 #[async_trait]
55 impl Source for FixedToken {
56 async fn token(&self) -> crate::error::Result<Token> {
57 Ok(Token::new(
58 "Bearer".to_string(),
59 SecretValue::from("minted-id-token"),
60 Timestamp::now() + SignedDuration::from_hours(1),
61 ))
62 }
63 }
64
65 #[tokio::test]
66 async fn requests_carry_the_generator_token() {
67 let service = StubServer::start(vec![StubResponse::json("200 OK", "{}")]).await;
68 let client = reqwest_middleware::ClientBuilder::new(reqwest::Client::new())
69 .with(GoogleAuthReqwestMiddleware::new(
70 GoogleAuthTokenGenerator::from_source(Box::new(FixedToken) as crate::BoxSource),
71 ))
72 .build();
73
74 let response = client
75 .get(format!("{}/orders", service.url))
76 .send()
77 .await
78 .unwrap();
79
80 assert_eq!(response.status(), reqwest::StatusCode::OK);
81 assert_eq!(
82 service.received()[0].header("authorization"),
83 Some("Bearer minted-id-token")
84 );
85 }
86}