amplify-swift/AmplifyPlugins/Auth/Sources/AWSCognitoAuthPlugin/AWSCognitoAuthPlugin+Config...

248 lines
11 KiB
Swift

//
// Copyright Amazon.com Inc. or its affiliates.
// All Rights Reserved.
//
// SPDX-License-Identifier: Apache-2.0
//
import Foundation
import Amplify
import AWSCognitoIdentity
import AWSCognitoIdentityProvider
import AWSPluginsCore
import ClientRuntime
extension AWSCognitoAuthPlugin {
/// Configures AWSCognitoAuthPlugin with the specified configuration.
///
/// - Parameter configuration: The configuration specified for this plugin
/// - Throws:
/// - PluginError.pluginConfigurationError: If one of the configuration values is invalid or empty
public func configure(using configuration: Any?) throws {
guard let jsonValueConfiguration = configuration as? JSONValue else {
throw PluginError.pluginConfigurationError(
AuthPluginErrorConstants.decodeConfigurationError.errorDescription,
AuthPluginErrorConstants.decodeConfigurationError.recoverySuggestion)
}
let authConfiguration = try ConfigurationHelper.authConfiguration(jsonValueConfiguration)
let credentialStoreResolver = CredentialStoreState.Resolver().eraseToAnyResolver()
let credentialEnvironment = credentialStoreEnvironment(authConfiguration: authConfiguration)
let credentialStoreMachine = StateMachine(resolver: credentialStoreResolver,
environment: credentialEnvironment)
let credentialsClient = CredentialStoreOperationClient(
credentialStoreStateMachine: credentialStoreMachine)
let authResolver = AuthState.Resolver().eraseToAnyResolver()
let authEnvironment = makeAuthEnvironment(
authConfiguration: authConfiguration,
credentialsClient: credentialsClient
)
let authStateMachine = StateMachine(resolver: authResolver, environment: authEnvironment)
let hubEventHandler = AuthHubEventHandler()
let analyticsHandler = try UserPoolAnalytics(
authConfiguration.getUserPoolConfiguration(),
credentialStoreEnvironment: credentialEnvironment.credentialStoreEnvironment)
configure(authConfiguration: authConfiguration,
authEnvironment: authEnvironment,
authStateMachine: authStateMachine,
credentialStoreStateMachine: credentialStoreMachine,
hubEventHandler: hubEventHandler,
analyticsHandler: analyticsHandler)
}
func configure(authConfiguration: AuthConfiguration,
authEnvironment: AuthEnvironment,
authStateMachine: AuthStateMachine,
credentialStoreStateMachine: CredentialStoreStateMachine,
hubEventHandler: AuthHubEventBehavior,
analyticsHandler: UserPoolAnalyticsBehavior,
queue: OperationQueue = OperationQueue()) {
self.authConfiguration = authConfiguration
self.queue = queue
self.queue.maxConcurrentOperationCount = 1
self.authEnvironment = authEnvironment
self.authStateMachine = authStateMachine
self.credentialStoreStateMachine = credentialStoreStateMachine
self.internalConfigure()
self.listenToStateMachineChanges()
self.hubEventHandler = hubEventHandler
self.analyticsHandler = analyticsHandler
self.taskQueue = TaskQueue()
}
// MARK: - Configure Helpers
private func makeUserPool() throws -> CognitoUserPoolBehavior {
switch authConfiguration {
case .userPools(let userPoolConfig), .userPoolsAndIdentityPools(let userPoolConfig, _):
let configuration: CognitoIdentityProviderClient.CognitoIdentityProviderClientConfiguration
if let customEndpoint = userPoolConfig.endpoint {
configuration = try .init(
region: userPoolConfig.region,
endpointResolver: customEndpoint.resolver,
frameworkMetadata: AmplifyAWSServiceConfiguration.frameworkMetaData()
)
} else {
configuration = try CognitoIdentityProviderClient.CognitoIdentityProviderClientConfiguration(
region: userPoolConfig.region, frameworkMetadata: AmplifyAWSServiceConfiguration.frameworkMetaData())
}
return CognitoIdentityProviderClient(config: configuration)
default:
fatalError()
}
}
private func makeIdentityClient() throws -> CognitoIdentityBehavior {
switch authConfiguration {
case .identityPools(let identityPoolConfig), .userPoolsAndIdentityPools(_, let identityPoolConfig):
let configuration = try CognitoIdentityClient.CognitoIdentityClientConfiguration(
region: identityPoolConfig.region, frameworkMetadata: AmplifyAWSServiceConfiguration.frameworkMetaData())
return CognitoIdentityClient(config: configuration)
default:
fatalError()
}
}
private func makeHostedUISession() -> HostedUISessionBehavior {
return HostedUIASWebAuthenticationSession()
}
private func makeURLSession() -> URLSession {
return URLSession.shared
}
private func makeRandomString() -> RandomStringBehavior {
return RandomStringGenerator()
}
private func makeCognitoASF() -> AdvancedSecurityBehavior {
CognitoUserPoolASF()
}
private func makeUserPoolAnalytics() -> UserPoolAnalyticsBehavior {
return analyticsHandler
}
private func makeCredentialStore() -> AmplifyAuthCredentialStoreBehavior {
AWSCognitoAuthCredentialStore(authConfiguration: authConfiguration)
}
private func makeLegacyKeychainStore(service: String) -> KeychainStoreBehavior {
KeychainStore(service: service)
}
private func makeAuthEnvironment(
authConfiguration: AuthConfiguration,
credentialsClient: CredentialStoreStateBehavior
) -> AuthEnvironment {
switch authConfiguration {
case .userPools(let userPoolConfigurationData):
let authenticationEnvironment = authenticationEnvironment(
userPoolConfigData: userPoolConfigurationData)
return AuthEnvironment(
configuration: authConfiguration,
userPoolConfigData: userPoolConfigurationData,
identityPoolConfigData: nil,
authenticationEnvironment: authenticationEnvironment,
authorizationEnvironment: nil,
credentialsClient: credentialsClient,
logger: log)
case .identityPools(let identityPoolConfigurationData):
let authorizationEnvironment = authorizationEnvironment(
identityPoolConfigData: identityPoolConfigurationData)
return AuthEnvironment(
configuration: authConfiguration,
userPoolConfigData: nil,
identityPoolConfigData: identityPoolConfigurationData,
authenticationEnvironment: nil,
authorizationEnvironment: authorizationEnvironment,
credentialsClient: credentialsClient,
logger: log)
case .userPoolsAndIdentityPools(let userPoolConfigurationData,
let identityPoolConfigurationData):
let authenticationEnvironment = authenticationEnvironment(
userPoolConfigData: userPoolConfigurationData)
let authorizationEnvironment = authorizationEnvironment(
identityPoolConfigData: identityPoolConfigurationData)
return AuthEnvironment(
configuration: authConfiguration,
userPoolConfigData: userPoolConfigurationData,
identityPoolConfigData: identityPoolConfigurationData,
authenticationEnvironment: authenticationEnvironment,
authorizationEnvironment: authorizationEnvironment,
credentialsClient: credentialsClient,
logger: log)
}
}
private func authenticationEnvironment(userPoolConfigData: UserPoolConfigurationData) -> AuthenticationEnvironment {
let srpAuthEnvironment = BasicSRPAuthEnvironment(userPoolConfiguration: userPoolConfigData,
cognitoUserPoolFactory: makeUserPool)
let srpSignInEnvironment = BasicSRPSignInEnvironment(srpAuthEnvironment: srpAuthEnvironment)
let userPoolEnvironment = BasicUserPoolEnvironment(
userPoolConfiguration: userPoolConfigData,
cognitoUserPoolFactory: makeUserPool,
cognitoUserPoolASFFactory: makeCognitoASF,
cognitoUserPoolAnalyticsHandlerFactory: makeUserPoolAnalytics)
let hostedUIEnvironment = hostedUIEnvironment(userPoolConfigData)
return BasicAuthenticationEnvironment(srpSignInEnvironment: srpSignInEnvironment,
userPoolEnvironment: userPoolEnvironment,
hostedUIEnvironment: hostedUIEnvironment)
}
private func hostedUIEnvironment(_ configuration: UserPoolConfigurationData) -> HostedUIEnvironment? {
guard let hostedUIConfig = configuration.hostedUIConfig else {
return nil
}
return BasicHostedUIEnvironment(configuration: hostedUIConfig,
hostedUISessionFactory: makeHostedUISession,
urlSessionFactory: makeURLSession,
randomStringFactory: makeRandomString)
}
private func authorizationEnvironment(identityPoolConfigData: IdentityPoolConfigurationData) -> AuthorizationEnvironment {
BasicAuthorizationEnvironment(identityPoolConfiguration: identityPoolConfigData,
cognitoIdentityFactory: makeIdentityClient)
}
private func credentialStoreEnvironment(authConfiguration: AuthConfiguration) -> CredentialEnvironment {
CredentialEnvironment(
authConfiguration: authConfiguration,
credentialStoreEnvironment: BasicCredentialStoreEnvironment(
amplifyCredentialStoreFactory: makeCredentialStore,
legacyKeychainStoreFactory: makeLegacyKeychainStore(service:)
), logger: log
)
}
private func internalConfigure() {
let request = AuthConfigureRequest(authConfiguration: authConfiguration)
let operation = AuthConfigureOperation(
request: request,
authStateMachine: authStateMachine,
credentialStoreStateMachine: credentialStoreStateMachine)
self.queue.addOperation(operation)
}
}
extension CognitoIdentityProviderClient: CognitoUserPoolBehavior {}
extension CognitoIdentityClient: CognitoIdentityBehavior {}