From ccb7b08058158d80aaf23b6573cb363b98b7c5fe Mon Sep 17 00:00:00 2001 From: John DiSanti Date: Wed, 9 Aug 2023 15:31:16 -0700 Subject: [PATCH 1/3] Improve presigning module docs (#2903) _By submitting this pull request, I confirm that you can use, modify, copy, and redistribute this contribution, under the terms of your choice._ --- aws/rust-runtime/aws-inlineable/src/presigning.rs | 7 +++++++ .../amazon/smithy/rustsdk/AwsPresigningDecorator.kt | 3 +++ 2 files changed, 10 insertions(+) diff --git a/aws/rust-runtime/aws-inlineable/src/presigning.rs b/aws/rust-runtime/aws-inlineable/src/presigning.rs index c9de75dfb0..a633352769 100644 --- a/aws/rust-runtime/aws-inlineable/src/presigning.rs +++ b/aws/rust-runtime/aws-inlineable/src/presigning.rs @@ -3,7 +3,14 @@ * SPDX-License-Identifier: Apache-2.0 */ +// TODO(https://github.com/awslabs/smithy-rs/issues/2902): Code generate this documentation so that service-specific examples can be added. //! Presigned request types and configuration. +//! +//! The [`Client`](crate::Client) is used to create presigned requests. They are made +//! by calling `.presigned()` instead of `.send()` on an operation, and require a +//! [`PresigningConfig`](crate::presigning::PresigningConfig) to provide an expiration time. +//! +//! Only operations that support presigning have the `presigned()` method on them. use std::fmt; use std::time::{Duration, SystemTime}; diff --git a/aws/sdk-codegen/src/main/kotlin/software/amazon/smithy/rustsdk/AwsPresigningDecorator.kt b/aws/sdk-codegen/src/main/kotlin/software/amazon/smithy/rustsdk/AwsPresigningDecorator.kt index 3957f77391..e0a2df817f 100644 --- a/aws/sdk-codegen/src/main/kotlin/software/amazon/smithy/rustsdk/AwsPresigningDecorator.kt +++ b/aws/sdk-codegen/src/main/kotlin/software/amazon/smithy/rustsdk/AwsPresigningDecorator.kt @@ -500,6 +500,9 @@ private fun RustWriter.documentPresignedMethod(hasConfigArg: Boolean) { Presigned requests can be given to other users or applications to access a resource or perform an operation without having access to the AWS security credentials. + + _Important:_ If you're using credentials that can expire, such as those from STS AssumeRole or SSO, then + the presigned request can only be valid for as long as the credentials used to create it are. """, ) } From d7ffa89338225108e2d11a57f1aa6b6c289bd7af Mon Sep 17 00:00:00 2001 From: John DiSanti Date: Thu, 10 Aug 2023 10:43:57 -0700 Subject: [PATCH 2/3] Clean up the pre-commit config (#2915) Update the name of the `sdk-lints` check since it checks more than just license headers now, and make it run at the end so that KTLint runs and fixes files even if there's an invalid changelog entry. ---- _By submitting this pull request, I confirm that you can use, modify, copy, and redistribute this contribution, under the terms of your choice._ --- .pre-commit-config.yaml | 26 +++++++++---------- .../{license-header.sh => sdk-lints.sh} | 3 +-- 2 files changed, 14 insertions(+), 15 deletions(-) rename .pre-commit-hooks/{license-header.sh => sdk-lints.sh} (99%) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index a45d403a09..c6e004a8a7 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -6,19 +6,6 @@ repos: - id: end-of-file-fixer exclude: ^aws/rust-runtime/aws-sigv4/aws-sig-v4-test-suite/ - id: trailing-whitespace -- repo: local - hooks: - - id: kotlin-block-quotes - name: Kotlin Block Quotes - entry: ./.pre-commit-hooks/kotlin-block-quotes.py - language: python - files: ^.*\.kt$ - - id: license-header-check - name: License Header Check - entry: ./.pre-commit-hooks/license-header.sh - language: system - files: ^.*$ - pass_filenames: false - repo: https://github.com/macisamuele/language-formatters-pre-commit-hooks rev: v2.10.0 hooks: @@ -29,3 +16,16 @@ repos: - id: pretty-format-rust entry: rustfmt --edition 2021 files: ^.*\.rs$ +- repo: local + hooks: + - id: kotlin-block-quotes + name: Kotlin Block Quotes + entry: ./.pre-commit-hooks/kotlin-block-quotes.py + language: python + files: ^.*\.kt$ + - id: sdk-lints-check + name: sdk-lints + entry: ./.pre-commit-hooks/sdk-lints.sh + language: system + files: ^.*$ + pass_filenames: false diff --git a/.pre-commit-hooks/license-header.sh b/.pre-commit-hooks/sdk-lints.sh similarity index 99% rename from .pre-commit-hooks/license-header.sh rename to .pre-commit-hooks/sdk-lints.sh index 653320a98e..be7bf421f3 100755 --- a/.pre-commit-hooks/license-header.sh +++ b/.pre-commit-hooks/sdk-lints.sh @@ -1,9 +1,8 @@ #!/bin/bash -set -e - # # Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. # SPDX-License-Identifier: Apache-2.0 # +set -e cd "$(git rev-parse --show-toplevel)/tools/ci-build/sdk-lints" && cargo run -- check --license --changelog From 0286b9fbea4235071a5ce8837c25f11c933d4d4a Mon Sep 17 00:00:00 2001 From: John DiSanti Date: Thu, 10 Aug 2023 15:18:03 -0700 Subject: [PATCH 3/3] Fix S3 optional auth (#2907) ## Motivation and Context This PR implements a short-term solution for aws-sdk-rust#864 while a long-term solution is worked out. ## Testing - Tested manually against S3. - Added DVR tests. ---- _By submitting this pull request, I confirm that you can use, modify, copy, and redistribute this contribution, under the terms of your choice._ --- CHANGELOG.next.toml | 6 + .../rustsdk/customize/s3/S3Decorator.kt | 24 ++++ aws/sdk/build.gradle.kts | 2 +- .../s3/tests/data/no_auth/get-object.json | 85 +++++++++++ .../s3/tests/data/no_auth/head-object.json | 94 ++++++++++++ .../tests/data/no_auth/list-objects-v2.json | 93 ++++++++++++ .../s3/tests/data/no_auth/list-objects.json | 93 ++++++++++++ aws/sdk/integration-tests/s3/tests/no_auth.rs | 136 ++++++++++++++++++ .../src/client/orchestrator/auth.rs | 8 +- 9 files changed, 539 insertions(+), 2 deletions(-) create mode 100644 aws/sdk/integration-tests/s3/tests/data/no_auth/get-object.json create mode 100644 aws/sdk/integration-tests/s3/tests/data/no_auth/head-object.json create mode 100644 aws/sdk/integration-tests/s3/tests/data/no_auth/list-objects-v2.json create mode 100644 aws/sdk/integration-tests/s3/tests/data/no_auth/list-objects.json create mode 100644 aws/sdk/integration-tests/s3/tests/no_auth.rs diff --git a/CHANGELOG.next.toml b/CHANGELOG.next.toml index fac4ec6ebd..8cf6a7fb2a 100644 --- a/CHANGELOG.next.toml +++ b/CHANGELOG.next.toml @@ -22,3 +22,9 @@ message = "`RuntimeComponents` and `RuntimeComponentsBuilder` are now re-exporte references = ["smithy-rs#2904"] meta = { "breaking" = false, "tada" = false, "bug" = false, "target" = "client"} author = "jdisanti" + +[[aws-sdk-rust]] +message = "Fix requests to S3 with `no_credentials` set." +references = ["smithy-rs#2907", "aws-sdk-rust#864"] +meta = { "breaking" = false, "tada" = false, "bug" = true } +author = "jdisanti" diff --git a/aws/sdk-codegen/src/main/kotlin/software/amazon/smithy/rustsdk/customize/s3/S3Decorator.kt b/aws/sdk-codegen/src/main/kotlin/software/amazon/smithy/rustsdk/customize/s3/S3Decorator.kt index 72f128fb70..e83ebb1e9a 100644 --- a/aws/sdk-codegen/src/main/kotlin/software/amazon/smithy/rustsdk/customize/s3/S3Decorator.kt +++ b/aws/sdk-codegen/src/main/kotlin/software/amazon/smithy/rustsdk/customize/s3/S3Decorator.kt @@ -13,6 +13,7 @@ import software.amazon.smithy.model.shapes.ServiceShape import software.amazon.smithy.model.shapes.Shape import software.amazon.smithy.model.shapes.ShapeId import software.amazon.smithy.model.shapes.StructureShape +import software.amazon.smithy.model.traits.OptionalAuthTrait import software.amazon.smithy.model.transform.ModelTransformer import software.amazon.smithy.rulesengine.traits.EndpointTestCase import software.amazon.smithy.rulesengine.traits.EndpointTestOperationInput @@ -34,6 +35,7 @@ import software.amazon.smithy.rust.codegen.core.smithy.protocols.ProtocolFunctio import software.amazon.smithy.rust.codegen.core.smithy.protocols.ProtocolMap import software.amazon.smithy.rust.codegen.core.smithy.protocols.RestXml import software.amazon.smithy.rust.codegen.core.smithy.traits.AllowInvalidXmlRoot +import software.amazon.smithy.rust.codegen.core.util.hasTrait import software.amazon.smithy.rust.codegen.core.util.letIf import software.amazon.smithy.rustsdk.getBuiltIn import software.amazon.smithy.rustsdk.toWritable @@ -82,6 +84,8 @@ class S3Decorator : ClientCodegenDecorator { }, )::transform, ) + // enable optional auth for operations commonly used with public buckets + .let(AddOptionalAuth()::transform) override fun endpointCustomizations(codegenContext: ClientCodegenContext): List { return listOf( @@ -129,6 +133,26 @@ class FilterEndpointTests( } } +// TODO(P96049742): This model transform may need to change depending on if and how the S3 model is updated. +private class AddOptionalAuth { + private val s3OptionalAuthOperations = listOf( + ShapeId.from("com.amazonaws.s3#ListObjects"), + ShapeId.from("com.amazonaws.s3#ListObjectsV2"), + ShapeId.from("com.amazonaws.s3#HeadObject"), + ShapeId.from("com.amazonaws.s3#GetObject"), + ) + + fun transform(model: Model) = ModelTransformer.create().mapShapes(model) { shape -> + if (shape is OperationShape && s3OptionalAuthOperations.contains(shape.id) && !shape.hasTrait()) { + shape.toBuilder() + .addTrait(OptionalAuthTrait()) + .build() + } else { + shape + } + } +} + class S3ProtocolOverride(codegenContext: CodegenContext) : RestXml(codegenContext) { private val runtimeConfig = codegenContext.runtimeConfig private val errorScope = arrayOf( diff --git a/aws/sdk/build.gradle.kts b/aws/sdk/build.gradle.kts index ebf1b3a705..03e9bcfde5 100644 --- a/aws/sdk/build.gradle.kts +++ b/aws/sdk/build.gradle.kts @@ -338,7 +338,7 @@ tasks.register("generateCargoWorkspace") { doFirst { outputDir.mkdirs() outputDir.resolve("Cargo.toml").writeText(generateCargoWorkspace(awsServices)) - rootProject.rootDir.resolve("clippy-root.toml").copyTo(outputDir.resolve("clippy.toml")) + rootProject.rootDir.resolve("clippy-root.toml").copyTo(outputDir.resolve("clippy.toml"), overwrite = true) } inputs.property("servicelist", awsServices.moduleNames.toString()) if (awsServices.examples.isNotEmpty()) { diff --git a/aws/sdk/integration-tests/s3/tests/data/no_auth/get-object.json b/aws/sdk/integration-tests/s3/tests/data/no_auth/get-object.json new file mode 100644 index 0000000000..4cc94177a3 --- /dev/null +++ b/aws/sdk/integration-tests/s3/tests/data/no_auth/get-object.json @@ -0,0 +1,85 @@ +{ + "events": [ + { + "connection_id": 0, + "action": { + "Request": { + "request": { + "uri": "https://gdc-organoid-pancreatic-phs001611-2-open.s3.us-east-1.amazonaws.com/0431cddc-a418-4a79-a34d-6c041394e8e4/a6ddcc84-8e4d-4c68-885c-2d51168eec97.FPKM-UQ.txt.gz?x-id=GetObject", + "headers": { + "amz-sdk-request": [ + "attempt=1; max=3" + ], + "user-agent": [ + "aws-sdk-rust/0.123.test os/windows/XPSP3 lang/rust/1.50.0" + ], + "x-amz-user-agent": [ + "aws-sdk-rust/0.123.test api/test-service/0.123 os/windows/XPSP3 lang/rust/1.50.0" + ] + }, + "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": { + "content-type": [ + "binary/octet-stream" + ], + "x-amz-id-2": [ + "mO5q2ZSztYdEU923Zi5sHNctHwRRzOyngQEWsZWHwOJEgxrj9dw0KH0IVovTxu2Y8V0ps5z4KMQ=" + ], + "content-length": [ + "386910" + ], + "accept-ranges": [ + "bytes" + ], + "x-amz-server-side-encryption": [ + "AES256" + ], + "x-amz-request-id": [ + "EGGB3A7GXR9YWDYM" + ], + "last-modified": [ + "Mon, 27 Jan 2020 20:56:51 GMT" + ], + "date": [ + "Mon, 07 Aug 2023 20:44:42 GMT" + ], + "x-amz-meta-description": [ + "{\"url\": \"s3://cleversafe.service.consul/stage-submission-5/ORGANOID-PANCREATIC/0431cddc-a418-4a79-a34d-6c041394e8e4/a6ddcc84-8e4d-4c68-885c-2d51168eec97.FPKM-UQ.txt.gz\", \"node_id\": \"0431cddc-a418-4a79-a34d-6c041394e8e4/a6ddcc84-8e4d-4c68-885c-2d51168eec97.FPKM-UQ.txt.gz\"}" + ], + "server": [ + "AmazonS3" + ], + "etag": [ + "\"446fc665f99183cd0540d7656a79d3ed\"" + ] + } + } + } + } + } + } + ], + "docs": "traffic recording of optional auth (no Authorization header is included)", + "version": "V0" +} diff --git a/aws/sdk/integration-tests/s3/tests/data/no_auth/head-object.json b/aws/sdk/integration-tests/s3/tests/data/no_auth/head-object.json new file mode 100644 index 0000000000..c0ab633b57 --- /dev/null +++ b/aws/sdk/integration-tests/s3/tests/data/no_auth/head-object.json @@ -0,0 +1,94 @@ +{ + "events": [ + { + "connection_id": 0, + "action": { + "Request": { + "request": { + "uri": "https://gdc-organoid-pancreatic-phs001611-2-open.s3.us-east-1.amazonaws.com/0431cddc-a418-4a79-a34d-6c041394e8e4/a6ddcc84-8e4d-4c68-885c-2d51168eec97.FPKM-UQ.txt.gz", + "headers": { + "user-agent": [ + "aws-sdk-rust/0.123.test os/windows/XPSP3 lang/rust/1.50.0" + ], + "amz-sdk-request": [ + "attempt=1; max=3" + ], + "x-amz-user-agent": [ + "aws-sdk-rust/0.123.test api/test-service/0.123 os/windows/XPSP3 lang/rust/1.50.0" + ] + }, + "method": "HEAD" + } + } + } + }, + { + "connection_id": 0, + "action": { + "Eof": { + "ok": true, + "direction": "Request" + } + } + }, + { + "connection_id": 0, + "action": { + "Response": { + "response": { + "Ok": { + "status": 200, + "version": "HTTP/1.1", + "headers": { + "last-modified": [ + "Mon, 27 Jan 2020 20:56:51 GMT" + ], + "content-type": [ + "binary/octet-stream" + ], + "date": [ + "Mon, 07 Aug 2023 20:44:42 GMT" + ], + "server": [ + "AmazonS3" + ], + "content-length": [ + "386910" + ], + "accept-ranges": [ + "bytes" + ], + "x-amz-server-side-encryption": [ + "AES256" + ], + "x-amz-id-2": [ + "+d6tSM3krTTrvY+y6PFHnkw9OhAtJhQy8RzFrPO6vnUOIuvqViB9gFZvfJCcVMj7gX+dpIvZ3HI=" + ], + "x-amz-request-id": [ + "EGGF3G9KFMFHZ3E0" + ], + "etag": [ + "\"446fc665f99183cd0540d7656a79d3ed\"" + ], + "x-amz-meta-description": [ + "{\"url\": \"s3://cleversafe.service.consul/stage-submission-5/ORGANOID-PANCREATIC/0431cddc-a418-4a79-a34d-6c041394e8e4/a6ddcc84-8e4d-4c68-885c-2d51168eec97.FPKM-UQ.txt.gz\", \"node_id\": \"0431cddc-a418-4a79-a34d-6c041394e8e4/a6ddcc84-8e4d-4c68-885c-2d51168eec97.FPKM-UQ.txt.gz\"}" + ] + } + } + } + } + } + }, + { + "connection_id": 0, + "action": { + "Eof": { + "ok": true, + "direction": "Response" + } + } + } + ], + "docs": "traffic recording of optional auth (no Authorization header is included)", + "version": "V0" +} diff --git a/aws/sdk/integration-tests/s3/tests/data/no_auth/list-objects-v2.json b/aws/sdk/integration-tests/s3/tests/data/no_auth/list-objects-v2.json new file mode 100644 index 0000000000..952e22dc51 --- /dev/null +++ b/aws/sdk/integration-tests/s3/tests/data/no_auth/list-objects-v2.json @@ -0,0 +1,93 @@ +{ + "events": [ + { + "connection_id": 0, + "action": { + "Request": { + "request": { + "uri": "https://gdc-organoid-pancreatic-phs001611-2-open.s3.us-east-1.amazonaws.com/?list-type=2&max-keys=3", + "headers": { + "amz-sdk-request": [ + "attempt=1; max=3" + ], + "x-amz-user-agent": [ + "aws-sdk-rust/0.123.test api/test-service/0.123 os/windows/XPSP3 lang/rust/1.50.0" + ], + "user-agent": [ + "aws-sdk-rust/0.123.test os/windows/XPSP3 lang/rust/1.50.0" + ] + }, + "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": { + "x-amz-id-2": [ + "InRlbSiDTNSjIiYuGbkpnrz0TIgFVsDu8bnzVwF2UvZiOuiwhvdA3oltBT1ILZqNyFzSIkShTKk=" + ], + "x-amz-request-id": [ + "H8T96AN5TTDT3SSQ" + ], + "server": [ + "AmazonS3" + ], + "x-amz-bucket-region": [ + "us-east-1" + ], + "date": [ + "Mon, 07 Aug 2023 20:44:41 GMT" + ], + "content-type": [ + "application/xml" + ], + "transfer-encoding": [ + "chunked" + ] + } + } + } + } + } + }, + { + "connection_id": 0, + "action": { + "Data": { + "data": { + "Utf8": "\ngdc-organoid-pancreatic-phs001611-2-open1SL9nYFaimMAwnR9dJnF4M5NMfm3Em6/ClPUVLEH3GOSw5yjeI+wCBLj3THB8DuJSUFhKNy5cGK5QBb/SvE+MKMZurarr0ZhOhQae2SQ8B4QQPkqQHKp9MeJXsYe4UH8/okpqJUZNS2AQt7gXrz7mFdIJXPuSckj02e06tvxZAOkHu7ER4xTJ+odI774K2xB+pcD3H0pqTUt+TebzB83BzA==33true0431cddc-a418-4a79-a34d-6c041394e8e4/a6ddcc84-8e4d-4c68-885c-2d51168eec97.FPKM-UQ.txt.gz2020-01-27T20:56:51.000Z"446fc665f99183cd0540d7656a79d3ed"386910STANDARD04a0a508-459a-4758-ac40-c3e8cb966683/30520ecd-c6bd-4039-9b1a-d3f999235598.FPKM-UQ.txt.gz2020-01-27T20:56:50.000Z"a2c6997aa0c6a9fd697af3e0517d96be"388349STANDARD0541851c-ac0c-496e-93d2-3c03921fa6bd/c92f3dc4-24ea-457b-b90a-d6d599b14a73.rna_seq.star_gene_counts.tsv.gz2020-01-27T20:56:51.000Z"f2c4e159c9b2f4233c4c0c27f4c25472"396626STANDARD" + }, + "direction": "Response" + } + } + }, + { + "connection_id": 0, + "action": { + "Eof": { + "ok": true, + "direction": "Response" + } + } + } + ], + "docs": "traffic recording of optional auth (no Authorization header is included)", + "version": "V0" +} diff --git a/aws/sdk/integration-tests/s3/tests/data/no_auth/list-objects.json b/aws/sdk/integration-tests/s3/tests/data/no_auth/list-objects.json new file mode 100644 index 0000000000..9b9b01c5a5 --- /dev/null +++ b/aws/sdk/integration-tests/s3/tests/data/no_auth/list-objects.json @@ -0,0 +1,93 @@ +{ + "events": [ + { + "connection_id": 0, + "action": { + "Request": { + "request": { + "uri": "https://gdc-organoid-pancreatic-phs001611-2-open.s3.us-east-1.amazonaws.com/?max-keys=3", + "headers": { + "x-amz-user-agent": [ + "aws-sdk-rust/0.123.test api/test-service/0.123 os/windows/XPSP3 lang/rust/1.50.0" + ], + "amz-sdk-request": [ + "attempt=1; max=3" + ], + "user-agent": [ + "aws-sdk-rust/0.123.test os/windows/XPSP3 lang/rust/1.50.0" + ] + }, + "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": { + "transfer-encoding": [ + "chunked" + ], + "server": [ + "AmazonS3" + ], + "x-amz-id-2": [ + "9/ufVv0fY5POrsdgAV2QMGmmpa78fx0YlL5KkQHzg46B0/NAWr/l0YsmR/F2HPn8ByFIwO5NdFs=" + ], + "x-amz-bucket-region": [ + "us-east-1" + ], + "date": [ + "Mon, 07 Aug 2023 20:44:40 GMT" + ], + "x-amz-request-id": [ + "QJE4M4NA5KFKN6YA" + ], + "content-type": [ + "application/xml" + ] + } + } + } + } + } + }, + { + "connection_id": 0, + "action": { + "Data": { + "data": { + "Utf8": "\ngdc-organoid-pancreatic-phs001611-2-open3true0431cddc-a418-4a79-a34d-6c041394e8e4/a6ddcc84-8e4d-4c68-885c-2d51168eec97.FPKM-UQ.txt.gz2020-01-27T20:56:51.000Z"446fc665f99183cd0540d7656a79d3ed"386910118c9f5f9e6a1a31d2f3be2a5e3aea8b3075cdc9dfbb29978656b42b7cad1c08dcfopen-bucketsSTANDARD04a0a508-459a-4758-ac40-c3e8cb966683/30520ecd-c6bd-4039-9b1a-d3f999235598.FPKM-UQ.txt.gz2020-01-27T20:56:50.000Z"a2c6997aa0c6a9fd697af3e0517d96be"388349118c9f5f9e6a1a31d2f3be2a5e3aea8b3075cdc9dfbb29978656b42b7cad1c08dcfopen-bucketsSTANDARD0541851c-ac0c-496e-93d2-3c03921fa6bd/c92f3dc4-24ea-457b-b90a-d6d599b14a73.rna_seq.star_gene_counts.tsv.gz2020-01-27T20:56:51.000Z"f2c4e159c9b2f4233c4c0c27f4c25472"396626118c9f5f9e6a1a31d2f3be2a5e3aea8b3075cdc9dfbb29978656b42b7cad1c08dcfopen-bucketsSTANDARD" + }, + "direction": "Response" + } + } + }, + { + "connection_id": 0, + "action": { + "Eof": { + "ok": true, + "direction": "Response" + } + } + } + ], + "docs": "traffic recording of optional auth (no Authorization header is included)", + "version": "V0" +} diff --git a/aws/sdk/integration-tests/s3/tests/no_auth.rs b/aws/sdk/integration-tests/s3/tests/no_auth.rs new file mode 100644 index 0000000000..1d6947582a --- /dev/null +++ b/aws/sdk/integration-tests/s3/tests/no_auth.rs @@ -0,0 +1,136 @@ +/* + * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. + * SPDX-License-Identifier: Apache-2.0 + */ + +#[cfg(not(aws_sdk_middleware_mode))] +mod access_public_datasets_without_credentials { + use aws_smithy_client::dvr::ReplayingConnection; + use aws_smithy_protocol_test::MediaType; + use aws_smithy_runtime::test_util::capture_test_logs::capture_test_logs; + + #[tokio::test] + async fn list_objects() { + let _logs = capture_test_logs(); + + let conn = ReplayingConnection::from_file("tests/data/no_auth/list-objects.json").unwrap(); + let config = aws_config::from_env() + .http_connector(conn.clone()) + .no_credentials() + .region("us-east-1") + .load() + .await; + let client = aws_sdk_s3::Client::new(&config); + + let result = client + .list_objects() + .bucket("gdc-organoid-pancreatic-phs001611-2-open") + .max_keys(3) + .customize() + .await + .unwrap() + .remove_invocation_id_for_tests() + .user_agent_for_tests() + .send() + .await; + dbg!(result).expect("success"); + + conn.validate_body_and_headers(None, MediaType::Xml) + .await + .unwrap(); + } + + #[tokio::test] + async fn list_objects_v2() { + let _logs = capture_test_logs(); + + let conn = + ReplayingConnection::from_file("tests/data/no_auth/list-objects-v2.json").unwrap(); + let config = aws_config::from_env() + .http_connector(conn.clone()) + .no_credentials() + .region("us-east-1") + .load() + .await; + let client = aws_sdk_s3::Client::new(&config); + + let result = client + .list_objects_v2() + .bucket("gdc-organoid-pancreatic-phs001611-2-open") + .max_keys(3) + .customize() + .await + .unwrap() + .remove_invocation_id_for_tests() + .user_agent_for_tests() + .send() + .await; + dbg!(result).expect("success"); + + conn.validate_body_and_headers(None, MediaType::Xml) + .await + .unwrap(); + } + + #[tokio::test] + async fn head_object() { + let _logs = capture_test_logs(); + + let conn = ReplayingConnection::from_file("tests/data/no_auth/head-object.json").unwrap(); + let config = aws_config::from_env() + .http_connector(conn.clone()) + .no_credentials() + .region("us-east-1") + .load() + .await; + let client = aws_sdk_s3::Client::new(&config); + + let result = client + .head_object() + .bucket("gdc-organoid-pancreatic-phs001611-2-open") + .key("0431cddc-a418-4a79-a34d-6c041394e8e4/a6ddcc84-8e4d-4c68-885c-2d51168eec97.FPKM-UQ.txt.gz") + .customize() + .await + .unwrap() + .remove_invocation_id_for_tests() + .user_agent_for_tests() + .send() + .await; + dbg!(result).expect("success"); + + conn.validate_body_and_headers(None, MediaType::Xml) + .await + .unwrap(); + } + + #[tokio::test] + async fn get_object() { + let _logs = capture_test_logs(); + + let conn = ReplayingConnection::from_file("tests/data/no_auth/get-object.json").unwrap(); + let config = aws_config::from_env() + .http_connector(conn.clone()) + .no_credentials() + .region("us-east-1") + .load() + .await; + let client = aws_sdk_s3::Client::new(&config); + + let result = client + .get_object() + .bucket("gdc-organoid-pancreatic-phs001611-2-open") + .key("0431cddc-a418-4a79-a34d-6c041394e8e4/a6ddcc84-8e4d-4c68-885c-2d51168eec97.FPKM-UQ.txt.gz") + .customize() + .await + .unwrap() + .remove_invocation_id_for_tests() + .user_agent_for_tests() + .send() + .await; + dbg!(result).expect("success"); + + conn.validate_body_and_headers(None, MediaType::Xml) + .await + .unwrap(); + } +} diff --git a/rust-runtime/aws-smithy-runtime/src/client/orchestrator/auth.rs b/rust-runtime/aws-smithy-runtime/src/client/orchestrator/auth.rs index 71a9b04873..ae17780979 100644 --- a/rust-runtime/aws-smithy-runtime/src/client/orchestrator/auth.rs +++ b/rust-runtime/aws-smithy-runtime/src/client/orchestrator/auth.rs @@ -3,6 +3,7 @@ * SPDX-License-Identifier: Apache-2.0 */ +use crate::client::auth::no_auth::NO_AUTH_SCHEME_ID; use aws_smithy_runtime_api::box_error::BoxError; use aws_smithy_runtime_api::client::auth::{ AuthScheme, AuthSchemeEndpointConfig, AuthSchemeId, AuthSchemeOptionResolver, @@ -124,10 +125,15 @@ fn extract_endpoint_auth_scheme_config( endpoint: &Endpoint, scheme_id: AuthSchemeId, ) -> Result, AuthOrchestrationError> { + // TODO(P96049742): Endpoint config doesn't currently have a concept of optional auth or "no auth", so + // we are short-circuiting lookup of endpoint auth scheme config if that is the selected scheme. + if scheme_id == NO_AUTH_SCHEME_ID { + return Ok(AuthSchemeEndpointConfig::empty()); + } let auth_schemes = match endpoint.properties().get("authSchemes") { Some(Document::Array(schemes)) => schemes, // no auth schemes: - None => return Ok(AuthSchemeEndpointConfig::from(None)), + None => return Ok(AuthSchemeEndpointConfig::empty()), _other => { return Err(AuthOrchestrationError::BadAuthSchemeEndpointConfig( "expected an array for `authSchemes` in endpoint config".into(),