From cf7cf0ec9641880372c7b59ef44b175aeee348f2 Mon Sep 17 00:00:00 2001 From: Eduardo Rodrigues Date: Mon, 26 Dec 2022 03:01:45 +0100 Subject: [PATCH 01/38] feat(aws-types): add api key to configuration --- aws/rust-runtime/aws-types/src/sdk_config.rs | 25 ++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/aws/rust-runtime/aws-types/src/sdk_config.rs b/aws/rust-runtime/aws-types/src/sdk_config.rs index c714276c52..e00e6716fb 100644 --- a/aws/rust-runtime/aws-types/src/sdk_config.rs +++ b/aws/rust-runtime/aws-types/src/sdk_config.rs @@ -28,6 +28,7 @@ pub struct SdkConfig { credentials_provider: Option, region: Option, endpoint_resolver: Option>, + api_key: Option, retry_config: Option, sleep_impl: Option>, timeout_config: Option, @@ -45,6 +46,7 @@ pub struct Builder { credentials_provider: Option, region: Option, endpoint_resolver: Option>, + api_key: Option, retry_config: Option, sleep_impl: Option>, timeout_config: Option, @@ -131,6 +133,23 @@ impl Builder { self } + /// Set the api key to use when making requests. + /// # Examples + /// ``` + /// use aws_types::SdkConfig; + /// let config = SdkConfig::builder().api_key("some-api-key").build(); + /// ``` + pub fn api_key(mut self, api_key: impl Into) -> Self { + self.set_api_key(Some(api_key.into())); + self + } + + /// Set the api key to use when making requests. + pub fn set_api_key(&mut self, api_key: Option) -> &mut Self { + self.api_key = api_key; + self + } + /// Set the retry_config for the builder /// /// _Note:_ Retries require a sleep implementation in order to work. When enabling retry, make @@ -446,6 +465,7 @@ impl Builder { credentials_provider: self.credentials_provider, region: self.region, endpoint_resolver: self.endpoint_resolver, + api_key: self.api_key, retry_config: self.retry_config, sleep_impl: self.sleep_impl, timeout_config: self.timeout_config, @@ -465,6 +485,11 @@ impl SdkConfig { self.endpoint_resolver.clone() } + /// Configured API key + pub fn api_key(&self) -> Option<&String> { + self.api_key.as_ref() + } + /// Configured retry config pub fn retry_config(&self) -> Option<&RetryConfig> { self.retry_config.as_ref() From da660fcf160e24605ebe082deb6f339213926340 Mon Sep 17 00:00:00 2001 From: Eduardo Rodrigues Date: Mon, 26 Dec 2022 03:49:23 +0100 Subject: [PATCH 02/38] chore: set package version to 0.52.0 --- aws/rust-runtime/aws-config/Cargo.toml | 2 +- aws/rust-runtime/aws-endpoint/Cargo.toml | 2 +- aws/rust-runtime/aws-http/Cargo.toml | 2 +- aws/rust-runtime/aws-hyper/Cargo.toml | 2 +- aws/rust-runtime/aws-inlineable/Cargo.toml | 2 +- aws/rust-runtime/aws-sig-auth/Cargo.toml | 2 +- aws/rust-runtime/aws-sigv4/Cargo.toml | 2 +- aws/rust-runtime/aws-types/Cargo.toml | 2 +- rust-runtime/aws-smithy-async/Cargo.toml | 2 +- rust-runtime/aws-smithy-checksums/Cargo.toml | 2 +- rust-runtime/aws-smithy-client/Cargo.toml | 2 +- rust-runtime/aws-smithy-eventstream/Cargo.toml | 2 +- rust-runtime/aws-smithy-http-server-python/Cargo.toml | 2 +- rust-runtime/aws-smithy-http-server/Cargo.toml | 2 +- rust-runtime/aws-smithy-http-tower/Cargo.toml | 2 +- rust-runtime/aws-smithy-http/Cargo.toml | 2 +- rust-runtime/aws-smithy-json/Cargo.toml | 2 +- rust-runtime/aws-smithy-protocol-test/Cargo.toml | 2 +- rust-runtime/aws-smithy-query/Cargo.toml | 2 +- rust-runtime/aws-smithy-types-convert/Cargo.toml | 2 +- rust-runtime/aws-smithy-types/Cargo.toml | 2 +- rust-runtime/aws-smithy-xml/Cargo.toml | 2 +- rust-runtime/inlineable/Cargo.toml | 2 +- 23 files changed, 23 insertions(+), 23 deletions(-) diff --git a/aws/rust-runtime/aws-config/Cargo.toml b/aws/rust-runtime/aws-config/Cargo.toml index 5e6727da45..44e21b1ad3 100644 --- a/aws/rust-runtime/aws-config/Cargo.toml +++ b/aws/rust-runtime/aws-config/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "aws-config" -version = "0.0.0-smithy-rs-head" +version = "0.52.0" authors = ["AWS Rust SDK Team ", "Russell Cohen "] description = "AWS SDK config and credential provider implementations." edition = "2021" diff --git a/aws/rust-runtime/aws-endpoint/Cargo.toml b/aws/rust-runtime/aws-endpoint/Cargo.toml index 67cb4d4e6e..577bedd7b6 100644 --- a/aws/rust-runtime/aws-endpoint/Cargo.toml +++ b/aws/rust-runtime/aws-endpoint/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "aws-endpoint" -version = "0.0.0-smithy-rs-head" +version = "0.52.0" authors = ["AWS Rust SDK Team ", "Russell Cohen "] description = "AWS SDK endpoint support." edition = "2021" diff --git a/aws/rust-runtime/aws-http/Cargo.toml b/aws/rust-runtime/aws-http/Cargo.toml index a20a7edac7..5ce6988e24 100644 --- a/aws/rust-runtime/aws-http/Cargo.toml +++ b/aws/rust-runtime/aws-http/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "aws-http" -version = "0.0.0-smithy-rs-head" +version = "0.52.0" authors = ["AWS Rust SDK Team ", "Russell Cohen "] description = "HTTP specific AWS SDK behaviors." edition = "2021" diff --git a/aws/rust-runtime/aws-hyper/Cargo.toml b/aws/rust-runtime/aws-hyper/Cargo.toml index e7eb87f3de..91b0f96b7a 100644 --- a/aws/rust-runtime/aws-hyper/Cargo.toml +++ b/aws/rust-runtime/aws-hyper/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "aws-hyper" -version = "0.0.0-smithy-rs-head" +version = "0.52.0" authors = ["AWS Rust SDK Team ", "Russell Cohen "] description = "This crate has been removed and is deprecated." edition = "2021" diff --git a/aws/rust-runtime/aws-inlineable/Cargo.toml b/aws/rust-runtime/aws-inlineable/Cargo.toml index b20b25c20a..f88f89151e 100644 --- a/aws/rust-runtime/aws-inlineable/Cargo.toml +++ b/aws/rust-runtime/aws-inlineable/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "aws-inlineable" -version = "0.0.0-smithy-rs-head" +version = "0.52.0" authors = ["AWS Rust SDK Team ", "Russell Cohen "] description = """ The modules of this crate are intended to be inlined directly into the SDK as needed. The dependencies here diff --git a/aws/rust-runtime/aws-sig-auth/Cargo.toml b/aws/rust-runtime/aws-sig-auth/Cargo.toml index 1d8966d162..97b0ec9c7e 100644 --- a/aws/rust-runtime/aws-sig-auth/Cargo.toml +++ b/aws/rust-runtime/aws-sig-auth/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "aws-sig-auth" -version = "0.0.0-smithy-rs-head" +version = "0.52.0" authors = ["AWS Rust SDK Team ", "Russell Cohen "] description = "SigV4 signing middleware for the AWS SDK." edition = "2021" diff --git a/aws/rust-runtime/aws-sigv4/Cargo.toml b/aws/rust-runtime/aws-sigv4/Cargo.toml index ad1570bb86..793c6e0ed7 100644 --- a/aws/rust-runtime/aws-sigv4/Cargo.toml +++ b/aws/rust-runtime/aws-sigv4/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "aws-sigv4" -version = "0.0.0-smithy-rs-head" +version = "0.52.0" authors = ["AWS Rust SDK Team ", "David Barsky "] description = "SigV4 signer for HTTP requests and Event Stream messages." edition = "2021" diff --git a/aws/rust-runtime/aws-types/Cargo.toml b/aws/rust-runtime/aws-types/Cargo.toml index 755ccdba07..87f10bf1eb 100644 --- a/aws/rust-runtime/aws-types/Cargo.toml +++ b/aws/rust-runtime/aws-types/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "aws-types" -version = "0.0.0-smithy-rs-head" +version = "0.52.0" authors = ["AWS Rust SDK Team ", "Russell Cohen "] description = "Cross-service types for the AWS SDK." edition = "2021" diff --git a/rust-runtime/aws-smithy-async/Cargo.toml b/rust-runtime/aws-smithy-async/Cargo.toml index 04d600ea62..9cd6c0eb95 100644 --- a/rust-runtime/aws-smithy-async/Cargo.toml +++ b/rust-runtime/aws-smithy-async/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "aws-smithy-async" -version = "0.0.0-smithy-rs-head" +version = "0.52.0" authors = ["AWS Rust SDK Team ", "John DiSanti "] description = "Async runtime agnostic abstractions for smithy-rs." edition = "2021" diff --git a/rust-runtime/aws-smithy-checksums/Cargo.toml b/rust-runtime/aws-smithy-checksums/Cargo.toml index b210360d55..1036016c69 100644 --- a/rust-runtime/aws-smithy-checksums/Cargo.toml +++ b/rust-runtime/aws-smithy-checksums/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "aws-smithy-checksums" -version = "0.0.0-smithy-rs-head" +version = "0.52.0" authors = [ "AWS Rust SDK Team ", "Zelda Hessler ", diff --git a/rust-runtime/aws-smithy-client/Cargo.toml b/rust-runtime/aws-smithy-client/Cargo.toml index f184552dac..7efd5fcc7b 100644 --- a/rust-runtime/aws-smithy-client/Cargo.toml +++ b/rust-runtime/aws-smithy-client/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "aws-smithy-client" -version = "0.0.0-smithy-rs-head" +version = "0.52.0" authors = ["AWS Rust SDK Team ", "Russell Cohen "] description = "Client for smithy-rs." edition = "2021" diff --git a/rust-runtime/aws-smithy-eventstream/Cargo.toml b/rust-runtime/aws-smithy-eventstream/Cargo.toml index a77aff9e85..d2fc258ae7 100644 --- a/rust-runtime/aws-smithy-eventstream/Cargo.toml +++ b/rust-runtime/aws-smithy-eventstream/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "aws-smithy-eventstream" -version = "0.0.0-smithy-rs-head" +version = "0.52.0" authors = ["AWS Rust SDK Team ", "John DiSanti "] description = "Event stream logic for smithy-rs." edition = "2021" diff --git a/rust-runtime/aws-smithy-http-server-python/Cargo.toml b/rust-runtime/aws-smithy-http-server-python/Cargo.toml index 8085e000b4..fc0bcebf00 100644 --- a/rust-runtime/aws-smithy-http-server-python/Cargo.toml +++ b/rust-runtime/aws-smithy-http-server-python/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "aws-smithy-http-server-python" -version = "0.0.0-smithy-rs-head" +version = "0.52.0" authors = ["Smithy Rust Server "] edition = "2021" license = "Apache-2.0" diff --git a/rust-runtime/aws-smithy-http-server/Cargo.toml b/rust-runtime/aws-smithy-http-server/Cargo.toml index 4497eb8806..41be781be8 100644 --- a/rust-runtime/aws-smithy-http-server/Cargo.toml +++ b/rust-runtime/aws-smithy-http-server/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "aws-smithy-http-server" -version = "0.0.0-smithy-rs-head" +version = "0.52.0" authors = ["Smithy Rust Server "] edition = "2021" license = "Apache-2.0" diff --git a/rust-runtime/aws-smithy-http-tower/Cargo.toml b/rust-runtime/aws-smithy-http-tower/Cargo.toml index e74934119b..6482b42627 100644 --- a/rust-runtime/aws-smithy-http-tower/Cargo.toml +++ b/rust-runtime/aws-smithy-http-tower/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "aws-smithy-http-tower" -version = "0.0.0-smithy-rs-head" +version = "0.52.0" authors = ["AWS Rust SDK Team ", "Russell Cohen "] description = "Tower-compatible shims for smithy-rs middleware." edition = "2021" diff --git a/rust-runtime/aws-smithy-http/Cargo.toml b/rust-runtime/aws-smithy-http/Cargo.toml index 23bb28437d..f76591d93c 100644 --- a/rust-runtime/aws-smithy-http/Cargo.toml +++ b/rust-runtime/aws-smithy-http/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "aws-smithy-http" -version = "0.0.0-smithy-rs-head" +version = "0.52.0" authors = [ "AWS Rust SDK Team ", "Russell Cohen ", diff --git a/rust-runtime/aws-smithy-json/Cargo.toml b/rust-runtime/aws-smithy-json/Cargo.toml index 3ad4d2225f..5dbaa9741d 100644 --- a/rust-runtime/aws-smithy-json/Cargo.toml +++ b/rust-runtime/aws-smithy-json/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "aws-smithy-json" -version = "0.0.0-smithy-rs-head" +version = "0.52.0" authors = ["AWS Rust SDK Team ", "John DiSanti "] description = "Token streaming JSON parser for smithy-rs." edition = "2021" diff --git a/rust-runtime/aws-smithy-protocol-test/Cargo.toml b/rust-runtime/aws-smithy-protocol-test/Cargo.toml index b4d5bb516b..13cfa9496a 100644 --- a/rust-runtime/aws-smithy-protocol-test/Cargo.toml +++ b/rust-runtime/aws-smithy-protocol-test/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "aws-smithy-protocol-test" -version = "0.0.0-smithy-rs-head" +version = "0.52.0" authors = ["AWS Rust SDK Team ", "Russell Cohen "] description = "A collection of library functions to validate HTTP requests against Smithy protocol tests." edition = "2021" diff --git a/rust-runtime/aws-smithy-query/Cargo.toml b/rust-runtime/aws-smithy-query/Cargo.toml index a4f517ae2a..ec9f7f4085 100644 --- a/rust-runtime/aws-smithy-query/Cargo.toml +++ b/rust-runtime/aws-smithy-query/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "aws-smithy-query" -version = "0.0.0-smithy-rs-head" +version = "0.52.0" authors = ["AWS Rust SDK Team ", "John DiSanti "] description = "AWSQuery and EC2Query Smithy protocol logic for smithy-rs." edition = "2021" diff --git a/rust-runtime/aws-smithy-types-convert/Cargo.toml b/rust-runtime/aws-smithy-types-convert/Cargo.toml index c9ffbd22a0..8bbc0de5f6 100644 --- a/rust-runtime/aws-smithy-types-convert/Cargo.toml +++ b/rust-runtime/aws-smithy-types-convert/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "aws-smithy-types-convert" -version = "0.0.0-smithy-rs-head" +version = "0.52.0" authors = ["AWS Rust SDK Team "] description = "Conversion of types from aws-smithy-types to other libraries." edition = "2021" diff --git a/rust-runtime/aws-smithy-types/Cargo.toml b/rust-runtime/aws-smithy-types/Cargo.toml index 12049c3af8..cf32022bc5 100644 --- a/rust-runtime/aws-smithy-types/Cargo.toml +++ b/rust-runtime/aws-smithy-types/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "aws-smithy-types" -version = "0.0.0-smithy-rs-head" +version = "0.52.0" authors = ["AWS Rust SDK Team ", "Russell Cohen "] description = "Types for smithy-rs codegen." edition = "2021" diff --git a/rust-runtime/aws-smithy-xml/Cargo.toml b/rust-runtime/aws-smithy-xml/Cargo.toml index 1563fa0ed7..9aa92f038d 100644 --- a/rust-runtime/aws-smithy-xml/Cargo.toml +++ b/rust-runtime/aws-smithy-xml/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "aws-smithy-xml" -version = "0.0.0-smithy-rs-head" +version = "0.52.0" authors = ["AWS Rust SDK Team ", "Russell Cohen "] description = "XML parsing logic for Smithy protocols." edition = "2021" diff --git a/rust-runtime/inlineable/Cargo.toml b/rust-runtime/inlineable/Cargo.toml index b76a17e5e7..96718bd10b 100644 --- a/rust-runtime/inlineable/Cargo.toml +++ b/rust-runtime/inlineable/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "inlineable" -version = "0.0.0-smithy-rs-head" +version = "0.52.0" authors = ["AWS Rust SDK Team ", "Russell Cohen "] edition = "2021" description = """ From d8750e23881666cd67b8cb20b23bbee72755fbca Mon Sep 17 00:00:00 2001 From: Eduardo Rodrigues Date: Mon, 26 Dec 2022 04:40:18 +0100 Subject: [PATCH 03/38] feat(aws-smithy-types): create auth types --- rust-runtime/aws-smithy-types/src/auth.rs | 36 +++++++++++++++++++++++ rust-runtime/aws-smithy-types/src/lib.rs | 1 + 2 files changed, 37 insertions(+) create mode 100644 rust-runtime/aws-smithy-types/src/auth.rs diff --git a/rust-runtime/aws-smithy-types/src/auth.rs b/rust-runtime/aws-smithy-types/src/auth.rs new file mode 100644 index 0000000000..165324b6ec --- /dev/null +++ b/rust-runtime/aws-smithy-types/src/auth.rs @@ -0,0 +1,36 @@ +/* + * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. + * SPDX-License-Identifier: Apache-2.0 + */ +//! Smithy HTTP Auth Types + +use std::fmt::Debug; + +/// Authentication configuration to connect to an Smithy Service +#[derive(Clone, Debug)] +pub struct AuthApiKey { + api_key: String, +} + +impl AuthApiKey { + /// Constructs a new API key. + pub fn new(api_key: String) -> AuthApiKey { + AuthApiKey { + api_key, + } + } + + /// Returns the underlying api key. + pub fn api_key(self) -> String { + self.api_key + } + + /// Sets the value for the api key + pub fn set_api_key( + mut self, + api_key: impl Into, + ) -> Self { + self.api_key = api_key.into(); + self + } +} diff --git a/rust-runtime/aws-smithy-types/src/lib.rs b/rust-runtime/aws-smithy-types/src/lib.rs index f2729cefa1..07ec501fe7 100644 --- a/rust-runtime/aws-smithy-types/src/lib.rs +++ b/rust-runtime/aws-smithy-types/src/lib.rs @@ -16,6 +16,7 @@ use crate::error::{TryFromNumberError, TryFromNumberErrorKind}; use std::collections::HashMap; +pub mod auth; pub mod base64; pub mod date_time; pub mod endpoint; From 05deb97ca5c8df51c5377f9781874d31b2d48ba3 Mon Sep 17 00:00:00 2001 From: Eduardo Rodrigues Date: Mon, 26 Dec 2022 04:40:58 +0100 Subject: [PATCH 04/38] chore: use auth from smithy types --- aws/rust-runtime/aws-types/src/sdk_config.rs | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/aws/rust-runtime/aws-types/src/sdk_config.rs b/aws/rust-runtime/aws-types/src/sdk_config.rs index e00e6716fb..7cacf6548f 100644 --- a/aws/rust-runtime/aws-types/src/sdk_config.rs +++ b/aws/rust-runtime/aws-types/src/sdk_config.rs @@ -13,6 +13,7 @@ use std::sync::Arc; use aws_smithy_async::rt::sleep::AsyncSleep; use aws_smithy_client::http_connector::HttpConnector; +use aws_smithy_types::auth::AuthApiKey; use aws_smithy_types::retry::RetryConfig; use aws_smithy_types::timeout::TimeoutConfig; @@ -28,7 +29,7 @@ pub struct SdkConfig { credentials_provider: Option, region: Option, endpoint_resolver: Option>, - api_key: Option, + api_key: Option, retry_config: Option, sleep_impl: Option>, timeout_config: Option, @@ -46,7 +47,7 @@ pub struct Builder { credentials_provider: Option, region: Option, endpoint_resolver: Option>, - api_key: Option, + api_key: Option, retry_config: Option, sleep_impl: Option>, timeout_config: Option, @@ -139,14 +140,14 @@ impl Builder { /// use aws_types::SdkConfig; /// let config = SdkConfig::builder().api_key("some-api-key").build(); /// ``` - pub fn api_key(mut self, api_key: impl Into) -> Self { - self.set_api_key(Some(api_key.into())); + pub fn api_key(&mut self, api_key: impl Into>) -> &mut self { + self.api_key = api_key.into(); self } /// Set the api key to use when making requests. - pub fn set_api_key(&mut self, api_key: Option) -> &mut Self { - self.api_key = api_key; + pub fn set_api_key(&mut self, api_key: impl Into>) -> &mut Self { + self.api_key = api_key.into(); self } @@ -486,7 +487,7 @@ impl SdkConfig { } /// Configured API key - pub fn api_key(&self) -> Option<&String> { + pub fn api_key(&self) -> Option<&AuthApiKey> { self.api_key.as_ref() } From 8ba9a1ca2b3fc07d3b90eee58fb58014bab661dc Mon Sep 17 00:00:00 2001 From: Eduardo Rodrigues Date: Mon, 26 Dec 2022 04:44:34 +0100 Subject: [PATCH 05/38] chore: fix return self type --- aws/rust-runtime/aws-types/src/sdk_config.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/aws/rust-runtime/aws-types/src/sdk_config.rs b/aws/rust-runtime/aws-types/src/sdk_config.rs index 7cacf6548f..5f28ac7ec1 100644 --- a/aws/rust-runtime/aws-types/src/sdk_config.rs +++ b/aws/rust-runtime/aws-types/src/sdk_config.rs @@ -140,7 +140,7 @@ impl Builder { /// use aws_types::SdkConfig; /// let config = SdkConfig::builder().api_key("some-api-key").build(); /// ``` - pub fn api_key(&mut self, api_key: impl Into>) -> &mut self { + pub fn api_key(&mut self, api_key: impl Into>) -> &mut Self { self.api_key = api_key.into(); self } From 3a10084ac0f5ae2c85058765e7c5917fe2d18bb7 Mon Sep 17 00:00:00 2001 From: Eduardo Rodrigues Date: Thu, 29 Dec 2022 13:47:42 +0100 Subject: [PATCH 06/38] chore: create http auth definition type --- rust-runtime/aws-smithy-types/src/auth.rs | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/rust-runtime/aws-smithy-types/src/auth.rs b/rust-runtime/aws-smithy-types/src/auth.rs index 165324b6ec..abb064a646 100644 --- a/rust-runtime/aws-smithy-types/src/auth.rs +++ b/rust-runtime/aws-smithy-types/src/auth.rs @@ -34,3 +34,23 @@ impl AuthApiKey { self } } + +/// An HTTP-specific authentication scheme that sends an arbitrary +/// auth value in a header or query string parameter. +// As described in the Smithy documentation: +// https://github.com/awslabs/smithy/blob/main/smithy-model/src/main/resources/software/amazon/smithy/model/loader/prelude.smithy +#[derive(Clone, Debug)] +#[allow(dead_code)] +pub struct HttpAuthDefinition { + /// Defines the location of where the Auth is serialized. This value + /// can be set to `"header"` or `"query"`. + location: String, + + /// Defines the name of the HTTP header or query string parameter + /// that contains the Auth. + name: String, + + /// Defines the security scheme to use on the `Authorization` header value. + /// This can only be set if the "in" property is set to `"header"`. + scheme: Option, +} From c8f67018dff4bd56ff8084a4259a18711c01e3af Mon Sep 17 00:00:00 2001 From: Eduardo Rodrigues Date: Fri, 30 Dec 2022 00:02:02 +0100 Subject: [PATCH 07/38] chore: add constructor for http auth definition --- rust-runtime/aws-smithy-types/src/auth.rs | 67 ++++++++++++++++++++++- 1 file changed, 64 insertions(+), 3 deletions(-) diff --git a/rust-runtime/aws-smithy-types/src/auth.rs b/rust-runtime/aws-smithy-types/src/auth.rs index abb064a646..05e755fe0e 100644 --- a/rust-runtime/aws-smithy-types/src/auth.rs +++ b/rust-runtime/aws-smithy-types/src/auth.rs @@ -5,6 +5,7 @@ //! Smithy HTTP Auth Types use std::fmt::Debug; +use std::cmp::PartialEq; /// Authentication configuration to connect to an Smithy Service #[derive(Clone, Debug)] @@ -14,8 +15,8 @@ pub struct AuthApiKey { impl AuthApiKey { /// Constructs a new API key. - pub fn new(api_key: String) -> AuthApiKey { - AuthApiKey { + pub fn new(api_key: String) -> Self { + Self { api_key, } } @@ -40,7 +41,6 @@ impl AuthApiKey { // As described in the Smithy documentation: // https://github.com/awslabs/smithy/blob/main/smithy-model/src/main/resources/software/amazon/smithy/model/loader/prelude.smithy #[derive(Clone, Debug)] -#[allow(dead_code)] pub struct HttpAuthDefinition { /// Defines the location of where the Auth is serialized. This value /// can be set to `"header"` or `"query"`. @@ -54,3 +54,64 @@ pub struct HttpAuthDefinition { /// This can only be set if the "in" property is set to `"header"`. scheme: Option, } + +impl HttpAuthDefinition { + /// Constructs a new HTTP auth definition. + pub fn new(location: String, name: String, scheme: Option) -> Self { + Self { + location, + name, + scheme, + } + } + + /// Returns the HTTP auth location. + pub fn location(self) -> String { + self.location + } + + /// Sets the value for HTTP auth location. + pub fn set_location( + mut self, + location: impl Into + std::cmp::PartialEq + Debug, + ) -> Self { + if location != "header".to_string() && location != "query".to_string() { + panic!("Location not allowed: Got: {:?}. Expected: `header` or `query`", location); + } + self.location = location.into(); + self + } + + /// Returns the HTTP auth name. + pub fn name(self) -> String { + self.name + } + + /// Sets the value for HTTP auth name. + pub fn set_name( + mut self, + name: impl Into, + ) -> Self { + self.name = name.into(); + self + } + + /// Returns the HTTP auth scheme. + pub fn scheme(self) -> Option { + self.scheme + } + + /// Sets the value for HTTP auth scheme. + pub fn set_scheme( + mut self, + scheme: impl Into, + ) -> Self { + if self.location.eq("header") && self.name.eq_ignore_ascii_case("authorization") { + self.scheme = Some(scheme.into()); + println!("Scheme can only be set when it is set into the `Authorization header`."); + } else { + self.scheme = None + } + self + } +} From cba79fbda5807b7ea97c45f7c505541a731f16d0 Mon Sep 17 00:00:00 2001 From: Eduardo Rodrigues Date: Fri, 30 Dec 2022 21:56:44 +0100 Subject: [PATCH 08/38] chore: ensure properties are not moved --- rust-runtime/aws-smithy-types/src/auth.rs | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/rust-runtime/aws-smithy-types/src/auth.rs b/rust-runtime/aws-smithy-types/src/auth.rs index 05e755fe0e..e75131528c 100644 --- a/rust-runtime/aws-smithy-types/src/auth.rs +++ b/rust-runtime/aws-smithy-types/src/auth.rs @@ -22,8 +22,8 @@ impl AuthApiKey { } /// Returns the underlying api key. - pub fn api_key(self) -> String { - self.api_key + pub fn api_key(&self) -> &str { + &self.api_key } /// Sets the value for the api key @@ -66,8 +66,8 @@ impl HttpAuthDefinition { } /// Returns the HTTP auth location. - pub fn location(self) -> String { - self.location + pub fn location(&self) -> &str { + &self.location } /// Sets the value for HTTP auth location. @@ -83,8 +83,8 @@ impl HttpAuthDefinition { } /// Returns the HTTP auth name. - pub fn name(self) -> String { - self.name + pub fn name(&self) -> &str { + &self.name } /// Sets the value for HTTP auth name. @@ -97,8 +97,8 @@ impl HttpAuthDefinition { } /// Returns the HTTP auth scheme. - pub fn scheme(self) -> Option { - self.scheme + pub fn scheme(&self) -> &Option { + &self.scheme } /// Sets the value for HTTP auth scheme. From b3b8d7e4c49303519f7c2ca0c331adf9132023a2 Mon Sep 17 00:00:00 2001 From: Eduardo Rodrigues Date: Fri, 30 Dec 2022 22:21:17 +0100 Subject: [PATCH 09/38] chore: create convenience constructors --- rust-runtime/aws-smithy-types/src/auth.rs | 63 +++++++++++++---------- 1 file changed, 37 insertions(+), 26 deletions(-) diff --git a/rust-runtime/aws-smithy-types/src/auth.rs b/rust-runtime/aws-smithy-types/src/auth.rs index e75131528c..12b04539e0 100644 --- a/rust-runtime/aws-smithy-types/src/auth.rs +++ b/rust-runtime/aws-smithy-types/src/auth.rs @@ -4,8 +4,8 @@ */ //! Smithy HTTP Auth Types -use std::fmt::Debug; use std::cmp::PartialEq; +use std::fmt::Debug; /// Authentication configuration to connect to an Smithy Service #[derive(Clone, Debug)] @@ -16,9 +16,7 @@ pub struct AuthApiKey { impl AuthApiKey { /// Constructs a new API key. pub fn new(api_key: String) -> Self { - Self { - api_key, - } + Self { api_key } } /// Returns the underlying api key. @@ -27,10 +25,7 @@ impl AuthApiKey { } /// Sets the value for the api key - pub fn set_api_key( - mut self, - api_key: impl Into, - ) -> Self { + pub fn set_api_key(mut self, api_key: impl Into) -> Self { self.api_key = api_key.into(); self } @@ -42,22 +37,22 @@ impl AuthApiKey { // https://github.com/awslabs/smithy/blob/main/smithy-model/src/main/resources/software/amazon/smithy/model/loader/prelude.smithy #[derive(Clone, Debug)] pub struct HttpAuthDefinition { - /// Defines the location of where the Auth is serialized. This value + /// Defines the location of where the Auth is serialized. This value /// can be set to `"header"` or `"query"`. - location: String, + location: String, - /// Defines the name of the HTTP header or query string parameter - /// that contains the Auth. - name: String, + /// Defines the name of the HTTP header or query string parameter + /// that contains the Auth. + name: String, - /// Defines the security scheme to use on the `Authorization` header value. - /// This can only be set if the "in" property is set to `"header"`. - scheme: Option, + /// Defines the security scheme to use on the `Authorization` header value. + /// This can only be set if the "in" property is set to `"header"`. + scheme: Option, } impl HttpAuthDefinition { /// Constructs a new HTTP auth definition. - pub fn new(location: String, name: String, scheme: Option) -> Self { + fn new(location: String, name: String, scheme: Option) -> Self { Self { location, name, @@ -65,6 +60,25 @@ impl HttpAuthDefinition { } } + /// Constructs a new HTTP auth definition in header. + pub fn new_with_header(name: String, scheme: Option) -> Self { + HttpAuthDefinition::new("header".to_owned(), name, scheme) + } + + /// Constructs a new HTTP auth definition following the RFC 6750 for Bearer Auth. + pub fn new_with_bearer_auth() -> Self { + HttpAuthDefinition::new( + "header".to_owned(), + "Authorization".to_owned(), + Some("Bearer".to_owned()), + ) + } + + /// Constructs a new HTTP auth definition in header. + pub fn new_with_query(name: String) -> Self { + HttpAuthDefinition::new("query".to_owned(), name, None) + } + /// Returns the HTTP auth location. pub fn location(&self) -> &str { &self.location @@ -76,7 +90,10 @@ impl HttpAuthDefinition { location: impl Into + std::cmp::PartialEq + Debug, ) -> Self { if location != "header".to_string() && location != "query".to_string() { - panic!("Location not allowed: Got: {:?}. Expected: `header` or `query`", location); + panic!( + "Location not allowed: Got: {:?}. Expected: `header` or `query`", + location + ); } self.location = location.into(); self @@ -88,10 +105,7 @@ impl HttpAuthDefinition { } /// Sets the value for HTTP auth name. - pub fn set_name( - mut self, - name: impl Into, - ) -> Self { + pub fn set_name(mut self, name: impl Into) -> Self { self.name = name.into(); self } @@ -102,10 +116,7 @@ impl HttpAuthDefinition { } /// Sets the value for HTTP auth scheme. - pub fn set_scheme( - mut self, - scheme: impl Into, - ) -> Self { + pub fn set_scheme(mut self, scheme: impl Into) -> Self { if self.location.eq("header") && self.name.eq_ignore_ascii_case("authorization") { self.scheme = Some(scheme.into()); println!("Scheme can only be set when it is set into the `Authorization header`."); From 16bd6344d14c6c80abfe6ce6f609997799c4882c Mon Sep 17 00:00:00 2001 From: Eduardo Rodrigues Date: Sat, 31 Dec 2022 18:14:38 +0100 Subject: [PATCH 10/38] chore: add some todo comments --- rust-runtime/aws-smithy-types/src/auth.rs | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/rust-runtime/aws-smithy-types/src/auth.rs b/rust-runtime/aws-smithy-types/src/auth.rs index 12b04539e0..24358d8930 100644 --- a/rust-runtime/aws-smithy-types/src/auth.rs +++ b/rust-runtime/aws-smithy-types/src/auth.rs @@ -7,7 +7,7 @@ use std::cmp::PartialEq; use std::fmt::Debug; -/// Authentication configuration to connect to an Smithy Service +/// Authentication configuration to connect to a Smithy Service #[derive(Clone, Debug)] pub struct AuthApiKey { api_key: String, @@ -90,6 +90,7 @@ impl HttpAuthDefinition { location: impl Into + std::cmp::PartialEq + Debug, ) -> Self { if location != "header".to_string() && location != "query".to_string() { + // TODO: return auth defined error panic!( "Location not allowed: Got: {:?}. Expected: `header` or `query`", location @@ -119,8 +120,9 @@ impl HttpAuthDefinition { pub fn set_scheme(mut self, scheme: impl Into) -> Self { if self.location.eq("header") && self.name.eq_ignore_ascii_case("authorization") { self.scheme = Some(scheme.into()); - println!("Scheme can only be set when it is set into the `Authorization header`."); } else { + // TODO: return auth defined error + println!("Scheme can only be set when it is set into the `Authorization header`."); self.scheme = None } self From dae2980de162ebec401da0a02770d4899a4cb04a Mon Sep 17 00:00:00 2001 From: Eduardo Rodrigues Date: Sat, 31 Dec 2022 18:27:11 +0100 Subject: [PATCH 11/38] feat: move query writer to aws-smithy-http crate --- .../src/http_request/canonical_request.rs | 2 +- aws/rust-runtime/aws-sigv4/src/http_request/mod.rs | 1 - .../aws-sigv4/src/http_request/url_escape.rs | 6 +----- rust-runtime/aws-smithy-http/src/lib.rs | 1 + .../aws-smithy-http/src}/query_writer.rs | 14 +++++++------- 5 files changed, 10 insertions(+), 14 deletions(-) rename {aws/rust-runtime/aws-sigv4/src/http_request => rust-runtime/aws-smithy-http/src}/query_writer.rs (94%) diff --git a/aws/rust-runtime/aws-sigv4/src/http_request/canonical_request.rs b/aws/rust-runtime/aws-sigv4/src/http_request/canonical_request.rs index b1aa4f2b00..6f9cfdc436 100644 --- a/aws/rust-runtime/aws-sigv4/src/http_request/canonical_request.rs +++ b/aws/rust-runtime/aws-sigv4/src/http_request/canonical_request.rs @@ -5,7 +5,6 @@ use crate::date_time::{format_date, format_date_time}; use crate::http_request::error::CanonicalRequestError; -use crate::http_request::query_writer::QueryWriter; use crate::http_request::settings::UriPathNormalizationMode; use crate::http_request::sign::SignableRequest; use crate::http_request::uri_path_normalization::normalize_uri_path; @@ -13,6 +12,7 @@ use crate::http_request::url_escape::percent_encode_path; use crate::http_request::PercentEncodingMode; use crate::http_request::{PayloadChecksumKind, SignableBody, SignatureLocation, SigningParams}; use crate::sign::sha256_hex_string; +use aws_smithy_http::query_writer::QueryWriter; use http::header::{HeaderName, HOST}; use http::{HeaderMap, HeaderValue, Method, Uri}; use std::borrow::Cow; diff --git a/aws/rust-runtime/aws-sigv4/src/http_request/mod.rs b/aws/rust-runtime/aws-sigv4/src/http_request/mod.rs index c93a052887..543d58fb2d 100644 --- a/aws/rust-runtime/aws-sigv4/src/http_request/mod.rs +++ b/aws/rust-runtime/aws-sigv4/src/http_request/mod.rs @@ -43,7 +43,6 @@ mod canonical_request; mod error; -mod query_writer; mod settings; mod sign; mod uri_path_normalization; diff --git a/aws/rust-runtime/aws-sigv4/src/http_request/url_escape.rs b/aws/rust-runtime/aws-sigv4/src/http_request/url_escape.rs index 651c62c44a..d7656c355b 100644 --- a/aws/rust-runtime/aws-sigv4/src/http_request/url_escape.rs +++ b/aws/rust-runtime/aws-sigv4/src/http_request/url_escape.rs @@ -3,11 +3,7 @@ * SPDX-License-Identifier: Apache-2.0 */ -use aws_smithy_http::{label, query}; - -pub(super) fn percent_encode_query(value: &str) -> String { - query::fmt_string(value) -} +use aws_smithy_http::label; pub(super) fn percent_encode_path(value: &str) -> String { label::fmt_string(value, label::EncodingStrategy::Greedy) diff --git a/rust-runtime/aws-smithy-http/src/lib.rs b/rust-runtime/aws-smithy-http/src/lib.rs index 54449bf38e..5595335aa1 100644 --- a/rust-runtime/aws-smithy-http/src/lib.rs +++ b/rust-runtime/aws-smithy-http/src/lib.rs @@ -26,6 +26,7 @@ pub mod middleware; pub mod operation; pub mod property_bag; pub mod query; +pub mod query_writer; pub mod response; pub mod result; pub mod retry; diff --git a/aws/rust-runtime/aws-sigv4/src/http_request/query_writer.rs b/rust-runtime/aws-smithy-http/src/query_writer.rs similarity index 94% rename from aws/rust-runtime/aws-sigv4/src/http_request/query_writer.rs rename to rust-runtime/aws-smithy-http/src/query_writer.rs index 40a98d9aba..e94e3f02db 100644 --- a/aws/rust-runtime/aws-sigv4/src/http_request/query_writer.rs +++ b/rust-runtime/aws-smithy-http/src/query_writer.rs @@ -3,11 +3,11 @@ * SPDX-License-Identifier: Apache-2.0 */ -use crate::http_request::url_escape::percent_encode_query; +use crate::query::fmt_string as percent_encode_query; use http::Uri; /// Utility for updating the query string in a [`Uri`]. -pub(super) struct QueryWriter { +pub struct QueryWriter { base_uri: Uri, new_path_and_query: String, prefix: Option, @@ -15,7 +15,7 @@ pub(super) struct QueryWriter { impl QueryWriter { /// Creates a new `QueryWriter` based off the given `uri`. - pub(super) fn new(uri: &Uri) -> Self { + pub fn new(uri: &Uri) -> Self { let new_path_and_query = uri .path_and_query() .map(|pq| pq.to_string()) @@ -35,7 +35,7 @@ impl QueryWriter { } /// Clears all query parameters. - pub(super) fn clear_params(&mut self) { + pub fn clear_params(&mut self) { if let Some(index) = self.new_path_and_query.find('?') { self.new_path_and_query.truncate(index); self.prefix = Some('?'); @@ -44,7 +44,7 @@ impl QueryWriter { /// Inserts a new query parameter. The key and value are percent encoded /// by `QueryWriter`. Passing in percent encoded values will result in double encoding. - pub(super) fn insert(&mut self, k: &str, v: &str) { + pub fn insert(&mut self, k: &str, v: &str) { if let Some(prefix) = self.prefix { self.new_path_and_query.push(prefix); } @@ -56,12 +56,12 @@ impl QueryWriter { } /// Returns just the built query string. - pub(super) fn build_query(self) -> String { + pub fn build_query(self) -> String { self.build_uri().query().unwrap_or_default().to_string() } /// Returns a full [`Uri`] with the query string updated. - pub(super) fn build_uri(self) -> Uri { + pub fn build_uri(self) -> Uri { let mut parts = self.base_uri.into_parts(); parts.path_and_query = Some( self.new_path_and_query From d06aa3a819f52ea90267b8d8a6e61fc6ccbf665a Mon Sep 17 00:00:00 2001 From: Eduardo Rodrigues Date: Sat, 31 Dec 2022 18:28:33 +0100 Subject: [PATCH 12/38] chore(codegen): expose smithy http tower dependency --- .../amazon/smithy/rust/codegen/core/smithy/RuntimeType.kt | 1 + 1 file changed, 1 insertion(+) diff --git a/codegen-core/src/main/kotlin/software/amazon/smithy/rust/codegen/core/smithy/RuntimeType.kt b/codegen-core/src/main/kotlin/software/amazon/smithy/rust/codegen/core/smithy/RuntimeType.kt index 7d29b3c067..39eb236ef4 100644 --- a/codegen-core/src/main/kotlin/software/amazon/smithy/rust/codegen/core/smithy/RuntimeType.kt +++ b/codegen-core/src/main/kotlin/software/amazon/smithy/rust/codegen/core/smithy/RuntimeType.kt @@ -244,6 +244,7 @@ data class RuntimeType(val path: String, val dependency: RustDependency? = null) fun smithyClient(runtimeConfig: RuntimeConfig) = CargoDependency.smithyClient(runtimeConfig).toType() fun smithyEventStream(runtimeConfig: RuntimeConfig) = CargoDependency.smithyEventStream(runtimeConfig).toType() fun smithyHttp(runtimeConfig: RuntimeConfig) = CargoDependency.smithyHttp(runtimeConfig).toType() + fun smithyHttpTower(runtimeConfig: RuntimeConfig) = CargoDependency.smithyHttpTower(runtimeConfig).toType() fun smithyJson(runtimeConfig: RuntimeConfig) = CargoDependency.smithyJson(runtimeConfig).toType() fun smithyQuery(runtimeConfig: RuntimeConfig) = CargoDependency.smithyQuery(runtimeConfig).toType() fun smithyTypes(runtimeConfig: RuntimeConfig) = CargoDependency.smithyTypes(runtimeConfig).toType() From 64dd5bfb0bbc757a71739db8f7570fa5e021826d Mon Sep 17 00:00:00 2001 From: Eduardo Rodrigues Date: Sun, 1 Jan 2023 03:01:40 +0100 Subject: [PATCH 13/38] chore: remove setters for auth definition --- rust-runtime/aws-smithy-types/src/auth.rs | 85 ++++++++++++----------- 1 file changed, 43 insertions(+), 42 deletions(-) diff --git a/rust-runtime/aws-smithy-types/src/auth.rs b/rust-runtime/aws-smithy-types/src/auth.rs index 24358d8930..54170af03e 100644 --- a/rust-runtime/aws-smithy-types/src/auth.rs +++ b/rust-runtime/aws-smithy-types/src/auth.rs @@ -4,9 +4,36 @@ */ //! Smithy HTTP Auth Types -use std::cmp::PartialEq; use std::fmt::Debug; +#[derive(Debug)] +enum AuthErrorKind { + InvalidLocation, + SchemeNotAllowed, +} + +/// Error for Smithy authentication +#[derive(Debug)] +pub struct AuthError { + kind: AuthErrorKind, +} + +impl std::fmt::Display for AuthError { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + use AuthErrorKind::*; + match &self.kind { + InvalidLocation => write!(f, "invalid location: expected `header` or `query`"), + SchemeNotAllowed => write!(f, "scheme only allowed when it is set into the `Authorization header`"), + } + } +} + +impl From for AuthError { + fn from(kind: AuthErrorKind) -> Self { + Self { kind } + } +} + /// Authentication configuration to connect to a Smithy Service #[derive(Clone, Debug)] pub struct AuthApiKey { @@ -52,16 +79,24 @@ pub struct HttpAuthDefinition { impl HttpAuthDefinition { /// Constructs a new HTTP auth definition. - fn new(location: String, name: String, scheme: Option) -> Self { - Self { + fn new(location: String, name: String, scheme: Option) -> Result { + if location != "header" && location != "query" { + return Err(AuthError::from(AuthErrorKind::InvalidLocation)); + } + Ok(Self { location, name, scheme, - } + }) } /// Constructs a new HTTP auth definition in header. - pub fn new_with_header(name: String, scheme: Option) -> Self { + pub fn new_with_header(header_name: impl Into, scheme: impl Into>) -> Result { + let name: String = header_name.into(); + let scheme: Option = scheme.into(); + if scheme.is_some() && name.eq_ignore_ascii_case("authorization") { + return Err(AuthError::from(AuthErrorKind::SchemeNotAllowed)); + } HttpAuthDefinition::new("header".to_owned(), name, scheme) } @@ -71,12 +106,12 @@ impl HttpAuthDefinition { "header".to_owned(), "Authorization".to_owned(), Some("Bearer".to_owned()), - ) + ).unwrap() } /// Constructs a new HTTP auth definition in header. - pub fn new_with_query(name: String) -> Self { - HttpAuthDefinition::new("query".to_owned(), name, None) + pub fn new_with_query(name: impl Into) -> Result { + HttpAuthDefinition::new("query".to_owned(), name.into(), None) } /// Returns the HTTP auth location. @@ -84,47 +119,13 @@ impl HttpAuthDefinition { &self.location } - /// Sets the value for HTTP auth location. - pub fn set_location( - mut self, - location: impl Into + std::cmp::PartialEq + Debug, - ) -> Self { - if location != "header".to_string() && location != "query".to_string() { - // TODO: return auth defined error - panic!( - "Location not allowed: Got: {:?}. Expected: `header` or `query`", - location - ); - } - self.location = location.into(); - self - } - /// Returns the HTTP auth name. pub fn name(&self) -> &str { &self.name } - /// Sets the value for HTTP auth name. - pub fn set_name(mut self, name: impl Into) -> Self { - self.name = name.into(); - self - } - /// Returns the HTTP auth scheme. pub fn scheme(&self) -> &Option { &self.scheme } - - /// Sets the value for HTTP auth scheme. - pub fn set_scheme(mut self, scheme: impl Into) -> Self { - if self.location.eq("header") && self.name.eq_ignore_ascii_case("authorization") { - self.scheme = Some(scheme.into()); - } else { - // TODO: return auth defined error - println!("Scheme can only be set when it is set into the `Authorization header`."); - self.scheme = None - } - self - } } From 11be011f61559d8e53bf55437d15e781b4312f9a Mon Sep 17 00:00:00 2001 From: Eduardo Rodrigues Date: Sun, 1 Jan 2023 03:09:41 +0100 Subject: [PATCH 14/38] chore: fix logical error for scheme not allowed --- rust-runtime/aws-smithy-types/src/auth.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rust-runtime/aws-smithy-types/src/auth.rs b/rust-runtime/aws-smithy-types/src/auth.rs index 54170af03e..b54412de67 100644 --- a/rust-runtime/aws-smithy-types/src/auth.rs +++ b/rust-runtime/aws-smithy-types/src/auth.rs @@ -94,7 +94,7 @@ impl HttpAuthDefinition { pub fn new_with_header(header_name: impl Into, scheme: impl Into>) -> Result { let name: String = header_name.into(); let scheme: Option = scheme.into(); - if scheme.is_some() && name.eq_ignore_ascii_case("authorization") { + if scheme.is_some() && !name.eq_ignore_ascii_case("authorization") { return Err(AuthError::from(AuthErrorKind::SchemeNotAllowed)); } HttpAuthDefinition::new("header".to_owned(), name, scheme) From 4a44293f6acc2f99cf77b7ed3993d7a82cab580c Mon Sep 17 00:00:00 2001 From: Eduardo Rodrigues Date: Sun, 1 Jan 2023 20:21:16 +0100 Subject: [PATCH 15/38] chore: add constructor for basic and digest auth --- rust-runtime/aws-smithy-types/src/auth.rs | 35 ++++++++++++++++++++--- 1 file changed, 31 insertions(+), 4 deletions(-) diff --git a/rust-runtime/aws-smithy-types/src/auth.rs b/rust-runtime/aws-smithy-types/src/auth.rs index b54412de67..e599c0ecdd 100644 --- a/rust-runtime/aws-smithy-types/src/auth.rs +++ b/rust-runtime/aws-smithy-types/src/auth.rs @@ -23,7 +23,10 @@ impl std::fmt::Display for AuthError { use AuthErrorKind::*; match &self.kind { InvalidLocation => write!(f, "invalid location: expected `header` or `query`"), - SchemeNotAllowed => write!(f, "scheme only allowed when it is set into the `Authorization header`"), + SchemeNotAllowed => write!( + f, + "scheme only allowed when it is set into the `Authorization header`" + ), } } } @@ -91,7 +94,10 @@ impl HttpAuthDefinition { } /// Constructs a new HTTP auth definition in header. - pub fn new_with_header(header_name: impl Into, scheme: impl Into>) -> Result { + pub fn new_with_header( + header_name: impl Into, + scheme: impl Into>, + ) -> Result { let name: String = header_name.into(); let scheme: Option = scheme.into(); if scheme.is_some() && !name.eq_ignore_ascii_case("authorization") { @@ -100,16 +106,37 @@ impl HttpAuthDefinition { HttpAuthDefinition::new("header".to_owned(), name, scheme) } + /// Constructs a new HTTP auth definition following the RFC 2617 for Basic Auth. + pub fn new_with_basic_auth() -> Self { + HttpAuthDefinition::new( + "header".to_owned(), + "Authorization".to_owned(), + Some("Basic".to_owned()), + ) + .unwrap() + } + + /// Constructs a new HTTP auth definition following the RFC 2617 for Digest Auth. + pub fn new_with_digest_auth() -> Self { + HttpAuthDefinition::new( + "header".to_owned(), + "Authorization".to_owned(), + Some("Digest".to_owned()), + ) + .unwrap() + } + /// Constructs a new HTTP auth definition following the RFC 6750 for Bearer Auth. pub fn new_with_bearer_auth() -> Self { HttpAuthDefinition::new( "header".to_owned(), "Authorization".to_owned(), Some("Bearer".to_owned()), - ).unwrap() + ) + .unwrap() } - /// Constructs a new HTTP auth definition in header. + /// Constructs a new HTTP auth definition in query string. pub fn new_with_query(name: impl Into) -> Result { HttpAuthDefinition::new("query".to_owned(), name.into(), None) } From 5fd556e84f0e2b29efa4078f803d4e946af8ff6b Mon Sep 17 00:00:00 2001 From: Eduardo Rodrigues Date: Mon, 2 Jan 2023 12:25:09 +0100 Subject: [PATCH 16/38] chore: allow equality comparision for api key --- rust-runtime/aws-smithy-types/src/auth.rs | 31 +++++++++++++++++++++-- 1 file changed, 29 insertions(+), 2 deletions(-) diff --git a/rust-runtime/aws-smithy-types/src/auth.rs b/rust-runtime/aws-smithy-types/src/auth.rs index e599c0ecdd..b1c4c6241a 100644 --- a/rust-runtime/aws-smithy-types/src/auth.rs +++ b/rust-runtime/aws-smithy-types/src/auth.rs @@ -45,8 +45,8 @@ pub struct AuthApiKey { impl AuthApiKey { /// Constructs a new API key. - pub fn new(api_key: String) -> Self { - Self { api_key } + pub fn new(api_key: impl Into) -> Self { + Self { api_key: api_key.into() } } /// Returns the underlying api key. @@ -61,6 +61,14 @@ impl AuthApiKey { } } +impl PartialEq for AuthApiKey { + fn eq(&self, other: &Self) -> bool { + self.api_key == other.api_key + } +} + +trait Eq: PartialEq {} + /// An HTTP-specific authentication scheme that sends an arbitrary /// auth value in a header or query string parameter. // As described in the Smithy documentation: @@ -156,3 +164,22 @@ impl HttpAuthDefinition { &self.scheme } } + +#[cfg(test)] +mod tests { + use crate::auth::AuthApiKey; + + #[test] + fn api_key_is_equal() { + let api_key_a = AuthApiKey::new("some-api-key"); + let api_key_b = AuthApiKey::new("some-api-key"); + assert_eq!(api_key_a, api_key_b); + } + + #[test] + fn api_key_is_different() { + let api_key_a = AuthApiKey::new("some-api-key"); + let api_key_b = AuthApiKey::new("another-api-key"); + assert_ne!(api_key_a, api_key_b); + } +} From 10ea5b1ae13270794e89895b00c79f79f63d28bd Mon Sep 17 00:00:00 2001 From: Eduardo Rodrigues Date: Mon, 2 Jan 2023 18:46:52 +0100 Subject: [PATCH 17/38] Revert "chore: set package version to 0.52.0" This reverts commit da660fcf160e24605ebe082deb6f339213926340. --- aws/rust-runtime/aws-config/Cargo.toml | 2 +- aws/rust-runtime/aws-endpoint/Cargo.toml | 2 +- aws/rust-runtime/aws-http/Cargo.toml | 2 +- aws/rust-runtime/aws-hyper/Cargo.toml | 2 +- aws/rust-runtime/aws-inlineable/Cargo.toml | 2 +- aws/rust-runtime/aws-sig-auth/Cargo.toml | 2 +- aws/rust-runtime/aws-sigv4/Cargo.toml | 2 +- aws/rust-runtime/aws-types/Cargo.toml | 2 +- rust-runtime/aws-smithy-async/Cargo.toml | 2 +- rust-runtime/aws-smithy-checksums/Cargo.toml | 2 +- rust-runtime/aws-smithy-client/Cargo.toml | 2 +- rust-runtime/aws-smithy-eventstream/Cargo.toml | 2 +- rust-runtime/aws-smithy-http-server-python/Cargo.toml | 2 +- rust-runtime/aws-smithy-http-server/Cargo.toml | 2 +- rust-runtime/aws-smithy-http-tower/Cargo.toml | 2 +- rust-runtime/aws-smithy-http/Cargo.toml | 2 +- rust-runtime/aws-smithy-json/Cargo.toml | 2 +- rust-runtime/aws-smithy-protocol-test/Cargo.toml | 2 +- rust-runtime/aws-smithy-query/Cargo.toml | 2 +- rust-runtime/aws-smithy-types-convert/Cargo.toml | 2 +- rust-runtime/aws-smithy-types/Cargo.toml | 2 +- rust-runtime/aws-smithy-xml/Cargo.toml | 2 +- rust-runtime/inlineable/Cargo.toml | 2 +- 23 files changed, 23 insertions(+), 23 deletions(-) diff --git a/aws/rust-runtime/aws-config/Cargo.toml b/aws/rust-runtime/aws-config/Cargo.toml index 44e21b1ad3..5e6727da45 100644 --- a/aws/rust-runtime/aws-config/Cargo.toml +++ b/aws/rust-runtime/aws-config/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "aws-config" -version = "0.52.0" +version = "0.0.0-smithy-rs-head" authors = ["AWS Rust SDK Team ", "Russell Cohen "] description = "AWS SDK config and credential provider implementations." edition = "2021" diff --git a/aws/rust-runtime/aws-endpoint/Cargo.toml b/aws/rust-runtime/aws-endpoint/Cargo.toml index 577bedd7b6..67cb4d4e6e 100644 --- a/aws/rust-runtime/aws-endpoint/Cargo.toml +++ b/aws/rust-runtime/aws-endpoint/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "aws-endpoint" -version = "0.52.0" +version = "0.0.0-smithy-rs-head" authors = ["AWS Rust SDK Team ", "Russell Cohen "] description = "AWS SDK endpoint support." edition = "2021" diff --git a/aws/rust-runtime/aws-http/Cargo.toml b/aws/rust-runtime/aws-http/Cargo.toml index 5ce6988e24..a20a7edac7 100644 --- a/aws/rust-runtime/aws-http/Cargo.toml +++ b/aws/rust-runtime/aws-http/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "aws-http" -version = "0.52.0" +version = "0.0.0-smithy-rs-head" authors = ["AWS Rust SDK Team ", "Russell Cohen "] description = "HTTP specific AWS SDK behaviors." edition = "2021" diff --git a/aws/rust-runtime/aws-hyper/Cargo.toml b/aws/rust-runtime/aws-hyper/Cargo.toml index 91b0f96b7a..e7eb87f3de 100644 --- a/aws/rust-runtime/aws-hyper/Cargo.toml +++ b/aws/rust-runtime/aws-hyper/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "aws-hyper" -version = "0.52.0" +version = "0.0.0-smithy-rs-head" authors = ["AWS Rust SDK Team ", "Russell Cohen "] description = "This crate has been removed and is deprecated." edition = "2021" diff --git a/aws/rust-runtime/aws-inlineable/Cargo.toml b/aws/rust-runtime/aws-inlineable/Cargo.toml index f88f89151e..b20b25c20a 100644 --- a/aws/rust-runtime/aws-inlineable/Cargo.toml +++ b/aws/rust-runtime/aws-inlineable/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "aws-inlineable" -version = "0.52.0" +version = "0.0.0-smithy-rs-head" authors = ["AWS Rust SDK Team ", "Russell Cohen "] description = """ The modules of this crate are intended to be inlined directly into the SDK as needed. The dependencies here diff --git a/aws/rust-runtime/aws-sig-auth/Cargo.toml b/aws/rust-runtime/aws-sig-auth/Cargo.toml index 97b0ec9c7e..1d8966d162 100644 --- a/aws/rust-runtime/aws-sig-auth/Cargo.toml +++ b/aws/rust-runtime/aws-sig-auth/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "aws-sig-auth" -version = "0.52.0" +version = "0.0.0-smithy-rs-head" authors = ["AWS Rust SDK Team ", "Russell Cohen "] description = "SigV4 signing middleware for the AWS SDK." edition = "2021" diff --git a/aws/rust-runtime/aws-sigv4/Cargo.toml b/aws/rust-runtime/aws-sigv4/Cargo.toml index 793c6e0ed7..ad1570bb86 100644 --- a/aws/rust-runtime/aws-sigv4/Cargo.toml +++ b/aws/rust-runtime/aws-sigv4/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "aws-sigv4" -version = "0.52.0" +version = "0.0.0-smithy-rs-head" authors = ["AWS Rust SDK Team ", "David Barsky "] description = "SigV4 signer for HTTP requests and Event Stream messages." edition = "2021" diff --git a/aws/rust-runtime/aws-types/Cargo.toml b/aws/rust-runtime/aws-types/Cargo.toml index 87f10bf1eb..755ccdba07 100644 --- a/aws/rust-runtime/aws-types/Cargo.toml +++ b/aws/rust-runtime/aws-types/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "aws-types" -version = "0.52.0" +version = "0.0.0-smithy-rs-head" authors = ["AWS Rust SDK Team ", "Russell Cohen "] description = "Cross-service types for the AWS SDK." edition = "2021" diff --git a/rust-runtime/aws-smithy-async/Cargo.toml b/rust-runtime/aws-smithy-async/Cargo.toml index 9cd6c0eb95..04d600ea62 100644 --- a/rust-runtime/aws-smithy-async/Cargo.toml +++ b/rust-runtime/aws-smithy-async/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "aws-smithy-async" -version = "0.52.0" +version = "0.0.0-smithy-rs-head" authors = ["AWS Rust SDK Team ", "John DiSanti "] description = "Async runtime agnostic abstractions for smithy-rs." edition = "2021" diff --git a/rust-runtime/aws-smithy-checksums/Cargo.toml b/rust-runtime/aws-smithy-checksums/Cargo.toml index 1036016c69..b210360d55 100644 --- a/rust-runtime/aws-smithy-checksums/Cargo.toml +++ b/rust-runtime/aws-smithy-checksums/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "aws-smithy-checksums" -version = "0.52.0" +version = "0.0.0-smithy-rs-head" authors = [ "AWS Rust SDK Team ", "Zelda Hessler ", diff --git a/rust-runtime/aws-smithy-client/Cargo.toml b/rust-runtime/aws-smithy-client/Cargo.toml index 7efd5fcc7b..f184552dac 100644 --- a/rust-runtime/aws-smithy-client/Cargo.toml +++ b/rust-runtime/aws-smithy-client/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "aws-smithy-client" -version = "0.52.0" +version = "0.0.0-smithy-rs-head" authors = ["AWS Rust SDK Team ", "Russell Cohen "] description = "Client for smithy-rs." edition = "2021" diff --git a/rust-runtime/aws-smithy-eventstream/Cargo.toml b/rust-runtime/aws-smithy-eventstream/Cargo.toml index d2fc258ae7..a77aff9e85 100644 --- a/rust-runtime/aws-smithy-eventstream/Cargo.toml +++ b/rust-runtime/aws-smithy-eventstream/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "aws-smithy-eventstream" -version = "0.52.0" +version = "0.0.0-smithy-rs-head" authors = ["AWS Rust SDK Team ", "John DiSanti "] description = "Event stream logic for smithy-rs." edition = "2021" diff --git a/rust-runtime/aws-smithy-http-server-python/Cargo.toml b/rust-runtime/aws-smithy-http-server-python/Cargo.toml index fc0bcebf00..8085e000b4 100644 --- a/rust-runtime/aws-smithy-http-server-python/Cargo.toml +++ b/rust-runtime/aws-smithy-http-server-python/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "aws-smithy-http-server-python" -version = "0.52.0" +version = "0.0.0-smithy-rs-head" authors = ["Smithy Rust Server "] edition = "2021" license = "Apache-2.0" diff --git a/rust-runtime/aws-smithy-http-server/Cargo.toml b/rust-runtime/aws-smithy-http-server/Cargo.toml index 41be781be8..4497eb8806 100644 --- a/rust-runtime/aws-smithy-http-server/Cargo.toml +++ b/rust-runtime/aws-smithy-http-server/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "aws-smithy-http-server" -version = "0.52.0" +version = "0.0.0-smithy-rs-head" authors = ["Smithy Rust Server "] edition = "2021" license = "Apache-2.0" diff --git a/rust-runtime/aws-smithy-http-tower/Cargo.toml b/rust-runtime/aws-smithy-http-tower/Cargo.toml index 6482b42627..e74934119b 100644 --- a/rust-runtime/aws-smithy-http-tower/Cargo.toml +++ b/rust-runtime/aws-smithy-http-tower/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "aws-smithy-http-tower" -version = "0.52.0" +version = "0.0.0-smithy-rs-head" authors = ["AWS Rust SDK Team ", "Russell Cohen "] description = "Tower-compatible shims for smithy-rs middleware." edition = "2021" diff --git a/rust-runtime/aws-smithy-http/Cargo.toml b/rust-runtime/aws-smithy-http/Cargo.toml index f76591d93c..23bb28437d 100644 --- a/rust-runtime/aws-smithy-http/Cargo.toml +++ b/rust-runtime/aws-smithy-http/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "aws-smithy-http" -version = "0.52.0" +version = "0.0.0-smithy-rs-head" authors = [ "AWS Rust SDK Team ", "Russell Cohen ", diff --git a/rust-runtime/aws-smithy-json/Cargo.toml b/rust-runtime/aws-smithy-json/Cargo.toml index 5dbaa9741d..3ad4d2225f 100644 --- a/rust-runtime/aws-smithy-json/Cargo.toml +++ b/rust-runtime/aws-smithy-json/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "aws-smithy-json" -version = "0.52.0" +version = "0.0.0-smithy-rs-head" authors = ["AWS Rust SDK Team ", "John DiSanti "] description = "Token streaming JSON parser for smithy-rs." edition = "2021" diff --git a/rust-runtime/aws-smithy-protocol-test/Cargo.toml b/rust-runtime/aws-smithy-protocol-test/Cargo.toml index 13cfa9496a..b4d5bb516b 100644 --- a/rust-runtime/aws-smithy-protocol-test/Cargo.toml +++ b/rust-runtime/aws-smithy-protocol-test/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "aws-smithy-protocol-test" -version = "0.52.0" +version = "0.0.0-smithy-rs-head" authors = ["AWS Rust SDK Team ", "Russell Cohen "] description = "A collection of library functions to validate HTTP requests against Smithy protocol tests." edition = "2021" diff --git a/rust-runtime/aws-smithy-query/Cargo.toml b/rust-runtime/aws-smithy-query/Cargo.toml index ec9f7f4085..a4f517ae2a 100644 --- a/rust-runtime/aws-smithy-query/Cargo.toml +++ b/rust-runtime/aws-smithy-query/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "aws-smithy-query" -version = "0.52.0" +version = "0.0.0-smithy-rs-head" authors = ["AWS Rust SDK Team ", "John DiSanti "] description = "AWSQuery and EC2Query Smithy protocol logic for smithy-rs." edition = "2021" diff --git a/rust-runtime/aws-smithy-types-convert/Cargo.toml b/rust-runtime/aws-smithy-types-convert/Cargo.toml index 8bbc0de5f6..c9ffbd22a0 100644 --- a/rust-runtime/aws-smithy-types-convert/Cargo.toml +++ b/rust-runtime/aws-smithy-types-convert/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "aws-smithy-types-convert" -version = "0.52.0" +version = "0.0.0-smithy-rs-head" authors = ["AWS Rust SDK Team "] description = "Conversion of types from aws-smithy-types to other libraries." edition = "2021" diff --git a/rust-runtime/aws-smithy-types/Cargo.toml b/rust-runtime/aws-smithy-types/Cargo.toml index cf32022bc5..12049c3af8 100644 --- a/rust-runtime/aws-smithy-types/Cargo.toml +++ b/rust-runtime/aws-smithy-types/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "aws-smithy-types" -version = "0.52.0" +version = "0.0.0-smithy-rs-head" authors = ["AWS Rust SDK Team ", "Russell Cohen "] description = "Types for smithy-rs codegen." edition = "2021" diff --git a/rust-runtime/aws-smithy-xml/Cargo.toml b/rust-runtime/aws-smithy-xml/Cargo.toml index 9aa92f038d..1563fa0ed7 100644 --- a/rust-runtime/aws-smithy-xml/Cargo.toml +++ b/rust-runtime/aws-smithy-xml/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "aws-smithy-xml" -version = "0.52.0" +version = "0.0.0-smithy-rs-head" authors = ["AWS Rust SDK Team ", "Russell Cohen "] description = "XML parsing logic for Smithy protocols." edition = "2021" diff --git a/rust-runtime/inlineable/Cargo.toml b/rust-runtime/inlineable/Cargo.toml index 96718bd10b..b76a17e5e7 100644 --- a/rust-runtime/inlineable/Cargo.toml +++ b/rust-runtime/inlineable/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "inlineable" -version = "0.52.0" +version = "0.0.0-smithy-rs-head" authors = ["AWS Rust SDK Team ", "Russell Cohen "] edition = "2021" description = """ From 889b9d310dffce082f3760ee5ad745626d8e4c43 Mon Sep 17 00:00:00 2001 From: Eduardo Rodrigues Date: Mon, 2 Jan 2023 20:48:36 +0100 Subject: [PATCH 18/38] chore: fix additional references to querywriter --- .../aws-sigv4/src/http_request/canonical_request.rs | 2 +- aws/rust-runtime/aws-sigv4/src/http_request/sign.rs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/aws/rust-runtime/aws-sigv4/src/http_request/canonical_request.rs b/aws/rust-runtime/aws-sigv4/src/http_request/canonical_request.rs index 6f9cfdc436..c36ddc7347 100644 --- a/aws/rust-runtime/aws-sigv4/src/http_request/canonical_request.rs +++ b/aws/rust-runtime/aws-sigv4/src/http_request/canonical_request.rs @@ -513,7 +513,7 @@ mod tests { use crate::http_request::canonical_request::{ normalize_header_value, trim_all, CanonicalRequest, SigningScope, StringToSign, }; - use crate::http_request::query_writer::QueryWriter; + use aws_smithy_http::query_writer::QueryWriter; use crate::http_request::test::{test_canonical_request, test_request, test_sts}; use crate::http_request::{ PayloadChecksumKind, SignableBody, SignableRequest, SigningSettings, diff --git a/aws/rust-runtime/aws-sigv4/src/http_request/sign.rs b/aws/rust-runtime/aws-sigv4/src/http_request/sign.rs index 69f5c00819..bb46fc3a87 100644 --- a/aws/rust-runtime/aws-sigv4/src/http_request/sign.rs +++ b/aws/rust-runtime/aws-sigv4/src/http_request/sign.rs @@ -8,7 +8,7 @@ use super::{PayloadChecksumKind, SignatureLocation}; use crate::http_request::canonical_request::header; use crate::http_request::canonical_request::param; use crate::http_request::canonical_request::{CanonicalRequest, StringToSign, HMAC_256}; -use crate::http_request::query_writer::QueryWriter; +use aws_smithy_http::query_writer::QueryWriter; use crate::http_request::SigningParams; use crate::sign::{calculate_signature, generate_signing_key, sha256_hex_string}; use crate::SigningOutput; From 57df9cbaf8bc58946e579f3b53e4a2c7c2409de6 Mon Sep 17 00:00:00 2001 From: Eduardo Rodrigues Date: Tue, 3 Jan 2023 02:54:18 +0100 Subject: [PATCH 19/38] chore: implement from string for api key struct --- rust-runtime/aws-smithy-types/src/auth.rs | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/rust-runtime/aws-smithy-types/src/auth.rs b/rust-runtime/aws-smithy-types/src/auth.rs index b1c4c6241a..4f9bd22fb5 100644 --- a/rust-runtime/aws-smithy-types/src/auth.rs +++ b/rust-runtime/aws-smithy-types/src/auth.rs @@ -46,7 +46,9 @@ pub struct AuthApiKey { impl AuthApiKey { /// Constructs a new API key. pub fn new(api_key: impl Into) -> Self { - Self { api_key: api_key.into() } + Self { + api_key: api_key.into(), + } } /// Returns the underlying api key. @@ -69,6 +71,20 @@ impl PartialEq for AuthApiKey { trait Eq: PartialEq {} +impl From<&str> for AuthApiKey { + fn from(api_key: &str) -> Self { + Self { + api_key: api_key.to_owned(), + } + } +} + +impl From for AuthApiKey { + fn from(api_key: String) -> Self { + Self { api_key } + } +} + /// An HTTP-specific authentication scheme that sends an arbitrary /// auth value in a header or query string parameter. // As described in the Smithy documentation: From 7b0e877b06c7f3b9a38039e2b9b55de3456bef7f Mon Sep 17 00:00:00 2001 From: Eduardo Rodrigues Date: Tue, 3 Jan 2023 02:55:40 +0100 Subject: [PATCH 20/38] chore: disallow none api key in sdk config --- aws/rust-runtime/aws-types/src/sdk_config.rs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/aws/rust-runtime/aws-types/src/sdk_config.rs b/aws/rust-runtime/aws-types/src/sdk_config.rs index ce4268c297..f28a3e9237 100644 --- a/aws/rust-runtime/aws-types/src/sdk_config.rs +++ b/aws/rust-runtime/aws-types/src/sdk_config.rs @@ -162,14 +162,14 @@ impl Builder { /// use aws_types::SdkConfig; /// let config = SdkConfig::builder().api_key("some-api-key").build(); /// ``` - pub fn api_key(&mut self, api_key: impl Into>) -> &mut Self { - self.api_key = api_key.into(); + pub fn api_key(mut self, api_key: impl Into) -> Self { + self.set_api_key(Some(api_key.into())); self } /// Set the api key to use when making requests. - pub fn set_api_key(&mut self, api_key: impl Into>) -> &mut Self { - self.api_key = api_key.into(); + pub fn set_api_key(&mut self, api_key: Option) -> &mut Self { + self.api_key = api_key; self } From f5042490b9b519244104edbd7ef3784551789f0f Mon Sep 17 00:00:00 2001 From: Eduardo Rodrigues Date: Tue, 3 Jan 2023 02:55:46 +0100 Subject: [PATCH 21/38] chore: fix formatting --- .../aws-sigv4/src/http_request/canonical_request.rs | 2 +- aws/rust-runtime/aws-sigv4/src/http_request/sign.rs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/aws/rust-runtime/aws-sigv4/src/http_request/canonical_request.rs b/aws/rust-runtime/aws-sigv4/src/http_request/canonical_request.rs index c36ddc7347..c7c06f04ad 100644 --- a/aws/rust-runtime/aws-sigv4/src/http_request/canonical_request.rs +++ b/aws/rust-runtime/aws-sigv4/src/http_request/canonical_request.rs @@ -513,13 +513,13 @@ mod tests { use crate::http_request::canonical_request::{ normalize_header_value, trim_all, CanonicalRequest, SigningScope, StringToSign, }; - use aws_smithy_http::query_writer::QueryWriter; use crate::http_request::test::{test_canonical_request, test_request, test_sts}; use crate::http_request::{ PayloadChecksumKind, SignableBody, SignableRequest, SigningSettings, }; use crate::http_request::{SignatureLocation, SigningParams}; use crate::sign::sha256_hex_string; + use aws_smithy_http::query_writer::QueryWriter; use http::Uri; use http::{header::HeaderName, HeaderValue}; use pretty_assertions::assert_eq; diff --git a/aws/rust-runtime/aws-sigv4/src/http_request/sign.rs b/aws/rust-runtime/aws-sigv4/src/http_request/sign.rs index bb46fc3a87..d62e432fd5 100644 --- a/aws/rust-runtime/aws-sigv4/src/http_request/sign.rs +++ b/aws/rust-runtime/aws-sigv4/src/http_request/sign.rs @@ -8,10 +8,10 @@ use super::{PayloadChecksumKind, SignatureLocation}; use crate::http_request::canonical_request::header; use crate::http_request::canonical_request::param; use crate::http_request::canonical_request::{CanonicalRequest, StringToSign, HMAC_256}; -use aws_smithy_http::query_writer::QueryWriter; use crate::http_request::SigningParams; use crate::sign::{calculate_signature, generate_signing_key, sha256_hex_string}; use crate::SigningOutput; +use aws_smithy_http::query_writer::QueryWriter; use http::header::HeaderValue; use http::{HeaderMap, Method, Uri}; use std::borrow::Cow; From 8d731b8940e93ed0435639e54e096c670d5bb3d1 Mon Sep 17 00:00:00 2001 From: Eduardo Rodrigues Date: Tue, 3 Jan 2023 04:59:09 +0100 Subject: [PATCH 22/38] chore: add unit tests for auth types --- rust-runtime/aws-smithy-types/src/auth.rs | 121 +++++++++++++++++----- 1 file changed, 95 insertions(+), 26 deletions(-) diff --git a/rust-runtime/aws-smithy-types/src/auth.rs b/rust-runtime/aws-smithy-types/src/auth.rs index 4f9bd22fb5..771eab5bfb 100644 --- a/rust-runtime/aws-smithy-types/src/auth.rs +++ b/rust-runtime/aws-smithy-types/src/auth.rs @@ -4,9 +4,10 @@ */ //! Smithy HTTP Auth Types +use std::cmp::PartialEq; use std::fmt::Debug; -#[derive(Debug)] +#[derive(Debug, PartialEq)] enum AuthErrorKind { InvalidLocation, SchemeNotAllowed, @@ -38,7 +39,7 @@ impl From for AuthError { } /// Authentication configuration to connect to a Smithy Service -#[derive(Clone, Debug)] +#[derive(Clone, Debug, PartialEq)] pub struct AuthApiKey { api_key: String, } @@ -63,14 +64,6 @@ impl AuthApiKey { } } -impl PartialEq for AuthApiKey { - fn eq(&self, other: &Self) -> bool { - self.api_key == other.api_key - } -} - -trait Eq: PartialEq {} - impl From<&str> for AuthApiKey { fn from(api_key: &str) -> Self { Self { @@ -89,7 +82,7 @@ impl From for AuthApiKey { /// auth value in a header or query string parameter. // As described in the Smithy documentation: // https://github.com/awslabs/smithy/blob/main/smithy-model/src/main/resources/software/amazon/smithy/model/loader/prelude.smithy -#[derive(Clone, Debug)] +#[derive(Clone, Debug, PartialEq)] pub struct HttpAuthDefinition { /// Defines the location of where the Auth is serialized. This value /// can be set to `"header"` or `"query"`. @@ -106,22 +99,26 @@ pub struct HttpAuthDefinition { impl HttpAuthDefinition { /// Constructs a new HTTP auth definition. - fn new(location: String, name: String, scheme: Option) -> Result { + fn new(location: String, name: String, scheme: S) -> Result + where + S: Into>, + { if location != "header" && location != "query" { return Err(AuthError::from(AuthErrorKind::InvalidLocation)); } Ok(Self { location, name, - scheme, + scheme: scheme.into(), }) } /// Constructs a new HTTP auth definition in header. - pub fn new_with_header( - header_name: impl Into, - scheme: impl Into>, - ) -> Result { + pub fn new_with_header(header_name: N, scheme: S) -> Result + where + N: Into, + S: Into>, + { let name: String = header_name.into(); let scheme: Option = scheme.into(); if scheme.is_some() && !name.eq_ignore_ascii_case("authorization") { @@ -135,7 +132,7 @@ impl HttpAuthDefinition { HttpAuthDefinition::new( "header".to_owned(), "Authorization".to_owned(), - Some("Basic".to_owned()), + "Basic".to_owned(), ) .unwrap() } @@ -145,7 +142,7 @@ impl HttpAuthDefinition { HttpAuthDefinition::new( "header".to_owned(), "Authorization".to_owned(), - Some("Digest".to_owned()), + "Digest".to_owned(), ) .unwrap() } @@ -155,14 +152,14 @@ impl HttpAuthDefinition { HttpAuthDefinition::new( "header".to_owned(), "Authorization".to_owned(), - Some("Bearer".to_owned()), + "Bearer".to_owned(), ) .unwrap() } /// Constructs a new HTTP auth definition in query string. - pub fn new_with_query(name: impl Into) -> Result { - HttpAuthDefinition::new("query".to_owned(), name.into(), None) + pub fn new_with_query(name: impl Into) -> Self { + HttpAuthDefinition::new("query".to_owned(), name.into(), None).unwrap() } /// Returns the HTTP auth location. @@ -176,18 +173,20 @@ impl HttpAuthDefinition { } /// Returns the HTTP auth scheme. - pub fn scheme(&self) -> &Option { - &self.scheme + pub fn scheme(&self) -> Option<&str> { + self.scheme.as_deref() } } #[cfg(test)] mod tests { use crate::auth::AuthApiKey; + use crate::auth::AuthErrorKind; + use crate::auth::HttpAuthDefinition; #[test] fn api_key_is_equal() { - let api_key_a = AuthApiKey::new("some-api-key"); + let api_key_a: AuthApiKey = "some-api-key".into(); let api_key_b = AuthApiKey::new("some-api-key"); assert_eq!(api_key_a, api_key_b); } @@ -195,7 +194,77 @@ mod tests { #[test] fn api_key_is_different() { let api_key_a = AuthApiKey::new("some-api-key"); - let api_key_b = AuthApiKey::new("another-api-key"); + let api_key_b: AuthApiKey = String::from("another-api-key").into(); assert_ne!(api_key_a, api_key_b); } + + #[test] + fn auth_definition_fails_with_invalid_location() { + let result = + HttpAuthDefinition::new("invalid".to_owned(), "".to_owned(), None).map_err(|e| e.kind); + let expected = Err(AuthErrorKind::InvalidLocation); + assert_eq!(expected, result); + } + + #[test] + fn auth_definition_for_header_without_scheme() { + let definition = HttpAuthDefinition::new_with_header("Header", None).unwrap(); + assert_eq!(definition.location, "header"); + assert_eq!(definition.name, "Header"); + assert_eq!(definition.scheme, None); + } + + #[test] + fn auth_definition_for_authorization_header_with_scheme() { + let definition = + HttpAuthDefinition::new_with_header("authorization", "Scheme".to_owned()).unwrap(); + assert_eq!(definition.location(), "header"); + assert_eq!(definition.name(), "authorization"); + assert_eq!(definition.scheme(), Some("Scheme")); + } + + #[test] + fn auth_definition_fails_with_scheme_not_allowed() { + let result = HttpAuthDefinition::new_with_header("Invalid".to_owned(), "Scheme".to_owned()) + .map_err(|e| e.kind); + let expected = Err(AuthErrorKind::SchemeNotAllowed); + assert_eq!(expected, result); + } + + #[test] + fn auth_definition_for_basic() { + let definition = HttpAuthDefinition::new_with_basic_auth(); + assert_eq!( + definition, + HttpAuthDefinition { + location: "header".to_owned(), + name: "Authorization".to_owned(), + scheme: Some("Basic".to_owned()), + } + ); + } + + #[test] + fn auth_definition_for_digest() { + let definition = HttpAuthDefinition::new_with_digest_auth(); + assert_eq!(definition.location(), "header"); + assert_eq!(definition.name(), "Authorization"); + assert_eq!(definition.scheme(), Some("Digest")); + } + + #[test] + fn auth_definition_for_bearer_token() { + let definition = HttpAuthDefinition::new_with_bearer_auth(); + assert_eq!(definition.location(), "header"); + assert_eq!(definition.name(), "Authorization"); + assert_eq!(definition.scheme(), Some("Bearer")); + } + + #[test] + fn auth_definition_for_query() { + let definition = HttpAuthDefinition::new_with_query("query_key"); + assert_eq!(definition.location(), "query"); + assert_eq!(definition.name(), "query_key"); + assert_eq!(definition.scheme(), None); + } } From b2318b02304fdeefbe5cb8eba80047ae307d08fa Mon Sep 17 00:00:00 2001 From: Eduardo Rodrigues Date: Tue, 3 Jan 2023 04:59:31 +0100 Subject: [PATCH 23/38] chore: add auth api key to external types --- aws/rust-runtime/aws-types/external-types.toml | 1 + 1 file changed, 1 insertion(+) diff --git a/aws/rust-runtime/aws-types/external-types.toml b/aws/rust-runtime/aws-types/external-types.toml index 640a363e7d..7aff945fd6 100644 --- a/aws/rust-runtime/aws-types/external-types.toml +++ b/aws/rust-runtime/aws-types/external-types.toml @@ -6,6 +6,7 @@ allowed_external_types = [ "aws_smithy_http::endpoint::Endpoint", "aws_smithy_http::endpoint::EndpointPrefix", "aws_smithy_http::endpoint::error::InvalidEndpointError", + "aws_smithy_types::auth::AuthApiKey", "aws_smithy_types::retry::RetryConfig", "aws_smithy_types::timeout::TimeoutConfig", "http::uri::Uri", From b2a23a0f2bea8db2bec9984a33eae01b0e9c548d Mon Sep 17 00:00:00 2001 From: Eduardo Rodrigues Date: Mon, 30 Jan 2023 18:18:05 +0100 Subject: [PATCH 24/38] chore: make query writer doc hidden --- rust-runtime/aws-smithy-http/src/lib.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/rust-runtime/aws-smithy-http/src/lib.rs b/rust-runtime/aws-smithy-http/src/lib.rs index 5595335aa1..3a785b72c0 100644 --- a/rust-runtime/aws-smithy-http/src/lib.rs +++ b/rust-runtime/aws-smithy-http/src/lib.rs @@ -26,6 +26,7 @@ pub mod middleware; pub mod operation; pub mod property_bag; pub mod query; +#[doc(hidden)] pub mod query_writer; pub mod response; pub mod result; From 16d65f871245279b3dcaf96a1669d07ed02d743f Mon Sep 17 00:00:00 2001 From: Eduardo Rodrigues Date: Mon, 30 Jan 2023 18:43:04 +0100 Subject: [PATCH 25/38] feat: create aws-smithy-http-auth crate --- rust-runtime/Cargo.toml | 1 + rust-runtime/aws-smithy-http-auth/Cargo.toml | 17 ++ rust-runtime/aws-smithy-http-auth/LICENSE | 175 ++++++++++++++++++ rust-runtime/aws-smithy-http-auth/README.md | 7 + .../aws-smithy-http-auth/external-types.toml | 2 + .../src/auth.rs | 0 rust-runtime/aws-smithy-http-auth/src/lib.rs | 6 + rust-runtime/aws-smithy-types/src/lib.rs | 1 - 8 files changed, 208 insertions(+), 1 deletion(-) create mode 100644 rust-runtime/aws-smithy-http-auth/Cargo.toml create mode 100644 rust-runtime/aws-smithy-http-auth/LICENSE create mode 100644 rust-runtime/aws-smithy-http-auth/README.md create mode 100644 rust-runtime/aws-smithy-http-auth/external-types.toml rename rust-runtime/{aws-smithy-types => aws-smithy-http-auth}/src/auth.rs (100%) create mode 100644 rust-runtime/aws-smithy-http-auth/src/lib.rs diff --git a/rust-runtime/Cargo.toml b/rust-runtime/Cargo.toml index 185d7082a0..6a53b080e9 100644 --- a/rust-runtime/Cargo.toml +++ b/rust-runtime/Cargo.toml @@ -7,6 +7,7 @@ members = [ "aws-smithy-checksums", "aws-smithy-eventstream", "aws-smithy-http", + "aws-smithy-http-auth", "aws-smithy-http-tower", "aws-smithy-json", "aws-smithy-protocol-test", diff --git a/rust-runtime/aws-smithy-http-auth/Cargo.toml b/rust-runtime/aws-smithy-http-auth/Cargo.toml new file mode 100644 index 0000000000..45dffe9abd --- /dev/null +++ b/rust-runtime/aws-smithy-http-auth/Cargo.toml @@ -0,0 +1,17 @@ +[package] +name = "aws-smithy-http-auth" +version = "0.0.0-smithy-rs-head" +authors = [ + "AWS Rust SDK Team ", + "Eduardo Rodrigues <16357187+eduardomourar@users.noreply.github.com>", +] +description = "Smithy HTTP logic for smithy-rs." +edition = "2021" +license = "Apache-2.0" +repository = "https://github.com/awslabs/smithy-rs" + +[package.metadata.docs.rs] +all-features = true +targets = ["x86_64-unknown-linux-gnu"] +rustdoc-args = ["--cfg", "docsrs"] +# End of docs.rs metadata diff --git a/rust-runtime/aws-smithy-http-auth/LICENSE b/rust-runtime/aws-smithy-http-auth/LICENSE new file mode 100644 index 0000000000..67db858821 --- /dev/null +++ b/rust-runtime/aws-smithy-http-auth/LICENSE @@ -0,0 +1,175 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. diff --git a/rust-runtime/aws-smithy-http-auth/README.md b/rust-runtime/aws-smithy-http-auth/README.md new file mode 100644 index 0000000000..1d963cafce --- /dev/null +++ b/rust-runtime/aws-smithy-http-auth/README.md @@ -0,0 +1,7 @@ +# aws-smithy-http-auth + +HTTP Auth implementation for service clients generated by [smithy-rs](https://github.com/awslabs/smithy-rs). + + +This crate is part of the [AWS SDK for Rust](https://awslabs.github.io/aws-sdk-rust/) and the [smithy-rs](https://github.com/awslabs/smithy-rs) code generator. In most cases, it should not be used directly. + diff --git a/rust-runtime/aws-smithy-http-auth/external-types.toml b/rust-runtime/aws-smithy-http-auth/external-types.toml new file mode 100644 index 0000000000..ff30ccf5ad --- /dev/null +++ b/rust-runtime/aws-smithy-http-auth/external-types.toml @@ -0,0 +1,2 @@ +allowed_external_types = [ +] diff --git a/rust-runtime/aws-smithy-types/src/auth.rs b/rust-runtime/aws-smithy-http-auth/src/auth.rs similarity index 100% rename from rust-runtime/aws-smithy-types/src/auth.rs rename to rust-runtime/aws-smithy-http-auth/src/auth.rs diff --git a/rust-runtime/aws-smithy-http-auth/src/lib.rs b/rust-runtime/aws-smithy-http-auth/src/lib.rs new file mode 100644 index 0000000000..e6ee489169 --- /dev/null +++ b/rust-runtime/aws-smithy-http-auth/src/lib.rs @@ -0,0 +1,6 @@ +/* + * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. + * SPDX-License-Identifier: Apache-2.0 + */ + +pub mod auth; diff --git a/rust-runtime/aws-smithy-types/src/lib.rs b/rust-runtime/aws-smithy-types/src/lib.rs index 07ec501fe7..f2729cefa1 100644 --- a/rust-runtime/aws-smithy-types/src/lib.rs +++ b/rust-runtime/aws-smithy-types/src/lib.rs @@ -16,7 +16,6 @@ use crate::error::{TryFromNumberError, TryFromNumberErrorKind}; use std::collections::HashMap; -pub mod auth; pub mod base64; pub mod date_time; pub mod endpoint; From 05657e1b89c6534ae2d32f745c3d40f819b19862 Mon Sep 17 00:00:00 2001 From: Eduardo Rodrigues Date: Mon, 30 Jan 2023 19:55:16 +0100 Subject: [PATCH 26/38] chore: use zeroing for auth api key --- rust-runtime/aws-smithy-http-auth/Cargo.toml | 3 ++ rust-runtime/aws-smithy-http-auth/src/auth.rs | 43 +++++++++++-------- 2 files changed, 29 insertions(+), 17 deletions(-) diff --git a/rust-runtime/aws-smithy-http-auth/Cargo.toml b/rust-runtime/aws-smithy-http-auth/Cargo.toml index 45dffe9abd..0d70b25eec 100644 --- a/rust-runtime/aws-smithy-http-auth/Cargo.toml +++ b/rust-runtime/aws-smithy-http-auth/Cargo.toml @@ -10,6 +10,9 @@ edition = "2021" license = "Apache-2.0" repository = "https://github.com/awslabs/smithy-rs" +[dependencies] +zeroize = "1" + [package.metadata.docs.rs] all-features = true targets = ["x86_64-unknown-linux-gnu"] diff --git a/rust-runtime/aws-smithy-http-auth/src/auth.rs b/rust-runtime/aws-smithy-http-auth/src/auth.rs index 771eab5bfb..ae8f086c6f 100644 --- a/rust-runtime/aws-smithy-http-auth/src/auth.rs +++ b/rust-runtime/aws-smithy-http-auth/src/auth.rs @@ -6,6 +6,8 @@ use std::cmp::PartialEq; use std::fmt::Debug; +use std::sync::Arc; +use zeroize::Zeroizing; #[derive(Debug, PartialEq)] enum AuthErrorKind { @@ -39,42 +41,49 @@ impl From for AuthError { } /// Authentication configuration to connect to a Smithy Service -#[derive(Clone, Debug, PartialEq)] -pub struct AuthApiKey { - api_key: String, +#[derive(Clone, Eq, PartialEq)] +pub struct AuthApiKey(Arc); + +#[derive(Clone, Eq, PartialEq)] +struct Inner { + api_key: Zeroizing, +} + +impl Debug for AuthApiKey { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + let mut auth_api_key = f.debug_struct("AuthApiKey"); + auth_api_key.field("api_key", &"** redacted **"); + auth_api_key.finish() + } } impl AuthApiKey { /// Constructs a new API key. pub fn new(api_key: impl Into) -> Self { - Self { - api_key: api_key.into(), - } + Self(Arc::new(Inner { + api_key: Zeroizing::new(api_key.into()), + })) } /// Returns the underlying api key. pub fn api_key(&self) -> &str { - &self.api_key - } - - /// Sets the value for the api key - pub fn set_api_key(mut self, api_key: impl Into) -> Self { - self.api_key = api_key.into(); - self + &self.0.api_key } } impl From<&str> for AuthApiKey { fn from(api_key: &str) -> Self { - Self { - api_key: api_key.to_owned(), - } + Self(Arc::new(Inner { + api_key: Zeroizing::new(api_key.to_owned()), + })) } } impl From for AuthApiKey { fn from(api_key: String) -> Self { - Self { api_key } + Self(Arc::new(Inner { + api_key: Zeroizing::new(api_key), + })) } } From accaf9301e579f56281222336ef16bd5a85a7b30 Mon Sep 17 00:00:00 2001 From: Eduardo Rodrigues Date: Mon, 30 Jan 2023 22:22:02 +0100 Subject: [PATCH 27/38] chore: use builder pattern for auth definition --- rust-runtime/aws-smithy-http-auth/src/auth.rs | 221 ++++++++++++------ 1 file changed, 153 insertions(+), 68 deletions(-) diff --git a/rust-runtime/aws-smithy-http-auth/src/auth.rs b/rust-runtime/aws-smithy-http-auth/src/auth.rs index ae8f086c6f..bd4b8f0ea7 100644 --- a/rust-runtime/aws-smithy-http-auth/src/auth.rs +++ b/rust-runtime/aws-smithy-http-auth/src/auth.rs @@ -28,7 +28,7 @@ impl std::fmt::Display for AuthError { InvalidLocation => write!(f, "invalid location: expected `header` or `query`"), SchemeNotAllowed => write!( f, - "scheme only allowed when it is set into the `Authorization header`" + "scheme only allowed when it is set into the `Authorization` header" ), } } @@ -87,93 +87,129 @@ impl From for AuthApiKey { } } -/// An HTTP-specific authentication scheme that sends an arbitrary +/// Enum for describing where the HTTP Auth can be placed. +#[derive(Copy, Clone, Debug, Default, Eq, PartialEq)] +pub enum HttpAuthLocation { + /// In the HTTP header. + #[default] Header, + /// In the query string of the URL. + Query, +} + +impl HttpAuthLocation { + fn as_str(&self) -> &'static str { + match self { + Self::Header => "header", + Self::Query => "query" + } + } +} + +impl TryFrom<&str> for HttpAuthLocation { + type Error = AuthError; + fn try_from(value: &str) -> Result { + match value { + "header" => Ok(Self::Header), + "query" => Ok(Self::Query), + _ => Err(AuthError::from(AuthErrorKind::InvalidLocation)) + } + } +} + +impl TryFrom for HttpAuthLocation { + type Error = AuthError; + fn try_from(value: String) -> Result { + Self::try_from(value.as_str()) + } +} + +impl AsRef for HttpAuthLocation { + fn as_ref(&self) -> &str { + self.as_str() + } +} + +impl std::fmt::Display for HttpAuthLocation { + fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { + std::fmt::Display::fmt(&self.as_str(), f) + } +} + +/// A HTTP-specific authentication scheme that sends an arbitrary /// auth value in a header or query string parameter. // As described in the Smithy documentation: // https://github.com/awslabs/smithy/blob/main/smithy-model/src/main/resources/software/amazon/smithy/model/loader/prelude.smithy -#[derive(Clone, Debug, PartialEq)] +#[derive(Clone, Debug, Default, PartialEq)] pub struct HttpAuthDefinition { - /// Defines the location of where the Auth is serialized. This value - /// can be set to `"header"` or `"query"`. - location: String, + /// Defines the location of where the Auth is serialized. + location: HttpAuthLocation, /// Defines the name of the HTTP header or query string parameter /// that contains the Auth. name: String, /// Defines the security scheme to use on the `Authorization` header value. - /// This can only be set if the "in" property is set to `"header"`. + /// This can only be set if the "location" property is set to [`HttpAuthLocation::Header`]. scheme: Option, } impl HttpAuthDefinition { - /// Constructs a new HTTP auth definition. - fn new(location: String, name: String, scheme: S) -> Result - where - S: Into>, - { - if location != "header" && location != "query" { - return Err(AuthError::from(AuthErrorKind::InvalidLocation)); - } - Ok(Self { - location, - name, - scheme: scheme.into(), - }) + /// Returns a builder for `HttpAuthDefinition`. + pub fn builder() -> http_auth_definition::Builder { + http_auth_definition::Builder::default() } /// Constructs a new HTTP auth definition in header. - pub fn new_with_header(header_name: N, scheme: S) -> Result + pub fn header(header_name: N, scheme: S) -> Result where N: Into, S: Into>, { - let name: String = header_name.into(); - let scheme: Option = scheme.into(); - if scheme.is_some() && !name.eq_ignore_ascii_case("authorization") { - return Err(AuthError::from(AuthErrorKind::SchemeNotAllowed)); - } - HttpAuthDefinition::new("header".to_owned(), name, scheme) + Self::builder() + .location(HttpAuthLocation::Header) + .name(header_name) + .scheme(scheme) + .build() } /// Constructs a new HTTP auth definition following the RFC 2617 for Basic Auth. - pub fn new_with_basic_auth() -> Self { - HttpAuthDefinition::new( - "header".to_owned(), - "Authorization".to_owned(), - "Basic".to_owned(), - ) - .unwrap() + pub fn basic_auth() -> Result { + Self::builder() + .location(HttpAuthLocation::Header) + .name("Authorization".to_owned()) + .scheme("Basic".to_owned()) + .build() } /// Constructs a new HTTP auth definition following the RFC 2617 for Digest Auth. - pub fn new_with_digest_auth() -> Self { - HttpAuthDefinition::new( - "header".to_owned(), - "Authorization".to_owned(), - "Digest".to_owned(), - ) - .unwrap() + pub fn digest_auth() -> Result { + Self::builder() + .location(HttpAuthLocation::Header) + .name("Authorization".to_owned()) + .scheme("Digest".to_owned()) + .build() } /// Constructs a new HTTP auth definition following the RFC 6750 for Bearer Auth. - pub fn new_with_bearer_auth() -> Self { - HttpAuthDefinition::new( - "header".to_owned(), - "Authorization".to_owned(), - "Bearer".to_owned(), - ) - .unwrap() + pub fn bearer_auth() -> Result { + Self::builder() + .location(HttpAuthLocation::Header) + .name("Authorization".to_owned()) + .scheme("Bearer".to_owned()) + .build() } /// Constructs a new HTTP auth definition in query string. - pub fn new_with_query(name: impl Into) -> Self { - HttpAuthDefinition::new("query".to_owned(), name.into(), None).unwrap() + pub fn query(name: impl Into) -> Result { + Self::builder() + .location(HttpAuthLocation::Query) + .name(name.into()) + .build() } /// Returns the HTTP auth location. - pub fn location(&self) -> &str { - &self.location + pub fn location(&self) -> HttpAuthLocation { + self.location } /// Returns the HTTP auth name. @@ -187,11 +223,61 @@ impl HttpAuthDefinition { } } +/// Types associated with [`HttpAuthDefinition`]. +pub mod http_auth_definition { + use super::AuthError; + use super::AuthErrorKind; + use super::HttpAuthDefinition; + use super::HttpAuthLocation; + + /// A builder for [`HttpAuthDefinition`]. + #[derive(Debug, Default)] + pub struct Builder { + location: HttpAuthLocation, + name: String, + scheme: Option, + } + + impl Builder { + /// Sets the HTTP auth location. + pub fn location(mut self, location: HttpAuthLocation) -> Self { + self.location = location; + self + } + + /// Sets the the HTTP auth name. + pub fn name(mut self, name: impl Into) -> Self { + self.name = name.into(); + self + } + + /// Sets the HTTP auth scheme. + pub fn scheme(mut self, scheme: impl Into>) -> Self { + let scheme: Option = scheme.into(); + self.scheme = scheme; + self + } + + /// Constructs a [`HttpAuthDefinition`] from the builder. + pub fn build(self) -> Result { + if self.scheme.is_some() && !self.name.eq_ignore_ascii_case("authorization") { + return Err(AuthError::from(AuthErrorKind::SchemeNotAllowed)); + } + Ok(HttpAuthDefinition { + location: self.location, + name: self.name, + scheme: self.scheme, + }) + } + } +} + #[cfg(test)] mod tests { use crate::auth::AuthApiKey; use crate::auth::AuthErrorKind; use crate::auth::HttpAuthDefinition; + use crate::auth::HttpAuthLocation; #[test] fn api_key_is_equal() { @@ -208,17 +294,16 @@ mod tests { } #[test] - fn auth_definition_fails_with_invalid_location() { - let result = - HttpAuthDefinition::new("invalid".to_owned(), "".to_owned(), None).map_err(|e| e.kind); + fn auth_location_fails_when_invalid() { + let result = HttpAuthLocation::try_from("invalid").map_err(|e| e.kind); let expected = Err(AuthErrorKind::InvalidLocation); assert_eq!(expected, result); } #[test] fn auth_definition_for_header_without_scheme() { - let definition = HttpAuthDefinition::new_with_header("Header", None).unwrap(); - assert_eq!(definition.location, "header"); + let definition = HttpAuthDefinition::header("Header", None).unwrap(); + assert_eq!(definition.location, HttpAuthLocation::Header); assert_eq!(definition.name, "Header"); assert_eq!(definition.scheme, None); } @@ -226,15 +311,15 @@ mod tests { #[test] fn auth_definition_for_authorization_header_with_scheme() { let definition = - HttpAuthDefinition::new_with_header("authorization", "Scheme".to_owned()).unwrap(); - assert_eq!(definition.location(), "header"); + HttpAuthDefinition::header("authorization", "Scheme".to_owned()).unwrap(); + assert_eq!(definition.location(), HttpAuthLocation::Header); assert_eq!(definition.name(), "authorization"); assert_eq!(definition.scheme(), Some("Scheme")); } #[test] fn auth_definition_fails_with_scheme_not_allowed() { - let result = HttpAuthDefinition::new_with_header("Invalid".to_owned(), "Scheme".to_owned()) + let result = HttpAuthDefinition::header("Invalid".to_owned(), "Scheme".to_owned()) .map_err(|e| e.kind); let expected = Err(AuthErrorKind::SchemeNotAllowed); assert_eq!(expected, result); @@ -242,11 +327,11 @@ mod tests { #[test] fn auth_definition_for_basic() { - let definition = HttpAuthDefinition::new_with_basic_auth(); + let definition = HttpAuthDefinition::basic_auth().unwrap(); assert_eq!( definition, HttpAuthDefinition { - location: "header".to_owned(), + location: HttpAuthLocation::Header, name: "Authorization".to_owned(), scheme: Some("Basic".to_owned()), } @@ -255,24 +340,24 @@ mod tests { #[test] fn auth_definition_for_digest() { - let definition = HttpAuthDefinition::new_with_digest_auth(); - assert_eq!(definition.location(), "header"); + let definition = HttpAuthDefinition::digest_auth().unwrap(); + assert_eq!(definition.location(), HttpAuthLocation::Header); assert_eq!(definition.name(), "Authorization"); assert_eq!(definition.scheme(), Some("Digest")); } #[test] fn auth_definition_for_bearer_token() { - let definition = HttpAuthDefinition::new_with_bearer_auth(); - assert_eq!(definition.location(), "header"); + let definition = HttpAuthDefinition::bearer_auth().unwrap(); + assert_eq!(definition.location(), HttpAuthLocation::Header); assert_eq!(definition.name(), "Authorization"); assert_eq!(definition.scheme(), Some("Bearer")); } #[test] fn auth_definition_for_query() { - let definition = HttpAuthDefinition::new_with_query("query_key"); - assert_eq!(definition.location(), "query"); + let definition = HttpAuthDefinition::query("query_key").unwrap(); + assert_eq!(definition.location(), HttpAuthLocation::Query); assert_eq!(definition.name(), "query_key"); assert_eq!(definition.scheme(), None); } From 87f76fa2fdabfcf09a06faa6dde1b9ed99d826d0 Mon Sep 17 00:00:00 2001 From: Eduardo Rodrigues Date: Mon, 30 Jan 2023 22:47:52 +0100 Subject: [PATCH 28/38] chore: restructure http auth package --- .../aws-smithy-http-auth/src/api_key.rs | 75 +++++++ .../src/{auth.rs => definition.rs} | 192 +++--------------- .../aws-smithy-http-auth/src/error.rs | 39 ++++ rust-runtime/aws-smithy-http-auth/src/lib.rs | 7 +- .../aws-smithy-http-auth/src/location.rs | 72 +++++++ 5 files changed, 215 insertions(+), 170 deletions(-) create mode 100644 rust-runtime/aws-smithy-http-auth/src/api_key.rs rename rust-runtime/aws-smithy-http-auth/src/{auth.rs => definition.rs} (56%) create mode 100644 rust-runtime/aws-smithy-http-auth/src/error.rs create mode 100644 rust-runtime/aws-smithy-http-auth/src/location.rs diff --git a/rust-runtime/aws-smithy-http-auth/src/api_key.rs b/rust-runtime/aws-smithy-http-auth/src/api_key.rs new file mode 100644 index 0000000000..b6088dfc92 --- /dev/null +++ b/rust-runtime/aws-smithy-http-auth/src/api_key.rs @@ -0,0 +1,75 @@ +/* + * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. + * SPDX-License-Identifier: Apache-2.0 + */ + +use std::cmp::PartialEq; +use std::fmt::Debug; +use std::sync::Arc; +use zeroize::Zeroizing; + +/// Authentication configuration to connect to a Smithy Service +#[derive(Clone, Eq, PartialEq)] +pub struct AuthApiKey(Arc); + +#[derive(Clone, Eq, PartialEq)] +struct Inner { + api_key: Zeroizing, +} + +impl Debug for AuthApiKey { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + let mut auth_api_key = f.debug_struct("AuthApiKey"); + auth_api_key.field("api_key", &"** redacted **"); + auth_api_key.finish() + } +} + +impl AuthApiKey { + /// Constructs a new API key. + pub fn new(api_key: impl Into) -> Self { + Self(Arc::new(Inner { + api_key: Zeroizing::new(api_key.into()), + })) + } + + /// Returns the underlying api key. + pub fn api_key(&self) -> &str { + &self.0.api_key + } +} + +impl From<&str> for AuthApiKey { + fn from(api_key: &str) -> Self { + Self(Arc::new(Inner { + api_key: Zeroizing::new(api_key.to_owned()), + })) + } +} + +impl From for AuthApiKey { + fn from(api_key: String) -> Self { + Self(Arc::new(Inner { + api_key: Zeroizing::new(api_key), + })) + } +} + +#[cfg(test)] +mod tests { + use super::AuthApiKey; + + #[test] + fn api_key_is_equal() { + let api_key_a: AuthApiKey = "some-api-key".into(); + let api_key_b = AuthApiKey::new("some-api-key"); + assert_eq!(api_key_a, api_key_b); + } + + #[test] + fn api_key_is_different() { + let api_key_a = AuthApiKey::new("some-api-key"); + let api_key_b: AuthApiKey = String::from("another-api-key").into(); + assert_ne!(api_key_a, api_key_b); + } +} diff --git a/rust-runtime/aws-smithy-http-auth/src/auth.rs b/rust-runtime/aws-smithy-http-auth/src/definition.rs similarity index 56% rename from rust-runtime/aws-smithy-http-auth/src/auth.rs rename to rust-runtime/aws-smithy-http-auth/src/definition.rs index bd4b8f0ea7..cef757b944 100644 --- a/rust-runtime/aws-smithy-http-auth/src/auth.rs +++ b/rust-runtime/aws-smithy-http-auth/src/definition.rs @@ -4,136 +4,10 @@ */ //! Smithy HTTP Auth Types +use crate::error::AuthError; +use crate::location::HttpAuthLocation; use std::cmp::PartialEq; use std::fmt::Debug; -use std::sync::Arc; -use zeroize::Zeroizing; - -#[derive(Debug, PartialEq)] -enum AuthErrorKind { - InvalidLocation, - SchemeNotAllowed, -} - -/// Error for Smithy authentication -#[derive(Debug)] -pub struct AuthError { - kind: AuthErrorKind, -} - -impl std::fmt::Display for AuthError { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - use AuthErrorKind::*; - match &self.kind { - InvalidLocation => write!(f, "invalid location: expected `header` or `query`"), - SchemeNotAllowed => write!( - f, - "scheme only allowed when it is set into the `Authorization` header" - ), - } - } -} - -impl From for AuthError { - fn from(kind: AuthErrorKind) -> Self { - Self { kind } - } -} - -/// Authentication configuration to connect to a Smithy Service -#[derive(Clone, Eq, PartialEq)] -pub struct AuthApiKey(Arc); - -#[derive(Clone, Eq, PartialEq)] -struct Inner { - api_key: Zeroizing, -} - -impl Debug for AuthApiKey { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - let mut auth_api_key = f.debug_struct("AuthApiKey"); - auth_api_key.field("api_key", &"** redacted **"); - auth_api_key.finish() - } -} - -impl AuthApiKey { - /// Constructs a new API key. - pub fn new(api_key: impl Into) -> Self { - Self(Arc::new(Inner { - api_key: Zeroizing::new(api_key.into()), - })) - } - - /// Returns the underlying api key. - pub fn api_key(&self) -> &str { - &self.0.api_key - } -} - -impl From<&str> for AuthApiKey { - fn from(api_key: &str) -> Self { - Self(Arc::new(Inner { - api_key: Zeroizing::new(api_key.to_owned()), - })) - } -} - -impl From for AuthApiKey { - fn from(api_key: String) -> Self { - Self(Arc::new(Inner { - api_key: Zeroizing::new(api_key), - })) - } -} - -/// Enum for describing where the HTTP Auth can be placed. -#[derive(Copy, Clone, Debug, Default, Eq, PartialEq)] -pub enum HttpAuthLocation { - /// In the HTTP header. - #[default] Header, - /// In the query string of the URL. - Query, -} - -impl HttpAuthLocation { - fn as_str(&self) -> &'static str { - match self { - Self::Header => "header", - Self::Query => "query" - } - } -} - -impl TryFrom<&str> for HttpAuthLocation { - type Error = AuthError; - fn try_from(value: &str) -> Result { - match value { - "header" => Ok(Self::Header), - "query" => Ok(Self::Query), - _ => Err(AuthError::from(AuthErrorKind::InvalidLocation)) - } - } -} - -impl TryFrom for HttpAuthLocation { - type Error = AuthError; - fn try_from(value: String) -> Result { - Self::try_from(value.as_str()) - } -} - -impl AsRef for HttpAuthLocation { - fn as_ref(&self) -> &str { - self.as_str() - } -} - -impl std::fmt::Display for HttpAuthLocation { - fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { - std::fmt::Display::fmt(&self.as_str(), f) - } -} /// A HTTP-specific authentication scheme that sends an arbitrary /// auth value in a header or query string parameter. @@ -225,10 +99,11 @@ impl HttpAuthDefinition { /// Types associated with [`HttpAuthDefinition`]. pub mod http_auth_definition { - use super::AuthError; - use super::AuthErrorKind; use super::HttpAuthDefinition; - use super::HttpAuthLocation; + use crate::{ + definition::HttpAuthLocation, + error::{AuthError, AuthErrorKind}, + }; /// A builder for [`HttpAuthDefinition`]. #[derive(Debug, Default)] @@ -274,34 +149,14 @@ pub mod http_auth_definition { #[cfg(test)] mod tests { - use crate::auth::AuthApiKey; - use crate::auth::AuthErrorKind; - use crate::auth::HttpAuthDefinition; - use crate::auth::HttpAuthLocation; - - #[test] - fn api_key_is_equal() { - let api_key_a: AuthApiKey = "some-api-key".into(); - let api_key_b = AuthApiKey::new("some-api-key"); - assert_eq!(api_key_a, api_key_b); - } - - #[test] - fn api_key_is_different() { - let api_key_a = AuthApiKey::new("some-api-key"); - let api_key_b: AuthApiKey = String::from("another-api-key").into(); - assert_ne!(api_key_a, api_key_b); - } - - #[test] - fn auth_location_fails_when_invalid() { - let result = HttpAuthLocation::try_from("invalid").map_err(|e| e.kind); - let expected = Err(AuthErrorKind::InvalidLocation); - assert_eq!(expected, result); - } + use super::HttpAuthDefinition; + use crate::{ + error::{AuthError, AuthErrorKind}, + location::HttpAuthLocation, + }; #[test] - fn auth_definition_for_header_without_scheme() { + fn definition_for_header_without_scheme() { let definition = HttpAuthDefinition::header("Header", None).unwrap(); assert_eq!(definition.location, HttpAuthLocation::Header); assert_eq!(definition.name, "Header"); @@ -309,24 +164,23 @@ mod tests { } #[test] - fn auth_definition_for_authorization_header_with_scheme() { - let definition = - HttpAuthDefinition::header("authorization", "Scheme".to_owned()).unwrap(); + fn definition_for_authorization_header_with_scheme() { + let definition = HttpAuthDefinition::header("authorization", "Scheme".to_owned()).unwrap(); assert_eq!(definition.location(), HttpAuthLocation::Header); assert_eq!(definition.name(), "authorization"); assert_eq!(definition.scheme(), Some("Scheme")); } #[test] - fn auth_definition_fails_with_scheme_not_allowed() { - let result = HttpAuthDefinition::header("Invalid".to_owned(), "Scheme".to_owned()) - .map_err(|e| e.kind); - let expected = Err(AuthErrorKind::SchemeNotAllowed); - assert_eq!(expected, result); + fn definition_fails_with_scheme_not_allowed() { + let actual = + HttpAuthDefinition::header("Invalid".to_owned(), "Scheme".to_owned()).unwrap_err(); + let expected = AuthError::from(AuthErrorKind::SchemeNotAllowed); + assert_eq!(actual, expected); } #[test] - fn auth_definition_for_basic() { + fn definition_for_basic() { let definition = HttpAuthDefinition::basic_auth().unwrap(); assert_eq!( definition, @@ -339,7 +193,7 @@ mod tests { } #[test] - fn auth_definition_for_digest() { + fn definition_for_digest() { let definition = HttpAuthDefinition::digest_auth().unwrap(); assert_eq!(definition.location(), HttpAuthLocation::Header); assert_eq!(definition.name(), "Authorization"); @@ -347,7 +201,7 @@ mod tests { } #[test] - fn auth_definition_for_bearer_token() { + fn definition_for_bearer_token() { let definition = HttpAuthDefinition::bearer_auth().unwrap(); assert_eq!(definition.location(), HttpAuthLocation::Header); assert_eq!(definition.name(), "Authorization"); @@ -355,7 +209,7 @@ mod tests { } #[test] - fn auth_definition_for_query() { + fn definition_for_query() { let definition = HttpAuthDefinition::query("query_key").unwrap(); assert_eq!(definition.location(), HttpAuthLocation::Query); assert_eq!(definition.name(), "query_key"); diff --git a/rust-runtime/aws-smithy-http-auth/src/error.rs b/rust-runtime/aws-smithy-http-auth/src/error.rs new file mode 100644 index 0000000000..472f3fd51c --- /dev/null +++ b/rust-runtime/aws-smithy-http-auth/src/error.rs @@ -0,0 +1,39 @@ +/* + * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. + * SPDX-License-Identifier: Apache-2.0 + */ +//! Smithy HTTP Auth Types + +use std::cmp::PartialEq; +use std::fmt::Debug; + +#[derive(Debug, Eq, PartialEq)] +pub(crate) enum AuthErrorKind { + InvalidLocation, + SchemeNotAllowed, +} + +/// Error for Smithy authentication +#[derive(Debug, Eq, PartialEq)] +pub struct AuthError { + kind: AuthErrorKind, +} + +impl std::fmt::Display for AuthError { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + use AuthErrorKind::*; + match &self.kind { + InvalidLocation => write!(f, "invalid location: expected `header` or `query`"), + SchemeNotAllowed => write!( + f, + "scheme only allowed when it is set into the `Authorization` header" + ), + } + } +} + +impl From for AuthError { + fn from(kind: AuthErrorKind) -> Self { + Self { kind } + } +} diff --git a/rust-runtime/aws-smithy-http-auth/src/lib.rs b/rust-runtime/aws-smithy-http-auth/src/lib.rs index e6ee489169..2cde02e32f 100644 --- a/rust-runtime/aws-smithy-http-auth/src/lib.rs +++ b/rust-runtime/aws-smithy-http-auth/src/lib.rs @@ -3,4 +3,9 @@ * SPDX-License-Identifier: Apache-2.0 */ -pub mod auth; +//! Smithy HTTP Auth Types + +pub mod api_key; +pub mod definition; +pub mod error; +pub mod location; diff --git a/rust-runtime/aws-smithy-http-auth/src/location.rs b/rust-runtime/aws-smithy-http-auth/src/location.rs new file mode 100644 index 0000000000..3bd8b63756 --- /dev/null +++ b/rust-runtime/aws-smithy-http-auth/src/location.rs @@ -0,0 +1,72 @@ +/* + * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. + * SPDX-License-Identifier: Apache-2.0 + */ +//! Smithy HTTP Auth Types + +use std::cmp::PartialEq; +use std::fmt::Debug; + +use crate::error::{AuthError, AuthErrorKind}; + +/// Enum for describing where the HTTP Auth can be placed. +#[derive(Copy, Clone, Debug, Default, Eq, PartialEq)] +pub enum HttpAuthLocation { + /// In the HTTP header. + #[default] + Header, + /// In the query string of the URL. + Query, +} + +impl HttpAuthLocation { + fn as_str(&self) -> &'static str { + match self { + Self::Header => "header", + Self::Query => "query", + } + } +} + +impl TryFrom<&str> for HttpAuthLocation { + type Error = AuthError; + fn try_from(value: &str) -> Result { + match value { + "header" => Ok(Self::Header), + "query" => Ok(Self::Query), + _ => Err(AuthError::from(AuthErrorKind::InvalidLocation)), + } + } +} + +impl TryFrom for HttpAuthLocation { + type Error = AuthError; + fn try_from(value: String) -> Result { + Self::try_from(value.as_str()) + } +} + +impl AsRef for HttpAuthLocation { + fn as_ref(&self) -> &str { + self.as_str() + } +} + +impl std::fmt::Display for HttpAuthLocation { + fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { + std::fmt::Display::fmt(&self.as_str(), f) + } +} + +#[cfg(test)] +mod tests { + use super::HttpAuthLocation; + use crate::error::{AuthError, AuthErrorKind}; + + #[test] + fn fails_if_location_is_invalid() { + let actual = HttpAuthLocation::try_from("invalid").unwrap_err(); + let expected = AuthError::from(AuthErrorKind::InvalidLocation); + assert_eq!(actual, expected); + } +} From 8fcf0d6a718ce9a74d505ab071191aee8abb37dd Mon Sep 17 00:00:00 2001 From: Eduardo Rodrigues Date: Mon, 30 Jan 2023 23:47:16 +0100 Subject: [PATCH 29/38] chore: define default lint warning --- rust-runtime/aws-smithy-http-auth/src/api_key.rs | 2 ++ rust-runtime/aws-smithy-http-auth/src/definition.rs | 3 ++- rust-runtime/aws-smithy-http-auth/src/error.rs | 3 ++- rust-runtime/aws-smithy-http-auth/src/lib.rs | 2 ++ rust-runtime/aws-smithy-http-auth/src/location.rs | 3 ++- 5 files changed, 10 insertions(+), 3 deletions(-) diff --git a/rust-runtime/aws-smithy-http-auth/src/api_key.rs b/rust-runtime/aws-smithy-http-auth/src/api_key.rs index b6088dfc92..62945dfe76 100644 --- a/rust-runtime/aws-smithy-http-auth/src/api_key.rs +++ b/rust-runtime/aws-smithy-http-auth/src/api_key.rs @@ -3,6 +3,8 @@ * SPDX-License-Identifier: Apache-2.0 */ +//! HTTP Auth API Key + use std::cmp::PartialEq; use std::fmt::Debug; use std::sync::Arc; diff --git a/rust-runtime/aws-smithy-http-auth/src/definition.rs b/rust-runtime/aws-smithy-http-auth/src/definition.rs index cef757b944..3a8b16f539 100644 --- a/rust-runtime/aws-smithy-http-auth/src/definition.rs +++ b/rust-runtime/aws-smithy-http-auth/src/definition.rs @@ -2,7 +2,8 @@ * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. * SPDX-License-Identifier: Apache-2.0 */ -//! Smithy HTTP Auth Types + +//! HTTP Auth Definition use crate::error::AuthError; use crate::location::HttpAuthLocation; diff --git a/rust-runtime/aws-smithy-http-auth/src/error.rs b/rust-runtime/aws-smithy-http-auth/src/error.rs index 472f3fd51c..4cf2ac5e2d 100644 --- a/rust-runtime/aws-smithy-http-auth/src/error.rs +++ b/rust-runtime/aws-smithy-http-auth/src/error.rs @@ -2,7 +2,8 @@ * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. * SPDX-License-Identifier: Apache-2.0 */ -//! Smithy HTTP Auth Types + +//! HTTP Auth Error use std::cmp::PartialEq; use std::fmt::Debug; diff --git a/rust-runtime/aws-smithy-http-auth/src/lib.rs b/rust-runtime/aws-smithy-http-auth/src/lib.rs index 2cde02e32f..f5003f8f64 100644 --- a/rust-runtime/aws-smithy-http-auth/src/lib.rs +++ b/rust-runtime/aws-smithy-http-auth/src/lib.rs @@ -3,6 +3,8 @@ * SPDX-License-Identifier: Apache-2.0 */ +#![warn(missing_debug_implementations, missing_docs, rustdoc::all)] + //! Smithy HTTP Auth Types pub mod api_key; diff --git a/rust-runtime/aws-smithy-http-auth/src/location.rs b/rust-runtime/aws-smithy-http-auth/src/location.rs index 3bd8b63756..9fc0ced0e8 100644 --- a/rust-runtime/aws-smithy-http-auth/src/location.rs +++ b/rust-runtime/aws-smithy-http-auth/src/location.rs @@ -2,7 +2,8 @@ * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. * SPDX-License-Identifier: Apache-2.0 */ -//! Smithy HTTP Auth Types + +//! HTTP Auth Location use std::cmp::PartialEq; use std::fmt::Debug; From e3cc30033c6670afa1d92458a8d92e2081d40c7b Mon Sep 17 00:00:00 2001 From: Eduardo Rodrigues Date: Mon, 30 Jan 2023 23:47:58 +0100 Subject: [PATCH 30/38] chore: include http auth in runtime common list --- buildSrc/src/main/kotlin/CrateSet.kt | 1 + 1 file changed, 1 insertion(+) diff --git a/buildSrc/src/main/kotlin/CrateSet.kt b/buildSrc/src/main/kotlin/CrateSet.kt index c915649f61..90e1df95ab 100644 --- a/buildSrc/src/main/kotlin/CrateSet.kt +++ b/buildSrc/src/main/kotlin/CrateSet.kt @@ -21,6 +21,7 @@ object CrateSet { "aws-smithy-checksums", "aws-smithy-eventstream", "aws-smithy-http", + "aws-smithy-http-auth", "aws-smithy-http-tower", "aws-smithy-json", "aws-smithy-protocol-test", From 38e61ed17c465f31f5cd7a5b192cc99ef9503973 Mon Sep 17 00:00:00 2001 From: Eduardo Rodrigues Date: Tue, 31 Jan 2023 00:29:19 +0100 Subject: [PATCH 31/38] chore: define setter for optional scheme --- .../aws-smithy-http-auth/src/definition.rs | 20 +++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) diff --git a/rust-runtime/aws-smithy-http-auth/src/definition.rs b/rust-runtime/aws-smithy-http-auth/src/definition.rs index 3a8b16f539..0ade659b17 100644 --- a/rust-runtime/aws-smithy-http-auth/src/definition.rs +++ b/rust-runtime/aws-smithy-http-auth/src/definition.rs @@ -40,11 +40,14 @@ impl HttpAuthDefinition { N: Into, S: Into>, { - Self::builder() + let mut builder = Self::builder() .location(HttpAuthLocation::Header) - .name(header_name) - .scheme(scheme) - .build() + .name(header_name); + let scheme: Option = scheme.into(); + if scheme.is_some() { + builder.set_scheme(scheme); + } + builder.build() } /// Constructs a new HTTP auth definition following the RFC 2617 for Basic Auth. @@ -128,8 +131,13 @@ pub mod http_auth_definition { } /// Sets the HTTP auth scheme. - pub fn scheme(mut self, scheme: impl Into>) -> Self { - let scheme: Option = scheme.into(); + pub fn scheme(mut self, scheme: impl Into) -> Self { + self.scheme = Some(scheme.into()); + self + } + + /// Sets the HTTP auth scheme. + pub fn set_scheme(&mut self, scheme: Option) -> &mut Self { self.scheme = scheme; self } From ae2ea2e0d0295bec80e5c603f6d0ffb017d6f9cb Mon Sep 17 00:00:00 2001 From: Eduardo Rodrigues Date: Tue, 31 Jan 2023 00:38:43 +0100 Subject: [PATCH 32/38] chore: should panic while building auth definition --- .../aws-smithy-http-auth/src/definition.rs | 44 +++++++++---------- 1 file changed, 20 insertions(+), 24 deletions(-) diff --git a/rust-runtime/aws-smithy-http-auth/src/definition.rs b/rust-runtime/aws-smithy-http-auth/src/definition.rs index 0ade659b17..3cdc506e76 100644 --- a/rust-runtime/aws-smithy-http-auth/src/definition.rs +++ b/rust-runtime/aws-smithy-http-auth/src/definition.rs @@ -5,7 +5,6 @@ //! HTTP Auth Definition -use crate::error::AuthError; use crate::location::HttpAuthLocation; use std::cmp::PartialEq; use std::fmt::Debug; @@ -35,7 +34,7 @@ impl HttpAuthDefinition { } /// Constructs a new HTTP auth definition in header. - pub fn header(header_name: N, scheme: S) -> Result + pub fn header(header_name: N, scheme: S) -> Self where N: Into, S: Into>, @@ -51,7 +50,7 @@ impl HttpAuthDefinition { } /// Constructs a new HTTP auth definition following the RFC 2617 for Basic Auth. - pub fn basic_auth() -> Result { + pub fn basic_auth() -> Self { Self::builder() .location(HttpAuthLocation::Header) .name("Authorization".to_owned()) @@ -60,7 +59,7 @@ impl HttpAuthDefinition { } /// Constructs a new HTTP auth definition following the RFC 2617 for Digest Auth. - pub fn digest_auth() -> Result { + pub fn digest_auth() -> Self { Self::builder() .location(HttpAuthLocation::Header) .name("Authorization".to_owned()) @@ -69,7 +68,7 @@ impl HttpAuthDefinition { } /// Constructs a new HTTP auth definition following the RFC 6750 for Bearer Auth. - pub fn bearer_auth() -> Result { + pub fn bearer_auth() -> Self { Self::builder() .location(HttpAuthLocation::Header) .name("Authorization".to_owned()) @@ -78,7 +77,7 @@ impl HttpAuthDefinition { } /// Constructs a new HTTP auth definition in query string. - pub fn query(name: impl Into) -> Result { + pub fn query(name: impl Into) -> Self { Self::builder() .location(HttpAuthLocation::Query) .name(name.into()) @@ -143,15 +142,17 @@ pub mod http_auth_definition { } /// Constructs a [`HttpAuthDefinition`] from the builder. - pub fn build(self) -> Result { + pub fn build(self) -> HttpAuthDefinition { if self.scheme.is_some() && !self.name.eq_ignore_ascii_case("authorization") { - return Err(AuthError::from(AuthErrorKind::SchemeNotAllowed)); + // Stop execution because the Smithy model should not contain such combination. + // Otherwise, this would cause unexpected behavior in the SDK. + panic!("{}", AuthError::from(AuthErrorKind::SchemeNotAllowed)); } - Ok(HttpAuthDefinition { + HttpAuthDefinition { location: self.location, name: self.name, scheme: self.scheme, - }) + } } } } @@ -159,14 +160,11 @@ pub mod http_auth_definition { #[cfg(test)] mod tests { use super::HttpAuthDefinition; - use crate::{ - error::{AuthError, AuthErrorKind}, - location::HttpAuthLocation, - }; + use crate::location::HttpAuthLocation; #[test] fn definition_for_header_without_scheme() { - let definition = HttpAuthDefinition::header("Header", None).unwrap(); + let definition = HttpAuthDefinition::header("Header", None); assert_eq!(definition.location, HttpAuthLocation::Header); assert_eq!(definition.name, "Header"); assert_eq!(definition.scheme, None); @@ -174,23 +172,21 @@ mod tests { #[test] fn definition_for_authorization_header_with_scheme() { - let definition = HttpAuthDefinition::header("authorization", "Scheme".to_owned()).unwrap(); + let definition = HttpAuthDefinition::header("authorization", "Scheme".to_owned()); assert_eq!(definition.location(), HttpAuthLocation::Header); assert_eq!(definition.name(), "authorization"); assert_eq!(definition.scheme(), Some("Scheme")); } #[test] + #[should_panic] fn definition_fails_with_scheme_not_allowed() { - let actual = - HttpAuthDefinition::header("Invalid".to_owned(), "Scheme".to_owned()).unwrap_err(); - let expected = AuthError::from(AuthErrorKind::SchemeNotAllowed); - assert_eq!(actual, expected); + let _ = HttpAuthDefinition::header("Invalid".to_owned(), "Scheme".to_owned()); } #[test] fn definition_for_basic() { - let definition = HttpAuthDefinition::basic_auth().unwrap(); + let definition = HttpAuthDefinition::basic_auth(); assert_eq!( definition, HttpAuthDefinition { @@ -203,7 +199,7 @@ mod tests { #[test] fn definition_for_digest() { - let definition = HttpAuthDefinition::digest_auth().unwrap(); + let definition = HttpAuthDefinition::digest_auth(); assert_eq!(definition.location(), HttpAuthLocation::Header); assert_eq!(definition.name(), "Authorization"); assert_eq!(definition.scheme(), Some("Digest")); @@ -211,7 +207,7 @@ mod tests { #[test] fn definition_for_bearer_token() { - let definition = HttpAuthDefinition::bearer_auth().unwrap(); + let definition = HttpAuthDefinition::bearer_auth(); assert_eq!(definition.location(), HttpAuthLocation::Header); assert_eq!(definition.name(), "Authorization"); assert_eq!(definition.scheme(), Some("Bearer")); @@ -219,7 +215,7 @@ mod tests { #[test] fn definition_for_query() { - let definition = HttpAuthDefinition::query("query_key").unwrap(); + let definition = HttpAuthDefinition::query("query_key"); assert_eq!(definition.location(), HttpAuthLocation::Query); assert_eq!(definition.name(), "query_key"); assert_eq!(definition.scheme(), None); From 001ee701c51a6ae89942b36057eefb173e1e0b07 Mon Sep 17 00:00:00 2001 From: Eduardo Rodrigues Date: Tue, 31 Jan 2023 01:43:15 +0100 Subject: [PATCH 33/38] chore: return missing required field error --- .../aws-smithy-http-auth/src/definition.rs | 65 +++++++++++++------ .../aws-smithy-http-auth/src/error.rs | 2 + 2 files changed, 46 insertions(+), 21 deletions(-) diff --git a/rust-runtime/aws-smithy-http-auth/src/definition.rs b/rust-runtime/aws-smithy-http-auth/src/definition.rs index 3cdc506e76..2cb2265e10 100644 --- a/rust-runtime/aws-smithy-http-auth/src/definition.rs +++ b/rust-runtime/aws-smithy-http-auth/src/definition.rs @@ -5,6 +5,7 @@ //! HTTP Auth Definition +use crate::error::AuthError; use crate::location::HttpAuthLocation; use std::cmp::PartialEq; use std::fmt::Debug; @@ -34,7 +35,7 @@ impl HttpAuthDefinition { } /// Constructs a new HTTP auth definition in header. - pub fn header(header_name: N, scheme: S) -> Self + pub fn header(header_name: N, scheme: S) -> Result where N: Into, S: Into>, @@ -50,7 +51,7 @@ impl HttpAuthDefinition { } /// Constructs a new HTTP auth definition following the RFC 2617 for Basic Auth. - pub fn basic_auth() -> Self { + pub fn basic_auth() -> Result { Self::builder() .location(HttpAuthLocation::Header) .name("Authorization".to_owned()) @@ -59,7 +60,7 @@ impl HttpAuthDefinition { } /// Constructs a new HTTP auth definition following the RFC 2617 for Digest Auth. - pub fn digest_auth() -> Self { + pub fn digest_auth() -> Result { Self::builder() .location(HttpAuthLocation::Header) .name("Authorization".to_owned()) @@ -68,7 +69,7 @@ impl HttpAuthDefinition { } /// Constructs a new HTTP auth definition following the RFC 6750 for Bearer Auth. - pub fn bearer_auth() -> Self { + pub fn bearer_auth() -> Result { Self::builder() .location(HttpAuthLocation::Header) .name("Authorization".to_owned()) @@ -77,7 +78,7 @@ impl HttpAuthDefinition { } /// Constructs a new HTTP auth definition in query string. - pub fn query(name: impl Into) -> Self { + pub fn query(name: impl Into) -> Result { Self::builder() .location(HttpAuthLocation::Query) .name(name.into()) @@ -111,21 +112,33 @@ pub mod http_auth_definition { /// A builder for [`HttpAuthDefinition`]. #[derive(Debug, Default)] pub struct Builder { - location: HttpAuthLocation, - name: String, + location: Option, + name: Option, scheme: Option, } impl Builder { /// Sets the HTTP auth location. pub fn location(mut self, location: HttpAuthLocation) -> Self { + self.location = Some(location); + self + } + + /// Sets the HTTP auth location. + pub fn set_location(&mut self, location: Option) -> &mut Self { self.location = location; self } /// Sets the the HTTP auth name. pub fn name(mut self, name: impl Into) -> Self { - self.name = name.into(); + self.name = Some(name.into()); + self + } + + /// Sets the the HTTP auth name. + pub fn set_name(&mut self, name: Option) -> &mut Self { + self.name = name; self } @@ -142,17 +155,27 @@ pub mod http_auth_definition { } /// Constructs a [`HttpAuthDefinition`] from the builder. - pub fn build(self) -> HttpAuthDefinition { - if self.scheme.is_some() && !self.name.eq_ignore_ascii_case("authorization") { + pub fn build(self) -> Result { + if self.scheme.is_some() + && self + .name + .as_deref() + .map_or("".to_string(), |s| s.to_ascii_lowercase()) + != "authorization" + { // Stop execution because the Smithy model should not contain such combination. // Otherwise, this would cause unexpected behavior in the SDK. panic!("{}", AuthError::from(AuthErrorKind::SchemeNotAllowed)); } - HttpAuthDefinition { - location: self.location, - name: self.name, + Ok(HttpAuthDefinition { + location: self.location.ok_or_else(|| { + AuthError::from(AuthErrorKind::MissingRequiredField("location")) + })?, + name: self + .name + .ok_or_else(|| AuthError::from(AuthErrorKind::MissingRequiredField("name")))?, scheme: self.scheme, - } + }) } } } @@ -164,7 +187,7 @@ mod tests { #[test] fn definition_for_header_without_scheme() { - let definition = HttpAuthDefinition::header("Header", None); + let definition = HttpAuthDefinition::header("Header", None).unwrap(); assert_eq!(definition.location, HttpAuthLocation::Header); assert_eq!(definition.name, "Header"); assert_eq!(definition.scheme, None); @@ -172,7 +195,7 @@ mod tests { #[test] fn definition_for_authorization_header_with_scheme() { - let definition = HttpAuthDefinition::header("authorization", "Scheme".to_owned()); + let definition = HttpAuthDefinition::header("authorization", "Scheme".to_owned()).unwrap(); assert_eq!(definition.location(), HttpAuthLocation::Header); assert_eq!(definition.name(), "authorization"); assert_eq!(definition.scheme(), Some("Scheme")); @@ -181,12 +204,12 @@ mod tests { #[test] #[should_panic] fn definition_fails_with_scheme_not_allowed() { - let _ = HttpAuthDefinition::header("Invalid".to_owned(), "Scheme".to_owned()); + let _ = HttpAuthDefinition::header("Invalid".to_owned(), "Scheme".to_owned()).unwrap(); } #[test] fn definition_for_basic() { - let definition = HttpAuthDefinition::basic_auth(); + let definition = HttpAuthDefinition::basic_auth().unwrap(); assert_eq!( definition, HttpAuthDefinition { @@ -199,7 +222,7 @@ mod tests { #[test] fn definition_for_digest() { - let definition = HttpAuthDefinition::digest_auth(); + let definition = HttpAuthDefinition::digest_auth().unwrap(); assert_eq!(definition.location(), HttpAuthLocation::Header); assert_eq!(definition.name(), "Authorization"); assert_eq!(definition.scheme(), Some("Digest")); @@ -207,7 +230,7 @@ mod tests { #[test] fn definition_for_bearer_token() { - let definition = HttpAuthDefinition::bearer_auth(); + let definition = HttpAuthDefinition::bearer_auth().unwrap(); assert_eq!(definition.location(), HttpAuthLocation::Header); assert_eq!(definition.name(), "Authorization"); assert_eq!(definition.scheme(), Some("Bearer")); @@ -215,7 +238,7 @@ mod tests { #[test] fn definition_for_query() { - let definition = HttpAuthDefinition::query("query_key"); + let definition = HttpAuthDefinition::query("query_key").unwrap(); assert_eq!(definition.location(), HttpAuthLocation::Query); assert_eq!(definition.name(), "query_key"); assert_eq!(definition.scheme(), None); diff --git a/rust-runtime/aws-smithy-http-auth/src/error.rs b/rust-runtime/aws-smithy-http-auth/src/error.rs index 4cf2ac5e2d..227dbe1cf2 100644 --- a/rust-runtime/aws-smithy-http-auth/src/error.rs +++ b/rust-runtime/aws-smithy-http-auth/src/error.rs @@ -11,6 +11,7 @@ use std::fmt::Debug; #[derive(Debug, Eq, PartialEq)] pub(crate) enum AuthErrorKind { InvalidLocation, + MissingRequiredField(&'static str), SchemeNotAllowed, } @@ -25,6 +26,7 @@ impl std::fmt::Display for AuthError { use AuthErrorKind::*; match &self.kind { InvalidLocation => write!(f, "invalid location: expected `header` or `query`"), + MissingRequiredField(field) => write!(f, "missing required field: {}", field), SchemeNotAllowed => write!( f, "scheme only allowed when it is set into the `Authorization` header" From da25004ea39f41a75af09e2f603d24687ab8d122 Mon Sep 17 00:00:00 2001 From: Eduardo Rodrigues Date: Tue, 31 Jan 2023 01:53:51 +0100 Subject: [PATCH 34/38] chore: make few code simplications for api key --- rust-runtime/aws-smithy-http-auth/src/api_key.rs | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/rust-runtime/aws-smithy-http-auth/src/api_key.rs b/rust-runtime/aws-smithy-http-auth/src/api_key.rs index 62945dfe76..bb2ab65b3c 100644 --- a/rust-runtime/aws-smithy-http-auth/src/api_key.rs +++ b/rust-runtime/aws-smithy-http-auth/src/api_key.rs @@ -22,8 +22,7 @@ struct Inner { impl Debug for AuthApiKey { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { let mut auth_api_key = f.debug_struct("AuthApiKey"); - auth_api_key.field("api_key", &"** redacted **"); - auth_api_key.finish() + auth_api_key.field("api_key", &"** redacted **").finish() } } @@ -43,9 +42,7 @@ impl AuthApiKey { impl From<&str> for AuthApiKey { fn from(api_key: &str) -> Self { - Self(Arc::new(Inner { - api_key: Zeroizing::new(api_key.to_owned()), - })) + Self::from(api_key.to_owned()) } } From 0e5d1ee44a2450e640dd3416be3abada4b3d2811 Mon Sep 17 00:00:00 2001 From: Eduardo Rodrigues Date: Tue, 31 Jan 2023 01:59:48 +0100 Subject: [PATCH 35/38] Revert "chore: add auth api key to external types" This reverts commit b2318b02304fdeefbe5cb8eba80047ae307d08fa. --- aws/rust-runtime/aws-types/external-types.toml | 1 - 1 file changed, 1 deletion(-) diff --git a/aws/rust-runtime/aws-types/external-types.toml b/aws/rust-runtime/aws-types/external-types.toml index 3c779dcc61..71ce4acd8a 100644 --- a/aws/rust-runtime/aws-types/external-types.toml +++ b/aws/rust-runtime/aws-types/external-types.toml @@ -7,7 +7,6 @@ allowed_external_types = [ "aws_smithy_http::endpoint::Endpoint", "aws_smithy_http::endpoint::EndpointPrefix", "aws_smithy_http::endpoint::error::InvalidEndpointError", - "aws_smithy_types::auth::AuthApiKey", "aws_smithy_types::retry::RetryConfig", "aws_smithy_types::timeout::TimeoutConfig", "http::uri::Uri", From b506ff0e4a7f8c19d42b49aac310351bdc2e6289 Mon Sep 17 00:00:00 2001 From: Eduardo Rodrigues Date: Tue, 31 Jan 2023 02:02:30 +0100 Subject: [PATCH 36/38] chore: revert api key from sdk config --- aws/rust-runtime/aws-types/src/sdk_config.rs | 26 -------------------- 1 file changed, 26 deletions(-) diff --git a/aws/rust-runtime/aws-types/src/sdk_config.rs b/aws/rust-runtime/aws-types/src/sdk_config.rs index 0bf6c1c801..77df879722 100644 --- a/aws/rust-runtime/aws-types/src/sdk_config.rs +++ b/aws/rust-runtime/aws-types/src/sdk_config.rs @@ -15,7 +15,6 @@ use aws_credential_types::cache::CredentialsCache; use aws_credential_types::provider::SharedCredentialsProvider; use aws_smithy_async::rt::sleep::AsyncSleep; use aws_smithy_client::http_connector::HttpConnector; -use aws_smithy_types::auth::AuthApiKey; use aws_smithy_types::retry::RetryConfig; use aws_smithy_types::timeout::TimeoutConfig; @@ -54,7 +53,6 @@ pub struct SdkConfig { region: Option, endpoint_resolver: Option>, endpoint_url: Option, - api_key: Option, retry_config: Option, sleep_impl: Option>, timeout_config: Option, @@ -76,7 +74,6 @@ pub struct Builder { region: Option, endpoint_resolver: Option>, endpoint_url: Option, - api_key: Option, retry_config: Option, sleep_impl: Option>, timeout_config: Option, @@ -185,23 +182,6 @@ impl Builder { self } - /// Set the api key to use when making requests. - /// # Examples - /// ``` - /// use aws_types::SdkConfig; - /// let config = SdkConfig::builder().api_key("some-api-key").build(); - /// ``` - pub fn api_key(mut self, api_key: impl Into) -> Self { - self.set_api_key(Some(api_key.into())); - self - } - - /// Set the api key to use when making requests. - pub fn set_api_key(&mut self, api_key: Option) -> &mut Self { - self.api_key = api_key; - self - } - /// Set the retry_config for the builder /// /// _Note:_ Retries require a sleep implementation in order to work. When enabling retry, make @@ -579,7 +559,6 @@ impl Builder { region: self.region, endpoint_resolver: self.endpoint_resolver, endpoint_url: self.endpoint_url, - api_key: self.api_key, retry_config: self.retry_config, sleep_impl: self.sleep_impl, timeout_config: self.timeout_config, @@ -606,11 +585,6 @@ impl SdkConfig { self.endpoint_url.as_deref() } - /// Configured API key - pub fn api_key(&self) -> Option<&AuthApiKey> { - self.api_key.as_ref() - } - /// Configured retry config pub fn retry_config(&self) -> Option<&RetryConfig> { self.retry_config.as_ref() From 9abb7959156c3d040da1ae045f34beebdbf987b4 Mon Sep 17 00:00:00 2001 From: Eduardo Rodrigues Date: Tue, 31 Jan 2023 02:56:26 +0100 Subject: [PATCH 37/38] chore: panic on missing required field --- .../aws-smithy-http-auth/src/definition.rs | 49 ++++++++++--------- 1 file changed, 27 insertions(+), 22 deletions(-) diff --git a/rust-runtime/aws-smithy-http-auth/src/definition.rs b/rust-runtime/aws-smithy-http-auth/src/definition.rs index 2cb2265e10..918f6aae8f 100644 --- a/rust-runtime/aws-smithy-http-auth/src/definition.rs +++ b/rust-runtime/aws-smithy-http-auth/src/definition.rs @@ -5,7 +5,6 @@ //! HTTP Auth Definition -use crate::error::AuthError; use crate::location::HttpAuthLocation; use std::cmp::PartialEq; use std::fmt::Debug; @@ -35,7 +34,7 @@ impl HttpAuthDefinition { } /// Constructs a new HTTP auth definition in header. - pub fn header(header_name: N, scheme: S) -> Result + pub fn header(header_name: N, scheme: S) -> Self where N: Into, S: Into>, @@ -51,7 +50,7 @@ impl HttpAuthDefinition { } /// Constructs a new HTTP auth definition following the RFC 2617 for Basic Auth. - pub fn basic_auth() -> Result { + pub fn basic_auth() -> Self { Self::builder() .location(HttpAuthLocation::Header) .name("Authorization".to_owned()) @@ -60,7 +59,7 @@ impl HttpAuthDefinition { } /// Constructs a new HTTP auth definition following the RFC 2617 for Digest Auth. - pub fn digest_auth() -> Result { + pub fn digest_auth() -> Self { Self::builder() .location(HttpAuthLocation::Header) .name("Authorization".to_owned()) @@ -69,7 +68,7 @@ impl HttpAuthDefinition { } /// Constructs a new HTTP auth definition following the RFC 6750 for Bearer Auth. - pub fn bearer_auth() -> Result { + pub fn bearer_auth() -> Self { Self::builder() .location(HttpAuthLocation::Header) .name("Authorization".to_owned()) @@ -78,7 +77,7 @@ impl HttpAuthDefinition { } /// Constructs a new HTTP auth definition in query string. - pub fn query(name: impl Into) -> Result { + pub fn query(name: impl Into) -> Self { Self::builder() .location(HttpAuthLocation::Query) .name(name.into()) @@ -155,7 +154,7 @@ pub mod http_auth_definition { } /// Constructs a [`HttpAuthDefinition`] from the builder. - pub fn build(self) -> Result { + pub fn build(self) -> HttpAuthDefinition { if self.scheme.is_some() && self .name @@ -167,15 +166,21 @@ pub mod http_auth_definition { // Otherwise, this would cause unexpected behavior in the SDK. panic!("{}", AuthError::from(AuthErrorKind::SchemeNotAllowed)); } - Ok(HttpAuthDefinition { - location: self.location.ok_or_else(|| { - AuthError::from(AuthErrorKind::MissingRequiredField("location")) - })?, - name: self - .name - .ok_or_else(|| AuthError::from(AuthErrorKind::MissingRequiredField("name")))?, + HttpAuthDefinition { + location: self.location.unwrap_or_else(|| { + panic!( + "{}", + AuthError::from(AuthErrorKind::MissingRequiredField("location")) + ) + }), + name: self.name.unwrap_or_else(|| { + panic!( + "{}", + AuthError::from(AuthErrorKind::MissingRequiredField("name")) + ) + }), scheme: self.scheme, - }) + } } } } @@ -187,7 +192,7 @@ mod tests { #[test] fn definition_for_header_without_scheme() { - let definition = HttpAuthDefinition::header("Header", None).unwrap(); + let definition = HttpAuthDefinition::header("Header", None); assert_eq!(definition.location, HttpAuthLocation::Header); assert_eq!(definition.name, "Header"); assert_eq!(definition.scheme, None); @@ -195,7 +200,7 @@ mod tests { #[test] fn definition_for_authorization_header_with_scheme() { - let definition = HttpAuthDefinition::header("authorization", "Scheme".to_owned()).unwrap(); + let definition = HttpAuthDefinition::header("authorization", "Scheme".to_owned()); assert_eq!(definition.location(), HttpAuthLocation::Header); assert_eq!(definition.name(), "authorization"); assert_eq!(definition.scheme(), Some("Scheme")); @@ -204,12 +209,12 @@ mod tests { #[test] #[should_panic] fn definition_fails_with_scheme_not_allowed() { - let _ = HttpAuthDefinition::header("Invalid".to_owned(), "Scheme".to_owned()).unwrap(); + let _ = HttpAuthDefinition::header("Invalid".to_owned(), "Scheme".to_owned()); } #[test] fn definition_for_basic() { - let definition = HttpAuthDefinition::basic_auth().unwrap(); + let definition = HttpAuthDefinition::basic_auth(); assert_eq!( definition, HttpAuthDefinition { @@ -222,7 +227,7 @@ mod tests { #[test] fn definition_for_digest() { - let definition = HttpAuthDefinition::digest_auth().unwrap(); + let definition = HttpAuthDefinition::digest_auth(); assert_eq!(definition.location(), HttpAuthLocation::Header); assert_eq!(definition.name(), "Authorization"); assert_eq!(definition.scheme(), Some("Digest")); @@ -230,7 +235,7 @@ mod tests { #[test] fn definition_for_bearer_token() { - let definition = HttpAuthDefinition::bearer_auth().unwrap(); + let definition = HttpAuthDefinition::bearer_auth(); assert_eq!(definition.location(), HttpAuthLocation::Header); assert_eq!(definition.name(), "Authorization"); assert_eq!(definition.scheme(), Some("Bearer")); @@ -238,7 +243,7 @@ mod tests { #[test] fn definition_for_query() { - let definition = HttpAuthDefinition::query("query_key").unwrap(); + let definition = HttpAuthDefinition::query("query_key"); assert_eq!(definition.location(), HttpAuthLocation::Query); assert_eq!(definition.name(), "query_key"); assert_eq!(definition.scheme(), None); From c9a8416f389cc9b1659ad36b962e791ed02b0c0f Mon Sep 17 00:00:00 2001 From: John DiSanti Date: Mon, 13 Feb 2023 14:32:52 -0800 Subject: [PATCH 38/38] Opt out of `clippy::derive_partial_eq_without_eq` --- rust-runtime/aws-smithy-http-auth/src/lib.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/rust-runtime/aws-smithy-http-auth/src/lib.rs b/rust-runtime/aws-smithy-http-auth/src/lib.rs index f5003f8f64..ada202143e 100644 --- a/rust-runtime/aws-smithy-http-auth/src/lib.rs +++ b/rust-runtime/aws-smithy-http-auth/src/lib.rs @@ -3,6 +3,7 @@ * SPDX-License-Identifier: Apache-2.0 */ +#![allow(clippy::derive_partial_eq_without_eq)] #![warn(missing_debug_implementations, missing_docs, rustdoc::all)] //! Smithy HTTP Auth Types