Skip to content

Commit

Permalink
Move Claims type into custom_service_account
Browse files Browse the repository at this point in the history
  • Loading branch information
djc committed Apr 9, 2024
1 parent 8791bfe commit f6eea3a
Show file tree
Hide file tree
Showing 3 changed files with 56 additions and 66 deletions.
58 changes: 56 additions & 2 deletions src/custom_service_account.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ use std::path::{Path, PathBuf};
use std::sync::RwLock;

use async_trait::async_trait;
use base64::{engine::general_purpose::URL_SAFE, Engine};
use chrono::Utc;
use serde::{Deserialize, Serialize};
use tracing::{instrument, Level};

Expand Down Expand Up @@ -95,8 +97,6 @@ impl ServiceAccount for CustomServiceAccount {

#[instrument(level = Level::DEBUG)]
async fn refresh_token(&self, client: &HyperClient, scopes: &[&str]) -> Result<Token, Error> {
use crate::jwt::Claims;
use crate::jwt::GRANT_TYPE;
use hyper::header;
use url::form_urlencoded;

Expand Down Expand Up @@ -136,6 +136,57 @@ impl ServiceAccount for CustomServiceAccount {
}
}

/// Permissions requested for a JWT.
/// See https://developers.google.com/identity/protocols/OAuth2ServiceAccount#authorizingrequests.
#[derive(Serialize, Debug)]
pub(crate) struct Claims<'a> {
iss: &'a str,
aud: &'a str,
exp: i64,
iat: i64,
sub: Option<&'a str>,
scope: String,
}

impl<'a> Claims<'a> {
pub(crate) fn new(
key: &'a ApplicationCredentials,
scopes: &[&str],
sub: Option<&'a str>,
) -> Self {
let mut scope = String::with_capacity(16);
for (i, s) in scopes.iter().enumerate() {
if i != 0 {
scope.push(' ');
}

scope.push_str(s);
}

let iat = Utc::now().timestamp();
Claims {
iss: &key.client_email,
aud: &key.token_uri,
exp: iat + 3600 - 5, // Max validity is 1h
iat,
sub,
scope,
}
}

pub(crate) fn to_jwt(&self, signer: &Signer) -> Result<String, Error> {
let mut jwt = String::new();
URL_SAFE.encode_string(GOOGLE_RS256_HEAD, &mut jwt);
jwt.push('.');
URL_SAFE.encode_string(&serde_json::to_string(self).unwrap(), &mut jwt);

let signature = signer.sign(jwt.as_bytes())?;
jwt.push('.');
URL_SAFE.encode_string(&signature, &mut jwt);
Ok(jwt)
}
}

#[derive(Serialize, Deserialize, Clone)]
pub(crate) struct ApplicationCredentials {
pub(crate) r#type: Option<String>,
Expand Down Expand Up @@ -168,5 +219,8 @@ impl fmt::Debug for ApplicationCredentials {
}
}

pub(crate) const GRANT_TYPE: &str = "urn:ietf:params:oauth:grant-type:jwt-bearer";
const GOOGLE_RS256_HEAD: &str = r#"{"alg":"RS256","typ":"JWT"}"#;

/// How many times to attempt to fetch a token from the set credentials token endpoint.
const RETRY_COUNT: u8 = 5;
63 changes: 0 additions & 63 deletions src/jwt.rs

This file was deleted.

1 change: 0 additions & 1 deletion src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,6 @@ mod default_authorized_user;
mod default_service_account;
mod error;
mod gcloud_authorized_user;
mod jwt;
mod types;
mod util;

Expand Down

0 comments on commit f6eea3a

Please sign in to comment.