Skip to content

Commit d0aa7c3

Browse files
committed
Addressed review comments
1 parent cee8fb1 commit d0aa7c3

4 files changed

Lines changed: 65 additions & 3 deletions

File tree

auth0/src/main/java/com/auth0/android/provider/OAuthManager.kt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -394,7 +394,7 @@ internal fun OAuthManager.Companion.fromState(
394394
): OAuthManager {
395395
// Enable DPoP on the restored PKCE's AuthenticationAPIClient so that
396396
// the token exchange request includes the DPoP proof after process restore.
397-
if (state.dPoPEnabled && state.pkce != null) {
397+
if (state.dPoPEnabled && state.pkce != null) {
398398
state.pkce.apiClient.useDPoP(context)
399399
}
400400
return OAuthManager(
@@ -403,7 +403,7 @@ internal fun OAuthManager.Companion.fromState(
403403
parameters = state.parameters,
404404
callback = callback,
405405
customAuthorizeUrl = state.customAuthorizeUrl,
406-
dPoP = if (state.dPoPEnabled ) DPoP(context) else null
406+
dPoP = if (state.dPoPEnabled) DPoP(context) else null
407407
).apply {
408408
setHeaders(
409409
state.headers

auth0/src/main/java/com/auth0/android/provider/OAuthManagerState.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ internal data class OAuthManagerState(
3636
val idTokenVerificationLeeway: Int?,
3737
val idTokenVerificationIssuer: String?,
3838
val customAuthorizeUrl: String? = null,
39-
val dPoPEnabled: Boolean
39+
val dPoPEnabled: Boolean = false
4040
)
4141

4242
fun serializeToJson(

auth0/src/test/java/com/auth0/android/provider/OAuthManagerStateTest.kt

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,16 @@
11
package com.auth0.android.provider
22

3+
import android.content.Context
34
import android.graphics.Color
45
import com.auth0.android.Auth0
6+
import com.auth0.android.authentication.AuthenticationAPIClient
7+
import com.auth0.android.authentication.AuthenticationException
8+
import com.auth0.android.callback.Callback
9+
import com.auth0.android.result.Credentials
510
import com.nhaarman.mockitokotlin2.mock
11+
import com.nhaarman.mockitokotlin2.whenever
12+
import org.hamcrest.MatcherAssert.assertThat
13+
import org.hamcrest.core.Is.`is`
614
import org.junit.Assert
715
import org.junit.Test
816
import org.junit.runner.RunWith
@@ -128,4 +136,54 @@ internal class OAuthManagerStateTest {
128136

129137
Assert.assertFalse(deserializedState.dPoPEnabled)
130138
}
139+
140+
@Test
141+
fun `fromState should re-enable DPoP on the restored PKCE's API client when dPoPEnabled is true`() {
142+
val context = mock<Context>()
143+
whenever(context.applicationContext).thenReturn(context)
144+
val auth0 = Auth0.getInstance("clientId", "domain")
145+
val apiClient = AuthenticationAPIClient(auth0)
146+
val state = OAuthManagerState(
147+
auth0 = auth0,
148+
parameters = emptyMap(),
149+
headers = emptyMap(),
150+
requestCode = 0,
151+
ctOptions = CustomTabsOptions.newBuilder().build(),
152+
pkce = PKCE(apiClient, "codeVerifier", "redirectUri", "codeChallenge", emptyMap()),
153+
idTokenVerificationLeeway = null,
154+
idTokenVerificationIssuer = null,
155+
dPoPEnabled = true
156+
)
157+
val callback = mock<Callback<Credentials, AuthenticationException>>()
158+
159+
OAuthManager.fromState(state, callback, context)
160+
161+
// This is the actual regression guard: the token exchange after process death only
162+
// includes the DPoP proof because fromState re-enables DPoP on the restored API client.
163+
assertThat(apiClient.isDPoPEnabled, `is`(true))
164+
}
165+
166+
@Test
167+
fun `fromState should not enable DPoP on the restored PKCE's API client when dPoPEnabled is false`() {
168+
val context = mock<Context>()
169+
whenever(context.applicationContext).thenReturn(context)
170+
val auth0 = Auth0.getInstance("clientId", "domain")
171+
val apiClient = AuthenticationAPIClient(auth0)
172+
val state = OAuthManagerState(
173+
auth0 = auth0,
174+
parameters = emptyMap(),
175+
headers = emptyMap(),
176+
requestCode = 0,
177+
ctOptions = CustomTabsOptions.newBuilder().build(),
178+
pkce = PKCE(apiClient, "codeVerifier", "redirectUri", "codeChallenge", emptyMap()),
179+
idTokenVerificationLeeway = null,
180+
idTokenVerificationIssuer = null,
181+
dPoPEnabled = false
182+
)
183+
val callback = mock<Callback<Credentials, AuthenticationException>>()
184+
185+
OAuthManager.fromState(state, callback, context)
186+
187+
assertThat(apiClient.isDPoPEnabled, `is`(false))
188+
}
131189
}

auth0/src/test/java/com/auth0/android/provider/WebAuthProviderTest.kt

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2977,6 +2977,10 @@ public class WebAuthProviderTest {
29772977
WebAuthProvider.onRestoreInstanceState(bundle, activity)
29782978

29792979
val restoredManager = WebAuthProvider.managerInstance as OAuthManager
2980+
// This asserts the save/restore wiring reconstructs a DPoP-enabled manager. The actual
2981+
// regression guard — that DPoP is re-enabled on the restored PKCE's API client so the
2982+
// token exchange carries the proof — lives in OAuthManagerStateTest.fromState tests,
2983+
// since OAuthManager.pkce is private and not reachable here without reflection.
29802984
assertThat(restoredManager.dPoP, `is`(notNullValue()))
29812985
}
29822986

0 commit comments

Comments
 (0)