Browse Source
Further fix for refreshing access token See merge request funkwhale/funkwhale-android!71deploy-in-docker
Ryan Harg
3 years ago
7 changed files with 91 additions and 148 deletions
@ -1,120 +0,0 @@ |
|||||||
package audio.funkwhale.ffa.utils |
|
||||||
|
|
||||||
import android.content.Context |
|
||||||
import audio.funkwhale.ffa.activities.FwCredentials |
|
||||||
import com.github.kittinunf.fuel.Fuel |
|
||||||
import com.github.kittinunf.fuel.core.FuelError |
|
||||||
import com.github.kittinunf.fuel.coroutines.awaitObjectResponseResult |
|
||||||
import com.github.kittinunf.fuel.coroutines.awaitObjectResult |
|
||||||
import com.github.kittinunf.fuel.gson.gsonDeserializerOf |
|
||||||
import com.github.kittinunf.result.Result |
|
||||||
import com.preference.PowerPreference |
|
||||||
import java.io.BufferedReader |
|
||||||
import java.io.File |
|
||||||
import java.nio.charset.Charset |
|
||||||
import java.security.MessageDigest |
|
||||||
|
|
||||||
object RefreshError : Throwable() |
|
||||||
|
|
||||||
class HTTP( |
|
||||||
val context: Context?, |
|
||||||
val oAuth: OAuth |
|
||||||
) { |
|
||||||
|
|
||||||
suspend fun refresh(): Boolean { |
|
||||||
context?.let { |
|
||||||
val body = mapOf( |
|
||||||
"username" to PowerPreference.getFileByName(AppContext.PREFS_CREDENTIALS) |
|
||||||
.getString("username"), |
|
||||||
"password" to PowerPreference.getFileByName(AppContext.PREFS_CREDENTIALS) |
|
||||||
.getString("password") |
|
||||||
).toList() |
|
||||||
|
|
||||||
val result = Fuel.post(mustNormalizeUrl("/api/v1/token"), body).apply { |
|
||||||
if (!Settings.isAnonymous()) { |
|
||||||
authorize(it, oAuth) |
|
||||||
header("Authorization", "Bearer ${oAuth.state().accessToken}") |
|
||||||
} |
|
||||||
} |
|
||||||
.awaitObjectResult(gsonDeserializerOf(FwCredentials::class.java)) |
|
||||||
|
|
||||||
return result.fold( |
|
||||||
{ data -> |
|
||||||
PowerPreference.getFileByName(AppContext.PREFS_CREDENTIALS) |
|
||||||
.setString("access_token", data.token) |
|
||||||
|
|
||||||
true |
|
||||||
}, |
|
||||||
{ false } |
|
||||||
) |
|
||||||
} |
|
||||||
throw IllegalStateException("Illegal state: context is null") |
|
||||||
} |
|
||||||
|
|
||||||
suspend inline fun <reified T : Any> get(url: String): Result<T, FuelError> { |
|
||||||
|
|
||||||
context?.let { |
|
||||||
val request = Fuel.get(mustNormalizeUrl(url)).apply { |
|
||||||
if (!Settings.isAnonymous()) { |
|
||||||
authorize(it, oAuth) |
|
||||||
header("Authorization", "Bearer ${oAuth.state().accessToken}") |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
val (_, response, result) = request.awaitObjectResponseResult(gsonDeserializerOf(T::class.java)) |
|
||||||
|
|
||||||
if (response.statusCode == 401) { |
|
||||||
return retryGet(url) |
|
||||||
} else { |
|
||||||
return result |
|
||||||
} |
|
||||||
} |
|
||||||
throw IllegalStateException("Illegal state: context is null") |
|
||||||
} |
|
||||||
|
|
||||||
suspend inline fun <reified T : Any> retryGet( |
|
||||||
url: String |
|
||||||
): Result<T, FuelError> { |
|
||||||
context?.let { |
|
||||||
val request = Fuel.get(mustNormalizeUrl(url)).apply { |
|
||||||
if (!Settings.isAnonymous()) { |
|
||||||
authorize(context,oAuth) |
|
||||||
header("Authorization", "Bearer ${oAuth.state().accessToken}") |
|
||||||
} |
|
||||||
} |
|
||||||
request.awaitObjectResult(gsonDeserializerOf(T::class.java)) |
|
||||||
} |
|
||||||
throw IllegalStateException("Illegal state: context is null") |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
object FFACache { |
|
||||||
private fun key(key: String): String { |
|
||||||
val md = MessageDigest.getInstance("SHA-1") |
|
||||||
val digest = md.digest(key.toByteArray(Charset.defaultCharset())) |
|
||||||
|
|
||||||
return digest.fold("", { acc, it -> acc + "%02x".format(it) }) |
|
||||||
} |
|
||||||
|
|
||||||
fun set(context: Context?, key: String, value: ByteArray) = context?.let { |
|
||||||
with(File(it.cacheDir, key(key))) { |
|
||||||
writeBytes(value) |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
fun get(context: Context?, key: String): BufferedReader? = context?.let { |
|
||||||
try { |
|
||||||
with(File(it.cacheDir, key(key))) { |
|
||||||
bufferedReader() |
|
||||||
} |
|
||||||
} catch (e: Exception) { |
|
||||||
return null |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
fun delete(context: Context?, key: String) = context?.let { |
|
||||||
with(File(it.cacheDir, key(key))) { |
|
||||||
delete() |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
@ -0,0 +1,38 @@ |
|||||||
|
package audio.funkwhale.ffa.utils |
||||||
|
|
||||||
|
import android.content.Context |
||||||
|
import java.io.BufferedReader |
||||||
|
import java.io.File |
||||||
|
import java.nio.charset.Charset |
||||||
|
import java.security.MessageDigest |
||||||
|
|
||||||
|
object FFACache { |
||||||
|
private fun key(key: String): String { |
||||||
|
val md = MessageDigest.getInstance("SHA-1") |
||||||
|
val digest = md.digest(key.toByteArray(Charset.defaultCharset())) |
||||||
|
|
||||||
|
return digest.fold("", { acc, it -> acc + "%02x".format(it) }) |
||||||
|
} |
||||||
|
|
||||||
|
fun set(context: Context?, key: String, value: ByteArray) = context?.let { |
||||||
|
with(File(it.cacheDir, key(key))) { |
||||||
|
writeBytes(value) |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
fun get(context: Context?, key: String): BufferedReader? = context?.let { |
||||||
|
try { |
||||||
|
with(File(it.cacheDir, key(key))) { |
||||||
|
bufferedReader() |
||||||
|
} |
||||||
|
} catch (e: Exception) { |
||||||
|
return null |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
fun delete(context: Context?, key: String) = context?.let { |
||||||
|
with(File(it.cacheDir, key(key))) { |
||||||
|
delete() |
||||||
|
} |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,4 @@ |
|||||||
|
package audio.funkwhale.ffa.utils |
||||||
|
|
||||||
|
object RefreshError : Throwable() |
||||||
|
|
Loading…
Reference in new issue