From 5c6227bdc0365019645af78715479dcb0db84252 Mon Sep 17 00:00:00 2001 From: Hamza Israr Date: Wed, 22 Nov 2023 03:54:32 +0500 Subject: [PATCH] refactor: Use milliseconds for expiry time --- .../OauthRefreshTokenAuthenticator.kt | 23 +++++++++---------- .../openedx/auth/data/model/AuthResponse.kt | 14 ++++++++++- .../auth/data/repository/AuthRepository.kt | 9 ++++---- .../openedx/auth/domain/model/AuthResponse.kt | 19 +++++++++++++++ .../java/org/openedx/core/utils/TimeUtils.kt | 5 ++-- 5 files changed, 49 insertions(+), 21 deletions(-) create mode 100644 auth/src/main/java/org/openedx/auth/domain/model/AuthResponse.kt diff --git a/app/src/main/java/org/openedx/app/data/networking/OauthRefreshTokenAuthenticator.kt b/app/src/main/java/org/openedx/app/data/networking/OauthRefreshTokenAuthenticator.kt index 3b7521dd3..8a9601995 100644 --- a/app/src/main/java/org/openedx/app/data/networking/OauthRefreshTokenAuthenticator.kt +++ b/app/src/main/java/org/openedx/app/data/networking/OauthRefreshTokenAuthenticator.kt @@ -12,7 +12,7 @@ import org.json.JSONObject import org.openedx.app.system.notifier.AppNotifier import org.openedx.app.system.notifier.LogoutEvent import org.openedx.auth.data.api.AuthApi -import org.openedx.auth.data.model.AuthResponse +import org.openedx.auth.domain.model.AuthResponse import org.openedx.core.ApiConstants import org.openedx.core.ApiConstants.TOKEN_TYPE_JWT import org.openedx.core.BuildConfig @@ -128,12 +128,12 @@ class OauthRefreshTokenAuthenticator( } private fun isTokenExpired(): Boolean { - val timeInSeconds = TimeUtils.getCurrentTimeInSeconds() + REFRESH_TOKEN_EXPIRY_THRESHOLD - return timeInSeconds >= preferencesManager.accessTokenExpiresAt + val time = TimeUtils.getCurrentTime() + REFRESH_TOKEN_EXPIRY_THRESHOLD + return time >= preferencesManager.accessTokenExpiresAt } private fun canRequestTokenRefresh(): Boolean { - return TimeUtils.getCurrentTimeInSeconds() - lastTokenRefreshRequestTime > + return TimeUtils.getCurrentTime() - lastTokenRefreshRequestTime > REFRESH_TOKEN_INTERVAL_MINIMUM } @@ -147,18 +147,17 @@ class OauthRefreshTokenAuthenticator( refreshToken, ACCESS_TOKEN_TYPE ).execute() - authResponse = response.body() + authResponse = response.body()?.mapToDomain() if (response.isSuccessful && authResponse != null) { val newAccessToken = authResponse.accessToken ?: "" val newRefreshToken = authResponse.refreshToken ?: "" - val newExpireTime = authResponse.expiresIn ?: 0L + val newExpireTime = authResponse.getTokenExpiryTime() - if (newAccessToken.isNotEmpty() && newRefreshToken.isNotEmpty() && newExpireTime > 0L) { + if (newAccessToken.isNotEmpty() && newRefreshToken.isNotEmpty()) { preferencesManager.accessToken = newAccessToken preferencesManager.refreshToken = newRefreshToken - preferencesManager.accessTokenExpiresAt = - newExpireTime + TimeUtils.getCurrentTimeInSeconds() - lastTokenRefreshRequestTime = TimeUtils.getCurrentTimeInSeconds() + preferencesManager.accessTokenExpiresAt = newExpireTime + lastTokenRefreshRequestTime = TimeUtils.getCurrentTime() } } else if (response.code() == 400) { //another refresh already in progress @@ -251,13 +250,13 @@ class OauthRefreshTokenAuthenticator( * verification method of the access token to ensure that the token doesn't expire during * an active session. */ - private const val REFRESH_TOKEN_EXPIRY_THRESHOLD = 60 + private const val REFRESH_TOKEN_EXPIRY_THRESHOLD = 60 * 1000 /** * [REFRESH_TOKEN_INTERVAL_MINIMUM] behave as a buffer time for refresh token network * requests. It prevents multiple calls to refresh network requests in case of an * unauthorized access token during async requests. */ - private const val REFRESH_TOKEN_INTERVAL_MINIMUM = 60 + private const val REFRESH_TOKEN_INTERVAL_MINIMUM = 60 * 1000 } } diff --git a/auth/src/main/java/org/openedx/auth/data/model/AuthResponse.kt b/auth/src/main/java/org/openedx/auth/data/model/AuthResponse.kt index 622ddb928..64c5cf27e 100644 --- a/auth/src/main/java/org/openedx/auth/data/model/AuthResponse.kt +++ b/auth/src/main/java/org/openedx/auth/data/model/AuthResponse.kt @@ -1,6 +1,7 @@ package org.openedx.auth.data.model import com.google.gson.annotations.SerializedName +import org.openedx.auth.domain.model.AuthResponse data class AuthResponse( @SerializedName("access_token") @@ -15,4 +16,15 @@ data class AuthResponse( var error: String?, @SerializedName("refresh_token") var refreshToken: String?, -) +) { + fun mapToDomain(): AuthResponse { + return AuthResponse( + accessToken = accessToken, + tokenType = tokenType, + expiresIn = expiresIn?.times(1000), + scope = scope, + error = error, + refreshToken = refreshToken, + ) + } +} diff --git a/auth/src/main/java/org/openedx/auth/data/repository/AuthRepository.kt b/auth/src/main/java/org/openedx/auth/data/repository/AuthRepository.kt index b4a1d8749..9a96674dc 100644 --- a/auth/src/main/java/org/openedx/auth/data/repository/AuthRepository.kt +++ b/auth/src/main/java/org/openedx/auth/data/repository/AuthRepository.kt @@ -2,11 +2,11 @@ package org.openedx.auth.data.repository import org.openedx.auth.data.api.AuthApi import org.openedx.auth.data.model.ValidationFields +import org.openedx.auth.domain.model.AuthResponse import org.openedx.core.ApiConstants import org.openedx.core.data.storage.CorePreferences import org.openedx.core.domain.model.RegistrationField import org.openedx.core.system.EdxError -import org.openedx.core.utils.TimeUtils class AuthRepository( private val api: AuthApi, @@ -17,20 +17,19 @@ class AuthRepository( username: String, password: String, ) { - val authResponse = api.getAccessToken( + val authResponse: AuthResponse = api.getAccessToken( ApiConstants.GRANT_TYPE_PASSWORD, org.openedx.core.BuildConfig.CLIENT_ID, username, password, org.openedx.core.BuildConfig.ACCESS_TOKEN_TYPE - ) + ).mapToDomain() if (authResponse.error != null) { throw EdxError.UnknownException(authResponse.error!!) } preferencesManager.accessToken = authResponse.accessToken ?: "" preferencesManager.refreshToken = authResponse.refreshToken ?: "" - preferencesManager.accessTokenExpiresAt = - (authResponse.expiresIn ?: 0L) + TimeUtils.getCurrentTimeInSeconds() + preferencesManager.accessTokenExpiresAt = authResponse.getTokenExpiryTime() val user = api.getProfile() preferencesManager.user = user } diff --git a/auth/src/main/java/org/openedx/auth/domain/model/AuthResponse.kt b/auth/src/main/java/org/openedx/auth/domain/model/AuthResponse.kt new file mode 100644 index 000000000..47c5a0cf4 --- /dev/null +++ b/auth/src/main/java/org/openedx/auth/domain/model/AuthResponse.kt @@ -0,0 +1,19 @@ +package org.openedx.auth.domain.model + +import android.os.Parcelable +import kotlinx.parcelize.Parcelize +import org.openedx.core.utils.TimeUtils + +@Parcelize +data class AuthResponse( + var accessToken: String?, + var tokenType: String?, + var expiresIn: Long?, + var scope: String?, + var error: String?, + var refreshToken: String?, +) : Parcelable { + fun getTokenExpiryTime(): Long { + return (expiresIn ?: 0L) + TimeUtils.getCurrentTime() + } +} diff --git a/core/src/main/java/org/openedx/core/utils/TimeUtils.kt b/core/src/main/java/org/openedx/core/utils/TimeUtils.kt index c60a2ad60..99cf7ffbc 100644 --- a/core/src/main/java/org/openedx/core/utils/TimeUtils.kt +++ b/core/src/main/java/org/openedx/core/utils/TimeUtils.kt @@ -12,7 +12,6 @@ import java.text.SimpleDateFormat import java.util.Calendar import java.util.Date import java.util.Locale -import java.util.concurrent.TimeUnit object TimeUtils { @@ -24,8 +23,8 @@ object TimeUtils { private const val SEVEN_DAYS_IN_MILLIS = 604800000L - fun getCurrentTimeInSeconds(): Long { - return TimeUnit.MILLISECONDS.toSeconds(Calendar.getInstance().timeInMillis) + fun getCurrentTime(): Long { + return Calendar.getInstance().timeInMillis } fun iso8601ToDate(text: String): Date? {