builder pattern for adc struct

This commit is contained in:
Antti Peltonen
2021-06-10 05:49:41 +00:00
committed by Lukas Winkler
parent 7638946508
commit 921f1c7190
3 changed files with 68 additions and 32 deletions

View File

@@ -1,12 +1,18 @@
use yup_oauth2::authenticator::ApplicationDefaultCredentialsTypes;
use yup_oauth2::ApplicationDefaultCredentialsAuthenticator;
#[tokio::main]
async fn main() {
let auth = ApplicationDefaultCredentialsAuthenticator::builder()
.await
.build()
.await
.unwrap();
let auth = match ApplicationDefaultCredentialsAuthenticator::builder().await {
ApplicationDefaultCredentialsTypes::InstanceMetadata(auth) => auth
.build()
.await
.expect("Unable to create instance metadata authenticator"),
ApplicationDefaultCredentialsTypes::ServiceAccount(auth) => auth
.build()
.await
.expect("Unable to create service account authenticator"),
};
let scopes = &["https://www.googleapis.com/auth/pubsub"];
let tok = auth.token(scopes).await.unwrap();

View File

@@ -260,36 +260,66 @@ impl ServiceAccountAuthenticator {
/// Create an authenticator that uses a application default credentials.
/// ```
/// # async fn foo() {
/// let authenticator = yup_oauth2::ApplicationDefaultCredentialsAuthenticator::builder()
/// .await
/// .build()
/// .await
/// .expect("failed to create authenticator");
/// let authenticator = match ApplicationDefaultCredentialsAuthenticator::builder().await {
/// ApplicationDefaultCredentialsTypes::InstanceMetadata(auth) => auth
/// .build()
/// .await
/// .expect("Unable to create instance metadata authenticator"),
/// ApplicationDefaultCredentialsTypes::ServiceAccount(auth) => auth
/// .build()
/// .await
/// .expect("Unable to create service account authenticator"),
/// };
/// # }
/// ```
pub struct ApplicationDefaultCredentialsAuthenticator;
impl ApplicationDefaultCredentialsAuthenticator {
/// Use the builder pattern to create an Authenticator that uses a service account.
pub async fn builder(
/// Use modified builder pattern to create an Authenticator that uses GCE instance metadata server
/// to provide tokens.
pub fn from_instance_metadata(
) -> AuthenticatorBuilder<DefaultHyperClient, ApplicationDefaultCredentialsFlowOpts> {
match std::env::var("GOOGLE_APPLICATION_CREDENTIALS") {
Ok(_path) => {
todo!()
// # here we would need to do something like this:
// let service_account_key = crate::read_service_account_key(path).await.unwrap();
// AuthenticatorBuilder::<DefaultHyperClient, _>::with_auth_flow(
// ServiceAccountFlowOpts {
// key: service_account_key,
// subject: None,
// },
// )
}
Err(_e) => AuthenticatorBuilder::<DefaultHyperClient, _>::with_auth_flow(
ApplicationDefaultCredentialsFlowOpts {},
AuthenticatorBuilder::<DefaultHyperClient, _>::with_auth_flow(
ApplicationDefaultCredentialsFlowOpts {},
)
}
/// Use modified builder pattern to create an Authenticator that pulls default application credentials
/// service account file name from os environment variable.
pub async fn from_environment(
) -> Result<AuthenticatorBuilder<DefaultHyperClient, ServiceAccountFlowOpts>, std::env::VarError>
{
let service_account_key =
crate::read_service_account_key(std::env::var("GOOGLE_APPLICATION_CREDENTIALS")?)
.await
.unwrap();
Ok(
AuthenticatorBuilder::<DefaultHyperClient, _>::with_auth_flow(ServiceAccountFlowOpts {
key: service_account_key,
subject: None,
}),
)
}
/// Use the builder pattern to deduce which model of authenticator should be used:
/// Service account one or GCE instance metadata kind
pub async fn builder() -> ApplicationDefaultCredentialsTypes {
match ApplicationDefaultCredentialsAuthenticator::from_environment().await {
Ok(builder) => ApplicationDefaultCredentialsTypes::ServiceAccount(builder),
Err(_) => ApplicationDefaultCredentialsTypes::InstanceMetadata(
ApplicationDefaultCredentialsAuthenticator::from_instance_metadata(),
),
}
}
}
/// Types of authenticators provided by ApplicationDefaultCredentialsAuthenticator
pub enum ApplicationDefaultCredentialsTypes {
/// Service account based authenticator signature
ServiceAccount(AuthenticatorBuilder<DefaultHyperClient, ServiceAccountFlowOpts>),
/// GCE Instance Metadata based authenticator signature
InstanceMetadata(
AuthenticatorBuilder<DefaultHyperClient, ApplicationDefaultCredentialsFlowOpts>,
),
}
/// ## Methods available when building any Authenticator.
/// ```

View File

@@ -599,7 +599,8 @@ async fn test_disk_storage() {
}
#[tokio::test]
async fn test_default_application_credentials() {
async fn test_default_application_credentials_from_metadata_server() {
use yup_oauth2::authenticator::ApplicationDefaultCredentialsTypes;
let _ = env_logger::try_init();
let server = Server::run();
server.expect(
@@ -618,11 +619,10 @@ async fn test_default_application_credentials() {
"expires_in": 12345678,
}))),
);
let authenticator = ApplicationDefaultCredentialsAuthenticator::builder()
.await
.build()
.await
.unwrap();
let authenticator = match ApplicationDefaultCredentialsAuthenticator::builder().await {
ApplicationDefaultCredentialsTypes::InstanceMetadata(auth) => auth.build().await.unwrap(),
_ => panic!("We are not testing service account adc model"),
};
let token = authenticator
.token(&["https://googleapis.com/some/scope"])
.await