use jsonwebtoken::{encode, Algorithm, EncodingKey, Header};
use serde::{Deserialize, Serialize};
#[path = "google/protos.rs"]
pub mod google_cloud_ai {}
#[derive(Debug, Serialize, Deserialize)]
struct Token {
access_token: String,
}
#[derive(Debug, Serialize, Deserialize)]
struct Claims {
iss: String,
scope: String,
aud: String,
exp: usize,
iat: usize,
}
pub async fn get_token() -> String {
let client = reqwest::Client::new();
let response = client.get("http://metadata.google.internal/computeMetadata/v1/instance/service-accounts/default/token")
.header("Metadata-Flavor", "Google")
.send()
.await
.unwrap();
let result = response.json::<Token>().await.unwrap();
return result.access_token;
}
pub async fn get_service_account_token(email: String, rsa_pem: String) -> String {
let timestamp = chrono::Utc::now();
let iat_value = timestamp.timestamp().try_into().unwrap();
let exp_value = (timestamp.timestamp() + 3600).try_into().unwrap();
let claims = Claims {
iss: email,
scope: String::from("https://www.googleapis.com/auth/datastore"),
aud: String::from("https://oauth2.googleapis.com/token"),
exp: exp_value,
iat: iat_value,
};
let mut headers = Header::new(Algorithm::RS256);
headers.typ = Some("JWT".to_string());
let token = encode(
&headers,
&claims,
&EncodingKey::from_rsa_pem(rsa_pem.as_ref()).unwrap(),
)
.unwrap();
let client = reqwest::Client::new();
let resp = client
.post("https://oauth2.googleapis.com/token")
.header("Content-Type", "application/x-www-form-urlencoded")
.body(format!(
"grant_type=urn%3Aietf%3Aparams%3Aoauth%3Agrant-type%3Ajwt-bearer&assertion={}",
token
))
.send()
.await
.unwrap();
let result = resp.json::<Token>().await.unwrap();
return result.access_token;
}