Skip to content

Commit

Permalink
refactor: Use milliseconds for expiry time
Browse files Browse the repository at this point in the history
  • Loading branch information
HamzaIsrar12 committed Nov 21, 2023
1 parent 5bdf03a commit 5c6227b
Show file tree
Hide file tree
Showing 5 changed files with 49 additions and 21 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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
}

Expand All @@ -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
Expand Down Expand Up @@ -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
}
}
14 changes: 13 additions & 1 deletion auth/src/main/java/org/openedx/auth/data/model/AuthResponse.kt
Original file line number Diff line number Diff line change
@@ -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")
Expand All @@ -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,
)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand All @@ -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
}
Expand Down
19 changes: 19 additions & 0 deletions auth/src/main/java/org/openedx/auth/domain/model/AuthResponse.kt
Original file line number Diff line number Diff line change
@@ -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()
}
}
5 changes: 2 additions & 3 deletions core/src/main/java/org/openedx/core/utils/TimeUtils.kt
Original file line number Diff line number Diff line change
Expand Up @@ -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 {

Expand All @@ -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? {
Expand Down

0 comments on commit 5c6227b

Please sign in to comment.