Use WebView auth flow for MAL (fixes #4100)

This commit is contained in:
arkon
2020-12-08 22:19:59 -05:00
parent c2b8fea291
commit 2bb7a33bc3
8 changed files with 183 additions and 151 deletions

View File

@@ -100,37 +100,18 @@ class MyAnimeList(private val context: Context, id: Int) : TrackService(id) {
}
}
override fun login(username: String, password: String): Completable {
logout()
fun login(csrfToken: String): Completable = login("myanimelist", csrfToken)
return Observable.fromCallable { api.login(username, password) }
.doOnNext { csrf -> saveCSRF(csrf) }
override fun login(username: String, password: String): Completable {
return Observable.fromCallable { saveCSRF(password) }
.doOnNext { saveCredentials(username, password) }
.doOnError { logout() }
.toCompletable()
}
fun refreshLogin() {
val username = getUsername()
val password = getPassword()
logout()
try {
val csrf = api.login(username, password)
saveCSRF(csrf)
saveCredentials(username, password)
} catch (e: Exception) {
logout()
throw e
}
}
// Attempt to login again if cookies have been cleared but credentials are still filled
fun ensureLoggedIn() {
if (isAuthorized) return
if (!isLogged) throw Exception("MAL Login Credentials not found")
refreshLogin()
if (!isLogged) throw Exception("MAL login credentials not found")
}
override fun logout() {
@@ -139,7 +120,7 @@ class MyAnimeList(private val context: Context, id: Int) : TrackService(id) {
networkService.cookieManager.remove(BASE_URL.toHttpUrlOrNull()!!)
}
val isAuthorized: Boolean
private val isAuthorized: Boolean
get() = super.isLogged &&
getCSRF().isNotEmpty() &&
checkCookies()

View File

@@ -133,30 +133,6 @@ class MyAnimeListApi(private val client: OkHttpClient, interceptor: MyAnimeListI
.map { it ?: throw Exception("Could not find manga") }
}
fun login(username: String, password: String): String {
val csrf = getSessionInfo()
login(username, password, csrf)
return csrf
}
private fun getSessionInfo(): String {
val response = client.newCall(GET(loginUrl())).execute()
return Jsoup.parse(response.consumeBody())
.select("meta[name=csrf_token]")
.attr("content")
}
private fun login(username: String, password: String, csrf: String) {
val response = client.newCall(POST(url = loginUrl(), body = loginPostBody(username, password, csrf))).execute()
response.use {
if (response.priorResponse?.code != 302) throw Exception("Authentication error")
}
}
private fun getList(): Observable<List<TrackSearch>> {
return getListUrl()
.flatMap { url ->
@@ -258,12 +234,12 @@ class MyAnimeListApi(private val client: OkHttpClient, interceptor: MyAnimeListI
private const val PREFIX_MY = "my:"
private const val TD = "td"
private fun mangaUrl(remoteId: Int) = baseMangaUrl + remoteId
private fun loginUrl() = baseUrl.toUri().buildUpon()
fun loginUrl() = baseUrl.toUri().buildUpon()
.appendPath("login.php")
.toString()
private fun mangaUrl(remoteId: Int) = baseMangaUrl + remoteId
private fun searchUrl(query: String): String {
val col = "c[]"
return baseUrl.toUri().buildUpon()
@@ -292,17 +268,6 @@ class MyAnimeListApi(private val client: OkHttpClient, interceptor: MyAnimeListI
.appendPath("add.json")
.toString()
private fun loginPostBody(username: String, password: String, csrf: String): RequestBody {
return FormBody.Builder()
.add("user_name", username)
.add("password", password)
.add("cookie", "1")
.add("sublogin", "Login")
.add("submit", "1")
.add(CSRF, csrf)
.build()
}
private fun exportPostBody(): RequestBody {
return FormBody.Builder()
.add("type", "2")

View File

@@ -14,15 +14,7 @@ class MyAnimeListInterceptor(private val myanimelist: MyAnimeList) : Interceptor
myanimelist.ensureLoggedIn()
val request = chain.request()
var response = chain.proceed(updateRequest(request))
if (response.code == 400) {
myanimelist.refreshLogin()
response.close()
response = chain.proceed(updateRequest(request))
}
return response
return chain.proceed(updateRequest(request))
}
private fun updateRequest(request: Request): Request {