|
| 1 | +// |
| 2 | +// Copyright Amazon.com Inc. or its affiliates. |
| 3 | +// All Rights Reserved. |
| 4 | +// |
| 5 | +// SPDX-License-Identifier: Apache-2.0 |
| 6 | +// |
| 7 | + |
| 8 | +import Foundation |
| 9 | +import AWSClientRuntime // AWSClientRuntime.CredentialsProviding |
| 10 | +import ClientRuntime // SdkHttpRequestBuilder |
| 11 | +import InternalAmplifyCredentials // AmplifyAWSCredentialsProvider() |
| 12 | +import AwsCommonRuntimeKit // CommonRuntimeKit.initialize() |
| 13 | + |
| 14 | +extension AWSCognitoAuthPlugin { |
| 15 | + |
| 16 | + public static func createAppSyncSigner(region: String) -> ((URLRequest) async throws -> URLRequest) { |
| 17 | + return { request in |
| 18 | + try await signAppSyncRequest(request, region: region) |
| 19 | + } |
| 20 | + } |
| 21 | + public static func signAppSyncRequest(_ urlRequest: URLRequest, |
| 22 | + region: Swift.String, |
| 23 | + credentialsProvider: AWSClientRuntime.CredentialsProviding = AmplifyAWSCredentialsProvider(), |
| 24 | + signingName: Swift.String = "appsync", |
| 25 | + date: ClientRuntime.Date = Date()) async throws -> URLRequest { |
| 26 | + CommonRuntimeKit.initialize() |
| 27 | + |
| 28 | + // Convert URLRequest to SDK's HTTPRequest |
| 29 | + guard let requestBuilder = try createAppSyncSdkHttpRequestBuilder( |
| 30 | + urlRequest: urlRequest) else { |
| 31 | + return urlRequest |
| 32 | + } |
| 33 | + |
| 34 | + // Retrieve the credentials from credentials provider |
| 35 | + let credentials = try await credentialsProvider.getCredentials() |
| 36 | + |
| 37 | + // Prepare signing |
| 38 | + let flags = SigningFlags(useDoubleURIEncode: true, |
| 39 | + shouldNormalizeURIPath: true, |
| 40 | + omitSessionToken: false) |
| 41 | + let signedBodyHeader: AWSSignedBodyHeader = .none |
| 42 | + let signedBodyValue: AWSSignedBodyValue = .empty |
| 43 | + let signingConfig = AWSSigningConfig(credentials: credentials, |
| 44 | + signedBodyHeader: signedBodyHeader, |
| 45 | + signedBodyValue: signedBodyValue, |
| 46 | + flags: flags, |
| 47 | + date: date, |
| 48 | + service: signingName, |
| 49 | + region: region, |
| 50 | + signatureType: .requestHeaders, |
| 51 | + signingAlgorithm: .sigv4) |
| 52 | + |
| 53 | + // Sign request |
| 54 | + guard let httpRequest = await AWSSigV4Signer.sigV4SignedRequest( |
| 55 | + requestBuilder: requestBuilder, |
| 56 | + |
| 57 | + signingConfig: signingConfig |
| 58 | + ) else { |
| 59 | + return urlRequest |
| 60 | + } |
| 61 | + |
| 62 | + // Update original request with new headers |
| 63 | + return setHeaders(from: httpRequest, to: urlRequest) |
| 64 | + } |
| 65 | + |
| 66 | + static func setHeaders(from sdkRequest: SdkHttpRequest, to urlRequest: URLRequest) -> URLRequest { |
| 67 | + var urlRequest = urlRequest |
| 68 | + for header in sdkRequest.headers.headers { |
| 69 | + urlRequest.setValue(header.value.joined(separator: ","), forHTTPHeaderField: header.name) |
| 70 | + } |
| 71 | + return urlRequest |
| 72 | + } |
| 73 | + |
| 74 | + static func createAppSyncSdkHttpRequestBuilder(urlRequest: URLRequest) throws -> SdkHttpRequestBuilder? { |
| 75 | + |
| 76 | + guard let url = urlRequest.url, |
| 77 | + let host = url.host else { |
| 78 | + return nil |
| 79 | + } |
| 80 | + |
| 81 | + var headers = urlRequest.allHTTPHeaderFields ?? [:] |
| 82 | + headers.updateValue(host, forKey: "host") |
| 83 | + |
| 84 | + let httpMethod = (urlRequest.httpMethod?.uppercased()) |
| 85 | + .flatMap(HttpMethodType.init(rawValue:)) ?? .get |
| 86 | + |
| 87 | + let queryItems = URLComponents(url: url, resolvingAgainstBaseURL: false)?.queryItems? |
| 88 | + .map { ClientRuntime.SDKURLQueryItem(name: $0.name, value: $0.value)} ?? [] |
| 89 | + |
| 90 | + let requestBuilder = SdkHttpRequestBuilder() |
| 91 | + .withHost(host) |
| 92 | + .withPath(url.path) |
| 93 | + .withQueryItems(queryItems) |
| 94 | + .withMethod(httpMethod) |
| 95 | + .withPort(443) |
| 96 | + .withProtocol(.https) |
| 97 | + .withHeaders(.init(headers)) |
| 98 | + .withBody(.data(urlRequest.httpBody)) |
| 99 | + |
| 100 | + return requestBuilder |
| 101 | + } |
| 102 | +} |
0 commit comments