Merge pull request #176 from rnarubin/service_account_panic

Remove file IO panic in ApplicationDefaultCreds flow
This commit is contained in:
Lewin Bormann
2022-05-21 09:08:56 -07:00
committed by GitHub
2 changed files with 29 additions and 17 deletions

View File

@@ -10,7 +10,7 @@ use crate::installed::{InstalledFlow, InstalledFlowReturnMethod};
use crate::refresh::RefreshFlow;
#[cfg(feature = "service_account")]
use crate::service_account::{ServiceAccountFlow, ServiceAccountFlowOpts, ServiceAccountKey};
use crate::service_account::{self, ServiceAccountFlow, ServiceAccountFlowOpts, ServiceAccountKey};
use crate::storage::{self, Storage, TokenStorage};
use crate::types::{AccessToken, ApplicationSecret, TokenInfo};
use private::AuthFlow;
@@ -278,7 +278,7 @@ impl ServiceAccountAuthenticator {
) -> AuthenticatorBuilder<C, ServiceAccountFlowOpts> {
AuthenticatorBuilder::new(
ServiceAccountFlowOpts {
key: service_account_key,
key: service_account::FlowOptsKey::Key(service_account_key),
subject: None,
},
client,
@@ -312,13 +312,10 @@ impl ApplicationDefaultCredentialsAuthenticator {
/// Try to build ServiceAccountFlowOpts from the environment
#[cfg(feature = "service_account")]
pub async fn from_environment() -> Result<ServiceAccountFlowOpts, std::env::VarError> {
let service_account_key =
crate::read_service_account_key(std::env::var("GOOGLE_APPLICATION_CREDENTIALS")?)
.await
.unwrap();
let key_path = std::env::var("GOOGLE_APPLICATION_CREDENTIALS")?;
Ok(ServiceAccountFlowOpts {
key: service_account_key,
key: service_account::FlowOptsKey::Path(key_path.into()),
subject: None,
})
}
@@ -626,7 +623,7 @@ impl<C> AuthenticatorBuilder<C, ServiceAccountFlowOpts> {
where
C: HyperClientBuilder,
{
let service_account_auth_flow = ServiceAccountFlow::new(self.auth_flow)?;
let service_account_auth_flow = ServiceAccountFlow::new(self.auth_flow).await?;
Self::common_build(
self.hyper_client_builder,
self.storage_type,

View File

@@ -16,7 +16,7 @@
use crate::error::Error;
use crate::types::TokenInfo;
use std::io;
use std::{io, path::PathBuf};
use hyper::header;
use rustls::{
@@ -158,10 +158,18 @@ impl JWTSigner {
}
pub struct ServiceAccountFlowOpts {
pub(crate) key: ServiceAccountKey,
pub(crate) key: FlowOptsKey,
pub(crate) subject: Option<String>,
}
/// The source of the key given to ServiceAccountFlowOpts.
pub(crate) enum FlowOptsKey {
/// A path at which the key can be read from disk
Path(PathBuf),
/// An already initialized key
Key(ServiceAccountKey),
}
/// ServiceAccountFlow can fetch oauth tokens using a service account.
pub struct ServiceAccountFlow {
key: ServiceAccountKey,
@@ -170,10 +178,15 @@ pub struct ServiceAccountFlow {
}
impl ServiceAccountFlow {
pub(crate) fn new(opts: ServiceAccountFlowOpts) -> Result<Self, io::Error> {
let signer = JWTSigner::new(&opts.key.private_key)?;
pub(crate) async fn new(opts: ServiceAccountFlowOpts) -> Result<Self, io::Error> {
let key = match opts.key {
FlowOptsKey::Path(path) => crate::read_service_account_key(path).await?,
FlowOptsKey::Key(key) => key,
};
let signer = JWTSigner::new(&key.private_key)?;
Ok(ServiceAccountFlow {
key: opts.key,
key,
subject: opts.subject,
signer,
})
@@ -223,10 +236,12 @@ mod tests {
//#[tokio::test]
#[allow(dead_code)]
async fn test_service_account_e2e() {
let key = read_service_account_key(TEST_PRIVATE_KEY_PATH)
.await
.unwrap();
let acc = ServiceAccountFlow::new(ServiceAccountFlowOpts { key, subject: None }).unwrap();
let acc = ServiceAccountFlow::new(ServiceAccountFlowOpts {
key: FlowOptsKey::Path(TEST_PRIVATE_KEY_PATH.into()),
subject: None,
})
.await
.unwrap();
let client = hyper::Client::builder().build(
hyper_rustls::HttpsConnectorBuilder::new()
.with_native_roots()