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 diff --git a/CHANGELOG.next.toml b/CHANGELOG.next.toml index d371a7c012..e0ea56e68b 100644 --- a/CHANGELOG.next.toml +++ b/CHANGELOG.next.toml @@ -28,3 +28,9 @@ message = "Fix incorrect summary docs for builders" references = ["smithy-rs#2914", "aws-sdk-rust#825"] meta = { "breaking" = false, "tada" = false, "bug" = true, "target" = "client" } author = "rcoh" + +[[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/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. """, ) } 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(),