Skip to content

Commit 81fc83e

Browse files
ysaito1001jdisanti
andauthored
Fix config::Builder::set_credentials_provider to override what's previsouly set (#3278)
## Motivation and Context Fixes awslabs/aws-sdk-rust#973 ## Description Prior to the PR, if a customer explicitly passed a credentials provider to a client's config `Builder::set_credentials_provider`, what's passed did not override a credentials provider previously set ([actual use case](awslabs/aws-sdk-rust#973 (comment))). While in general, we recommend customers single-source a credentials provider through [aws_config::ConfigLoader::credentials_provider](https://docs.rs/aws-config/1.0.1/aws_config/struct.ConfigLoader.html#method.credentials_provider), we should eliminate the said footgun in case they directly pass a credentials provider to a client's config `Builder`. The PR reverts test signature updates in #3156 (in hindsight, having to update test signatures in that PR was a sign of regression). ## Testing Added a Kotlin test to `CredentialProviderConfigTest.kt` to verify the fix ## 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 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>
1 parent 76ae89a commit 81fc83e

File tree

14 files changed

+181
-23
lines changed

14 files changed

+181
-23
lines changed

CHANGELOG.next.toml

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,4 +9,22 @@
99
# message = "Fix typos in module documentation for generated crates"
1010
# references = ["smithy-rs#920"]
1111
# meta = { "breaking" = false, "tada" = false, "bug" = false, "target" = "client | server | all"}
12-
# author = "rcoh"
12+
# author = "rcoh"
13+
14+
[[aws-sdk-rust]]
15+
message = "Fix `config::Builder::set_credentials_provider` to override a credentials provider previously set."
16+
references = ["aws-sdk-rust#973", "smithy-rs#3278"]
17+
meta = { "breaking" = false, "tada" = false, "bug" = true }
18+
author = "ysaito1001"
19+
20+
[[aws-sdk-rust]]
21+
message = "`config::Config::credentials_provider` has been broken since `release-2023-11-15` and is now marked as `deprecated` explicitly."
22+
references = ["smithy-rs#3251", "smithy-rs#3278"]
23+
meta = { "breaking" = false, "tada" = false, "bug" = false }
24+
author = "ysaito1001"
25+
26+
[[smithy-rs]]
27+
message = "`RuntimeComponentsBuilder::push_identity_resolver` is now deprecated since it does not replace the existing identity resolver of a given auth scheme ID. Use `RuntimeComponentsBuilder::set_identity_resolver` instead."
28+
references = ["smithy-rs#3278"]
29+
meta = { "breaking" = false, "tada" = false, "bug" = false, "target" = "client" }
30+
author = "ysaito1001"

aws/sdk-codegen/src/main/kotlin/software/amazon/smithy/rustsdk/CredentialProviders.kt

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -81,9 +81,10 @@ class CredentialProviderConfig(private val codegenContext: ClientCodegenContext)
8181
ServiceConfig.ConfigImpl -> {
8282
rustTemplate(
8383
"""
84-
/// Returns the credentials provider for this service
84+
/// This function was intended to be removed, and has been broken since release-2023-11-15 as it always returns a `None`. Do not use.
85+
##[deprecated(note = "This function was intended to be removed, and has been broken since release-2023-11-15 as it always returns a `None`. Do not use.")]
8586
pub fn credentials_provider(&self) -> Option<#{SharedCredentialsProvider}> {
86-
self.config.load::<#{SharedCredentialsProvider}>().cloned()
87+
#{None}
8788
}
8889
""",
8990
*codegenScope,
@@ -118,13 +119,13 @@ class CredentialProviderConfig(private val codegenContext: ClientCodegenContext)
118119
if (codegenContext.serviceShape.supportedAuthSchemes().contains("sigv4a")) {
119120
featureGateBlock("sigv4a") {
120121
rustTemplate(
121-
"self.runtime_components.push_identity_resolver(#{SIGV4A_SCHEME_ID}, credentials_provider.clone());",
122+
"self.runtime_components.set_identity_resolver(#{SIGV4A_SCHEME_ID}, credentials_provider.clone());",
122123
*codegenScope,
123124
)
124125
}
125126
}
126127
rustTemplate(
127-
"self.runtime_components.push_identity_resolver(#{SIGV4_SCHEME_ID}, credentials_provider);",
128+
"self.runtime_components.set_identity_resolver(#{SIGV4_SCHEME_ID}, credentials_provider);",
128129
*codegenScope,
129130
)
130131
}

aws/sdk-codegen/src/test/kotlin/software/amazon/smithy/rustsdk/CredentialProviderConfigTest.kt

Lines changed: 68 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ internal class CredentialProviderConfigTest {
3030
val moduleName = ctx.moduleUseName()
3131
rustTemplate(
3232
"""
33-
let (http_client, _rx) = #{capture_request}(None);
33+
let (http_client, _rx) = #{capture_request}(#{None});
3434
let client_config = $moduleName::Config::builder()
3535
.http_client(http_client)
3636
.build();
@@ -62,4 +62,71 @@ internal class CredentialProviderConfigTest {
6262
}
6363
}
6464
}
65+
66+
@Test
67+
fun `configuring credentials provider on builder should replace what was previously set`() {
68+
awsSdkIntegrationTest(SdkCodegenIntegrationTest.model) { ctx, rustCrate ->
69+
val rc = ctx.runtimeConfig
70+
val codegenScope = arrayOf(
71+
*RuntimeType.preludeScope,
72+
"capture_request" to RuntimeType.captureRequest(rc),
73+
"Credentials" to AwsRuntimeType.awsCredentialTypesTestUtil(rc)
74+
.resolve("Credentials"),
75+
"Region" to AwsRuntimeType.awsTypes(rc).resolve("region::Region"),
76+
"SdkConfig" to AwsRuntimeType.awsTypes(rc).resolve("sdk_config::SdkConfig"),
77+
"SharedCredentialsProvider" to AwsRuntimeType.awsCredentialTypes(rc)
78+
.resolve("provider::SharedCredentialsProvider"),
79+
)
80+
rustCrate.integrationTest("credentials_provider") {
81+
// per https://github.com/awslabs/aws-sdk-rust/issues/973
82+
tokioTest("configuring_credentials_provider_on_builder_should_replace_what_was_previously_set") {
83+
val moduleName = ctx.moduleUseName()
84+
rustTemplate(
85+
"""
86+
let (http_client, rx) = #{capture_request}(#{None});
87+
88+
let replace_me = #{Credentials}::new(
89+
"replace_me",
90+
"replace_me",
91+
#{None},
92+
#{None},
93+
"replace_me",
94+
);
95+
let sdk_config = #{SdkConfig}::builder()
96+
.credentials_provider(
97+
#{SharedCredentialsProvider}::new(replace_me),
98+
)
99+
.region(#{Region}::new("us-west-2"))
100+
.build();
101+
102+
let expected = #{Credentials}::new(
103+
"expected_credential",
104+
"expected_credential",
105+
#{None},
106+
#{None},
107+
"expected_credential",
108+
);
109+
let conf = $moduleName::config::Builder::from(&sdk_config)
110+
.http_client(http_client)
111+
.credentials_provider(expected)
112+
.build();
113+
114+
let client = $moduleName::Client::from_conf(conf);
115+
116+
let _ = client
117+
.some_operation()
118+
.send()
119+
.await
120+
.expect("success");
121+
122+
let req = rx.expect_request();
123+
let auth_header = req.headers().get("AUTHORIZATION").unwrap();
124+
assert!(auth_header.contains("expected_credential"), "{auth_header}");
125+
""",
126+
*codegenScope,
127+
)
128+
}
129+
}
130+
}
131+
}
65132
}

aws/sdk/integration-tests/kms/tests/integration.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ async fn generate_random() {
5252
.header("content-type", "application/x-amz-json-1.1")
5353
.header("x-amz-target", "TrentService.GenerateRandom")
5454
.header("content-length", "20")
55-
.header("authorization", "AWS4-HMAC-SHA256 Credential=ANOTREAL/20090213/us-east-1/kms/aws4_request, SignedHeaders=content-length;content-type;host;x-amz-date;x-amz-security-token;x-amz-target;x-amz-user-agent, Signature=703f72fe50c310e3ee1a7a106df947b980cb91bc8bad7a4a603b057096603aed")
55+
.header("authorization", "AWS4-HMAC-SHA256 Credential=ANOTREAL/20090213/us-east-1/kms/aws4_request, SignedHeaders=content-length;content-type;host;x-amz-date;x-amz-target;x-amz-user-agent, Signature=53dcf70f6f852cb576185dcabef5aaa3d068704cf1b7ea7dc644efeaa46674d7")
5656
.header("x-amz-date", "20090213T233130Z")
5757
.header("user-agent", "aws-sdk-rust/0.123.test os/windows/XPSP3 lang/rust/1.50.0")
5858
.header("x-amz-user-agent", "aws-sdk-rust/0.123.test api/test-service/0.123 os/windows/XPSP3 lang/rust/1.50.0")

aws/sdk/integration-tests/qldbsession/tests/integration.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ async fn signv4_use_correct_service_name() {
2020
.header("content-type", "application/x-amz-json-1.0")
2121
.header("x-amz-target", "QLDBSession.SendCommand")
2222
.header("content-length", "49")
23-
.header("authorization", "AWS4-HMAC-SHA256 Credential=ANOTREAL/20090213/us-east-1/qldb/aws4_request, SignedHeaders=content-length;content-type;host;x-amz-date;x-amz-security-token;x-amz-target;x-amz-user-agent, Signature=e8d50282fa369adf05f33a5b32e3ce2a7582edc902312c59de311001a97426d9")
23+
.header("authorization", "AWS4-HMAC-SHA256 Credential=ANOTREAL/20090213/us-east-1/qldb/aws4_request, SignedHeaders=content-length;content-type;host;x-amz-date;x-amz-target;x-amz-user-agent, Signature=9a07c60550504d015fb9a2b0f1b175a4d906651f9dd4ee44bebb32a802d03815")
2424
// qldbsession uses the signing name 'qldb' in signature _________________________^^^^
2525
.header("x-amz-date", "20090213T233130Z")
2626
.header("user-agent", "aws-sdk-rust/0.123.test os/windows/XPSP3 lang/rust/1.50.0")

aws/sdk/integration-tests/s3/tests/naughty-string-metadata.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,7 @@ async fn test_s3_signer_with_naughty_string_metadata() {
8888

8989
// This is a snapshot test taken from a known working test result
9090
let snapshot_signature =
91-
"Signature=733dba2f1ca3c9a39f4eef3a6750a71eff00297cd765408ad3cef5dcdc44d642";
91+
"Signature=a5115604df66219874a9e5a8eab4c9f7a28c992ab2d918037a285756c019f3b2";
9292
assert!(
9393
auth_header .contains(snapshot_signature),
9494
"authorization header signature did not match expected signature: got {}, expected it to contain {}",

aws/sdk/integration-tests/s3/tests/normalize-uri-path.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ async fn test_operation_should_not_normalize_uri_path() {
4141
let expected_uri = "https://test-bucket-ad7c9f01-7f7b-4669-b550-75cc6d4df0f1.s3.us-east-1.amazonaws.com/a/.././b.txt?x-id=PutObject";
4242
assert_eq!(actual_uri, expected_uri);
4343

44-
let expected_sig = "Signature=404fb9502378c8f46fb83544848c42d29d55610a14b4bed9577542e49e549d08";
44+
let expected_sig = "Signature=2ac540538c84dc2616d92fb51d4fc6146ccd9ccc1ee85f518a1a686c5ef97b86";
4545
assert!(
4646
actual_auth.contains(expected_sig),
4747
"authorization header signature did not match expected signature: expected {} but not found in {}",

aws/sdk/integration-tests/s3/tests/query-strings-are-correctly-encoded.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ async fn test_s3_signer_query_string_with_all_valid_chars() {
4545

4646
// This is a snapshot test taken from a known working test result
4747
let snapshot_signature =
48-
"Signature=740feb1de3968a643e68fb1a17c415d98dd6a1cc28782fb1ef6157586548c747";
48+
"Signature=9a931d20606f93fa4e5553602866a9b5ccac2cd42b54ae5a4b17e4614fb443ce";
4949
assert!(
5050
auth_header
5151
.contains(snapshot_signature),

aws/sdk/integration-tests/s3/tests/signing-it.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ use aws_smithy_types::body::SdkBody;
1515
async fn test_signer() {
1616
let http_client = StaticReplayClient::new(vec![ReplayEvent::new(
1717
http::Request::builder()
18-
.header("authorization", "AWS4-HMAC-SHA256 Credential=ANOTREAL/20090213/us-east-1/s3/aws4_request, SignedHeaders=host;x-amz-content-sha256;x-amz-date;x-amz-security-token;x-amz-user-agent, Signature=d8ea22461a59cc1cbeb01fa093423ffafcb7695197ba2409b477216a4be2c104")
18+
.header("authorization", "AWS4-HMAC-SHA256 Credential=ANOTREAL/20090213/us-east-1/s3/aws4_request, SignedHeaders=host;x-amz-content-sha256;x-amz-date;x-amz-user-agent, Signature=27e3f59ec3cffaa10e4f1c92112e8fb62d468a04cd32be39e68215f830404dbb")
1919
.uri("https://test-bucket.s3.us-east-1.amazonaws.com/?list-type=2&prefix=prefix~")
2020
.body(SdkBody::empty())
2121
.unwrap(),

aws/sdk/integration-tests/s3control/tests/signing-it.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,10 +13,10 @@ use aws_smithy_types::body::SdkBody;
1313
async fn test_signer() {
1414
let http_client = StaticReplayClient::new(vec![ReplayEvent::new(
1515
http::Request::builder()
16-
.header("authorization",
16+
.header("authorization",
1717
"AWS4-HMAC-SHA256 Credential=ANOTREAL/20090213/us-east-1/s3/aws4_request, \
18-
SignedHeaders=host;x-amz-account-id;x-amz-content-sha256;x-amz-date;x-amz-security-token;x-amz-user-agent, \
19-
Signature=01a71226e959c7b0b998adf26fa266f9c3612df57a60b187d549822e86d90667")
18+
SignedHeaders=host;x-amz-account-id;x-amz-content-sha256;x-amz-date;x-amz-user-agent, \
19+
Signature=0102a74cb220f8445c4efada17660572ff813e07b524032ec831e8c2514be903")
2020
.uri("https://test-bucket.s3-control.us-east-1.amazonaws.com/v20180820/accesspoint")
2121
.body(SdkBody::empty())
2222
.unwrap(),

0 commit comments

Comments
 (0)