google-cloud-ai 0.3.0

A gRPC-based crate designed to interact with Google Cloud AI API
Documentation
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;
}