* fix(auth): await cookie scope hydration before ticket mint and request loading (#961) * refactor(auth): scope latch activation to active store hydration --------- Co-authored-by: M57 <hy4ri@users.noreply.github.com>
This commit is contained in:
1 parent
913ae1275d
commit
764cb3455f
3 files changed
+66
-9
No files matched your search
@@ -11,6 +11,7 @@ import okhttp3.CookieJar
|
||||
import okhttp3.HttpUrl
|
||||
import java.util.concurrent.ConcurrentHashMap
|
||||
import java.util.concurrent.CountDownLatch
|
||||
import java.util.concurrent.TimeUnit
|
||||
import java.util.concurrent.atomic.AtomicReference
|
||||
|
||||
/**
|
||||
@@ -63,6 +64,9 @@ class PersistentCookieJar(
|
||||
*/
|
||||
fun getCookie(name: String): Cookie? {
|
||||
val serverId = currentServerId.get()
|
||||
if (!loadedScopes.contains(serverId)) {
|
||||
loadLatches[serverId]?.await(5, TimeUnit.SECONDS)
|
||||
}
|
||||
val hosts = cache[serverId] ?: return null
|
||||
for (bucket in hosts.values) {
|
||||
synchronized(bucket) {
|
||||
@@ -126,6 +130,9 @@ class PersistentCookieJar(
|
||||
|
||||
override fun loadForRequest(url: HttpUrl): List<Cookie> {
|
||||
val serverId = currentServerId.get()
|
||||
if (!loadedScopes.contains(serverId)) {
|
||||
loadLatches[serverId]?.await(5, TimeUnit.SECONDS)
|
||||
}
|
||||
val hostKey = url.host
|
||||
val hosts = cache[serverId] ?: return emptyList()
|
||||
val now = System.currentTimeMillis()
|
||||
@@ -152,16 +159,21 @@ class PersistentCookieJar(
|
||||
|
||||
private suspend fun ensureLoaded(serverId: String) {
|
||||
if (loadedScopes.contains(serverId)) return
|
||||
val persisted = store.load(serverId)
|
||||
val byHost = ConcurrentHashMap<String, MutableList<Cookie>>()
|
||||
for (cookie in persisted) {
|
||||
// Blank domain => host-only (e.g. legacy migrated session cookie).
|
||||
// Bucket it under a wildcard "*" so it is returned for every host.
|
||||
val host = cookie.domain.removePrefix(".").ifBlank { WILDCARD_HOST }
|
||||
byHost.getOrPut(host) { mutableListOf() }.add(cookie)
|
||||
val latch = loadLatches.computeIfAbsent(serverId) { CountDownLatch(1) }
|
||||
try {
|
||||
val persisted = store.load(serverId)
|
||||
val byHost = ConcurrentHashMap<String, MutableList<Cookie>>()
|
||||
for (cookie in persisted) {
|
||||
// Blank domain => host-only (e.g. legacy migrated session cookie).
|
||||
// Bucket it under a wildcard "*" so it is returned for every host.
|
||||
val host = cookie.domain.removePrefix(".").ifBlank { WILDCARD_HOST }
|
||||
byHost.getOrPut(host) { mutableListOf() }.add(cookie)
|
||||
}
|
||||
cache[serverId] = byHost
|
||||
loadedScopes.add(serverId)
|
||||
} finally {
|
||||
latch.countDown()
|
||||
}
|
||||
cache[serverId] = byHost
|
||||
loadedScopes.add(serverId)
|
||||
}
|
||||
|
||||
private fun persist(serverId: String) {
|
||||
@@ -195,6 +207,7 @@ class PersistentCookieJar(
|
||||
val scope = currentServerId.get()
|
||||
cache.remove(scope)
|
||||
loadedScopes.remove(scope)
|
||||
loadLatches.remove(scope)
|
||||
storeScope.launch { store.clear(scope) }
|
||||
}
|
||||
|
||||
@@ -202,6 +215,7 @@ class PersistentCookieJar(
|
||||
fun clearAll() {
|
||||
cache.clear()
|
||||
loadedScopes.clear()
|
||||
loadLatches.clear()
|
||||
storeScope.launch { store.clearAll() }
|
||||
}
|
||||
|
||||
|
||||
@@ -4,6 +4,7 @@ import android.util.Log
|
||||
import androidx.annotation.VisibleForTesting
|
||||
import com.m57.hermescontrol.BuildConfig
|
||||
import com.m57.hermescontrol.data.local.AuthManager
|
||||
import com.m57.hermescontrol.data.remote.CookieManager
|
||||
import com.m57.hermescontrol.data.remote.DashboardSessionTokenRefresher
|
||||
import com.m57.hermescontrol.data.remote.NetworkMonitor
|
||||
import com.m57.hermescontrol.data.remote.OkHttpProvider
|
||||
@@ -493,6 +494,9 @@ object HermesWsClient {
|
||||
// read throws NetworkOnMainThreadException and the mint fails.
|
||||
val (code, body) =
|
||||
kotlinx.coroutines.runBlocking(Dispatchers.IO) {
|
||||
if (CookieManager.isInitialized()) {
|
||||
CookieManager.useStore(CookieManager.cookieJar.currentServer())
|
||||
}
|
||||
client.newCall(request).execute().use { resp ->
|
||||
resp.code to resp.body.string()
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user