Skip to content

Commit

Permalink
feat: Expose sigv4 signer for SdkHttpRequestBuilder (#414)
Browse files Browse the repository at this point in the history
  • Loading branch information
wooj2 authored Sep 30, 2021
1 parent 7b4363c commit 8556dbc
Show file tree
Hide file tree
Showing 2 changed files with 123 additions and 0 deletions.
68 changes: 68 additions & 0 deletions AWSClientRuntime/Sources/Signing/AWSSigV4Signer.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
//
// Copyright Amazon.com Inc. or its affiliates.
// All Rights Reserved.
//
// SPDX-License-Identifier: Apache-2.0
//

import ClientRuntime
import AwsCommonRuntimeKit

public class AWSSigV4Signer {
static let logger: SwiftLogger = SwiftLogger(label: "AWSSigV4Signer")

public static func sigV4SignedURL(requestBuilder: SdkHttpRequestBuilder,
credentialsProvider: CredentialsProvider,
signingName: Swift.String,
signingRegion: Swift.String,
date: ClientRuntime.Date,
expiration: Int64) -> ClientRuntime.URL? {
do {
let credentials = try credentialsProvider.getCredentials()

let flags = SigningFlags(useDoubleURIEncode: true,
shouldNormalizeURIPath: true,
omitSessionToken: false)
let signedBodyHeader: AWSSignedBodyHeader = .none
let signedBodyValue: AWSSignedBodyValue = .empty
let signingConfig = AWSSigningConfig(credentials: credentials,
expiration: expiration,
signedBodyHeader: signedBodyHeader,
signedBodyValue: signedBodyValue,
flags: flags,
date: date,
service: signingName,
region: signingRegion,
signatureType: .requestQueryParams)
let builtRequest = sigV4SignedRequest(requestBuilder: requestBuilder, signingConfig: signingConfig)
guard let presignedURL = builtRequest?.endpoint.url else {
logger.error("Failed to generate presigend url")
return nil
}
return presignedURL
} catch let err {
logger.error("Failed to generate presigned url: \(err)")
return nil
}
}

public static func sigV4SignedRequest(requestBuilder: SdkHttpRequestBuilder,
signingConfig: AWSSigningConfig) -> SdkHttpRequest? {
let originalRequest = requestBuilder.build()
let crtUnsignedRequest = originalRequest.toHttpRequest()
let signer = SigV4HttpRequestSigner()
do {
let result = try signer.signRequest(request: crtUnsignedRequest,
config: signingConfig.toCRTType())
let crtSignedRequest = try result.get()
let sdkSignedRequest = requestBuilder.update(from: crtSignedRequest, originalRequest: originalRequest)
return sdkSignedRequest.build()
} catch CRTError.crtError(let crtError) {
logger.error("Failed to sign request (CRT): \(crtError)")
return nil
} catch let err {
logger.error("Failed to sign request: \(err)")
return nil
}
}
}
55 changes: 55 additions & 0 deletions AWSClientRuntime/Tests/Sigv4/SigV4SigningTests.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
//
// Copyright Amazon.com Inc. or its affiliates.
// All Rights Reserved.
//
// SPDX-License-Identifier: Apache-2.0
//

import AwsCommonRuntimeKit
import ClientRuntime
import XCTest

@testable import AWSClientRuntime

class Sigv4SigningTests: XCTestCase {
override func setUp() {
AwsCommonRuntimeKit.initialize()
}

struct MyCustomCredentialsProvider: CredentialsProvider {
func getCredentials() throws -> AWSCredentials {
return AWSCredentials(accessKey: "AKIDEXAMPLE", secret: "wJalrXUtnFEMI/K7MDENG+bPxRfiCYEXAMPLEKEY", expirationTimeout: 30)
}
}

func testPresigner() throws {
let dateString = "2015-08-30T12:36:00Z"
let dateFormatter = DateFormatter.iso8601DateFormatterWithoutFractionalSeconds
guard let date = dateFormatter.date(from: dateString) else {
XCTFail("Unable to parse date")
return
}


let requestBuilder = SdkHttpRequestBuilder()
.withHost("example.amazonaws.com")
.withPath("")
.withMethod(.get)
.withPort(443)
.withProtocol(.http)
.withHeader(name: "host", value: "example.amazonaws.com")
.withQueryItem(URLQueryItem(name: "%E1%88%B4", value: "bar"))

guard let url = AWSSigV4Signer.sigV4SignedURL(requestBuilder: requestBuilder,
credentialsProvider: MyCustomCredentialsProvider(),
signingName: "service",
signingRegion: "us-east-1",
date: date,
expiration: 86400) else {
XCTFail("Unable to generate URL")
return
}
XCTAssertEqual("http://example.amazonaws.com:443?%E1%88%B4=bar&X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=AKIDEXAMPLE/20150830/us-east-1/service/aws4_request&X-Amz-Date=20150830T123600Z&X-Amz-SignedHeaders=host&X-Amz-Expires=86400&X-Amz-Signature=32dea9080047b41e56ee852fe3eba49dae1911b9c5e5728cc1691704f168c70f", url.absoluteString)
}
}

0 comments on commit 8556dbc

Please sign in to comment.