Skip to content

Commit 19585f3

Browse files
authored
fix(DataStore): Fallback when missing auth rule providers to API requirements (#1465)
* fix(DataStore): Fallback when missing auth rule providers to API requirements * address PR comments and add unit tests * integ test updates * fix MockAPIPlugin * fix conflict API unit test with Amplify.reset
1 parent e7f9c8f commit 19585f3

File tree

16 files changed

+438
-28
lines changed

16 files changed

+438
-28
lines changed

Amplify.xcodeproj/project.pbxproj

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,8 @@
1616
210DBC142332B3C6009B9E51 /* StorageGetURLOperation.swift in Sources */ = {isa = PBXBuildFile; fileRef = 210DBC132332B3C6009B9E51 /* StorageGetURLOperation.swift */; };
1717
210DBC162332B3CB009B9E51 /* StorageDownloadDataOperation.swift in Sources */ = {isa = PBXBuildFile; fileRef = 210DBC152332B3CB009B9E51 /* StorageDownloadDataOperation.swift */; };
1818
210DBC472332F0C5009B9E51 /* StorageError.swift in Sources */ = {isa = PBXBuildFile; fileRef = 210DBC462332F0C5009B9E51 /* StorageError.swift */; };
19+
211A81DB2717239100C5483D /* AWSAPIAuthInformation.swift in Sources */ = {isa = PBXBuildFile; fileRef = 211A81DA2717239100C5483D /* AWSAPIAuthInformation.swift */; };
20+
211A82012718631800C5483D /* AWSAuthorizationTypeTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 211A82002718631800C5483D /* AWSAuthorizationTypeTests.swift */; };
1921
211FFEE326CD650500F0DB75 /* DataStoreQuerySnapshot.swift in Sources */ = {isa = PBXBuildFile; fileRef = 211FFEE226CD650500F0DB75 /* DataStoreQuerySnapshot.swift */; };
2022
2125E2542319EC3100B3DEB5 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2125E2532319EC3100B3DEB5 /* AppDelegate.swift */; };
2123
2125E2562319EC3100B3DEB5 /* ViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2125E2552319EC3100B3DEB5 /* ViewController.swift */; };
@@ -848,6 +850,8 @@
848850
210DBC132332B3C6009B9E51 /* StorageGetURLOperation.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = StorageGetURLOperation.swift; sourceTree = "<group>"; };
849851
210DBC152332B3CB009B9E51 /* StorageDownloadDataOperation.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = StorageDownloadDataOperation.swift; sourceTree = "<group>"; };
850852
210DBC462332F0C5009B9E51 /* StorageError.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StorageError.swift; sourceTree = "<group>"; };
853+
211A81DA2717239100C5483D /* AWSAPIAuthInformation.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AWSAPIAuthInformation.swift; sourceTree = "<group>"; };
854+
211A82002718631800C5483D /* AWSAuthorizationTypeTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AWSAuthorizationTypeTests.swift; sourceTree = "<group>"; };
851855
211FFEE226CD650500F0DB75 /* DataStoreQuerySnapshot.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DataStoreQuerySnapshot.swift; sourceTree = "<group>"; };
852856
2125E2102318D73B00B3DEB5 /* awsconfiguration.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; path = awsconfiguration.json; sourceTree = "<group>"; };
853857
2125E2512319EC3000B3DEB5 /* AmplifyTestApp.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = AmplifyTestApp.app; sourceTree = BUILT_PRODUCTS_DIR; };
@@ -2224,6 +2228,7 @@
22242228
isa = PBXGroup;
22252229
children = (
22262230
21C395B2245729EC00597EA2 /* AppSyncErrorType.swift */,
2231+
211A81DA2717239100C5483D /* AWSAPIAuthInformation.swift */,
22272232
);
22282233
path = API;
22292234
sourceTree = "<group>";
@@ -2523,8 +2528,9 @@
25232528
6BEE0815253114E600133961 /* Auth */ = {
25242529
isa = PBXGroup;
25252530
children = (
2526-
6BEE0816253114FD00133961 /* AWSAuthServiceTests.swift */,
25272531
76C0F4EA26797F3C00F0E6AB /* AuthModeStrategyTests.swift */,
2532+
211A82002718631800C5483D /* AWSAuthorizationTypeTests.swift */,
2533+
6BEE0816253114FD00133961 /* AWSAuthServiceTests.swift */,
25282534
);
25292535
path = Auth;
25302536
sourceTree = "<group>";
@@ -4781,6 +4787,7 @@
47814787
21420AA0237222A900FA140C /* AWSAuthorizationType.swift in Sources */,
47824788
B4EBEB64246204D000D06375 /* AuthAWSCredentialsProvider.swift in Sources */,
47834789
212CE6FC23E9E523007D8E71 /* SelectionSet.swift in Sources */,
4790+
211A81DB2717239100C5483D /* AWSAPIAuthInformation.swift in Sources */,
47844791
2129BE1F2394806B006363A1 /* Model+GraphQL.swift in Sources */,
47854792
212CE70323E9E967007D8E71 /* GraphQLMutation.swift in Sources */,
47864793
2129BE0F23948005006363A1 /* SingleDirectiveGraphQLDocument.swift in Sources */,
@@ -4842,6 +4849,7 @@
48424849
76C0F4EC26797F4500F0E6AB /* AuthModeStrategyTests.swift in Sources */,
48434850
2129BE3A2394828B006363A1 /* QueryPredicateGraphQLTests.swift in Sources */,
48444851
2129BE48239489AC006363A1 /* MutationSyncMetadataTests.swift in Sources */,
4852+
211A82012718631800C5483D /* AWSAuthorizationTypeTests.swift in Sources */,
48454853
216E45F1248E971E0035E3CE /* GraphQLRequestEmbeddableTypeTests.swift in Sources */,
48464854
21A3FDAF24630D7F00E76120 /* ModelWithOwnerFieldAuthRuleTests.swift in Sources */,
48474855
6BDF15B825412DE600B5BE69 /* ModelWithOwnerAuthAndMultiGroup.swift in Sources */,

AmplifyPlugins/API/APICategoryPlugin.xcodeproj/project.pbxproj

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@
1111
1FF6093C5054651046CBD72F /* Pods_HostApp_AWSAPICategoryPluginTestCommon_GraphQLWithLambdaAuthIntegrationTests.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4DFADA148F376B33D0F75509 /* Pods_HostApp_AWSAPICategoryPluginTestCommon_GraphQLWithLambdaAuthIntegrationTests.framework */; };
1212
210E217E265E9BB000D90ED8 /* GraphQLModelBasedTests+Concurrency.swift in Sources */ = {isa = PBXBuildFile; fileRef = 210E217D265E9BB000D90ED8 /* GraphQLModelBasedTests+Concurrency.swift */; };
1313
210E2180265EFD6800D90ED8 /* GraphQLSyncCustomPrimaryKeyTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 210E217F265EFD6800D90ED8 /* GraphQLSyncCustomPrimaryKeyTests.swift */; };
14+
211A81DD27176C7300C5483D /* AWSAPIPlugin+AuthInformation.swift in Sources */ = {isa = PBXBuildFile; fileRef = 211A81DC27176C7300C5483D /* AWSAPIPlugin+AuthInformation.swift */; };
15+
211A81FF271851B000C5483D /* AWSAPICategoryPlugin+AuthInformationTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 211A81FE271851B000C5483D /* AWSAPICategoryPlugin+AuthInformationTests.swift */; };
1416
211BEDF025E5904E004F367A /* AWSHTTPURLResponse.swift in Sources */ = {isa = PBXBuildFile; fileRef = 211BEDEF25E5904E004F367A /* AWSHTTPURLResponse.swift */; };
1517
211BEDFB25E59DC8004F367A /* AWSHTTPURLResponseTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 211BEDFA25E59DC8004F367A /* AWSHTTPURLResponseTests.swift */; };
1618
21233D032469B06B00039337 /* SocialNote.swift in Sources */ = {isa = PBXBuildFile; fileRef = 21233D022469B06B00039337 /* SocialNote.swift */; };
@@ -344,6 +346,8 @@
344346
1FDC07084023DEF205FF6598 /* Pods-AWSAPICategoryPlugin-AWSAPICategoryPluginTests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-AWSAPICategoryPlugin-AWSAPICategoryPluginTests.debug.xcconfig"; path = "Target Support Files/Pods-AWSAPICategoryPlugin-AWSAPICategoryPluginTests/Pods-AWSAPICategoryPlugin-AWSAPICategoryPluginTests.debug.xcconfig"; sourceTree = "<group>"; };
345347
210E217D265E9BB000D90ED8 /* GraphQLModelBasedTests+Concurrency.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "GraphQLModelBasedTests+Concurrency.swift"; sourceTree = "<group>"; };
346348
210E217F265EFD6800D90ED8 /* GraphQLSyncCustomPrimaryKeyTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GraphQLSyncCustomPrimaryKeyTests.swift; sourceTree = "<group>"; };
349+
211A81DC27176C7300C5483D /* AWSAPIPlugin+AuthInformation.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "AWSAPIPlugin+AuthInformation.swift"; sourceTree = "<group>"; };
350+
211A81FE271851B000C5483D /* AWSAPICategoryPlugin+AuthInformationTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "AWSAPICategoryPlugin+AuthInformationTests.swift"; sourceTree = "<group>"; };
347351
211BEDEF25E5904E004F367A /* AWSHTTPURLResponse.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AWSHTTPURLResponse.swift; sourceTree = "<group>"; };
348352
211BEDFA25E59DC8004F367A /* AWSHTTPURLResponseTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AWSHTTPURLResponseTests.swift; sourceTree = "<group>"; };
349353
21233D022469B06B00039337 /* SocialNote.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SocialNote.swift; sourceTree = "<group>"; };
@@ -945,6 +949,7 @@
945949
21D7A099237B54D90057D00D /* AWSAPIPlugin+InterceptorBehavior.swift */,
946950
FA8EE784238632620097E4F1 /* AWSAPIPlugin+Log.swift */,
947951
6B33897123AAD94800561E5B /* AWSAPIPlugin+Reachability.swift */,
952+
211A81DC27176C7300C5483D /* AWSAPIPlugin+AuthInformation.swift */,
948953
21D7A096237B54D90057D00D /* AWSAPIPlugin+Resettable.swift */,
949954
21D7A0D0237B54D90057D00D /* AWSAPIPlugin+RESTBehavior.swift */,
950955
21D7A0D1237B54D90057D00D /* AWSAPIPlugin+URLSessionBehaviorDelegate.swift */,
@@ -1191,6 +1196,7 @@
11911196
B4DFA5BE237A611D0013E17B /* AWSAPICategoryPluginTests */ = {
11921197
isa = PBXGroup;
11931198
children = (
1199+
211A81FE271851B000C5483D /* AWSAPICategoryPlugin+AuthInformationTests.swift */,
11941200
B4DFA5DE237A611D0013E17B /* AWSAPICategoryPlugin+ConfigureTests.swift */,
11951201
B4DFA5CC237A611D0013E17B /* AWSAPICategoryPlugin+GraphQLBehaviorTests.swift */,
11961202
B4DFA5C9237A611D0013E17B /* AWSAPICategoryPlugin+InterceptorBehaviorTests.swift */,
@@ -2545,6 +2551,7 @@
25452551
21D7A118237B54D90057D00D /* APIKeyURLRequestInterceptor.swift in Sources */,
25462552
21D7A116237B54D90057D00D /* AWSAPIPlugin+URLSessionBehaviorDelegate.swift in Sources */,
25472553
214BD3D023FB76740059A286 /* AWSSubscriptionConnectionFactory.swift in Sources */,
2554+
211A81DD27176C7300C5483D /* AWSAPIPlugin+AuthInformation.swift in Sources */,
25482555
21D7A0E6237B54D90057D00D /* AWSAPICategoryPluginConfiguration+EndpointConfig.swift in Sources */,
25492556
21D7A0EB237B54D90057D00D /* AWSAPIPlugin+URLSessionDelegate.swift in Sources */,
25502557
21D7A0DF237B54D90057D00D /* AWSGraphQLOperation.swift in Sources */,
@@ -2610,6 +2617,7 @@
26102617
21A4F95725A7AEB300E1047D /* GraphQLRequestToListQueryTests.swift in Sources */,
26112618
FA1C810A25868A4B006160E9 /* AWSAPICategoryPluginAmplifyVersionableTests.swift in Sources */,
26122619
FADC469524C0E8AF00EF447B /* GraphQLQueryCombineTests.swift in Sources */,
2620+
211A81FF271851B000C5483D /* AWSAPICategoryPlugin+AuthInformationTests.swift in Sources */,
26132621
B4DFA5E3237A611D0013E17B /* AWSGraphQLOperationTests.swift in Sources */,
26142622
763C857326B06E12005164B2 /* AuthenticationTokenAuthInterceptorTests.swift in Sources */,
26152623
B4DFA5F9237A611D0013E17B /* AWSAPICategoryPlugin+URLSessionDelegateTests.swift in Sources */,
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
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 Amplify
9+
import AWSPluginsCore
10+
import Foundation
11+
12+
extension AWSAPIPlugin {
13+
public func defaultAuthType() throws -> AWSAuthorizationType {
14+
try defaultAuthType(for: nil)
15+
}
16+
17+
public func defaultAuthType(for apiName: String?) throws -> AWSAuthorizationType {
18+
try pluginConfig.endpoints.getConfig(for: apiName).authorizationType
19+
}
20+
}

AmplifyPlugins/API/AWSAPICategoryPlugin/AWSAPIPlugin.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ import Amplify
99
import AWSPluginsCore
1010
import Foundation
1111

12-
final public class AWSAPIPlugin: NSObject, APICategoryPlugin {
12+
final public class AWSAPIPlugin: NSObject, APICategoryPlugin, AWSAPIAuthInformation {
1313
/// The unique key of the plugin within the API category.
1414
public var key: PluginKey {
1515
return "awsAPIPlugin"
Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
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 XCTest
9+
10+
@testable import Amplify
11+
@testable import AWSAPICategoryPlugin
12+
13+
class AWSAPICategoryPluginAuthInformationTests: AWSAPICategoryPluginTestBase {
14+
15+
func testDefaultAuthTypeForApiName() throws {
16+
let apiPlugin = AWSAPIPlugin()
17+
let apiPluginConfig: JSONValue = [
18+
"api1": [
19+
"endpoint": "http://www.example.com",
20+
"authorizationType": "API_KEY",
21+
"apiKey": "SpecialApiKey33",
22+
"endpointType": "REST"
23+
],
24+
"api2": [
25+
"endpoint": "http://www.example.com",
26+
"authorizationType": "AMAZON_COGNITO_USER_POOLS",
27+
"endpointType": "GraphQL"
28+
]
29+
]
30+
31+
try apiPlugin.configure(using: apiPluginConfig)
32+
let authType1 = try apiPlugin.defaultAuthType(for: "api1")
33+
XCTAssertEqual(authType1, .apiKey)
34+
let authTypeFromDefault = try apiPlugin.defaultAuthType()
35+
XCTAssertEqual(authTypeFromDefault, .amazonCognitoUserPools)
36+
let authType2 = try apiPlugin.defaultAuthType(for: "api2")
37+
XCTAssertEqual(authType2, .amazonCognitoUserPools)
38+
}
39+
40+
func testDefaultAuthType() throws {
41+
let apiPlugin = AWSAPIPlugin()
42+
let apiPluginConfig: JSONValue = [
43+
"api1": [
44+
"endpoint": "http://www.example.com",
45+
"authorizationType": "API_KEY",
46+
"apiKey": "SpecialApiKey33",
47+
"endpointType": "REST"
48+
]
49+
]
50+
51+
try apiPlugin.configure(using: apiPluginConfig)
52+
let authType = try apiPlugin.defaultAuthType()
53+
XCTAssertEqual(authType, .apiKey)
54+
}
55+
}

AmplifyPlugins/API/AWSAPICategoryPluginTests/Configuration/AWSAPICategoryPluginConfigurationTests.swift

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ class AWSAPICategoryPluginConfigurationTests: XCTestCase {
3434
}
3535

3636
func testThrowsOnMissingConfig() throws {
37+
Amplify.reset()
3738
let plugin = AWSAPIPlugin()
3839
try Amplify.add(plugin: plugin)
3940

AmplifyPlugins/API/Podfile.lock

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -107,4 +107,4 @@ SPEC CHECKSUMS:
107107

108108
PODFILE CHECKSUM: 0abaf757d71567dcf70f5a3e79b0149917c3bb38
109109

110-
COCOAPODS: 1.10.1
110+
COCOAPODS: 1.11.2
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
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+
10+
/// API Plugin's Auth related information
11+
public protocol AWSAPIAuthInformation {
12+
13+
/// Returns the deafult auth type from the default endpoint. The endpoint may accept more than one auth mode,
14+
/// however the default returned is the one configured on the endpoint configuration. The default endpoint is the
15+
/// the one determined by the API plugin, which is the one returned when called without an `apiName`.
16+
func defaultAuthType() throws -> AWSAuthorizationType
17+
18+
/// Returns the default auth type on endpoint specified by `apiName`.
19+
func defaultAuthType(for apiName: String?) throws -> AWSAuthorizationType
20+
}

AmplifyPlugins/Core/AWSPluginsCore/Auth/AWSAuthorizationType.swift

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,3 +44,15 @@ public enum AWSAuthorizationType: String {
4444
// swiftlint:enable line_length
4545

4646
extension AWSAuthorizationType: CaseIterable { }
47+
48+
/// Indicates whether the authotization type requires the auth plugin to operate.
49+
extension AWSAuthorizationType {
50+
public var requiresAuthPlugin: Bool {
51+
switch self {
52+
case .none, .apiKey, .openIDConnect, .function:
53+
return false
54+
case .awsIAM, .amazonCognitoUserPools:
55+
return true
56+
}
57+
}
58+
}
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
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 XCTest
9+
@testable import Amplify
10+
@testable import AWSPluginsCore
11+
12+
class AWSAuthorizationTypeTests: XCTestCase {
13+
14+
func testRequiresAuthPlugin() {
15+
XCTAssertFalse(AWSAuthorizationType.apiKey.requiresAuthPlugin)
16+
XCTAssertFalse(AWSAuthorizationType.none.requiresAuthPlugin)
17+
XCTAssertFalse(AWSAuthorizationType.openIDConnect.requiresAuthPlugin)
18+
XCTAssertFalse(AWSAuthorizationType.function.requiresAuthPlugin)
19+
XCTAssertTrue(AWSAuthorizationType.awsIAM.requiresAuthPlugin)
20+
XCTAssertTrue(AWSAuthorizationType.amazonCognitoUserPools.requiresAuthPlugin)
21+
}
22+
}

0 commit comments

Comments
 (0)