Loading aws/rust-runtime/aws-auth/Cargo.toml +1 −0 Original line number Diff line number Diff line Loading @@ -9,3 +9,4 @@ edition = "2018" [dependencies] smithy-http = { path = "../../../rust-runtime/smithy-http" } zeroize = "1.2.0" aws/rust-runtime/aws-auth/src/lib.rs +51 −16 Original line number Diff line number Diff line Loading @@ -11,18 +11,22 @@ use std::fmt; use std::fmt::{Debug, Display, Formatter}; use std::sync::Arc; use std::time::SystemTime; use zeroize::Zeroizing; /// AWS SDK Credentials /// /// An opaque struct representing credentials that may be used in an AWS SDK, modeled on /// the [CRT credentials implementation](https://github.com/awslabs/aws-c-auth/blob/main/source/credentials.c). /// /// Future design note: It may be desirable to make Credentials cheap to clone because they are cloned frequently. /// When `Credentials` is dropped, its contents are zeroed in memory. Credentials uses an interior Arc to ensure /// that even when cloned, credentials don't exist in multiple memory locations. #[derive(Clone)] pub struct Credentials { access_key_id: String, secret_access_key: String, session_token: Option<String>, pub struct Credentials(Arc<Inner>); struct Inner { access_key_id: Zeroizing<String>, secret_access_key: Zeroizing<String>, session_token: Zeroizing<Option<String>>, /// Credential Expiry /// Loading @@ -39,38 +43,57 @@ pub struct Credentials { impl Debug for Credentials { fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { let mut creds = f.debug_struct("Credentials"); creds.field("provider_name", &self.provider_name); creds.field("provider_name", &self.0.provider_name); creds.finish() } } const STATIC_CREDENTIALS: &str = "Static"; impl Credentials { pub fn new( access_key_id: impl Into<String>, secret_access_key: impl Into<String>, session_token: Option<String>, expires_after: Option<SystemTime>, provider_name: &'static str, ) -> Self { Credentials(Arc::new(Inner { access_key_id: Zeroizing::new(access_key_id.into()), secret_access_key: Zeroizing::new(secret_access_key.into()), session_token: Zeroizing::new(session_token), expires_after, provider_name, })) } pub fn from_keys( access_key_id: impl Into<String>, secret_access_key: impl Into<String>, session_token: Option<String>, ) -> Self { Credentials { access_key_id: access_key_id.into(), secret_access_key: secret_access_key.into(), Self::new( access_key_id, secret_access_key, session_token, expires_after: None, provider_name: STATIC_CREDENTIALS, } None, STATIC_CREDENTIALS, ) } pub fn access_key_id(&self) -> &str { &self.access_key_id &self.0.access_key_id } pub fn secret_access_key(&self) -> &str { &self.secret_access_key &self.0.secret_access_key } pub fn expiry(&self) -> Option<SystemTime> { self.0.expires_after } pub fn session_token(&self) -> Option<&str> { self.session_token.as_deref() self.0.session_token.as_deref() } } Loading Loading @@ -125,3 +148,15 @@ impl ProvideCredentials for Credentials { pub fn set_provider(config: &mut PropertyBag, provider: Arc<dyn ProvideCredentials>) { config.insert(provider); } #[cfg(test)] mod test { use crate::Credentials; fn assert_send_sync<T: Send + Sync>() {} #[test] fn creds_are_send_sync() { assert_send_sync::<Credentials>() } } aws/rust-runtime/aws-auth/src/provider.rs +15 −15 Original line number Diff line number Diff line Loading @@ -48,13 +48,13 @@ impl ProvideCredentials for EnvironmentVariableCredentialsProvider { .or_else(|_| (self.env)("SECRET_ACCESS_KEY")) .map_err(to_cred_error)?; let session_token = (self.env)("AWS_SESSION_TOKEN").ok(); Ok(Credentials { access_key_id: access_key, secret_access_key: secret_key, Ok(Credentials::new( access_key, secret_key, session_token, expires_after: None, provider_name: ENV_PROVIDER, }) None, ENV_PROVIDER, )) } } Loading @@ -79,9 +79,9 @@ mod test { let provider = EnvironmentVariableCredentialsProvider::for_map(env); let creds = provider.provide_credentials().expect("valid credentials"); assert_eq!(creds.session_token, None); assert_eq!(creds.access_key_id, "access"); assert_eq!(creds.secret_access_key, "secret"); assert_eq!(creds.session_token(), None); assert_eq!(creds.access_key_id(), "access"); assert_eq!(creds.secret_access_key(), "secret"); } #[test] Loading @@ -93,9 +93,9 @@ mod test { let provider = EnvironmentVariableCredentialsProvider::for_map(env); let creds = provider.provide_credentials().expect("valid credentials"); assert_eq!(creds.session_token.unwrap(), "token"); assert_eq!(creds.access_key_id, "access"); assert_eq!(creds.secret_access_key, "secret"); assert_eq!(creds.session_token().unwrap(), "token"); assert_eq!(creds.access_key_id(), "access"); assert_eq!(creds.secret_access_key(), "secret"); } #[test] Loading @@ -107,9 +107,9 @@ mod test { let provider = EnvironmentVariableCredentialsProvider::for_map(env); let creds = provider.provide_credentials().expect("valid credentials"); assert_eq!(creds.session_token.unwrap(), "token"); assert_eq!(creds.access_key_id, "access"); assert_eq!(creds.secret_access_key, "secret"); assert_eq!(creds.session_token().unwrap(), "token"); assert_eq!(creds.access_key_id(), "access"); assert_eq!(creds.secret_access_key(), "secret"); } #[test] Loading Loading
aws/rust-runtime/aws-auth/Cargo.toml +1 −0 Original line number Diff line number Diff line Loading @@ -9,3 +9,4 @@ edition = "2018" [dependencies] smithy-http = { path = "../../../rust-runtime/smithy-http" } zeroize = "1.2.0"
aws/rust-runtime/aws-auth/src/lib.rs +51 −16 Original line number Diff line number Diff line Loading @@ -11,18 +11,22 @@ use std::fmt; use std::fmt::{Debug, Display, Formatter}; use std::sync::Arc; use std::time::SystemTime; use zeroize::Zeroizing; /// AWS SDK Credentials /// /// An opaque struct representing credentials that may be used in an AWS SDK, modeled on /// the [CRT credentials implementation](https://github.com/awslabs/aws-c-auth/blob/main/source/credentials.c). /// /// Future design note: It may be desirable to make Credentials cheap to clone because they are cloned frequently. /// When `Credentials` is dropped, its contents are zeroed in memory. Credentials uses an interior Arc to ensure /// that even when cloned, credentials don't exist in multiple memory locations. #[derive(Clone)] pub struct Credentials { access_key_id: String, secret_access_key: String, session_token: Option<String>, pub struct Credentials(Arc<Inner>); struct Inner { access_key_id: Zeroizing<String>, secret_access_key: Zeroizing<String>, session_token: Zeroizing<Option<String>>, /// Credential Expiry /// Loading @@ -39,38 +43,57 @@ pub struct Credentials { impl Debug for Credentials { fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { let mut creds = f.debug_struct("Credentials"); creds.field("provider_name", &self.provider_name); creds.field("provider_name", &self.0.provider_name); creds.finish() } } const STATIC_CREDENTIALS: &str = "Static"; impl Credentials { pub fn new( access_key_id: impl Into<String>, secret_access_key: impl Into<String>, session_token: Option<String>, expires_after: Option<SystemTime>, provider_name: &'static str, ) -> Self { Credentials(Arc::new(Inner { access_key_id: Zeroizing::new(access_key_id.into()), secret_access_key: Zeroizing::new(secret_access_key.into()), session_token: Zeroizing::new(session_token), expires_after, provider_name, })) } pub fn from_keys( access_key_id: impl Into<String>, secret_access_key: impl Into<String>, session_token: Option<String>, ) -> Self { Credentials { access_key_id: access_key_id.into(), secret_access_key: secret_access_key.into(), Self::new( access_key_id, secret_access_key, session_token, expires_after: None, provider_name: STATIC_CREDENTIALS, } None, STATIC_CREDENTIALS, ) } pub fn access_key_id(&self) -> &str { &self.access_key_id &self.0.access_key_id } pub fn secret_access_key(&self) -> &str { &self.secret_access_key &self.0.secret_access_key } pub fn expiry(&self) -> Option<SystemTime> { self.0.expires_after } pub fn session_token(&self) -> Option<&str> { self.session_token.as_deref() self.0.session_token.as_deref() } } Loading Loading @@ -125,3 +148,15 @@ impl ProvideCredentials for Credentials { pub fn set_provider(config: &mut PropertyBag, provider: Arc<dyn ProvideCredentials>) { config.insert(provider); } #[cfg(test)] mod test { use crate::Credentials; fn assert_send_sync<T: Send + Sync>() {} #[test] fn creds_are_send_sync() { assert_send_sync::<Credentials>() } }
aws/rust-runtime/aws-auth/src/provider.rs +15 −15 Original line number Diff line number Diff line Loading @@ -48,13 +48,13 @@ impl ProvideCredentials for EnvironmentVariableCredentialsProvider { .or_else(|_| (self.env)("SECRET_ACCESS_KEY")) .map_err(to_cred_error)?; let session_token = (self.env)("AWS_SESSION_TOKEN").ok(); Ok(Credentials { access_key_id: access_key, secret_access_key: secret_key, Ok(Credentials::new( access_key, secret_key, session_token, expires_after: None, provider_name: ENV_PROVIDER, }) None, ENV_PROVIDER, )) } } Loading @@ -79,9 +79,9 @@ mod test { let provider = EnvironmentVariableCredentialsProvider::for_map(env); let creds = provider.provide_credentials().expect("valid credentials"); assert_eq!(creds.session_token, None); assert_eq!(creds.access_key_id, "access"); assert_eq!(creds.secret_access_key, "secret"); assert_eq!(creds.session_token(), None); assert_eq!(creds.access_key_id(), "access"); assert_eq!(creds.secret_access_key(), "secret"); } #[test] Loading @@ -93,9 +93,9 @@ mod test { let provider = EnvironmentVariableCredentialsProvider::for_map(env); let creds = provider.provide_credentials().expect("valid credentials"); assert_eq!(creds.session_token.unwrap(), "token"); assert_eq!(creds.access_key_id, "access"); assert_eq!(creds.secret_access_key, "secret"); assert_eq!(creds.session_token().unwrap(), "token"); assert_eq!(creds.access_key_id(), "access"); assert_eq!(creds.secret_access_key(), "secret"); } #[test] Loading @@ -107,9 +107,9 @@ mod test { let provider = EnvironmentVariableCredentialsProvider::for_map(env); let creds = provider.provide_credentials().expect("valid credentials"); assert_eq!(creds.session_token.unwrap(), "token"); assert_eq!(creds.access_key_id, "access"); assert_eq!(creds.secret_access_key, "secret"); assert_eq!(creds.session_token().unwrap(), "token"); assert_eq!(creds.access_key_id(), "access"); assert_eq!(creds.secret_access_key(), "secret"); } #[test] Loading