From 90e7b1e9c7c25c4be9fddb14bf190b0837d5363a Mon Sep 17 00:00:00 2001 From: Kacper Ziubryniewicz Date: Mon, 23 Dec 2019 00:46:06 +0100 Subject: [PATCH] [Edudziennik] Implement base of the new e-register. --- .../edziennik/data/api/LoginMethods.kt | 9 + .../edziennik/edudziennik/DataEdudziennik.kt | 76 ++++++++ .../api/edziennik/edudziennik/Edudziennik.kt | 113 ++++++++++++ .../edudziennik/EdudziennikFeatures.kt | 24 +++ .../edudziennik/data/EdudziennikApi.kt | 45 +++++ .../edudziennik/data/EdudziennikData.kt | 41 +++++ .../edudziennik/data/EdudziennikWeb.kt | 45 +++++ .../firstlogin/EdudziennikFirstLogin.kt | 31 ++++ .../edudziennik/login/EdudziennikLogin.kt | 54 ++++++ .../edudziennik/login/EdudziennikLoginWeb.kt | 53 ++++++ .../edziennik/data/api/task/EdziennikTask.kt | 2 + .../modules/login/LoginChooserFragment.java | 1 + .../modules/login/LoginEdudziennikFragment.kt | 41 +++++ .../drawable-hdpi/login_logo_edudziennik.png | Bin 0 -> 10054 bytes .../res/layout/fragment_login_chooser.xml | 11 +- .../res/layout/fragment_login_edudziennik.xml | 173 ++++++++++++++++++ app/src/main/res/navigation/nav_login.xml | 12 ++ app/src/main/res/values/strings.xml | 2 + 18 files changed, 727 insertions(+), 6 deletions(-) create mode 100644 app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/edudziennik/DataEdudziennik.kt create mode 100644 app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/edudziennik/Edudziennik.kt create mode 100644 app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/edudziennik/EdudziennikFeatures.kt create mode 100644 app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/edudziennik/data/EdudziennikApi.kt create mode 100644 app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/edudziennik/data/EdudziennikData.kt create mode 100644 app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/edudziennik/data/EdudziennikWeb.kt create mode 100644 app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/edudziennik/firstlogin/EdudziennikFirstLogin.kt create mode 100644 app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/edudziennik/login/EdudziennikLogin.kt create mode 100644 app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/edudziennik/login/EdudziennikLoginWeb.kt create mode 100644 app/src/main/java/pl/szczodrzynski/edziennik/ui/modules/login/LoginEdudziennikFragment.kt create mode 100644 app/src/main/res/drawable-hdpi/login_logo_edudziennik.png create mode 100644 app/src/main/res/layout/fragment_login_edudziennik.xml diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/data/api/LoginMethods.kt b/app/src/main/java/pl/szczodrzynski/edziennik/data/api/LoginMethods.kt index 41350c84..6f73a59a 100644 --- a/app/src/main/java/pl/szczodrzynski/edziennik/data/api/LoginMethods.kt +++ b/app/src/main/java/pl/szczodrzynski/edziennik/data/api/LoginMethods.kt @@ -4,6 +4,7 @@ package pl.szczodrzynski.edziennik.data.api +import pl.szczodrzynski.edziennik.data.api.edziennik.edudziennik.login.EdudziennikLoginWeb import pl.szczodrzynski.edziennik.data.api.edziennik.idziennik.login.IdziennikLoginApi import pl.szczodrzynski.edziennik.data.api.edziennik.idziennik.login.IdziennikLoginWeb import pl.szczodrzynski.edziennik.data.api.edziennik.librus.login.LibrusLoginApi @@ -130,6 +131,14 @@ val idziennikLoginMethods = listOf( .withRequiredLoginMethod { _, _ -> LOGIN_METHOD_IDZIENNIK_WEB } ) +const val LOGIN_TYPE_EDUDZIENNIK = 5 +const val LOGIN_METHOD_EDUDZIENNIK_WEB = 100 +val edudziennikLoginMethods = listOf( + LoginMethod(LOGIN_TYPE_EDUDZIENNIK, LOGIN_METHOD_EDUDZIENNIK_WEB, EdudziennikLoginWeb::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 } diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/edudziennik/DataEdudziennik.kt b/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/edudziennik/DataEdudziennik.kt new file mode 100644 index 00000000..cb879f27 --- /dev/null +++ b/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/edudziennik/DataEdudziennik.kt @@ -0,0 +1,76 @@ +/* + * Copyright (c) Kacper Ziubryniewicz 2019-12-22 + */ + +package pl.szczodrzynski.edziennik.data.api.edziennik.edudziennik + +import okhttp3.Cookie +import pl.szczodrzynski.edziennik.App +import pl.szczodrzynski.edziennik.currentTimeUnix +import pl.szczodrzynski.edziennik.data.api.LOGIN_METHOD_TEMPLATE_API +import pl.szczodrzynski.edziennik.data.api.LOGIN_METHOD_TEMPLATE_WEB +import pl.szczodrzynski.edziennik.data.api.models.Data +import pl.szczodrzynski.edziennik.data.db.modules.login.LoginStore +import pl.szczodrzynski.edziennik.data.db.modules.profiles.Profile +import pl.szczodrzynski.edziennik.isNotNullNorEmpty + +/** + * Use http://patorjk.com/software/taag/#p=display&f=Big for the ascii art + * + * Use https://codepen.io/kubasz/pen/RwwwbGN to easily generate the student data getters/setters + */ +class DataEdudziennik(app: App, profile: Profile?, loginStore: LoginStore) : Data(app, profile, loginStore) { + + fun isWebLoginValid() = webExpiryTime-30 > currentTimeUnix() && webCookie.isNotNullNorEmpty() + fun isApiLoginValid() = apiExpiryTime-30 > currentTimeUnix() && apiToken.isNotNullNorEmpty() + + override fun satisfyLoginMethods() { + loginMethods.clear() + if (isWebLoginValid()) { + loginMethods += LOGIN_METHOD_TEMPLATE_WEB + app.cookieJar.saveFromResponse(null, listOf( + Cookie.Builder() + .name("AuthCookie") + .value(webCookie!!) + .domain("eregister.example.com") + .secure().httpOnly().build() + )) + } + if (isApiLoginValid()) + loginMethods += LOGIN_METHOD_TEMPLATE_API + } + + /* __ __ _ + \ \ / / | | + \ \ /\ / /__| |__ + \ \/ \/ / _ \ '_ \ + \ /\ / __/ |_) | + \/ \/ \___|_._*/ + private var mWebCookie: String? = null + var webCookie: String? + get() { mWebCookie = mWebCookie ?: profile?.getStudentData("webCookie", null); return mWebCookie } + set(value) { profile?.putStudentData("webCookie", value) ?: return; mWebCookie = value } + + private var mWebExpiryTime: Long? = null + var webExpiryTime: Long + get() { mWebExpiryTime = mWebExpiryTime ?: profile?.getStudentData("webExpiryTime", 0L); return mWebExpiryTime ?: 0L } + set(value) { profile?.putStudentData("webExpiryTime", value) ?: return; mWebExpiryTime = value } + + /* _ + /\ (_) + / \ _ __ _ + / /\ \ | '_ \| | + / ____ \| |_) | | + /_/ \_\ .__/|_| + | | + |*/ + private var mApiToken: String? = null + var apiToken: String? + get() { mApiToken = mApiToken ?: profile?.getStudentData("apiToken", null); return mApiToken } + set(value) { profile?.putStudentData("apiToken", value) ?: return; mApiToken = value } + + private var mApiExpiryTime: Long? = null + var apiExpiryTime: Long + get() { mApiExpiryTime = mApiExpiryTime ?: profile?.getStudentData("apiExpiryTime", 0L); return mApiExpiryTime ?: 0L } + set(value) { profile?.putStudentData("apiExpiryTime", value) ?: return; mApiExpiryTime = value } +} diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/edudziennik/Edudziennik.kt b/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/edudziennik/Edudziennik.kt new file mode 100644 index 00000000..ef3ca8e0 --- /dev/null +++ b/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/edudziennik/Edudziennik.kt @@ -0,0 +1,113 @@ +/* + * Copyright (c) Kacper Ziubryniewicz 2019-12-22 + */ + +package pl.szczodrzynski.edziennik.data.api.edziennik.edudziennik + +import com.google.gson.JsonObject +import pl.szczodrzynski.edziennik.App +import pl.szczodrzynski.edziennik.data.api.edudziennikLoginMethods +import pl.szczodrzynski.edziennik.data.api.edziennik.edudziennik.data.EdudziennikData +import pl.szczodrzynski.edziennik.data.api.edziennik.edudziennik.firstlogin.EdudziennikFirstLogin +import pl.szczodrzynski.edziennik.data.api.edziennik.edudziennik.login.EdudziennikLogin +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.db.modules.login.LoginStore +import pl.szczodrzynski.edziennik.data.db.modules.messages.Message +import pl.szczodrzynski.edziennik.data.db.modules.messages.MessageFull +import pl.szczodrzynski.edziennik.data.db.modules.profiles.Profile +import pl.szczodrzynski.edziennik.utils.Utils.d + +class Edudziennik(val app: App, val profile: Profile?, val loginStore: LoginStore, val callback: EdziennikCallback) : EdziennikInterface { + companion object { + private const val TAG = "Edudziennik" + } + + val internalErrorList = mutableListOf() + val data: DataEdudziennik + + init { + data = DataEdudziennik(app, profile, loginStore).apply { + callback = wrapCallback(this@Edudziennik.callback) + satisfyLoginMethods() + } + } + + private fun completed() { + data.saveData() + data.notify { + callback.onCompleted() + } + } + + /* _______ _ _ _ _ _ + |__ __| | /\ | | (_) | | | + | | | |__ ___ / \ | | __ _ ___ _ __ _| |_| |__ _ __ ___ + | | | '_ \ / _ \ / /\ \ | |/ _` |/ _ \| '__| | __| '_ \| '_ ` _ \ + | | | | | | __/ / ____ \| | (_| | (_) | | | | |_| | | | | | | | | + |_| |_| |_|\___| /_/ \_\_|\__, |\___/|_| |_|\__|_| |_|_| |_| |_| + __/ | + |__*/ + override fun sync(featureIds: List, viewId: Int?, arguments: JsonObject?) { + data.arguments = arguments + data.prepare(edudziennikLoginMethods, EdudziennikFeatures, featureIds, viewId) + d(TAG, "LoginMethod IDs: ${data.targetLoginMethodIds}") + d(TAG, "Endpoint IDs: ${data.targetEndpointIds}") + EdudziennikLogin(data) { + EdudziennikData(data) { + completed() + } + } + } + + override fun getMessage(message: MessageFull) { + + } + + override fun markAllAnnouncementsAsRead() { + + } + + override fun getAttachment(message: Message, attachmentId: Long, attachmentName: String) { + + } + + override fun firstLogin() { + EdudziennikFirstLogin(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) + } + } + } + } +} diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/edudziennik/EdudziennikFeatures.kt b/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/edudziennik/EdudziennikFeatures.kt new file mode 100644 index 00000000..92eb2936 --- /dev/null +++ b/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/edudziennik/EdudziennikFeatures.kt @@ -0,0 +1,24 @@ +/* + * Copyright (c) Kacper Ziubryniewicz 2019-12-23 + */ + +package pl.szczodrzynski.edziennik.data.api.edziennik.edudziennik + +import pl.szczodrzynski.edziennik.data.api.* +import pl.szczodrzynski.edziennik.data.api.models.Feature + +const val ENDPOINT_TEMPLATE_WEB_SAMPLE = 9991 +const val ENDPOINT_TEMPLATE_WEB_SAMPLE_2 = 9992 +const val ENDPOINT_TEMPLATE_API_SAMPLE = 9993 + +val EdudziennikFeatures = listOf( + Feature(LOGIN_TYPE_TEMPLATE, FEATURE_STUDENT_INFO, listOf( + ENDPOINT_TEMPLATE_WEB_SAMPLE to LOGIN_METHOD_TEMPLATE_WEB + ), listOf(LOGIN_METHOD_TEMPLATE_WEB)), + Feature(LOGIN_TYPE_TEMPLATE, FEATURE_SCHOOL_INFO, listOf( + ENDPOINT_TEMPLATE_WEB_SAMPLE_2 to LOGIN_METHOD_TEMPLATE_WEB + ), listOf(LOGIN_METHOD_TEMPLATE_WEB)), + Feature(LOGIN_TYPE_TEMPLATE, FEATURE_GRADES, listOf( + ENDPOINT_TEMPLATE_API_SAMPLE to LOGIN_METHOD_TEMPLATE_API + ), listOf(LOGIN_METHOD_TEMPLATE_API)) +) diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/edudziennik/data/EdudziennikApi.kt b/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/edudziennik/data/EdudziennikApi.kt new file mode 100644 index 00000000..1cb074a0 --- /dev/null +++ b/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/edudziennik/data/EdudziennikApi.kt @@ -0,0 +1,45 @@ +/* + * Copyright (c) Kacper Ziubryniewicz 2019-12-22 + */ + +package pl.szczodrzynski.edziennik.data.api.edziennik.edudziennik.data + +import com.google.gson.JsonObject +import pl.szczodrzynski.edziennik.currentTimeUnix +import pl.szczodrzynski.edziennik.data.api.ERROR_TEMPLATE_WEB_OTHER +import pl.szczodrzynski.edziennik.data.api.GET +import pl.szczodrzynski.edziennik.data.api.edziennik.edudziennik.DataEdudziennik +import pl.szczodrzynski.edziennik.data.api.models.ApiError + +open class EdudziennikApi(open val data: DataEdudziennik) { + companion object { + private const val TAG = "TemplateApi" + } + + val profileId + get() = data.profile?.id ?: -1 + + val profile + get() = data.profile + + /** + * This will be used by all TemplateApi* endpoints. + * + * You can customize this method's parameters to best fit the implemented e-register. + * Just make sure that [tag] and [onSuccess] is present. + */ + fun apiGet(tag: String, endpoint: String, method: Int = GET, payload: JsonObject? = null, onSuccess: (json: JsonObject?) -> Unit) { + val json = JsonObject() + json.addProperty("foo", "bar") + json.addProperty("sample", "text") + + if (currentTimeUnix() % 4L == 0L) { + // let's set a 20% chance of error, just as a test + data.error(ApiError(tag, ERROR_TEMPLATE_WEB_OTHER) + .withApiResponse("404 Not Found - this is the text returned by the API")) + return + } + + onSuccess(json) + } +} diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/edudziennik/data/EdudziennikData.kt b/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/edudziennik/data/EdudziennikData.kt new file mode 100644 index 00000000..30b562c1 --- /dev/null +++ b/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/edudziennik/data/EdudziennikData.kt @@ -0,0 +1,41 @@ +/* + * Copyright (c) Kacper Ziubryniewicz 2019-12-22 + */ + +package pl.szczodrzynski.edziennik.data.api.edziennik.edudziennik.data + +import pl.szczodrzynski.edziennik.data.api.edziennik.edudziennik.DataEdudziennik +import pl.szczodrzynski.edziennik.utils.Utils + +class EdudziennikData(val data: DataEdudziennik, val onSuccess: () -> Unit) { + companion object { + private const val TAG = "TemplateData" + } + + init { + nextEndpoint(onSuccess) + } + + private fun nextEndpoint(onSuccess: () -> Unit) { + if (data.targetEndpointIds.isEmpty()) { + onSuccess() + return + } + if (data.cancelled) { + onSuccess() + return + } + useEndpoint(data.targetEndpointIds.removeAt(0)) { + data.progress(data.progressStep) + nextEndpoint(onSuccess) + } + } + + private fun useEndpoint(endpointId: Int, onSuccess: () -> Unit) { + Utils.d(TAG, "Using endpoint $endpointId") + when (endpointId) { + // TODO + else -> onSuccess() + } + } +} diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/edudziennik/data/EdudziennikWeb.kt b/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/edudziennik/data/EdudziennikWeb.kt new file mode 100644 index 00000000..c1f4aa6b --- /dev/null +++ b/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/edudziennik/data/EdudziennikWeb.kt @@ -0,0 +1,45 @@ +/* + * Copyright (c) Kacper Ziubryniewicz 2019-12-22 + */ + +package pl.szczodrzynski.edziennik.data.api.edziennik.edudziennik.data + +import com.google.gson.JsonObject +import pl.szczodrzynski.edziennik.currentTimeUnix +import pl.szczodrzynski.edziennik.data.api.ERROR_TEMPLATE_WEB_OTHER +import pl.szczodrzynski.edziennik.data.api.GET +import pl.szczodrzynski.edziennik.data.api.edziennik.edudziennik.DataEdudziennik +import pl.szczodrzynski.edziennik.data.api.models.ApiError + +open class EdudziennikWeb(open val data: DataEdudziennik) { + companion object { + private const val TAG = "TemplateWeb" + } + + val profileId + get() = data.profile?.id ?: -1 + + val profile + get() = data.profile + + /** + * This will be used by all TemplateWeb* endpoints. + * + * You can customize this method's parameters to best fit the implemented e-register. + * Just make sure that [tag] and [onSuccess] is present. + */ + fun webGet(tag: String, endpoint: String, method: Int = GET, payload: JsonObject? = null, onSuccess: (json: JsonObject?) -> Unit) { + val json = JsonObject() + json.addProperty("foo", "bar") + json.addProperty("sample", "text") + + if (currentTimeUnix() % 4L == 0L) { + // let's set a 20% chance of error, just as a test + data.error(ApiError(tag, ERROR_TEMPLATE_WEB_OTHER) + .withApiResponse("404 Not Found - this is the text returned by the API")) + return + } + + onSuccess(json) + } +} diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/edudziennik/firstlogin/EdudziennikFirstLogin.kt b/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/edudziennik/firstlogin/EdudziennikFirstLogin.kt new file mode 100644 index 00000000..fa5f2c4c --- /dev/null +++ b/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/edudziennik/firstlogin/EdudziennikFirstLogin.kt @@ -0,0 +1,31 @@ +/* + * Copyright (c) Kacper Ziubryniewicz 2019-12-22 + */ + +package pl.szczodrzynski.edziennik.data.api.edziennik.edudziennik.firstlogin + +import pl.szczodrzynski.edziennik.data.api.edziennik.edudziennik.DataEdudziennik +import pl.szczodrzynski.edziennik.data.api.edziennik.edudziennik.data.EdudziennikApi +import pl.szczodrzynski.edziennik.data.api.edziennik.edudziennik.data.EdudziennikWeb +import pl.szczodrzynski.edziennik.data.db.modules.profiles.Profile + +class EdudziennikFirstLogin(val data: DataEdudziennik, val onSuccess: () -> Unit) { + companion object { + private const val TAG = "TemplateFirstLogin" + } + + private val web = EdudziennikWeb(data) + private val api = EdudziennikApi(data) + private val profileList = mutableListOf() + + init { + /*TemplateLoginWeb(data) { + web.webGet(TAG, "get all accounts") { text -> + //val accounts = json.getJsonArray("accounts") + + EventBus.getDefault().post(FirstLoginFinishedEvent(profileList, data.loginStore)) + onSuccess() + } + }*/ + } +} diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/edudziennik/login/EdudziennikLogin.kt b/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/edudziennik/login/EdudziennikLogin.kt new file mode 100644 index 00000000..0199ebbb --- /dev/null +++ b/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/edudziennik/login/EdudziennikLogin.kt @@ -0,0 +1,54 @@ +/* + * Copyright (c) Kacper Ziubryniewicz 2019-12-22 + */ + +package pl.szczodrzynski.edziennik.data.api.edziennik.edudziennik.login + +import pl.szczodrzynski.edziennik.R +import pl.szczodrzynski.edziennik.data.api.LOGIN_METHOD_EDUDZIENNIK_WEB +import pl.szczodrzynski.edziennik.data.api.edziennik.edudziennik.DataEdudziennik +import pl.szczodrzynski.edziennik.utils.Utils + +class EdudziennikLogin(val data: DataEdudziennik, val onSuccess: () -> Unit) { + companion object { + private const val TAG = "EdudziennikLogin" + } + + 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 + } + Utils.d(TAG, "Using login method $loginMethodId") + when (loginMethodId) { + LOGIN_METHOD_EDUDZIENNIK_WEB -> { + data.startProgress(R.string.edziennik_progress_login_template_web) + EdudziennikLoginWeb(data) { onSuccess(loginMethodId) } + } + } + } +} diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/edudziennik/login/EdudziennikLoginWeb.kt b/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/edudziennik/login/EdudziennikLoginWeb.kt new file mode 100644 index 00000000..ac23611c --- /dev/null +++ b/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/edudziennik/login/EdudziennikLoginWeb.kt @@ -0,0 +1,53 @@ +/* + * Copyright (c) Kacper Ziubryniewicz 2019-12-22 + */ + +package pl.szczodrzynski.edziennik.data.api.edziennik.edudziennik.login + +import okhttp3.Cookie +import pl.szczodrzynski.edziennik.currentTimeUnix +import pl.szczodrzynski.edziennik.data.api.ERROR_LOGIN_DATA_MISSING +import pl.szczodrzynski.edziennik.data.api.ERROR_PROFILE_MISSING +import pl.szczodrzynski.edziennik.data.api.edziennik.edudziennik.DataEdudziennik +import pl.szczodrzynski.edziennik.data.api.models.ApiError + +class EdudziennikLoginWeb(val data: DataEdudziennik, val onSuccess: () -> Unit) { + companion object { + private const val TAG = "EdudziennikLoginWeb" + } + + init { run { + if (data.profile == null) { + data.error(ApiError(TAG, ERROR_PROFILE_MISSING)) + return@run + } + + if (data.isWebLoginValid()) { + data.app.cookieJar.saveFromResponse(null, listOf( + Cookie.Builder() + .name("AuthCookie") + .value(data.webCookie!!) + .domain("eregister.example.com") + .secure().httpOnly().build() + )) + onSuccess() + } + else { + data.app.cookieJar.clearForDomain("eregister.example.com") + if (/*data.webLogin != null && data.webPassword != null && */true) { + loginWithCredentials() + } + else { + data.error(ApiError(TAG, ERROR_LOGIN_DATA_MISSING)) + } + } + }} + + fun loginWithCredentials() { + // succeed immediately + + data.webCookie = "ThisIsACookie" + data.webExpiryTime = currentTimeUnix() + 45 * 60 /* 45min */ + onSuccess() + } +} diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/data/api/task/EdziennikTask.kt b/app/src/main/java/pl/szczodrzynski/edziennik/data/api/task/EdziennikTask.kt index c9a0bc5c..760703ad 100644 --- a/app/src/main/java/pl/szczodrzynski/edziennik/data/api/task/EdziennikTask.kt +++ b/app/src/main/java/pl/szczodrzynski/edziennik/data/api/task/EdziennikTask.kt @@ -4,6 +4,7 @@ import com.google.gson.JsonObject import pl.szczodrzynski.edziennik.App import pl.szczodrzynski.edziennik.R import pl.szczodrzynski.edziennik.data.api.* +import pl.szczodrzynski.edziennik.data.api.edziennik.edudziennik.Edudziennik import pl.szczodrzynski.edziennik.data.api.edziennik.idziennik.Idziennik import pl.szczodrzynski.edziennik.data.api.edziennik.librus.Librus import pl.szczodrzynski.edziennik.data.api.edziennik.mobidziennik.Mobidziennik @@ -59,6 +60,7 @@ open class EdziennikTask(override val profileId: Int, val request: Any) : IApiTa LOGIN_TYPE_MOBIDZIENNIK -> Mobidziennik(app, profile, loginStore, taskCallback) LOGIN_TYPE_VULCAN -> Vulcan(app, profile, loginStore, taskCallback) LOGIN_TYPE_IDZIENNIK -> Idziennik(app, profile, loginStore, taskCallback) + LOGIN_TYPE_EDUDZIENNIK -> Edudziennik(app, profile, loginStore, taskCallback) LOGIN_TYPE_TEMPLATE -> Template(app, profile, loginStore, taskCallback) else -> null } diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/ui/modules/login/LoginChooserFragment.java b/app/src/main/java/pl/szczodrzynski/edziennik/ui/modules/login/LoginChooserFragment.java index a3088685..752eaa99 100644 --- a/app/src/main/java/pl/szczodrzynski/edziennik/ui/modules/login/LoginChooserFragment.java +++ b/app/src/main/java/pl/szczodrzynski/edziennik/ui/modules/login/LoginChooserFragment.java @@ -54,6 +54,7 @@ public class LoginChooserFragment extends Fragment { b.loginLibrusJstLogo.setOnClickListener((v) -> nav.navigate(R.id.loginLibrusJstFragment, null, LoginActivity.navOptions)); b.loginVulcanLogo.setOnClickListener((v) -> nav.navigate(R.id.loginVulcanFragment, null, LoginActivity.navOptions)); b.loginIuczniowieLogo.setOnClickListener((v) -> nav.navigate(R.id.loginIuczniowieFragment, null, LoginActivity.navOptions)); + b.loginEdudziennikLogo.setOnClickListener((v) -> nav.navigate(R.id.loginEdudziennikFragment, null, LoginActivity.navOptions)); if (LoginActivity.firstCompleted) { // we are navigated here from LoginSummary diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/ui/modules/login/LoginEdudziennikFragment.kt b/app/src/main/java/pl/szczodrzynski/edziennik/ui/modules/login/LoginEdudziennikFragment.kt new file mode 100644 index 00000000..a23009c4 --- /dev/null +++ b/app/src/main/java/pl/szczodrzynski/edziennik/ui/modules/login/LoginEdudziennikFragment.kt @@ -0,0 +1,41 @@ +/* + * Copyright (c) Kacper Ziubryniewicz 2019-12-23 + */ + +package pl.szczodrzynski.edziennik.ui.modules.login + +import android.os.Bundle +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import androidx.fragment.app.Fragment +import androidx.navigation.NavController +import androidx.navigation.Navigation +import pl.szczodrzynski.edziennik.App +import pl.szczodrzynski.edziennik.R +import pl.szczodrzynski.edziennik.databinding.FragmentLoginEdudziennikBinding +import pl.szczodrzynski.edziennik.ui.modules.error.ErrorSnackbar + +class LoginEdudziennikFragment : Fragment() { + + private val app by lazy { activity?.application as App? } + + private lateinit var b: FragmentLoginEdudziennikBinding + + private lateinit var nav: NavController + private lateinit var errorSnackbar: ErrorSnackbar + + override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? { + activity?.also { activity -> + nav = Navigation.findNavController(activity, R.id.nav_host_fragment) + errorSnackbar = (activity as LoginActivity).errorSnackbar + } + + b = FragmentLoginEdudziennikBinding.inflate(inflater, container, false) + return b.root + } + + override fun onViewCreated(view: View, savedInstanceState: Bundle?) { + + } +} diff --git a/app/src/main/res/drawable-hdpi/login_logo_edudziennik.png b/app/src/main/res/drawable-hdpi/login_logo_edudziennik.png new file mode 100644 index 0000000000000000000000000000000000000000..bed4383a819e551ac05dce115d4d07928ea3fcc0 GIT binary patch literal 10054 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 + android:layout_weight="1"> - + app:srcCompat="@drawable/login_logo_edudziennik" /> @@ -247,4 +246,4 @@ - \ No newline at end of file + diff --git a/app/src/main/res/layout/fragment_login_edudziennik.xml b/app/src/main/res/layout/fragment_login_edudziennik.xml new file mode 100644 index 00000000..588eb6b0 --- /dev/null +++ b/app/src/main/res/layout/fragment_login_edudziennik.xml @@ -0,0 +1,173 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/navigation/nav_login.xml b/app/src/main/res/navigation/nav_login.xml index c3dd6a38..af47d04f 100644 --- a/app/src/main/res/navigation/nav_login.xml +++ b/app/src/main/res/navigation/nav_login.xml @@ -125,6 +125,18 @@ android:id="@+id/action_loginVulcanFragment_to_loginProgressFragment" app:destination="@id/loginProgressFragment" /> + + + + Brak lekcji przez nast. 7 dni. Nie ma dzisiaj żadnych lekcji! Nie ma dzisiaj więcej lekcji! + Zaloguj się - Edudziennik + Użyj danych, którymi logujesz się do wersji komputerowej Edudziennika.