use OkHttpClient Authenticator instead of always adding credentials in headers (#1767)

[Komga] better handling of authentication
This commit is contained in:
Gauthier 2019-11-11 23:19:09 +08:00 committed by arkon
parent 12f71a7278
commit 231705d8c1
2 changed files with 33 additions and 30 deletions

View File

@ -5,7 +5,7 @@ ext {
appName = 'Tachiyomi: Komga' appName = 'Tachiyomi: Komga'
pkgNameSuffix = 'all.komga' pkgNameSuffix = 'all.komga'
extClass = '.Komga' extClass = '.Komga'
extVersionCode = 3 extVersionCode = 4
libVersion = '1.2' libVersion = '1.2'
} }

View File

@ -21,20 +21,19 @@ import uy.kohesive.injekt.Injekt
import uy.kohesive.injekt.api.get import uy.kohesive.injekt.api.get
import java.text.SimpleDateFormat import java.text.SimpleDateFormat
import java.util.* import java.util.*
import java.util.concurrent.TimeUnit
open class Komga : ConfigurableSource, HttpSource() { open class Komga : ConfigurableSource, HttpSource() {
override fun popularMangaRequest(page: Int): Request = override fun popularMangaRequest(page: Int): Request =
GET("$baseUrl/api/v1/series?page=${page - 1}", headers) GET("$baseUrl/api/v1/series?page=${page - 1}", headers)
override fun popularMangaParse(response: Response): MangasPage = override fun popularMangaParse(response: Response): MangasPage =
processSeriePage(response) processSeriesPage(response)
override fun latestUpdatesRequest(page: Int): Request = override fun latestUpdatesRequest(page: Int): Request =
GET("$baseUrl/api/v1/series/latest?page=${page - 1}", headers) GET("$baseUrl/api/v1/series/latest?page=${page - 1}", headers)
override fun latestUpdatesParse(response: Response): MangasPage = override fun latestUpdatesParse(response: Response): MangasPage =
processSeriePage(response) processSeriesPage(response)
override fun searchMangaRequest(page: Int, query: String, filters: FilterList): Request { override fun searchMangaRequest(page: Int, query: String, filters: FilterList): Request {
val url = HttpUrl.parse("$baseUrl/api/v1/series?search=$query&page=${page - 1}")!!.newBuilder() val url = HttpUrl.parse("$baseUrl/api/v1/series?search=$query&page=${page - 1}")!!.newBuilder()
@ -59,7 +58,7 @@ open class Komga : ConfigurableSource, HttpSource() {
} }
override fun searchMangaParse(response: Response): MangasPage = override fun searchMangaParse(response: Response): MangasPage =
processSeriePage(response) processSeriesPage(response)
override fun mangaDetailsRequest(manga: SManga): Request = override fun mangaDetailsRequest(manga: SManga): Request =
GET(baseUrl + manga.url, headers) GET(baseUrl + manga.url, headers)
@ -106,7 +105,7 @@ open class Komga : ConfigurableSource, HttpSource() {
} }
} }
private fun processSeriePage(response: Response): MangasPage { private fun processSeriesPage(response: Response): MangasPage {
val page = gson.fromJson<PageWrapperDto<SeriesDto>>(response.body()?.charStream()!!) val page = gson.fromJson<PageWrapperDto<SeriesDto>>(response.body()?.charStream()!!)
val mangas = page.content.map { val mangas = page.content.map {
it.toSManga() it.toSManga()
@ -149,9 +148,7 @@ open class Komga : ConfigurableSource, HttpSource() {
private var libraries = emptyList<LibraryDto>() private var libraries = emptyList<LibraryDto>()
override val name = "Komga" override val name = "Komga"
override val lang = "en" override val lang = "en"
override val supportsLatest = true override val supportsLatest = true
@ -160,36 +157,26 @@ open class Komga : ConfigurableSource, HttpSource() {
private val password by lazy { getPrefPassword() } private val password by lazy { getPrefPassword() }
private val gson by lazy { Gson() } private val gson by lazy { Gson() }
init {
Single.fromCallable {
client.newCall(GET("$baseUrl/api/v1/libraries", headers)).execute()
}
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe({
libraries = try {
gson.fromJson(it.body()?.charStream()!!)
} catch (e: Exception) {
emptyList()
}
}, {})
}
override fun headersBuilder(): Headers.Builder = override fun headersBuilder(): Headers.Builder =
Headers.Builder() Headers.Builder()
.add("Authorization", Credentials.basic(username, password))
.add("User-Agent", "Tachiyomi Komga v${BuildConfig.VERSION_NAME}") .add("User-Agent", "Tachiyomi Komga v${BuildConfig.VERSION_NAME}")
private val preferences: SharedPreferences by lazy { private val preferences: SharedPreferences by lazy {
Injekt.get<Application>().getSharedPreferences("source_$id", 0x0000) Injekt.get<Application>().getSharedPreferences("source_$id", 0x0000)
} }
private fun clientBuilder(): OkHttpClient = network.client.newBuilder() override val client: OkHttpClient =
.connectTimeout(10, TimeUnit.SECONDS) network.client.newBuilder()
.readTimeout(30, TimeUnit.SECONDS) .authenticator { _, response ->
.cache(null) if (response.request().header("Authorization") != null) {
.build()!! null // Give up, we've already failed to authenticate.
} else {
response.request().newBuilder()
.addHeader("Authorization", Credentials.basic(username, password))
.build()
}
}
.build()
override fun setupPreferenceScreen(screen: PreferenceScreen) { override fun setupPreferenceScreen(screen: PreferenceScreen) {
screen.addPreference(screen.editTextPreference(ADDRESS_TITLE, ADDRESS_DEFAULT, baseUrl)) screen.addPreference(screen.editTextPreference(ADDRESS_TITLE, ADDRESS_DEFAULT, baseUrl))
@ -223,6 +210,22 @@ open class Komga : ConfigurableSource, HttpSource() {
private fun getPrefUsername(): String = preferences.getString(USERNAME_TITLE, USERNAME_DEFAULT)!! private fun getPrefUsername(): String = preferences.getString(USERNAME_TITLE, USERNAME_DEFAULT)!!
private fun getPrefPassword(): String = preferences.getString(PASSWORD_TITLE, PASSWORD_DEFAULT)!! private fun getPrefPassword(): String = preferences.getString(PASSWORD_TITLE, PASSWORD_DEFAULT)!!
init {
Single.fromCallable {
client.newCall(GET("$baseUrl/api/v1/libraries", headers)).execute()
}
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe({
libraries = try {
gson.fromJson(it.body()?.charStream()!!)
} catch (e: Exception) {
emptyList()
}
}, {})
}
companion object { companion object {
private const val ADDRESS_TITLE = "Address" private const val ADDRESS_TITLE = "Address"
private const val ADDRESS_DEFAULT = "" private const val ADDRESS_DEFAULT = ""