Skip to content

Commit

Permalink
adding support for multiple scopes (#24)
Browse files Browse the repository at this point in the history
  • Loading branch information
fermanjj authored Jun 17, 2024
1 parent 02ac058 commit 07fd57d
Show file tree
Hide file tree
Showing 5 changed files with 50 additions and 13 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ fn main() -> Result<(), GoErr>{
let credentials = Credentials::from_file("dummy_credentials_file_for_tests.json").unwrap();
let claims = JwtClaims::new(String::from(iss),
&Scope::DevStorageReadWrite,
&[Scope::DevStorageReadWrite],
String::from(token_url),
None, None);
let jwt = Jwt::new(claims, credentials.rsa_key().unwrap(), None);
Expand Down
9 changes: 6 additions & 3 deletions src/auth.rs
Original file line number Diff line number Diff line change
Expand Up @@ -40,12 +40,11 @@ impl JwtClaims {
claims.iat = iat;
claims.exp = iat + expires_after;
claims

}

pub fn new(
service_acc_id: String,
scope: &Scope,
scopes: &[Scope],
aud_url: String,
valid_from: Option<i64>,
expires_after: Option<i64>,
Expand All @@ -60,7 +59,11 @@ impl JwtClaims {
};
JwtClaims {
iss: service_acc_id,
scope: scope.url(),
scope: scopes
.iter()
.map(|scope| scope.url())
.collect::<Vec<String>>()
.join(" "),
aud: aud_url,
exp,
iat,
Expand Down
2 changes: 2 additions & 0 deletions src/credentials.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,13 +22,15 @@ pub struct Credentials {
}

impl Credentials {
#[allow(clippy::result_large_err)]
pub fn from_file(fp: &str) -> Result<Self> {
let mut f = File::open(fp)?;
let mut buffer = Vec::new();
f.read_to_end(&mut buffer)?;
Ok(serde_json::from_slice(buffer.as_slice())?)
}

#[allow(clippy::result_large_err)]
pub fn rsa_key(&self) -> Result<RSAKey> {
Ok(RSAKey::from_str(&self.private_key)?)
}
Expand Down
11 changes: 7 additions & 4 deletions src/fetcher.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@

use crate::auth::{JwtClaims, Token};
use crate::credentials::Credentials;
use crate::{Result, get_token_with_client_and_body};
use crate::{get_token_with_client_and_body, Result};

use arc_swap::ArcSwapOption;
use reqwest::Client;
Expand Down Expand Up @@ -89,7 +89,8 @@ impl TokenFetcher {
async fn get_token(&self) -> Result<Token> {
let now = OffsetDateTime::now_utc();
let jwt_body = self.get_jwt_body(now)?;
let token = get_token_with_client_and_body(&self.client, jwt_body, &self.credentials).await?;
let token =
get_token_with_client_and_body(&self.client, jwt_body, &self.credentials).await?;
let expires_in = Duration::new(token.expires_in().into(), 0);

assert!(
Expand All @@ -107,10 +108,12 @@ impl TokenFetcher {
Ok(token)
}

#[allow(clippy::result_large_err)]
fn get_jwt_body(&self, valid_from: OffsetDateTime) -> Result<String> {
let mut jwt = self.jwt.lock().unwrap();
// Refresh jwt claims
jwt.body_mut().update(Some(valid_from.unix_timestamp()), None);
jwt.body_mut()
.update(Some(valid_from.unix_timestamp()), None);
let jwt_body = jwt.finalize()?;
Ok(jwt_body)
}
Expand Down Expand Up @@ -138,7 +141,7 @@ mod tests {

let claims = JwtClaims::new(
String::from(iss),
&Scope::DevStorageReadWrite,
&[Scope::DevStorageReadWrite],
String::from(token_url.clone()),
None,
None,
Expand Down
39 changes: 34 additions & 5 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ simpl::err!(GoErr,
/// let private_key_file = "random_rsa_for_testing";
///
/// let claims = JwtClaims::new(String::from(iss),
/// &Scope::DevStorageReadWrite,
/// &[Scope::DevStorageReadWrite],
/// String::from(token_url),
/// None, None);
/// let key = match RSAKey::from_pem(private_key_file) {
Expand All @@ -72,6 +72,7 @@ simpl::err!(GoErr,
/// }
///
/// ```
#[allow(clippy::result_large_err)]
pub fn get_token_legacy(jwt: &Jwt<JwtClaims>, url: Option<&str>) -> Result<Token> {
let client = reqwest::blocking::Client::new();
let final_jwt = jwt.finalize()?;
Expand All @@ -84,10 +85,12 @@ pub fn get_token_legacy(jwt: &Jwt<JwtClaims>, url: Option<&str>) -> Result<Token
Token::from_str(&response.text()?)
}

#[allow(clippy::result_large_err)]
pub fn get_token_as_string_legacy(jwt: &Jwt<JwtClaims>, url: Option<&str>) -> Result<String> {
Ok(serde_json::to_string(&get_token_legacy(jwt, url)?)?)
}

#[allow(clippy::result_large_err)]
pub fn get_token_as_string(jwt: &Jwt<JwtClaims>, credentials: &Credentials) -> Result<String> {
Ok(serde_json::to_string(&get_token_blocking(
jwt,
Expand Down Expand Up @@ -115,7 +118,7 @@ pub fn get_token_as_string(jwt: &Jwt<JwtClaims>, credentials: &Credentials) -> R
/// let credentials = Credentials::from_file("dummy_credentials_file_for_tests.json").unwrap();
///
/// let claims = JwtClaims::new(credentials.iss(),
/// &Scope::DevStorageReadWrite,
/// &[Scope::DevStorageReadWrite],
/// credentials.token_uri(),
/// None, None);
///
Expand All @@ -127,6 +130,7 @@ pub fn get_token_as_string(jwt: &Jwt<JwtClaims>, credentials: &Credentials) -> R
/// }
///
/// ```
#[allow(clippy::result_large_err)]
pub fn get_token_blocking(jwt: &Jwt<JwtClaims>, credentials: &Credentials) -> Result<Token> {
let rt = Runtime::new()?;
rt.block_on(get_token(jwt, credentials))
Expand Down Expand Up @@ -156,7 +160,7 @@ pub fn get_token_blocking(jwt: &Jwt<JwtClaims>, credentials: &Credentials) -> Re
/// let credentials = Credentials::from_file("dummy_credentials_file_for_tests.json").unwrap();
///
/// let claims = JwtClaims::new(credentials.iss(),
/// &Scope::DevStorageReadWrite,
/// &[Scope::DevStorageReadWrite],
/// credentials.token_uri(),
/// None, None);
///
Expand Down Expand Up @@ -227,7 +231,7 @@ mod tests {

let claims = JwtClaims::new(
String::from(iss),
&Scope::DevStorageReadWrite,
&[Scope::DevStorageReadWrite],
String::from(token_url),
Some(1482317385),
Some(3600),
Expand All @@ -240,6 +244,31 @@ mod tests {
assert_eq!(jwt.finalize().unwrap(), "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzb21lX2lzcyIsInNjb3BlIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vYXV0aC9kZXZzdG9yYWdlLnJlYWRfd3JpdGUiLCJhdWQiOiJodHRwczovL3d3dy5nb29nbGVhcGlzLmNvbS9vYXV0aDIvdjQvdG9rZW4iLCJleHAiOjE0ODIzMjA5ODUsImlhdCI6MTQ4MjMxNzM4NX0=.BldQozpzNYnLnYWBbqwAWY1j2hPDD3oVY9EOG0eRJN77sC4ZInEyGJT5eXLD39C726TdrEVCHmvhKBJFmaFL2BXNto69_v8lz-3oGnFL5FkUr4RRpukd_6tj7-RZzx15LIzdTqzKfAUlqWoZUdze8Fcd1NJ6w1g49CCghvN_eryvecALpjnHoBkKlIXnSm_udiSf26cYWvCikmW5g8nUqAduFsIYfR-4LMwyUfYH1hNC64SRsfLH9bL4-tyeaoUCv5MXTIhxrJbrhQy3TEOSc5didDrMoYNUu_qjJvxBQbq1Um1W1SpyvSd4eVJn18xZcOmCnoE73RDZcxT5hDpaRQ==");
}

#[test]
fn test_jwt_encode_multiple_scopes() {
use auth::JwtClaims;
use scopes::Scope;
use smpl_jwt::{Jwt, RSAKey};

let token_url = "https://www.googleapis.com/oauth2/v4/token";
let iss = "some_iss"; // https://developers.google.com/identity/protocols/OAuth2ServiceAccount
let private_key_file = "random_rsa_for_testing";

let claims = JwtClaims::new(
String::from(iss),
&[Scope::DevStorageReadWrite, Scope::DevStorageReadOnly],
String::from(token_url),
Some(1482317385),
Some(3600),
);
let key = match RSAKey::from_pem(private_key_file) {
Ok(x) => x,
Err(e) => panic!("{}", e),
};
let jwt = Jwt::new(claims, key, None);
assert_eq!(jwt.finalize().unwrap(), "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzb21lX2lzcyIsInNjb3BlIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vYXV0aC9kZXZzdG9yYWdlLnJlYWRfd3JpdGUgaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vYXV0aC9kZXZzdG9yYWdlLnJlYWRfb25seSIsImF1ZCI6Imh0dHBzOi8vd3d3Lmdvb2dsZWFwaXMuY29tL29hdXRoMi92NC90b2tlbiIsImV4cCI6MTQ4MjMyMDk4NSwiaWF0IjoxNDgyMzE3Mzg1fQ==.BUWdKTcaN11Y8X6MV2KLBnB1JBeEq-7AvepT_1gjgG7g2out7zlxgQmK-RxhjZBDr0UeIThtB-afaTxOMEEhtrxXW4Moz8p8SIC01j6a8HS49xCfTCPsyqnrXRcOJwEaI6LNAht_yJ-H5Q6ql0bk1zdtZyVBVMbQ94ZWAeZqQcUWQqIGsr11W-6hueFX8fIDCTGHsmsz0VuyQEpwfSFdeO_7LrLjfmUMN8GGzldT0b8v7-SwK7xzEl4DrReRpDW0s0Aeq16WZzFd-dzaFox5xWWJq3xcNl_tR3eTk7DW8s95bMQDmNa4CGFmGha1PrUnVJRW9p9wqFO90t1G7xD97A==");
}

#[test]
fn get_token_test() {
// This test will always pass, output is logged via debug macro
Expand All @@ -253,7 +282,7 @@ mod tests {

let claims = JwtClaims::new(
String::from(iss),
&Scope::DevStorageReadWrite,
&[Scope::DevStorageReadWrite],
String::from(token_url),
None,
None,
Expand Down

0 comments on commit 07fd57d

Please sign in to comment.