gcloud_sdk/token_source/
auth_token_generator.rs1use std::sync::Arc;
2
3use chrono::prelude::*;
4use tokio::sync::RwLock;
5
6use crate::token_source::*;
7use tracing::*;
8
9pub struct GoogleAuthTokenGenerator {
10 token_source: BoxSource,
11 cached_token: Arc<RwLock<Option<Token>>>,
12}
13
14impl GoogleAuthTokenGenerator {
15 pub async fn new(
16 token_source_type: TokenSourceType,
17 token_scopes: Vec<String>,
18 ) -> crate::error::Result<GoogleAuthTokenGenerator> {
19 let token_source: BoxSource = create_source(token_source_type, token_scopes).await?;
20
21 Ok(GoogleAuthTokenGenerator {
22 token_source,
23 cached_token: Arc::new(RwLock::new(None)),
24 })
25 }
26
27 pub async fn clear_cache(&self) {
28 let mut write_state = self.cached_token.write().await;
29 *write_state = None;
30 }
31
32 pub async fn create_token(&self) -> crate::error::Result<Token> {
33 let existing_token: Option<Token> = {
34 let read_state = self.cached_token.read().await;
35 read_state.clone()
36 };
37
38 let now = Utc::now();
39
40 match existing_token {
41 Some(token) if token.expiry.gt(&now.add(chrono::Duration::seconds(15))) => Ok(token),
43 _ => {
44 let new_token = {
45 let mut write_token = self.cached_token.write().await;
46
47 match write_token.as_ref() {
48 Some(updated_token) if updated_token.expiry.gt(&now) => {
49 updated_token.clone()
50 }
51 _ => {
52 let new_token = self.token_source.token().await?;
53 *write_token = Some(new_token.clone());
54 debug!(
55 "Created a new Google OAuth token. Type: {}. Expiring: {}.",
56 new_token.token_type, new_token.expiry,
57 );
58 new_token
59 }
60 }
61 };
62 Ok(new_token)
63 }
64 }
65 }
66}