mirror of
https://github.com/szkolny-eu/szkolny-android.git
synced 2024-11-24 10:54:36 -06:00
[API/Usos] Add basic USOS API structure.
This commit is contained in:
parent
132729bbd9
commit
4b64277948
@ -13,6 +13,7 @@
|
||||
<w>synergia</w>
|
||||
<w>szczodrzyński</w>
|
||||
<w>szkolny</w>
|
||||
<w>usos</w>
|
||||
</words>
|
||||
</dictionary>
|
||||
</component>
|
@ -204,6 +204,8 @@ const val ERROR_PODLASIE_API_NO_TOKEN = 630
|
||||
const val ERROR_PODLASIE_API_OTHER = 631
|
||||
const val ERROR_PODLASIE_API_DATA_MISSING = 632
|
||||
|
||||
const val ERROR_USOS_OAUTH_LOGIN_REQUEST = 701
|
||||
|
||||
const val ERROR_TEMPLATE_WEB_OTHER = 801
|
||||
|
||||
const val EXCEPTION_API_TASK = 900
|
||||
|
@ -13,6 +13,7 @@ import pl.szczodrzynski.edziennik.data.api.edziennik.mobidziennik.login.Mobidzie
|
||||
import pl.szczodrzynski.edziennik.data.api.edziennik.podlasie.login.PodlasieLoginApi
|
||||
import pl.szczodrzynski.edziennik.data.api.edziennik.template.login.TemplateLoginApi
|
||||
import pl.szczodrzynski.edziennik.data.api.edziennik.template.login.TemplateLoginWeb
|
||||
import pl.szczodrzynski.edziennik.data.api.edziennik.usos.login.UsosLoginApi
|
||||
import pl.szczodrzynski.edziennik.data.api.edziennik.vulcan.login.VulcanLoginHebe
|
||||
import pl.szczodrzynski.edziennik.data.api.edziennik.vulcan.login.VulcanLoginWebMain
|
||||
import pl.szczodrzynski.edziennik.data.api.models.LoginMethod
|
||||
@ -127,6 +128,15 @@ val podlasieLoginMethods = listOf(
|
||||
.withRequiredLoginMethod { _, _ -> LOGIN_METHOD_NOT_NEEDED }
|
||||
)
|
||||
|
||||
const val LOGIN_TYPE_USOS = 7
|
||||
const val LOGIN_MODE_USOS_OAUTH = 0
|
||||
const val LOGIN_METHOD_USOS_API = 100
|
||||
val usosLoginMethods = listOf(
|
||||
LoginMethod(LOGIN_TYPE_USOS, LOGIN_METHOD_USOS_API, UsosLoginApi::class.java)
|
||||
.withIsPossible { _, _ -> true }
|
||||
.withRequiredLoginMethod { _, _ -> LOGIN_METHOD_NOT_NEEDED }
|
||||
)
|
||||
|
||||
val templateLoginMethods = listOf(
|
||||
LoginMethod(LOGIN_TYPE_TEMPLATE, LOGIN_METHOD_TEMPLATE_WEB, TemplateLoginWeb::class.java)
|
||||
.withIsPossible { _, _ -> true }
|
||||
|
@ -0,0 +1,39 @@
|
||||
/*
|
||||
* Copyright (c) Kuba Szczodrzyński 2022-10-11.
|
||||
*/
|
||||
|
||||
package pl.szczodrzynski.edziennik.data.api.edziennik.usos
|
||||
|
||||
import pl.szczodrzynski.edziennik.App
|
||||
import pl.szczodrzynski.edziennik.data.api.LOGIN_METHOD_USOS_API
|
||||
import pl.szczodrzynski.edziennik.data.api.models.Data
|
||||
import pl.szczodrzynski.edziennik.data.db.entity.LoginStore
|
||||
import pl.szczodrzynski.edziennik.data.db.entity.Profile
|
||||
|
||||
class DataUsos(
|
||||
app: App,
|
||||
profile: Profile?,
|
||||
loginStore: LoginStore,
|
||||
) : Data(app, profile, loginStore) {
|
||||
|
||||
fun isApiLoginValid() = oauthTokenKey != null && oauthTokenSecret != null
|
||||
|
||||
override fun satisfyLoginMethods() {
|
||||
loginMethods.clear()
|
||||
if (isApiLoginValid()) {
|
||||
loginMethods += LOGIN_METHOD_USOS_API
|
||||
}
|
||||
}
|
||||
|
||||
override fun generateUserCode() = "USOS:TEST"
|
||||
|
||||
var oauthTokenKey: String?
|
||||
get() { mOauthTokenKey = mOauthTokenKey ?: loginStore.getLoginData("oauthTokenKey", null); return mOauthTokenKey }
|
||||
set(value) { loginStore.putLoginData("oauthTokenKey", value); mOauthTokenKey = value }
|
||||
private var mOauthTokenKey: String? = null
|
||||
|
||||
var oauthTokenSecret: String?
|
||||
get() { mOauthTokenSecret = mOauthTokenSecret ?: loginStore.getLoginData("oauthTokenSecret", null); return mOauthTokenSecret }
|
||||
set(value) { loginStore.putLoginData("oauthTokenSecret", value); mOauthTokenSecret = value }
|
||||
private var mOauthTokenSecret: String? = null
|
||||
}
|
@ -0,0 +1,109 @@
|
||||
/*
|
||||
* Copyright (c) Kuba Szczodrzyński 2022-10-11.
|
||||
*/
|
||||
|
||||
package pl.szczodrzynski.edziennik.data.api.edziennik.usos
|
||||
|
||||
import com.google.gson.JsonObject
|
||||
import pl.szczodrzynski.edziennik.App
|
||||
import pl.szczodrzynski.edziennik.data.api.edziennik.usos.login.UsosLogin
|
||||
import pl.szczodrzynski.edziennik.data.api.interfaces.EdziennikCallback
|
||||
import pl.szczodrzynski.edziennik.data.api.interfaces.EdziennikInterface
|
||||
import pl.szczodrzynski.edziennik.data.api.models.ApiError
|
||||
import pl.szczodrzynski.edziennik.data.api.prepare
|
||||
import pl.szczodrzynski.edziennik.data.api.usosLoginMethods
|
||||
import pl.szczodrzynski.edziennik.data.db.entity.LoginStore
|
||||
import pl.szczodrzynski.edziennik.data.db.entity.Profile
|
||||
import pl.szczodrzynski.edziennik.data.db.entity.Teacher
|
||||
import pl.szczodrzynski.edziennik.data.db.full.AnnouncementFull
|
||||
import pl.szczodrzynski.edziennik.data.db.full.EventFull
|
||||
import pl.szczodrzynski.edziennik.data.db.full.MessageFull
|
||||
import pl.szczodrzynski.edziennik.utils.Utils.d
|
||||
|
||||
class Usos(
|
||||
val app: App,
|
||||
val profile: Profile?,
|
||||
val loginStore: LoginStore,
|
||||
val callback: EdziennikCallback,
|
||||
) : EdziennikInterface {
|
||||
companion object {
|
||||
private const val TAG = "Usos"
|
||||
}
|
||||
|
||||
val internalErrorList = mutableListOf<Int>()
|
||||
val data: DataUsos
|
||||
|
||||
init {
|
||||
data = DataUsos(app, profile, loginStore).apply {
|
||||
callback = wrapCallback(this@Usos.callback)
|
||||
satisfyLoginMethods()
|
||||
}
|
||||
}
|
||||
|
||||
private fun completed() {
|
||||
data.saveData()
|
||||
callback.onCompleted()
|
||||
}
|
||||
|
||||
override fun sync(
|
||||
featureIds: List<Int>,
|
||||
viewId: Int?,
|
||||
onlyEndpoints: List<Int>?,
|
||||
arguments: JsonObject?,
|
||||
) {
|
||||
data.arguments = arguments
|
||||
data.prepare(usosLoginMethods, UsosFeatures, featureIds, viewId, onlyEndpoints)
|
||||
d(TAG, "LoginMethod IDs: ${data.targetLoginMethodIds}")
|
||||
d(TAG, "Endpoint IDs: ${data.targetEndpointIds}")
|
||||
UsosLogin(data) {
|
||||
/*UsosData(data) {
|
||||
completed()
|
||||
}*/
|
||||
}
|
||||
}
|
||||
|
||||
override fun getMessage(message: MessageFull) {}
|
||||
override fun sendMessage(recipients: List<Teacher>, subject: String, text: String) {}
|
||||
override fun markAllAnnouncementsAsRead() {}
|
||||
override fun getAnnouncement(announcement: AnnouncementFull) {}
|
||||
override fun getAttachment(owner: Any, attachmentId: Long, attachmentName: String) {}
|
||||
override fun getRecipientList() {}
|
||||
override fun getEvent(eventFull: EventFull) {}
|
||||
|
||||
override fun firstLogin() {
|
||||
/*UsosFirstLogin(data) {
|
||||
completed()
|
||||
}*/
|
||||
}
|
||||
|
||||
override fun cancel() {
|
||||
d(TAG, "Cancelled")
|
||||
data.cancel()
|
||||
}
|
||||
|
||||
private fun wrapCallback(callback: EdziennikCallback): EdziennikCallback {
|
||||
return object : EdziennikCallback {
|
||||
override fun onCompleted() {
|
||||
callback.onCompleted()
|
||||
}
|
||||
|
||||
override fun onProgress(step: Float) {
|
||||
callback.onProgress(step)
|
||||
}
|
||||
|
||||
override fun onStartProgress(stringRes: Int) {
|
||||
callback.onStartProgress(stringRes)
|
||||
}
|
||||
|
||||
override fun onError(apiError: ApiError) {
|
||||
when (apiError.errorCode) {
|
||||
in internalErrorList -> {
|
||||
// finish immediately if the same error occurs twice during the same sync
|
||||
callback.onError(apiError)
|
||||
}
|
||||
else -> callback.onError(apiError)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,18 @@
|
||||
/*
|
||||
* Copyright (c) Kuba Szczodrzyński 2022-10-11.
|
||||
*/
|
||||
|
||||
package pl.szczodrzynski.edziennik.data.api.edziennik.usos
|
||||
|
||||
import pl.szczodrzynski.edziennik.data.api.FEATURE_STUDENT_INFO
|
||||
import pl.szczodrzynski.edziennik.data.api.LOGIN_METHOD_USOS_API
|
||||
import pl.szczodrzynski.edziennik.data.api.LOGIN_TYPE_USOS
|
||||
import pl.szczodrzynski.edziennik.data.api.models.Feature
|
||||
|
||||
const val ENDPOINT_USOS_API_USER = 7000
|
||||
|
||||
val UsosFeatures = listOf(
|
||||
Feature(LOGIN_TYPE_USOS, FEATURE_STUDENT_INFO, listOf(
|
||||
ENDPOINT_USOS_API_USER to LOGIN_METHOD_USOS_API,
|
||||
), listOf(LOGIN_METHOD_USOS_API)),
|
||||
)
|
@ -0,0 +1,54 @@
|
||||
/*
|
||||
* Copyright (c) Kuba Szczodrzyński 2022-10-11.
|
||||
*/
|
||||
|
||||
package pl.szczodrzynski.edziennik.data.api.edziennik.usos.login
|
||||
|
||||
import pl.szczodrzynski.edziennik.R
|
||||
import pl.szczodrzynski.edziennik.data.api.LOGIN_METHOD_USOS_API
|
||||
import pl.szczodrzynski.edziennik.data.api.edziennik.usos.DataUsos
|
||||
import pl.szczodrzynski.edziennik.utils.Utils.d
|
||||
|
||||
class UsosLogin(val data: DataUsos, val onSuccess: () -> Unit) {
|
||||
companion object {
|
||||
private const val TAG = "UsosLogin"
|
||||
}
|
||||
|
||||
private var cancelled = false
|
||||
|
||||
init {
|
||||
nextLoginMethod(onSuccess)
|
||||
}
|
||||
|
||||
private fun nextLoginMethod(onSuccess: () -> Unit) {
|
||||
if (data.targetLoginMethodIds.isEmpty()) {
|
||||
onSuccess()
|
||||
return
|
||||
}
|
||||
if (cancelled) {
|
||||
onSuccess()
|
||||
return
|
||||
}
|
||||
useLoginMethod(data.targetLoginMethodIds.removeAt(0)) { usedMethodId ->
|
||||
data.progress(data.progressStep)
|
||||
if (usedMethodId != -1)
|
||||
data.loginMethods.add(usedMethodId)
|
||||
nextLoginMethod(onSuccess)
|
||||
}
|
||||
}
|
||||
|
||||
private fun useLoginMethod(loginMethodId: Int, onSuccess: (usedMethodId: Int) -> Unit) {
|
||||
// this should never be true
|
||||
if (data.loginMethods.contains(loginMethodId)) {
|
||||
onSuccess(-1)
|
||||
return
|
||||
}
|
||||
d(TAG, "Using login method $loginMethodId")
|
||||
when (loginMethodId) {
|
||||
LOGIN_METHOD_USOS_API -> {
|
||||
data.startProgress(R.string.edziennik_progress_login_usos_api)
|
||||
UsosLoginApi(data) { onSuccess(loginMethodId) }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,29 @@
|
||||
/*
|
||||
* Copyright (c) Kuba Szczodrzyński 2022-10-11.
|
||||
*/
|
||||
|
||||
package pl.szczodrzynski.edziennik.data.api.edziennik.usos.login
|
||||
|
||||
import pl.szczodrzynski.edziennik.data.api.ERROR_PROFILE_MISSING
|
||||
import pl.szczodrzynski.edziennik.data.api.ERROR_USOS_OAUTH_LOGIN_REQUEST
|
||||
import pl.szczodrzynski.edziennik.data.api.edziennik.usos.DataUsos
|
||||
import pl.szczodrzynski.edziennik.data.api.models.ApiError
|
||||
|
||||
class UsosLoginApi(val data: DataUsos, val onSuccess: () -> Unit) {
|
||||
companion object {
|
||||
private const val TAG = "UsosLoginApi"
|
||||
}
|
||||
|
||||
init { run {
|
||||
if (data.profile == null) {
|
||||
data.error(ApiError(TAG, ERROR_PROFILE_MISSING))
|
||||
return@run
|
||||
}
|
||||
|
||||
if (data.isApiLoginValid()) {
|
||||
onSuccess()
|
||||
} else {
|
||||
data.error(ApiError(TAG, ERROR_USOS_OAUTH_LOGIN_REQUEST))
|
||||
}
|
||||
}}
|
||||
}
|
@ -313,7 +313,24 @@ object LoginInfo {
|
||||
errorCodes = mapOf()
|
||||
)
|
||||
)
|
||||
)
|
||||
),
|
||||
Register(
|
||||
loginType = LOGIN_TYPE_USOS,
|
||||
internalName = "usos",
|
||||
registerName = R.string.login_type_usos,
|
||||
registerLogo = R.drawable.login_logo_usos,
|
||||
loginModes = listOf(
|
||||
Mode(
|
||||
loginMode = LOGIN_MODE_USOS_OAUTH,
|
||||
name = R.string.login_mode_usos_oauth,
|
||||
icon = R.drawable.login_logo_usos,
|
||||
guideText = R.string.login_mode_usos_oauth_guide,
|
||||
isPlatformSelection = true,
|
||||
credentials = listOf(),
|
||||
errorCodes = mapOf(),
|
||||
),
|
||||
),
|
||||
),
|
||||
)
|
||||
}
|
||||
|
||||
|
BIN
app/src/main/res/drawable/login_logo_usos.png
Normal file
BIN
app/src/main/res/drawable/login_logo_usos.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 15 KiB |
@ -174,6 +174,8 @@
|
||||
<string name="error_631" translatable="false">ERROR_PODLASIE_API_OTHER</string>
|
||||
<string name="error_632" translatable="false">ERROR_PODLASIE_API_DATA_MISSING</string>
|
||||
|
||||
<string name="error_701" translatable="false">ERROR_USOS_OAUTH_LOGIN_REQUEST</string>
|
||||
|
||||
<string name="error_801" translatable="false">ERROR_TEMPLATE_WEB_OTHER</string>
|
||||
|
||||
<string name="error_900" translatable="false">EXCEPTION_API_TASK</string>
|
||||
@ -364,6 +366,8 @@
|
||||
<string name="error_631_reason">ERROR_PODLASIE_API_OTHER</string>
|
||||
<string name="error_632_reason">Brak danych. Zgłoś błąd programiście.</string>
|
||||
|
||||
<string name="error_701_reason">Wymagane logowanie w przeglądarce</string>
|
||||
|
||||
<string name="error_801_reason">ERROR_TEMPLATE_WEB_OTHER</string>
|
||||
|
||||
<string name="error_900_reason">Błąd synchronizacji. Upewnij się, że masz połączenie z internetem, a następnie zgłoś błąd.</string>
|
||||
|
@ -1537,4 +1537,8 @@
|
||||
<string name="login_summary_account_parent">(rodzic)</string>
|
||||
<string name="grades_subject_unknown">- nieznany przedmiot -</string>
|
||||
<string name="grades_subject_unknown_help">{cmd-information-outline} Oceny, których przedmiot nie został podany w dzienniku. Może to być na przykład taki, który nie jest prowadzony w tym roku szkolnym.</string>
|
||||
<string name="edziennik_progress_login_usos_api">Logowanie do USOS API...</string>
|
||||
<string name="login_type_usos">USOS</string>
|
||||
<string name="login_mode_usos_oauth">Logowanie z użyciem przeglądarki</string>
|
||||
<string name="login_mode_usos_oauth_guide">TODO</string>
|
||||
</resources>
|
||||
|
Loading…
Reference in New Issue
Block a user