Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Ensure identity resolver exists when a credentials provider is given only at operation level #3021

6 changes: 6 additions & 0 deletions CHANGELOG.next.toml
Original file line number Diff line number Diff line change
Expand Up @@ -46,3 +46,9 @@ message = "Fix code generation for union members with the `@httpPayload` trait."
references = ["smithy-rs#2969", "smithy-rs#1896"]
meta = { "breaking" = false, "tada" = false, "bug" = true, "target" = "all" }
author = "jdisanti"

[[aws-sdk-rust]]
message = "Fix operation level configuration so that it now sets a) an `IdentityResolver` when a credentials provider is provided only at the operation level and b) a `SigningRegion` when a `Region` is provided only at the operation level."
ysaito1001 marked this conversation as resolved.
Show resolved Hide resolved
references = ["smithy-rs#3021", "aws-sdk-rust#901"]
meta = { "breaking" = false, "tada" = false, "bug" = true }
author = "ysaito1001"
Original file line number Diff line number Diff line change
Expand Up @@ -57,10 +57,17 @@ class CredentialCacheConfig(codegenContext: ClientCodegenContext) : ConfigCustom
private val codegenScope = arrayOf(
*preludeScope,
"CredentialsCache" to AwsRuntimeType.awsCredentialTypes(runtimeConfig).resolve("cache::CredentialsCache"),
"CredentialsIdentityResolver" to AwsRuntimeType.awsRuntime(runtimeConfig)
.resolve("identity::credentials::CredentialsIdentityResolver"),
"DefaultProvider" to defaultProvider(),
"SIGV4_SCHEME_ID" to AwsRuntimeType.awsRuntime(runtimeConfig).resolve("auth::sigv4::SCHEME_ID"),
"SharedAsyncSleep" to RuntimeType.smithyAsync(runtimeConfig).resolve("rt::sleep::SharedAsyncSleep"),
"SharedCredentialsCache" to AwsRuntimeType.awsCredentialTypes(runtimeConfig).resolve("cache::SharedCredentialsCache"),
"SharedCredentialsProvider" to AwsRuntimeType.awsCredentialTypes(runtimeConfig).resolve("provider::SharedCredentialsProvider"),
"SharedCredentialsCache" to AwsRuntimeType.awsCredentialTypes(runtimeConfig)
.resolve("cache::SharedCredentialsCache"),
"SharedCredentialsProvider" to AwsRuntimeType.awsCredentialTypes(runtimeConfig)
.resolve("provider::SharedCredentialsProvider"),
"SharedIdentityResolver" to RuntimeType.smithyRuntimeApi(runtimeConfig)
.resolve("client::identity::SharedIdentityResolver"),
)

override fun section(section: ServiceConfig) = writable {
Expand Down Expand Up @@ -209,7 +216,14 @@ class CredentialCacheConfig(codegenContext: ClientCodegenContext) : ConfigCustom
#{Some}(credentials_cache),
#{Some}(credentials_provider),
) => {
resolver.config_mut().store_put(credentials_cache.create_cache(credentials_provider));
let credentials_cache = credentials_cache.create_cache(credentials_provider);
resolver.config_mut().store_put(credentials_cache.clone());
ysaito1001 marked this conversation as resolved.
Show resolved Hide resolved
resolver.runtime_components_mut().push_identity_resolver(
#{SIGV4_SCHEME_ID},
#{SharedIdentityResolver}::new(
#{CredentialsIdentityResolver}::new(credentials_cache),
),
);
}
}
""",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,19 @@ class SigV4SigningConfig(
)
}
}
is ServiceConfig.OperationConfigOverride -> {
if (runtimeMode.generateOrchestrator) {
rustTemplate(
"""
resolver.config_mut()
jdisanti marked this conversation as resolved.
Show resolved Hide resolved
.load::<#{Region}>()
.cloned()
.map(|r| resolver.config_mut().store_put(#{SigningRegion}::from(r)));
""",
*codegenScope,
)
}
}

else -> emptySection
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,10 +19,13 @@ internal class CredentialCacheConfigTest {
namespace com.example
use aws.protocols#awsJson1_0
use aws.api#service
use aws.auth#sigv4
use smithy.rules#endpointRuleSet

@service(sdkId: "Some Value")
@awsJson1_0
@sigv4(name: "dontcare")
@auth([sigv4])
@endpointRuleSet({
"version": "1.0",
"rules": [{
Expand All @@ -39,7 +42,6 @@ internal class CredentialCacheConfigTest {
version: "1"
}

@optionalAuth
operation SayHello { input: TestInput }
structure TestInput {
foo: String,
Expand All @@ -58,6 +60,7 @@ internal class CredentialCacheConfigTest {
.resolve("cache::CredentialsCache"),
"ProvideCachedCredentials" to AwsRuntimeType.awsCredentialTypes(runtimeConfig)
.resolve("cache::ProvideCachedCredentials"),
"Region" to AwsRuntimeType.awsTypes(runtimeConfig).resolve("region::Region"),
"RuntimePlugin" to RuntimeType.smithyRuntimeApi(runtimeConfig)
.resolve("client::runtime_plugin::RuntimePlugin"),
"SharedCredentialsCache" to AwsRuntimeType.awsCredentialTypes(runtimeConfig)
Expand Down Expand Up @@ -186,6 +189,39 @@ internal class CredentialCacheConfigTest {
*codegenScope,
)
}

tokioTest("test_specifying_credentials_provider_only_at_operation_level_should_work") {
// per https://github.com/awslabs/aws-sdk-rust/issues/901
rustTemplate(
"""
let client_config = crate::config::Config::builder().build();
let client = crate::client::Client::from_conf(client_config);

let credentials = #{Credentials}::new(
"test",
"test",
#{None},
#{None},
"test",
);
let operation_config_override = crate::config::Config::builder()
.credentials_cache(#{CredentialsCache}::no_caching())
.credentials_provider(credentials.clone())
.region(#{Region}::new("us-west-2"));

let _ = client
.say_hello()
.customize()
.await
.unwrap()
.config_override(operation_config_override)
.send()
.await
.expect("success");
""",
*codegenScope,
)
}
}
}
}
Expand Down