@@ -2298,7 +2298,7 @@ public class AuthenticationAPIClientTest {
22982298 public fun shouldCustomTokenExchange () {
22992299 mockAPI.willReturnSuccessfulLogin()
23002300 val callback = MockAuthenticationCallback <Credentials >()
2301- client.customTokenExchange(" subject-token-type" , " subject-token" )
2301+ client.customTokenExchange(" subject-token-type" , " subject-token" , " org_12345 " )
23022302 .start(callback)
23032303 ShadowLooper .idleMainLooper()
23042304 val request = mockAPI.takeRequest()
@@ -2316,6 +2316,7 @@ public class AuthenticationAPIClientTest {
23162316 )
23172317 assertThat(body, Matchers .hasEntry(" subject_token" , " subject-token" ))
23182318 assertThat(body, Matchers .hasEntry(" subject_token_type" , " subject-token-type" ))
2319+ assertThat(body, Matchers .hasEntry(" organization" , " org_12345" ))
23192320 assertThat(body, Matchers .hasEntry(" scope" , " openid profile email" ))
23202321 assertThat(
23212322 callback, AuthenticationCallbackMatcher .hasPayloadOfType(
@@ -2328,7 +2329,7 @@ public class AuthenticationAPIClientTest {
23282329 public fun shouldCustomTokenExchangeSync () {
23292330 mockAPI.willReturnSuccessfulLogin()
23302331 val credentials = client
2331- .customTokenExchange(" subject-token-type" , " subject-token" )
2332+ .customTokenExchange(" subject-token-type" , " subject-token" , " org_abc " )
23322333 .execute()
23332334 val request = mockAPI.takeRequest()
23342335 assertThat(
@@ -2345,6 +2346,7 @@ public class AuthenticationAPIClientTest {
23452346 )
23462347 assertThat(body, Matchers .hasEntry(" subject_token" , " subject-token" ))
23472348 assertThat(body, Matchers .hasEntry(" subject_token_type" , " subject-token-type" ))
2349+ assertThat(body, Matchers .hasEntry(" organization" , " org_abc" ))
23482350 assertThat(body, Matchers .hasEntry(" scope" , " openid profile email" ))
23492351 assertThat(credentials, Matchers .`is `(Matchers .notNullValue()))
23502352 }
@@ -2371,10 +2373,97 @@ public class AuthenticationAPIClientTest {
23712373 )
23722374 assertThat(body, Matchers .hasEntry(" subject_token" , " subject-token" ))
23732375 assertThat(body, Matchers .hasEntry(" subject_token_type" , " subject-token-type" ))
2376+ assertThat(body, Matchers .not (Matchers .hasKey(" organization" )))
23742377 assertThat(body, Matchers .hasEntry(" scope" , " openid profile email" ))
23752378 assertThat(credentials, Matchers .`is `(Matchers .notNullValue()))
23762379 }
23772380
2381+ @Test
2382+ public fun shouldFailCustomTokenExchangeWithReservedNamespace () {
2383+ val callback = MockAuthenticationCallback <Credentials >()
2384+ client.customTokenExchange(" https://auth0.com" , " subject-token" )
2385+ .start(callback)
2386+ ShadowLooper .idleMainLooper()
2387+
2388+ assertThat(
2389+ callback.error.message,
2390+ Matchers .containsString(" Invalid URI" )
2391+ )
2392+ assertThat(callback.error.cause, Matchers .instanceOf(IllegalArgumentException ::class .java))
2393+ assertThat(
2394+ callback.error.cause?.message,
2395+ Matchers .containsString(" reserved namespace" )
2396+ )
2397+ }
2398+
2399+ @Test
2400+ public fun shouldFailCustomTokenExchangeSyncWithReservedNamespace () {
2401+ val exception = assertThrows(AuthenticationException ::class .java) {
2402+ client.customTokenExchange(" urn:okta" , " subject-token" )
2403+ .execute()
2404+ }
2405+
2406+ assertThat(exception.message, Matchers .containsString(" Invalid URI" ))
2407+ assertThat(exception.cause, Matchers .instanceOf(IllegalArgumentException ::class .java))
2408+ assertThat(
2409+ exception.cause?.message,
2410+ Matchers .containsString(" reserved namespace" )
2411+ )
2412+ }
2413+
2414+ @Test
2415+ @ExperimentalCoroutinesApi
2416+ public fun shouldFailCustomTokenExchangeAwaitWithReservedNamespace () {
2417+ val exception = assertThrows(AuthenticationException ::class .java) {
2418+ runTest {
2419+ client.customTokenExchange(" urn:auth0" , " subject-token" )
2420+ .await()
2421+ }
2422+ }
2423+
2424+ assertThat(exception.message, Matchers .containsString(" Invalid URI" ))
2425+ assertThat(exception.cause, Matchers .instanceOf(IllegalArgumentException ::class .java))
2426+ assertThat(
2427+ exception.cause?.message,
2428+ Matchers .containsString(" reserved namespace" )
2429+ )
2430+ }
2431+
2432+ @Test
2433+ public fun shouldFailCustomTokenExchangeWithInvalidHttpUri () {
2434+ val callback = MockAuthenticationCallback <Credentials >()
2435+ client.customTokenExchange(" http://invalid uri with spaces" , " subject-token" )
2436+ .start(callback)
2437+ ShadowLooper .idleMainLooper()
2438+
2439+ assertThat(callback, AuthenticationCallbackMatcher .hasError(Credentials ::class .java))
2440+ assertThat(
2441+ callback.error.message,
2442+ Matchers .containsString(" Invalid URI" )
2443+ )
2444+ assertThat(
2445+ callback.error.cause?.message,
2446+ Matchers .containsString(" not a valid URI" )
2447+ )
2448+ }
2449+
2450+ @Test
2451+ public fun shouldFailCustomTokenExchangeWithMalformedHttpsUri () {
2452+ val callback = MockAuthenticationCallback <Credentials >()
2453+ client.customTokenExchange(" https://[invalid:uri:format" , " subject-token" )
2454+ .start(callback)
2455+ ShadowLooper .idleMainLooper()
2456+
2457+ assertThat(
2458+ callback.error.message,
2459+ Matchers .containsString(" Invalid URI" )
2460+ )
2461+ assertThat(
2462+ callback.error.cause?.message,
2463+ Matchers .containsString(" not a valid URI" )
2464+ )
2465+ }
2466+
23782467 @Test
23792468 public fun shouldSsoExchange () {
23802469 mockAPI.willReturnSuccessfulLogin()
@@ -2871,7 +2960,10 @@ public class AuthenticationAPIClientTest {
28712960 assertThat(request.path, Matchers .equalTo(" /oauth/token" ))
28722961
28732962 val body = bodyFromRequest<String >(request)
2874- assertThat(body, Matchers .hasEntry(" grant_type" , ParameterBuilder .GRANT_TYPE_AUTHORIZATION_CODE ))
2963+ assertThat(
2964+ body,
2965+ Matchers .hasEntry(" grant_type" , ParameterBuilder .GRANT_TYPE_AUTHORIZATION_CODE )
2966+ )
28752967 assertThat(body, Matchers .hasEntry(" code" , " auth-code" ))
28762968
28772969 // Verify that key pair generation was attempted
@@ -2935,7 +3027,10 @@ public class AuthenticationAPIClientTest {
29353027 assertThat(request.path, Matchers .equalTo(" /oauth/token" ))
29363028
29373029 val body = bodyFromRequest<String >(request)
2938- assertThat(body, Matchers .hasEntry(" grant_type" , ParameterBuilder .GRANT_TYPE_TOKEN_EXCHANGE ))
3030+ assertThat(
3031+ body,
3032+ Matchers .hasEntry(" grant_type" , ParameterBuilder .GRANT_TYPE_TOKEN_EXCHANGE )
3033+ )
29393034 assertThat(body, Matchers .hasEntry(" subject_token_type" , " subject-token-type" ))
29403035
29413036 // Verify that key pair generation was attempted
@@ -3114,9 +3209,12 @@ public class AuthenticationAPIClientTest {
31143209 client.useDPoP(mockContext).login(SUPPORT_AUTH0_COM , PASSWORD , MY_CONNECTION )
31153210 .execute()
31163211 }
3117- Assert .assertEquals(" Key pair is not found in the keystore. Please generate a key pair first." , exception.message)
3212+ Assert .assertEquals(
3213+ " Key pair is not found in the keystore. Please generate a key pair first." ,
3214+ exception.message
3215+ )
31183216 assertThat(exception.cause, Matchers .notNullValue())
3119- assertThat(exception.cause, Matchers .instanceOf(DPoPException ::class .java ))
3217+ assertThat(exception.cause, Matchers .instanceOf(DPoPException ::class .java))
31203218 }
31213219
31223220 private fun <T > bodyFromRequest (request : RecordedRequest ): Map <String , T > {
0 commit comments