[APIv2/Vulcan] Add Vulcan Api

This commit is contained in:
Kacper Ziubryniewicz 2019-10-19 20:38:30 +02:00
parent b32ebe4479
commit 92fb83ccf9
8 changed files with 156 additions and 22 deletions

View File

@ -155,6 +155,8 @@ dependencies {
debugImplementation "com.github.ChuckerTeam.Chucker:library:3.0.1"
releaseImplementation "com.github.ChuckerTeam.Chucker:library-no-op:3.0.1"
implementation 'com.github.wulkanowy:uonet-request-signer:master-SNAPSHOT'
}
repositories {
mavenCentral()

View File

@ -51,19 +51,20 @@ val MOBIDZIENNIK_USER_AGENT = SYSTEM_USER_AGENT
const val VULCAN_API_USER_AGENT = "MobileUserAgent"
const val VULCAN_API_APP_NAME = "VULCAN-Android-ModulUcznia"
const val VULCAN_API_APP_VERSION = "19.4.1.436"
const val VULCAN_API_PASSWORD = "CE75EA598C7743AD9B0B7328DED85B06"
val VULCAN_API_DEVICE_NAME = "Szkolny.eu ${Build.MODEL}"
const val VULCAN_API_ENDPOINT_CERTIFICATE = "mobile-api/Uczen.v3.UczenStart/Certyfikat";
const val VULCAN_API_ENDPOINT_STUDENT_LIST = "mobile-api/Uczen.v3.UczenStart/ListaUczniow";
const val VULCAN_API_ENDPOINT_DICTIONARIES = "mobile-api/Uczen.v3.Uczen/Slowniki";
const val VULCAN_API_ENDPOINT_TIMETABLE = "mobile-api/Uczen.v3.Uczen/PlanLekcjiZeZmianami";
const val VULCAN_API_ENDPOINT_GRADES = "mobile-api/Uczen.v3.Uczen/Oceny";
const val VULCAN_API_ENDPOINT_GRADES_PROPOSITIONS = "mobile-api/Uczen.v3.Uczen/OcenyPodsumowanie";
const val VULCAN_API_ENDPOINT_EVENTS = "mobile-api/Uczen.v3.Uczen/Sprawdziany";
const val VULCAN_API_ENDPOINT_HOMEWORK = "mobile-api/Uczen.v3.Uczen/ZadaniaDomowe";
const val VULCAN_API_ENDPOINT_NOTICES = "mobile-api/Uczen.v3.Uczen/UwagiUcznia";
const val VULCAN_API_ENDPOINT_ATTENDANCE = "mobile-api/Uczen.v3.Uczen/Frekwencje";
const val VULCAN_API_ENDPOINT_MESSAGES_RECEIVED = "mobile-api/Uczen.v3.Uczen/WiadomosciOdebrane";
const val VULCAN_API_ENDPOINT_MESSAGES_SENT = "mobile-api/Uczen.v3.Uczen/WiadomosciWyslane";
const val VULCAN_API_ENDPOINT_MESSAGES_CHANGE_STATUS = "mobile-api/Uczen.v3.Uczen/ZmienStatusWiadomosci";
const val VULCAN_API_ENDPOINT_PUSH = "mobile-api/Uczen.v3.Uczen/UstawPushToken";
const val VULCAN_API_ENDPOINT_CERTIFICATE = "mobile-api/Uczen.v3.UczenStart/Certyfikat"
const val VULCAN_API_ENDPOINT_STUDENT_LIST = "mobile-api/Uczen.v3.UczenStart/ListaUczniow"
const val VULCAN_API_ENDPOINT_DICTIONARIES = "mobile-api/Uczen.v3.Uczen/Slowniki"
const val VULCAN_API_ENDPOINT_TIMETABLE = "mobile-api/Uczen.v3.Uczen/PlanLekcjiZeZmianami"
const val VULCAN_API_ENDPOINT_GRADES = "mobile-api/Uczen.v3.Uczen/Oceny"
const val VULCAN_API_ENDPOINT_GRADES_PROPOSITIONS = "mobile-api/Uczen.v3.Uczen/OcenyPodsumowanie"
const val VULCAN_API_ENDPOINT_EVENTS = "mobile-api/Uczen.v3.Uczen/Sprawdziany"
const val VULCAN_API_ENDPOINT_HOMEWORK = "mobile-api/Uczen.v3.Uczen/ZadaniaDomowe"
const val VULCAN_API_ENDPOINT_NOTICES = "mobile-api/Uczen.v3.Uczen/UwagiUcznia"
const val VULCAN_API_ENDPOINT_ATTENDANCE = "mobile-api/Uczen.v3.Uczen/Frekwencje"
const val VULCAN_API_ENDPOINT_MESSAGES_RECEIVED = "mobile-api/Uczen.v3.Uczen/WiadomosciOdebrane"
const val VULCAN_API_ENDPOINT_MESSAGES_SENT = "mobile-api/Uczen.v3.Uczen/WiadomosciWyslane"
const val VULCAN_API_ENDPOINT_MESSAGES_CHANGE_STATUS = "mobile-api/Uczen.v3.Uczen/ZmienStatusWiadomosci"
const val VULCAN_API_ENDPOINT_PUSH = "mobile-api/Uczen.v3.Uczen/UstawPushToken"

View File

@ -126,4 +126,5 @@ const val EXCEPTION_LOGIN_LIBRUS_PORTAL_TOKEN = 902
const val EXCEPTION_LIBRUS_PORTAL_SYNERGIA_TOKEN = 903
const val EXCEPTION_LIBRUS_API_REQUEST = 904
const val EXCEPTION_MOBIDZIENNIK_WEB_REQUEST = 905
const val EXCEPTION_NOTIFY_AND_SYNC = 910
const val EXCEPTION_VULCAN_API_REQUEST = 906
const val EXCEPTION_NOTIFY_AND_SYNC = 910

View File

@ -169,4 +169,9 @@ class DataVulcan(app: App, profile: Profile?, loginStore: LoginStore) : Data(app
else -> null
}
}
val fullApiUrl: String?
get() {
return "${apiUrl}${schoolSymbol}/"
}
}

View File

@ -0,0 +1,96 @@
/*
* Copyright (c) Kacper Ziubryniewicz 2019-10-19
*/
package pl.szczodrzynski.edziennik.api.v2.vulcan.data
import com.google.gson.JsonObject
import im.wangchao.mhttp.Request
import im.wangchao.mhttp.Response
import im.wangchao.mhttp.callback.JsonCallbackHandler
import io.github.wulkanowy.signer.signContent
import pl.szczodrzynski.edziennik.api.v2.*
import pl.szczodrzynski.edziennik.api.v2.models.ApiError
import pl.szczodrzynski.edziennik.api.v2.vulcan.DataVulcan
import pl.szczodrzynski.edziennik.utils.Utils.d
import java.net.HttpURLConnection
import java.util.*
open class VulcanApi(open val data: DataVulcan) {
companion object {
const val TAG = "VulcanApi"
}
val profileId
get() = data.profile?.id ?: -1
val profile
get() = data.profile
fun apiGet(tag: String, endpoint: String, method: Int = POST, payload: JsonObject? = null, onSuccess: (json: JsonObject) -> Unit) {
d(tag, "Request: Librus/Api - ${data.fullApiUrl}/$endpoint")
val finalPayload = JsonObject()
finalPayload.addProperty("IdUczen", data.studentId)
finalPayload.addProperty("IdOkresKlasyfikacyjny", data.studentSemesterId)
finalPayload.addProperty("IdOddzial", data.studentClassId)
finalPayload.addProperty("RemoteMobileTimeKey", System.currentTimeMillis() / 1000)
finalPayload.addProperty("TimeKey", System.currentTimeMillis() / 1000 - 1)
finalPayload.addProperty("RequestId", UUID.randomUUID().toString())
finalPayload.addProperty("RemoteMobileAppVersion", VULCAN_API_APP_VERSION)
finalPayload.addProperty("RemoteMobileAppName", VULCAN_API_APP_NAME)
val callback = object : JsonCallbackHandler() {
override fun onSuccess(json: JsonObject?, response: Response?) {
if (json == null && response?.parserErrorBody == null) {
data.error(ApiError(TAG, ERROR_RESPONSE_EMPTY)
.withResponse(response))
return
}
// TODO: Vulcan error handling
if (json == null) {
data.error(ApiError(tag, ERROR_RESPONSE_EMPTY)
.withResponse(response))
return
}
try {
onSuccess(json)
} catch (e: Exception) {
data.error(ApiError(tag, EXCEPTION_VULCAN_API_REQUEST)
.withResponse(response)
.withThrowable(e)
.withApiResponse(json))
}
}
override fun onFailure(response: Response?, throwable: Throwable?) {
data.error(ApiError(tag, ERROR_REQUEST_FAILURE)
.withResponse(response)
.withThrowable(throwable))
}
}
Request.builder()
.url("${data.fullApiUrl}$endpoint")
.userAgent(VULCAN_API_USER_AGENT)
.addHeader("RequestCertificateKey", data.apiCertificateKey)
.addHeader("RequestSignatureValue",
signContent(VULCAN_API_PASSWORD, data.apiCertificatePfx, finalPayload.toString()))
.apply {
when (method) {
GET -> get()
POST -> post()
}
}
.setJsonBody(finalPayload)
.allowErrorCode(HttpURLConnection.HTTP_BAD_REQUEST)
.allowErrorCode(HttpURLConnection.HTTP_FORBIDDEN)
.allowErrorCode(HttpURLConnection.HTTP_UNAUTHORIZED)
.callback(callback)
.build()
.enqueue()
}
}

View File

@ -4,7 +4,10 @@
package pl.szczodrzynski.edziennik.api.v2.vulcan.data
import pl.szczodrzynski.edziennik.R
import pl.szczodrzynski.edziennik.api.v2.vulcan.DataVulcan
import pl.szczodrzynski.edziennik.api.v2.vulcan.ENDPOINT_VULCAN_API_GRADES
import pl.szczodrzynski.edziennik.api.v2.vulcan.data.api.VulcanApiGrades
import pl.szczodrzynski.edziennik.utils.Utils
class VulcanData(val data: DataVulcan, val onSuccess: () -> Unit) {
@ -35,11 +38,11 @@ class VulcanData(val data: DataVulcan, val onSuccess: () -> Unit) {
private fun useEndpoint(endpointId: Int, onSuccess: () -> Unit) {
Utils.d(TAG, "Using endpoint $endpointId")
when (endpointId) {
/*ENDPOINT_VULCAN_API -> {
data.startProgress(R.string.edziennik_progress_endpoint_data)
VulcanApi(data) { onSuccess() }
}*/
ENDPOINT_VULCAN_API_GRADES -> {
data.startProgress(R.string.edziennik_progress_endpoint_grades)
VulcanApiGrades(data) { onSuccess() }
}
else -> onSuccess()
}
}
}
}

View File

@ -0,0 +1,27 @@
/*
* Copyright (c) Kacper Ziubryniewicz 2019-10-19
*/
package pl.szczodrzynski.edziennik.api.v2.vulcan.data.api
import pl.szczodrzynski.edziennik.api.v2.VULCAN_API_ENDPOINT_GRADES
import pl.szczodrzynski.edziennik.api.v2.vulcan.DataVulcan
import pl.szczodrzynski.edziennik.api.v2.vulcan.ENDPOINT_VULCAN_API_GRADES
import pl.szczodrzynski.edziennik.api.v2.vulcan.data.VulcanApi
import pl.szczodrzynski.edziennik.data.db.modules.api.SYNC_ALWAYS
import pl.szczodrzynski.edziennik.getJsonArray
class VulcanApiGrades(override val data: DataVulcan, val onSuccess: () -> Unit) : VulcanApi(data) {
companion object {
const val TAG = "VulcanApiGrades"
}
init {
apiGet(TAG, VULCAN_API_ENDPOINT_GRADES) { json ->
val grades = json.getJsonArray("Data")
data.setSyncNext(ENDPOINT_VULCAN_API_GRADES, SYNC_ALWAYS)
onSuccess()
}
}
}

View File

@ -13,7 +13,6 @@ import pl.szczodrzynski.edziennik.*
import pl.szczodrzynski.edziennik.api.v2.*
import pl.szczodrzynski.edziennik.api.v2.models.ApiError
import pl.szczodrzynski.edziennik.api.v2.vulcan.DataVulcan
import pl.szczodrzynski.edziennik.utils.Utils
import pl.szczodrzynski.edziennik.utils.Utils.d
import java.net.HttpURLConnection.HTTP_BAD_REQUEST
import java.util.*
@ -131,4 +130,4 @@ class VulcanLoginApi(val data: DataVulcan, val onSuccess: () -> Unit) {
.build()
.enqueue()
}
}
}