Skip to content

Commit c0b6095

Browse files
committed
refactor : Updated the MRRT key storing logic
1 parent e111c9d commit c0b6095

File tree

3 files changed

+62
-18
lines changed

3 files changed

+62
-18
lines changed

auth0/src/main/java/com/auth0/android/authentication/storage/BaseCredentialsManager.kt

Lines changed: 28 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3,16 +3,12 @@ package com.auth0.android.authentication.storage
33
import androidx.annotation.VisibleForTesting
44
import com.auth0.android.authentication.AuthenticationAPIClient
55
import com.auth0.android.callback.Callback
6-
import com.auth0.android.request.internal.GsonProvider
7-
import com.auth0.android.request.internal.Jwt
86
import com.auth0.android.result.APICredentials
97
import com.auth0.android.result.Credentials
108
import com.auth0.android.result.SSOCredentials
119
import com.auth0.android.result.UserProfile
1210
import com.auth0.android.util.Clock
1311
import java.util.*
14-
import kotlin.collections.component1
15-
import kotlin.collections.component2
1612

1713
/**
1814
* Base class meant to abstract common logic across Credentials Manager implementations.
@@ -36,7 +32,12 @@ public abstract class BaseCredentialsManager internal constructor(
3632

3733
@Throws(CredentialsManagerException::class)
3834
public abstract fun saveCredentials(credentials: Credentials)
39-
public abstract fun saveApiCredentials(apiCredentials: APICredentials, audience: String)
35+
public abstract fun saveApiCredentials(
36+
apiCredentials: APICredentials,
37+
audience: String,
38+
scope: String?
39+
)
40+
4041
public abstract fun getCredentials(callback: Callback<Credentials, CredentialsManagerException>)
4142
public abstract fun getSsoCredentials(
4243
parameters: Map<String, String>,
@@ -158,13 +159,22 @@ public abstract class BaseCredentialsManager internal constructor(
158159
*
159160
* @param storedScope the stored scope, separated by space characters.
160161
* @param requiredScope the required scope, separated by space characters.
162+
* @param ignoreOpenid whether to ignore the openid scope from the storedScope or not while comparing.
161163
* @return whether the scope are different or not
162164
*/
163-
protected fun hasScopeChanged(storedScope: String?, requiredScope: String?): Boolean {
165+
protected fun hasScopeChanged(
166+
storedScope: String?,
167+
requiredScope: String?,
168+
ignoreOpenid: Boolean = false
169+
): Boolean {
164170
if (requiredScope == null) {
165171
return false
166172
}
167-
val stored = storedScope.orEmpty().split(" ").toTypedArray()
173+
val storedScopeList = storedScope.orEmpty().split(" ").toMutableList()
174+
175+
if (ignoreOpenid) storedScopeList.remove("openid")
176+
177+
val stored = storedScopeList.toTypedArray()
168178
Arrays.sort(stored)
169179
val required = requiredScope.split(" ").toTypedArray()
170180
Arrays.sort(required)
@@ -196,4 +206,15 @@ public abstract class BaseCredentialsManager internal constructor(
196206
protected fun hasExpired(expiresAt: Long): Boolean {
197207
return expiresAt <= currentTimeInMillis
198208
}
209+
210+
/**
211+
* Returns the key for storing the APICredentials in storage. Uses a combination of audience and scope.
212+
*
213+
* @param audience the audience of the credentials.
214+
* @param scope optional scope for the credentials.
215+
*/
216+
protected fun getAPICredentialsKey(audience: String, scope: String?): String {
217+
// Use audience if scope is null else use a combination of audience and scope
218+
return if (scope == null) audience else "$audience::$scope"
219+
}
199220
}

auth0/src/main/java/com/auth0/android/authentication/storage/CredentialsManager.kt

Lines changed: 20 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -81,10 +81,16 @@ public class CredentialsManager @VisibleForTesting(otherwise = VisibleForTesting
8181
* Stores the given [APICredentials] in the storage for the given audience.
8282
* @param apiCredentials the API Credentials to be stored
8383
* @param audience the audience for which the credentials are stored
84+
* @param scope the scope for which the credentials are stored
8485
*/
85-
override fun saveApiCredentials(apiCredentials: APICredentials, audience: String) {
86+
override fun saveApiCredentials(
87+
apiCredentials: APICredentials,
88+
audience: String,
89+
scope: String?
90+
) {
91+
val key = getAPICredentialsKey(audience, scope)
8692
gson.toJson(apiCredentials).let {
87-
storage.store(audience, it)
93+
storage.store(key, it)
8894
}
8995
}
9096

@@ -590,14 +596,23 @@ public class CredentialsManager @VisibleForTesting(otherwise = VisibleForTesting
590596
headers: Map<String, String>,
591597
callback: Callback<APICredentials, CredentialsManagerException>
592598
) {
599+
593600
serialExecutor.execute {
594601
//Check if existing api credentials are present and valid
595-
val apiCredentialsJson = storage.retrieveString(audience)
602+
val key = getAPICredentialsKey(audience, scope)
603+
val apiCredentialsJson = storage.retrieveString(key)
596604
apiCredentialsJson?.let {
597605
val apiCredentials = gson.fromJson(it, APICredentials::class.java)
598606
val willTokenExpire = willExpire(apiCredentials.expiresAt.time, minTtl.toLong())
599-
val scopeChanged = hasScopeChanged(apiCredentials.scope, scope)
607+
608+
val scopeChanged = hasScopeChanged(
609+
apiCredentials.scope,
610+
scope,
611+
ignoreOpenid = scope?.contains("openid") == false
612+
)
613+
600614
val hasExpired = hasExpired(apiCredentials.expiresAt.time)
615+
601616
if (!hasExpired && !willTokenExpire && !scopeChanged) {
602617
callback.onSuccess(apiCredentials)
603618
return@execute
@@ -641,7 +656,7 @@ public class CredentialsManager @VisibleForTesting(otherwise = VisibleForTesting
641656
val newApiCredentials = newCredentials.toAPICredentials()
642657
storage.store(KEY_REFRESH_TOKEN, updatedRefreshToken)
643658
storage.store(KEY_ID_TOKEN, newCredentials.idToken)
644-
saveApiCredentials(newApiCredentials, audience)
659+
saveApiCredentials(newApiCredentials, audience, scope)
645660
callback.onSuccess(newApiCredentials)
646661
} catch (error: AuthenticationException) {
647662
val exception = when {

auth0/src/main/java/com/auth0/android/authentication/storage/SecureCredentialsManager.kt

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -208,13 +208,19 @@ public class SecureCredentialsManager @VisibleForTesting(otherwise = VisibleForT
208208
* Stores the given [APICredentials] in the storage for the given audience.
209209
* @param apiCredentials the API Credentials to be stored
210210
* @param audience the audience for which the credentials are stored
211+
* @param scope the scope for which the credentials are stored
211212
*/
212-
override fun saveApiCredentials(apiCredentials: APICredentials, audience: String) {
213+
override fun saveApiCredentials(
214+
apiCredentials: APICredentials,
215+
audience: String,
216+
scope: String?
217+
) {
218+
val key = getAPICredentialsKey(audience, scope)
213219
val json = gson.toJson(apiCredentials)
214220
try {
215221
val encrypted = crypto.encrypt(json.toByteArray())
216222
val encryptedEncoded = Base64.encodeToString(encrypted, Base64.DEFAULT)
217-
storage.store(audience, encryptedEncoded)
223+
storage.store(key, encryptedEncoded)
218224
} catch (e: IncompatibleDeviceException) {
219225
throw CredentialsManagerException(
220226
CredentialsManagerException.Code.INCOMPATIBLE_DEVICE,
@@ -973,7 +979,7 @@ public class SecureCredentialsManager @VisibleForTesting(otherwise = VisibleForT
973979
callback: Callback<APICredentials, CredentialsManagerException>
974980
) {
975981
serialExecutor.execute {
976-
val encryptedEncodedJson = storage.retrieveString(audience)
982+
val encryptedEncodedJson = storage.retrieveString(getAPICredentialsKey(audience, scope))
977983
//Check if existing api credentials are present and valid
978984
encryptedEncodedJson?.let { encryptedEncoded ->
979985
val encrypted = Base64.decode(encryptedEncoded, Base64.DEFAULT)
@@ -1003,7 +1009,10 @@ public class SecureCredentialsManager @VisibleForTesting(otherwise = VisibleForT
10031009

10041010
val expiresAt = apiCredentials.expiresAt.time
10051011
val willAccessTokenExpire = willExpire(expiresAt, minTtl.toLong())
1006-
val scopeChanged = hasScopeChanged(apiCredentials.scope, scope)
1012+
val scopeChanged = hasScopeChanged(
1013+
apiCredentials.scope, scope,
1014+
ignoreOpenid = scope?.contains("openid") == false
1015+
)
10071016
val hasExpired = hasExpired(apiCredentials.expiresAt.time)
10081017
if (!hasExpired && !willAccessTokenExpire && !scopeChanged) {
10091018
callback.onSuccess(apiCredentials)
@@ -1058,7 +1067,7 @@ public class SecureCredentialsManager @VisibleForTesting(otherwise = VisibleForT
10581067
idToken = newCredentials.idToken
10591068
)
10601069
)
1061-
saveApiCredentials(newApiCredentials, audience)
1070+
saveApiCredentials(newApiCredentials, audience, scope)
10621071
callback.onSuccess(newApiCredentials)
10631072

10641073
} catch (error: AuthenticationException) {
@@ -1203,7 +1212,6 @@ public class SecureCredentialsManager @VisibleForTesting(otherwise = VisibleForT
12031212
internal fun isBiometricSessionValid(): Boolean {
12041213
val lastAuth = lastBiometricAuthTime.get()
12051214
if (lastAuth == NO_SESSION) return false // No session exists
1206-
12071215
val policy = localAuthenticationOptions?.policy ?: BiometricPolicy.Always
12081216
return when (policy) {
12091217
is BiometricPolicy.Session,

0 commit comments

Comments
 (0)