From 8edfbf1446be483bfb9957213d02c496695d84be Mon Sep 17 00:00:00 2001 From: Sai Venkat Desu Date: Fri, 19 Jul 2024 12:23:41 +0530 Subject: [PATCH] BREAKING CHANGE: incorporated breaking changes planned for v3 --- .../storage/BaseCredentialsManager.kt | 156 +++++++++++++++++- .../storage/CredentialsManager.kt | 16 +- .../storage/SecureCredentialsManager.kt | 29 ++-- .../auth0/android/request/DefaultClient.kt | 10 +- .../java/com/auth0/android/request/Request.kt | 8 +- .../com/auth0/android/result/Credentials.kt | 19 +-- .../storage/CredentialsManagerTest.kt | 45 +++-- .../storage/SecureCredentialsManagerTest.kt | 126 +++++++++++--- .../android/request/DefaultClientTest.kt | 1 + .../internal/CredentialsDeserializerMock.kt | 2 +- .../request/internal/CredentialsGsonTest.kt | 4 +- .../auth0/android/result/CredentialsMock.kt | 23 +-- .../auth0/android/result/CredentialsTest.kt | 24 ++- .../com/auth0/android/util/SSLTestUtils.kt | 2 + 14 files changed, 348 insertions(+), 117 deletions(-) diff --git a/auth0/src/main/java/com/auth0/android/authentication/storage/BaseCredentialsManager.kt b/auth0/src/main/java/com/auth0/android/authentication/storage/BaseCredentialsManager.kt index 4da6f634..ad695934 100644 --- a/auth0/src/main/java/com/auth0/android/authentication/storage/BaseCredentialsManager.kt +++ b/auth0/src/main/java/com/auth0/android/authentication/storage/BaseCredentialsManager.kt @@ -7,9 +7,6 @@ import com.auth0.android.callback.Callback import com.auth0.android.result.Credentials import com.auth0.android.util.Clock import java.util.* -import java.util.concurrent.Executor -import java.util.concurrent.Executors -import kotlin.math.min /** * Base class meant to abstract common logic across Credentials Manager implementations. @@ -100,6 +97,65 @@ public abstract class DefaultCredentialsManager internal constructor( minTtl: Int, callback: Callback ) + + @JvmSynthetic + @Throws(CredentialsManagerException::class) + public abstract suspend fun awaitCredentials(): Credentials + + @JvmSynthetic + @Throws(CredentialsManagerException::class) + public abstract suspend fun awaitCredentials(scope: String?, minTtl: Int): Credentials + + @JvmSynthetic + @Throws(CredentialsManagerException::class) + public abstract suspend fun awaitCredentials( + scope: String?, + minTtl: Int, + parameters: Map + ): Credentials + + @JvmSynthetic + @Throws(CredentialsManagerException::class) + public abstract suspend fun awaitCredentials( + scope: String?, + minTtl: Int, + parameters: Map, + forceRefresh: Boolean + ): Credentials + + @JvmSynthetic + @Throws(CredentialsManagerException::class) + public abstract suspend fun awaitCredentials( + scope: String?, + minTtl: Int, + parameters: Map, + headers: Map, + forceRefresh: Boolean + ): Credentials + + public abstract fun getCredentials( + scope: String?, + minTtl: Int, + parameters: Map, + callback: Callback + ) + + public abstract fun getCredentials( + scope: String?, + minTtl: Int, + parameters: Map, + forceRefresh: Boolean, + callback: Callback + ) + + public abstract fun getCredentials( + scope: String?, + minTtl: Int, + parameters: Map, + headers: Map, + forceRefresh: Boolean, + callback: Callback + ) } public abstract class SecuredCredentialsManager internal constructor( @@ -109,6 +165,96 @@ public abstract class SecuredCredentialsManager internal constructor( ) : BaseCredentialsManager( authenticationClient, storage, jwtDecoder ) { - public abstract fun getCredentials(fragmentActivity: FragmentActivity, authenticationOptions: LocalAuthenticationOptions, callback: Callback) - public abstract fun getCredentials(fragmentActivity: FragmentActivity, authenticationOptions: LocalAuthenticationOptions, scope: String?, minTtl: Int, callback: Callback) + public abstract fun getCredentials( + fragmentActivity: FragmentActivity, + authenticationOptions: LocalAuthenticationOptions, + callback: Callback + ) + + public abstract fun getCredentials( + fragmentActivity: FragmentActivity, + authenticationOptions: LocalAuthenticationOptions, + scope: String?, + minTtl: Int, + callback: Callback + ) + + @JvmSynthetic + @Throws(CredentialsManagerException::class) + public abstract suspend fun awaitCredentials( + fragmentActivity: FragmentActivity, + authenticationOptions: LocalAuthenticationOptions + ): Credentials + + @JvmSynthetic + @Throws(CredentialsManagerException::class) + public abstract suspend fun awaitCredentials( + fragmentActivity: FragmentActivity, + authenticationOptions: LocalAuthenticationOptions, + scope: String?, + minTtl: Int + ): Credentials + + @JvmSynthetic + @Throws(CredentialsManagerException::class) + public abstract suspend fun awaitCredentials( + fragmentActivity: FragmentActivity, + authenticationOptions: LocalAuthenticationOptions, + scope: String?, + minTtl: Int, + parameters: Map + ): Credentials + + @JvmSynthetic + @Throws(CredentialsManagerException::class) + public abstract suspend fun awaitCredentials( + fragmentActivity: FragmentActivity, + authenticationOptions: LocalAuthenticationOptions, + scope: String?, + minTtl: Int, + parameters: Map, + forceRefresh: Boolean + ): Credentials + + @JvmSynthetic + @Throws(CredentialsManagerException::class) + public abstract suspend fun awaitCredentials( + fragmentActivity: FragmentActivity, + authenticationOptions: LocalAuthenticationOptions, + scope: String?, + minTtl: Int, + parameters: Map, + headers: Map, + forceRefresh: Boolean + ): Credentials + + public abstract fun getCredentials( + fragmentActivity: FragmentActivity, + authenticationOptions: LocalAuthenticationOptions, + scope: String?, + minTtl: Int, + parameters: Map, + callback: Callback + ) + + public abstract fun getCredentials( + fragmentActivity: FragmentActivity, + authenticationOptions: LocalAuthenticationOptions, + scope: String?, + minTtl: Int, + parameters: Map, + forceRefresh: Boolean, + callback: Callback + ) + + public abstract fun getCredentials( + fragmentActivity: FragmentActivity, + authenticationOptions: LocalAuthenticationOptions, + scope: String? = null, + minTtl: Int = 0, + parameters: Map = emptyMap(), + headers: Map = emptyMap(), + forceRefresh: Boolean = false, + callback: Callback + ) } \ No newline at end of file diff --git a/auth0/src/main/java/com/auth0/android/authentication/storage/CredentialsManager.kt b/auth0/src/main/java/com/auth0/android/authentication/storage/CredentialsManager.kt index 197c7bfb..77daf205 100644 --- a/auth0/src/main/java/com/auth0/android/authentication/storage/CredentialsManager.kt +++ b/auth0/src/main/java/com/auth0/android/authentication/storage/CredentialsManager.kt @@ -61,7 +61,7 @@ public class CredentialsManager @VisibleForTesting(otherwise = VisibleForTesting */ @JvmSynthetic @Throws(CredentialsManagerException::class) - public suspend fun awaitCredentials(): Credentials { + override suspend fun awaitCredentials(): Credentials { return awaitCredentials(null, 0) } @@ -76,7 +76,7 @@ public class CredentialsManager @VisibleForTesting(otherwise = VisibleForTesting */ @JvmSynthetic @Throws(CredentialsManagerException::class) - public suspend fun awaitCredentials(scope: String?, minTtl: Int): Credentials { + override suspend fun awaitCredentials(scope: String?, minTtl: Int): Credentials { return awaitCredentials(scope, minTtl, emptyMap()) } @@ -92,7 +92,7 @@ public class CredentialsManager @VisibleForTesting(otherwise = VisibleForTesting */ @JvmSynthetic @Throws(CredentialsManagerException::class) - public suspend fun awaitCredentials( + override suspend fun awaitCredentials( scope: String?, minTtl: Int, parameters: Map @@ -113,7 +113,7 @@ public class CredentialsManager @VisibleForTesting(otherwise = VisibleForTesting */ @JvmSynthetic @Throws(CredentialsManagerException::class) - public suspend fun awaitCredentials( + override suspend fun awaitCredentials( scope: String?, minTtl: Int, parameters: Map, @@ -136,7 +136,7 @@ public class CredentialsManager @VisibleForTesting(otherwise = VisibleForTesting */ @JvmSynthetic @Throws(CredentialsManagerException::class) - public suspend fun awaitCredentials( + override suspend fun awaitCredentials( scope: String?, minTtl: Int, parameters: Map, @@ -200,7 +200,7 @@ public class CredentialsManager @VisibleForTesting(otherwise = VisibleForTesting * @param parameters additional parameters to send in the request to refresh expired credentials * @param callback the callback that will receive a valid [Credentials] or the [CredentialsManagerException]. */ - public fun getCredentials( + override fun getCredentials( scope: String?, minTtl: Int, parameters: Map, @@ -220,7 +220,7 @@ public class CredentialsManager @VisibleForTesting(otherwise = VisibleForTesting * @param forceRefresh this will avoid returning the existing credentials and retrieves a new one even if valid credentials exist. * @param callback the callback that will receive a valid [Credentials] or the [CredentialsManagerException]. */ - public fun getCredentials( + override fun getCredentials( scope: String?, minTtl: Int, parameters: Map, @@ -242,7 +242,7 @@ public class CredentialsManager @VisibleForTesting(otherwise = VisibleForTesting * @param forceRefresh this will avoid returning the existing credentials and retrieves a new one even if valid credentials exist. * @param callback the callback that will receive a valid [Credentials] or the [CredentialsManagerException]. */ - public fun getCredentials( + override fun getCredentials( scope: String?, minTtl: Int, parameters: Map, diff --git a/auth0/src/main/java/com/auth0/android/authentication/storage/SecureCredentialsManager.kt b/auth0/src/main/java/com/auth0/android/authentication/storage/SecureCredentialsManager.kt index 43ca9c1a..b351e88e 100644 --- a/auth0/src/main/java/com/auth0/android/authentication/storage/SecureCredentialsManager.kt +++ b/auth0/src/main/java/com/auth0/android/authentication/storage/SecureCredentialsManager.kt @@ -1,9 +1,6 @@ package com.auth0.android.authentication.storage -import android.app.Activity import android.content.Context -import android.opengl.Visibility -import android.provider.Settings.Secure import android.text.TextUtils import android.util.Base64 import android.util.Log @@ -114,7 +111,7 @@ public class SecureCredentialsManager @VisibleForTesting(otherwise = VisibleForT */ @JvmSynthetic @Throws(CredentialsManagerException::class) - public suspend fun awaitCredentials( + override suspend fun awaitCredentials( fragmentActivity: FragmentActivity, authenticationOptions: LocalAuthenticationOptions ): Credentials { @@ -137,7 +134,7 @@ public class SecureCredentialsManager @VisibleForTesting(otherwise = VisibleForT */ @JvmSynthetic @Throws(CredentialsManagerException::class) - public suspend fun awaitCredentials( + override suspend fun awaitCredentials( fragmentActivity: FragmentActivity, authenticationOptions: LocalAuthenticationOptions, scope: String?, @@ -163,7 +160,7 @@ public class SecureCredentialsManager @VisibleForTesting(otherwise = VisibleForT */ @JvmSynthetic @Throws(CredentialsManagerException::class) - public suspend fun awaitCredentials( + override suspend fun awaitCredentials( fragmentActivity: FragmentActivity, authenticationOptions: LocalAuthenticationOptions, scope: String?, @@ -198,7 +195,7 @@ public class SecureCredentialsManager @VisibleForTesting(otherwise = VisibleForT */ @JvmSynthetic @Throws(CredentialsManagerException::class) - public suspend fun awaitCredentials( + override suspend fun awaitCredentials( fragmentActivity: FragmentActivity, authenticationOptions: LocalAuthenticationOptions, scope: String?, @@ -236,7 +233,7 @@ public class SecureCredentialsManager @VisibleForTesting(otherwise = VisibleForT */ @JvmSynthetic @Throws(CredentialsManagerException::class) - public suspend fun awaitCredentials( + override suspend fun awaitCredentials( fragmentActivity: FragmentActivity, authenticationOptions: LocalAuthenticationOptions, scope: String?, @@ -325,7 +322,7 @@ public class SecureCredentialsManager @VisibleForTesting(otherwise = VisibleForT * @param parameters additional parameters to send in the request to refresh expired credentials * @param callback the callback to receive the result in. */ - public fun getCredentials( + override fun getCredentials( fragmentActivity: FragmentActivity, authenticationOptions: LocalAuthenticationOptions, scope: String?, @@ -361,7 +358,7 @@ public class SecureCredentialsManager @VisibleForTesting(otherwise = VisibleForT * @param forceRefresh this will avoid returning the existing credentials and retrieves a new one even if valid credentials exist. * @param callback the callback to receive the result in. */ - public fun getCredentials( + override fun getCredentials( fragmentActivity: FragmentActivity, authenticationOptions: LocalAuthenticationOptions, scope: String?, @@ -399,14 +396,14 @@ public class SecureCredentialsManager @VisibleForTesting(otherwise = VisibleForT * @param forceRefresh this will avoid returning the existing credentials and retrieves a new one even if valid credentials exist. * @param callback the callback to receive the result in. */ - public fun getCredentials( + override fun getCredentials( fragmentActivity: FragmentActivity, authenticationOptions: LocalAuthenticationOptions, - scope: String? = null, - minTtl: Int = 0, - parameters: Map = emptyMap(), - headers: Map = emptyMap(), - forceRefresh: Boolean = false, + scope: String?, + minTtl: Int, + parameters: Map, + headers: Map, + forceRefresh: Boolean, callback: Callback ) { diff --git a/auth0/src/main/java/com/auth0/android/request/DefaultClient.kt b/auth0/src/main/java/com/auth0/android/request/DefaultClient.kt index c0c676b6..a00a57d8 100644 --- a/auth0/src/main/java/com/auth0/android/request/DefaultClient.kt +++ b/auth0/src/main/java/com/auth0/android/request/DefaultClient.kt @@ -24,6 +24,7 @@ public class DefaultClient @VisibleForTesting(otherwise = VisibleForTesting.PRIV readTimeout: Int, private val defaultHeaders: Map, enableLogging: Boolean, + private val gson: Gson, sslSocketFactory: SSLSocketFactory?, trustManager: X509TrustManager? ) : NetworkingClient { @@ -40,11 +41,8 @@ public class DefaultClient @VisibleForTesting(otherwise = VisibleForTesting.PRIV connectTimeout: Int = DEFAULT_TIMEOUT_SECONDS, readTimeout: Int = DEFAULT_TIMEOUT_SECONDS, defaultHeaders: Map = mapOf(), - enableLogging: Boolean = false - ) : this(connectTimeout, readTimeout, defaultHeaders, enableLogging, null, null) - - //TODO: receive this via internal constructor parameters - private val gson: Gson = GsonProvider.gson + enableLogging: Boolean = false, + ) : this(connectTimeout, readTimeout, defaultHeaders, enableLogging, GsonProvider.gson, null, null) @get:VisibleForTesting(otherwise = VisibleForTesting.PRIVATE) internal val okHttpClient: OkHttpClient @@ -71,6 +69,7 @@ public class DefaultClient @VisibleForTesting(otherwise = VisibleForTesting.PRIV .map { urlBuilder.addQueryParameter(it.key, it.value as String) } requestBuilder.method(options.method.toString(), null) } + else -> { // add parameters as body val body = gson.toJson(options.parameters).toRequestBody(APPLICATION_JSON_UTF8) @@ -90,7 +89,6 @@ public class DefaultClient @VisibleForTesting(otherwise = VisibleForTesting.PRIV val builder = OkHttpClient.Builder() // logging - //TODO: OFF by default! if (enableLogging) { val logger: Interceptor = HttpLoggingInterceptor() .setLevel(HttpLoggingInterceptor.Level.BODY) diff --git a/auth0/src/main/java/com/auth0/android/request/Request.kt b/auth0/src/main/java/com/auth0/android/request/Request.kt index 7bba4a29..e6825e9f 100755 --- a/auth0/src/main/java/com/auth0/android/request/Request.kt +++ b/auth0/src/main/java/com/auth0/android/request/Request.kt @@ -21,10 +21,6 @@ public interface Request { * Performs an async HTTP request against Auth0 API inside a Coroutine * This is a Coroutine that is exposed only for Kotlin. * - * Note: This method was added after the interface was released. - * It is defined as a default method for compatibility reasons. - * From version 3.0 on, the method will be abstract and all implementations of this interface - * will have to provide their own implementation. * * The default implementation throws an [UnsupportedOperationException]. * @@ -32,9 +28,7 @@ public interface Request { */ @JvmSynthetic @Throws(Auth0Exception::class) - public suspend fun await(): T { - throw UnsupportedOperationException("await") - } + public suspend fun await(): T /** * Executes the HTTP request against Auth0 API (blocking the current thread) diff --git a/auth0/src/main/java/com/auth0/android/result/Credentials.kt b/auth0/src/main/java/com/auth0/android/result/Credentials.kt index 84166563..42904212 100755 --- a/auth0/src/main/java/com/auth0/android/result/Credentials.kt +++ b/auth0/src/main/java/com/auth0/android/result/Credentials.kt @@ -1,6 +1,5 @@ package com.auth0.android.result -import androidx.annotation.VisibleForTesting import com.auth0.android.request.internal.GsonProvider import com.auth0.android.request.internal.Jwt import com.google.gson.annotations.SerializedName @@ -18,7 +17,7 @@ import java.util.* * * *scope*: The token's granted scope. * */ -public open class Credentials( +public data class Credentials( /** * Getter for the Identity Token with user information. * @@ -61,11 +60,6 @@ public open class Credentials( @field:SerializedName("scope") public val scope: String? ) { - //TODO this could be removed and the class be a data class instead - @get:VisibleForTesting(otherwise = VisibleForTesting.PRIVATE) - internal open val currentTimeInMillis: Long - get() = System.currentTimeMillis() - /** * Getter for the new multi-factor authentication recovery code. Only available if these credentials are the result of logging in using an MFA recovery code. * @@ -79,10 +73,11 @@ public open class Credentials( return "Credentials(idToken='xxxxx', accessToken='xxxxx', type='$type', refreshToken='xxxxx', expiresAt='$expiresAt', scope='$scope')" } - public val user: UserProfile get() { - val (_, payload) = Jwt.splitToken(idToken) - val gson = GsonProvider.gson - return gson.fromJson(Jwt.decodeBase64(payload), UserProfile::class.java) - } + public val user: UserProfile + get() { + val (_, payload) = Jwt.splitToken(idToken) + val gson = GsonProvider.gson + return gson.fromJson(Jwt.decodeBase64(payload), UserProfile::class.java) + } } \ No newline at end of file diff --git a/auth0/src/test/java/com/auth0/android/authentication/storage/CredentialsManagerTest.kt b/auth0/src/test/java/com/auth0/android/authentication/storage/CredentialsManagerTest.kt index eda4d1ad..98c4faff 100644 --- a/auth0/src/test/java/com/auth0/android/authentication/storage/CredentialsManagerTest.kt +++ b/auth0/src/test/java/com/auth0/android/authentication/storage/CredentialsManagerTest.kt @@ -73,7 +73,7 @@ public class CredentialsManagerTest { val refreshToken = invocation.getArgument(3, String::class.java) val expiresAt = invocation.getArgument(4, Date::class.java) val scope = invocation.getArgument(5, String::class.java) - CredentialsMock(idToken, accessToken, type, refreshToken, expiresAt, scope) + CredentialsMock.create(idToken, accessToken, type, refreshToken, expiresAt, scope) }.`when`(manager).recreateCredentials( ArgumentMatchers.anyString(), ArgumentMatchers.anyString(), @@ -87,7 +87,7 @@ public class CredentialsManagerTest { @Test public fun shouldSaveRefreshableCredentialsInStorage() { val expirationTime = CredentialsMock.ONE_HOUR_AHEAD_MS - val credentials: Credentials = CredentialsMock( + val credentials: Credentials = CredentialsMock.create( "idToken", "accessToken", "type", @@ -110,7 +110,7 @@ public class CredentialsManagerTest { @Test public fun shouldSaveRefreshableCredentialsUsingAccessTokenExpForCacheExpirationInStorage() { val accessTokenExpirationTime = CredentialsMock.ONE_HOUR_AHEAD_MS - val credentials: Credentials = CredentialsMock( + val credentials: Credentials = CredentialsMock.create( "", "accessToken", "type", @@ -134,7 +134,7 @@ public class CredentialsManagerTest { public fun shouldSaveRefreshableCredentialsIgnoringIdTokenExpForCacheExpirationInStorage() { val accessTokenExpirationTime = CredentialsMock.CURRENT_TIME_MS + 5000 * 1000 val idTokenExpirationTime = CredentialsMock.CURRENT_TIME_MS + 2000 * 1000 - val credentials: Credentials = CredentialsMock( + val credentials: Credentials = CredentialsMock.create( "idToken", "accessToken", "type", @@ -158,7 +158,14 @@ public class CredentialsManagerTest { public fun shouldSaveNonRefreshableCredentialsInStorage() { val expirationTime = CredentialsMock.ONE_HOUR_AHEAD_MS val credentials: Credentials = - CredentialsMock("idToken", "accessToken", "type", null, Date(expirationTime), "scope") + CredentialsMock.create( + "idToken", + "accessToken", + "type", + null, + Date(expirationTime), + "scope" + ) prepareJwtDecoderMock(Date(expirationTime)) manager.saveCredentials(credentials) verify(storage).store("com.auth0.id_token", "idToken") @@ -176,21 +183,21 @@ public class CredentialsManagerTest { exception.expect(CredentialsManagerException::class.java) exception.expectMessage("Credentials must have a valid access_token or id_token value.") val credentials: Credentials = - CredentialsMock("", "", "type", "refreshToken", Date(), null) + CredentialsMock.create("", "", "type", "refreshToken", Date(), null) manager.saveCredentials(credentials) } @Test public fun shouldNotThrowOnSetIfCredentialsHasAccessTokenAndExpiresAt() { val credentials: Credentials = - CredentialsMock("", "accessToken", "type", "refreshToken", Date(), null) + CredentialsMock.create("", "accessToken", "type", "refreshToken", Date(), null) manager.saveCredentials(credentials) } @Test public fun shouldNotThrowOnSetIfCredentialsHasIdTokenAndExpiresAt() { val credentials: Credentials = - CredentialsMock("idToken", "", "type", "refreshToken", Date(), null) + CredentialsMock.create("idToken", "", "type", "refreshToken", Date(), null) prepareJwtDecoderMock(Date()) manager.saveCredentials(credentials) } @@ -946,8 +953,8 @@ public class CredentialsManagerTest { throw IllegalArgumentException("Proper Executor Set") } manager.getCredentials(object : Callback { - override fun onSuccess(result: Credentials) { } - override fun onFailure(error: CredentialsManagerException) { } + override fun onSuccess(result: Credentials) {} + override fun onFailure(error: CredentialsManagerException) {} }) } @@ -1024,12 +1031,21 @@ public class CredentialsManagerTest { verify(callback).onSuccess(credentialsCaptor.capture()) val retrievedCredentials = credentialsCaptor.firstValue MatcherAssert.assertThat(retrievedCredentials, Is.`is`(Matchers.notNullValue())) - MatcherAssert.assertThat(retrievedCredentials.accessToken, Is.`is`(expectedCredentials.accessToken)) + MatcherAssert.assertThat( + retrievedCredentials.accessToken, + Is.`is`(expectedCredentials.accessToken) + ) MatcherAssert.assertThat(retrievedCredentials.idToken, Is.`is`(expectedCredentials.idToken)) - MatcherAssert.assertThat(retrievedCredentials.refreshToken, Is.`is`(expectedCredentials.refreshToken)) + MatcherAssert.assertThat( + retrievedCredentials.refreshToken, + Is.`is`(expectedCredentials.refreshToken) + ) MatcherAssert.assertThat(retrievedCredentials.type, Is.`is`(expectedCredentials.type)) MatcherAssert.assertThat(retrievedCredentials.expiresAt, Is.`is`(Matchers.notNullValue())) - MatcherAssert.assertThat(retrievedCredentials.expiresAt.time, Is.`is`(expectedCredentials.expiresAt.time)) + MatcherAssert.assertThat( + retrievedCredentials.expiresAt.time, + Is.`is`(expectedCredentials.expiresAt.time) + ) MatcherAssert.assertThat(retrievedCredentials.scope, Is.`is`(expectedCredentials.scope)) } @@ -1045,7 +1061,8 @@ public class CredentialsManagerTest { Mockito.`when`(storage.retrieveLong("com.auth0.cache_expires_at")) .thenReturn(expirationTime) Mockito.`when`(storage.retrieveString("com.auth0.scope")).thenReturn("scope") - manager.getCredentials("scope", + manager.getCredentials( + "scope", 0, emptyMap(), false, diff --git a/auth0/src/test/java/com/auth0/android/authentication/storage/SecureCredentialsManagerTest.kt b/auth0/src/test/java/com/auth0/android/authentication/storage/SecureCredentialsManagerTest.kt index 7764d365..015552ef 100644 --- a/auth0/src/test/java/com/auth0/android/authentication/storage/SecureCredentialsManagerTest.kt +++ b/auth0/src/test/java/com/auth0/android/authentication/storage/SecureCredentialsManagerTest.kt @@ -129,7 +129,7 @@ public class SecureCredentialsManagerTest { @Test public fun shouldSaveRefreshableCredentialsInStorage() { val sharedExpirationTime = CredentialsMock.ONE_HOUR_AHEAD_MS - val credentials: Credentials = CredentialsMock( + val credentials: Credentials = CredentialsMock.create( "idToken", "accessToken", "type", @@ -164,7 +164,7 @@ public class SecureCredentialsManagerTest { @Test public fun shouldSaveRefreshableCredentialsUsingAccessTokenExpForCacheExpirationInStorage() { val accessTokenExpirationTime = CredentialsMock.ONE_HOUR_AHEAD_MS - val credentials: Credentials = CredentialsMock( + val credentials: Credentials = CredentialsMock.create( "", "accessToken", "type", @@ -203,7 +203,7 @@ public class SecureCredentialsManagerTest { public fun shouldSaveRefreshableCredentialsIgnoringIdTokenExpForCacheExpirationInStorage() { val accessTokenExpirationTime = CredentialsMock.ONE_HOUR_AHEAD_MS val idTokenExpirationTime = CredentialsMock.CURRENT_TIME_MS + 2000 * 1000 - val credentials: Credentials = CredentialsMock( + val credentials: Credentials = CredentialsMock.create( "idToken", "accessToken", "type", @@ -242,7 +242,14 @@ public class SecureCredentialsManagerTest { public fun shouldSaveNonRefreshableCredentialsInStorage() { val expirationTime = CredentialsMock.ONE_HOUR_AHEAD_MS val credentials: Credentials = - CredentialsMock("idToken", "accessToken", "type", null, Date(expirationTime), "scope") + CredentialsMock.create( + "idToken", + "accessToken", + "type", + null, + Date(expirationTime), + "scope" + ) val json = gson.toJson(credentials) prepareJwtDecoderMock(Date(expirationTime)) Mockito.`when`(crypto.encrypt(json.toByteArray())).thenReturn(json.toByteArray()) @@ -270,7 +277,7 @@ public class SecureCredentialsManagerTest { @Test public fun shouldClearStoredCredentialsAndThrowOnSaveOnCryptoException() { val expirationTime = CredentialsMock.ONE_HOUR_AHEAD_MS - val credentials: Credentials = CredentialsMock( + val credentials: Credentials = CredentialsMock.create( "idToken", "accessToken", "type", @@ -302,7 +309,7 @@ public class SecureCredentialsManagerTest { @Test public fun shouldThrowOnSaveOnIncompatibleDeviceException() { val expirationTime = CredentialsMock.ONE_HOUR_AHEAD_MS - val credentials: Credentials = CredentialsMock( + val credentials: Credentials = CredentialsMock.create( "idToken", "accessToken", "type", @@ -332,14 +339,14 @@ public class SecureCredentialsManagerTest { exception.expect(CredentialsManagerException::class.java) exception.expectMessage("Credentials must have a valid access_token or id_token value.") val credentials: Credentials = - CredentialsMock("", "", "type", "refreshToken", Date(), "scope") + CredentialsMock.create("", "", "type", "refreshToken", Date(), "scope") manager.saveCredentials(credentials) } @Test public fun shouldNotThrowOnSaveIfCredentialsHaveAccessTokenAndExpiresIn() { val credentials: Credentials = - CredentialsMock("", "accessToken", "type", "refreshToken", Date(), "scope") + CredentialsMock.create("", "accessToken", "type", "refreshToken", Date(), "scope") Mockito.`when`(crypto.encrypt(any())) .thenReturn(byteArrayOf(12, 34, 56, 78)) manager.saveCredentials(credentials) @@ -348,7 +355,7 @@ public class SecureCredentialsManagerTest { @Test public fun shouldNotThrowOnSaveIfCredentialsHaveIdTokenAndExpiresIn() { val credentials: Credentials = - CredentialsMock("idToken", "", "type", "refreshToken", Date(), "scope") + CredentialsMock.create("idToken", "", "type", "refreshToken", Date(), "scope") prepareJwtDecoderMock(Date()) Mockito.`when`(crypto.encrypt(any())) .thenReturn(byteArrayOf(12, 34, 56, 78)) @@ -446,7 +453,14 @@ public class SecureCredentialsManagerTest { val expectedJson = gson.toJson(expectedCredentials) Mockito.`when`(crypto.encrypt(expectedJson.toByteArray())) .thenThrow(CryptoException("CryptoException is thrown")) - manager.getCredentials("different scope", 0, emptyMap(), emptyMap(), false, callback) // minTTL of 0 seconds (default) + manager.getCredentials( + "different scope", + 0, + emptyMap(), + emptyMap(), + false, + callback + ) // minTTL of 0 seconds (default) verify(request) .addParameter(eq("scope"), eq("different scope")) verify(callback).onFailure( @@ -494,7 +508,14 @@ public class SecureCredentialsManagerTest { val expectedJson = gson.toJson(expectedCredentials) Mockito.`when`(crypto.encrypt(expectedJson.toByteArray())) .thenThrow(IncompatibleDeviceException(Exception())) - manager.getCredentials("different scope", 0, emptyMap(), emptyMap(), false, callback) // minTTL of 0 seconds (default) + manager.getCredentials( + "different scope", + 0, + emptyMap(), + emptyMap(), + false, + callback + ) // minTTL of 0 seconds (default) verify(request) .addParameter(eq("scope"), eq("different scope")) verify(callback).onFailure( @@ -540,7 +561,14 @@ public class SecureCredentialsManagerTest { Credentials("", "", "newType", "refreshToken", newDate, "different scope") Mockito.`when`(request.execute()).thenReturn(expectedCredentials) - manager.getCredentials("different scope", 0, emptyMap(), emptyMap(), false, callback) // minTTL of 0 seconds (default) + manager.getCredentials( + "different scope", + 0, + emptyMap(), + emptyMap(), + false, + callback + ) // minTTL of 0 seconds (default) verify(request) .addParameter(eq("scope"), eq("different scope")) verify(callback).onFailure( @@ -622,7 +650,8 @@ public class SecureCredentialsManagerTest { verifyNoMoreInteractions(client) val expiresAt = Date(CredentialsMock.CURRENT_TIME_MS + ONE_HOUR_SECONDS * 1000) insertTestCredentials(true, true, true, expiresAt, "scope") - val retrievedCredentials = manager.awaitCredentials(fragmentActivity, getAuthenticationOptions()) + val retrievedCredentials = + manager.awaitCredentials(fragmentActivity, getAuthenticationOptions()) MatcherAssert.assertThat(retrievedCredentials, Is.`is`(Matchers.notNullValue())) MatcherAssert.assertThat(retrievedCredentials.accessToken, Is.`is`("accessToken")) MatcherAssert.assertThat(retrievedCredentials.idToken, Is.`is`("idToken")) @@ -683,7 +712,8 @@ public class SecureCredentialsManagerTest { emptyMap(), emptyMap(), false, - callback) + callback + ) verify(callback).onSuccess( credentialsCaptor.capture() ) @@ -716,7 +746,14 @@ public class SecureCredentialsManagerTest { val expectedJson = gson.toJson(expectedCredentials) Mockito.`when`(crypto.encrypt(expectedJson.toByteArray())) .thenReturn(expectedJson.toByteArray()) - manager.getCredentials(null, 60, emptyMap(), emptyMap(), false, callback) // minTTL of 1 minute + manager.getCredentials( + null, + 60, + emptyMap(), + emptyMap(), + false, + callback + ) // minTTL of 1 minute verify(request, never()) .addParameter(eq("scope"), anyString()) verify(callback).onSuccess( @@ -778,7 +815,14 @@ public class SecureCredentialsManagerTest { val expectedJson = gson.toJson(expectedCredentials) Mockito.`when`(crypto.encrypt(expectedJson.toByteArray())) .thenReturn(expectedJson.toByteArray()) - manager.getCredentials(null, 60, emptyMap(), emptyMap(), false, callback) // minTTL of 1 minute + manager.getCredentials( + null, + 60, + emptyMap(), + emptyMap(), + false, + callback + ) // minTTL of 1 minute verify(request, never()) .addParameter(eq("scope"), anyString()) verify(callback).onFailure( @@ -823,7 +867,14 @@ public class SecureCredentialsManagerTest { val expectedJson = gson.toJson(expectedCredentials) Mockito.`when`(crypto.encrypt(expectedJson.toByteArray())) .thenReturn(expectedJson.toByteArray()) - manager.getCredentials("different scope", 0, emptyMap(), emptyMap(), false, callback) // minTTL of 0 seconds (default) + manager.getCredentials( + "different scope", + 0, + emptyMap(), + emptyMap(), + false, + callback + ) // minTTL of 0 seconds (default) verify(request) .addParameter(eq("scope"), eq("different scope")) verify(callback).onSuccess( @@ -884,7 +935,14 @@ public class SecureCredentialsManagerTest { val expectedJson = gson.toJson(expectedCredentials) Mockito.`when`(crypto.encrypt(expectedJson.toByteArray())) .thenReturn(expectedJson.toByteArray()) - manager.getCredentials("different scope", 0, emptyMap(), emptyMap(), false, callback) // minTTL of 0 seconds (default) + manager.getCredentials( + "different scope", + 0, + emptyMap(), + emptyMap(), + false, + callback + ) // minTTL of 0 seconds (default) verify(request) .addParameter(eq("scope"), eq("different scope")) verify(callback).onSuccess( @@ -947,7 +1005,14 @@ public class SecureCredentialsManagerTest { Mockito.`when`(crypto.encrypt(expectedJson.toByteArray())) .thenReturn(expectedJson.toByteArray()) - manager.getCredentials("different scope", 0, emptyMap(), emptyMap(), false, callback) // minTTL of 0 seconds (default) + manager.getCredentials( + "different scope", + 0, + emptyMap(), + emptyMap(), + false, + callback + ) // minTTL of 0 seconds (default) verify(request) .addParameter(eq("scope"), eq("different scope")) verify(callback).onSuccess( @@ -1034,7 +1099,8 @@ public class SecureCredentialsManagerTest { emptyMap(), emptyMap(), false, - callback) + callback + ) // requestCallbackCaptor.firstValue.onSuccess(renewedCredentials)TODO poovam verify(callback).onSuccess( credentialsCaptor.capture() @@ -1100,7 +1166,8 @@ public class SecureCredentialsManagerTest { emptyMap(), emptyMap(), false, - callback) + callback + ) verify(request, never()) .addParameter(eq("scope"), anyString()) verify(callback).onSuccess( @@ -1160,7 +1227,8 @@ public class SecureCredentialsManagerTest { emptyMap(), emptyMap(), false, - callback) + callback + ) verify(callback).onFailure( exceptionCaptor.capture() ) @@ -1717,10 +1785,16 @@ public class SecureCredentialsManagerTest { .thenReturn(expirationTime) Mockito.`when`(storage.retrieveString("com.auth0.credentials")) .thenReturn("{\"access_token\":\"accessToken\"}") - manager.getCredentials(null, 0, emptyMap(), emptyMap(), false, object : Callback { - override fun onSuccess(result: Credentials) {} - override fun onFailure(error: CredentialsManagerException) {} - }) + manager.getCredentials( + null, + 0, + emptyMap(), + emptyMap(), + false, + object : Callback { + override fun onSuccess(result: Credentials) {} + override fun onFailure(error: CredentialsManagerException) {} + }) } @Test diff --git a/auth0/src/test/java/com/auth0/android/request/DefaultClientTest.kt b/auth0/src/test/java/com/auth0/android/request/DefaultClientTest.kt index 4f1e1902..a30ca88b 100644 --- a/auth0/src/test/java/com/auth0/android/request/DefaultClientTest.kt +++ b/auth0/src/test/java/com/auth0/android/request/DefaultClientTest.kt @@ -306,6 +306,7 @@ public class DefaultClientTest { readTimeout = 10, connectTimeout = 10, enableLogging = false, + gson = gson, sslSocketFactory = SSLTestUtils.clientCertificates.sslSocketFactory(), trustManager = SSLTestUtils.clientCertificates.trustManager ) diff --git a/auth0/src/test/java/com/auth0/android/request/internal/CredentialsDeserializerMock.kt b/auth0/src/test/java/com/auth0/android/request/internal/CredentialsDeserializerMock.kt index 52d74546..b2ade84c 100644 --- a/auth0/src/test/java/com/auth0/android/request/internal/CredentialsDeserializerMock.kt +++ b/auth0/src/test/java/com/auth0/android/request/internal/CredentialsDeserializerMock.kt @@ -15,7 +15,7 @@ internal class CredentialsDeserializerMock : CredentialsDeserializer() { recoveryCode: String? ): Credentials { val credentials = - CredentialsMock(idToken, accessToken, type, refreshToken, expiresAt, scope) + CredentialsMock.create(idToken, accessToken, type, refreshToken, expiresAt, scope) credentials.recoveryCode = recoveryCode return credentials } diff --git a/auth0/src/test/java/com/auth0/android/request/internal/CredentialsGsonTest.kt b/auth0/src/test/java/com/auth0/android/request/internal/CredentialsGsonTest.kt index 6813a2a5..d10df32a 100755 --- a/auth0/src/test/java/com/auth0/android/request/internal/CredentialsGsonTest.kt +++ b/auth0/src/test/java/com/auth0/android/request/internal/CredentialsGsonTest.kt @@ -120,7 +120,7 @@ public class CredentialsGsonTest : GsonBaseTest() { val expiresAt = Date(CredentialsMock.CURRENT_TIME_MS + 123456 * 1000) val expectedExpiresAt = formatDate(expiresAt) val expiresInCredentials: Credentials = - CredentialsMock("id", "access", "ty", "refresh", expiresAt, null) + CredentialsMock.create("id", "access", "ty", "refresh", expiresAt, null) val expiresInJson = gson.toJson(expiresInCredentials) MatcherAssert.assertThat(expiresInJson, CoreMatchers.containsString("\"id_token\":\"id\"")) MatcherAssert.assertThat( @@ -149,7 +149,7 @@ public class CredentialsGsonTest : GsonBaseTest() { CoreMatchers.not(CoreMatchers.containsString("\"scope\"")) ) val expiresAtCredentials: Credentials = - CredentialsMock("id", "access", "ty", "refresh", expiresAt, "openid") + CredentialsMock.create("id", "access", "ty", "refresh", expiresAt, "openid") val expiresAtJson = gson.toJson(expiresAtCredentials) MatcherAssert.assertThat(expiresAtJson, CoreMatchers.containsString("\"id_token\":\"id\"")) MatcherAssert.assertThat( diff --git a/auth0/src/test/java/com/auth0/android/result/CredentialsMock.kt b/auth0/src/test/java/com/auth0/android/result/CredentialsMock.kt index c60371c5..50dd8b41 100644 --- a/auth0/src/test/java/com/auth0/android/result/CredentialsMock.kt +++ b/auth0/src/test/java/com/auth0/android/result/CredentialsMock.kt @@ -2,17 +2,7 @@ package com.auth0.android.result import java.util.* -public class CredentialsMock( - idToken: String, - accessToken: String, - type: String, - refreshToken: String?, - expiresAt: Date, - scope: String? -) : Credentials(idToken, accessToken, type, refreshToken, expiresAt, scope) { - - override val currentTimeInMillis: Long - get() = CURRENT_TIME_MS +public class CredentialsMock { public companion object { @JvmField @@ -26,5 +16,16 @@ public class CredentialsMock( cal.timeZone = TimeZone.getTimeZone("UTC") return cal.timeInMillis } + + public fun create( + idToken: String, + accessToken: String, + type: String, + refreshToken: String?, + expiresAt: Date, + scope: String? + ): Credentials { + return Credentials(idToken, accessToken, type, refreshToken, expiresAt, scope) + } } } \ No newline at end of file diff --git a/auth0/src/test/java/com/auth0/android/result/CredentialsTest.kt b/auth0/src/test/java/com/auth0/android/result/CredentialsTest.kt index cd40d358..ac38dc36 100644 --- a/auth0/src/test/java/com/auth0/android/result/CredentialsTest.kt +++ b/auth0/src/test/java/com/auth0/android/result/CredentialsTest.kt @@ -6,10 +6,10 @@ import org.hamcrest.Matchers import org.junit.Test import org.junit.runner.RunWith import org.robolectric.RobolectricTestRunner -import java.text.SimpleDateFormat import java.util.* -private val idToken = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJodHRwOi8vbXktZG9tYWluLmF1dGgwLmNvbSIsInN1YiI6ImF1dGgwfDEyMzQ1NiIsImF1ZCI6Im15X2NsaWVudF9pZCIsImV4cCI6MTMxMTI4MTk3MCwiaWF0IjoxMzExMjgwOTcwLCJuYW1lIjoiSmFuZSBEb2UiLCJnaXZlbl9uYW1lIjoiSmFuZSIsImZhbWlseV9uYW1lIjoiRG9lIiwiZ2VuZGVyIjoiZmVtYWxlIiwiYmlydGhkYXRlIjoiMDAwMC0xMC0zMSIsImVtYWlsIjoiamFuZWRvZUBleGFtcGxlLmNvbSIsInBpY3R1cmUiOiJodHRwOi8vZXhhbXBsZS5jb20vamFuZWRvZS9tZS5qcGcifQ.FKw0UVWANEqibD9VTC9WLzstlyc_IRnyPSpUMDP3hKc" +private val idToken = + "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJodHRwOi8vbXktZG9tYWluLmF1dGgwLmNvbSIsInN1YiI6ImF1dGgwfDEyMzQ1NiIsImF1ZCI6Im15X2NsaWVudF9pZCIsImV4cCI6MTMxMTI4MTk3MCwiaWF0IjoxMzExMjgwOTcwLCJuYW1lIjoiSmFuZSBEb2UiLCJnaXZlbl9uYW1lIjoiSmFuZSIsImZhbWlseV9uYW1lIjoiRG9lIiwiZ2VuZGVyIjoiZmVtYWxlIiwiYmlydGhkYXRlIjoiMDAwMC0xMC0zMSIsImVtYWlsIjoiamFuZWRvZUBleGFtcGxlLmNvbSIsInBpY3R1cmUiOiJodHRwOi8vZXhhbXBsZS5jb20vamFuZWRvZS9tZS5qcGcifQ.FKw0UVWANEqibD9VTC9WLzstlyc_IRnyPSpUMDP3hKc" @RunWith(RobolectricTestRunner::class) public class CredentialsTest { @@ -17,7 +17,7 @@ public class CredentialsTest { public fun shouldCreate() { val date = Date() val credentials: Credentials = - CredentialsMock("idToken", "accessToken", "type", "refreshToken", date, "scope") + CredentialsMock.create("idToken", "accessToken", "type", "refreshToken", date, "scope") MatcherAssert.assertThat(credentials.idToken, Matchers.`is`("idToken")) MatcherAssert.assertThat(credentials.accessToken, Matchers.`is`("accessToken")) MatcherAssert.assertThat(credentials.type, Matchers.`is`("type")) @@ -38,7 +38,7 @@ public class CredentialsTest { public fun shouldGetRecoveryCode() { val date = Date() val credentials: Credentials = - CredentialsMock("idToken", "accessToken", "type", "refreshToken", date, "scope") + CredentialsMock.create("idToken", "accessToken", "type", "refreshToken", date, "scope") credentials.recoveryCode = "recoveryCode" MatcherAssert.assertThat(credentials.recoveryCode, Matchers.`is`("recoveryCode")) } @@ -47,12 +47,15 @@ public class CredentialsTest { public fun shouldGetUser() { val date = Date() val credentials: Credentials = - CredentialsMock(idToken, "accessToken", "type", "refreshToken", date, "scope") + CredentialsMock.create(idToken, "accessToken", "type", "refreshToken", date, "scope") MatcherAssert.assertThat(credentials.user.getId(), Matchers.`is`("auth0|123456")) MatcherAssert.assertThat(credentials.user.name, Matchers.`is`("Jane Doe")) MatcherAssert.assertThat(credentials.user.givenName, Matchers.`is`("Jane")) MatcherAssert.assertThat(credentials.user.familyName, Matchers.`is`("Doe")) - MatcherAssert.assertThat(credentials.user.pictureURL, Matchers.`is`("http://example.com/janedoe/me.jpg")) + MatcherAssert.assertThat( + credentials.user.pictureURL, + Matchers.`is`("http://example.com/janedoe/me.jpg") + ) MatcherAssert.assertThat(credentials.user.email, Matchers.`is`("janedoe@example.com")) } @@ -60,7 +63,7 @@ public class CredentialsTest { public fun shouldNotSerializeUser() { val date = Date() val credentials: Credentials = - CredentialsMock(idToken, "accessToken", "type", "refreshToken", date, "scope") + CredentialsMock.create(idToken, "accessToken", "type", "refreshToken", date, "scope") MatcherAssert.assertThat(credentials.user.getId(), Matchers.`is`("auth0|123456")) val json = gson.toJson(credentials, Credentials::class.java) MatcherAssert.assertThat(json, Matchers.not(Matchers.containsString("auth0|123456"))) @@ -72,7 +75,10 @@ public class CredentialsTest { public fun shouldNotPrintCredentials() { val date = Date() val credentials: Credentials = - CredentialsMock(idToken, "accessToken", "type", "refreshToken", date, "scope") - MatcherAssert.assertThat(credentials.toString(), Matchers.`is`("Credentials(idToken='xxxxx', accessToken='xxxxx', type='type', refreshToken='xxxxx', expiresAt='$date', scope='scope')")) + CredentialsMock.create(idToken, "accessToken", "type", "refreshToken", date, "scope") + MatcherAssert.assertThat( + credentials.toString(), + Matchers.`is`("Credentials(idToken='xxxxx', accessToken='xxxxx', type='type', refreshToken='xxxxx', expiresAt='$date', scope='scope')") + ) } } \ No newline at end of file diff --git a/auth0/src/test/java/com/auth0/android/util/SSLTestUtils.kt b/auth0/src/test/java/com/auth0/android/util/SSLTestUtils.kt index ac0128cf..542a8e4b 100644 --- a/auth0/src/test/java/com/auth0/android/util/SSLTestUtils.kt +++ b/auth0/src/test/java/com/auth0/android/util/SSLTestUtils.kt @@ -1,6 +1,7 @@ package com.auth0.android.util import com.auth0.android.request.DefaultClient +import com.auth0.android.request.internal.GsonProvider import okhttp3.mockwebserver.MockWebServer import okhttp3.tls.HandshakeCertificates import okhttp3.tls.HeldCertificate @@ -35,6 +36,7 @@ internal object SSLTestUtils { readTimeout = 10, connectTimeout = 10, enableLogging = false, + gson = GsonProvider.gson, sslSocketFactory = clientCertificates.sslSocketFactory(), trustManager = clientCertificates.trustManager )