Skip to content

Commit 22de15c

Browse files
committed
made the store method of sso internal and added support to pass headers
1 parent 4f7b045 commit 22de15c

File tree

4 files changed

+148
-84
lines changed

4 files changed

+148
-84
lines changed

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

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -30,9 +30,16 @@ public abstract class BaseCredentialsManager internal constructor(
3030

3131
@Throws(CredentialsManagerException::class)
3232
public abstract fun saveCredentials(credentials: Credentials)
33-
public abstract fun saveSsoCredentials(ssoCredentials: SSOCredentials)
3433
public abstract fun getCredentials(callback: Callback<Credentials, CredentialsManagerException>)
35-
public abstract fun getSsoCredentials(callback: Callback<SSOCredentials, CredentialsManagerException>)
34+
public abstract fun getSsoCredentials(
35+
headers: Map<String, String> = emptyMap(),
36+
callback: Callback<SSOCredentials, CredentialsManagerException>
37+
)
38+
39+
public abstract fun getSsoCredentials(
40+
callback: Callback<SSOCredentials, CredentialsManagerException>
41+
)
42+
3643
public abstract fun getCredentials(
3744
scope: String?,
3845
minTtl: Int,
@@ -65,7 +72,13 @@ public abstract class BaseCredentialsManager internal constructor(
6572

6673
@JvmSynthetic
6774
@Throws(CredentialsManagerException::class)
68-
public abstract suspend fun awaitSsoCredentials(): SSOCredentials
75+
public abstract suspend fun awaitSsoCredentials(headers: Map<String, String>)
76+
: SSOCredentials
77+
78+
@JvmSynthetic
79+
@Throws(CredentialsManagerException::class)
80+
public abstract suspend fun awaitSsoCredentials()
81+
: SSOCredentials
6982

7083
@JvmSynthetic
7184
@Throws(CredentialsManagerException::class)

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

Lines changed: 56 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -55,48 +55,41 @@ public class CredentialsManager @VisibleForTesting(otherwise = VisibleForTesting
5555
storage.store(LEGACY_KEY_CACHE_EXPIRES_AT, credentials.expiresAt.time)
5656
}
5757

58-
5958
/**
60-
* Stores the given [SSOCredentials] refresh token in the storage.
61-
* This method must be called if the SSOCredentials are obtained by directly invoking [AuthenticationAPIClient.fetchWebSsoToken] api and
62-
* [rotating refresh token](https://auth0.com/docs/secure/tokens/refresh-tokens/refresh-token-rotation) are enabled for
63-
* the client. Method will silently return ,if the passed credentials has no refresh token.
64-
* This is still an experimental feature, test it thoroughly in the targeted devices and OS variants and let us know your feedback.
65-
*
66-
* @param ssoCredentials the credentials to save in the storage.
59+
* Fetches a new [SSOCredentials] . It will fail with [CredentialsManagerException]
60+
* if the existing refresh_token is null or no longer valid. This method will handle saving the refresh_token,
61+
* if a new one is issued.
62+
* This is still an experimental feature, test it thoroughly and let us know your feedback.
6763
*/
6864
@ExperimentalAuth0Api
69-
override fun saveSsoCredentials(ssoCredentials: SSOCredentials) {
70-
if (ssoCredentials.refreshToken.isNullOrEmpty())
71-
return // No refresh token to save
72-
serialExecutor.execute {
73-
val existingRefreshToken = storage.retrieveString(KEY_REFRESH_TOKEN)
74-
// Checking if the existing one needs to be replaced with the new one
75-
if (ssoCredentials.refreshToken == existingRefreshToken)
76-
return@execute
77-
storage.store(KEY_REFRESH_TOKEN, ssoCredentials.refreshToken)
78-
}
65+
override fun getSsoCredentials(callback: Callback<SSOCredentials, CredentialsManagerException>) {
66+
getSsoCredentials(emptyMap(), callback)
7967
}
8068

8169
/**
8270
* Fetches a new [SSOCredentials] . It will fail with [CredentialsManagerException]
8371
* if the existing refresh_token is null or no longer valid. This method will handle saving the refresh_token,
8472
* if a new one is issued.
85-
* This is still an experimental feature, test it thoroughly in the targeted devices and OS variants and let us know your feedback.
73+
* This is still an experimental feature, test it thoroughly and let us know your feedback.
8674
*/
8775
@ExperimentalAuth0Api
88-
override fun getSsoCredentials(callback: Callback<SSOCredentials, CredentialsManagerException>) {
76+
override fun getSsoCredentials(
77+
headers: Map<String, String>,
78+
callback: Callback<SSOCredentials, CredentialsManagerException>
79+
) {
8980
serialExecutor.execute {
9081
val refreshToken = storage.retrieveString(KEY_REFRESH_TOKEN)
9182
if (refreshToken.isNullOrEmpty()) {
9283
callback.onFailure(CredentialsManagerException.NO_REFRESH_TOKEN)
9384
return@execute
9485
}
9586

87+
val request = authenticationClient.fetchWebSsoToken(refreshToken)
9688
try {
97-
val sessionCredentials =
98-
authenticationClient.fetchWebSsoToken(refreshToken)
99-
.execute()
89+
for (header in headers) {
90+
request.addHeader(header.key, header.value)
91+
}
92+
val sessionCredentials = request.execute()
10093
saveSsoCredentials(sessionCredentials)
10194
callback.onSuccess(sessionCredentials)
10295
} catch (error: AuthenticationException) {
@@ -121,22 +114,36 @@ public class CredentialsManager @VisibleForTesting(otherwise = VisibleForTesting
121114
* Fetches a new [SSOCredentials] . It will fail with [CredentialsManagerException]
122115
* if the existing refresh_token is null or no longer valid. This method will handle saving the refresh_token,
123116
* if a new one is issued.
124-
* This is still an experimental feature, test it thoroughly in the targeted devices and OS variants and let us know your feedback.
117+
* This is still an experimental feature, test it thoroughly and OS variants and let us know your feedback.
125118
*/
126119
@JvmSynthetic
127120
@Throws(CredentialsManagerException::class)
128121
@ExperimentalAuth0Api
129122
override suspend fun awaitSsoCredentials(): SSOCredentials {
123+
return awaitSsoCredentials(emptyMap())
124+
}
125+
126+
/**
127+
* Fetches a new [SSOCredentials] . It will fail with [CredentialsManagerException]
128+
* if the existing refresh_token is null or no longer valid. This method will handle saving the refresh_token,
129+
* if a new one is issued.
130+
* This is still an experimental feature, test it thoroughly and OS variants and let us know your feedback.
131+
*/
132+
@JvmSynthetic
133+
@Throws(CredentialsManagerException::class)
134+
@ExperimentalAuth0Api
135+
override suspend fun awaitSsoCredentials(headers: Map<String, String>): SSOCredentials {
130136
return suspendCancellableCoroutine { continuation ->
131-
getSsoCredentials(object : Callback<SSOCredentials, CredentialsManagerException> {
132-
override fun onSuccess(result: SSOCredentials) {
133-
continuation.resume(result)
134-
}
137+
getSsoCredentials(headers,
138+
object : Callback<SSOCredentials, CredentialsManagerException> {
139+
override fun onSuccess(result: SSOCredentials) {
140+
continuation.resume(result)
141+
}
135142

136-
override fun onFailure(error: CredentialsManagerException) {
137-
continuation.resumeWithException(error)
138-
}
139-
})
143+
override fun onFailure(error: CredentialsManagerException) {
144+
continuation.resumeWithException(error)
145+
}
146+
})
140147
}
141148
}
142149

@@ -465,6 +472,23 @@ public class CredentialsManager @VisibleForTesting(otherwise = VisibleForTesting
465472
storage.remove(LEGACY_KEY_CACHE_EXPIRES_AT)
466473
}
467474

475+
/**
476+
* Helper method to store the given [SSOCredentials] refresh token in the storage.
477+
* Method will silently return ,if the passed credentials has no refresh token.
478+
*
479+
* @param ssoCredentials the credentials to save in the storage.
480+
*/
481+
@VisibleForTesting(otherwise = VisibleForTesting.PRIVATE)
482+
internal fun saveSsoCredentials(ssoCredentials: SSOCredentials) {
483+
if (ssoCredentials.refreshToken.isNullOrEmpty())
484+
return // No refresh token to save
485+
val existingRefreshToken = storage.retrieveString(KEY_REFRESH_TOKEN)
486+
// Checking if the existing one needs to be replaced with the new one
487+
if (ssoCredentials.refreshToken == existingRefreshToken)
488+
return // Same refresh token, no need to save
489+
storage.store(KEY_REFRESH_TOKEN, ssoCredentials.refreshToken)
490+
}
491+
468492
@VisibleForTesting(otherwise = VisibleForTesting.PRIVATE)
469493
internal fun recreateCredentials(
470494
idToken: String,

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

Lines changed: 67 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -130,58 +130,47 @@ public class SecureCredentialsManager @VisibleForTesting(otherwise = VisibleForT
130130
}
131131

132132
/**
133-
* Stores the given [SSOCredentials] refresh token in the storage.
134-
* This method must be called if the SSOCredentials are obtained by directly invoking [AuthenticationAPIClient.fetchWebSsoToken] api and
135-
* [rotating refresh token](https://auth0.com/docs/secure/tokens/refresh-tokens/refresh-token-rotation) are enabled for
136-
* the client. Method will silently return ,if the passed credentials has no refresh token.
137-
* This is still an experimental feature, test it thoroughly in the targeted devices and OS variants and let us know your feedback.
138-
*
139-
* @param ssoCredentials the credentials to save in the storage.
133+
* Fetches a new [SSOCredentials] . It will fail with [CredentialsManagerException]
134+
* if the existing refresh_token is null or no longer valid. This method will handle saving the refresh_token,
135+
* if a new one is issued.
136+
* This is still an experimental feature, test it thoroughly and let us know your feedback.
140137
*/
141138
@ExperimentalAuth0Api
142-
override fun saveSsoCredentials(ssoCredentials: SSOCredentials) {
143-
if (ssoCredentials.refreshToken.isNullOrEmpty()) return // No refresh token to save
144-
serialExecutor.execute {
145-
lateinit var existingCredentials: Credentials
146-
try {
147-
existingCredentials = getExistingCredentials()
148-
} catch (exception: CredentialsManagerException) {
149-
Log.e(TAG,"Error while fetching existing credentials", exception)
150-
return@execute
151-
}
152-
// Checking if the existing one needs to be replaced with the new one
153-
if (existingCredentials.refreshToken == ssoCredentials.refreshToken)
154-
return@execute
155-
val newCredentials =
156-
existingCredentials.copy(refreshToken = ssoCredentials.refreshToken)
157-
saveCredentials(newCredentials)
158-
}
139+
override fun getSsoCredentials(callback: Callback<SSOCredentials, CredentialsManagerException>) {
140+
getSsoCredentials(emptyMap(), callback)
159141
}
160142

161143
/**
162144
* Fetches a new [SSOCredentials] . It will fail with [CredentialsManagerException]
163145
* if the existing refresh_token is null or no longer valid. This method will handle saving the refresh_token,
164146
* if a new one is issued.
165-
* This is still an experimental feature, test it thoroughly in the targeted devices and OS variants and let us know your feedback.
147+
* This is still an experimental feature, test it thoroughly and let us know your feedback.
166148
*/
167149
@ExperimentalAuth0Api
168-
override fun getSsoCredentials(callback: Callback<SSOCredentials, CredentialsManagerException>) {
150+
override fun getSsoCredentials(
151+
headers: Map<String, String>,
152+
callback: Callback<SSOCredentials, CredentialsManagerException>
153+
) {
169154
serialExecutor.execute {
170-
lateinit var existingCredentials:Credentials
171-
try{
155+
lateinit var existingCredentials: Credentials
156+
try {
172157
existingCredentials = getExistingCredentials()
173-
}catch (exception:CredentialsManagerException){
158+
} catch (exception: CredentialsManagerException) {
174159
callback.onFailure(exception)
175160
return@execute
176161
}
177162
if (existingCredentials.refreshToken.isNullOrEmpty()) {
178163
callback.onFailure(CredentialsManagerException.NO_REFRESH_TOKEN)
179164
return@execute
180165
}
166+
167+
val request = authenticationClient.fetchWebSsoToken(existingCredentials.refreshToken!!)
181168
try {
169+
for (header in headers) {
170+
request.addHeader(header.key, header.value)
171+
}
182172
val sessionCredentials =
183-
authenticationClient.fetchWebSsoToken(existingCredentials.refreshToken!!)
184-
.execute()
173+
request.execute()
185174
saveSsoCredentials(sessionCredentials)
186175
callback.onSuccess(sessionCredentials)
187176
} catch (error: AuthenticationException) {
@@ -211,22 +200,36 @@ public class SecureCredentialsManager @VisibleForTesting(otherwise = VisibleForT
211200
* Fetches a new [SSOCredentials] . It will fail with [CredentialsManagerException]
212201
* if the existing refresh_token is null or no longer valid. This method will handle saving the refresh_token,
213202
* if a new one is issued.
214-
* This is still an experimental feature, test it thoroughly in the targeted devices and OS variants and let us know your feedback.
203+
* This is still an experimental feature, test it thoroughly and let us know your feedback.
215204
*/
216205
@JvmSynthetic
217206
@Throws(CredentialsManagerException::class)
218207
@ExperimentalAuth0Api
219208
override suspend fun awaitSsoCredentials(): SSOCredentials {
209+
return awaitSsoCredentials(emptyMap())
210+
}
211+
212+
/**
213+
* Fetches a new [SSOCredentials] . It will fail with [CredentialsManagerException]
214+
* if the existing refresh_token is null or no longer valid. This method will handle saving the refresh_token,
215+
* if a new one is issued.
216+
* This is still an experimental feature, test it thoroughly and let us know your feedback.
217+
*/
218+
@JvmSynthetic
219+
@Throws(CredentialsManagerException::class)
220+
@ExperimentalAuth0Api
221+
override suspend fun awaitSsoCredentials(headers: Map<String, String>): SSOCredentials {
220222
return suspendCancellableCoroutine { continuation ->
221-
getSsoCredentials(object : Callback<SSOCredentials, CredentialsManagerException> {
222-
override fun onSuccess(result: SSOCredentials) {
223-
continuation.resume(result)
224-
}
223+
getSsoCredentials(headers,
224+
object : Callback<SSOCredentials, CredentialsManagerException> {
225+
override fun onSuccess(result: SSOCredentials) {
226+
continuation.resume(result)
227+
}
225228

226-
override fun onFailure(error: CredentialsManagerException) {
227-
continuation.resumeWithException(error)
228-
}
229-
})
229+
override fun onFailure(error: CredentialsManagerException) {
230+
continuation.resumeWithException(error)
231+
}
232+
})
230233
}
231234
}
232235

@@ -763,6 +766,30 @@ public class SecureCredentialsManager @VisibleForTesting(otherwise = VisibleForT
763766
fragmentActivity!!.clear()
764767
}
765768

769+
/**
770+
* Helper method to stores the given [SSOCredentials] refresh token in the storage.
771+
* Method will silently return ,if the passed credentials has no refresh token.
772+
*
773+
* @param ssoCredentials the credentials to save in the storage.
774+
*/
775+
@VisibleForTesting(otherwise = VisibleForTesting.PRIVATE)
776+
internal fun saveSsoCredentials(ssoCredentials: SSOCredentials) {
777+
if (ssoCredentials.refreshToken.isNullOrEmpty()) return // No refresh token to save
778+
lateinit var existingCredentials: Credentials
779+
try {
780+
existingCredentials = getExistingCredentials()
781+
} catch (exception: CredentialsManagerException) {
782+
Log.e(TAG, "Error while fetching existing credentials", exception)
783+
return
784+
}
785+
// Checking if the existing one needs to be replaced with the new one
786+
if (existingCredentials.refreshToken == ssoCredentials.refreshToken)
787+
return
788+
val newCredentials =
789+
existingCredentials.copy(refreshToken = ssoCredentials.refreshToken)
790+
saveCredentials(newCredentials)
791+
}
792+
766793
internal companion object {
767794
private val TAG = SecureCredentialsManager::class.java.simpleName
768795

auth0/src/test/java/com/auth0/android/authentication/storage/SecureCredentialsManagerTest.kt

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1859,32 +1859,32 @@ public class SecureCredentialsManagerTest {
18591859
)
18601860
secureCredsManager.getCredentials(object :
18611861
Callback<Credentials, CredentialsManagerException> {
1862-
override fun onFailure(exception: CredentialsManagerException) {
1863-
throw exception
1862+
override fun onFailure(error: CredentialsManagerException) {
1863+
throw error
18641864
}
18651865

1866-
override fun onSuccess(credentials: Credentials) {
1866+
override fun onSuccess(result: Credentials) {
18671867
// Verify all instances retrieved the same credentials
18681868
MatcherAssert.assertThat(
18691869
renewedCredentials.accessToken,
1870-
Is.`is`(credentials.accessToken)
1870+
Is.`is`(result.accessToken)
18711871
)
18721872
MatcherAssert.assertThat(
18731873
renewedCredentials.idToken,
1874-
Is.`is`(credentials.idToken)
1874+
Is.`is`(result.idToken)
18751875
)
18761876
MatcherAssert.assertThat(
18771877
renewedCredentials.refreshToken,
1878-
Is.`is`(credentials.refreshToken)
1878+
Is.`is`(result.refreshToken)
18791879
)
1880-
MatcherAssert.assertThat(renewedCredentials.type, Is.`is`(credentials.type))
1880+
MatcherAssert.assertThat(renewedCredentials.type, Is.`is`(result.type))
18811881
MatcherAssert.assertThat(
18821882
renewedCredentials.expiresAt,
1883-
Is.`is`(credentials.expiresAt)
1883+
Is.`is`(result.expiresAt)
18841884
)
18851885
MatcherAssert.assertThat(
18861886
renewedCredentials.scope,
1887-
Is.`is`(credentials.scope)
1887+
Is.`is`(result.scope)
18881888
)
18891889
latch.countDown()
18901890
}

0 commit comments

Comments
 (0)