Skip to content
New issue

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

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

Already on GitHub? Sign in to your account

feat(smithy-http-auth): add api key auth types #2153

Merged
merged 47 commits into from
Feb 13, 2023
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
47 commits
Select commit Hold shift + click to select a range
cf7cf0e
feat(aws-types): add api key to configuration
eduardomourar Dec 26, 2022
da660fc
chore: set package version to 0.52.0
eduardomourar Dec 26, 2022
d8750e2
feat(aws-smithy-types): create auth types
eduardomourar Dec 26, 2022
05deb97
chore: use auth from smithy types
eduardomourar Dec 26, 2022
8ba9a1c
chore: fix return self type
eduardomourar Dec 26, 2022
3a10084
chore: create http auth definition type
eduardomourar Dec 29, 2022
c8f6701
chore: add constructor for http auth definition
eduardomourar Dec 29, 2022
cba79fb
chore: ensure properties are not moved
eduardomourar Dec 30, 2022
b3b8d7e
chore: create convenience constructors
eduardomourar Dec 30, 2022
16bd634
chore: add some todo comments
eduardomourar Dec 31, 2022
dae2980
feat: move query writer to aws-smithy-http crate
eduardomourar Dec 31, 2022
d06aa3a
chore(codegen): expose smithy http tower dependency
eduardomourar Dec 31, 2022
64dd5bf
chore: remove setters for auth definition
eduardomourar Jan 1, 2023
11be011
chore: fix logical error for scheme not allowed
eduardomourar Jan 1, 2023
4a44293
chore: add constructor for basic and digest auth
eduardomourar Jan 1, 2023
5fd556e
chore: allow equality comparision for api key
eduardomourar Jan 2, 2023
10ea5b1
Revert "chore: set package version to 0.52.0"
eduardomourar Jan 2, 2023
a246595
Merge branch 'main' into feat/api-key-auth
eduardomourar Jan 2, 2023
889b9d3
chore: fix additional references to querywriter
eduardomourar Jan 2, 2023
57df9cb
chore: implement from string for api key struct
eduardomourar Jan 3, 2023
7b0e877
chore: disallow none api key in sdk config
eduardomourar Jan 3, 2023
f504249
chore: fix formatting
eduardomourar Jan 3, 2023
8d731b8
chore: add unit tests for auth types
eduardomourar Jan 3, 2023
b2318b0
chore: add auth api key to external types
eduardomourar Jan 3, 2023
b2a23a0
chore: make query writer doc hidden
eduardomourar Jan 30, 2023
16d65f8
feat: create aws-smithy-http-auth crate
eduardomourar Jan 30, 2023
05657e1
chore: use zeroing for auth api key
eduardomourar Jan 30, 2023
accaf93
chore: use builder pattern for auth definition
eduardomourar Jan 30, 2023
87f76fa
chore: restructure http auth package
eduardomourar Jan 30, 2023
ab058ed
Merge branch 'main' into feat/api-key-auth
eduardomourar Jan 30, 2023
8fcf0d6
chore: define default lint warning
eduardomourar Jan 30, 2023
e3cc300
chore: include http auth in runtime common list
eduardomourar Jan 30, 2023
38e61ed
chore: define setter for optional scheme
eduardomourar Jan 30, 2023
ae2ea2e
chore: should panic while building auth definition
eduardomourar Jan 30, 2023
001ee70
chore: return missing required field error
eduardomourar Jan 31, 2023
da25004
chore: make few code simplications for api key
eduardomourar Jan 31, 2023
69a1c4d
Merge branch 'main' into feat/api-key-auth
eduardomourar Jan 31, 2023
0e5d1ee
Revert "chore: add auth api key to external types"
eduardomourar Jan 31, 2023
b506ff0
chore: revert api key from sdk config
eduardomourar Jan 31, 2023
9abb795
chore: panic on missing required field
eduardomourar Jan 31, 2023
f560406
Merge branch 'main' into feat/api-key-auth
eduardomourar Jan 31, 2023
1ef3a38
Merge branch 'main' into feat/api-key-auth
jdisanti Feb 3, 2023
5b9ea0d
Merge branch 'main' into feat/api-key-auth
eduardomourar Feb 3, 2023
436c809
Merge remote-tracking branch 'origin/main' into eduardomourar-api-key…
jdisanti Feb 13, 2023
3d7ef89
Merge branch 'main' into feat/api-key-auth
eduardomourar Feb 13, 2023
f23760a
Merge branch 'main' into feat/api-key-auth
jdisanti Feb 13, 2023
c9a8416
Opt out of `clippy::derive_partial_eq_without_eq`
jdisanti Feb 13, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
65 changes: 44 additions & 21 deletions rust-runtime/aws-smithy-http-auth/src/definition.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@

//! HTTP Auth Definition

use crate::error::AuthError;
use crate::location::HttpAuthLocation;
use std::cmp::PartialEq;
use std::fmt::Debug;
Expand Down Expand Up @@ -34,7 +35,7 @@ impl HttpAuthDefinition {
}

/// Constructs a new HTTP auth definition in header.
pub fn header<N, S>(header_name: N, scheme: S) -> Self
pub fn header<N, S>(header_name: N, scheme: S) -> Result<Self, AuthError>
where
N: Into<String>,
S: Into<Option<String>>,
Expand All @@ -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, AuthError> {
Self::builder()
.location(HttpAuthLocation::Header)
.name("Authorization".to_owned())
Expand All @@ -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, AuthError> {
Self::builder()
.location(HttpAuthLocation::Header)
.name("Authorization".to_owned())
Expand All @@ -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, AuthError> {
Self::builder()
.location(HttpAuthLocation::Header)
.name("Authorization".to_owned())
Expand All @@ -77,7 +78,7 @@ impl HttpAuthDefinition {
}

/// Constructs a new HTTP auth definition in query string.
pub fn query(name: impl Into<String>) -> Self {
pub fn query(name: impl Into<String>) -> Result<Self, AuthError> {
Self::builder()
.location(HttpAuthLocation::Query)
.name(name.into())
Expand Down Expand Up @@ -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<HttpAuthLocation>,
name: Option<String>,
scheme: Option<String>,
}

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<HttpAuthLocation>) -> &mut Self {
self.location = location;
self
}

/// Sets the the HTTP auth name.
pub fn name(mut self, name: impl Into<String>) -> 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<String>) -> &mut Self {
self.name = name;
self
}

Expand All @@ -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<HttpAuthDefinition, AuthError> {
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")))?,
eduardomourar marked this conversation as resolved.
Show resolved Hide resolved
scheme: self.scheme,
}
})
}
}
}
Expand All @@ -164,15 +187,15 @@ 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);
}

#[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"));
Expand All @@ -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 {
Expand All @@ -199,23 +222,23 @@ 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"));
}

#[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"));
}

#[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);
Expand Down
2 changes: 2 additions & 0 deletions rust-runtime/aws-smithy-http-auth/src/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ use std::fmt::Debug;
#[derive(Debug, Eq, PartialEq)]
pub(crate) enum AuthErrorKind {
InvalidLocation,
MissingRequiredField(&'static str),
SchemeNotAllowed,
}

Expand All @@ -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"
Expand Down