Skip to content

Commit 18d3a76

Browse files
lawmichasebaland
andauthored
fix(DataStore-v1): auth plugin requirement for single auth rule (#3454)
* fix(DataStore-v1): auth plugin requirement for single auth rule * fix code structure * Update AmplifyPlugins/DataStore/AWSDataStoreCategoryPlugin/Storage/StorageEngine+SyncRequirement.swift Co-authored-by: Sebastian Villena <[email protected]> --------- Co-authored-by: Sebastian Villena <[email protected]>
1 parent 6ed4fc3 commit 18d3a76

File tree

2 files changed

+97
-22
lines changed

2 files changed

+97
-22
lines changed

AmplifyPlugins/DataStore/AWSDataStoreCategoryPlugin/Storage/StorageEngine+SyncRequirement.swift

Lines changed: 34 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,10 @@ extension StorageEngine {
2525
))
2626
}
2727

28-
let authPluginRequired = StorageEngine.requiresAuthPlugin(api)
28+
let authPluginRequired = StorageEngine.requiresAuthPlugin(
29+
api,
30+
authModeStrategy: dataStoreConfiguration.authModeStrategyType
31+
)
2932

3033
guard authPluginRequired else {
3134
syncEngine.start(api: api, auth: nil)
@@ -81,20 +84,45 @@ extension StorageEngine {
8184
}
8285
}
8386

84-
static func requiresAuthPlugin(_ apiPlugin: APICategoryPlugin) -> Bool {
87+
static func requiresAuthPlugin(
88+
_ apiPlugin: APICategoryPlugin,
89+
authModeStrategy: AuthModeStrategyType
90+
) -> Bool {
8591
let modelsRequireAuthPlugin = ModelRegistry.modelSchemas.contains { schema in
8692
guard schema.isSyncable else {
8793
return false
8894
}
89-
return StorageEngine.requiresAuthPlugin(apiPlugin, authRules: schema.authRules)
95+
return StorageEngine.requiresAuthPlugin(apiPlugin,
96+
authRules: schema.authRules,
97+
authModeStrategy: authModeStrategy)
9098
}
9199

92100
return modelsRequireAuthPlugin
93101
}
94102

95-
static func requiresAuthPlugin(_ apiPlugin: APICategoryPlugin, authRules: [AuthRule]) -> Bool {
96-
if let rulesRequireAuthPlugin = authRules.requireAuthPlugin {
97-
return rulesRequireAuthPlugin
103+
static func requiresAuthPlugin(
104+
_ apiPlugin: APICategoryPlugin,
105+
authRules: [AuthRule],
106+
authModeStrategy: AuthModeStrategyType
107+
) -> Bool {
108+
switch authModeStrategy {
109+
case .default:
110+
if authRules.isEmpty {
111+
return false
112+
}
113+
// Only use the auth rule as determination for auth plugin requirement when there is
114+
// exactly one. If there is more than one auth rule AND multi-auth is not enabled,
115+
// then immediately fall back to using the default auth type configured on the APIPlugin because
116+
// we do not have enough information to know which provider to use to make the determination.
117+
if authRules.count == 1,
118+
let singleAuthRule = authRules.first,
119+
let ruleRequireAuthPlugin = singleAuthRule.requiresAuthPlugin {
120+
return ruleRequireAuthPlugin
121+
}
122+
case .multiAuth:
123+
if let rulesRequireAuthPlugin = authRules.requireAuthPlugin {
124+
return rulesRequireAuthPlugin
125+
}
98126
}
99127

100128
// Fall back to the endpoint's auth type if a determination cannot be made from the auth rules. This can

AmplifyPlugins/DataStore/AWSDataStoreCategoryPluginTests/Sync/StorageEngineSyncRequirementsTests.swift

Lines changed: 63 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -17,80 +17,91 @@ class StorageEngineSyncRequirementsTests: XCTestCase {
1717

1818
func testRequiresAuthPluginFalseForMissingAuthRules() {
1919
let apiPlugin = MockAPICategoryPlugin()
20-
let result = StorageEngine.requiresAuthPlugin(apiPlugin)
21-
XCTAssertFalse(result)
20+
XCTAssertFalse(StorageEngine.requiresAuthPlugin(apiPlugin, authModeStrategy: .default))
21+
XCTAssertFalse(StorageEngine.requiresAuthPlugin(apiPlugin, authModeStrategy: .multiAuth))
2222
}
2323

2424
func testRequiresAuthPluginSingleAuthRuleAPIKey() {
2525
let apiPlugin = MockAPICategoryPlugin()
2626
let authRules = [AuthRule(allow: .owner, provider: .apiKey)]
27-
XCTAssertFalse(StorageEngine.requiresAuthPlugin(apiPlugin, authRules: authRules))
27+
XCTAssertFalse(StorageEngine.requiresAuthPlugin(apiPlugin, authRules: authRules, authModeStrategy: .default))
28+
XCTAssertFalse(StorageEngine.requiresAuthPlugin(apiPlugin, authRules: authRules, authModeStrategy: .multiAuth))
2829
}
2930

3031
func testRequiresAuthPluginSingleAuthRuleOIDC() {
3132
let apiPlugin = MockAPICategoryPlugin()
3233
let authRules = [AuthRule(allow: .owner, provider: .oidc)]
33-
XCTAssertFalse(StorageEngine.requiresAuthPlugin(apiPlugin, authRules: authRules))
34+
XCTAssertFalse(StorageEngine.requiresAuthPlugin(apiPlugin, authRules: authRules, authModeStrategy: .default))
35+
XCTAssertFalse(StorageEngine.requiresAuthPlugin(apiPlugin, authRules: authRules, authModeStrategy: .multiAuth))
3436
}
3537

3638
func testRequiresAuthPluginSingleAuthRuleFunction() {
3739
let apiPlugin = MockAPICategoryPlugin()
3840
let authRules = [AuthRule(allow: .private, provider: .function)]
39-
XCTAssertFalse(StorageEngine.requiresAuthPlugin(apiPlugin, authRules: authRules))
41+
XCTAssertFalse(StorageEngine.requiresAuthPlugin(apiPlugin, authRules: authRules, authModeStrategy: .default))
42+
XCTAssertFalse(StorageEngine.requiresAuthPlugin(apiPlugin, authRules: authRules, authModeStrategy: .multiAuth))
4043
}
4144

4245
func testRequiresAuthPluginSingleAuthRuleUserPools() {
4346
let apiPlugin = MockAPICategoryPlugin()
4447
let authRules = [AuthRule(allow: .owner, provider: .userPools)]
45-
XCTAssertTrue(StorageEngine.requiresAuthPlugin(apiPlugin, authRules: authRules))
48+
XCTAssertTrue(StorageEngine.requiresAuthPlugin(apiPlugin, authRules: authRules, authModeStrategy: .default))
49+
XCTAssertTrue(StorageEngine.requiresAuthPlugin(apiPlugin, authRules: authRules, authModeStrategy: .multiAuth))
4650
}
4751

4852
func testRequiresAuthPluginSingleAuthRuleIAM() {
4953
let apiPlugin = MockAPICategoryPlugin()
5054
let authRules = [AuthRule(allow: .owner, provider: .iam)]
51-
XCTAssertTrue(StorageEngine.requiresAuthPlugin(apiPlugin, authRules: authRules))
55+
XCTAssertTrue(StorageEngine.requiresAuthPlugin(apiPlugin, authRules: authRules, authModeStrategy: .default))
56+
XCTAssertTrue(StorageEngine.requiresAuthPlugin(apiPlugin, authRules: authRules, authModeStrategy: .multiAuth))
5257
}
5358

5459
func testRequiresAuthPluginNoProvidersWithAuthTypeFunction() {
5560
let authRules = [AuthRule(allow: .owner)]
5661
let apiPlugin = MockAPIAuthInformationPlugin()
5762
apiPlugin.authType = .function
58-
XCTAssertFalse(StorageEngine.requiresAuthPlugin(apiPlugin, authRules: authRules))
63+
XCTAssertFalse(StorageEngine.requiresAuthPlugin(apiPlugin, authRules: authRules, authModeStrategy: .default))
64+
XCTAssertFalse(StorageEngine.requiresAuthPlugin(apiPlugin, authRules: authRules, authModeStrategy: .multiAuth))
5965
}
6066

6167
func testRequiresAuthPluginNoProvidersWithAuthTypeAPIKey() {
6268
let authRules = [AuthRule(allow: .owner)]
6369
let apiPlugin = MockAPIAuthInformationPlugin()
6470
apiPlugin.authType = .apiKey
65-
XCTAssertFalse(StorageEngine.requiresAuthPlugin(apiPlugin, authRules: authRules))
71+
XCTAssertFalse(StorageEngine.requiresAuthPlugin(apiPlugin, authRules: authRules, authModeStrategy: .default))
72+
XCTAssertFalse(StorageEngine.requiresAuthPlugin(apiPlugin, authRules: authRules, authModeStrategy: .multiAuth))
6673
}
6774

6875
func testRequiresAuthPluginNoProvidersWithAuthTypeUserPools() {
6976
let authRules = [AuthRule(allow: .owner)]
7077
let apiPlugin = MockAPIAuthInformationPlugin()
7178
apiPlugin.authType = .amazonCognitoUserPools
72-
XCTAssertTrue(StorageEngine.requiresAuthPlugin(apiPlugin, authRules: authRules))
79+
XCTAssertTrue(StorageEngine.requiresAuthPlugin(apiPlugin, authRules: authRules, authModeStrategy: .default))
80+
XCTAssertTrue(StorageEngine.requiresAuthPlugin(apiPlugin, authRules: authRules, authModeStrategy: .multiAuth))
7381
}
7482

7583
func testRequiresAuthPluginNoProvidersWithAuthTypeIAM() {
7684
let authRules = [AuthRule(allow: .owner)]
7785
let apiPlugin = MockAPIAuthInformationPlugin()
7886
apiPlugin.authType = .awsIAM
79-
XCTAssertTrue(StorageEngine.requiresAuthPlugin(apiPlugin, authRules: authRules))
87+
XCTAssertTrue(StorageEngine.requiresAuthPlugin(apiPlugin, authRules: authRules, authModeStrategy: .default))
88+
XCTAssertTrue(StorageEngine.requiresAuthPlugin(apiPlugin, authRules: authRules, authModeStrategy: .multiAuth))
8089
}
8190

8291
func testRequiresAuthPluginNoProvidersWithAuthTypeODIC() {
8392
let authRules = [AuthRule(allow: .owner)]
8493
let apiPlugin = MockAPIAuthInformationPlugin()
8594
apiPlugin.authType = .openIDConnect
86-
XCTAssertFalse(StorageEngine.requiresAuthPlugin(apiPlugin, authRules: authRules))
95+
XCTAssertFalse(StorageEngine.requiresAuthPlugin(apiPlugin, authRules: authRules, authModeStrategy: .default))
96+
XCTAssertFalse(StorageEngine.requiresAuthPlugin(apiPlugin, authRules: authRules, authModeStrategy: .multiAuth))
8797
}
8898

8999
func testRequiresAuthPluginNoProvidersWithAuthTypeNone() {
90100
let authRules = [AuthRule(allow: .owner)]
91101
let apiPlugin = MockAPIAuthInformationPlugin()
92102
apiPlugin.authType = AWSAuthorizationType.none
93-
XCTAssertFalse(StorageEngine.requiresAuthPlugin(apiPlugin, authRules: authRules))
103+
XCTAssertFalse(StorageEngine.requiresAuthPlugin(apiPlugin, authRules: authRules, authModeStrategy: .default))
104+
XCTAssertFalse(StorageEngine.requiresAuthPlugin(apiPlugin, authRules: authRules, authModeStrategy: .multiAuth))
94105
}
95106

96107
func testRequiresAuthPluginOIDCProvider() {
@@ -99,7 +110,41 @@ class StorageEngineSyncRequirementsTests: XCTestCase {
99110
apiPlugin.defaultAuthTypeError = APIError.unknown("Could not get default auth type", "", nil)
100111
let oidcProvider = MockOIDCAuthProvider()
101112
apiPlugin.authProviderFactory = MockAPIAuthProviderFactory(oidcProvider: oidcProvider)
102-
XCTAssertFalse(StorageEngine.requiresAuthPlugin(apiPlugin, authRules: authRules))
113+
XCTAssertFalse(StorageEngine.requiresAuthPlugin(apiPlugin, authRules: authRules, authModeStrategy: .default))
114+
XCTAssertFalse(StorageEngine.requiresAuthPlugin(apiPlugin, authRules: authRules, authModeStrategy: .multiAuth))
115+
}
116+
117+
func testRequiresAuthPluginOIDCProvider_MultiAuthRules() {
118+
// OIDC requires an auth provider on the API, this is added below
119+
let authRules = [AuthRule(allow: .owner, provider: .oidc),
120+
AuthRule(allow: .private, provider: .iam)]
121+
let apiPlugin = MockAPIAuthInformationPlugin()
122+
apiPlugin.defaultAuthTypeError = APIError.unknown("Could not get default auth type", "", nil)
123+
let oidcProvider = MockOIDCAuthProvider()
124+
apiPlugin.authProviderFactory = MockAPIAuthProviderFactory(oidcProvider: oidcProvider)
125+
XCTAssertFalse(StorageEngine.requiresAuthPlugin(apiPlugin,
126+
authRules: authRules,
127+
authModeStrategy: .default),
128+
"Should be false since OIDC is the default auth type on the API.")
129+
XCTAssertTrue(StorageEngine.requiresAuthPlugin(apiPlugin,
130+
authRules: authRules,
131+
authModeStrategy: .multiAuth),
132+
"Should be true since IAM requires auth plugin.")
133+
}
134+
135+
func testRequiresAuthPluginUserPoolProvider_MultiAuthRules() {
136+
let authRules = [AuthRule(allow: .owner, provider: .userPools),
137+
AuthRule(allow: .private, provider: .iam)]
138+
let apiPlugin = MockAPIAuthInformationPlugin()
139+
apiPlugin.authType = AWSAuthorizationType.amazonCognitoUserPools
140+
XCTAssertTrue(StorageEngine.requiresAuthPlugin(apiPlugin,
141+
authRules: authRules,
142+
authModeStrategy: .default),
143+
"Should be true since UserPool is the default auth type on the API.")
144+
XCTAssertTrue(StorageEngine.requiresAuthPlugin(apiPlugin,
145+
authRules: authRules,
146+
authModeStrategy: .multiAuth),
147+
"Should be true since both UserPool and IAM requires auth plugin.")
103148
}
104149

105150
func testRequiresAuthPluginFunctionProvider() {
@@ -108,14 +153,16 @@ class StorageEngineSyncRequirementsTests: XCTestCase {
108153
apiPlugin.defaultAuthTypeError = APIError.unknown("Could not get default auth type", "", nil)
109154
let functionProvider = MockFunctionAuthProvider()
110155
apiPlugin.authProviderFactory = MockAPIAuthProviderFactory(functionProvider: functionProvider)
111-
XCTAssertFalse(StorageEngine.requiresAuthPlugin(apiPlugin, authRules: authRules))
156+
XCTAssertFalse(StorageEngine.requiresAuthPlugin(apiPlugin, authRules: authRules, authModeStrategy: .default))
157+
XCTAssertFalse(StorageEngine.requiresAuthPlugin(apiPlugin, authRules: authRules, authModeStrategy: .multiAuth))
112158
}
113159

114160
func testRequiresAuthPluginWithAuthRules() {
115161
let authRules = [AuthRule(allow: .owner)]
116162
let apiPlugin = MockAPIAuthInformationPlugin()
117163
apiPlugin.defaultAuthTypeError = APIError.unknown("Could not get default auth type", "", nil)
118-
XCTAssertTrue(StorageEngine.requiresAuthPlugin(apiPlugin, authRules: authRules))
164+
XCTAssertTrue(StorageEngine.requiresAuthPlugin(apiPlugin, authRules: authRules, authModeStrategy: .default))
165+
XCTAssertTrue(StorageEngine.requiresAuthPlugin(apiPlugin, authRules: authRules, authModeStrategy: .multiAuth))
119166
}
120167

121168
// MARK: - AuthRules tests

0 commit comments

Comments
 (0)