Skip to content

Commit 97e491f

Browse files
authored
fix(auth): Replace force unwrap to throw an error in AWS credentials (#1476)
1 parent cc77e86 commit 97e491f

File tree

7 files changed

+181
-38
lines changed

7 files changed

+181
-38
lines changed

AmplifyPlugins/Auth/AWSCognitoAuthPlugin/Dependency/AuthorizationProviderAdapter+SignedInSession.swift

Lines changed: 13 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -182,13 +182,19 @@ extension AuthorizationProviderAdapter {
182182
self.fetchSignedInSession(withError: error, completionHandler)
183183
return nil
184184
}
185-
let amplifyCredentials = credentials.toAmplifyAWSCredentials()
186-
let authSession = AWSAuthCognitoSession(isSignedIn: true,
187-
userSubResult: userSubResult,
188-
identityIdResult: .success(identityId),
189-
awsCredentialsResult: .success(amplifyCredentials),
190-
cognitoTokensResult: tokenResult)
191-
completionHandler(.success(authSession))
185+
186+
do {
187+
let amplifyCredentials = try credentials.toAmplifyAWSCredentials()
188+
let authSession = AWSAuthCognitoSession(isSignedIn: true,
189+
userSubResult: userSubResult,
190+
identityIdResult: .success(identityId),
191+
awsCredentialsResult: .success(amplifyCredentials),
192+
cognitoTokensResult: tokenResult)
193+
completionHandler(.success(authSession))
194+
} catch {
195+
let authError = AuthErrorHelper.toAuthError(error)
196+
self.fetchSignedInSession(withError: authError, completionHandler)
197+
}
192198
return nil
193199
}
194200
}

AmplifyPlugins/Auth/AWSCognitoAuthPlugin/Dependency/AuthorizationProviderAdapter+SignedOutSession.swift

Lines changed: 16 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -61,11 +61,22 @@ extension AuthorizationProviderAdapter {
6161
completionHandler(.success(authSession))
6262
return nil
6363
}
64-
let authSession = AuthCognitoSignedOutSessionHelper.makeSignedOutSession(
65-
identityId: identityId,
66-
awsCredentials: awsCredentials.toAmplifyAWSCredentials())
67-
completionHandler(.success(authSession))
68-
return nil
64+
65+
do {
66+
let amplifyAWSCredentials = try awsCredentials.toAmplifyAWSCredentials()
67+
let authSession = AuthCognitoSignedOutSessionHelper.makeSignedOutSession(
68+
identityId: identityId,
69+
awsCredentials: amplifyAWSCredentials
70+
)
71+
completionHandler(.success(authSession))
72+
return nil
73+
74+
} catch {
75+
let authSession = AuthCognitoSignedOutSessionHelper.makeSignedOutSession(withError: error)
76+
completionHandler(.success(authSession))
77+
return nil
78+
}
79+
6980
}
7081
}
7182
}

AmplifyPlugins/Auth/AWSCognitoAuthPlugin/Support/Utils/AWSCredentials+Extension.swift

Lines changed: 20 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -7,16 +7,29 @@
77

88
import Foundation
99
import AWSCore
10+
import Amplify
1011

1112
extension AWSCredentials {
1213

13-
func toAmplifyAWSCredentials() -> AuthAWSCognitoCredentials {
14+
func toAmplifyAWSCredentials() throws -> AuthAWSCognitoCredentials {
15+
1416
// Credentials are fetched through Cognito Identity Pool and thus these are temporary credentials
15-
// so sessionKey and expiration date will not be nil.
16-
let credentials = AuthAWSCognitoCredentials(accessKey: accessKey,
17-
secretKey: secretKey,
18-
sessionKey: sessionKey!,
19-
expiration: expiration!)
20-
return credentials
17+
// so sessionKey and expiration date should not be nil.
18+
let nonNilAccessKey = accessKey
19+
let nonNilSecretKey = secretKey
20+
guard let nonNilSessionKey = sessionKey,
21+
let nonNilExpiration = expiration,
22+
!nonNilAccessKey.isEmpty,
23+
!nonNilSecretKey.isEmpty else {
24+
let error = AuthError.unknown("""
25+
Could not retreive AWS credentials, credential value is nil or empty.
26+
""")
27+
throw error
28+
}
29+
30+
return AuthAWSCognitoCredentials(accessKey: nonNilAccessKey,
31+
secretKey: nonNilSecretKey,
32+
sessionKey: nonNilSessionKey,
33+
expiration: nonNilExpiration)
2134
}
2235
}

AmplifyPlugins/Auth/AWSCognitoAuthPlugin/Support/Utils/AuthErrorHelper.swift

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -171,6 +171,8 @@ struct AuthErrorHelper {
171171
static func toAuthError(_ error: Error) -> AuthError {
172172
if let awsMobileClientError = error as? AWSMobileClientError {
173173
return toAuthError(awsMobileClientError: awsMobileClientError)
174+
} else if let authError = error as? AuthError {
175+
return authError
174176
}
175177
return AuthError.unknown("An unknown error occurred", error)
176178

AmplifyPlugins/Auth/AWSCognitoAuthPluginTests/AuthorizationProviderTests/AuthorizationProviderSessionSignInTests.swift

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -713,4 +713,61 @@ class AuthorizationProviderSessionSignInTests: BaseAuthorizationProviderTest {
713713
}
714714
wait(for: [resultExpectation], timeout: apiTimeout)
715715
}
716+
717+
/// Test signedIn session with nil values in AWS credentials
718+
///
719+
/// - Given: Given an auth plugin with signedIn state
720+
/// - When:
721+
/// - I invoke fetchAuthSession and mock nil values for aws credentials
722+
/// - Then:
723+
/// - I should get an a valid session with the following details:
724+
/// - isSignedIn = true
725+
/// - aws credentails = unknown error
726+
/// - identity id = unknown error
727+
/// - cognito tokens = unknown error
728+
///
729+
func testSignInSessionWithNilValuesAWSCredentials() {
730+
mockAWSCredentials()
731+
mockCognitoTokens()
732+
mockIdentityId()
733+
mockAWSMobileClient.awsCredentialsMockResult = .success(AWSCredentials(accessKey: "mockAccess",
734+
secretKey: "mockSecret",
735+
sessionKey: "mockSession",
736+
expiration: nil))
737+
let resultExpectation = expectation(description: "Should receive a result")
738+
_ = plugin.fetchAuthSession(options: AuthFetchSessionRequest.Options()) { result in
739+
defer {
740+
resultExpectation.fulfill()
741+
}
742+
switch result {
743+
case .success(let session):
744+
745+
XCTAssertTrue(session.isSignedIn)
746+
747+
let credentialsResult = (session as? AuthAWSCredentialsProvider)?.getAWSCredentials()
748+
guard case .failure(let error) = credentialsResult,
749+
case .unknown = error else {
750+
XCTFail("Should return unknown error")
751+
return
752+
}
753+
754+
let identityIdResult = (session as? AuthCognitoIdentityProvider)?.getIdentityId()
755+
guard case .failure(let identityIdError) = identityIdResult,
756+
case .unknown = identityIdError else {
757+
XCTFail("Should return unknown error")
758+
return
759+
}
760+
761+
let tokensResult = (session as? AuthCognitoTokensProvider)?.getCognitoTokens()
762+
guard case .failure(let tokenError) = tokensResult,
763+
case .unknown = tokenError else {
764+
XCTFail("Should return unknown error")
765+
return
766+
}
767+
case .failure(let error):
768+
XCTFail("Received failure with error \(error)")
769+
}
770+
}
771+
wait(for: [resultExpectation], timeout: apiTimeout)
772+
}
716773
}

AmplifyPlugins/Auth/AWSCognitoAuthPluginTests/AuthorizationProviderTests/AuthorizationProviderSessionSignoutTests.swift

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -880,4 +880,58 @@ class AuthorizationProviderSessionSignoutTests: BaseAuthorizationProviderTest {
880880
}
881881
wait(for: [resultExpectation], timeout: apiTimeout)
882882
}
883+
884+
/// Test signedOut session with session with nil values in AWS credentials
885+
///
886+
/// - Given: Given an auth plugin with signedOut state and unauthenticated access enabled in backend
887+
/// - When:
888+
/// - I invoke fetchAuthSession and mock nil values in aws credentials
889+
/// - Then:
890+
/// - I should get an a valid session with the following details:
891+
/// - isSignedIn = false
892+
/// - aws credentails = .unknown error
893+
/// - identity id = .unknown error
894+
/// - cognito tokens = .signedOut error
895+
func testSignedOutSessionWithNilAWSCredentials() {
896+
mockIdentityId()
897+
mockAWSMobileClient.awsCredentialsMockResult = .success(AWSCredentials(accessKey: "mockAccess",
898+
secretKey: "mockSecret",
899+
sessionKey: "mockSession",
900+
expiration: nil))
901+
902+
let resultExpectation = expectation(description: "Should receive a result")
903+
_ = plugin.fetchAuthSession(options: AuthFetchSessionRequest.Options()) { result in
904+
defer {
905+
resultExpectation.fulfill()
906+
}
907+
switch result {
908+
case .success(let session):
909+
XCTAssertFalse(session.isSignedIn)
910+
911+
let credentialsResult = (session as? AuthAWSCredentialsProvider)?.getAWSCredentials()
912+
guard case .failure(let credentialsError) = credentialsResult,
913+
case .unknown = credentialsError else {
914+
XCTFail("Should return unknown error")
915+
return
916+
}
917+
918+
let identityIdResult = (session as? AuthCognitoIdentityProvider)?.getIdentityId()
919+
guard case .failure(let identityIdError) = identityIdResult,
920+
case .unknown = identityIdError else {
921+
XCTFail("Should return unknown error")
922+
return
923+
}
924+
925+
let tokensResult = (session as? AuthCognitoTokensProvider)?.getCognitoTokens()
926+
guard case .failure(let error) = tokensResult,
927+
case .signedOut = error else {
928+
XCTFail("Should return signedOut error")
929+
return
930+
}
931+
case .failure(let error):
932+
XCTFail("Received failure with error \(error)")
933+
}
934+
}
935+
wait(for: [resultExpectation], timeout: apiTimeout)
936+
}
883937
}

AmplifyPlugins/Auth/Podfile.lock

Lines changed: 19 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -10,26 +10,26 @@ PODS:
1010
- AWSCore (~> 2.26.1)
1111
- AWSMobileClient (~> 2.26.1)
1212
- AWSPluginsCore (= 1.15.2)
13-
- AWSAuthCore (2.26.1):
14-
- AWSCore (= 2.26.1)
15-
- AWSCognitoIdentityProvider (2.26.1):
16-
- AWSCognitoIdentityProviderASF (= 2.26.1)
17-
- AWSCore (= 2.26.1)
18-
- AWSCognitoIdentityProviderASF (2.26.1)
19-
- AWSCore (2.26.1)
20-
- AWSMobileClient (2.26.1):
21-
- AWSAuthCore (= 2.26.1)
22-
- AWSCognitoIdentityProvider (= 2.26.1)
23-
- AWSCognitoIdentityProviderASF (= 2.26.1)
24-
- AWSCore (= 2.26.1)
13+
- AWSAuthCore (2.26.2):
14+
- AWSCore (= 2.26.2)
15+
- AWSCognitoIdentityProvider (2.26.2):
16+
- AWSCognitoIdentityProviderASF (= 2.26.2)
17+
- AWSCore (= 2.26.2)
18+
- AWSCognitoIdentityProviderASF (2.26.2)
19+
- AWSCore (2.26.2)
20+
- AWSMobileClient (2.26.2):
21+
- AWSAuthCore (= 2.26.2)
22+
- AWSCognitoIdentityProvider (= 2.26.2)
23+
- AWSCognitoIdentityProviderASF (= 2.26.2)
24+
- AWSCore (= 2.26.2)
2525
- AWSPluginsCore (1.15.2):
2626
- Amplify (= 1.15.2)
2727
- AWSCore (~> 2.26.1)
2828
- CwlCatchException (1.0.2)
2929
- CwlPreconditionTesting (1.1.1):
3030
- CwlCatchException
3131
- SwiftFormat/CLI (0.44.17)
32-
- SwiftLint (0.44.0)
32+
- SwiftLint (0.45.0)
3333

3434
DEPENDENCIES:
3535
- Amplify (from `../../`)
@@ -76,16 +76,16 @@ CHECKOUT OPTIONS:
7676
SPEC CHECKSUMS:
7777
Amplify: f0e9e511d05925a1dd7b2b097b13694b2015aa25
7878
AmplifyTestCommon: 283bd8bf694569b1dda7f40f40a8ad1f97784eeb
79-
AWSAuthCore: 264faaa6af5990af2c77effe8f398a4b80e6c44e
80-
AWSCognitoIdentityProvider: 5df455775b57eb4e61862acd88d93e56113950c4
81-
AWSCognitoIdentityProviderASF: b2c180f69537d57ff485f7314fd266032ca3f898
82-
AWSCore: 0f855e20ccb13e028932b737f0706023a9561399
83-
AWSMobileClient: ba255030a481b8a123b21585548e761456efc64b
79+
AWSAuthCore: c785a33af10a45aab6456a5fa7150f759dad836f
80+
AWSCognitoIdentityProvider: 0bea89a822d7dd76c7dc62212561a1074dee0031
81+
AWSCognitoIdentityProviderASF: 425d7f40fb6a520f8437a5f8b991215239ec620b
82+
AWSCore: dd7f74ab3f354aad435f83afdbfac91bcb7d44c2
83+
AWSMobileClient: fc20c58eaad166b3d2a569ef9ce691d6fed0c5dd
8484
AWSPluginsCore: ff09e8b86b7969327a1ba0b8c6946d83008cbf81
8585
CwlCatchException: 70a52ae44ea5d46db7bd385f801a94942420cd8c
8686
CwlPreconditionTesting: d33a4e4f285c0b885fddcae5dfedfbb34d4f3961
8787
SwiftFormat: 3b5caa6389b2b9adbc00e133b3ccc8c6e687a6a4
88-
SwiftLint: e96c0a8c770c7ebbc4d36c55baf9096bb65c4584
88+
SwiftLint: e5c7f1fba68eccfc51509d5b2ce1699f5502e0c7
8989

9090
PODFILE CHECKSUM: 371cf67fe35ebb5167d0880bad12b01618a0fb0e
9191

0 commit comments

Comments
 (0)