gcloud_auth/token_source/
compute_token_source.rs

1use async_trait::async_trait;
2use urlencoding::encode;
3
4use google_cloud_metadata::{METADATA_FLAVOR_KEY, METADATA_GOOGLE, METADATA_HOST_ENV, METADATA_IP};
5
6use crate::error::Error;
7use crate::token::Token;
8use crate::token_source::InternalToken;
9use crate::token_source::{default_http_client, TokenSource};
10
11#[allow(dead_code)]
12#[derive(Debug)]
13pub struct ComputeTokenSource {
14    token_url: String,
15    client: reqwest::Client,
16}
17
18impl ComputeTokenSource {
19    pub(crate) fn new(scope: &str) -> Result<ComputeTokenSource, Error> {
20        let host = match std::env::var(METADATA_HOST_ENV) {
21            Ok(s) => s,
22            Err(_e) => METADATA_IP.to_string(),
23        };
24
25        Ok(ComputeTokenSource {
26            token_url: format!(
27                "http://{}/computeMetadata/v1/instance/service-accounts/default/token?scopes={}",
28                host,
29                encode(scope)
30            ),
31            client: default_http_client(),
32        })
33    }
34}
35
36#[async_trait]
37impl TokenSource for ComputeTokenSource {
38    async fn token(&self) -> Result<Token, Error> {
39        let it = self
40            .client
41            .get(self.token_url.to_string())
42            .header(METADATA_FLAVOR_KEY, METADATA_GOOGLE)
43            .send()
44            .await?
45            .json::<InternalToken>()
46            .await?;
47        return Ok(it.to_token(time::OffsetDateTime::now_utc()));
48    }
49}