From a4c9b6034efd101c88f74999687f95d2cc3bf4e4 Mon Sep 17 00:00:00 2001 From: Glenn Griffin Date: Thu, 7 Nov 2019 15:21:38 -0800 Subject: [PATCH] Require trait implementations to be Send + Sync. Tidy up some of the trait bounds on types and methods. --- src/authenticator.rs | 12 +++++------- src/authenticator_delegate.rs | 12 ++++++------ src/device.rs | 14 +++++++------- src/installed.rs | 24 +++++++++++++++--------- src/service_account.rs | 9 ++++++--- src/storage.rs | 28 ++++++---------------------- 6 files changed, 45 insertions(+), 54 deletions(-) diff --git a/src/authenticator.rs b/src/authenticator.rs index cde9fe4..6e17d2e 100644 --- a/src/authenticator.rs +++ b/src/authenticator.rs @@ -167,9 +167,9 @@ where /// Create the authenticator. pub fn build(self) -> io::Result where - T::TokenGetter: 'static + GetToken + Send, + T::TokenGetter: 'static + GetToken, S: 'static + Send, - AD: 'static + Send + Sync, + AD: 'static, C::Connector: 'static + Clone + Send, { let client = self.client.build_hyper_client(); @@ -189,12 +189,12 @@ impl AuthenticatorImpl where GT: 'static + GetToken, S: 'static + TokenStorage, - AD: 'static + AuthenticatorDelegate + Send + Sync, + AD: 'static + AuthenticatorDelegate, C: 'static + hyper::client::connect::Connect + Clone + Send, { async fn get_token(&self, scope_key: u64, scopes: Vec) -> Result { let store = self.store.clone(); - let mut delegate = self.delegate.clone(); + let delegate = &self.delegate; let client = self.client.clone(); let appsecret = self.inner.application_secret(); let gettoken = self.inner.clone(); @@ -209,7 +209,6 @@ where } // Implement refresh flow. let refresh_token = t.refresh_token.clone(); - let mut delegate = delegate.clone(); let store = store.clone(); let scopes = scopes.clone(); let rr = RefreshFlow::refresh_token( @@ -254,7 +253,6 @@ where Ok(None) => { let store = store.clone(); let scopes = scopes.clone(); - let mut delegate = delegate.clone(); let t = gettoken.token(scopes.clone()).await?; if let Err(e) = store.set( scope_key, @@ -282,7 +280,7 @@ where impl< GT: 'static + GetToken, S: 'static + TokenStorage, - AD: 'static + AuthenticatorDelegate + Send + Sync, + AD: 'static + AuthenticatorDelegate, C: 'static + hyper::client::connect::Connect + Clone + Send, > GetToken for AuthenticatorImpl { diff --git a/src/authenticator_delegate.rs b/src/authenticator_delegate.rs index eb3bceb..0ac916b 100644 --- a/src/authenticator_delegate.rs +++ b/src/authenticator_delegate.rs @@ -71,11 +71,11 @@ impl Error for PollError { /// /// The only method that needs to be implemented manually is `present_user_code(...)`, /// as no assumptions are made on how this presentation should happen. -pub trait AuthenticatorDelegate: Clone { +pub trait AuthenticatorDelegate: Clone + Send + Sync { /// Called whenever there is an client, usually if there are network problems. /// /// Return retry information. - fn client_error(&mut self, _: &hyper::Error) -> Retry { + fn client_error(&self, _: &hyper::Error) -> Retry { Retry::Abort } @@ -84,19 +84,19 @@ pub trait AuthenticatorDelegate: Clone { /// This can be useful if the underlying `TokenStorage` may fail occasionally. /// if `is_set` is true, the failure resulted from `TokenStorage.set(...)`. Otherwise, /// it was `TokenStorage.get(...)` - fn token_storage_failure(&mut self, is_set: bool, _: &(dyn Error + Send + Sync)) -> Retry { + fn token_storage_failure(&self, is_set: bool, _: &(dyn Error + Send + Sync)) -> Retry { let _ = is_set; Retry::Abort } /// The server denied the attempt to obtain a request code - fn request_failure(&mut self, _: RequestError) {} + fn request_failure(&self, _: RequestError) {} /// Called if we could not acquire a refresh token for a reason possibly specified /// by the server. /// This call is made for the delegate's information only. fn token_refresh_failed>( - &mut self, + &self, error: S, error_description: &Option, ) { @@ -111,7 +111,7 @@ pub trait AuthenticatorDelegate: Clone { /// FlowDelegate methods are called when an OAuth flow needs to ask the application what to do in /// certain cases. -pub trait FlowDelegate: Clone { +pub trait FlowDelegate: Clone + Send + Sync { /// Called if the request code is expired. You will have to start over in this case. /// This will be the last call the delegate receives. /// Given `DateTime` is the expiration date diff --git a/src/device.rs b/src/device.rs index dc4cfdf..02f19c7 100644 --- a/src/device.rs +++ b/src/device.rs @@ -73,7 +73,7 @@ impl DeviceFlow { impl crate::authenticator::AuthFlow for DeviceFlow where - FD: FlowDelegate + Send + Sync + 'static, + FD: FlowDelegate + 'static, C: hyper::client::connect::Connect + 'static, { type TokenGetter = DeviceFlowImpl; @@ -105,10 +105,10 @@ impl Flow for DeviceFlowImpl { } } -impl< - FD: FlowDelegate + Clone + Send + Sync + 'static, - C: hyper::client::connect::Connect + Sync + 'static, - > GetToken for DeviceFlowImpl +impl GetToken for DeviceFlowImpl +where + FD: FlowDelegate + 'static, + C: hyper::client::connect::Connect + 'static, { fn token<'a, I, T>( &'a self, @@ -130,10 +130,10 @@ impl< impl DeviceFlowImpl where - C: hyper::client::connect::Connect + Sync + 'static, + C: hyper::client::connect::Connect + 'static, C::Transport: 'static, C::Future: 'static, - FD: FlowDelegate + Clone + Send + 'static, + FD: FlowDelegate + 'static, { /// Essentially what `GetToken::token` does: Retrieve a token for the given scopes without /// caching. diff --git a/src/installed.rs b/src/installed.rs index 1733e6f..ba6758e 100644 --- a/src/installed.rs +++ b/src/installed.rs @@ -61,10 +61,10 @@ where }) } -impl< - FD: FlowDelegate + 'static + Send + Sync + Clone, - C: hyper::client::connect::Connect + 'static, - > GetToken for InstalledFlowImpl +impl GetToken for InstalledFlowImpl +where + FD: FlowDelegate + 'static, + C: hyper::client::connect::Connect + 'static, { fn token<'a, I, T>( &'a self, @@ -85,7 +85,11 @@ impl< } /// The InstalledFlow implementation. -pub struct InstalledFlowImpl { +pub struct InstalledFlowImpl +where + FD: FlowDelegate + 'static, + C: hyper::client::connect::Connect + 'static, +{ method: InstalledFlowReturnMethod, client: hyper::client::Client, fd: FD, @@ -109,7 +113,7 @@ pub enum InstalledFlowReturnMethod { /// InstalledFlowImpl provides tokens for services that follow the "Installed" OAuth flow. (See /// https://www.oauth.com/oauth2-servers/authorization/, /// https://developers.google.com/identity/protocols/OAuth2InstalledApp). -pub struct InstalledFlow { +pub struct InstalledFlow { method: InstalledFlowReturnMethod, flow_delegate: FD, appsecret: ApplicationSecret, @@ -145,7 +149,7 @@ where impl crate::authenticator::AuthFlow for InstalledFlow where - FD: FlowDelegate + Send + Sync + 'static, + FD: FlowDelegate + 'static, C: hyper::client::connect::Connect + 'static, { type TokenGetter = InstalledFlowImpl; @@ -160,8 +164,10 @@ where } } -impl<'c, FD: 'static + FlowDelegate + Clone + Send, C: 'c + hyper::client::connect::Connect> - InstalledFlowImpl +impl InstalledFlowImpl +where + FD: FlowDelegate + 'static, + C: hyper::client::connect::Connect + 'static, { /// Handles the token request flow; it consists of the following steps: /// . Obtain a authorization code with user cooperation or internal redirect. diff --git a/src/service_account.rs b/src/service_account.rs index eb63200..c56a9cb 100644 --- a/src/service_account.rs +++ b/src/service_account.rs @@ -266,7 +266,10 @@ struct TokenResponse { expires_in: Option, } -impl<'a, C: 'static + hyper::client::connect::Connect> ServiceAccountAccessImpl { +impl ServiceAccountAccessImpl +where + C: hyper::client::connect::Connect + 'static, +{ /// Send a request for a new Bearer token to the OAuth provider. async fn request_token( client: hyper::client::Client, @@ -358,9 +361,9 @@ impl<'a, C: 'static + hyper::client::connect::Connect> ServiceAccountAccessImpl< } } -impl GetToken for ServiceAccountAccessImpl +impl GetToken for ServiceAccountAccessImpl where - C: hyper::client::connect::Connect, + C: hyper::client::connect::Connect + 'static, { fn token<'a, I, T>( &'a self, diff --git a/src/storage.rs b/src/storage.rs index 81049ba..a1224e7 100644 --- a/src/storage.rs +++ b/src/storage.rs @@ -6,7 +6,6 @@ use std::cmp::Ordering; use std::collections::hash_map::DefaultHasher; use std::error::Error; -use std::fmt; use std::fs; use std::hash::{Hash, Hasher}; use std::io; @@ -54,27 +53,12 @@ where #[derive(Default)] pub struct NullStorage; -#[derive(Debug)] -pub struct NullError; - -impl Error for NullError { - fn description(&self) -> &str { - "NULL" - } -} - -impl fmt::Display for NullError { - fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> { - "NULL-ERROR".fmt(f) - } -} - impl TokenStorage for NullStorage { - type Error = NullError; - fn set(&self, _: u64, _: &Vec<&str>, _: Option) -> Result<(), NullError> { + type Error = std::convert::Infallible; + fn set(&self, _: u64, _: &Vec<&str>, _: Option) -> Result<(), Self::Error> { Ok(()) } - fn get(&self, _: u64, _: &Vec<&str>) -> Result, NullError> { + fn get(&self, _: u64, _: &Vec<&str>) -> Result, Self::Error> { Ok(None) } } @@ -92,14 +76,14 @@ impl MemoryStorage { } impl TokenStorage for MemoryStorage { - type Error = NullError; + type Error = std::convert::Infallible; fn set( &self, scope_hash: u64, scopes: &Vec<&str>, token: Option, - ) -> Result<(), NullError> { + ) -> Result<(), Self::Error> { let mut tokens = self.tokens.lock().expect("poisoned mutex"); let matched = tokens.iter().find_position(|x| x.hash == scope_hash); if let Some((idx, _)) = matched { @@ -120,7 +104,7 @@ impl TokenStorage for MemoryStorage { Ok(()) } - fn get(&self, scope_hash: u64, scopes: &Vec<&str>) -> Result, NullError> { + fn get(&self, scope_hash: u64, scopes: &Vec<&str>) -> Result, Self::Error> { let scopes: Vec<_> = scopes.iter().sorted().unique().collect(); let tokens = self.tokens.lock().expect("poisoned mutex");