Skip to content

Commit f2fd6f7

Browse files
authored
fix(auth): Fix isSignedIn states (#2830)
1 parent 37fc35e commit f2fd6f7

File tree

18 files changed

+506
-85
lines changed

18 files changed

+506
-85
lines changed

aws-auth-cognito/build.gradle.kts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,7 @@ dependencies {
5656
testImplementation(libs.test.androidx.core)
5757
testImplementation(libs.test.kotlin.reflection)
5858
testImplementation(libs.test.kotest.assertions)
59+
testImplementation(libs.test.kotest.assertions.json)
5960

6061
androidTestImplementation(libs.gson)
6162
//noinspection GradleDependency

aws-auth-cognito/src/main/java/com/amplifyframework/auth/cognito/AWSCognitoAuthSession.kt

Lines changed: 41 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -65,21 +65,39 @@ internal fun AmplifyCredential.isValid(): Boolean {
6565
}
6666

6767
internal fun AmplifyCredential.getCognitoSession(
68-
exception: AuthException = SignedOutException()
68+
exception: AuthException? = null
6969
): AWSAuthSessionBehavior<AWSCognitoUserPoolTokens> {
70-
fun getCredentialsResult(awsCredentials: CognitoCredentials): AuthSessionResult<AWSCredentials> =
71-
with(awsCredentials) {
70+
71+
fun getCredentialsResult(
72+
awsCredentials: CognitoCredentials,
73+
exception: AuthException?
74+
): AuthSessionResult<AWSCredentials> {
75+
if (exception != null && exception !is SignedOutException) {
76+
return AuthSessionResult.failure(exception)
77+
}
78+
79+
return with(awsCredentials) {
7280
AWSCredentials.createAWSCredentials(accessKeyId, secretAccessKey, sessionToken, expiration)
7381
}?.let {
7482
AuthSessionResult.success(it)
7583
} ?: AuthSessionResult.failure(UnknownException("Failed to fetch AWS credentials."))
84+
}
7685

77-
fun getIdentityIdResult(identityId: String): AuthSessionResult<String> {
78-
return if (identityId.isNotEmpty()) AuthSessionResult.success(identityId)
79-
else AuthSessionResult.failure(UnknownException("Failed to fetch identity id."))
86+
fun getIdentityIdResult(identityId: String, exception: AuthException?): AuthSessionResult<String> {
87+
return if (exception != null && exception !is SignedOutException) {
88+
AuthSessionResult.failure(exception)
89+
} else if (identityId.isNotEmpty()) {
90+
AuthSessionResult.success(identityId)
91+
} else {
92+
AuthSessionResult.failure(UnknownException("Failed to fetch identity id."))
93+
}
8094
}
8195

82-
fun getUserSubResult(userPoolTokens: CognitoUserPoolTokens?): AuthSessionResult<String> {
96+
fun getUserSubResult(userPoolTokens: CognitoUserPoolTokens?, exception: AuthException?): AuthSessionResult<String> {
97+
if (exception != null && exception !is SignedOutException) {
98+
return AuthSessionResult.failure(exception)
99+
}
100+
83101
return try {
84102
AuthSessionResult.success(userPoolTokens?.accessToken?.let(SessionHelper::getUserSub))
85103
} catch (e: Exception) {
@@ -88,8 +106,13 @@ internal fun AmplifyCredential.getCognitoSession(
88106
}
89107

90108
fun getUserPoolTokensResult(
91-
cognitoUserPoolTokens: CognitoUserPoolTokens
109+
cognitoUserPoolTokens: CognitoUserPoolTokens,
110+
exception: AuthException?
92111
): AuthSessionResult<AWSCognitoUserPoolTokens> {
112+
if (exception != null && exception !is SignedOutException) {
113+
return AuthSessionResult.failure(exception)
114+
}
115+
93116
return AuthSessionResult.success(
94117
AWSCognitoUserPoolTokens(
95118
accessToken = cognitoUserPoolTokens.accessToken,
@@ -113,20 +136,20 @@ internal fun AmplifyCredential.getCognitoSession(
113136
"Cognito Identity not configured. Please check amplifyconfiguration.json file."
114137
)
115138
),
116-
userSubResult = getUserSubResult(signedInData.cognitoUserPoolTokens),
117-
userPoolTokensResult = getUserPoolTokensResult(signedInData.cognitoUserPoolTokens)
139+
userSubResult = getUserSubResult(signedInData.cognitoUserPoolTokens, exception),
140+
userPoolTokensResult = getUserPoolTokensResult(signedInData.cognitoUserPoolTokens, exception)
118141
)
119142
is AmplifyCredential.UserAndIdentityPool -> AWSCognitoAuthSession(
120143
true,
121-
identityIdResult = getIdentityIdResult(identityId),
122-
awsCredentialsResult = getCredentialsResult(credentials),
123-
userSubResult = getUserSubResult(signedInData.cognitoUserPoolTokens),
124-
userPoolTokensResult = getUserPoolTokensResult(signedInData.cognitoUserPoolTokens)
144+
identityIdResult = getIdentityIdResult(identityId, exception),
145+
awsCredentialsResult = getCredentialsResult(credentials, exception),
146+
userSubResult = getUserSubResult(signedInData.cognitoUserPoolTokens, exception),
147+
userPoolTokensResult = getUserPoolTokensResult(signedInData.cognitoUserPoolTokens, exception)
125148
)
126149
is AmplifyCredential.IdentityPool -> AWSCognitoAuthSession(
127150
false,
128-
identityIdResult = getIdentityIdResult(identityId),
129-
awsCredentialsResult = getCredentialsResult(credentials),
151+
identityIdResult = getIdentityIdResult(identityId, exception),
152+
awsCredentialsResult = getCredentialsResult(credentials, exception),
130153
userSubResult = AuthSessionResult.failure(SignedOutException()),
131154
userPoolTokensResult = AuthSessionResult.failure(SignedOutException())
132155
)
@@ -137,8 +160,8 @@ internal fun AmplifyCredential.getCognitoSession(
137160
)
138161
AWSCognitoAuthSession(
139162
true,
140-
identityIdResult = getIdentityIdResult(identityId),
141-
awsCredentialsResult = getCredentialsResult(credentials),
163+
identityIdResult = getIdentityIdResult(identityId, exception),
164+
awsCredentialsResult = getCredentialsResult(credentials, exception),
142165
userSubResult = AuthSessionResult.failure(userPoolException),
143166
userPoolTokensResult = AuthSessionResult.failure(userPoolException)
144167
)

aws-auth-cognito/src/main/java/com/amplifyframework/auth/cognito/RealAWSCognitoAuthPlugin.kt

Lines changed: 11 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1127,7 +1127,7 @@ internal class RealAWSCognitoAuthPlugin(
11271127
when (val authZState = authState.authZState) {
11281128
is AuthorizationState.Configured -> {
11291129
authStateMachine.send(AuthorizationEvent(AuthorizationEvent.EventType.FetchUnAuthSession))
1130-
_fetchAuthSession(onSuccess, onError)
1130+
_fetchAuthSession(onSuccess)
11311131
}
11321132
is AuthorizationState.SessionEstablished -> {
11331133
val credential = authZState.amplifyCredential
@@ -1147,7 +1147,7 @@ internal class RealAWSCognitoAuthPlugin(
11471147
AuthorizationEvent(AuthorizationEvent.EventType.RefreshSession(credential))
11481148
)
11491149
}
1150-
_fetchAuthSession(onSuccess, onError)
1150+
_fetchAuthSession(onSuccess)
11511151
} else {
11521152
onSuccess.accept(credential.getCognitoSession())
11531153
}
@@ -1171,7 +1171,7 @@ internal class RealAWSCognitoAuthPlugin(
11711171
AuthorizationEvent(AuthorizationEvent.EventType.RefreshSession(amplifyCredential))
11721172
)
11731173
}
1174-
_fetchAuthSession(onSuccess, onError)
1174+
_fetchAuthSession(onSuccess)
11751175
} else {
11761176
onError.accept(InvalidStateException())
11771177
}
@@ -1182,8 +1182,7 @@ internal class RealAWSCognitoAuthPlugin(
11821182
}
11831183

11841184
private fun _fetchAuthSession(
1185-
onSuccess: Consumer<AuthSession>,
1186-
onError: Consumer<AuthException>
1185+
onSuccess: Consumer<AuthSession>
11871186
) {
11881187
val token = StateChangeListenerToken()
11891188
authStateMachine.listen(
@@ -1198,23 +1197,23 @@ internal class RealAWSCognitoAuthPlugin(
11981197
authStateMachine.cancel(token)
11991198
when (val error = authZState.exception) {
12001199
is SessionError -> {
1201-
when (error.exception) {
1200+
when (val innerException = error.exception) {
12021201
is SignedOutException -> {
1203-
onSuccess.accept(error.amplifyCredential.getCognitoSession(error.exception))
1202+
onSuccess.accept(error.amplifyCredential.getCognitoSession(innerException))
12041203
}
12051204
is SessionExpiredException -> {
1206-
onSuccess.accept(AmplifyCredential.Empty.getCognitoSession(error.exception))
1205+
onSuccess.accept(error.amplifyCredential.getCognitoSession(innerException))
12071206
sendHubEvent(AuthChannelEventName.SESSION_EXPIRED.toString())
12081207
}
12091208
is ServiceException -> {
1210-
onSuccess.accept(AmplifyCredential.Empty.getCognitoSession(error.exception))
1209+
onSuccess.accept(error.amplifyCredential.getCognitoSession(innerException))
12111210
}
12121211
is NotAuthorizedException -> {
1213-
onSuccess.accept(AmplifyCredential.Empty.getCognitoSession(error.exception))
1212+
onSuccess.accept(error.amplifyCredential.getCognitoSession(innerException))
12141213
}
12151214
else -> {
1216-
val errorResult = UnknownException("Fetch auth session failed.", error)
1217-
onSuccess.accept(AmplifyCredential.Empty.getCognitoSession(errorResult))
1215+
val errorResult = UnknownException("Fetch auth session failed.", innerException)
1216+
onSuccess.accept(error.amplifyCredential.getCognitoSession(errorResult))
12181217
}
12191218
}
12201219
}

aws-auth-cognito/src/main/java/com/amplifyframework/auth/cognito/actions/FetchAuthSessionCognitoActions.kt

Lines changed: 2 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -136,11 +136,7 @@ internal object FetchAuthSessionCognitoActions : FetchAuthSessionActions {
136136
)
137137
AuthorizationEvent(AuthorizationEvent.EventType.ThrowError(exception))
138138
} catch (e: Exception) {
139-
val exception = SignedOutException(
140-
recoverySuggestion = SignedOutException.RECOVERY_SUGGESTION_GUEST_ACCESS_POSSIBLE,
141-
cause = e
142-
)
143-
AuthorizationEvent(AuthorizationEvent.EventType.ThrowError(exception))
139+
AuthorizationEvent(AuthorizationEvent.EventType.ThrowError(e))
144140
}
145141
logger.verbose("$id Sending event ${evt.type}")
146142
dispatcher.send(evt)
@@ -173,11 +169,7 @@ internal object FetchAuthSessionCognitoActions : FetchAuthSessionActions {
173169
)
174170
AuthorizationEvent(AuthorizationEvent.EventType.ThrowError(exception))
175171
} catch (e: Exception) {
176-
val exception = SignedOutException(
177-
recoverySuggestion = SignedOutException.RECOVERY_SUGGESTION_GUEST_ACCESS_POSSIBLE,
178-
cause = e
179-
)
180-
AuthorizationEvent(AuthorizationEvent.EventType.ThrowError(exception))
172+
AuthorizationEvent(AuthorizationEvent.EventType.ThrowError(e))
181173
}
182174
logger.verbose("$id Sending event ${evt.type}")
183175
dispatcher.send(evt)

aws-auth-cognito/src/test/java/com/amplifyframework/auth/cognito/AWSCognitoAuthPluginFeatureTest.kt

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,9 @@ import com.amplifyframework.statemachine.codegen.data.DeviceMetadata
3333
import com.amplifyframework.statemachine.codegen.states.AuthState
3434
import featureTest.utilities.CognitoMockFactory
3535
import featureTest.utilities.CognitoRequestFactory
36+
import featureTest.utilities.TimeZoneRule
3637
import featureTest.utilities.apiExecutor
38+
import io.kotest.assertions.json.shouldEqualJson
3739
import io.mockk.clearAllMocks
3840
import io.mockk.coEvery
3941
import io.mockk.coVerify
@@ -43,6 +45,7 @@ import io.mockk.mockkObject
4345
import io.mockk.mockkStatic
4446
import io.mockk.slot
4547
import java.io.File
48+
import java.util.TimeZone
4649
import java.util.concurrent.CountDownLatch
4750
import java.util.concurrent.TimeUnit
4851
import kotlin.reflect.full.callSuspend
@@ -56,13 +59,16 @@ import kotlinx.serialization.json.Json
5659
import org.json.JSONObject
5760
import org.junit.After
5861
import org.junit.Before
62+
import org.junit.Rule
5963
import org.junit.Test
6064
import org.junit.runner.RunWith
6165
import org.junit.runners.Parameterized
6266

6367
@RunWith(Parameterized::class)
6468
class AWSCognitoAuthPluginFeatureTest(private val testCase: FeatureTestCase) {
6569

70+
@Rule @JvmField val timeZoneRule = TimeZoneRule(TimeZone.getTimeZone("US/Pacific"))
71+
6672
lateinit var feature: FeatureTestCase
6773
private var apiExecutionResult: Any? = null
6874

@@ -114,6 +120,7 @@ class AWSCognitoAuthPluginFeatureTest(private val testCase: FeatureTestCase) {
114120

115121
@Before
116122
fun setUp() {
123+
// set timezone to be same as generated json from JsonGenerator
117124
Dispatchers.setMain(mainThreadSurrogate)
118125
feature = testCase
119126
sut.realPlugin = readConfiguration(feature.preConditions.`amplify-configuration`)
@@ -189,9 +196,9 @@ class AWSCognitoAuthPluginFeatureTest(private val testCase: FeatureTestCase) {
189196
is Cognito -> verifyCognito(validation)
190197

191198
is ExpectationShapes.Amplify -> {
192-
val expectedResponse = validation.response
193-
194-
assertEquals(expectedResponse, apiExecutionResult.toJsonElement())
199+
val expected = validation.response.toString()
200+
val actual = apiExecutionResult.toJsonElement().toString()
201+
actual shouldEqualJson expected
195202
}
196203
is ExpectationShapes.State -> {
197204
val getStateLatch = CountDownLatch(1)
@@ -214,7 +221,7 @@ class AWSCognitoAuthPluginFeatureTest(private val testCase: FeatureTestCase) {
214221

215222
coVerify {
216223
when (validation) {
217-
is CognitoIdentity -> mockCognitoIdClient to mockCognitoIPClient::class
224+
is CognitoIdentity -> mockCognitoIdClient to mockCognitoIdClient::class
218225
is CognitoIdentityProvider -> mockCognitoIPClient to mockCognitoIPClient::class
219226
}.apply {
220227
second.declaredFunctions.first {

aws-auth-cognito/src/test/java/com/amplifyframework/auth/cognito/featuretest/generators/JsonGenerator.kt

Lines changed: 28 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -29,15 +29,22 @@ import com.amplifyframework.auth.cognito.featuretest.generators.testcasegenerato
2929
import com.amplifyframework.auth.cognito.featuretest.generators.testcasegenerators.SignOutTestCaseGenerator
3030
import com.amplifyframework.auth.cognito.featuretest.generators.testcasegenerators.SignUpTestCaseGenerator
3131
import com.amplifyframework.statemachine.codegen.states.AuthState
32+
import org.junit.Ignore
33+
import org.junit.Test
3234

3335
interface SerializableProvider {
3436
val serializables: List<Any>
37+
38+
// used to reset any global state changes during generation
39+
fun tearDown() {
40+
// default no op
41+
}
3542
}
3643

3744
/**
3845
* Top level generator for generating Json and writing to the destination directory
3946
*/
40-
object JsonGenerator {
47+
class JsonGenerator {
4148
private val providers: List<SerializableProvider> = listOf(
4249
AuthStateJsonGenerator,
4350
ResetPasswordTestCaseGenerator,
@@ -53,7 +60,26 @@ object JsonGenerator {
5360
FetchUserAttributesTestCaseGenerator,
5461
)
5562

63+
@Ignore("Uncomment and run to clean feature test directory")
64+
@Test
65+
fun clean() {
66+
cleanDirectory()
67+
}
68+
69+
@Ignore("Uncomment and run to clean feature test directory as well as generate json for feature tests.")
70+
@Test
71+
fun cleanAndGenerate() {
72+
cleanDirectory()
73+
generateJson()
74+
}
75+
76+
@Ignore("Uncomment and run to generate json for feature tests.")
77+
@Test
5678
fun generate() {
79+
generateJson()
80+
}
81+
82+
private fun generateJson() {
5783
providers.forEach { provider ->
5884
provider.serializables.forEach {
5985
when (it) {
@@ -64,11 +90,7 @@ object JsonGenerator {
6490
}
6591
}
6692
}
93+
provider.tearDown()
6794
}
6895
}
6996
}
70-
71-
fun main() {
72-
// cleanDirectory()
73-
JsonGenerator.generate()
74-
}

aws-auth-cognito/src/test/java/com/amplifyframework/auth/cognito/featuretest/generators/SerializationTools.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ import kotlinx.serialization.json.JsonNull
4343
import kotlinx.serialization.json.JsonObject
4444
import kotlinx.serialization.json.JsonPrimitive
4545

46-
const val basePath = "aws-auth-cognito/src/test/resources/feature-test"
46+
const val basePath = "src/test/resources/feature-test"
4747

4848
fun writeFile(json: String, dirName: String, fileName: String) {
4949
val directory = File("$basePath/$dirName")

0 commit comments

Comments
 (0)