Loading aws/rust-runtime/aws-auth/Cargo.toml +1 −0 Original line number Diff line number Diff line Loading @@ -14,3 +14,4 @@ zeroize = "1.2.0" [dev-dependencies] http = "0.2.3" tokio = { version = "1.0", features = ["rt", "macros"] } async-trait = "0.1.50" aws/rust-runtime/aws-auth/src/middleware.rs +5 −2 Original line number Diff line number Diff line Loading @@ -72,13 +72,16 @@ impl AsyncMapRequest for CredentialsStage { fn apply(&self, mut request: Request) -> BoxFuture<Result<Request, Self::Error>> { Box::pin(async move { let cred_future = { let provider = { let config = request.config(); let credential_provider = config .get::<CredentialsProvider>() .ok_or(CredentialsStageError::MissingCredentialsProvider)?; credential_provider.provide_credentials() // we need to enable releasing the config lock so that we don't hold the config // lock across an await point credential_provider.clone() }; let cred_future = { provider.provide_credentials() }; let credentials = cred_future.await?; request.config_mut().insert(credentials); Ok(request) Loading aws/rust-runtime/aws-auth/src/provider.rs +38 −5 Original line number Diff line number Diff line Loading @@ -40,7 +40,7 @@ impl Error for CredentialsError { } pub type CredentialsResult = Result<Credentials, CredentialsError>; type BoxFuture<T> = Pin<Box<dyn Future<Output = T> + Send>>; type BoxFuture<'a, T> = Pin<Box<dyn Future<Output = T> + Send + 'a>>; /// An asynchronous credentials provider /// Loading @@ -48,7 +48,9 @@ type BoxFuture<T> = Pin<Box<dyn Future<Output = T> + Send>>; /// consider using [`async_provide_credentials_fn`] with a closure rather than directly implementing /// this trait. pub trait AsyncProvideCredentials: Send + Sync { fn provide_credentials(&self) -> BoxFuture<CredentialsResult>; fn provide_credentials<'a>(&'a self) -> BoxFuture<'a, CredentialsResult> where Self: 'a; } pub type CredentialsProvider = Arc<dyn AsyncProvideCredentials>; Loading @@ -66,7 +68,10 @@ where T: Fn() -> F + Send + Sync, F: Future<Output = CredentialsResult> + Send + 'static, { fn provide_credentials(&self) -> BoxFuture<CredentialsResult> { fn provide_credentials<'a>(&'a self) -> BoxFuture<'a, CredentialsResult> where Self: 'a, { Box::pin((self.f)()) } } Loading @@ -81,9 +86,13 @@ where /// use aws_auth::Credentials; /// use aws_auth::provider::async_provide_credentials_fn; /// /// async fn load_credentials() -> Credentials { /// todo!() /// } /// /// async_provide_credentials_fn(|| async { /// // Async process to retrieve credentials goes here /// let credentials: Credentials = todo!().await?; /// let credentials = load_credentials().await; /// Ok(credentials) /// }); /// ``` Loading @@ -107,7 +116,10 @@ impl<T> AsyncProvideCredentials for T where T: ProvideCredentials, { fn provide_credentials(&self) -> BoxFuture<CredentialsResult> { fn provide_credentials<'a>(&'a self) -> BoxFuture<'a, CredentialsResult> where Self: 'a, { let result = self.provide_credentials(); Box::pin(future::ready(result)) } Loading @@ -130,7 +142,9 @@ pub fn set_provider(config: &mut PropertyBag, provider: Arc<dyn AsyncProvideCred #[cfg(test)] mod test { use crate::provider::{AsyncProvideCredentials, BoxFuture, CredentialsResult}; use crate::Credentials; use async_trait::async_trait; fn assert_send_sync<T: Send + Sync>() {} Loading @@ -138,4 +152,23 @@ mod test { fn creds_are_send_sync() { assert_send_sync::<Credentials>() } #[async_trait] trait AnotherTrait: Send + Sync { async fn creds(&self) -> Credentials; } struct AnotherTraitWrapper<T> { inner: T, } impl<T: AnotherTrait> AsyncProvideCredentials for AnotherTraitWrapper<T> { fn provide_credentials<'a>(&'a self) -> BoxFuture<'a, CredentialsResult> where Self: 'a, { let inner_fut = self.inner.creds(); Box::pin(async move { Ok(inner_fut.await) }) } } } Loading
aws/rust-runtime/aws-auth/Cargo.toml +1 −0 Original line number Diff line number Diff line Loading @@ -14,3 +14,4 @@ zeroize = "1.2.0" [dev-dependencies] http = "0.2.3" tokio = { version = "1.0", features = ["rt", "macros"] } async-trait = "0.1.50"
aws/rust-runtime/aws-auth/src/middleware.rs +5 −2 Original line number Diff line number Diff line Loading @@ -72,13 +72,16 @@ impl AsyncMapRequest for CredentialsStage { fn apply(&self, mut request: Request) -> BoxFuture<Result<Request, Self::Error>> { Box::pin(async move { let cred_future = { let provider = { let config = request.config(); let credential_provider = config .get::<CredentialsProvider>() .ok_or(CredentialsStageError::MissingCredentialsProvider)?; credential_provider.provide_credentials() // we need to enable releasing the config lock so that we don't hold the config // lock across an await point credential_provider.clone() }; let cred_future = { provider.provide_credentials() }; let credentials = cred_future.await?; request.config_mut().insert(credentials); Ok(request) Loading
aws/rust-runtime/aws-auth/src/provider.rs +38 −5 Original line number Diff line number Diff line Loading @@ -40,7 +40,7 @@ impl Error for CredentialsError { } pub type CredentialsResult = Result<Credentials, CredentialsError>; type BoxFuture<T> = Pin<Box<dyn Future<Output = T> + Send>>; type BoxFuture<'a, T> = Pin<Box<dyn Future<Output = T> + Send + 'a>>; /// An asynchronous credentials provider /// Loading @@ -48,7 +48,9 @@ type BoxFuture<T> = Pin<Box<dyn Future<Output = T> + Send>>; /// consider using [`async_provide_credentials_fn`] with a closure rather than directly implementing /// this trait. pub trait AsyncProvideCredentials: Send + Sync { fn provide_credentials(&self) -> BoxFuture<CredentialsResult>; fn provide_credentials<'a>(&'a self) -> BoxFuture<'a, CredentialsResult> where Self: 'a; } pub type CredentialsProvider = Arc<dyn AsyncProvideCredentials>; Loading @@ -66,7 +68,10 @@ where T: Fn() -> F + Send + Sync, F: Future<Output = CredentialsResult> + Send + 'static, { fn provide_credentials(&self) -> BoxFuture<CredentialsResult> { fn provide_credentials<'a>(&'a self) -> BoxFuture<'a, CredentialsResult> where Self: 'a, { Box::pin((self.f)()) } } Loading @@ -81,9 +86,13 @@ where /// use aws_auth::Credentials; /// use aws_auth::provider::async_provide_credentials_fn; /// /// async fn load_credentials() -> Credentials { /// todo!() /// } /// /// async_provide_credentials_fn(|| async { /// // Async process to retrieve credentials goes here /// let credentials: Credentials = todo!().await?; /// let credentials = load_credentials().await; /// Ok(credentials) /// }); /// ``` Loading @@ -107,7 +116,10 @@ impl<T> AsyncProvideCredentials for T where T: ProvideCredentials, { fn provide_credentials(&self) -> BoxFuture<CredentialsResult> { fn provide_credentials<'a>(&'a self) -> BoxFuture<'a, CredentialsResult> where Self: 'a, { let result = self.provide_credentials(); Box::pin(future::ready(result)) } Loading @@ -130,7 +142,9 @@ pub fn set_provider(config: &mut PropertyBag, provider: Arc<dyn AsyncProvideCred #[cfg(test)] mod test { use crate::provider::{AsyncProvideCredentials, BoxFuture, CredentialsResult}; use crate::Credentials; use async_trait::async_trait; fn assert_send_sync<T: Send + Sync>() {} Loading @@ -138,4 +152,23 @@ mod test { fn creds_are_send_sync() { assert_send_sync::<Credentials>() } #[async_trait] trait AnotherTrait: Send + Sync { async fn creds(&self) -> Credentials; } struct AnotherTraitWrapper<T> { inner: T, } impl<T: AnotherTrait> AsyncProvideCredentials for AnotherTraitWrapper<T> { fn provide_credentials<'a>(&'a self) -> BoxFuture<'a, CredentialsResult> where Self: 'a, { let inner_fut = self.inner.creds(); Box::pin(async move { Ok(inner_fut.await) }) } } }