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