mirror of
https://github.com/OMGeeky/yup-oauth2.git
synced 2026-02-15 22:24:31 +01:00
Allow overriding metadata url used during testing
This commit is contained in:
@@ -1,9 +1,11 @@
|
||||
use yup_oauth2::authenticator::ApplicationDefaultCredentialsTypes;
|
||||
use yup_oauth2::ApplicationDefaultCredentialsAuthenticator;
|
||||
use yup_oauth2::ApplicationDefaultCredentialsFlowOpts;
|
||||
|
||||
#[tokio::main]
|
||||
async fn main() {
|
||||
let auth = match ApplicationDefaultCredentialsAuthenticator::builder().await {
|
||||
let opts = ApplicationDefaultCredentialsFlowOpts::default();
|
||||
let auth = match ApplicationDefaultCredentialsAuthenticator::builder(opts).await {
|
||||
ApplicationDefaultCredentialsTypes::InstanceMetadata(auth) => auth
|
||||
.build()
|
||||
.await
|
||||
|
||||
@@ -1,13 +1,25 @@
|
||||
use crate::error::Error;
|
||||
use crate::types::TokenInfo;
|
||||
|
||||
pub struct ApplicationDefaultCredentialsFlowOpts;
|
||||
/// Provide options for the Application Default Credential Flow, mostly used for testing
|
||||
pub struct ApplicationDefaultCredentialsFlowOpts {
|
||||
/// Used as base to build the url during token request from GCP metadata server
|
||||
pub metadata_url: Option<String>,
|
||||
}
|
||||
impl Default for ApplicationDefaultCredentialsFlowOpts {
|
||||
fn default() -> Self {
|
||||
Self { metadata_url: None }
|
||||
}
|
||||
}
|
||||
|
||||
pub struct ApplicationDefaultCredentialsFlow {
|
||||
metadata_url: String,
|
||||
}
|
||||
|
||||
/// ServiceAccountFlow can fetch oauth tokens using a service account.
|
||||
pub struct ApplicationDefaultCredentialsFlow;
|
||||
impl ApplicationDefaultCredentialsFlow {
|
||||
pub(crate) fn new(_opts: ApplicationDefaultCredentialsFlowOpts) -> Self {
|
||||
ApplicationDefaultCredentialsFlow {}
|
||||
pub(crate) fn new(opts: ApplicationDefaultCredentialsFlowOpts) -> Self {
|
||||
let metadata_url = opts.metadata_url.unwrap_or_else(|| "http://metadata.google.internal/computeMetadata/v1/instance/service-accounts/default/token".to_string());
|
||||
ApplicationDefaultCredentialsFlow { metadata_url }
|
||||
}
|
||||
|
||||
pub(crate) async fn token<C, T>(
|
||||
@@ -20,7 +32,7 @@ impl ApplicationDefaultCredentialsFlow {
|
||||
C: hyper::client::connect::Connect + Clone + Send + Sync + 'static,
|
||||
{
|
||||
let scope = crate::helper::join(scopes, ",");
|
||||
let token_uri = format!("http://metadata.google.internal/computeMetadata/v1/instance/service-accounts/default/token?scopes={}", scope);
|
||||
let token_uri = format!("{}?scopes={}", self.metadata_url, scope); // TODO: This feels jank, can it be done better?
|
||||
let request = hyper::Request::get(token_uri)
|
||||
.header("Metadata-Flavor", "Google")
|
||||
.body(hyper::Body::from(String::new())) // why body is needed?
|
||||
|
||||
@@ -274,14 +274,7 @@ impl ServiceAccountAuthenticator {
|
||||
/// ```
|
||||
pub struct ApplicationDefaultCredentialsAuthenticator;
|
||||
impl ApplicationDefaultCredentialsAuthenticator {
|
||||
/// Use modified builder pattern to create an Authenticator that uses GCE instance metadata server
|
||||
/// to provide tokens.
|
||||
pub fn from_instance_metadata() -> ApplicationDefaultCredentialsFlowOpts {
|
||||
ApplicationDefaultCredentialsFlowOpts {}
|
||||
}
|
||||
|
||||
/// Use modified builder pattern to create an Authenticator that pulls default application credentials
|
||||
/// service account file name from os environment variable.
|
||||
/// Try to build ServiceAccountFlowOpts from the environment
|
||||
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")?)
|
||||
@@ -296,12 +289,17 @@ impl ApplicationDefaultCredentialsAuthenticator {
|
||||
|
||||
/// 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<DefaultHyperClient> {
|
||||
Self::with_client(DefaultHyperClient).await
|
||||
pub async fn builder(
|
||||
opts: ApplicationDefaultCredentialsFlowOpts,
|
||||
) -> ApplicationDefaultCredentialsTypes<DefaultHyperClient> {
|
||||
Self::with_client(DefaultHyperClient, opts).await
|
||||
}
|
||||
|
||||
/// Use the builder pattern to deduce which model of authenticator should be used and allow providing a hyper client
|
||||
pub async fn with_client<C>(client: C) -> ApplicationDefaultCredentialsTypes<C>
|
||||
pub async fn with_client<C>(
|
||||
client: C,
|
||||
opts: ApplicationDefaultCredentialsFlowOpts,
|
||||
) -> ApplicationDefaultCredentialsTypes<C>
|
||||
where
|
||||
C: HyperClientBuilder,
|
||||
{
|
||||
@@ -311,12 +309,9 @@ impl ApplicationDefaultCredentialsAuthenticator {
|
||||
|
||||
ApplicationDefaultCredentialsTypes::ServiceAccount(builder)
|
||||
}
|
||||
Err(_) => {
|
||||
ApplicationDefaultCredentialsTypes::InstanceMetadata(AuthenticatorBuilder::new(
|
||||
ApplicationDefaultCredentialsAuthenticator::from_instance_metadata(),
|
||||
client,
|
||||
))
|
||||
}
|
||||
Err(_) => ApplicationDefaultCredentialsTypes::InstanceMetadata(
|
||||
AuthenticatorBuilder::new(opts, client),
|
||||
),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -97,6 +97,7 @@ pub use crate::authenticator::{
|
||||
pub use crate::helper::*;
|
||||
pub use crate::installed::InstalledFlowReturnMethod;
|
||||
|
||||
pub use crate::application_default_credentials::ApplicationDefaultCredentialsFlowOpts;
|
||||
pub use crate::service_account::ServiceAccountKey;
|
||||
|
||||
#[doc(inline)]
|
||||
|
||||
@@ -2,9 +2,9 @@ use yup_oauth2::{
|
||||
authenticator::{DefaultAuthenticator, DefaultHyperClient, HyperClientBuilder},
|
||||
authenticator_delegate::{DeviceAuthResponse, DeviceFlowDelegate, InstalledFlowDelegate},
|
||||
error::{AuthError, AuthErrorCode},
|
||||
ApplicationDefaultCredentialsAuthenticator, ApplicationSecret, DeviceFlowAuthenticator, Error,
|
||||
InstalledFlowAuthenticator, InstalledFlowReturnMethod, ServiceAccountAuthenticator,
|
||||
ServiceAccountKey,
|
||||
ApplicationDefaultCredentialsAuthenticator, ApplicationDefaultCredentialsFlowOpts,
|
||||
ApplicationSecret, DeviceFlowAuthenticator, Error, InstalledFlowAuthenticator,
|
||||
InstalledFlowReturnMethod, ServiceAccountAuthenticator, ServiceAccountKey,
|
||||
};
|
||||
|
||||
use std::future::Future;
|
||||
@@ -619,7 +619,11 @@ async fn test_default_application_credentials_from_metadata_server() {
|
||||
"expires_in": 12345678,
|
||||
}))),
|
||||
);
|
||||
let authenticator = match ApplicationDefaultCredentialsAuthenticator::builder().await {
|
||||
|
||||
let opts = ApplicationDefaultCredentialsFlowOpts {
|
||||
metadata_url: Some(server.url("/token").to_string()),
|
||||
};
|
||||
let authenticator = match ApplicationDefaultCredentialsAuthenticator::builder(opts).await {
|
||||
ApplicationDefaultCredentialsTypes::InstanceMetadata(auth) => auth.build().await.unwrap(),
|
||||
_ => panic!("We are not testing service account adc model"),
|
||||
};
|
||||
@@ -627,5 +631,5 @@ async fn test_default_application_credentials_from_metadata_server() {
|
||||
.token(&["https://googleapis.com/some/scope"])
|
||||
.await
|
||||
.unwrap();
|
||||
assert_ne!(token.as_str(), "accesstoken");
|
||||
assert_eq!(token.as_str(), "accesstoken");
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user