1use crate::application_default_credentials::{
3 ApplicationDefaultCredentialsFlow, ApplicationDefaultCredentialsFlowOpts,
4};
5use crate::authenticator_delegate::{DeviceFlowDelegate, InstalledFlowDelegate};
6use crate::authorized_user::{AuthorizedUserFlow, AuthorizedUserSecret};
7#[cfg(any(feature = "hyper-rustls", feature = "hyper-tls"))]
8use crate::client::DefaultHyperClientBuilder;
9use crate::client::{HttpClient, HyperClientBuilder};
10use crate::device::DeviceFlow;
11use crate::error::Error;
12use crate::external_account::{ExternalAccountFlow, ExternalAccountSecret};
13use crate::installed::{InstalledFlow, InstalledFlowReturnMethod};
14use crate::refresh::RefreshFlow;
15use crate::service_account_impersonator::ServiceAccountImpersonationFlow;
16
17#[cfg(feature = "service-account")]
18use crate::service_account::{self, ServiceAccountFlow, ServiceAccountFlowOpts, ServiceAccountKey};
19use crate::storage::{self, Storage, TokenStorage};
20use crate::types::{AccessToken, ApplicationSecret, TokenInfo};
21use private::AuthFlow;
22
23use crate::access_token::AccessTokenFlow;
24
25use hyper_util::client::legacy::connect::Connect;
26use std::borrow::Cow;
27use std::fmt;
28use std::io;
29use std::path::PathBuf;
30use std::sync::Arc;
31use std::time::Duration;
32use tokio::sync::Mutex;
33
34struct InnerAuthenticator<C>
35where
36 C: Connect + Clone + Send + Sync + 'static,
37{
38 hyper_client: HttpClient<C>,
39 storage: Storage,
40 auth_flow: AuthFlow,
41}
42
43#[derive(Clone)]
46pub struct Authenticator<C>
47where
48 C: Connect + Clone + Send + Sync + 'static,
49{
50 inner: Arc<InnerAuthenticator<C>>,
51}
52
53struct DisplayScopes<'a, T>(&'a [T]);
54impl<T> fmt::Display for DisplayScopes<'_, T>
55where
56 T: AsRef<str>,
57{
58 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
59 f.write_str("[")?;
60 let mut iter = self.0.iter();
61 if let Some(first) = iter.next() {
62 f.write_str(first.as_ref())?;
63 for scope in iter {
64 f.write_str(", ")?;
65 f.write_str(scope.as_ref())?;
66 }
67 }
68 f.write_str("]")
69 }
70}
71
72impl<C> Authenticator<C>
73where
74 C: Connect + Clone + Send + Sync + 'static,
75{
76 pub async fn token<'a, T>(&'a self, scopes: &'a [T]) -> Result<AccessToken, Error>
78 where
79 T: AsRef<str>,
80 {
81 self.find_token_info(scopes, false)
82 .await
83 .map(|info| info.into())
84 }
85
86 pub async fn force_refreshed_token<'a, T>(
89 &'a self,
90 scopes: &'a [T],
91 ) -> Result<AccessToken, Error>
92 where
93 T: AsRef<str>,
94 {
95 self.find_token_info(scopes, true)
96 .await
97 .map(|info| info.into())
98 }
99
100 pub async fn id_token<'a, T>(&'a self, scopes: &'a [T]) -> Result<Option<String>, Error>
102 where
103 T: AsRef<str>,
104 {
105 self.find_token_info(scopes, false)
106 .await
107 .map(|info| info.id_token)
108 }
109
110 async fn find_token_info<'a, T>(
112 &'a self,
113 scopes: &'a [T],
114 force_refresh: bool,
115 ) -> Result<TokenInfo, Error>
116 where
117 T: AsRef<str>,
118 {
119 log::debug!(
120 "access token requested for scopes: {}",
121 DisplayScopes(scopes)
122 );
123 let hashed_scopes = storage::ScopeSet::from(scopes);
124 match (
125 self.inner.storage.get(hashed_scopes).await,
126 self.inner.auth_flow.app_secret(),
127 ) {
128 (Some(t), _) if !t.is_expired() && !force_refresh => {
129 log::debug!("found valid token in cache: {:?}", t);
131 Ok(t)
132 }
133 (
134 Some(TokenInfo {
135 refresh_token: Some(refresh_token),
136 ..
137 }),
138 Some(app_secret),
139 ) => {
140 let token_info_result = RefreshFlow::refresh_token(
142 &self.inner.hyper_client,
143 app_secret,
144 &refresh_token,
145 )
146 .await;
147 let token_info = if let Ok(token_info) = token_info_result {
148 token_info
149 } else {
150 self.inner
152 .auth_flow
153 .token(&self.inner.hyper_client, scopes)
154 .await?
155 };
156 self.inner
157 .storage
158 .set(hashed_scopes, token_info.clone())
159 .await?;
160 Ok(token_info)
161 }
162 _ => {
163 let token_info = self
165 .inner
166 .auth_flow
167 .token(&self.inner.hyper_client, scopes)
168 .await?;
169 self.inner
170 .storage
171 .set(hashed_scopes, token_info.clone())
172 .await?;
173 Ok(token_info)
174 }
175 }
176 }
177}
178
179pub struct AuthenticatorBuilder<C, F> {
181 hyper_client_builder: C,
182 storage_type: StorageType,
183 auth_flow: F,
184}
185
186pub struct InstalledFlowAuthenticator;
203impl InstalledFlowAuthenticator {
204 #[cfg(any(feature = "hyper-rustls", feature = "hyper-tls"))]
206 #[cfg_attr(docsrs, doc(cfg(any(feature = "hyper-rustls", feature = "hyper-tls"))))]
207 pub fn builder(
208 app_secret: ApplicationSecret,
209 method: InstalledFlowReturnMethod,
210 ) -> AuthenticatorBuilder<DefaultHyperClientBuilder, InstalledFlow> {
211 Self::with_client(app_secret, method, DefaultHyperClientBuilder::default())
212 }
213
214 pub fn with_client<C>(
216 app_secret: ApplicationSecret,
217 method: InstalledFlowReturnMethod,
218 client: C,
219 ) -> AuthenticatorBuilder<C, InstalledFlow> {
220 AuthenticatorBuilder::new(InstalledFlow::new(app_secret, method), client)
221 }
222}
223
224pub struct DeviceFlowAuthenticator;
236impl DeviceFlowAuthenticator {
237 #[cfg(any(feature = "hyper-rustls", feature = "hyper-tls"))]
239 #[cfg_attr(docsrs, doc(cfg(any(feature = "hyper-rustls", feature = "hyper-tls"))))]
240 pub fn builder(
241 app_secret: ApplicationSecret,
242 ) -> AuthenticatorBuilder<DefaultHyperClientBuilder, DeviceFlow> {
243 Self::with_client(app_secret, DefaultHyperClientBuilder::default())
244 }
245
246 pub fn with_client<C>(
248 app_secret: ApplicationSecret,
249 client: C,
250 ) -> AuthenticatorBuilder<C, DeviceFlow> {
251 AuthenticatorBuilder::new(DeviceFlow::new(app_secret), client)
252 }
253}
254
255#[cfg(feature = "service-account")]
267pub struct ServiceAccountAuthenticator;
268
269#[cfg(feature = "service-account")]
270impl ServiceAccountAuthenticator {
271 #[cfg(any(feature = "hyper-rustls", feature = "hyper-tls"))]
273 #[cfg_attr(docsrs, doc(cfg(any(feature = "hyper-rustls", feature = "hyper-tls"))))]
274 pub fn builder(
275 service_account_key: ServiceAccountKey,
276 ) -> AuthenticatorBuilder<DefaultHyperClientBuilder, ServiceAccountFlowOpts> {
277 Self::with_client(service_account_key, DefaultHyperClientBuilder::default())
278 }
279
280 pub fn with_client<C>(
282 service_account_key: ServiceAccountKey,
283 client: C,
284 ) -> AuthenticatorBuilder<C, ServiceAccountFlowOpts> {
285 AuthenticatorBuilder::new(
286 ServiceAccountFlowOpts {
287 key: service_account::FlowOptsKey::Key(Box::new(service_account_key)),
288 subject: None,
289 },
290 client,
291 )
292 }
293}
294
295pub struct ApplicationDefaultCredentialsAuthenticator;
317impl ApplicationDefaultCredentialsAuthenticator {
318 #[cfg(feature = "service-account")]
320 pub async fn from_environment() -> Result<ServiceAccountFlowOpts, std::env::VarError> {
321 let key_path = std::env::var("GOOGLE_APPLICATION_CREDENTIALS")?;
322
323 Ok(ServiceAccountFlowOpts {
324 key: service_account::FlowOptsKey::Path(key_path.into()),
325 subject: None,
326 })
327 }
328
329 #[cfg(feature = "service-account")]
332 #[cfg(any(feature = "hyper-rustls", feature = "hyper-tls"))]
333 #[cfg_attr(docsrs, doc(cfg(any(feature = "hyper-rustls", feature = "hyper-tls"))))]
334 pub async fn builder(
335 opts: ApplicationDefaultCredentialsFlowOpts,
336 ) -> ApplicationDefaultCredentialsTypes<DefaultHyperClientBuilder> {
337 Self::with_client(opts, DefaultHyperClientBuilder::default()).await
338 }
339
340 #[cfg(feature = "service-account")]
342 pub async fn with_client<C>(
343 opts: ApplicationDefaultCredentialsFlowOpts,
344 client: C,
345 ) -> ApplicationDefaultCredentialsTypes<C>
346 where
347 C: HyperClientBuilder,
348 {
349 match ApplicationDefaultCredentialsAuthenticator::from_environment().await {
350 Ok(flow_opts) => {
351 let builder = AuthenticatorBuilder::new(flow_opts, client);
352
353 ApplicationDefaultCredentialsTypes::ServiceAccount(builder)
354 }
355 Err(_) => ApplicationDefaultCredentialsTypes::InstanceMetadata(
356 AuthenticatorBuilder::new(opts, client),
357 ),
358 }
359 }
360}
361pub enum ApplicationDefaultCredentialsTypes<C>
363where
364 C: HyperClientBuilder,
365{
366 #[cfg(feature = "service-account")]
368 ServiceAccount(AuthenticatorBuilder<C, ServiceAccountFlowOpts>),
369 InstanceMetadata(AuthenticatorBuilder<C, ApplicationDefaultCredentialsFlowOpts>),
371}
372
373pub struct AuthorizedUserAuthenticator;
386impl AuthorizedUserAuthenticator {
387 #[cfg(any(feature = "hyper-rustls", feature = "hyper-tls"))]
389 #[cfg_attr(docsrs, doc(cfg(any(feature = "hyper-rustls", feature = "hyper-tls"))))]
390 pub fn builder(
391 authorized_user_secret: AuthorizedUserSecret,
392 ) -> AuthenticatorBuilder<DefaultHyperClientBuilder, AuthorizedUserFlow> {
393 Self::with_client(authorized_user_secret, DefaultHyperClientBuilder::default())
394 }
395
396 pub fn with_client<C>(
398 authorized_user_secret: AuthorizedUserSecret,
399 client: C,
400 ) -> AuthenticatorBuilder<C, AuthorizedUserFlow> {
401 AuthenticatorBuilder::new(
402 AuthorizedUserFlow {
403 secret: authorized_user_secret,
404 },
405 client,
406 )
407 }
408}
409
410pub struct ExternalAccountAuthenticator;
423impl ExternalAccountAuthenticator {
424 #[cfg(any(feature = "hyper-rustls", feature = "hyper-tls"))]
426 #[cfg_attr(docsrs, doc(cfg(any(feature = "hyper-rustls", feature = "hyper-tls"))))]
427 pub fn builder(
428 external_account_secret: ExternalAccountSecret,
429 ) -> AuthenticatorBuilder<DefaultHyperClientBuilder, ExternalAccountFlow> {
430 Self::with_client(
431 external_account_secret,
432 DefaultHyperClientBuilder::default(),
433 )
434 }
435
436 pub fn with_client<C>(
438 external_account_secret: ExternalAccountSecret,
439 client: C,
440 ) -> AuthenticatorBuilder<C, ExternalAccountFlow> {
441 AuthenticatorBuilder::new(
442 ExternalAccountFlow {
443 secret: external_account_secret,
444 },
445 client,
446 )
447 }
448}
449
450#[cfg(any(feature = "hyper-rustls", feature = "hyper-tls"))]
462pub struct AccessTokenAuthenticator;
463
464#[cfg(any(feature = "hyper-rustls", feature = "hyper-tls"))]
465impl AccessTokenAuthenticator {
466 pub fn builder(
468 access_token: String,
469 ) -> AuthenticatorBuilder<DefaultHyperClientBuilder, AccessTokenFlow> {
470 Self::with_client(access_token, DefaultHyperClientBuilder::default())
471 }
472 pub fn with_client<C>(
475 access_token: String,
476 client: C,
477 ) -> AuthenticatorBuilder<C, AccessTokenFlow> {
478 AuthenticatorBuilder::new(AccessTokenFlow { access_token }, client)
479 }
480}
481
482pub struct ServiceAccountImpersonationAuthenticator;
498impl ServiceAccountImpersonationAuthenticator {
499 #[cfg(any(feature = "hyper-rustls", feature = "hyper-tls"))]
501 #[cfg_attr(docsrs, doc(cfg(any(feature = "hyper-rustls", feature = "hyper-tls"))))]
502 pub fn builder(
503 authorized_user_secret: AuthorizedUserSecret,
504 service_account_email: &str,
505 ) -> AuthenticatorBuilder<DefaultHyperClientBuilder, ServiceAccountImpersonationFlow> {
506 Self::with_client(
507 authorized_user_secret,
508 service_account_email,
509 DefaultHyperClientBuilder::default(),
510 )
511 }
512
513 pub fn with_client<C>(
515 authorized_user_secret: AuthorizedUserSecret,
516 service_account_email: &str,
517 client: C,
518 ) -> AuthenticatorBuilder<C, ServiceAccountImpersonationFlow> {
519 AuthenticatorBuilder::new(
520 ServiceAccountImpersonationFlow::new(authorized_user_secret, service_account_email),
521 client,
522 )
523 }
524}
525
526impl<C, F> AuthenticatorBuilder<C, F> {
539 async fn common_build(
540 hyper_client_builder: C,
541 storage_type: StorageType,
542 auth_flow: AuthFlow,
543 ) -> io::Result<Authenticator<C::Connector>>
544 where
545 C: HyperClientBuilder,
546 {
547 let hyper_client = hyper_client_builder.build_hyper_client().map_err(|err| {
548 io::Error::other(
549 format!("failed to build hyper client: {}", err),
550 )
551 })?;
552
553 let storage = match storage_type {
554 StorageType::Memory => Storage::Memory {
555 tokens: Mutex::new(storage::JSONTokens::new()),
556 },
557 StorageType::Disk(path) => Storage::Disk(storage::DiskStorage::new(path).await?),
558 StorageType::Custom(custom_store) => Storage::Custom(custom_store),
559 };
560
561 Ok(Authenticator {
562 inner: Arc::new(InnerAuthenticator {
563 hyper_client,
564 storage,
565 auth_flow,
566 }),
567 })
568 }
569
570 fn new(auth_flow: F, hyper_client_builder: C) -> AuthenticatorBuilder<C, F> {
571 AuthenticatorBuilder {
572 hyper_client_builder,
573 storage_type: StorageType::Memory,
574 auth_flow,
575 }
576 }
577
578 pub fn with_storage(self, storage: Box<dyn TokenStorage>) -> Self {
580 AuthenticatorBuilder {
581 storage_type: StorageType::Custom(storage),
582 ..self
583 }
584 }
585
586 pub fn persist_tokens_to_disk<P: Into<PathBuf>>(self, path: P) -> AuthenticatorBuilder<C, F> {
588 AuthenticatorBuilder {
589 storage_type: StorageType::Disk(path.into()),
590 ..self
591 }
592 }
593}
594
595impl<C, F> AuthenticatorBuilder<C, F>
596where
597 C: HyperClientBuilder,
598{
599 pub fn with_timeout(self, timeout: Duration) -> Self {
601 AuthenticatorBuilder {
602 hyper_client_builder: self.hyper_client_builder.with_timeout(timeout),
603 ..self
604 }
605 }
606}
607
608impl<C> AuthenticatorBuilder<C, DeviceFlow> {
624 pub fn device_code_url(self, url: impl Into<Cow<'static, str>>) -> Self {
626 AuthenticatorBuilder {
627 auth_flow: DeviceFlow {
628 device_code_url: url.into(),
629 ..self.auth_flow
630 },
631 ..self
632 }
633 }
634
635 pub fn flow_delegate(self, flow_delegate: Box<dyn DeviceFlowDelegate>) -> Self {
637 AuthenticatorBuilder {
638 auth_flow: DeviceFlow {
639 flow_delegate,
640 ..self.auth_flow
641 },
642 ..self
643 }
644 }
645
646 pub fn grant_type(self, grant_type: impl Into<Cow<'static, str>>) -> Self {
648 AuthenticatorBuilder {
649 auth_flow: DeviceFlow {
650 grant_type: grant_type.into(),
651 ..self.auth_flow
652 },
653 ..self
654 }
655 }
656
657 pub async fn build(self) -> io::Result<Authenticator<C::Connector>>
659 where
660 C: HyperClientBuilder,
661 {
662 Self::common_build(
663 self.hyper_client_builder,
664 self.storage_type,
665 AuthFlow::DeviceFlow(self.auth_flow),
666 )
667 .await
668 }
669}
670
671impl<C> AuthenticatorBuilder<C, InstalledFlow> {
689 pub fn flow_delegate(self, flow_delegate: Box<dyn InstalledFlowDelegate>) -> Self {
691 AuthenticatorBuilder {
692 auth_flow: InstalledFlow {
693 flow_delegate,
694 ..self.auth_flow
695 },
696 ..self
697 }
698 }
699 pub fn force_account_selection(self, force: bool) -> Self {
701 AuthenticatorBuilder {
702 auth_flow: InstalledFlow {
703 force_account_selection: force,
704 ..self.auth_flow
705 },
706 ..self
707 }
708 }
709
710 pub async fn build(self) -> io::Result<Authenticator<C::Connector>>
712 where
713 C: HyperClientBuilder,
714 {
715 Self::common_build(
716 self.hyper_client_builder,
717 self.storage_type,
718 AuthFlow::InstalledFlow(self.auth_flow),
719 )
720 .await
721 }
722}
723
724#[cfg(feature = "service-account")]
739impl<C> AuthenticatorBuilder<C, ServiceAccountFlowOpts> {
740 pub fn subject(self, subject: impl Into<String>) -> Self {
742 AuthenticatorBuilder {
743 auth_flow: ServiceAccountFlowOpts {
744 subject: Some(subject.into()),
745 ..self.auth_flow
746 },
747 ..self
748 }
749 }
750
751 pub async fn build(self) -> io::Result<Authenticator<C::Connector>>
753 where
754 C: HyperClientBuilder,
755 {
756 let service_account_auth_flow = ServiceAccountFlow::new(self.auth_flow).await?;
757 Self::common_build(
758 self.hyper_client_builder,
759 self.storage_type,
760 AuthFlow::ServiceAccountFlow(service_account_auth_flow),
761 )
762 .await
763 }
764}
765
766impl<C> AuthenticatorBuilder<C, ApplicationDefaultCredentialsFlowOpts> {
767 pub async fn build(self) -> io::Result<Authenticator<C::Connector>>
769 where
770 C: HyperClientBuilder,
771 {
772 let application_default_credential_flow =
773 ApplicationDefaultCredentialsFlow::new(self.auth_flow);
774 Self::common_build(
775 self.hyper_client_builder,
776 self.storage_type,
777 AuthFlow::ApplicationDefaultCredentialsFlow(application_default_credential_flow),
778 )
779 .await
780 }
781}
782
783impl<C> AuthenticatorBuilder<C, AuthorizedUserFlow> {
785 pub async fn build(self) -> io::Result<Authenticator<C::Connector>>
787 where
788 C: HyperClientBuilder,
789 {
790 Self::common_build(
791 self.hyper_client_builder,
792 self.storage_type,
793 AuthFlow::AuthorizedUserFlow(self.auth_flow),
794 )
795 .await
796 }
797}
798
799impl<C> AuthenticatorBuilder<C, ExternalAccountFlow> {
801 pub async fn build(self) -> io::Result<Authenticator<C::Connector>>
803 where
804 C: HyperClientBuilder,
805 {
806 Self::common_build(
807 self.hyper_client_builder,
808 self.storage_type,
809 AuthFlow::ExternalAccountFlow(self.auth_flow),
810 )
811 .await
812 }
813}
814
815impl<C> AuthenticatorBuilder<C, ServiceAccountImpersonationFlow> {
817 pub async fn build(self) -> io::Result<Authenticator<C::Connector>>
819 where
820 C: HyperClientBuilder,
821 {
822 Self::common_build(
823 self.hyper_client_builder,
824 self.storage_type,
825 AuthFlow::ServiceAccountImpersonationFlow(self.auth_flow),
826 )
827 .await
828 }
829
830 pub fn request_id_token(mut self) -> Self {
835 self.auth_flow.access_token = false;
836 self
837 }
838}
839
840impl<C> AuthenticatorBuilder<C, AccessTokenFlow> {
842 pub async fn build(self) -> io::Result<Authenticator<C::Connector>>
844 where
845 C: HyperClientBuilder,
846 {
847 Self::common_build(
848 self.hyper_client_builder,
849 self.storage_type,
850 AuthFlow::AccessTokenFlow(self.auth_flow),
851 )
852 .await
853 }
854}
855mod private {
856 use crate::access_token::AccessTokenFlow;
857 use crate::application_default_credentials::ApplicationDefaultCredentialsFlow;
858 use crate::authorized_user::AuthorizedUserFlow;
859 use crate::client::SendRequest;
860 use crate::device::DeviceFlow;
861 use crate::error::Error;
862 use crate::external_account::ExternalAccountFlow;
863 use crate::installed::InstalledFlow;
864 #[cfg(feature = "service-account")]
865 use crate::service_account::ServiceAccountFlow;
866 use crate::service_account_impersonator::ServiceAccountImpersonationFlow;
867 use crate::types::{ApplicationSecret, TokenInfo};
868
869 #[allow(clippy::enum_variant_names)]
870 pub enum AuthFlow {
871 DeviceFlow(DeviceFlow),
872 InstalledFlow(InstalledFlow),
873 #[cfg(feature = "service-account")]
874 ServiceAccountFlow(ServiceAccountFlow),
875 ServiceAccountImpersonationFlow(ServiceAccountImpersonationFlow),
876 ApplicationDefaultCredentialsFlow(ApplicationDefaultCredentialsFlow),
877 AuthorizedUserFlow(AuthorizedUserFlow),
878 ExternalAccountFlow(ExternalAccountFlow),
879 AccessTokenFlow(AccessTokenFlow),
880 }
881
882 impl AuthFlow {
883 pub(crate) fn app_secret(&self) -> Option<&ApplicationSecret> {
884 match self {
885 AuthFlow::DeviceFlow(device_flow) => Some(&device_flow.app_secret),
886 AuthFlow::InstalledFlow(installed_flow) => Some(&installed_flow.app_secret),
887 #[cfg(feature = "service-account")]
888 AuthFlow::ServiceAccountFlow(_) => None,
889 AuthFlow::ServiceAccountImpersonationFlow(_) => None,
890 AuthFlow::ApplicationDefaultCredentialsFlow(_) => None,
891 AuthFlow::AuthorizedUserFlow(_) => None,
892 AuthFlow::ExternalAccountFlow(_) => None,
893 AuthFlow::AccessTokenFlow(_) => None,
894 }
895 }
896
897 pub(crate) async fn token<'a, T>(
898 &'a self,
899 hyper_client: &'a impl SendRequest,
900 scopes: &'a [T],
901 ) -> Result<TokenInfo, Error>
902 where
903 T: AsRef<str>,
904 {
905 match self {
906 AuthFlow::DeviceFlow(device_flow) => device_flow.token(hyper_client, scopes).await,
907 AuthFlow::InstalledFlow(installed_flow) => {
908 installed_flow.token(hyper_client, scopes).await
909 }
910 #[cfg(feature = "service-account")]
911 AuthFlow::ServiceAccountFlow(service_account_flow) => {
912 service_account_flow.token(hyper_client, scopes).await
913 }
914 AuthFlow::ServiceAccountImpersonationFlow(service_account_impersonation_flow) => {
915 service_account_impersonation_flow
916 .token(hyper_client, scopes)
917 .await
918 }
919 AuthFlow::ApplicationDefaultCredentialsFlow(adc_flow) => {
920 adc_flow.token(hyper_client, scopes).await
921 }
922 AuthFlow::AuthorizedUserFlow(authorized_user_flow) => {
923 authorized_user_flow.token(hyper_client, scopes).await
924 }
925 AuthFlow::ExternalAccountFlow(external_account_flow) => {
926 external_account_flow.token(hyper_client, scopes).await
927 }
928 AuthFlow::AccessTokenFlow(access_token_flow) => {
929 access_token_flow.token(hyper_client, scopes).await
930 }
931 }
932 }
933 }
934}
935
936#[cfg(feature = "hyper-rustls")]
937#[cfg_attr(docsrs, doc(cfg(any(feature = "hyper-rustls", feature = "hyper-tls"))))]
938pub type DefaultAuthenticator =
940 Authenticator<hyper_rustls::HttpsConnector<hyper_util::client::legacy::connect::HttpConnector>>;
941
942#[cfg(all(not(feature = "hyper-rustls"), feature = "hyper-tls"))]
943#[cfg_attr(docsrs, doc(cfg(any(feature = "hyper-rustls", feature = "hyper-tls"))))]
944pub type DefaultAuthenticator =
946 Authenticator<hyper_tls::HttpsConnector<hyper_util::client::legacy::connect::HttpConnector>>;
947
948enum StorageType {
950 Memory,
952 Disk(PathBuf),
954 Custom(Box<dyn TokenStorage>),
956}
957
958#[cfg(test)]
959mod tests {
960 #[test]
961 #[cfg(any(feature = "hyper-rustls", feature = "hyper-tls"))]
962 fn ensure_send_sync() {
963 use super::*;
964 fn is_send_sync<T: Send + Sync>() {}
965 is_send_sync::<Authenticator<<DefaultHyperClientBuilder as HyperClientBuilder>::Connector>>(
966 )
967 }
968}