Unverified Commit c84e404a authored by Russell Cohen's avatar Russell Cohen Committed by GitHub
Browse files

Add KMS example & fix bugs (#227)

* Add KMS example & fix bugs

* Set log to info & assert we got the right number of bytes back
parent cf55bcab
Loading
Loading
Loading
Loading
+18 −3
Original line number Diff line number Diff line
@@ -4,14 +4,16 @@ use std::fmt::{Debug, Display, Formatter};
use std::str::FromStr;
use std::sync::Arc;

use http::Uri;
use http::{HeaderValue, Uri};

use aws_types::region::{Region, SigningRegion};
use aws_types::SigningService;
use http::header::HOST;
use smithy_http::endpoint::{Endpoint, EndpointPrefix};
use smithy_http::middleware::MapRequest;
use smithy_http::operation::Request;
use smithy_http::property_bag::PropertyBag;
use std::convert::TryFrom;

/// Endpoint to connect to an AWS Service
///
@@ -99,8 +101,8 @@ impl ResolveAwsEndpoint for DefaultAwsEndpointResolver {
    fn endpoint(&self, region: &Region) -> Result<AwsEndpoint, BoxError> {
        let uri = Uri::from_str(&format!(
            "https://{}.{}.amazonaws.com",
            self.service,
            region.as_ref(),
            self.service
        ))?;
        Ok(AwsEndpoint {
            endpoint: Endpoint::mutable(uri),
@@ -167,6 +169,14 @@ impl MapRequest for AwsEndpointStage {
            endpoint
                .endpoint
                .set_endpoint(http_req.uri_mut(), config.get::<EndpointPrefix>());
            // host is only None if authority is not. `set_endpoint` guarantees that authority is not None
            let host = http_req
                .uri()
                .host()
                .expect("authority is guaranteed to be non-empty after `set_endpoint`");
            let host = HeaderValue::try_from(host)
                .expect("authority must only contain valid header characters");
            http_req.headers_mut().insert(HOST, host);
            Ok(http_req)
        })
    }
@@ -185,6 +195,7 @@ mod test {
    use smithy_http::operation;

    use crate::{set_endpoint_resolver, AwsEndpointStage, DefaultAwsEndpointResolver};
    use http::header::HOST;

    #[test]
    fn default_endpoint_updates_request() {
@@ -210,7 +221,11 @@ mod test {
        let (req, _conf) = req.into_parts();
        assert_eq!(
            req.uri(),
            &Uri::from_static("https://us-east-1.kinesis.amazonaws.com")
            &Uri::from_static("https://kinesis.us-east-1.amazonaws.com")
        );
        assert_eq!(
            req.headers().get(HOST).expect("host header must be set"),
            "kinesis.us-east-1.amazonaws.com"
        );
    }
}
+4 −3
Original line number Diff line number Diff line
@@ -10,7 +10,7 @@ use aws_hyper::Client;
use aws_sig_auth::signer::OperationSigningConfig;
use aws_types::region::Region;
use bytes::Bytes;
use http::header::AUTHORIZATION;
use http::header::{AUTHORIZATION, HOST};
use http::{Response, Uri};
use smithy_http::body::SdkBody;
use smithy_http::operation;
@@ -61,9 +61,10 @@ fn test_operation() -> Operation<TestOperationParser, ()> {
#[tokio::test]
async fn e2e_test() {
    let expected_req = http::Request::builder()
        .header(AUTHORIZATION, "AWS4-HMAC-SHA256 Credential=access_key/20210215/test-region/test-service/aws4_request, SignedHeaders=, Signature=e8a49c07c540558c4b53a5dcc61cbfb27003381fd8437fca0b3dddcdc703ec44")
        .header(HOST, "test-service.test-region.amazonaws.com")
        .header(AUTHORIZATION, "AWS4-HMAC-SHA256 Credential=access_key/20210215/test-region/test-service/aws4_request, SignedHeaders=host, Signature=b4bccc6f03b22e88b9e52a60314d4629c5d159a7cc2de25b1d687b3e5e480d2c")
        .header("x-amz-date", "20210215T184017Z")
        .uri(Uri::from_static("https://test-region.test-service.amazonaws.com/"))
        .uri(Uri::from_static("https://test-service.test-region.amazonaws.com/"))
        .body(SdkBody::from("request body")).unwrap();
    let events = vec![(
        expected_req,
+1 −1
Original line number Diff line number Diff line
@@ -183,6 +183,6 @@ mod test {
            .headers()
            .get(AUTHORIZATION)
            .expect("auth header must be present");
        assert_eq!(auth_header, "AWS4-HMAC-SHA256 Credential=AKIAfoo/20210120/us-east-1/kinesis/aws4_request, SignedHeaders=, Signature=bf3af0f70e58cb7f70cc545f1b2e83293b3e9860880bf8aef3fae0f3de324427");
        assert_eq!(auth_header, "AWS4-HMAC-SHA256 Credential=AKIAfoo/20210120/us-east-1/kinesis/aws4_request, SignedHeaders=host, Signature=c59f1b9040fe229bf924254d9ad71adaf0495db2ccda5eb6b1565529cdc2c120");
    }
}
+13 −0
Original line number Diff line number Diff line
[package]
name = "kms-helloworld"
version = "0.1.0"
authors = ["Russell Cohen <rcoh@amazon.com>"]
edition = "2018"
description = "Example usage of the KMS service"

[dependencies]
kms = { path = "../../build/aws-sdk/kms" }
aws-hyper = { path = "../../build/aws-sdk/aws-hyper" }
tokio = { version = "1", features = ["full"]}
# optional
env_logger = "0.8.2"
+21 −0
Original line number Diff line number Diff line
use kms::operation::GenerateRandom;
use kms::Region;
use env_logger::Env;

#[tokio::main]
async fn main() {
    env_logger::init_from_env(Env::default().default_filter_or("info"));
    let config = kms::Config::builder()
        // region can also be loaded from AWS_DEFAULT_REGION, just remove this line.
        .region(Region::from("us-east-1"))
        // creds loaded from environment variables, or they can be hard coded.
        // Other credential providers not currently supported
        .build();
    let client = aws_hyper::Client::https();
    let data = client
        .call(GenerateRandom::builder().number_of_bytes(64).build(&config))
        .await
        .expect("failed to generate random data");
    println!("{:?}", data);
    assert_eq!(data.plaintext.expect("should have data").as_ref().len(), 64);
}