Skip to content

Commit 6513d7d

Browse files
committed
refactor : Updated the MRRT key storing logic
1 parent ddb9db0 commit 6513d7d

File tree

3 files changed

+69
-32
lines changed

3 files changed

+69
-32
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: 22 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,28 +1,24 @@
11
package com.auth0.android.authentication.storage
22

33
import android.text.TextUtils
4-
import android.util.Base64
54
import android.util.Log
65
import androidx.annotation.VisibleForTesting
76
import com.auth0.android.authentication.AuthenticationAPIClient
87
import com.auth0.android.authentication.AuthenticationException
9-
import com.auth0.android.authentication.storage.SecureCredentialsManager.Companion.KEY_CREDENTIALS
108
import com.auth0.android.callback.Callback
119
import com.auth0.android.request.internal.GsonProvider
1210
import com.auth0.android.request.internal.Jwt
1311
import com.auth0.android.result.APICredentials
1412
import com.auth0.android.result.Credentials
15-
import com.auth0.android.result.OptionalCredentials
1613
import com.auth0.android.result.SSOCredentials
1714
import com.auth0.android.result.UserProfile
1815
import com.auth0.android.result.toAPICredentials
1916
import com.google.gson.Gson
2017
import kotlinx.coroutines.suspendCancellableCoroutine
21-
import java.util.*
18+
import java.util.Date
19+
import java.util.Locale
2220
import java.util.concurrent.Executor
2321
import java.util.concurrent.Executors
24-
import kotlin.collections.component1
25-
import kotlin.collections.component2
2622
import kotlin.coroutines.resume
2723
import kotlin.coroutines.resumeWithException
2824

@@ -85,10 +81,16 @@ public class CredentialsManager @VisibleForTesting(otherwise = VisibleForTesting
8581
* Stores the given [APICredentials] in the storage for the given audience.
8682
* @param apiCredentials the API Credentials to be stored
8783
* @param audience the audience for which the credentials are stored
84+
* @param scope the scope for which the credentials are stored
8885
*/
89-
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)
9092
gson.toJson(apiCredentials).let {
91-
storage.store(audience, it)
93+
storage.store(key, it)
9294
}
9395
}
9496

@@ -594,14 +596,23 @@ public class CredentialsManager @VisibleForTesting(otherwise = VisibleForTesting
594596
headers: Map<String, String>,
595597
callback: Callback<APICredentials, CredentialsManagerException>
596598
) {
599+
597600
serialExecutor.execute {
598601
//Check if existing api credentials are present and valid
599-
val apiCredentialsJson = storage.retrieveString(audience)
602+
val key = getAPICredentialsKey(audience, scope)
603+
val apiCredentialsJson = storage.retrieveString(key)
600604
apiCredentialsJson?.let {
601605
val apiCredentials = gson.fromJson(it, APICredentials::class.java)
602606
val willTokenExpire = willExpire(apiCredentials.expiresAt.time, minTtl.toLong())
603-
val scopeChanged = hasScopeChanged(apiCredentials.scope, scope)
607+
608+
val scopeChanged = hasScopeChanged(
609+
apiCredentials.scope,
610+
scope,
611+
ignoreOpenid = scope?.contains("openid") == false
612+
)
613+
604614
val hasExpired = hasExpired(apiCredentials.expiresAt.time)
615+
605616
if (!hasExpired && !willTokenExpire && !scopeChanged) {
606617
callback.onSuccess(apiCredentials)
607618
return@execute
@@ -645,7 +656,7 @@ public class CredentialsManager @VisibleForTesting(otherwise = VisibleForTesting
645656
val newApiCredentials = newCredentials.toAPICredentials()
646657
storage.store(KEY_REFRESH_TOKEN, updatedRefreshToken)
647658
storage.store(KEY_ID_TOKEN, newCredentials.idToken)
648-
saveApiCredentials(newApiCredentials, audience)
659+
saveApiCredentials(newApiCredentials, audience, scope)
649660
callback.onSuccess(newApiCredentials)
650661
} catch (error: AuthenticationException) {
651662
val exception = when {

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

Lines changed: 19 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -11,24 +11,19 @@ import com.auth0.android.authentication.AuthenticationAPIClient
1111
import com.auth0.android.authentication.AuthenticationException
1212
import com.auth0.android.callback.Callback
1313
import com.auth0.android.request.internal.GsonProvider
14-
import com.auth0.android.request.internal.Jwt
1514
import com.auth0.android.result.APICredentials
1615
import com.auth0.android.result.Credentials
1716
import com.auth0.android.result.OptionalCredentials
1817
import com.auth0.android.result.SSOCredentials
1918
import com.auth0.android.result.UserProfile
2019
import com.auth0.android.result.toAPICredentials
2120
import com.google.gson.Gson
22-
import kotlinx.coroutines.CoroutineScope
23-
import kotlinx.coroutines.GlobalScope
24-
import kotlinx.coroutines.launch
2521
import kotlinx.coroutines.suspendCancellableCoroutine
2622
import java.lang.ref.WeakReference
27-
import java.util.*
23+
import java.util.Date
24+
import java.util.Locale
2825
import java.util.concurrent.Executor
2926
import java.util.concurrent.atomic.AtomicLong
30-
import kotlin.collections.component1
31-
import kotlin.collections.component2
3227
import kotlin.coroutines.resume
3328
import kotlin.coroutines.resumeWithException
3429

@@ -143,13 +138,19 @@ public class SecureCredentialsManager @VisibleForTesting(otherwise = VisibleForT
143138
* Stores the given [APICredentials] in the storage for the given audience.
144139
* @param apiCredentials the API Credentials to be stored
145140
* @param audience the audience for which the credentials are stored
141+
* @param scope the scope for which the credentials are stored
146142
*/
147-
override fun saveApiCredentials(apiCredentials: APICredentials, audience: String) {
143+
override fun saveApiCredentials(
144+
apiCredentials: APICredentials,
145+
audience: String,
146+
scope: String?
147+
) {
148+
val key = getAPICredentialsKey(audience, scope)
148149
val json = gson.toJson(apiCredentials)
149150
try {
150151
val encrypted = crypto.encrypt(json.toByteArray())
151152
val encryptedEncoded = Base64.encodeToString(encrypted, Base64.DEFAULT)
152-
storage.store(audience, encryptedEncoded)
153+
storage.store(key, encryptedEncoded)
153154
} catch (e: IncompatibleDeviceException) {
154155
throw CredentialsManagerException(
155156
CredentialsManagerException.Code.INCOMPATIBLE_DEVICE,
@@ -270,7 +271,7 @@ public class SecureCredentialsManager @VisibleForTesting(otherwise = VisibleForT
270271
if (credentials == null) {
271272
return null
272273
}
273-
return credentials.user
274+
return credentials.user
274275
}
275276

276277
/**
@@ -908,7 +909,7 @@ public class SecureCredentialsManager @VisibleForTesting(otherwise = VisibleForT
908909
callback: Callback<APICredentials, CredentialsManagerException>
909910
) {
910911
serialExecutor.execute {
911-
val encryptedEncodedJson = storage.retrieveString(audience)
912+
val encryptedEncodedJson = storage.retrieveString(getAPICredentialsKey(audience, scope))
912913
//Check if existing api credentials are present and valid
913914
encryptedEncodedJson?.let { encryptedEncoded ->
914915
val encrypted = Base64.decode(encryptedEncoded, Base64.DEFAULT)
@@ -938,7 +939,10 @@ public class SecureCredentialsManager @VisibleForTesting(otherwise = VisibleForT
938939

939940
val expiresAt = apiCredentials.expiresAt.time
940941
val willAccessTokenExpire = willExpire(expiresAt, minTtl.toLong())
941-
val scopeChanged = hasScopeChanged(apiCredentials.scope, scope)
942+
val scopeChanged = hasScopeChanged(
943+
apiCredentials.scope, scope,
944+
ignoreOpenid = scope?.contains("openid") == false
945+
)
942946
val hasExpired = hasExpired(apiCredentials.expiresAt.time)
943947
if (!hasExpired && !willAccessTokenExpire && !scopeChanged) {
944948
callback.onSuccess(apiCredentials)
@@ -993,7 +997,7 @@ public class SecureCredentialsManager @VisibleForTesting(otherwise = VisibleForT
993997
idToken = newCredentials.idToken
994998
)
995999
)
996-
saveApiCredentials(newApiCredentials, audience)
1000+
saveApiCredentials(newApiCredentials, audience, scope)
9971001
callback.onSuccess(newApiCredentials)
9981002

9991003
} catch (error: AuthenticationException) {
@@ -1138,7 +1142,7 @@ public class SecureCredentialsManager @VisibleForTesting(otherwise = VisibleForT
11381142
internal fun isBiometricSessionValid(): Boolean {
11391143
val lastAuth = lastBiometricAuthTime.get()
11401144
if (lastAuth == NO_SESSION) return false // No session exists
1141-
1145+
11421146
return when (val policy = biometricPolicy) {
11431147
is BiometricPolicy.Session,
11441148
is BiometricPolicy.AppLifecycle -> {
@@ -1149,6 +1153,7 @@ public class SecureCredentialsManager @VisibleForTesting(otherwise = VisibleForT
11491153
} * 1000L
11501154
System.currentTimeMillis() - lastAuth < timeoutMillis
11511155
}
1156+
11521157
is BiometricPolicy.Always -> false
11531158
}
11541159
}

0 commit comments

Comments
 (0)