Skip to content

Commit 30a288e

Browse files
authored
feat(auth): Expose AuthConfiguration directly (#2740)
1 parent b448ecc commit 30a288e

28 files changed

+363
-124
lines changed

aws-auth-cognito/build.gradle.kts

+1
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@ dependencies {
5555
testImplementation(libs.test.robolectric)
5656
testImplementation(libs.test.androidx.core)
5757
testImplementation(libs.test.kotlin.reflection)
58+
testImplementation(libs.test.kotest.assertions)
5859

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

aws-auth-cognito/src/androidTest/java/com/amplifyframework/auth/cognito/AWSCognitoLegacyCredentialStoreInstrumentationTest.kt

-1
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,6 @@ import androidx.test.platform.app.InstrumentationRegistry
2020
import com.amplifyframework.auth.cognito.data.AWSCognitoLegacyCredentialStore
2121
import com.amplifyframework.auth.cognito.testutils.AuthConfigurationProvider
2222
import com.amplifyframework.auth.cognito.testutils.CredentialStoreUtil
23-
import com.amplifyframework.statemachine.codegen.data.AuthConfiguration
2423
import org.junit.Assert.assertTrue
2524
import org.junit.Before
2625
import org.junit.Test

aws-auth-cognito/src/androidTest/java/com/amplifyframework/auth/cognito/CredentialStoreStateMachineInstrumentationTest.kt

-1
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,6 @@ import androidx.test.platform.app.InstrumentationRegistry
2020
import com.amplifyframework.auth.cognito.data.AWSCognitoAuthCredentialStore
2121
import com.amplifyframework.auth.cognito.testutils.AuthConfigurationProvider
2222
import com.amplifyframework.auth.cognito.testutils.CredentialStoreUtil
23-
import com.amplifyframework.statemachine.codegen.data.AuthConfiguration
2423
import com.google.gson.Gson
2524
import org.json.JSONObject
2625
import org.junit.Before

aws-auth-cognito/src/androidTest/java/com/amplifyframework/auth/cognito/testutils/AuthConfigurationProvider.kt

+1-1
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515

1616
package com.amplifyframework.auth.cognito.testutils
1717

18-
import com.amplifyframework.statemachine.codegen.data.AuthConfiguration
18+
import com.amplifyframework.auth.cognito.AuthConfiguration
1919
import com.google.gson.Gson
2020
import com.google.gson.annotations.SerializedName
2121
import kotlinx.serialization.Serializable

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

+4-1
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,6 @@ import com.amplifyframework.core.Action
6161
import com.amplifyframework.core.Amplify
6262
import com.amplifyframework.core.Consumer
6363
import com.amplifyframework.core.category.CategoryType
64-
import com.amplifyframework.statemachine.codegen.data.AuthConfiguration
6564
import kotlinx.coroutines.CoroutineScope
6665
import kotlinx.coroutines.CoroutineStart
6766
import kotlinx.coroutines.Dispatchers
@@ -100,10 +99,14 @@ class AWSCognitoAuthPlugin : AuthPlugin<AWSCognitoAuthService>() {
10099
private lateinit var pluginConfigurationJSON: JSONObject
101100

102101
@InternalAmplifyApi
102+
@Deprecated("Use getAuthConfiguration instead", replaceWith = ReplaceWith("getAuthConfiguration()"))
103103
fun getPluginConfiguration(): JSONObject {
104104
return pluginConfigurationJSON
105105
}
106106

107+
@InternalAmplifyApi
108+
fun getAuthConfiguration() = realPlugin.configuration
109+
107110
@InternalAmplifyApi
108111
fun addToUserAgent(type: AWSCognitoAuthMetadataType, value: String) {
109112
realPlugin.addToUserAgent(type, value)

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

-1
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,6 @@ import aws.sdk.kotlin.services.cognitoidentityprovider.endpoints.CognitoIdentity
2222
import aws.smithy.kotlin.runtime.client.RequestInterceptorContext
2323
import aws.smithy.kotlin.runtime.client.endpoints.Endpoint
2424
import aws.smithy.kotlin.runtime.http.interceptors.HttpInterceptor
25-
import com.amplifyframework.statemachine.codegen.data.AuthConfiguration
2625

2726
interface AWSCognitoAuthService {
2827
val cognitoIdentityProviderClient: CognitoIdentityProviderClient?
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,139 @@
1+
/*
2+
* Copyright 2024 Amazon.com, Inc. or its affiliates. All Rights Reserved.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License").
5+
* You may not use this file except in compliance with the License.
6+
* A copy of the License is located at
7+
*
8+
* http://aws.amazon.com/apache2.0
9+
*
10+
* or in the "license" file accompanying this file. This file is distributed
11+
* on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
12+
* express or implied. See the License for the specific language governing
13+
* permissions and limitations under the License.
14+
*/
15+
16+
package com.amplifyframework.auth.cognito
17+
18+
import androidx.annotation.IntRange
19+
import com.amplifyframework.annotations.InternalAmplifyApi
20+
import com.amplifyframework.auth.AuthUserAttributeKey
21+
import com.amplifyframework.auth.cognito.options.AuthFlowType
22+
import com.amplifyframework.statemachine.codegen.data.IdentityPoolConfiguration
23+
import com.amplifyframework.statemachine.codegen.data.OauthConfiguration
24+
import com.amplifyframework.statemachine.codegen.data.UserPoolConfiguration
25+
import org.json.JSONArray
26+
import org.json.JSONObject
27+
28+
@InternalAmplifyApi
29+
enum class UsernameAttribute {
30+
Username,
31+
Email,
32+
PhoneNumber
33+
}
34+
35+
@InternalAmplifyApi
36+
enum class VerificationMechanism {
37+
Email,
38+
PhoneNumber
39+
}
40+
41+
@InternalAmplifyApi
42+
data class PasswordProtectionSettings(
43+
@IntRange(from = 6, to = 99) val length: Int,
44+
val requiresNumber: Boolean,
45+
val requiresSpecial: Boolean,
46+
val requiresUpper: Boolean,
47+
val requiresLower: Boolean
48+
)
49+
50+
/**
51+
* Configuration options for [AWSCognitoAuthPlugin].
52+
*/
53+
@InternalAmplifyApi
54+
data class AuthConfiguration internal constructor(
55+
val userPool: UserPoolConfiguration?,
56+
val identityPool: IdentityPoolConfiguration?,
57+
val oauth: OauthConfiguration?,
58+
val authFlowType: AuthFlowType,
59+
val signUpAttributes: List<AuthUserAttributeKey>,
60+
val usernameAttributes: List<UsernameAttribute>,
61+
val verificationMechanisms: List<VerificationMechanism>,
62+
val passwordProtectionSettings: PasswordProtectionSettings?
63+
) {
64+
65+
internal companion object {
66+
/**
67+
* Returns an AuthConfiguration instance from JSON
68+
* @return populated AuthConfiguration instance.
69+
*/
70+
fun fromJson(
71+
pluginJson: JSONObject,
72+
configName: String = "Default"
73+
): AuthConfiguration {
74+
val authConfig = pluginJson.optJSONObject("Auth")?.optJSONObject(configName)
75+
76+
val signUpAttributes = authConfig?.optJSONArray("signupAttributes")?.map {
77+
AuthUserAttributeKey.custom(getString(it).lowercase())
78+
} ?: emptyList()
79+
80+
val usernameAttributes = authConfig?.optJSONArray("usernameAttributes")?.map {
81+
when (getString(it)) {
82+
"EMAIL" -> UsernameAttribute.Email
83+
"PHONE_NUMBER" -> UsernameAttribute.PhoneNumber
84+
else -> UsernameAttribute.Username
85+
}
86+
} ?: emptyList()
87+
88+
val verificationMechanisms = authConfig?.optJSONArray("verificationMechanisms")?.map {
89+
when (getString(it)) {
90+
"EMAIL" -> VerificationMechanism.Email
91+
else -> VerificationMechanism.PhoneNumber
92+
}
93+
} ?: emptyList()
94+
95+
return AuthConfiguration(
96+
userPool = pluginJson.optJSONObject("CognitoUserPool")?.getJSONObject(configName)?.let {
97+
UserPoolConfiguration.fromJson(it).build()
98+
},
99+
identityPool = pluginJson.optJSONObject("CredentialsProvider")
100+
?.getJSONObject("CognitoIdentity")
101+
?.getJSONObject(configName)?.let {
102+
IdentityPoolConfiguration.fromJson(it).build()
103+
},
104+
oauth = authConfig?.optJSONObject("OAuth")?.let { OauthConfiguration.fromJson(it) },
105+
authFlowType = getAuthenticationFlowType(authConfig?.optString("authenticationFlowType")),
106+
signUpAttributes = signUpAttributes,
107+
usernameAttributes = usernameAttributes,
108+
verificationMechanisms = verificationMechanisms,
109+
passwordProtectionSettings = getPasswordProtectionSettings(authConfig)
110+
)
111+
}
112+
private fun getAuthenticationFlowType(authType: String?): AuthFlowType {
113+
return if (!authType.isNullOrEmpty() && AuthFlowType.values().any { it.name == authType }) {
114+
AuthFlowType.valueOf(authType)
115+
} else {
116+
AuthFlowType.USER_SRP_AUTH
117+
}
118+
}
119+
120+
private fun getPasswordProtectionSettings(authConfig: JSONObject?): PasswordProtectionSettings? {
121+
val passwordSettings = authConfig?.optJSONObject("passwordProtectionSettings") ?: return null
122+
val passwordLength = passwordSettings.optInt("passwordPolicyMinLength")
123+
val passwordRequirements = passwordSettings.optJSONArray("passwordPolicyCharacters")?.map {
124+
getString(it)
125+
} ?: emptyList()
126+
return PasswordProtectionSettings(
127+
length = passwordLength,
128+
requiresNumber = passwordRequirements.contains("REQUIRES_NUMBERS"),
129+
requiresSpecial = passwordRequirements.contains("REQUIRES_SYMBOLS"),
130+
requiresLower = passwordRequirements.contains("REQUIRES_LOWER"),
131+
requiresUpper = passwordRequirements.contains("REQUIRES_UPPER")
132+
)
133+
}
134+
135+
private inline fun <T> JSONArray.map(func: JSONArray.(Int) -> T) = List(length()) {
136+
func(it)
137+
}
138+
}
139+
}

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

-1
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,6 @@ import com.amplifyframework.logging.Logger
2323
import com.amplifyframework.statemachine.Environment
2424
import com.amplifyframework.statemachine.StateMachineEvent
2525
import com.amplifyframework.statemachine.codegen.data.AmplifyCredential
26-
import com.amplifyframework.statemachine.codegen.data.AuthConfiguration
2726
import com.amplifyframework.statemachine.codegen.data.CredentialType
2827
import com.amplifyframework.statemachine.codegen.data.DeviceMetadata
2928
import com.amplifyframework.statemachine.codegen.events.AuthEvent

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

-1
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,6 @@ import com.amplifyframework.auth.cognito.data.AWSCognitoLegacyCredentialStore
2121
import com.amplifyframework.logging.Logger
2222
import com.amplifyframework.statemachine.StateChangeListenerToken
2323
import com.amplifyframework.statemachine.codegen.data.AmplifyCredential
24-
import com.amplifyframework.statemachine.codegen.data.AuthConfiguration
2524
import com.amplifyframework.statemachine.codegen.data.CredentialType
2625
import com.amplifyframework.statemachine.codegen.events.CredentialStoreEvent
2726
import com.amplifyframework.statemachine.codegen.states.CredentialStoreState

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

+1-2
Original file line numberDiff line numberDiff line change
@@ -136,7 +136,6 @@ import com.amplifyframework.logging.Logger
136136
import com.amplifyframework.statemachine.StateChangeListenerToken
137137
import com.amplifyframework.statemachine.codegen.data.AmplifyCredential
138138
import com.amplifyframework.statemachine.codegen.data.AuthChallenge
139-
import com.amplifyframework.statemachine.codegen.data.AuthConfiguration
140139
import com.amplifyframework.statemachine.codegen.data.FederatedToken
141140
import com.amplifyframework.statemachine.codegen.data.HostedUIErrorData
142141
import com.amplifyframework.statemachine.codegen.data.SignInData
@@ -173,7 +172,7 @@ import kotlinx.coroutines.async
173172
import kotlinx.coroutines.launch
174173

175174
internal class RealAWSCognitoAuthPlugin(
176-
private val configuration: AuthConfiguration,
175+
val configuration: AuthConfiguration,
177176
private val authEnvironment: AuthEnvironment,
178177
private val authStateMachine: AuthStateMachine,
179178
private val logger: Logger

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

+2-3
Original file line numberDiff line numberDiff line change
@@ -16,20 +16,19 @@
1616
package com.amplifyframework.auth.cognito.data
1717

1818
import android.content.Context
19+
import com.amplifyframework.auth.cognito.AuthConfiguration
1920
import com.amplifyframework.core.store.KeyValueRepository
2021
import com.amplifyframework.statemachine.codegen.data.AmplifyCredential
21-
import com.amplifyframework.statemachine.codegen.data.AuthConfiguration
2222
import com.amplifyframework.statemachine.codegen.data.AuthCredentialStore
2323
import com.amplifyframework.statemachine.codegen.data.DeviceMetadata
24-
import kotlinx.serialization.decodeFromString
2524
import kotlinx.serialization.encodeToString
2625
import kotlinx.serialization.json.Json
2726

2827
internal class AWSCognitoAuthCredentialStore(
2928
val context: Context,
3029
private val authConfiguration: AuthConfiguration,
3130
isPersistenceEnabled: Boolean = true,
32-
keyValueRepoFactory: KeyValueRepositoryFactory = KeyValueRepositoryFactory(),
31+
keyValueRepoFactory: KeyValueRepositoryFactory = KeyValueRepositoryFactory()
3332
) : AuthCredentialStore {
3433

3534
companion object {

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

+9-4
Original file line numberDiff line numberDiff line change
@@ -17,12 +17,12 @@ package com.amplifyframework.auth.cognito.data
1717

1818
import android.content.Context
1919
import com.amplifyframework.auth.AuthProvider
20+
import com.amplifyframework.auth.cognito.AuthConfiguration
2021
import com.amplifyframework.auth.cognito.helpers.SessionHelper
2122
import com.amplifyframework.auth.cognito.helpers.identityProviderName
2223
import com.amplifyframework.core.store.KeyValueRepository
2324
import com.amplifyframework.statemachine.codegen.data.AWSCredentials
2425
import com.amplifyframework.statemachine.codegen.data.AmplifyCredential
25-
import com.amplifyframework.statemachine.codegen.data.AuthConfiguration
2626
import com.amplifyframework.statemachine.codegen.data.AuthCredentialStore
2727
import com.amplifyframework.statemachine.codegen.data.CognitoUserPoolTokens
2828
import com.amplifyframework.statemachine.codegen.data.DeviceMetadata
@@ -184,7 +184,9 @@ internal class AWSCognitoLegacyCredentialStore(
184184

185185
return if (accessKey == null && secretKey == null && sessionToken == null) {
186186
null
187-
} else AWSCredentials(accessKey, secretKey, sessionToken, expiration)
187+
} else {
188+
AWSCredentials(accessKey, secretKey, sessionToken, expiration)
189+
}
188190
}
189191

190192
private fun retrieveIdentityId() = idAndCredentialsKeyValue.get(namespace(ID_KEY))
@@ -224,8 +226,11 @@ internal class AWSCognitoLegacyCredentialStore(
224226
val deviceGroupKey = deviceKeyValue.get(DEVICE_GROUP_KEY)
225227
val deviceSecretKey = deviceKeyValue.get(DEVICE_SECRET_KEY)
226228

227-
return if (deviceKey.isNullOrEmpty() && deviceGroupKey.isNullOrEmpty()) DeviceMetadata.Empty
228-
else DeviceMetadata.Metadata(deviceKey ?: "", deviceGroupKey ?: "", deviceSecretKey)
229+
return if (deviceKey.isNullOrEmpty() && deviceGroupKey.isNullOrEmpty()) {
230+
DeviceMetadata.Empty
231+
} else {
232+
DeviceMetadata.Metadata(deviceKey ?: "", deviceGroupKey ?: "", deviceSecretKey)
233+
}
229234
}
230235

231236
private fun retrieveCognitoUserPoolTokens(keys: Map<String, String>): CognitoUserPoolTokens? {

aws-auth-cognito/src/main/java/com/amplifyframework/statemachine/codegen/data/AuthConfiguration.kt

-68
This file was deleted.

0 commit comments

Comments
 (0)