From 7241aa0e4681c12ded40594a4fd2c14a13b64aa6 Mon Sep 17 00:00:00 2001 From: Walter Ching Date: Thu, 25 Jul 2019 16:03:28 +0200 Subject: [PATCH 1/8] Use of JvmField instead of JvmStatic --- .../heimdall2/grants/OAuth2AuthorizationCodeGrant.kt | 4 ++-- .../heimdall2/grants/OAuth2ClientCredentialsGrant.kt | 2 +- .../de/rheinfabrik/heimdall2/grants/OAuth2ImplicitGrant.kt | 2 +- .../heimdall2/grants/OAuth2RefreshAccessTokenGrant.kt | 2 +- .../grants/OAuth2ResourceOwnerPasswordCredentialsGrant.kt | 2 +- 5 files changed, 6 insertions(+), 6 deletions(-) diff --git a/library/src/main/java/de/rheinfabrik/heimdall2/grants/OAuth2AuthorizationCodeGrant.kt b/library/src/main/java/de/rheinfabrik/heimdall2/grants/OAuth2AuthorizationCodeGrant.kt index 61bb15f..4b0df5e 100644 --- a/library/src/main/java/de/rheinfabrik/heimdall2/grants/OAuth2AuthorizationCodeGrant.kt +++ b/library/src/main/java/de/rheinfabrik/heimdall2/grants/OAuth2AuthorizationCodeGrant.kt @@ -45,9 +45,9 @@ abstract class OAuth2AuthorizationCodeGrant( // Constants companion object { - @JvmStatic + @JvmField val RESPONSE_TYPE = "code" - @JvmStatic + @JvmField val GRANT_TYPE = "authorization_code" private const val UTF_8 = "UTF-8" } diff --git a/library/src/main/java/de/rheinfabrik/heimdall2/grants/OAuth2ClientCredentialsGrant.kt b/library/src/main/java/de/rheinfabrik/heimdall2/grants/OAuth2ClientCredentialsGrant.kt index 9eec57f..a6e8c25 100644 --- a/library/src/main/java/de/rheinfabrik/heimdall2/grants/OAuth2ClientCredentialsGrant.kt +++ b/library/src/main/java/de/rheinfabrik/heimdall2/grants/OAuth2ClientCredentialsGrant.kt @@ -16,7 +16,7 @@ abstract class OAuth2ClientCredentialsGrant( * REQUIRED * The OAuth2 "grant_type". */ - @JvmStatic + @JvmField val GRANT_TYPE = "client_credentials" } } diff --git a/library/src/main/java/de/rheinfabrik/heimdall2/grants/OAuth2ImplicitGrant.kt b/library/src/main/java/de/rheinfabrik/heimdall2/grants/OAuth2ImplicitGrant.kt index b318062..9c2d546 100644 --- a/library/src/main/java/de/rheinfabrik/heimdall2/grants/OAuth2ImplicitGrant.kt +++ b/library/src/main/java/de/rheinfabrik/heimdall2/grants/OAuth2ImplicitGrant.kt @@ -44,7 +44,7 @@ abstract class OAuth2ImplicitGrant( * The "response_type" which MUST be "token". */ companion object { - @JvmStatic + @JvmField val RESPONSE_TYPE = "token" } } diff --git a/library/src/main/java/de/rheinfabrik/heimdall2/grants/OAuth2RefreshAccessTokenGrant.kt b/library/src/main/java/de/rheinfabrik/heimdall2/grants/OAuth2RefreshAccessTokenGrant.kt index c76e81d..784cf7b 100644 --- a/library/src/main/java/de/rheinfabrik/heimdall2/grants/OAuth2RefreshAccessTokenGrant.kt +++ b/library/src/main/java/de/rheinfabrik/heimdall2/grants/OAuth2RefreshAccessTokenGrant.kt @@ -21,7 +21,7 @@ abstract class OAuth2RefreshAccessTokenGrant( * The OAuth2 "grant_type". */ companion object { - @JvmStatic + @JvmField val GRANT_TYPE = "refresh_token" } } diff --git a/library/src/main/java/de/rheinfabrik/heimdall2/grants/OAuth2ResourceOwnerPasswordCredentialsGrant.kt b/library/src/main/java/de/rheinfabrik/heimdall2/grants/OAuth2ResourceOwnerPasswordCredentialsGrant.kt index 8b46863..c2bd232 100644 --- a/library/src/main/java/de/rheinfabrik/heimdall2/grants/OAuth2ResourceOwnerPasswordCredentialsGrant.kt +++ b/library/src/main/java/de/rheinfabrik/heimdall2/grants/OAuth2ResourceOwnerPasswordCredentialsGrant.kt @@ -21,7 +21,7 @@ abstract class OAuth2ResourceOwnerPasswordCredentialsGrant( ) : OAuth2Grant { companion object { - @JvmStatic + @JvmField val GRANT_TYPE = "password" } } From 92ea46af870eb7d944cc0d1906e6ea325763d7a4 Mon Sep 17 00:00:00 2001 From: Walter Ching Date: Fri, 26 Jul 2019 14:10:49 +0200 Subject: [PATCH 2/8] Access field with new annotation instead on sample --- .../network/oauth2/TraktTvAuthorizationCodeGrant.java | 4 ++-- .../network/oauth2/TraktTvRefreshAccessTokenGrant.java | 4 ++-- .../utils/SharedPreferencesOAuth2AccessTokenStorage.java | 9 ++++----- 3 files changed, 8 insertions(+), 9 deletions(-) diff --git a/sample/src/main/java/de/rheinfabrik/heimdalldroid/network/oauth2/TraktTvAuthorizationCodeGrant.java b/sample/src/main/java/de/rheinfabrik/heimdalldroid/network/oauth2/TraktTvAuthorizationCodeGrant.java index bf34834..6f2ad9f 100644 --- a/sample/src/main/java/de/rheinfabrik/heimdalldroid/network/oauth2/TraktTvAuthorizationCodeGrant.java +++ b/sample/src/main/java/de/rheinfabrik/heimdalldroid/network/oauth2/TraktTvAuthorizationCodeGrant.java @@ -29,7 +29,7 @@ public URL buildAuthorizationUrl() { .buildUpon() .appendQueryParameter("client_id", getClientId()) .appendQueryParameter("redirect_uri", getRedirectUri()) - .appendQueryParameter("response_type", OAuth2AuthorizationCodeGrant.getRESPONSE_TYPE()) + .appendQueryParameter("response_type", OAuth2AuthorizationCodeGrant.RESPONSE_TYPE) .build() .toString() ); @@ -41,7 +41,7 @@ public URL buildAuthorizationUrl() { @Override public Observable exchangeTokenUsingCode(String code) { AccessTokenRequestBody body = new AccessTokenRequestBody( - code, getClientId(), getRedirectUri(), clientSecret, getGRANT_TYPE() + code, getClientId(), getRedirectUri(), clientSecret, GRANT_TYPE ); return TraktTvApiFactory.newApiService().grantNewAccessToken(body); } diff --git a/sample/src/main/java/de/rheinfabrik/heimdalldroid/network/oauth2/TraktTvRefreshAccessTokenGrant.java b/sample/src/main/java/de/rheinfabrik/heimdalldroid/network/oauth2/TraktTvRefreshAccessTokenGrant.java index 2fad1fd..ddfc9c9 100644 --- a/sample/src/main/java/de/rheinfabrik/heimdalldroid/network/oauth2/TraktTvRefreshAccessTokenGrant.java +++ b/sample/src/main/java/de/rheinfabrik/heimdalldroid/network/oauth2/TraktTvRefreshAccessTokenGrant.java @@ -9,7 +9,7 @@ /** * TraktTv refresh token grant as described in http://docs.trakt.apiary.io/#reference/authentication-oauth/token/exchange-refresh_token-for-access_token. */ -public class TraktTvRefreshAccessTokenGrant extends OAuth2RefreshAccessTokenGrant { +public class TraktTvRefreshAccessTokenGrant extends OAuth2RefreshAccessTokenGrant { // Properties @@ -21,7 +21,7 @@ public class TraktTvRefreshAccessTokenGrant extends OAuth2RefreshAccessTokenGran @Override public Single grantNewAccessToken() { - RefreshTokenRequestBody body = new RefreshTokenRequestBody(getRefreshToken(), clientId, clientSecret, redirectUri, getGRANT_TYPE()); + RefreshTokenRequestBody body = new RefreshTokenRequestBody(getRefreshToken(), clientId, clientSecret, redirectUri, GRANT_TYPE); return TraktTvApiFactory.newApiService().refreshAccessToken(body).singleOrError(); } } diff --git a/sample/src/main/java/de/rheinfabrik/heimdalldroid/utils/SharedPreferencesOAuth2AccessTokenStorage.java b/sample/src/main/java/de/rheinfabrik/heimdalldroid/utils/SharedPreferencesOAuth2AccessTokenStorage.java index d0f6148..1c52885 100755 --- a/sample/src/main/java/de/rheinfabrik/heimdalldroid/utils/SharedPreferencesOAuth2AccessTokenStorage.java +++ b/sample/src/main/java/de/rheinfabrik/heimdalldroid/utils/SharedPreferencesOAuth2AccessTokenStorage.java @@ -14,7 +14,7 @@ * * @param The access token type. */ -public class SharedPreferencesOAuth2AccessTokenStorage implements OAuth2AccessTokenStorage { +public class SharedPreferencesOAuth2AccessTokenStorage implements OAuth2AccessTokenStorage { // Constants @@ -50,19 +50,18 @@ public SharedPreferencesOAuth2AccessTokenStorage(SharedPreferences sharedPrefere // OAuth2AccessTokenStorage - @SuppressWarnings("unchecked") @Override - public Single getStoredAccessToken() { + public Single getStoredAccessToken() { return Single .just(mSharedPreferences.getString(ACCESS_TOKEN_PREFERENCES_KEY, null)) .map(json -> (TAccessToken) new Gson().fromJson(json, mTokenClass)); } @Override - public void storeAccessToken(TAccessToken accessToken) { + public void storeAccessToken(OAuth2AccessToken token) { mSharedPreferences .edit() - .putString(ACCESS_TOKEN_PREFERENCES_KEY, new Gson().toJson(accessToken)) + .putString(ACCESS_TOKEN_PREFERENCES_KEY, new Gson().toJson(token)) .apply(); } From 592ac4756fe32436fae03185a71e63ca87c6b72e Mon Sep 17 00:00:00 2001 From: Walter Ching Date: Thu, 30 Jan 2020 14:17:32 +0100 Subject: [PATCH 3/8] Make OAuth2AccessToken a data class --- .../de/rheinfabrik/heimdall2/OAuth2AccessToken.kt | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/library/src/main/java/de/rheinfabrik/heimdall2/OAuth2AccessToken.kt b/library/src/main/java/de/rheinfabrik/heimdall2/OAuth2AccessToken.kt index 4a8c8f3..b5f56f6 100644 --- a/library/src/main/java/de/rheinfabrik/heimdall2/OAuth2AccessToken.kt +++ b/library/src/main/java/de/rheinfabrik/heimdall2/OAuth2AccessToken.kt @@ -4,21 +4,21 @@ import com.google.gson.annotations.SerializedName import java.io.Serializable import java.util.Calendar -class OAuth2AccessToken( +data class OAuth2AccessToken( /** * REQUIRED * The type of the token issued as described in https://tools.ietf.org/html/rfc6749#section-7.1. * Value is case insensitive. */ @SerializedName("token_type") - var tokenType: String? = null, + val tokenType: String? = null, /** * REQUIRED * The access token issued by the authorization server. */ @SerializedName("access_token") - var accessToken: String? = null, + val accessToken: String? = null, /** * OPTIONAL @@ -27,7 +27,7 @@ class OAuth2AccessToken( * in https://tools.ietf.org/html/rfc6749#section-6. */ @SerializedName("refresh_token") - var refreshToken: String? = null, + val refreshToken: String? = null, /** * RECOMMENDED @@ -38,13 +38,13 @@ class OAuth2AccessToken( * expiration time via other means or document the default value. */ @SerializedName("expires_in") - var expiresIn: Int? = null, + val expiresIn: Int? = null, /** * The expiration date used by Heimdall. */ @SerializedName("heimdall_expiration_date") - var expirationDate: Calendar? = null + val expirationDate: Calendar? = null ) : Serializable { // Public API From 0ef2f8a00e4509625b513e1309be246419ae061a Mon Sep 17 00:00:00 2001 From: Walter Ching Date: Thu, 30 Jan 2020 14:17:58 +0100 Subject: [PATCH 4/8] Use copy to set new expiration date --- .../de/rheinfabrik/heimdall2/OAuth2AccessTokenManager.kt | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/library/src/main/java/de/rheinfabrik/heimdall2/OAuth2AccessTokenManager.kt b/library/src/main/java/de/rheinfabrik/heimdall2/OAuth2AccessTokenManager.kt index fb8ea20..9d93f19 100644 --- a/library/src/main/java/de/rheinfabrik/heimdall2/OAuth2AccessTokenManager.kt +++ b/library/src/main/java/de/rheinfabrik/heimdall2/OAuth2AccessTokenManager.kt @@ -34,9 +34,10 @@ open class OAuth2AccessTokenManager( val newExpirationDate = (calendar.clone() as Calendar).apply { add(Calendar.SECOND, it) } - token.expirationDate = newExpirationDate + mStorage.storeAccessToken( + token = token.copy(expirationDate = newExpirationDate) + ) } - mStorage.storeAccessToken(token) }.cache() /** From fe4ad9a2d24adbf29ac66c7d244ea79a945794ea Mon Sep 17 00:00:00 2001 From: Walter Ching Date: Thu, 30 Jan 2020 14:27:07 +0100 Subject: [PATCH 5/8] Use of copy to alter values in token --- ...uth2AccessTokenManagerGrantNewAccessTokenTest.kt | 13 +++++++++---- .../heimdall2/OAuth2AccessTokenSerializationTest.kt | 8 ++++++-- 2 files changed, 15 insertions(+), 6 deletions(-) diff --git a/library/src/test/java/de/rheinfabrik/heimdall2/OAuth2AccessTokenManagerGrantNewAccessTokenTest.kt b/library/src/test/java/de/rheinfabrik/heimdall2/OAuth2AccessTokenManagerGrantNewAccessTokenTest.kt index 431cbff..c46f6ed 100644 --- a/library/src/test/java/de/rheinfabrik/heimdall2/OAuth2AccessTokenManagerGrantNewAccessTokenTest.kt +++ b/library/src/test/java/de/rheinfabrik/heimdall2/OAuth2AccessTokenManagerGrantNewAccessTokenTest.kt @@ -17,11 +17,14 @@ class OAuth2AccessTokenManagerGrantNewAccessTokenTest { val accessToken = OAuth2AccessToken( expirationDate = null ) - accessToken.expiresIn = 3 + val changedAccessToken = accessToken.copy( + expiresIn = 3 + ) + // and a grant that emits that token val grant = mock().apply { - whenever(grantNewAccessToken()).thenReturn(Single.just(accessToken)) + whenever(grantNewAccessToken()).thenReturn(Single.just(changedAccessToken)) } // and a tokenManager @@ -49,11 +52,13 @@ class OAuth2AccessTokenManagerGrantNewAccessTokenTest { val accessToken = OAuth2AccessToken( expirationDate = null ) - accessToken.expiresIn = null + val changedAccessToken = accessToken.copy( + expiresIn = null + ) // and a grant that emits that token val grant = mock().apply { - whenever(grantNewAccessToken()).thenReturn(Single.just(accessToken)) + whenever(grantNewAccessToken()).thenReturn(Single.just(changedAccessToken)) } // and a tokenManager diff --git a/library/src/test/java/de/rheinfabrik/heimdall2/OAuth2AccessTokenSerializationTest.kt b/library/src/test/java/de/rheinfabrik/heimdall2/OAuth2AccessTokenSerializationTest.kt index 07281b3..44ac6f2 100644 --- a/library/src/test/java/de/rheinfabrik/heimdall2/OAuth2AccessTokenSerializationTest.kt +++ b/library/src/test/java/de/rheinfabrik/heimdall2/OAuth2AccessTokenSerializationTest.kt @@ -28,10 +28,14 @@ class OAuth2AccessTokenSerializationTest { ) val expirationDate = Calendar.getInstance() expirationDate.timeInMillis = 0 - accessToken.expirationDate = expirationDate + + // and an updated expiration date + val changedAccessToken = accessToken.copy( + expirationDate = expirationDate + ) // when it gets serialized with Gson - val json = Gson().toJson(accessToken) + val json = Gson().toJson(changedAccessToken) // then the json should be written correctly assertEquals( From 38bca33250529609a7e433091bc2acb774b34438 Mon Sep 17 00:00:00 2001 From: Walter Ching Date: Fri, 7 Feb 2020 13:36:53 +0100 Subject: [PATCH 6/8] Update OAuth2AccessToken data class Also: - Removed the custom hashcode and equals method implementations - Required strings are not nullable anymore --- .../heimdall2/OAuth2AccessToken.kt | 19 ++----------------- 1 file changed, 2 insertions(+), 17 deletions(-) diff --git a/library/src/main/java/de/rheinfabrik/heimdall2/OAuth2AccessToken.kt b/library/src/main/java/de/rheinfabrik/heimdall2/OAuth2AccessToken.kt index b5f56f6..6370f90 100644 --- a/library/src/main/java/de/rheinfabrik/heimdall2/OAuth2AccessToken.kt +++ b/library/src/main/java/de/rheinfabrik/heimdall2/OAuth2AccessToken.kt @@ -11,14 +11,14 @@ data class OAuth2AccessToken( * Value is case insensitive. */ @SerializedName("token_type") - val tokenType: String? = null, + val tokenType: String = "", /** * REQUIRED * The access token issued by the authorization server. */ @SerializedName("access_token") - val accessToken: String? = null, + val accessToken: String = "", /** * OPTIONAL @@ -58,19 +58,4 @@ data class OAuth2AccessToken( expirationDate != null && Calendar.getInstance().after(expirationDate) - - override fun equals(other: Any?): Boolean = - when { - this === other -> true - other !is OAuth2AccessToken -> false - else -> { - accessToken.equals(other.accessToken) && tokenType.equals(other.accessToken) - } - } - - - override fun hashCode(): Int = - tokenType.hashCode().let { - 31 * it + accessToken.hashCode() - } } From 08328e219e61c34bc9504c8011a0c1f7f7f8435f Mon Sep 17 00:00:00 2001 From: Walter Ching Date: Fri, 7 Feb 2020 13:45:59 +0100 Subject: [PATCH 7/8] Fix bug on grantNewAccessToken method A dependency on the reference of token existed and when the token was made immutable the tests failed. The solution was to separate everything from the onSuccess path and add a map that updates the value if needed. --- .../heimdall2/OAuth2AccessTokenManager.kt | 21 ++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-) diff --git a/library/src/main/java/de/rheinfabrik/heimdall2/OAuth2AccessTokenManager.kt b/library/src/main/java/de/rheinfabrik/heimdall2/OAuth2AccessTokenManager.kt index 9d93f19..d9e4c90 100644 --- a/library/src/main/java/de/rheinfabrik/heimdall2/OAuth2AccessTokenManager.kt +++ b/library/src/main/java/de/rheinfabrik/heimdall2/OAuth2AccessTokenManager.kt @@ -29,16 +29,23 @@ open class OAuth2AccessTokenManager( calendar: Calendar = Calendar.getInstance() ): Single = grant.grantNewAccessToken() - .doOnSuccess { token -> - token.expiresIn?.let { + .map { + val token = if (it.expiresIn != null) { val newExpirationDate = (calendar.clone() as Calendar).apply { - add(Calendar.SECOND, it) + add(Calendar.SECOND, it.expiresIn) } - mStorage.storeAccessToken( - token = token.copy(expirationDate = newExpirationDate) - ) + it.copy(expirationDate = newExpirationDate) + } else { + it } - }.cache() + token + } + .doOnSuccess { token -> + mStorage.storeAccessToken( + token = token + ) + } + .cache() /** * Returns an Observable emitting an unexpired access token. From 9074cc5cf1d35e8cff8f5273f537e62c95993440 Mon Sep 17 00:00:00 2001 From: Walter Ching Date: Fri, 7 Feb 2020 13:56:33 +0100 Subject: [PATCH 8/8] Return the if directly --- .../java/de/rheinfabrik/heimdall2/OAuth2AccessTokenManager.kt | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/library/src/main/java/de/rheinfabrik/heimdall2/OAuth2AccessTokenManager.kt b/library/src/main/java/de/rheinfabrik/heimdall2/OAuth2AccessTokenManager.kt index d9e4c90..46587fc 100644 --- a/library/src/main/java/de/rheinfabrik/heimdall2/OAuth2AccessTokenManager.kt +++ b/library/src/main/java/de/rheinfabrik/heimdall2/OAuth2AccessTokenManager.kt @@ -30,7 +30,7 @@ open class OAuth2AccessTokenManager( ): Single = grant.grantNewAccessToken() .map { - val token = if (it.expiresIn != null) { + if (it.expiresIn != null) { val newExpirationDate = (calendar.clone() as Calendar).apply { add(Calendar.SECOND, it.expiresIn) } @@ -38,7 +38,6 @@ open class OAuth2AccessTokenManager( } else { it } - token } .doOnSuccess { token -> mStorage.storeAccessToken(