1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
use crate::prelude::*;
use tokio::sync::Mutex;
#[async_trait]
pub trait ServiceAccount: Send {
fn get_token(&self, scopes: &[&str]) -> Option<Token>;
async fn refresh_token(&mut self, client: &HyperClient, scopes: &[&str]) -> Result<(), GCPAuthError>;
}
pub struct AuthenticationManager {
pub(crate) client: HyperClient,
pub(crate) service_account: Mutex<Box<dyn ServiceAccount>>,
}
impl AuthenticationManager {
pub async fn get_token(&self, scopes: &[&str]) -> Result<Token, GCPAuthError> {
let mut sa = self.service_account.lock().await;
let mut token = sa.get_token(scopes);
if token.is_none() {
sa.refresh_token(&self.client, scopes).await?;
token = sa.get_token(scopes);
}
Ok(token.expect("Token obtained with refresh or failed before"))
}
}