[add] function implementation
This commit is contained in:
25
app/src/main/java/com/acitelight/aether/service/ApiClient.kt
Normal file
25
app/src/main/java/com/acitelight/aether/service/ApiClient.kt
Normal file
@@ -0,0 +1,25 @@
|
||||
|
||||
package com.acitelight.aether.service
|
||||
|
||||
import com.jakewharton.retrofit2.converter.kotlinx.serialization.asConverterFactory
|
||||
import kotlinx.serialization.json.Json
|
||||
import okhttp3.MediaType.Companion.toMediaType
|
||||
import retrofit2.Retrofit
|
||||
import retrofit2.converter.gson.GsonConverterFactory
|
||||
|
||||
object ApiClient {
|
||||
const val base: String = "http://192.168.1.213/"
|
||||
private val json = Json {
|
||||
ignoreUnknownKeys = true
|
||||
}
|
||||
|
||||
private val retrofit = Retrofit.Builder()
|
||||
.baseUrl(base)
|
||||
.addConverterFactory(GsonConverterFactory.create())
|
||||
.addConverterFactory(json.asConverterFactory("application/json".toMediaType()))
|
||||
.build()
|
||||
|
||||
val api: ApiInterface by lazy {
|
||||
retrofit.create(ApiInterface::class.java)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,55 @@
|
||||
package com.acitelight.aether.service
|
||||
|
||||
import com.acitelight.aether.model.ChallengeResponse
|
||||
import com.acitelight.aether.model.Comic
|
||||
import com.acitelight.aether.model.VideoResponse
|
||||
import okhttp3.ResponseBody
|
||||
import retrofit2.http.Body
|
||||
import retrofit2.http.GET
|
||||
import retrofit2.http.POST
|
||||
import retrofit2.http.Path
|
||||
import retrofit2.http.Query
|
||||
import retrofit2.http.Streaming
|
||||
|
||||
interface ApiInterface {
|
||||
@GET("api/video")
|
||||
suspend fun getVideoClasses(
|
||||
@Query("token") token: String
|
||||
): List<String>
|
||||
@GET("api/video/{klass}")
|
||||
suspend fun queryVideoClasses(
|
||||
@Path("klass") klass: String,
|
||||
@Query("token") token: String
|
||||
): List<String>
|
||||
@GET("api/video/{klass}/{id}")
|
||||
suspend fun queryVideo(
|
||||
@Path("klass") klass: String,
|
||||
@Path("id") id: String,
|
||||
@Query("token") token: String
|
||||
): VideoResponse
|
||||
|
||||
@GET("api/video/{klass}/{id}/nv")
|
||||
@Streaming
|
||||
suspend fun getNailVideo(
|
||||
@Path("klass") klass: String,
|
||||
@Path("id") id: String,
|
||||
@Query("token") token: String
|
||||
): ResponseBody
|
||||
|
||||
@GET("api/image/collections")
|
||||
suspend fun getComicCollections(): List<String>
|
||||
@GET("api/image/meta")
|
||||
suspend fun queryComicInfo(@Query("collection") collection: String): Comic
|
||||
|
||||
|
||||
@GET("api/user/{user}")
|
||||
suspend fun getChallenge(
|
||||
@Path("user") user: String
|
||||
): ResponseBody
|
||||
|
||||
@POST("api/user/{user}")
|
||||
suspend fun verifyChallenge(
|
||||
@Path("user") user: String,
|
||||
@Body challengeResponse: ChallengeResponse
|
||||
): ResponseBody
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
package com.acitelight.aether.service
|
||||
|
||||
import android.util.Base64
|
||||
import com.acitelight.aether.model.ChallengeResponse
|
||||
import kotlinx.coroutines.runBlocking
|
||||
import org.bouncycastle.crypto.params.Ed25519PrivateKeyParameters
|
||||
import org.bouncycastle.crypto.signers.Ed25519Signer
|
||||
import java.security.PrivateKey
|
||||
import java.security.Signature
|
||||
|
||||
object AuthManager {
|
||||
suspend fun fetchToken(baseUrl: String, username: String, privateKey: String): String? = runBlocking {
|
||||
val api = ApiClient.api
|
||||
var challengeBase64 = ""
|
||||
try{
|
||||
challengeBase64 = api.getChallenge(username).string()
|
||||
}catch (e: Exception)
|
||||
{
|
||||
print(e.message)
|
||||
}
|
||||
|
||||
val signedBase64 = signChallenge(db64(privateKey), db64(challengeBase64))
|
||||
|
||||
return@runBlocking try {
|
||||
api.verifyChallenge(username, ChallengeResponse(response = signedBase64)).string()
|
||||
} catch (e: Exception) {
|
||||
e.printStackTrace()
|
||||
null
|
||||
}
|
||||
}
|
||||
|
||||
fun db64(b64: String): ByteArray {
|
||||
return Base64.decode(b64, Base64.DEFAULT) // 32 bytes
|
||||
}
|
||||
|
||||
fun signChallenge(privateKey: ByteArray, data: ByteArray): String
|
||||
{
|
||||
val privateKeyParams = Ed25519PrivateKeyParameters(privateKey, 0)
|
||||
val signer = Ed25519Signer()
|
||||
signer.init(true, privateKeyParams)
|
||||
|
||||
signer.update(data, 0, data.size)
|
||||
val signature = signer.generateSignature()
|
||||
return Base64.encodeToString(signature, Base64.NO_WRAP)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
package com.acitelight.aether.service
|
||||
|
||||
import com.acitelight.aether.model.Comic
|
||||
import com.acitelight.aether.model.Video
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.withContext
|
||||
import java.io.IOException
|
||||
|
||||
|
||||
object MediaManager
|
||||
{
|
||||
var token: String = "null"
|
||||
|
||||
suspend fun listVideoKlasses(): List<String>
|
||||
{
|
||||
val j = ApiClient.api.getVideoClasses(token)
|
||||
return j.toList()
|
||||
}
|
||||
|
||||
suspend fun listVideos(klass: String): List<Video>
|
||||
{
|
||||
val j = ApiClient.api.queryVideoClasses(klass, token)
|
||||
return j.map{
|
||||
queryVideo(klass, it)
|
||||
}.toList()
|
||||
}
|
||||
|
||||
suspend fun queryVideo(klass: String, id: String): Video
|
||||
{
|
||||
val j = ApiClient.api.queryVideo(klass, id, token)
|
||||
return Video(klass = klass, id = id, token=token, j)
|
||||
}
|
||||
|
||||
suspend fun listComics() : List<String>
|
||||
{
|
||||
return ApiClient.api.getComicCollections()
|
||||
}
|
||||
|
||||
suspend fun queryComicInfo(c: String) : Comic
|
||||
{
|
||||
return ApiClient.api.queryComicInfo(c)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user