Skip to content

Commit

Permalink
refactor(datastore): new enum to represent inferred and designated au…
Browse files Browse the repository at this point in the history
…thType (#3694)

* refactor(datastore): new enum to represent inferred and designated auth type

* resolve failed multi auth integ tests

* resolve comments
  • Loading branch information
5d authored May 29, 2024
1 parent 7e5883a commit 82f9ec5
Show file tree
Hide file tree
Showing 11 changed files with 178 additions and 186 deletions.
71 changes: 0 additions & 71 deletions .swiftpm/xcode/xcshareddata/xcschemes/AWSPluginsSDKCore.xcscheme

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,10 @@ public final class RetryableGraphQLOperation<Payload: Decodable> {
private let nondeterminsticOperation: NondeterminsticOperation<GraphQLTask<Payload>.Success>

public init(
requestStream: AnyPublisher<() async throws -> GraphQLTask<Payload>.Success, Never>
requestStream: AsyncStream<() async throws -> GraphQLTask<Payload>.Success>
) {
self.nondeterminsticOperation = NondeterminsticOperation(
operationStream: requestStream,
operations: requestStream,
shouldTryNextOnError: Self.onError(_:)
)
}
Expand Down Expand Up @@ -80,9 +80,9 @@ public final class RetryableGraphQLSubscriptionOperation<Payload: Decodable> {
private let nondeterminsticOperation: NondeterminsticOperation<AmplifyAsyncThrowingSequence<SubscriptionEvents>>

public init(
requestStream: AnyPublisher<() async throws -> AmplifyAsyncThrowingSequence<SubscriptionEvents>, Never>
requestStream: AsyncStream<() async throws -> AmplifyAsyncThrowingSequence<SubscriptionEvents>>
) {
self.nondeterminsticOperation = NondeterminsticOperation(operationStream: requestStream)
self.nondeterminsticOperation = NondeterminsticOperation(operations: requestStream)
}

deinit {
Expand Down
51 changes: 21 additions & 30 deletions AmplifyPlugins/Core/AWSPluginsCore/Auth/AWSAuthModeStrategy.swift
Original file line number Diff line number Diff line change
Expand Up @@ -65,19 +65,23 @@ public protocol AuthorizationTypeIterator {
}

/// AuthorizationTypeIterator for values of type `AWSAuthorizationType`
public struct AWSAuthorizationTypeIterator: AuthorizationTypeIterator {
public typealias AuthorizationType = AWSAuthorizationType
public struct AWSAuthorizationTypeIterator: AuthorizationTypeIterator, Sequence, IteratorProtocol {
public typealias AuthorizationType = AmplifyAuthorizationType

private var values: IndexingIterator<[AWSAuthorizationType]>
private var values: IndexingIterator<[AmplifyAuthorizationType]>
private var _count: Int
private var _position: Int

public init(withValues values: [AWSAuthorizationType]) {
public init(withValues values: [AmplifyAuthorizationType]) {
self.values = values.makeIterator()
self._count = values.count
self._position = 0
}

public init(withValues values: [AmplifyAuthorizationType], valuesOnEmpty defaults: [AmplifyAuthorizationType]) {
self.init(withValues: values.isEmpty ? defaults : values)
}

public var count: Int {
_count
}
Expand All @@ -86,7 +90,7 @@ public struct AWSAuthorizationTypeIterator: AuthorizationTypeIterator {
_position < _count
}

public mutating func next() -> AWSAuthorizationType? {
public mutating func next() -> AmplifyAuthorizationType? {
if let value = values.next() {
_position += 1
return value
Expand All @@ -96,19 +100,6 @@ public struct AWSAuthorizationTypeIterator: AuthorizationTypeIterator {
}
}

extension AuthorizationTypeIterator {
public func publisher() -> AnyPublisher<AuthorizationType, Never> {
var it = self
return Deferred {
var authTypes = [AuthorizationType]()
while let authType = it.next() {
authTypes.append(authType)
}
return Publishers.MergeMany(authTypes.map { Just($0) })
}.eraseToAnyPublisher()
}
}

// MARK: - AWSDefaultAuthModeStrategy

/// AWS default auth mode strategy.
Expand All @@ -121,12 +112,12 @@ public class AWSDefaultAuthModeStrategy: AuthModeStrategy {

public func authTypesFor(schema: ModelSchema,
operation: ModelOperation) -> AWSAuthorizationTypeIterator {
return AWSAuthorizationTypeIterator(withValues: [])
return AWSAuthorizationTypeIterator(withValues: [.inferred])
}

public func authTypesFor(schema: ModelSchema,
operations: [ModelOperation]) -> AWSAuthorizationTypeIterator {
return AWSAuthorizationTypeIterator(withValues: [])
return AWSAuthorizationTypeIterator(withValues: [.inferred])
}
}

Expand All @@ -141,20 +132,18 @@ public class AWSMultiAuthModeStrategy: AuthModeStrategy {
required public init() {}

private static func defaultAuthTypeFor(authStrategy: AuthStrategy) -> AWSAuthorizationType {
var defaultAuthType: AWSAuthorizationType
switch authStrategy {
case .owner:
defaultAuthType = .amazonCognitoUserPools
return .amazonCognitoUserPools
case .groups:
defaultAuthType = .amazonCognitoUserPools
return .amazonCognitoUserPools
case .private:
defaultAuthType = .amazonCognitoUserPools
return .amazonCognitoUserPools
case .public:
defaultAuthType = .apiKey
return .apiKey
case .custom:
defaultAuthType = .function
return .function
}
return defaultAuthType
}

/// Given an auth rule, returns the corresponding AWSAuthorizationType
Expand Down Expand Up @@ -248,10 +237,12 @@ public class AWSMultiAuthModeStrategy: AuthModeStrategy {
return rule.allow == .public || rule.allow == .custom
}
}
let applicableAuthTypes = sortedRules.map {

let applicableAuthTypes: [AmplifyAuthorizationType] = sortedRules.map {
AWSMultiAuthModeStrategy.authTypeFor(authRule: $0)
}
return AWSAuthorizationTypeIterator(withValues: applicableAuthTypes)
}.map { .designated($0) }

return AWSAuthorizationTypeIterator(withValues: applicableAuthTypes, valuesOnEmpty: [.inferred])
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
//
// Copyright Amazon.com Inc. or its affiliates.
// All Rights Reserved.
//
// SPDX-License-Identifier: Apache-2.0
//


import Foundation

/// - Warning: Although this has `public` access, it is intended for internal use and should not be used directly
/// by host applications. The behavior of this may change without warning.
public enum AmplifyAuthorizationType {

/// Determine the authorization method based on the amplifyconfiguration.
case inferred

/// Specify the authentication method.
case designated(AWSAuthorizationType)

public var awsAuthType: AWSAuthorizationType? {
switch self {
case .inferred: return nil
case .designated(let authType): return authType
}
}
}

extension AmplifyAuthorizationType: Equatable { }
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,9 @@ class AuthModeStrategyTests: XCTestCase {
// Then: an empty iterator is returned
func testDefaultAuthModeShouldReturnAnEmptyIterator() {
let authMode = AWSDefaultAuthModeStrategy()
let authTypesIterator = authMode.authTypesFor(schema: AnyModelTester.schema, operation: .create)
XCTAssertEqual(authTypesIterator.count, 0)
var authTypesIterator = authMode.authTypesFor(schema: AnyModelTester.schema, operation: .create)
XCTAssertEqual(authTypesIterator.count, 1)
XCTAssertEqual(authTypesIterator.next(), .inferred)
}

// Given: multi-auth strategy and a model schema
Expand All @@ -28,8 +29,8 @@ class AuthModeStrategyTests: XCTestCase {
let authMode = AWSMultiAuthModeStrategy()
var authTypesIterator = await authMode.authTypesFor(schema: ModelWithOwnerAndPublicAuth.schema, operation: .create)
XCTAssertEqual(authTypesIterator.count, 2)
XCTAssertEqual(authTypesIterator.next(), .amazonCognitoUserPools)
XCTAssertEqual(authTypesIterator.next(), .apiKey)
XCTAssertEqual(authTypesIterator.next()?.awsAuthType, .amazonCognitoUserPools)
XCTAssertEqual(authTypesIterator.next()?.awsAuthType, .apiKey)
}

// Given: multi-auth strategy and a model schema without auth provider
Expand All @@ -39,8 +40,8 @@ class AuthModeStrategyTests: XCTestCase {
let authMode = AWSMultiAuthModeStrategy()
var authTypesIterator = await authMode.authTypesFor(schema: ModelNoProvider.schema, operation: .read)
XCTAssertEqual(authTypesIterator.count, 2)
XCTAssertEqual(authTypesIterator.next(), .amazonCognitoUserPools)
XCTAssertEqual(authTypesIterator.next(), .apiKey)
XCTAssertEqual(authTypesIterator.next()?.awsAuthType, .amazonCognitoUserPools)
XCTAssertEqual(authTypesIterator.next()?.awsAuthType, .apiKey)
}

// Given: multi-auth strategy and a model schema with 4 auth rules
Expand All @@ -50,10 +51,10 @@ class AuthModeStrategyTests: XCTestCase {
let authMode = AWSMultiAuthModeStrategy()
var authTypesIterator = await authMode.authTypesFor(schema: ModelAllStrategies.schema, operation: .read)
XCTAssertEqual(authTypesIterator.count, 4)
XCTAssertEqual(authTypesIterator.next(), .amazonCognitoUserPools)
XCTAssertEqual(authTypesIterator.next(), .amazonCognitoUserPools)
XCTAssertEqual(authTypesIterator.next(), .amazonCognitoUserPools)
XCTAssertEqual(authTypesIterator.next(), .awsIAM)
XCTAssertEqual(authTypesIterator.next()?.awsAuthType, .amazonCognitoUserPools)
XCTAssertEqual(authTypesIterator.next()?.awsAuthType, .amazonCognitoUserPools)
XCTAssertEqual(authTypesIterator.next()?.awsAuthType, .amazonCognitoUserPools)
XCTAssertEqual(authTypesIterator.next()?.awsAuthType, .awsIAM)
}

// Given: multi-auth strategy and a model schema multiple public rules
Expand All @@ -63,10 +64,10 @@ class AuthModeStrategyTests: XCTestCase {
let authMode = AWSMultiAuthModeStrategy()
var authTypesIterator = await authMode.authTypesFor(schema: ModelWithMultiplePublicRules.schema, operation: .read)
XCTAssertEqual(authTypesIterator.count, 4)
XCTAssertEqual(authTypesIterator.next(), .amazonCognitoUserPools)
XCTAssertEqual(authTypesIterator.next(), .openIDConnect)
XCTAssertEqual(authTypesIterator.next(), .awsIAM)
XCTAssertEqual(authTypesIterator.next(), .apiKey)
XCTAssertEqual(authTypesIterator.next()?.awsAuthType, .amazonCognitoUserPools)
XCTAssertEqual(authTypesIterator.next()?.awsAuthType, .openIDConnect)
XCTAssertEqual(authTypesIterator.next()?.awsAuthType, .awsIAM)
XCTAssertEqual(authTypesIterator.next()?.awsAuthType, .apiKey)
}

// Given: multi-auth strategy and a model schema
Expand All @@ -77,8 +78,8 @@ class AuthModeStrategyTests: XCTestCase {
let authMode = AWSMultiAuthModeStrategy()
var authTypesIterator = await authMode.authTypesFor(schema: ModelAllStrategies.schema, operation: .create)
XCTAssertEqual(authTypesIterator.count, 2)
XCTAssertEqual(authTypesIterator.next(), .amazonCognitoUserPools)
XCTAssertEqual(authTypesIterator.next(), .amazonCognitoUserPools)
XCTAssertEqual(authTypesIterator.next()?.awsAuthType, .amazonCognitoUserPools)
XCTAssertEqual(authTypesIterator.next()?.awsAuthType, .amazonCognitoUserPools)
}

// Given: multi-auth strategy a model schema
Expand All @@ -92,7 +93,7 @@ class AuthModeStrategyTests: XCTestCase {
var authTypesIterator = await authMode.authTypesFor(schema: ModelWithOwnerAndPublicAuth.schema,
operation: .create)
XCTAssertEqual(authTypesIterator.count, 1)
XCTAssertEqual(authTypesIterator.next(), .apiKey)
XCTAssertEqual(authTypesIterator.next()?.awsAuthType, .apiKey)
}

// Given: multi-auth model schema with a custom strategy
Expand All @@ -103,9 +104,9 @@ class AuthModeStrategyTests: XCTestCase {
var authTypesIterator = await authMode.authTypesFor(schema: ModelWithCustomStrategy.schema,
operation: .create)
XCTAssertEqual(authTypesIterator.count, 3)
XCTAssertEqual(authTypesIterator.next(), .function)
XCTAssertEqual(authTypesIterator.next(), .amazonCognitoUserPools)
XCTAssertEqual(authTypesIterator.next(), .awsIAM)
XCTAssertEqual(authTypesIterator.next()?.awsAuthType, .function)
XCTAssertEqual(authTypesIterator.next()?.awsAuthType, .amazonCognitoUserPools)
XCTAssertEqual(authTypesIterator.next()?.awsAuthType, .awsIAM)
}

// Given: multi-auth model schema with a custom strategy
Expand All @@ -119,8 +120,8 @@ class AuthModeStrategyTests: XCTestCase {
var authTypesIterator = await authMode.authTypesFor(schema: ModelWithCustomStrategy.schema,
operation: .create)
XCTAssertEqual(authTypesIterator.count, 2)
XCTAssertEqual(authTypesIterator.next(), .function)
XCTAssertEqual(authTypesIterator.next(), .awsIAM)
XCTAssertEqual(authTypesIterator.next()?.awsAuthType, .function)
XCTAssertEqual(authTypesIterator.next()?.awsAuthType, .awsIAM)
}

// Given: multi-auth strategy and a model schema without auth provider
Expand All @@ -130,8 +131,8 @@ class AuthModeStrategyTests: XCTestCase {
let authMode = AWSMultiAuthModeStrategy()
var authTypesIterator = await authMode.authTypesFor(schema: ModelNoProvider.schema, operations: [.read, .create])
XCTAssertEqual(authTypesIterator.count, 2)
XCTAssertEqual(authTypesIterator.next(), .amazonCognitoUserPools)
XCTAssertEqual(authTypesIterator.next(), .apiKey)
XCTAssertEqual(authTypesIterator.next()?.awsAuthType, .amazonCognitoUserPools)
XCTAssertEqual(authTypesIterator.next()?.awsAuthType, .apiKey)
}

// Given: multi-auth strategy and a model schema with auth provider
Expand All @@ -143,7 +144,7 @@ class AuthModeStrategyTests: XCTestCase {
authMode.authDelegate = delegate
var authTypesIterator = await authMode.authTypesFor(schema: ModelNoProvider.schema, operations: [.read, .create])
XCTAssertEqual(authTypesIterator.count, 1)
XCTAssertEqual(authTypesIterator.next(), .apiKey)
XCTAssertEqual(authTypesIterator.next()?.awsAuthType, .apiKey)
}

}
Expand Down
Loading

0 comments on commit 82f9ec5

Please sign in to comment.