forked from github/szkolny
[App] Fix cookie persistence.
This commit is contained in:
parent
31b569b02e
commit
beff1b6460
@ -29,11 +29,12 @@ class SignatureInterceptor(val app: App) : Interceptor {
|
|||||||
return chain.proceed(
|
return chain.proceed(
|
||||||
request.newBuilder()
|
request.newBuilder()
|
||||||
.header("X-ApiKey", app.config.apiKeyCustom?.takeValue() ?: API_KEY)
|
.header("X-ApiKey", app.config.apiKeyCustom?.takeValue() ?: API_KEY)
|
||||||
.header("X-AppVersion", BuildConfig.VERSION_CODE.toString())
|
|
||||||
.header("X-Timestamp", timestamp.toString())
|
|
||||||
.header("X-Signature", sign(timestamp, body, url))
|
|
||||||
.header("X-AppBuild", BuildConfig.BUILD_TYPE)
|
.header("X-AppBuild", BuildConfig.BUILD_TYPE)
|
||||||
.header("X-AppFlavor", BuildConfig.FLAVOR)
|
.header("X-AppFlavor", BuildConfig.FLAVOR)
|
||||||
|
.header("X-AppVersion", BuildConfig.VERSION_CODE.toString())
|
||||||
|
.header("X-DeviceId", app.deviceId)
|
||||||
|
.header("X-Signature", sign(timestamp, body, url))
|
||||||
|
.header("X-Timestamp", timestamp.toString())
|
||||||
.build())
|
.build())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -15,6 +15,7 @@ import android.text.style.CharacterStyle
|
|||||||
import android.text.style.ForegroundColorSpan
|
import android.text.style.ForegroundColorSpan
|
||||||
import android.text.style.StrikethroughSpan
|
import android.text.style.StrikethroughSpan
|
||||||
import android.text.style.StyleSpan
|
import android.text.style.StyleSpan
|
||||||
|
import android.text.style.UnderlineSpan
|
||||||
import androidx.annotation.PluralsRes
|
import androidx.annotation.PluralsRes
|
||||||
import androidx.annotation.StringRes
|
import androidx.annotation.StringRes
|
||||||
import com.mikepenz.materialdrawer.holder.StringHolder
|
import com.mikepenz.materialdrawer.holder.StringHolder
|
||||||
@ -160,6 +161,11 @@ fun CharSequence?.asBoldSpannable(): Spannable {
|
|||||||
spannable.setSpan(StyleSpan(Typeface.BOLD), 0, spannable.length, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE)
|
spannable.setSpan(StyleSpan(Typeface.BOLD), 0, spannable.length, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE)
|
||||||
return spannable
|
return spannable
|
||||||
}
|
}
|
||||||
|
fun CharSequence?.asUnderlineSpannable(): Spannable {
|
||||||
|
val spannable = SpannableString(this)
|
||||||
|
spannable.setSpan(UnderlineSpan(), 0, spannable.length, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE)
|
||||||
|
return spannable
|
||||||
|
}
|
||||||
fun CharSequence.asSpannable(
|
fun CharSequence.asSpannable(
|
||||||
vararg spans: CharacterStyle,
|
vararg spans: CharacterStyle,
|
||||||
substring: CharSequence? = null,
|
substring: CharSequence? = null,
|
||||||
|
@ -5,8 +5,20 @@
|
|||||||
package pl.szczodrzynski.edziennik.network.cookie
|
package pl.szczodrzynski.edziennik.network.cookie
|
||||||
|
|
||||||
import okhttp3.Cookie
|
import okhttp3.Cookie
|
||||||
|
import okhttp3.HttpUrl
|
||||||
|
|
||||||
class DumbCookie(var cookie: Cookie) {
|
class DumbCookie(var cookie: Cookie) {
|
||||||
|
companion object {
|
||||||
|
fun deserialize(key: String, value: String): DumbCookie? {
|
||||||
|
val (domain, _) = key.split('|', limit = 2)
|
||||||
|
val url = HttpUrl.Builder()
|
||||||
|
.scheme("https")
|
||||||
|
.host(domain)
|
||||||
|
.build()
|
||||||
|
val cookie = Cookie.parse(url, value) ?: return null
|
||||||
|
return DumbCookie(cookie)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
constructor(domain: String, name: String, value: String, expiresAt: Long? = null) : this(
|
constructor(domain: String, name: String, value: String, expiresAt: Long? = null) : this(
|
||||||
Cookie.Builder()
|
Cookie.Builder()
|
||||||
@ -45,4 +57,9 @@ class DumbCookie(var cookie: Cookie) {
|
|||||||
hash = 31 * hash + cookie.domain().hashCode()
|
hash = 31 * hash + cookie.domain().hashCode()
|
||||||
return hash
|
return hash
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun serialize(): Pair<String, String> {
|
||||||
|
val key = cookie.domain() + "|" + cookie.name()
|
||||||
|
return key to cookie.toString()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -5,6 +5,7 @@
|
|||||||
package pl.szczodrzynski.edziennik.network.cookie
|
package pl.szczodrzynski.edziennik.network.cookie
|
||||||
|
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
|
import androidx.core.content.edit
|
||||||
import okhttp3.Cookie
|
import okhttp3.Cookie
|
||||||
import okhttp3.CookieJar
|
import okhttp3.CookieJar
|
||||||
import okhttp3.HttpUrl
|
import okhttp3.HttpUrl
|
||||||
@ -26,22 +27,31 @@ class DumbCookieJar(
|
|||||||
) : CookieJar {
|
) : CookieJar {
|
||||||
|
|
||||||
private val prefs = context.getSharedPreferences("cookies", Context.MODE_PRIVATE)
|
private val prefs = context.getSharedPreferences("cookies", Context.MODE_PRIVATE)
|
||||||
val sessionCookies = mutableSetOf<DumbCookie>()
|
private val sessionCookies = mutableSetOf<DumbCookie>()
|
||||||
private val savedCookies = mutableSetOf<DumbCookie>()
|
|
||||||
|
init {
|
||||||
|
prefs.all.forEach { (key, value) ->
|
||||||
|
if (value !is String)
|
||||||
|
return@forEach
|
||||||
|
sessionCookies.add(DumbCookie.deserialize(key, value) ?: return@forEach)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private fun save(dc: DumbCookie) {
|
private fun save(dc: DumbCookie) {
|
||||||
sessionCookies.remove(dc)
|
sessionCookies.remove(dc)
|
||||||
sessionCookies.add(dc)
|
sessionCookies.add(dc)
|
||||||
if (dc.cookie.persistent() || persistAll) {
|
if (dc.cookie.persistent() || persistAll) {
|
||||||
savedCookies.remove(dc)
|
prefs.edit {
|
||||||
savedCookies.add(dc)
|
val (key, value) = dc.serialize()
|
||||||
|
putString(key, value)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
private fun delete(vararg toRemove: DumbCookie) {
|
private fun delete(vararg toRemove: DumbCookie) {
|
||||||
sessionCookies.removeAll(toRemove)
|
sessionCookies.removeAll(toRemove)
|
||||||
savedCookies.removeAll(toRemove)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun saveFromResponse(url: HttpUrl?, cookies: List<Cookie>) {
|
override fun saveFromResponse(url: HttpUrl, cookies: MutableList<Cookie>) {
|
||||||
for (cookie in cookies) {
|
for (cookie in cookies) {
|
||||||
val dc = DumbCookie(cookie)
|
val dc = DumbCookie(cookie)
|
||||||
save(dc)
|
save(dc)
|
||||||
@ -54,6 +64,10 @@ class DumbCookieJar(
|
|||||||
}.map { it.cookie }
|
}.map { it.cookie }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun getAllDomains(): List<Cookie> {
|
||||||
|
return sessionCookies.map { it.cookie }
|
||||||
|
}
|
||||||
|
|
||||||
fun get(domain: String, name: String): String? {
|
fun get(domain: String, name: String): String? {
|
||||||
return sessionCookies.firstOrNull {
|
return sessionCookies.firstOrNull {
|
||||||
it.domainMatches(domain) && it.cookie.name() == name
|
it.domainMatches(domain) && it.cookie.name() == name
|
||||||
@ -84,7 +98,7 @@ class DumbCookieJar(
|
|||||||
fun getAll(domain: String): Map<String, String> {
|
fun getAll(domain: String): Map<String, String> {
|
||||||
return sessionCookies.filter {
|
return sessionCookies.filter {
|
||||||
it.domainMatches(domain)
|
it.domainMatches(domain)
|
||||||
}.map { it.cookie.name() to it.cookie.value() }.toMap()
|
}.associate { it.cookie.name() to it.cookie.value() }
|
||||||
}
|
}
|
||||||
|
|
||||||
fun remove(domain: String, name: String) {
|
fun remove(domain: String, name: String) {
|
||||||
|
@ -181,22 +181,29 @@ class LabPageFragment : LazyFragment(), CoroutineScope {
|
|||||||
|
|
||||||
val colorSecondary = android.R.attr.textColorSecondary.resolveAttr(activity)
|
val colorSecondary = android.R.attr.textColorSecondary.resolveAttr(activity)
|
||||||
startCoroutineTimer(500L, 300L) {
|
startCoroutineTimer(500L, 300L) {
|
||||||
val text = app.cookieJar.sessionCookies
|
val text = app.cookieJar.getAllDomains()
|
||||||
.map { it.cookie }
|
|
||||||
.sortedBy { it.domain() }
|
.sortedBy { it.domain() }
|
||||||
.groupBy { it.domain() }
|
.groupBy { it.domain() }
|
||||||
.map {
|
.map { pair ->
|
||||||
listOf(
|
listOf(
|
||||||
it.key.asBoldSpannable(),
|
pair.key.asBoldSpannable(),
|
||||||
":\n",
|
":\n",
|
||||||
it.value
|
pair.value
|
||||||
.sortedBy { it.name() }
|
.sortedBy { it.name() }
|
||||||
.map {
|
.map { cookie ->
|
||||||
listOf(
|
listOf(
|
||||||
" ",
|
" ",
|
||||||
it.name(),
|
if (cookie.persistent())
|
||||||
|
cookie.name()
|
||||||
|
.asUnderlineSpannable()
|
||||||
|
else
|
||||||
|
cookie.name(),
|
||||||
"=",
|
"=",
|
||||||
it.value().decode().take(40).asItalicSpannable().asColoredSpannable(colorSecondary)
|
cookie.value()
|
||||||
|
.decode()
|
||||||
|
.take(40)
|
||||||
|
.asItalicSpannable()
|
||||||
|
.asColoredSpannable(colorSecondary),
|
||||||
).concat("")
|
).concat("")
|
||||||
}.concat("\n")
|
}.concat("\n")
|
||||||
).concat("")
|
).concat("")
|
||||||
|
Loading…
Reference in New Issue
Block a user