mirror of
https://github.com/mihonapp/mihon.git
synced 2024-11-21 20:47:03 -05:00
feat: more optimization Hikka authorization
This commit is contained in:
parent
9eeed9f050
commit
f39e947ece
4 changed files with 25 additions and 64 deletions
|
@ -151,14 +151,6 @@ class Hikka(id: Long) : BaseTracker(id, "Hikka"), DeletableTracker {
|
|||
interceptor.setAuth(null)
|
||||
}
|
||||
|
||||
fun getIfAuthExpired(): Boolean {
|
||||
return trackPreferences.trackAuthExpired(this).get()
|
||||
}
|
||||
|
||||
fun setAuthExpired() {
|
||||
trackPreferences.trackAuthExpired(this).set(true)
|
||||
}
|
||||
|
||||
fun saveOAuth(oAuth: HKOAuth?) {
|
||||
trackPreferences.trackToken(this).set(json.encodeToString(oAuth))
|
||||
}
|
||||
|
|
|
@ -174,12 +174,20 @@ class HikkaApi(
|
|||
.appendQueryParameter("scope", SCOPE)
|
||||
.build()
|
||||
|
||||
fun refreshTokenRequest(hkOAuth: HKOAuth): Request {
|
||||
fun refreshTokenRequest(accessToken: String): Request {
|
||||
val headers = Headers.Builder()
|
||||
.add("auth", hkOAuth.accessToken)
|
||||
.add("auth", accessToken)
|
||||
.build()
|
||||
|
||||
return GET("$BASE_API_URL/user/me", headers = headers)
|
||||
return GET("$BASE_API_URL/user/me", headers = headers) // Any request with auth
|
||||
}
|
||||
|
||||
fun authTokenInfo(accessToken: String): Request {
|
||||
val headers = Headers.Builder()
|
||||
.add("auth", accessToken)
|
||||
.build()
|
||||
|
||||
return GET("$BASE_API_URL/auth/token/info", headers = headers)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,31 +1,33 @@
|
|||
package eu.kanade.tachiyomi.data.track.hikka
|
||||
|
||||
import eu.kanade.tachiyomi.data.track.hikka.dto.HKAuthTokenInfo
|
||||
import eu.kanade.tachiyomi.data.track.hikka.dto.HKOAuth
|
||||
import kotlinx.serialization.json.Json
|
||||
import okhttp3.Interceptor
|
||||
import okhttp3.Response
|
||||
import org.json.JSONObject
|
||||
import uy.kohesive.injekt.injectLazy
|
||||
import java.io.IOException
|
||||
|
||||
class HikkaInterceptor(private val hikka: Hikka) : Interceptor {
|
||||
|
||||
private val json: Json by injectLazy()
|
||||
private var oauth: HKOAuth? = hikka.loadOAuth()
|
||||
private val tokenExpired get() = hikka.getIfAuthExpired()
|
||||
|
||||
override fun intercept(chain: Interceptor.Chain): Response {
|
||||
if (tokenExpired) {
|
||||
throw HKTokenExpired()
|
||||
}
|
||||
val originalRequest = chain.request()
|
||||
|
||||
if (oauth?.isExpired() == true) {
|
||||
refreshToken(chain)
|
||||
}
|
||||
val currAuth = oauth ?: throw Exception("Not authenticated with Hikka")
|
||||
|
||||
if (oauth == null) {
|
||||
throw IOException("User is not authenticated")
|
||||
if (currAuth.isExpired()) {
|
||||
val refreshTokenResponse = chain.proceed(HikkaApi.refreshTokenRequest(currAuth.accessToken))
|
||||
if (!refreshTokenResponse.isSuccessful)
|
||||
refreshTokenResponse.close()
|
||||
|
||||
val authTokenInfoResponse = chain.proceed(HikkaApi.authTokenInfo(currAuth.accessToken))
|
||||
if (!authTokenInfoResponse.isSuccessful)
|
||||
authTokenInfoResponse.close()
|
||||
|
||||
val authTokenInfo = json.decodeFromString<HKAuthTokenInfo>(authTokenInfoResponse.body.string())
|
||||
setAuth(HKOAuth(oauth!!.accessToken, authTokenInfo.expiration))
|
||||
}
|
||||
|
||||
val authRequest = originalRequest.newBuilder()
|
||||
|
@ -40,41 +42,4 @@ class HikkaInterceptor(private val hikka: Hikka) : Interceptor {
|
|||
this.oauth = oauth
|
||||
hikka.saveOAuth(oauth)
|
||||
}
|
||||
|
||||
private fun refreshToken(chain: Interceptor.Chain): HKOAuth = synchronized(this) {
|
||||
if (tokenExpired) throw HKTokenExpired()
|
||||
oauth?.takeUnless { it.isExpired() }?.let { return@synchronized it }
|
||||
|
||||
val response = try {
|
||||
chain.proceed(HikkaApi.refreshTokenRequest(oauth!!))
|
||||
} catch (_: Throwable) {
|
||||
throw HKTokenRefreshFailed()
|
||||
}
|
||||
|
||||
if (response.code != 200) {
|
||||
hikka.setAuthExpired()
|
||||
throw HKTokenExpired()
|
||||
}
|
||||
|
||||
return runCatching {
|
||||
if (response.isSuccessful && oauth != null) {
|
||||
val responseBody = response.body?.string() ?: return@runCatching null
|
||||
val jsonObject = JSONObject(responseBody)
|
||||
|
||||
val secret = oauth!!.accessToken
|
||||
val expiration = jsonObject.getLong("expiration")
|
||||
|
||||
HKOAuth(secret, expiration)
|
||||
} else {
|
||||
response.close()
|
||||
null
|
||||
}
|
||||
}.getOrNull()?.also {
|
||||
this.oauth = it
|
||||
hikka.saveOAuth(it)
|
||||
} ?: throw HKTokenRefreshFailed()
|
||||
}
|
||||
}
|
||||
|
||||
class HKTokenRefreshFailed : IOException("Hikka: Failed to refresh account token")
|
||||
class HKTokenExpired : IOException("Hikka: Login has expired")
|
||||
|
|
|
@ -1,17 +1,13 @@
|
|||
package eu.kanade.tachiyomi.data.track.hikka.dto
|
||||
|
||||
import kotlinx.serialization.SerialName
|
||||
import kotlinx.serialization.Serializable
|
||||
|
||||
@Serializable
|
||||
data class HKOAuth(
|
||||
@SerialName("secret")
|
||||
val accessToken: String,
|
||||
|
||||
@SerialName("expiration")
|
||||
val expiration: Long,
|
||||
) {
|
||||
fun isExpired(): Boolean {
|
||||
return (expiration - 7200) < (System.currentTimeMillis() / 1000)
|
||||
return (expiration - 43200) < (System.currentTimeMillis() / 1000)
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue