Skip to content
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,8 @@ import Amplify
import AWSPluginsCore
import InternalAmplifyCredentials
import Foundation
import ClientRuntime
import SmithyHTTPAPI
import Smithy

typealias AWSRegionType = String

Expand Down Expand Up @@ -41,12 +42,12 @@ struct IAMURLRequestInterceptor: URLRequestInterceptor {
request.setValue(userAgent, forHTTPHeaderField: URLRequestConstants.Header.userAgent)

let httpMethod = (request.httpMethod?.uppercased())
.flatMap(HttpMethodType.init(rawValue:)) ?? .get
.flatMap(HTTPMethodType.init(rawValue:)) ?? .get

let queryItems = URLComponents(url: url, resolvingAgainstBaseURL: false)?.queryItems?
.map { ClientRuntime.SDKURLQueryItem(name: $0.name, value: $0.value)} ?? []
.map { URIQueryItem(name: $0.name, value: $0.value)} ?? []

let requestBuilder = SdkHttpRequestBuilder()
let requestBuilder = HTTPRequestBuilder()
.withHost(host)
.withPath(url.path)
.withQueryItems(queryItems)
Expand All @@ -66,7 +67,7 @@ struct IAMURLRequestInterceptor: URLRequestInterceptor {

guard let urlRequest = try await AmplifyAWSSignatureV4Signer().sigV4SignedRequest(
requestBuilder: requestBuilder,
credentialsProvider: iamCredentialsProvider.getCredentialsProvider(),
credentialIdentityResolver: iamCredentialsProvider.getCredentialIdentityResolver(),
signingName: signingName,
signingRegion: region,
date: Date()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,15 +9,15 @@ import Foundation
@_spi(WebSocket) import AWSPluginsCore
import InternalAmplifyCredentials
import Amplify
import AWSClientRuntime
import ClientRuntime
import SmithyHTTPAPI
import SmithyIdentity

class IAMAuthInterceptor {

let authProvider: CredentialsProviding
let authProvider: any AWSCredentialIdentityResolver
let region: AWSRegionType

init(_ authProvider: CredentialsProviding, region: AWSRegionType) {
init(_ authProvider: some AWSCredentialIdentityResolver, region: AWSRegionType) {
self.authProvider = authProvider
self.region = region
}
Expand All @@ -35,7 +35,7 @@ class IAMAuthInterceptor {
///
/// 1. A request is created with the IAM based auth headers (date, accept, content encoding, content type, and
/// additional headers.
let requestBuilder = SdkHttpRequestBuilder()
let requestBuilder = HTTPRequestBuilder()
.withHost(host)
.withPath(endpoint.path)
.withMethod(.post)
Expand All @@ -51,7 +51,7 @@ class IAMAuthInterceptor {
/// the request headers as authorization and security token.
do {
guard let urlRequest = try await signer.sigV4SignedRequest(requestBuilder: requestBuilder,
credentialsProvider: authProvider,
credentialIdentityResolver: authProvider,
signingName: "appsync",
signingRegion: region,
date: Date()) else {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -101,8 +101,8 @@ actor AppSyncRealTimeClientFactory: AppSyncRealTimeClientFactoryProtocol {
let provider = AWSOIDCAuthProvider(authService: authService)
return AuthTokenInterceptor(getLatestAuthToken: provider.getLatestAuthToken)
case .awsIAM(let awsIAMConfiguration):
return IAMAuthInterceptor(authService.getCredentialsProvider(),
region: awsIAMConfiguration.region)
return IAMAuthInterceptor(authService.getCredentialIdentityResolver(),
region: awsIAMConfiguration.region)
case .openIDConnect:
guard let oidcAuthProvider = apiAuthProviderFactory.oidcAuthProvider() else {
throw APIError.invalidConfiguration(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ import XCTest
class AWSPinpointAnalyticsPluginConfigureTests: AWSPinpointAnalyticsPluginTestBase {

override func setUp() async throws {
AWSPinpointFactory.credentialsProvider = MockCredentialsProvider()
AWSPinpointFactory.credentialIdentityResolver = MockCredentialsProvider()
try await super.setUp()
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,13 @@
import Foundation
import Amplify // Amplify.Auth
import AWSPluginsCore // AuthAWSCredentialsProvider
import AWSClientRuntime // AWSClientRuntime.CredentialsProviding
import ClientRuntime // SdkHttpRequestBuilder
import AwsCommonRuntimeKit // CommonRuntimeKit.initialize()
import AWSSDKHTTPAuth // AWSSigV4Signer
import Smithy // URIQueryItem
import SmithyHTTPAPI
import SmithyHTTPAuth
import SmithyHTTPAuthAPI
import SmithyIdentity // AWSCredentialIdentity

extension AWSCognitoAuthPlugin {

Expand All @@ -29,11 +33,15 @@ extension AWSCognitoAuthPlugin {
region: region)
}
}


private static var signer = {
return AWSSigV4Signer()
}()

static func signAppSyncRequest(_ urlRequest: URLRequest,
region: Swift.String,
signingName: Swift.String = "appsync",
date: ClientRuntime.Date = Date()) async throws -> URLRequest {
date: Date = Date()) async throws -> URLRequest {
CommonRuntimeKit.initialize()

// Convert URLRequest to SDK's HTTPRequest
Expand All @@ -43,11 +51,11 @@ extension AWSCognitoAuthPlugin {
}

// Retrieve the credentials from credentials provider
let credentials: AWSClientRuntime.AWSCredentials
let credentials: AWSCredentialIdentity
let authSession = try await Amplify.Auth.fetchAuthSession()
if let awsCredentialsProvider = authSession as? AuthAWSCredentialsProvider {
let awsCredentials = try awsCredentialsProvider.getAWSCredentials().get()
credentials = awsCredentials.toAWSSDKCredentials()
credentials = try awsCredentials.toAWSSDKCredentials()
} else {
let error = AuthError.unknown("Auth session does not include AWS credentials information")
throw error
Expand All @@ -70,7 +78,7 @@ extension AWSCognitoAuthPlugin {
signingAlgorithm: .sigv4)

// Sign request
guard let httpRequest = await AWSSigV4Signer.sigV4SignedRequest(
guard let httpRequest = await signer.sigV4SignedRequest(
requestBuilder: requestBuilder,

signingConfig: signingConfig
Expand All @@ -82,15 +90,15 @@ extension AWSCognitoAuthPlugin {
return setHeaders(from: httpRequest, to: urlRequest)
}

static func setHeaders(from sdkRequest: SdkHttpRequest, to urlRequest: URLRequest) -> URLRequest {
static func setHeaders(from sdkRequest: SmithyHTTPAPI.HTTPRequest, to urlRequest: URLRequest) -> URLRequest {
var urlRequest = urlRequest
for header in sdkRequest.headers.headers {
urlRequest.setValue(header.value.joined(separator: ","), forHTTPHeaderField: header.name)
}
return urlRequest
}

static func createAppSyncSdkHttpRequestBuilder(urlRequest: URLRequest) throws -> SdkHttpRequestBuilder? {
static func createAppSyncSdkHttpRequestBuilder(urlRequest: URLRequest) throws -> HTTPRequestBuilder? {

guard let url = urlRequest.url,
let host = url.host else {
Expand All @@ -101,12 +109,12 @@ extension AWSCognitoAuthPlugin {
headers.updateValue(host, forKey: "host")

let httpMethod = (urlRequest.httpMethod?.uppercased())
.flatMap(HttpMethodType.init(rawValue:)) ?? .get
.flatMap(HTTPMethodType.init(rawValue:)) ?? .get

let queryItems = URLComponents(url: url, resolvingAgainstBaseURL: false)?.queryItems?
.map { ClientRuntime.SDKURLQueryItem(name: $0.name, value: $0.value)} ?? []
.map { URIQueryItem(name: $0.name, value: $0.value)} ?? []

let requestBuilder = SdkHttpRequestBuilder()
let requestBuilder = HTTPRequestBuilder()
.withHost(host)
.withPath(url.path)
.withQueryItems(queryItems)
Expand All @@ -122,19 +130,20 @@ extension AWSCognitoAuthPlugin {

extension AWSPluginsCore.AWSCredentials {

func toAWSSDKCredentials() -> AWSClientRuntime.AWSCredentials {
func toAWSSDKCredentials() throws -> AWSCredentialIdentity {
if let tempCredentials = self as? AWSTemporaryCredentials {
return AWSClientRuntime.AWSCredentials(
return AWSCredentialIdentity(
accessKey: tempCredentials.accessKeyId,
secret: tempCredentials.secretAccessKey,
expirationTimeout: tempCredentials.expiration,
sessionToken: tempCredentials.sessionToken)
expiration: tempCredentials.expiration,
sessionToken: tempCredentials.sessionToken
)
} else {
return AWSClientRuntime.AWSCredentials(
return AWSCredentialIdentity(
accessKey: accessKeyId,
secret: secretAccessKey,
expirationTimeout: Date())
expiration: nil
)
}

}
}
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@ import ClientRuntime
import AWSClientRuntime
@_spi(PluginHTTPClientEngine) import InternalAmplifyCredentials
@_spi(InternalHttpEngineProxy) import AWSPluginsCore
import SmithyRetriesAPI
import SmithyRetries

extension AWSCognitoAuthPlugin {

Expand Down Expand Up @@ -91,7 +93,8 @@ extension AWSCognitoAuthPlugin {
case .userPools(let userPoolConfig), .userPoolsAndIdentityPools(let userPoolConfig, _):
let configuration = try CognitoIdentityProviderClient.CognitoIdentityProviderClientConfiguration(
region: userPoolConfig.region,
serviceSpecific: .init(endpointResolver: userPoolConfig.endpoint?.resolver)
signingRegion: userPoolConfig.region,
endpointResolver: userPoolConfig.endpoint?.resolver
)

if var httpClientEngineProxy = httpClientEngineProxy {
Expand All @@ -108,11 +111,14 @@ extension AWSCognitoAuthPlugin {
}

if let maxRetryUnwrapped = networkPreferences?.maxRetryCount {
configuration.retryStrategyOptions = RetryStrategyOptions(maxRetriesBase: Int(maxRetryUnwrapped))
configuration.retryStrategyOptions = RetryStrategyOptions(
backoffStrategy: ExponentialBackoffStrategy(),
maxRetriesBase: Int(maxRetryUnwrapped)
)
}

let authService = AWSAuthService()
configuration.credentialsProvider = authService.getCredentialsProvider()
configuration.awsCredentialIdentityResolver = authService.getCredentialIdentityResolver()

return CognitoIdentityProviderClient(config: configuration)
default:
Expand All @@ -133,11 +139,14 @@ extension AWSCognitoAuthPlugin {
}

if let maxRetryUnwrapped = networkPreferences?.maxRetryCount {
configuration.retryStrategyOptions = RetryStrategyOptions(maxRetriesBase: Int(maxRetryUnwrapped))
configuration.retryStrategyOptions = RetryStrategyOptions(
backoffStrategy: ExponentialBackoffStrategy(),
maxRetriesBase: Int(maxRetryUnwrapped)
)
}

let authService = AWSAuthService()
configuration.credentialsProvider = authService.getCredentialsProvider()
configuration.awsCredentialIdentityResolver = authService.getCredentialIdentityResolver()

return CognitoIdentityClient(config: configuration)
default:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ enum AuthChallengeType {

}

extension CognitoIdentityProviderClientTypes.ChallengeNameType {
extension CognitoIdentityProviderClientTypes.ChallengeNameType: Codable {
var authChallengeType: AuthChallengeType {
switch self {
case .customChallenge:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
import Foundation
import Amplify
import AWSCognitoIdentityProvider
import AWSClientRuntime
@_spi(UnknownAWSHTTPServiceError) import AWSClientRuntime

extension ForbiddenException: AuthErrorConvertible {
var fallbackDescription: String { "Access to the requested resource is forbidden" }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,18 +7,26 @@

import Foundation
import Amplify
import ClientRuntime

extension ClientError: AuthErrorConvertible {
var fallbackDescription: String { "Client Error" }
import Smithy
import SmithyHTTPAPI

extension SmithyHTTPAPI.HTTPClientError: AuthErrorConvertible {
var authError: AuthError {
switch self {
case .pathCreationFailed(let message),
.queryItemCreationFailed(let message),
.serializationFailed(let message),
.dataNotFound(let message):
.queryItemCreationFailed(let message):
return .service(message, "", self)
}
}
}

extension Smithy.ClientError: AuthErrorConvertible {
var authError: AuthError {
switch self {
case .serializationFailed(let message),
.dataNotFound(let message),
.invalidValue(let message):
return .service(message, "Check the underlying error and try again", self)

case .authError(let message):
return .notAuthorized(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,5 +8,6 @@
import Foundation
import AWSClientRuntime
import ClientRuntime
import SmithyHTTPAPI

public typealias NetworkResult = (Result<HttpResponse, Error>) -> Void
public typealias NetworkResult = (Result<HTTPResponse, Error>) -> Void
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@

import ClientRuntime
@_spi(InternalAmplifyConfiguration) import Amplify
import SmithyHTTPAPI

struct UserPoolConfigurationData: Equatable {

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,22 +5,21 @@
// SPDX-License-Identifier: Apache-2.0
//

import AWSClientRuntime
import ClientRuntime
import AWSCognitoIdentityProvider
import SmithyHTTPAPI

struct AWSEndpointResolving: AWSCognitoIdentityProvider.EndpointResolver {
func resolve(params: AWSCognitoIdentityProvider.EndpointParams) throws -> ClientRuntime.Endpoint {
func resolve(params: AWSCognitoIdentityProvider.EndpointParams) throws -> SmithyHTTPAPI.Endpoint {
try endpoint()
}

let endpoint: () throws -> ClientRuntime.Endpoint
let endpoint: () throws -> SmithyHTTPAPI.Endpoint

init(_ endpoint: @escaping () throws -> ClientRuntime.Endpoint) {
init(_ endpoint: @escaping () throws -> SmithyHTTPAPI.Endpoint) {
self.endpoint = endpoint
}

init(_ endpoint: @escaping @autoclosure () throws -> ClientRuntime.Endpoint) {
init(_ endpoint: @escaping @autoclosure () throws -> SmithyHTTPAPI.Endpoint) {
self.endpoint = endpoint
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,10 @@
//

import Foundation
import ClientRuntime
import SmithyHTTPAPI

struct EndpointResolving {
let run: (String) throws -> ClientRuntime.Endpoint
let run: (String) throws -> SmithyHTTPAPI.Endpoint
}

extension EndpointResolving {
Expand Down Expand Up @@ -37,6 +37,6 @@ extension EndpointResolving {
// Finally, let's confirm that the endpoint doesn't contain a path.
try validate((components, endpoint), with: .pathIsEmpty())

return ClientRuntime.Endpoint(host: host)
return SmithyHTTPAPI.Endpoint(host: host)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@
//

@_spi(InternalHttpEngineProxy) @_spi(InternalAmplifyPluginExtension) import InternalAmplifyCredentials
import ClientRuntime
import Foundation
import SmithyHTTPAPI

protocol HttpClientEngineProxy: HTTPClient {
var target: HTTPClient? { get set }
Expand Down
Loading
Loading