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
548 .build_hyper_client()
549 .map_err(|err| io::Error::other(format!("failed to build hyper client: {}", err)))?;
550
551 let storage = match storage_type {
552 StorageType::Memory => Storage::Memory {
553 tokens: Mutex::new(storage::JSONTokens::new()),
554 },
555 StorageType::Disk(path) => Storage::Disk(storage::DiskStorage::new(path).await?),
556 StorageType::Custom(custom_store) => Storage::Custom(custom_store),
557 };
558
559 Ok(Authenticator {
560 inner: Arc::new(InnerAuthenticator {
561 hyper_client,
562 storage,
563 auth_flow,
564 }),
565 })
566 }
567
568 fn new(auth_flow: F, hyper_client_builder: C) -> AuthenticatorBuilder<C, F> {
569 AuthenticatorBuilder {
570 hyper_client_builder,
571 storage_type: StorageType::Memory,
572 auth_flow,
573 }
574 }
575
576 pub fn with_storage(self, storage: Box<dyn TokenStorage>) -> Self {
578 AuthenticatorBuilder {
579 storage_type: StorageType::Custom(storage),
580 ..self
581 }
582 }
583
584 pub fn persist_tokens_to_disk<P: Into<PathBuf>>(self, path: P) -> AuthenticatorBuilder<C, F> {
586 AuthenticatorBuilder {
587 storage_type: StorageType::Disk(path.into()),
588 ..self
589 }
590 }
591}
592
593impl<C, F> AuthenticatorBuilder<C, F>
594where
595 C: HyperClientBuilder,
596{
597 pub fn with_timeout(self, timeout: Duration) -> Self {
599 AuthenticatorBuilder {
600 hyper_client_builder: self.hyper_client_builder.with_timeout(timeout),
601 ..self
602 }
603 }
604}
605
606impl<C> AuthenticatorBuilder<C, DeviceFlow> {
622 pub fn device_code_url(self, url: impl Into<Cow<'static, str>>) -> Self {
624 AuthenticatorBuilder {
625 auth_flow: DeviceFlow {
626 device_code_url: url.into(),
627 ..self.auth_flow
628 },
629 ..self
630 }
631 }
632
633 pub fn flow_delegate(self, flow_delegate: Box<dyn DeviceFlowDelegate>) -> Self {
635 AuthenticatorBuilder {
636 auth_flow: DeviceFlow {
637 flow_delegate,
638 ..self.auth_flow
639 },
640 ..self
641 }
642 }
643
644 pub fn grant_type(self, grant_type: impl Into<Cow<'static, str>>) -> Self {
646 AuthenticatorBuilder {
647 auth_flow: DeviceFlow {
648 grant_type: grant_type.into(),
649 ..self.auth_flow
650 },
651 ..self
652 }
653 }
654
655 pub async fn build(self) -> io::Result<Authenticator<C::Connector>>
657 where
658 C: HyperClientBuilder,
659 {
660 Self::common_build(
661 self.hyper_client_builder,
662 self.storage_type,
663 AuthFlow::DeviceFlow(self.auth_flow),
664 )
665 .await
666 }
667}
668
669impl<C> AuthenticatorBuilder<C, InstalledFlow> {
687 pub fn flow_delegate(self, flow_delegate: Box<dyn InstalledFlowDelegate>) -> Self {
689 AuthenticatorBuilder {
690 auth_flow: InstalledFlow {
691 flow_delegate,
692 ..self.auth_flow
693 },
694 ..self
695 }
696 }
697 pub fn force_account_selection(self, force: bool) -> Self {
699 AuthenticatorBuilder {
700 auth_flow: InstalledFlow {
701 force_account_selection: force,
702 ..self.auth_flow
703 },
704 ..self
705 }
706 }
707
708 pub async fn build(self) -> io::Result<Authenticator<C::Connector>>
710 where
711 C: HyperClientBuilder,
712 {
713 Self::common_build(
714 self.hyper_client_builder,
715 self.storage_type,
716 AuthFlow::InstalledFlow(self.auth_flow),
717 )
718 .await
719 }
720}
721
722#[cfg(feature = "service-account")]
737impl<C> AuthenticatorBuilder<C, ServiceAccountFlowOpts> {
738 pub fn subject(self, subject: impl Into<String>) -> Self {
740 AuthenticatorBuilder {
741 auth_flow: ServiceAccountFlowOpts {
742 subject: Some(subject.into()),
743 ..self.auth_flow
744 },
745 ..self
746 }
747 }
748
749 pub async fn build(self) -> io::Result<Authenticator<C::Connector>>
751 where
752 C: HyperClientBuilder,
753 {
754 let service_account_auth_flow = ServiceAccountFlow::new(self.auth_flow).await?;
755 Self::common_build(
756 self.hyper_client_builder,
757 self.storage_type,
758 AuthFlow::ServiceAccountFlow(service_account_auth_flow),
759 )
760 .await
761 }
762}
763
764impl<C> AuthenticatorBuilder<C, ApplicationDefaultCredentialsFlowOpts> {
765 pub async fn build(self) -> io::Result<Authenticator<C::Connector>>
767 where
768 C: HyperClientBuilder,
769 {
770 let application_default_credential_flow =
771 ApplicationDefaultCredentialsFlow::new(self.auth_flow);
772 Self::common_build(
773 self.hyper_client_builder,
774 self.storage_type,
775 AuthFlow::ApplicationDefaultCredentialsFlow(application_default_credential_flow),
776 )
777 .await
778 }
779}
780
781impl<C> AuthenticatorBuilder<C, AuthorizedUserFlow> {
783 pub async fn build(self) -> io::Result<Authenticator<C::Connector>>
785 where
786 C: HyperClientBuilder,
787 {
788 Self::common_build(
789 self.hyper_client_builder,
790 self.storage_type,
791 AuthFlow::AuthorizedUserFlow(self.auth_flow),
792 )
793 .await
794 }
795}
796
797impl<C> AuthenticatorBuilder<C, ExternalAccountFlow> {
799 pub async fn build(self) -> io::Result<Authenticator<C::Connector>>
801 where
802 C: HyperClientBuilder,
803 {
804 Self::common_build(
805 self.hyper_client_builder,
806 self.storage_type,
807 AuthFlow::ExternalAccountFlow(self.auth_flow),
808 )
809 .await
810 }
811}
812
813impl<C> AuthenticatorBuilder<C, ServiceAccountImpersonationFlow> {
815 pub async fn build(self) -> io::Result<Authenticator<C::Connector>>
817 where
818 C: HyperClientBuilder,
819 {
820 Self::common_build(
821 self.hyper_client_builder,
822 self.storage_type,
823 AuthFlow::ServiceAccountImpersonationFlow(self.auth_flow),
824 )
825 .await
826 }
827
828 pub fn request_id_token(mut self) -> Self {
833 self.auth_flow.access_token = false;
834 self
835 }
836}
837
838impl<C> AuthenticatorBuilder<C, AccessTokenFlow> {
840 pub async fn build(self) -> io::Result<Authenticator<C::Connector>>
842 where
843 C: HyperClientBuilder,
844 {
845 Self::common_build(
846 self.hyper_client_builder,
847 self.storage_type,
848 AuthFlow::AccessTokenFlow(self.auth_flow),
849 )
850 .await
851 }
852}
853mod private {
854 use crate::access_token::AccessTokenFlow;
855 use crate::application_default_credentials::ApplicationDefaultCredentialsFlow;
856 use crate::authorized_user::AuthorizedUserFlow;
857 use crate::client::SendRequest;
858 use crate::device::DeviceFlow;
859 use crate::error::Error;
860 use crate::external_account::ExternalAccountFlow;
861 use crate::installed::InstalledFlow;
862 #[cfg(feature = "service-account")]
863 use crate::service_account::ServiceAccountFlow;
864 use crate::service_account_impersonator::ServiceAccountImpersonationFlow;
865 use crate::types::{ApplicationSecret, TokenInfo};
866
867 #[allow(clippy::enum_variant_names)]
868 pub enum AuthFlow {
869 DeviceFlow(DeviceFlow),
870 InstalledFlow(InstalledFlow),
871 #[cfg(feature = "service-account")]
872 ServiceAccountFlow(ServiceAccountFlow),
873 ServiceAccountImpersonationFlow(ServiceAccountImpersonationFlow),
874 ApplicationDefaultCredentialsFlow(ApplicationDefaultCredentialsFlow),
875 AuthorizedUserFlow(AuthorizedUserFlow),
876 ExternalAccountFlow(ExternalAccountFlow),
877 AccessTokenFlow(AccessTokenFlow),
878 }
879
880 impl AuthFlow {
881 pub(crate) fn app_secret(&self) -> Option<&ApplicationSecret> {
882 match self {
883 AuthFlow::DeviceFlow(device_flow) => Some(&device_flow.app_secret),
884 AuthFlow::InstalledFlow(installed_flow) => Some(&installed_flow.app_secret),
885 #[cfg(feature = "service-account")]
886 AuthFlow::ServiceAccountFlow(_) => None,
887 AuthFlow::ServiceAccountImpersonationFlow(_) => None,
888 AuthFlow::ApplicationDefaultCredentialsFlow(_) => None,
889 AuthFlow::AuthorizedUserFlow(_) => None,
890 AuthFlow::ExternalAccountFlow(_) => None,
891 AuthFlow::AccessTokenFlow(_) => None,
892 }
893 }
894
895 pub(crate) async fn token<'a, T>(
896 &'a self,
897 hyper_client: &'a impl SendRequest,
898 scopes: &'a [T],
899 ) -> Result<TokenInfo, Error>
900 where
901 T: AsRef<str>,
902 {
903 match self {
904 AuthFlow::DeviceFlow(device_flow) => device_flow.token(hyper_client, scopes).await,
905 AuthFlow::InstalledFlow(installed_flow) => {
906 installed_flow.token(hyper_client, scopes).await
907 }
908 #[cfg(feature = "service-account")]
909 AuthFlow::ServiceAccountFlow(service_account_flow) => {
910 service_account_flow.token(hyper_client, scopes).await
911 }
912 AuthFlow::ServiceAccountImpersonationFlow(service_account_impersonation_flow) => {
913 service_account_impersonation_flow
914 .token(hyper_client, scopes)
915 .await
916 }
917 AuthFlow::ApplicationDefaultCredentialsFlow(adc_flow) => {
918 adc_flow.token(hyper_client, scopes).await
919 }
920 AuthFlow::AuthorizedUserFlow(authorized_user_flow) => {
921 authorized_user_flow.token(hyper_client, scopes).await
922 }
923 AuthFlow::ExternalAccountFlow(external_account_flow) => {
924 external_account_flow.token(hyper_client, scopes).await
925 }
926 AuthFlow::AccessTokenFlow(access_token_flow) => {
927 access_token_flow.token(hyper_client, scopes).await
928 }
929 }
930 }
931 }
932}
933
934#[cfg(feature = "hyper-rustls")]
935#[cfg_attr(docsrs, doc(cfg(any(feature = "hyper-rustls", feature = "hyper-tls"))))]
936pub type DefaultAuthenticator =
938 Authenticator<hyper_rustls::HttpsConnector<hyper_util::client::legacy::connect::HttpConnector>>;
939
940#[cfg(all(not(feature = "hyper-rustls"), feature = "hyper-tls"))]
941#[cfg_attr(docsrs, doc(cfg(any(feature = "hyper-rustls", feature = "hyper-tls"))))]
942pub type DefaultAuthenticator =
944 Authenticator<hyper_tls::HttpsConnector<hyper_util::client::legacy::connect::HttpConnector>>;
945
946enum StorageType {
948 Memory,
950 Disk(PathBuf),
952 Custom(Box<dyn TokenStorage>),
954}
955
956#[cfg(test)]
957mod tests {
958 #[test]
959 #[cfg(any(feature = "hyper-rustls", feature = "hyper-tls"))]
960 fn ensure_send_sync() {
961 use super::*;
962 fn is_send_sync<T: Send + Sync>() {}
963 is_send_sync::<Authenticator<<DefaultHyperClientBuilder as HyperClientBuilder>::Connector>>(
964 )
965 }
966}