mirror of https://github.com/smithy-lang/smithy-rs
fix use_fips in provider config (#3007)
I'm not 100% that I fixed this in the right way. Feel free to set me straight if that's the case. ## Motivation and Context <!--- Why is this change required? What problem does it solve? --> <!--- If it fixes an open issue, please link to the issue here --> aws-sdk-rust#882 ## Description <!--- Describe your changes in detail --> This change causes the`ProviderConfig` to respect both `use_fips` and `use_dual_stack` when those settings are configured in a user's environment or profile. ## Testing <!--- Please describe in detail how you tested your changes --> <!--- Include details of your testing environment, and the tests you ran to --> <!--- see how your change affects other areas of the code, etc. --> I wrote two tests ## Checklist <!--- If a checkbox below is not applicable, then please DELETE it rather than leaving it unchecked --> - [x] I have updated `CHANGELOG.next.toml` if I made changes to the smithy-rs codegen or runtime crates - [x] I have updated `CHANGELOG.next.toml` if I made changes to the AWS SDK, generated SDK code, or SDK runtime crates ---- _By submitting this pull request, I confirm that you can use, modify, copy, and redistribute this contribution, under the terms of your choice._ --------- Co-authored-by: John DiSanti <jdisanti@amazon.com>
This commit is contained in:
parent
5129c1f5f0
commit
bb35688696
|
@ -261,3 +261,9 @@ For more information, see the [Change Log Discussion](https://github.com/awslabs
|
|||
meta = { "breaking" = true, "tada" = false, "bug" = false }
|
||||
references = ["smithy-rs#3014"]
|
||||
author = "rcoh"
|
||||
|
||||
[[aws-sdk-rust]]
|
||||
message = "STS and SSO-based credential providers will now respect both `use_fips` and `use_dual_stack` when those settings are configured in a user's environment or profile."
|
||||
references = ["aws-sdk-rust#882", "smithy-rs#3007"]
|
||||
meta = { "breaking" = true, "tada" = true, "bug" = true }
|
||||
author = "Velfi"
|
||||
|
|
|
@ -306,6 +306,9 @@ mod test {
|
|||
#[cfg(feature = "credentials-sso")]
|
||||
make_test!(sso_no_token_file);
|
||||
|
||||
#[cfg(feature = "credentials-sso")]
|
||||
make_test!(e2e_fips_and_dual_stack_sso);
|
||||
|
||||
#[tokio::test]
|
||||
async fn profile_name_override() {
|
||||
let conf =
|
||||
|
|
|
@ -245,6 +245,6 @@ mod test {
|
|||
fn real_environment() {
|
||||
let provider = EnvironmentVariableCredentialsProvider::new();
|
||||
// we don't know what's in the env, just make sure it doesn't crash.
|
||||
let _ = provider.provide_credentials();
|
||||
let _fut = provider.provide_credentials();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -589,6 +589,23 @@ mod loader {
|
|||
.with_http_connector(http_connector.clone())
|
||||
})
|
||||
.with_profile_config(self.profile_files_override, self.profile_name_override);
|
||||
|
||||
let use_fips = if let Some(use_fips) = self.use_fips {
|
||||
Some(use_fips)
|
||||
} else {
|
||||
use_fips_provider(&conf).await
|
||||
};
|
||||
|
||||
let use_dual_stack = if let Some(use_dual_stack) = self.use_dual_stack {
|
||||
Some(use_dual_stack)
|
||||
} else {
|
||||
use_dual_stack_provider(&conf).await
|
||||
};
|
||||
|
||||
let conf = conf
|
||||
.with_use_fips(use_fips)
|
||||
.with_use_dual_stack(use_dual_stack);
|
||||
|
||||
let region = if let Some(provider) = self.region {
|
||||
provider.region().await
|
||||
} else {
|
||||
|
@ -648,18 +665,6 @@ mod loader {
|
|||
None
|
||||
};
|
||||
|
||||
let use_fips = if let Some(use_fips) = self.use_fips {
|
||||
Some(use_fips)
|
||||
} else {
|
||||
use_fips_provider(&conf).await
|
||||
};
|
||||
|
||||
let use_dual_stack = if let Some(use_dual_stack) = self.use_dual_stack {
|
||||
Some(use_dual_stack)
|
||||
} else {
|
||||
use_dual_stack_provider(&conf).await
|
||||
};
|
||||
|
||||
let mut builder = SdkConfig::builder()
|
||||
.region(region)
|
||||
.retry_config(retry_config)
|
||||
|
|
|
@ -22,15 +22,13 @@
|
|||
//! - `exec` which contains a chain representation of providers to implement passing bootstrapped credentials
|
||||
//! through a series of providers.
|
||||
|
||||
use crate::profile::credentials::exec::named::NamedProviderFactory;
|
||||
use crate::profile::credentials::exec::ProviderChain;
|
||||
use crate::profile::parser::ProfileFileLoadError;
|
||||
use crate::profile::profile_file::ProfileFiles;
|
||||
use crate::profile::Profile;
|
||||
use crate::provider_config::ProviderConfig;
|
||||
use aws_credential_types::provider::{self, error::CredentialsError, future, ProvideCredentials};
|
||||
use aws_sdk_sts::config::Builder as StsConfigBuilder;
|
||||
use aws_smithy_types::error::display::DisplayErrorContext;
|
||||
use aws_types::SdkConfig;
|
||||
use std::borrow::Cow;
|
||||
use std::collections::HashMap;
|
||||
use std::error::Error;
|
||||
|
@ -141,8 +139,8 @@ impl ProvideCredentials for ProfileFileCredentialsProvider {
|
|||
#[doc = include_str!("location_of_profile_files.md")]
|
||||
#[derive(Debug)]
|
||||
pub struct ProfileFileCredentialsProvider {
|
||||
factory: NamedProviderFactory,
|
||||
sts_config: StsConfigBuilder,
|
||||
factory: exec::named::NamedProviderFactory,
|
||||
sdk_config: SdkConfig,
|
||||
provider_config: ProviderConfig,
|
||||
}
|
||||
|
||||
|
@ -182,7 +180,7 @@ impl ProfileFileCredentialsProvider {
|
|||
};
|
||||
for provider in inner_provider.chain().iter() {
|
||||
let next_creds = provider
|
||||
.credentials(creds, &self.sts_config)
|
||||
.credentials(creds, &self.sdk_config)
|
||||
.instrument(tracing::debug_span!("load_assume_role", provider = ?provider))
|
||||
.await;
|
||||
match next_creds {
|
||||
|
@ -444,7 +442,7 @@ impl Builder {
|
|||
|
||||
ProfileFileCredentialsProvider {
|
||||
factory,
|
||||
sts_config: conf.sts_client_config(),
|
||||
sdk_config: conf.client_config("profile file"),
|
||||
provider_config: conf,
|
||||
}
|
||||
}
|
||||
|
@ -452,8 +450,8 @@ impl Builder {
|
|||
|
||||
async fn build_provider_chain(
|
||||
provider_config: &ProviderConfig,
|
||||
factory: &NamedProviderFactory,
|
||||
) -> Result<ProviderChain, ProfileFileError> {
|
||||
factory: &exec::named::NamedProviderFactory,
|
||||
) -> Result<exec::ProviderChain, ProfileFileError> {
|
||||
let profile_set = provider_config
|
||||
.try_profile()
|
||||
.await
|
||||
|
@ -485,6 +483,7 @@ mod test {
|
|||
}
|
||||
|
||||
make_test!(e2e_assume_role);
|
||||
make_test!(e2e_fips_and_dual_stack_sts);
|
||||
make_test!(empty_config);
|
||||
make_test!(retry_on_error);
|
||||
make_test!(invalid_config);
|
||||
|
|
|
@ -11,10 +11,13 @@ use crate::provider_config::ProviderConfig;
|
|||
use crate::sso::{SsoCredentialsProvider, SsoProviderConfig};
|
||||
use crate::sts;
|
||||
use crate::web_identity_token::{StaticConfiguration, WebIdentityTokenCredentialsProvider};
|
||||
use aws_credential_types::provider::{self, error::CredentialsError, ProvideCredentials};
|
||||
use aws_sdk_sts::config::{Builder as StsConfigBuilder, Credentials};
|
||||
use aws_credential_types::provider::{
|
||||
self, error::CredentialsError, ProvideCredentials, SharedCredentialsProvider,
|
||||
};
|
||||
use aws_sdk_sts::config::Credentials;
|
||||
use aws_sdk_sts::Client as StsClient;
|
||||
use aws_smithy_async::time::SharedTimeSource;
|
||||
use aws_types::SdkConfig;
|
||||
use std::fmt::Debug;
|
||||
use std::sync::Arc;
|
||||
|
||||
|
@ -30,13 +33,13 @@ impl AssumeRoleProvider {
|
|||
pub(super) async fn credentials(
|
||||
&self,
|
||||
input_credentials: Credentials,
|
||||
sts_config: &StsConfigBuilder,
|
||||
sdk_config: &SdkConfig,
|
||||
) -> provider::Result {
|
||||
let config = sts_config
|
||||
.clone()
|
||||
.credentials_provider(input_credentials)
|
||||
let config = sdk_config
|
||||
.to_builder()
|
||||
.credentials_provider(SharedCredentialsProvider::new(input_credentials))
|
||||
.build();
|
||||
let client = StsClient::from_conf(config);
|
||||
let client = StsClient::new(&config);
|
||||
let session_name = &self.session_name.as_ref().cloned().unwrap_or_else(|| {
|
||||
sts::util::default_session_name("assume-role-from-profile", self.time_source.now())
|
||||
});
|
||||
|
@ -143,8 +146,8 @@ impl ProviderChain {
|
|||
tracing::info!(role_arn = ?role_arn, "which will be used to assume a role");
|
||||
AssumeRoleProvider {
|
||||
role_arn: role_arn.role_arn.into(),
|
||||
external_id: role_arn.external_id.map(|id| id.into()),
|
||||
session_name: role_arn.session_name.map(|id| id.into()),
|
||||
external_id: role_arn.external_id.map(Into::into),
|
||||
session_name: role_arn.session_name.map(Into::into),
|
||||
time_source: provider_config.time_source(),
|
||||
}
|
||||
})
|
||||
|
|
|
@ -5,27 +5,26 @@
|
|||
|
||||
//! Configuration Options for Credential Providers
|
||||
|
||||
use crate::connector::{default_connector, expect_connector};
|
||||
use crate::profile;
|
||||
use crate::profile::profile_file::ProfileFiles;
|
||||
use crate::profile::{ProfileFileLoadError, ProfileSet};
|
||||
use aws_smithy_async::rt::sleep::{default_async_sleep, AsyncSleep, SharedAsyncSleep};
|
||||
use aws_smithy_async::time::SharedTimeSource;
|
||||
use aws_smithy_client::erase::DynConnector;
|
||||
use aws_smithy_types::error::display::DisplayErrorContext;
|
||||
use aws_smithy_types::retry::RetryConfig;
|
||||
use aws_types::os_shim_internal::{Env, Fs};
|
||||
use aws_types::{
|
||||
http_connector::{ConnectorSettings, HttpConnector},
|
||||
region::Region,
|
||||
SdkConfig,
|
||||
};
|
||||
use std::borrow::Cow;
|
||||
|
||||
use std::fmt::{Debug, Formatter};
|
||||
use std::sync::Arc;
|
||||
use tokio::sync::OnceCell;
|
||||
|
||||
use crate::connector::default_connector;
|
||||
use crate::profile;
|
||||
|
||||
use crate::profile::profile_file::ProfileFiles;
|
||||
use crate::profile::{ProfileFileLoadError, ProfileSet};
|
||||
|
||||
/// Configuration options for Credential Providers
|
||||
///
|
||||
/// Most credential providers builders offer a `configure` method which applies general provider configuration
|
||||
|
@ -42,6 +41,8 @@ pub struct ProviderConfig {
|
|||
connector: HttpConnector,
|
||||
sleep: Option<SharedAsyncSleep>,
|
||||
region: Option<Region>,
|
||||
use_fips: Option<bool>,
|
||||
use_dual_stack: Option<bool>,
|
||||
/// An AWS profile created from `ProfileFiles` and a `profile_name`
|
||||
parsed_profile: Arc<OnceCell<Result<ProfileSet, ProfileFileLoadError>>>,
|
||||
/// A list of [std::path::Path]s to profile files
|
||||
|
@ -57,6 +58,8 @@ impl Debug for ProviderConfig {
|
|||
.field("fs", &self.fs)
|
||||
.field("sleep", &self.sleep)
|
||||
.field("region", &self.region)
|
||||
.field("use_fips", &self.use_fips)
|
||||
.field("use_dual_stack", &self.use_dual_stack)
|
||||
.finish()
|
||||
}
|
||||
}
|
||||
|
@ -76,6 +79,8 @@ impl Default for ProviderConfig {
|
|||
connector,
|
||||
sleep: default_async_sleep(),
|
||||
region: None,
|
||||
use_fips: None,
|
||||
use_dual_stack: None,
|
||||
parsed_profile: Default::default(),
|
||||
profile_files: ProfileFiles::default(),
|
||||
profile_name_override: None,
|
||||
|
@ -104,6 +109,8 @@ impl ProviderConfig {
|
|||
connector: HttpConnector::Prebuilt(None),
|
||||
sleep: None,
|
||||
region: None,
|
||||
use_fips: None,
|
||||
use_dual_stack: None,
|
||||
profile_name_override: None,
|
||||
}
|
||||
}
|
||||
|
@ -144,6 +151,8 @@ impl ProviderConfig {
|
|||
connector: HttpConnector::Prebuilt(None),
|
||||
sleep: None,
|
||||
region: None,
|
||||
use_fips: None,
|
||||
use_dual_stack: None,
|
||||
parsed_profile: Default::default(),
|
||||
profile_files: ProfileFiles::default(),
|
||||
profile_name_override: None,
|
||||
|
@ -161,6 +170,8 @@ impl ProviderConfig {
|
|||
connector: HttpConnector::Prebuilt(None),
|
||||
sleep,
|
||||
region: None,
|
||||
use_fips: None,
|
||||
use_dual_stack: None,
|
||||
profile_name_override: None,
|
||||
}
|
||||
}
|
||||
|
@ -181,6 +192,21 @@ impl ProviderConfig {
|
|||
Self::without_region().load_default_region().await
|
||||
}
|
||||
|
||||
pub(crate) fn client_config(&self, feature_name: &str) -> SdkConfig {
|
||||
let mut builder = SdkConfig::builder()
|
||||
.http_connector(expect_connector(
|
||||
&format!("The {feature_name} features of aws-config"),
|
||||
self.connector(&Default::default()),
|
||||
))
|
||||
.retry_config(RetryConfig::standard())
|
||||
.region(self.region())
|
||||
.time_source(self.time_source())
|
||||
.use_fips(self.use_fips().unwrap_or_default())
|
||||
.use_dual_stack(self.use_dual_stack().unwrap_or_default());
|
||||
builder.set_sleep_impl(self.sleep());
|
||||
builder.build()
|
||||
}
|
||||
|
||||
// When all crate features are disabled, these accessors are unused
|
||||
|
||||
#[allow(dead_code)]
|
||||
|
@ -219,6 +245,16 @@ impl ProviderConfig {
|
|||
self.region.clone()
|
||||
}
|
||||
|
||||
#[allow(dead_code)]
|
||||
pub(crate) fn use_fips(&self) -> Option<bool> {
|
||||
self.use_fips
|
||||
}
|
||||
|
||||
#[allow(dead_code)]
|
||||
pub(crate) fn use_dual_stack(&self) -> Option<bool> {
|
||||
self.use_dual_stack
|
||||
}
|
||||
|
||||
pub(crate) async fn try_profile(&self) -> Result<&ProfileSet, &ProfileFileLoadError> {
|
||||
let parsed_profile = self
|
||||
.parsed_profile
|
||||
|
@ -249,6 +285,18 @@ impl ProviderConfig {
|
|||
self
|
||||
}
|
||||
|
||||
/// Override the `use_fips` setting.
|
||||
pub(crate) fn with_use_fips(mut self, use_fips: Option<bool>) -> Self {
|
||||
self.use_fips = use_fips;
|
||||
self
|
||||
}
|
||||
|
||||
/// Override the `use_dual_stack` setting.
|
||||
pub(crate) fn with_use_dual_stack(mut self, use_dual_stack: Option<bool>) -> Self {
|
||||
self.use_dual_stack = use_dual_stack;
|
||||
self
|
||||
}
|
||||
|
||||
pub(crate) fn with_profile_name(self, profile_name: String) -> Self {
|
||||
let profile_files = self.profile_files.clone();
|
||||
self.with_profile_config(Some(profile_files), Some(profile_name))
|
||||
|
|
|
@ -18,12 +18,13 @@ use aws_credential_types::cache::CredentialsCache;
|
|||
use aws_credential_types::provider::{self, error::CredentialsError, future, ProvideCredentials};
|
||||
use aws_credential_types::Credentials;
|
||||
use aws_sdk_sso::types::RoleCredentials;
|
||||
use aws_sdk_sso::{config::Builder as SsoConfigBuilder, Client as SsoClient, Config as SsoConfig};
|
||||
use aws_sdk_sso::Client as SsoClient;
|
||||
use aws_smithy_json::deserialize::Token;
|
||||
use aws_smithy_types::date_time::Format;
|
||||
use aws_smithy_types::DateTime;
|
||||
use aws_types::os_shim_internal::{Env, Fs};
|
||||
use aws_types::region::Region;
|
||||
use aws_types::SdkConfig;
|
||||
|
||||
use std::convert::TryInto;
|
||||
use std::error::Error;
|
||||
|
@ -31,8 +32,6 @@ use std::fmt::{Display, Formatter};
|
|||
use std::io;
|
||||
use std::path::PathBuf;
|
||||
|
||||
use crate::connector::expect_connector;
|
||||
use aws_smithy_types::retry::RetryConfig;
|
||||
use ring::digest;
|
||||
use zeroize::Zeroizing;
|
||||
|
||||
|
@ -47,7 +46,7 @@ pub struct SsoCredentialsProvider {
|
|||
fs: Fs,
|
||||
env: Env,
|
||||
sso_provider_config: SsoProviderConfig,
|
||||
sso_config: SsoConfigBuilder,
|
||||
sdk_config: SdkConfig,
|
||||
}
|
||||
|
||||
impl SsoCredentialsProvider {
|
||||
|
@ -63,26 +62,18 @@ impl SsoCredentialsProvider {
|
|||
let fs = provider_config.fs();
|
||||
let env = provider_config.env();
|
||||
|
||||
let mut sso_config = SsoConfig::builder()
|
||||
.http_connector(expect_connector(
|
||||
"The SSO credentials provider",
|
||||
provider_config.connector(&Default::default()),
|
||||
))
|
||||
.retry_config(RetryConfig::standard());
|
||||
sso_config.set_sleep_impl(provider_config.sleep());
|
||||
|
||||
SsoCredentialsProvider {
|
||||
fs,
|
||||
env,
|
||||
sso_provider_config,
|
||||
sso_config,
|
||||
sdk_config: provider_config.client_config("SSO"),
|
||||
}
|
||||
}
|
||||
|
||||
async fn credentials(&self) -> provider::Result {
|
||||
load_sso_credentials(
|
||||
&self.sso_provider_config,
|
||||
&self.sso_config,
|
||||
&self.sdk_config,
|
||||
&self.env,
|
||||
&self.fs,
|
||||
)
|
||||
|
@ -206,20 +197,20 @@ pub(crate) struct SsoProviderConfig {
|
|||
|
||||
async fn load_sso_credentials(
|
||||
sso_provider_config: &SsoProviderConfig,
|
||||
sso_config: &SsoConfigBuilder,
|
||||
sdk_config: &SdkConfig,
|
||||
env: &Env,
|
||||
fs: &Fs,
|
||||
) -> provider::Result {
|
||||
let token = load_token(&sso_provider_config.start_url, env, fs)
|
||||
.await
|
||||
.map_err(CredentialsError::provider_error)?;
|
||||
let config = sso_config
|
||||
.clone()
|
||||
let config = sdk_config
|
||||
.to_builder()
|
||||
.region(sso_provider_config.region.clone())
|
||||
.credentials_cache(CredentialsCache::no_caching())
|
||||
.build();
|
||||
// TODO(enableNewSmithyRuntimeCleanup): Use `customize().config_override()` to set the region instead of creating a new client once middleware is removed
|
||||
let client = SsoClient::from_conf(config);
|
||||
let client = SsoClient::new(&config);
|
||||
let resp = client
|
||||
.get_role_credentials()
|
||||
.role_name(&sso_provider_config.role_name)
|
||||
|
|
|
@ -10,22 +10,3 @@ pub(crate) mod util;
|
|||
pub use assume_role::{AssumeRoleProvider, AssumeRoleProviderBuilder};
|
||||
|
||||
mod assume_role;
|
||||
|
||||
use crate::connector::expect_connector;
|
||||
use aws_sdk_sts::config::Builder as StsConfigBuilder;
|
||||
use aws_smithy_types::retry::RetryConfig;
|
||||
|
||||
impl crate::provider_config::ProviderConfig {
|
||||
pub(crate) fn sts_client_config(&self) -> StsConfigBuilder {
|
||||
let mut builder = aws_sdk_sts::Config::builder()
|
||||
.http_connector(expect_connector(
|
||||
"The STS features of aws-config",
|
||||
self.connector(&Default::default()),
|
||||
))
|
||||
.retry_config(RetryConfig::standard())
|
||||
.region(self.region())
|
||||
.time_source(self.time_source());
|
||||
builder.set_sleep_impl(self.sleep());
|
||||
builder
|
||||
}
|
||||
}
|
||||
|
|
|
@ -362,7 +362,7 @@ mod test {
|
|||
#[tokio::test]
|
||||
async fn configures_session_length() {
|
||||
let (server, request) = capture_request(None);
|
||||
let provider_conf = SdkConfig::builder()
|
||||
let sdk_config = SdkConfig::builder()
|
||||
.sleep_impl(SharedAsyncSleep::new(TokioSleep::new()))
|
||||
.time_source(StaticTimeSource::new(
|
||||
UNIX_EPOCH + Duration::from_secs(1234567890 - 120),
|
||||
|
@ -371,7 +371,7 @@ mod test {
|
|||
.region(Region::from_static("this-will-be-overridden"))
|
||||
.build();
|
||||
let provider = AssumeRoleProvider::builder("myrole")
|
||||
.configure(&provider_conf)
|
||||
.configure(&sdk_config)
|
||||
.region(Region::new("us-east-1"))
|
||||
.session_length(Duration::from_secs(1234567))
|
||||
.build_from_provider(provide_credentials_fn(|| async {
|
||||
|
@ -388,7 +388,7 @@ mod test {
|
|||
#[tokio::test]
|
||||
async fn loads_region_from_sdk_config() {
|
||||
let (server, request) = capture_request(None);
|
||||
let provider_conf = SdkConfig::builder()
|
||||
let sdk_config = SdkConfig::builder()
|
||||
.sleep_impl(SharedAsyncSleep::new(TokioSleep::new()))
|
||||
.time_source(StaticTimeSource::new(
|
||||
UNIX_EPOCH + Duration::from_secs(1234567890 - 120),
|
||||
|
@ -397,14 +397,12 @@ mod test {
|
|||
.credentials_provider(SharedCredentialsProvider::new(provide_credentials_fn(
|
||||
|| async {
|
||||
panic!("don't call me — will be overridden");
|
||||
#[allow(unreachable_code)]
|
||||
Ok(Credentials::for_tests())
|
||||
},
|
||||
)))
|
||||
.region(Region::from_static("us-west-2"))
|
||||
.build();
|
||||
let provider = AssumeRoleProvider::builder("myrole")
|
||||
.configure(&provider_conf)
|
||||
.configure(&sdk_config)
|
||||
.session_length(Duration::from_secs(1234567))
|
||||
.build_from_provider(provide_credentials_fn(|| async {
|
||||
Ok(Credentials::for_tests())
|
||||
|
@ -476,7 +474,7 @@ mod test {
|
|||
UNIX_EPOCH + Duration::from_secs(1234567890 - 120), // 1234567890 since UNIX_EPOCH is 2009-02-13T23:31:30Z
|
||||
);
|
||||
|
||||
let provider_conf = SdkConfig::builder()
|
||||
let sdk_config = SdkConfig::builder()
|
||||
.sleep_impl(SharedAsyncSleep::new(sleep))
|
||||
.time_source(testing_time_source.clone())
|
||||
.http_connector(DynConnector::new(conn))
|
||||
|
@ -499,7 +497,7 @@ mod test {
|
|||
]));
|
||||
let credentials_list_cloned = credentials_list.clone();
|
||||
let provider = AssumeRoleProvider::builder("myrole")
|
||||
.configure(&provider_conf)
|
||||
.configure(&sdk_config)
|
||||
.region(Region::new("us-east-1"))
|
||||
.build_from_provider(provide_credentials_fn(move || {
|
||||
let list = credentials_list.clone();
|
||||
|
|
|
@ -14,6 +14,8 @@ use aws_types::os_shim_internal::{Env, Fs};
|
|||
use serde::Deserialize;
|
||||
|
||||
use crate::connector::default_connector;
|
||||
use crate::default_provider::use_dual_stack::use_dual_stack_provider;
|
||||
use crate::default_provider::use_fips::use_fips_provider;
|
||||
use aws_smithy_types::error::display::DisplayErrorContext;
|
||||
use std::collections::HashMap;
|
||||
use std::env;
|
||||
|
@ -236,6 +238,13 @@ impl TestEnvironment {
|
|||
.with_sleep(TokioSleep::new())
|
||||
.load_default_region()
|
||||
.await;
|
||||
|
||||
let use_dual_stack = use_dual_stack_provider(&provider_config).await;
|
||||
let use_fips = use_fips_provider(&provider_config).await;
|
||||
let provider_config = provider_config
|
||||
.with_use_fips(use_fips)
|
||||
.with_use_dual_stack(use_dual_stack);
|
||||
|
||||
Ok(TestEnvironment {
|
||||
base_dir: dir.into(),
|
||||
metadata,
|
||||
|
|
|
@ -204,7 +204,7 @@ impl Builder {
|
|||
WebIdentityTokenCredentialsProvider {
|
||||
source,
|
||||
fs: conf.fs(),
|
||||
sts_client: StsClient::from_conf(conf.sts_client_config().build()),
|
||||
sts_client: StsClient::new(&conf.client_config("STS")),
|
||||
time_source: conf.time_source(),
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,7 @@
|
|||
{
|
||||
"HOME": "/home",
|
||||
"AWS_REGION": "us-west-2",
|
||||
"AWS_PROFILE": "sso-test",
|
||||
"AWS_USE_FIPS_ENDPOINT": "true",
|
||||
"AWS_USE_DUALSTACK_ENDPOINT": "true"
|
||||
}
|
|
@ -0,0 +1,6 @@
|
|||
[profile sso-test]
|
||||
sso_start_url = https://ssotest.awsapps.com/start
|
||||
sso_region = us-east-2
|
||||
sso_account_id = 123456789
|
||||
sso_role_name = MySsoRole
|
||||
region = us-east-2
|
|
@ -0,0 +1,5 @@
|
|||
{
|
||||
"accessToken": "a-token",
|
||||
"expiresAt": "2080-10-16T03:56:45Z",
|
||||
"startUrl": "https://ssotest.awsapps.com/start"
|
||||
}
|
|
@ -0,0 +1,93 @@
|
|||
{
|
||||
"events": [
|
||||
{
|
||||
"connection_id": 0,
|
||||
"action": {
|
||||
"Request": {
|
||||
"request": {
|
||||
"uri": "https://portal.sso-fips.us-east-2.api.aws/federation/credentials?account_id=123456789&role_name=MySsoRole",
|
||||
"headers": {
|
||||
"x-amz-sso_bearer_token": [
|
||||
"a-token"
|
||||
],
|
||||
"Host": [
|
||||
"portal.sso-fips.us-east-2.api.aws"
|
||||
]
|
||||
},
|
||||
"method": "GET"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"connection_id": 0,
|
||||
"action": {
|
||||
"Eof": {
|
||||
"ok": true,
|
||||
"direction": "Request"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"connection_id": 0,
|
||||
"action": {
|
||||
"Response": {
|
||||
"response": {
|
||||
"Ok": {
|
||||
"status": 200,
|
||||
"version": "HTTP/1.1",
|
||||
"headers": {
|
||||
"Date": [
|
||||
"Mon, 03 Jan 2022 19:13:54 GMT"
|
||||
],
|
||||
"Content-Type": [
|
||||
"application/json"
|
||||
],
|
||||
"Content-Length": [
|
||||
"144"
|
||||
],
|
||||
"Connection": [
|
||||
"keep-alive"
|
||||
],
|
||||
"Access-Control-Expose-Headers": [
|
||||
"RequestId"
|
||||
],
|
||||
"Cache-Control": [
|
||||
"no-cache"
|
||||
],
|
||||
"RequestId": [
|
||||
"b339b807-25d1-474c-a476-b070e9f350e4"
|
||||
],
|
||||
"Server": [
|
||||
"AWS SSO"
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"connection_id": 0,
|
||||
"action": {
|
||||
"Data": {
|
||||
"data": {
|
||||
"Utf8": "{\"roleCredentials\":{\"accessKeyId\":\"ASIARCORRECT\",\"secretAccessKey\":\"secretkeycorrect\",\"sessionToken\":\"tokencorrect\",\"expiration\":1234567890000}}"
|
||||
},
|
||||
"direction": "Response"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"connection_id": 0,
|
||||
"action": {
|
||||
"Eof": {
|
||||
"ok": true,
|
||||
"direction": "Response"
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
"docs": "Load SSO credentials",
|
||||
"version": "V0"
|
||||
}
|
|
@ -0,0 +1,12 @@
|
|||
{
|
||||
"name": "e2e_fips_and_dual_stack_sso",
|
||||
"docs": "end to end SSO test with FIPS and dual stack enabled",
|
||||
"result": {
|
||||
"Ok": {
|
||||
"access_key_id": "ASIARCORRECT",
|
||||
"secret_access_key": "secretkeycorrect",
|
||||
"session_token": "tokencorrect",
|
||||
"expiry": 1234567890
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,3 @@
|
|||
{
|
||||
"HOME": "/home"
|
||||
}
|
|
@ -0,0 +1,9 @@
|
|||
[default]
|
||||
region = us-east-1
|
||||
role_arn = arn:aws:iam::123456789:role/integration-test
|
||||
source_profile = base
|
||||
use_fips_endpoint = true
|
||||
use_dualstack_endpoint = true
|
||||
|
||||
[profile base]
|
||||
region = us-east-1
|
|
@ -0,0 +1,3 @@
|
|||
[base]
|
||||
aws_access_key_id = AKIAFAKE
|
||||
aws_secret_access_key = FAKE
|
|
@ -0,0 +1,107 @@
|
|||
{
|
||||
"events": [
|
||||
{
|
||||
"connection_id": 0,
|
||||
"action": {
|
||||
"Request": {
|
||||
"request": {
|
||||
"uri": "https://sts-fips.us-east-1.api.aws/",
|
||||
"headers": {
|
||||
"content-type": [
|
||||
"application/x-www-form-urlencoded"
|
||||
],
|
||||
"authorization": [
|
||||
"AWS4-HMAC-SHA256 Credential=AKIAFAKE/20210810/us-east-1/sts/aws4_request, SignedHeaders=content-length;content-type;host;x-amz-date;x-amz-user-agent, Signature=cd5cb2aa1d20717ca17692bcbda711797ae9eb8bb1130690b021b3952b7ae56e"
|
||||
],
|
||||
"user-agent": [
|
||||
"aws-sdk-rust/0.1.0 os/macos lang/rust/1.55.0-nightly"
|
||||
],
|
||||
"content-length": [
|
||||
"146"
|
||||
],
|
||||
"x-amz-date": [
|
||||
"20210810T003833Z"
|
||||
],
|
||||
"host": [
|
||||
"sts-fips.us-east-1.api.aws"
|
||||
],
|
||||
"x-amz-user-agent": [
|
||||
"aws-sdk-rust/0.1.0 api/sts/0.0.14-alpha os/macos lang/rust/1.55.0-nightly"
|
||||
]
|
||||
},
|
||||
"method": "POST"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"connection_id": 0,
|
||||
"action": {
|
||||
"Data": {
|
||||
"data": {
|
||||
"Utf8": "Action=AssumeRole&Version=2011-06-15&RoleArn=arn%3Aaws%3Aiam%3A%3A123456789%3Arole%2Fintegration-test&RoleSessionName=assume-role-provider-session"
|
||||
},
|
||||
"direction": "Request"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"connection_id": 0,
|
||||
"action": {
|
||||
"Eof": {
|
||||
"ok": true,
|
||||
"direction": "Request"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"connection_id": 0,
|
||||
"action": {
|
||||
"Response": {
|
||||
"response": {
|
||||
"Ok": {
|
||||
"status": 200,
|
||||
"version": "HTTP/1.1",
|
||||
"headers": {
|
||||
"date": [
|
||||
"Thu, 05 Aug 2021 18:58:02 GMT"
|
||||
],
|
||||
"content-length": [
|
||||
"1491"
|
||||
],
|
||||
"content-type": [
|
||||
"text/xml"
|
||||
],
|
||||
"x-amzn-requestid": [
|
||||
"c2e971c2-702d-4124-9b1f-1670febbea18"
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"connection_id": 0,
|
||||
"action": {
|
||||
"Data": {
|
||||
"data": {
|
||||
"Utf8": "<AssumeRoleResponse xmlns=\"https://sts.amazonaws.com/doc/2011-06-15/\">\n <AssumeRoleResult>\n <AssumedRoleUser>\n <AssumedRoleId>AROARABCDEFGHIJKLMNOP:assume-role-provider-session</AssumedRoleId>\n <Arn>arn:aws:sts::123456789012:assumed-role/integration-test/assume-role-provider-session</Arn>\n </AssumedRoleUser>\n <Credentials>\n <AccessKeyId>ASIARTESTID</AccessKeyId>\n <SecretAccessKey>TESTSECRETKEY</SecretAccessKey>\n <SessionToken>TESTSESSIONTOKEN</SessionToken>\n <Expiration>2021-08-05T19:58:02Z</Expiration>\n </Credentials>\n </AssumeRoleResult>\n <ResponseMetadata>\n <RequestId>c2e971c2-702d-4124-9b1f-1670febbea18</RequestId>\n </ResponseMetadata>\n</AssumeRoleResponse>\n"
|
||||
},
|
||||
"direction": "Response"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"connection_id": 0,
|
||||
"action": {
|
||||
"Eof": {
|
||||
"ok": true,
|
||||
"direction": "Response"
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
"docs": "standard request / response with STS",
|
||||
"version": "V0"
|
||||
}
|
|
@ -0,0 +1,12 @@
|
|||
{
|
||||
"name": "e2e_fips_and_dual_stack_sts",
|
||||
"docs": "end to end STS role assumption test with FIPS and dual stack enabled",
|
||||
"result": {
|
||||
"Ok": {
|
||||
"access_key_id": "ASIARTESTID",
|
||||
"secret_access_key": "TESTSECRETKEY",
|
||||
"session_token": "TESTSESSIONTOKEN",
|
||||
"expiry": 1628193482
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue