diff --git a/src/authenticator.rs b/src/authenticator.rs index 8d2f602..8325905 100644 --- a/src/authenticator.rs +++ b/src/authenticator.rs @@ -15,6 +15,8 @@ use crate::storage::{self, Storage, TokenStorage}; use crate::types::{AccessToken, ApplicationSecret, TokenInfo}; use private::AuthFlow; +use crate::access_token::{AccessTokenFlow}; + use futures::lock::Mutex; use http::{Uri}; use hyper::client::connect::Connection; @@ -414,6 +416,39 @@ impl AuthorizedUserAuthenticator { ) } } +/// Create a access token authenticator for use with pre-generated +/// access tokens +/// ``` +/// # async fn foo() { +/// # use yup_oauth2::authenticator::AccessTokenAuthenticator; +/// # let authenticator = yup_oauth2::AccessTokenAuthenticator::builder("TOKEN".to_string()) +/// # .build() +/// # .await +/// # .expect("failed to create authenticator"); +/// # } +/// ``` +pub struct AccessTokenAuthenticator; +impl AccessTokenAuthenticator { + /// the builder pattern for the authenticator + pub fn builder( + access_token: String, + ) -> AuthenticatorBuilder { + Self::with_client(access_token, DefaultHyperClient) + } + /// Construct a new Authenticator that uses the installed flow and the provided http client. + /// the client itself is not used + pub fn with_client( + access_token: String, + client: C, + ) -> AuthenticatorBuilder { + AuthenticatorBuilder::new( + AccessTokenFlow { + access_token: access_token, + }, + client, + ) + } +} /// ## Methods available when building any Authenticator. /// ``` @@ -674,6 +709,21 @@ impl AuthenticatorBuilder { } } +/// ## Methods available when building an access token flow Authenticator. +impl AuthenticatorBuilder { + /// Create the authenticator. + pub async fn build(self) -> io::Result> + where + C: HyperClientBuilder, + { + Self::common_build( + self.hyper_client_builder, + self.storage_type, + AuthFlow::AccessTokenFlow(self.auth_flow), + ) + .await + } +} mod private { use crate::application_default_credentials::ApplicationDefaultCredentialsFlow; use crate::authorized_user::AuthorizedUserFlow; @@ -684,6 +734,7 @@ mod private { #[cfg(feature = "service_account")] use crate::service_account::ServiceAccountFlow; use crate::types::{ApplicationSecret, TokenInfo}; + use crate::access_token::AccessTokenFlow; pub enum AuthFlow { DeviceFlow(DeviceFlow), @@ -692,6 +743,7 @@ mod private { ServiceAccountFlow(ServiceAccountFlow), ApplicationDefaultCredentialsFlow(ApplicationDefaultCredentialsFlow), AuthorizedUserFlow(AuthorizedUserFlow), + AccessTokenFlow(AccessTokenFlow), } impl AuthFlow { @@ -703,6 +755,7 @@ mod private { AuthFlow::ServiceAccountFlow(_) => None, AuthFlow::ApplicationDefaultCredentialsFlow(_) => None, AuthFlow::AuthorizedUserFlow(_) => None, + AuthFlow::AccessTokenFlow(_) => None, } } @@ -733,6 +786,9 @@ mod private { AuthFlow::AuthorizedUserFlow(authorized_user_flow) => { authorized_user_flow.token(hyper_client, scopes).await } + AuthFlow::AccessTokenFlow(access_token_flow) => { + access_token_flow.token(hyper_client, scopes).await + } } } } diff --git a/src/lib.rs b/src/lib.rs index f6f886d..b274277 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -76,6 +76,7 @@ mod application_default_credentials; pub mod authenticator; pub mod authenticator_delegate; pub mod authorized_user; +pub mod access_token; mod device; pub mod error; mod helper; @@ -98,6 +99,7 @@ pub use crate::authenticator::ServiceAccountAuthenticator; pub use crate::authenticator::{ ApplicationDefaultCredentialsAuthenticator, AuthorizedUserAuthenticator, DeviceFlowAuthenticator, InstalledFlowAuthenticator, + AccessTokenAuthenticator, }; pub use crate::helper::*; diff --git a/tests/tests.rs b/tests/tests.rs index 561876e..aa4756d 100644 --- a/tests/tests.rs +++ b/tests/tests.rs @@ -5,6 +5,7 @@ use yup_oauth2::{ ApplicationDefaultCredentialsAuthenticator, ApplicationDefaultCredentialsFlowOpts, ApplicationSecret, DeviceFlowAuthenticator, Error, InstalledFlowAuthenticator, InstalledFlowReturnMethod, ServiceAccountAuthenticator, ServiceAccountKey, + AccessTokenAuthenticator, }; use std::future::Future; @@ -643,3 +644,16 @@ async fn test_default_application_credentials_from_metadata_server() { .unwrap(); assert_eq!(token.as_str(), "accesstoken"); } + +#[tokio::test] +async fn test_access_token() { + let authenticator = AccessTokenAuthenticator::with_client("0815".to_string(), DefaultHyperClient) + .build() + .await + .unwrap(); + let token = authenticator + .token(&["https://googleapis.com/some/scope"]) + .await + .unwrap(); + assert_eq!(token.as_str(), "0815".to_string()); +}