mirror of
https://git.mihon.tech/mihonapp/mihon
synced 2024-11-21 20:55:41 +03:00
Don't throw MALTokenExpired
whenever we fail to refresh MAL token
Also cleanup
This commit is contained in:
parent
ddbe8efbc5
commit
0f4de03d7a
2 changed files with 34 additions and 38 deletions
|
@ -21,9 +21,8 @@ class MyAnimeListInterceptor(private val myanimelist: MyAnimeList) : Interceptor
|
|||
}
|
||||
val originalRequest = chain.request()
|
||||
|
||||
// Refresh access token if expired
|
||||
if (oauth != null && oauth!!.isExpired()) {
|
||||
setAuth(refreshToken(chain))
|
||||
if (oauth?.isExpired() == true) {
|
||||
refreshToken(chain)
|
||||
}
|
||||
|
||||
if (oauth == null) {
|
||||
|
@ -36,27 +35,7 @@ class MyAnimeListInterceptor(private val myanimelist: MyAnimeList) : Interceptor
|
|||
.header("User-Agent", "Mihon v${BuildConfig.VERSION_NAME} (${BuildConfig.APPLICATION_ID})")
|
||||
.build()
|
||||
|
||||
val response = chain.proceed(authRequest)
|
||||
val tokenIsExpired = response.headers["www-authenticate"]
|
||||
?.contains("The access token expired") ?: false
|
||||
|
||||
// Retry the request once with a new token in case it was not already refreshed
|
||||
// by the is expired check before.
|
||||
if (response.code == 401 && tokenIsExpired) {
|
||||
response.close()
|
||||
|
||||
val newToken = refreshToken(chain)
|
||||
setAuth(newToken)
|
||||
|
||||
val newRequest = originalRequest.newBuilder()
|
||||
.addHeader("Authorization", "Bearer ${newToken.access_token}")
|
||||
.header("User-Agent", "Mihon v${BuildConfig.VERSION_NAME} (${BuildConfig.APPLICATION_ID})")
|
||||
.build()
|
||||
|
||||
return chain.proceed(newRequest)
|
||||
}
|
||||
|
||||
return response
|
||||
return chain.proceed(authRequest)
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -68,22 +47,37 @@ class MyAnimeListInterceptor(private val myanimelist: MyAnimeList) : Interceptor
|
|||
myanimelist.saveOAuth(oauth)
|
||||
}
|
||||
|
||||
private fun refreshToken(chain: Interceptor.Chain): OAuth {
|
||||
private fun refreshToken(chain: Interceptor.Chain): OAuth = synchronized(this) {
|
||||
if (tokenExpired) throw MALTokenExpired()
|
||||
oauth?.takeUnless { it.isExpired() }?.let { return@synchronized it }
|
||||
|
||||
val response = try {
|
||||
chain.proceed(MyAnimeListApi.refreshTokenRequest(oauth!!))
|
||||
} catch (_: Throwable) {
|
||||
throw MALTokenRefreshFailed()
|
||||
}
|
||||
|
||||
if (response.code == 401) {
|
||||
myanimelist.setAuthExpired()
|
||||
throw MALTokenExpired()
|
||||
}
|
||||
|
||||
return runCatching {
|
||||
val oauthResponse = chain.proceed(MyAnimeListApi.refreshTokenRequest(oauth!!))
|
||||
if (oauthResponse.code == 401) {
|
||||
myanimelist.setAuthExpired()
|
||||
}
|
||||
if (oauthResponse.isSuccessful) {
|
||||
with(json) { oauthResponse.parseAs<OAuth>() }
|
||||
if (response.isSuccessful) {
|
||||
with(json) { response.parseAs<OAuth>() }
|
||||
} else {
|
||||
oauthResponse.close()
|
||||
response.close()
|
||||
null
|
||||
}
|
||||
}
|
||||
.getOrNull()
|
||||
?: throw MALTokenExpired()
|
||||
?.also {
|
||||
this.oauth = it
|
||||
myanimelist.saveOAuth(it)
|
||||
}
|
||||
?: throw MALTokenRefreshFailed()
|
||||
}
|
||||
}
|
||||
|
||||
class MALTokenRefreshFailed : IOException("MAL: Failed to refresh account token")
|
||||
class MALTokenExpired : IOException("MAL: Login has expired")
|
||||
|
|
|
@ -5,14 +5,16 @@ import kotlinx.serialization.Serializable
|
|||
|
||||
@Serializable
|
||||
data class OAuth(
|
||||
val token_type: String,
|
||||
val refresh_token: String,
|
||||
val access_token: String,
|
||||
val token_type: String,
|
||||
val created_at: Long = System.currentTimeMillis(),
|
||||
val expires_in: Long,
|
||||
)
|
||||
|
||||
fun OAuth.isExpired() = System.currentTimeMillis() > created_at + (expires_in * 1000)
|
||||
val created_at: Long = System.currentTimeMillis(),
|
||||
) {
|
||||
// Assumes expired a minute earlier
|
||||
private val adjustedExpiresIn: Long = (expires_in - 60) * 1000
|
||||
fun isExpired() = created_at + adjustedExpiresIn < System.currentTimeMillis()
|
||||
}
|
||||
|
||||
fun Track.toMyAnimeListStatus() = when (status) {
|
||||
MyAnimeList.READING -> "reading"
|
||||
|
|
Loading…
Reference in a new issue