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

feat: enable auth resolution via endpoints #1109

Merged
merged 11 commits into from
Nov 13, 2023
Merged

feat: enable auth resolution via endpoints #1109

merged 11 commits into from
Nov 13, 2023

Conversation

aajtodd
Copy link
Contributor

@aajtodd aajtodd commented Nov 8, 2023

Issue #

upstream: smithy-lang/smithy-kotlin#993

Description of changes

Enable using endpoint resolution as a way of resolving auth schemes for select services (S3 and EventBridge). This comes as a requirement from SRA for these services where their auth scheme rules are intimately tied to endpoints. This is an opt-in codegen feature since most services don't need this.

Also refactors the way S3 signing properties are set by defaulting them in the execution context rather than overriding the auth scheme instantiation expression. This ends up being a better customer experience if someone wants to override existing auth schemes (e.g. to replace the signer only) as they don't have to know about all the other S3 specific signer settings.

Testing

Tested against an MRAP bucket

val sigV4AScheme = SigV4AsymmetricAuthScheme(CrtAwsSigner)

S3Client.fromEnvironment {
    logMode = LogMode.LogRequest
    disableMrap = false
    authSchemes = listOf(sigV4AScheme)
}.use { s3 ->
    s3.putObject {
        bucket = "<redacted>.mrap"
        key = "test-mrap.txt"
        body = ByteStream.fromString("Hello MRAP!")
    }

    s3.listObjectsV2 {
        bucket = "<redacted>.mrap"
    }.contents.orEmpty().forEach(::println)
}

By submitting this pull request, I confirm that my contribution is made under the terms of the Apache 2.0 license.

@aajtodd aajtodd requested a review from a team as a code owner November 8, 2023 19:45
Copy link

github-actions bot commented Nov 8, 2023

A new generated diff is ready to view.

Copy link

github-actions bot commented Nov 9, 2023

A new generated diff is ready to view.

)
private fun renderDefaultSigningContext(writer: KotlinWriter, previousValue: String?) {
val signingAttrs = RuntimeTypes.Auth.Signing.AwsSigningCommon.AwsSigningAttributes
// https://github.com/awslabs/aws-sdk-kotlin/issues/200
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

question: this issue is closed, is it still relevant?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is here to remind us why path normalization and single URI encoding are important for S3.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah I left it as a clue for posterity about why we care about this and where the requirements come from.

* Service specific package settings
*/
val AwsService.packageSettings: String
get() = rootProject.file("$destinationDir/package.json").absolutePath
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

question/nit: Is package.json already an established name for SDK client codegen configuration? I think something like config.json makes more sense

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No established name, I don't have a strong preference. I think I went with package.json because that is what was proposed in the publishing QA doc. @ianbotsf do you have any preference?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't have a preference on the name—either package.json or config.json sounds fine to me.

Taking a closer look at this now, does Smithy not already have a way to handle this? If not, should we consider moving this kind of functionality up into the smithy-kotlin later?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Handle what? This is custom logic to feed into smithy-build.json.

Copy link

github-actions bot commented Nov 9, 2023

A new generated diff is ready to view.

Comment on lines 118 to 130
val packageSettingsFile = file(service.packageSettings)
val packageSettings = if (packageSettingsFile.exists()) {
val node = Node.parse(packageSettingsFile.inputStream())
node.asObjectNode().get()
} else {
Node.objectNode()
}

if (!packageSettings.isEmpty) {
packageSettings.expectMember("sdkId", "${packageSettingsFile.absolutePath} does not contain member `sdkId`")
val packageSdkId = packageSettings.getStringMember("sdkId").get().value
check(service.sdkId == packageSdkId) { "${packageSettingsFile.absolutePath} `sdkId` ($packageSdkId) does not match expected `${service.sdkId}`" }
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Question: I'm a little confused by this logic. It looks like if the file doesn't exist or contains only {} then we won't assert the existence of an sdkId...why is that? Shouldn't it be an error if the file exists and is malformed?

val packageSettingsFile = file(service.packageSettings)
if (packageSettingsFile.exists()) {
    val node = Node.parse(packageSettingsFile.inputStream()).asObjectNode().get()
    node.expectMember("sdkId", "${packageSettingsFile.absolutePath} does not contain member `sdkId`")
    val packageSdkId = node.getStringMember("sdkId").get().value
    check(service.sdkId == packageSdkId) { "${packageSettingsFile.absolutePath} `sdkId` ($packageSdkId) does not match expected `${service.sdkId}`" }
}

)
private fun renderDefaultSigningContext(writer: KotlinWriter, previousValue: String?) {
val signingAttrs = RuntimeTypes.Auth.Signing.AwsSigningCommon.AwsSigningAttributes
// https://github.com/awslabs/aws-sdk-kotlin/issues/200
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is here to remind us why path normalization and single URI encoding are important for S3.

Copy link

A new generated diff is ready to view.

Copy link

A new generated diff is ready to view.

Copy link

Kudos, SonarCloud Quality Gate passed!    Quality Gate passed

Bug A 0 Bugs
Vulnerability A 0 Vulnerabilities
Security Hotspot A 0 Security Hotspots
Code Smell A 1 Code Smell

No Coverage information No Coverage information
0.0% 0.0% Duplication

Copy link

A new generated diff is ready to view.

@aajtodd aajtodd merged commit a99254f into main Nov 13, 2023
16 of 17 checks passed
@aajtodd aajtodd deleted the endpoints4auth branch November 13, 2023 21:12
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants