diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/data/api/Constants.kt b/app/src/main/java/pl/szczodrzynski/edziennik/data/api/Constants.kt index d8bd5c8b..08639918 100644 --- a/app/src/main/java/pl/szczodrzynski/edziennik/data/api/Constants.kt +++ b/app/src/main/java/pl/szczodrzynski/edziennik/data/api/Constants.kt @@ -101,3 +101,5 @@ const val VULCAN_API_ENDPOINT_MESSAGES_RECEIVED = "mobile-api/Uczen.v3.Uczen/Wia 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" + +val EDUDZIENNIK_USER_AGENT = SYSTEM_USER_AGENT diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/data/api/Errors.kt b/app/src/main/java/pl/szczodrzynski/edziennik/data/api/Errors.kt index 8ad2024a..b0abb2c2 100644 --- a/app/src/main/java/pl/szczodrzynski/edziennik/data/api/Errors.kt +++ b/app/src/main/java/pl/szczodrzynski/edziennik/data/api/Errors.kt @@ -158,6 +158,10 @@ const val ERROR_IDZIENNIK_WEB_REQUEST_NO_DATA = 441 const val ERROR_IDZIENNIK_API_ACCESS_DENIED = 450 const val ERROR_IDZIENNIK_API_OTHER = 451 +const val ERROR_LOGIN_EDUDZIENNIK_WEB_INVALID_LOGIN = 501 +const val ERROR_LOGIN_EDUDZIENNIK_WEB_OTHER = 510 +const val ERROR_LOGIN_EDUDZIENNIK_WEB_NO_SESSION_ID = 511 + const val ERROR_TEMPLATE_WEB_OTHER = 801 const val EXCEPTION_API_TASK = 900 diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/data/api/Regexes.kt b/app/src/main/java/pl/szczodrzynski/edziennik/data/api/Regexes.kt index 87e885a6..d4567e4d 100644 --- a/app/src/main/java/pl/szczodrzynski/edziennik/data/api/Regexes.kt +++ b/app/src/main/java/pl/szczodrzynski/edziennik/data/api/Regexes.kt @@ -82,4 +82,10 @@ object Regexes { val LIBRUS_ATTACHMENT_KEY by lazy { """singleUseKey=([0-9A-f_]+)""".toRegex() } + + + + val EDUDZIENNIK_STUDENT_ID by lazy { + """""".toRegex() + } } 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 index cb879f27..894a0c79 100644 --- 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 @@ -4,11 +4,9 @@ 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.LOGIN_METHOD_EDUDZIENNIK_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 @@ -21,56 +19,62 @@ import pl.szczodrzynski.edziennik.isNotNullNorEmpty */ 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() + fun isWebLoginValid() = webSessionIdExpiryTime-30 > currentTimeUnix() && webSessionId.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() - )) + loginMethods += LOGIN_METHOD_EDUDZIENNIK_WEB } - if (isApiLoginValid()) - loginMethods += LOGIN_METHOD_TEMPLATE_API } + private var mLoginEmail: String? = null + var loginEmail: String? + get() { mLoginEmail = mLoginEmail ?: loginStore.getLoginData("email", null); return mLoginEmail } + set(value) { loginStore.putLoginData("email", value); mLoginEmail = value } + + private var mLoginPassword: String? = null + var loginPassword: String? + get() { mLoginPassword = mLoginPassword ?: loginStore.getLoginData("password", null); return mLoginPassword } + set(value) { loginStore.putLoginData("password", value); mLoginPassword = value } + + private var mStudentId: String? = null + var studentId: String? + get() { mStudentId = mStudentId ?: profile?.getStudentData("studentId", null); return mStudentId } + set(value) { profile?.putStudentData("studentId", value) ?: return; mStudentId = value } + + private var mSchoolId: String? = null + var schoolId: String? + get() { mSchoolId = mSchoolId ?: profile?.getStudentData("schoolId", null); return mSchoolId } + set(value) { profile?.putStudentData("schoolId", value) ?: return; mSchoolId = value } + + private var mCourseId: String? = null + var courseId: String? + get() { mCourseId = mCourseId ?: profile?.getStudentData("courseId", null); return mCourseId } + set(value) { profile?.putStudentData("courseId", value) ?: return; mCourseId = value } + /* __ __ _ \ \ / / | | \ \ /\ / /__| |__ \ \/ \/ / _ \ '_ \ \ /\ / __/ |_) | \/ \/ \___|_._*/ - 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 mWebSessionId: String? = null + var webSessionId: String? + get() { mWebSessionId = mWebSessionId ?: loginStore.getLoginData("sessionId", null); return mWebSessionId } + set(value) { loginStore.putLoginData("sessionId", value); mWebSessionId = 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 mWebSessionIdExpiryTime: Long? = null + var webSessionIdExpiryTime: Long + get() { mWebSessionIdExpiryTime = mWebSessionIdExpiryTime ?: loginStore.getLoginData("webSessionIdExpiryTime", 0L); return mWebSessionIdExpiryTime ?: 0L } + set(value) { loginStore.putLoginData("webSessionIdExpiryTime", value); mWebSessionIdExpiryTime = 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 } + val studentEndpoint: String + get() = "Students/$studentId/" - 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 } + val schoolEndpoint: String + get() = "Schools/$schoolId/" + + val courseEndpoint: String + get() = "Schools/$courseId/" } 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 deleted file mode 100644 index 1cb074a0..00000000 --- a/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/edudziennik/data/EdudziennikApi.kt +++ /dev/null @@ -1,45 +0,0 @@ -/* - * 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/EdudziennikWeb.kt b/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/edudziennik/data/EdudziennikWeb.kt index c1f4aa6b..b783bc5b 100644 --- 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 @@ -4,16 +4,20 @@ 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 im.wangchao.mhttp.Request +import im.wangchao.mhttp.Response +import im.wangchao.mhttp.callback.TextCallbackHandler +import okhttp3.Cookie +import pl.szczodrzynski.edziennik.data.api.EDUDZIENNIK_USER_AGENT +import pl.szczodrzynski.edziennik.data.api.ERROR_REQUEST_FAILURE +import pl.szczodrzynski.edziennik.data.api.ERROR_RESPONSE_EMPTY import pl.szczodrzynski.edziennik.data.api.edziennik.edudziennik.DataEdudziennik import pl.szczodrzynski.edziennik.data.api.models.ApiError +import pl.szczodrzynski.edziennik.utils.Utils.d open class EdudziennikWeb(open val data: DataEdudziennik) { companion object { - private const val TAG = "TemplateWeb" + private const val TAG = "EdudziennikWeb" } val profileId @@ -22,24 +26,51 @@ open class EdudziennikWeb(open val data: DataEdudziennik) { 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 + fun webGet(tag: String, endpoint: String, onSuccess: (text: String) -> Unit) { + val url = "https://dziennikel.appspot.com/" + when (endpoint.endsWith('/') || endpoint.isEmpty()) { + true -> endpoint + else -> "$endpoint/" } - onSuccess(json) + d(tag, "Request: Edudziennik/Web - $url") + + val callback = object : TextCallbackHandler() { + override fun onSuccess(text: String?, response: Response?) { + if (text == null || response == null) { + data.error(ApiError(TAG, ERROR_RESPONSE_EMPTY) + .withResponse(response)) + return + } + + onSuccess(text) + } + + override fun onFailure(response: Response?, throwable: Throwable?) { + data.error(ApiError(TAG, ERROR_REQUEST_FAILURE) + .withResponse(response) + .withThrowable(throwable)) + } + } + + data.app.cookieJar.saveFromResponse(null, listOf( + Cookie.Builder() + .name("sessionid") + .value(data.webSessionId!!) + .domain("dziennikel.appspot.com") + .secure().httpOnly().build(), + Cookie.Builder() + .name("semester") + .value((profile?.currentSemester ?: 1).toString()) + .domain("dziennikel.appspot.com") + .secure().httpOnly().build() + )) + + Request.builder() + .url(url) + .userAgent(EDUDZIENNIK_USER_AGENT) + .get() + .callback(callback) + .build() + .enqueue() } } 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 index fa5f2c4c..c3e392ad 100644 --- 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 @@ -4,28 +4,52 @@ package pl.szczodrzynski.edziennik.data.api.edziennik.edudziennik.firstlogin +import org.greenrobot.eventbus.EventBus +import org.jsoup.Jsoup +import pl.szczodrzynski.edziennik.data.api.Regexes.EDUDZIENNIK_STUDENT_ID 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.api.edziennik.edudziennik.login.EdudziennikLoginWeb +import pl.szczodrzynski.edziennik.data.api.events.FirstLoginFinishedEvent import pl.szczodrzynski.edziennik.data.db.modules.profiles.Profile +import pl.szczodrzynski.edziennik.fixName +import pl.szczodrzynski.edziennik.get +import pl.szczodrzynski.edziennik.getShortName +import pl.szczodrzynski.edziennik.utils.Utils class EdudziennikFirstLogin(val data: DataEdudziennik, val onSuccess: () -> Unit) { companion object { - private const val TAG = "TemplateFirstLogin" + private const val TAG = "EdudziennikFirstLogin" } 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") + EdudziennikLoginWeb(data) { + web.webGet(TAG, "") { text -> + val doc = Jsoup.parse(text) + val accountName = doc.select("#user_dn").first().text().fixName() + + doc.select("ul ul > li").first().children().forEach { + val studentId = EDUDZIENNIK_STUDENT_ID.find(it.attr("href"))?.get(1) + val studentName = it.text().fixName() + + val profile = Profile() + profile.studentNameLong = studentName + profile.studentNameShort = studentName.getShortName() + profile.accountNameLong = if (studentName == accountName) null else accountName + profile.studentSchoolYear = Utils.getCurrentSchoolYear() + profile.name = studentName + profile.subname = data.loginEmail + profile.empty = true + profile.putStudentData("studentId", studentId) + profileList.add(profile) + } EventBus.getDefault().post(FirstLoginFinishedEvent(profileList, data.loginStore)) onSuccess() } - }*/ + } } } 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 index ac23611c..8387a775 100644 --- 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 @@ -4,12 +4,15 @@ 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 im.wangchao.mhttp.Request +import im.wangchao.mhttp.Response +import im.wangchao.mhttp.callback.TextCallbackHandler +import pl.szczodrzynski.edziennik.data.api.* import pl.szczodrzynski.edziennik.data.api.edziennik.edudziennik.DataEdudziennik import pl.szczodrzynski.edziennik.data.api.models.ApiError +import pl.szczodrzynski.edziennik.getUnixDate +import pl.szczodrzynski.edziennik.isNotNullNorEmpty +import pl.szczodrzynski.edziennik.utils.Utils.d class EdudziennikLoginWeb(val data: DataEdudziennik, val onSuccess: () -> Unit) { companion object { @@ -17,24 +20,12 @@ class EdudziennikLoginWeb(val data: DataEdudziennik, val onSuccess: () -> Unit) } 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) { + data.app.cookieJar.clearForDomain("dziennikel.appspot.com") + if (data.loginEmail.isNotNullNorEmpty() && data.loginPassword.isNotNullNorEmpty()) { loginWithCredentials() } else { @@ -43,11 +34,64 @@ class EdudziennikLoginWeb(val data: DataEdudziennik, val onSuccess: () -> Unit) } }} - fun loginWithCredentials() { - // succeed immediately + private fun loginWithCredentials() { + d(TAG, "Request: Edudziennik/Login/Web - https://dziennikel.appspot.com/login/?next=/") - data.webCookie = "ThisIsACookie" - data.webExpiryTime = currentTimeUnix() + 45 * 60 /* 45min */ - onSuccess() + val callback = object : TextCallbackHandler() { + override fun onSuccess(text: String?, response: Response?) { + if (text == null || response == null) { + data.error(ApiError(TAG, ERROR_RESPONSE_EMPTY) + .withResponse(response)) + return + } + + val url = response.raw().request().url().toString() + + if (!url.contains("Student")) { + when { + text.contains("Wprowadzono nieprawidłową nazwę użytkownika lub hasło.") -> ERROR_LOGIN_EDUDZIENNIK_WEB_INVALID_LOGIN + else -> ERROR_LOGIN_EDUDZIENNIK_WEB_OTHER + }.let { errorCode -> + data.error(ApiError(TAG, errorCode) + .withApiResponse(text) + .withResponse(response)) + return + } + } + + val cookies = data.app.cookieJar.getForDomain("dziennikel.appspot.com") + val sessionId = cookies.firstOrNull { it.name() == "sessionid" }?.value() + + if (sessionId == null) { + data.error(ApiError(TAG, ERROR_LOGIN_EDUDZIENNIK_WEB_NO_SESSION_ID) + .withResponse(response) + .withApiResponse(text)) + return + } + + data.webSessionId = sessionId + data.webSessionIdExpiryTime = response.getUnixDate() + 45 * 60 /* 45 min */ + onSuccess() + } + + override fun onFailure(response: Response?, throwable: Throwable?) { + data.error(ApiError(TAG, ERROR_REQUEST_FAILURE) + .withResponse(response) + .withThrowable(throwable)) + } + } + + Request.builder() + .url("https://dziennikel.appspot.com/login/?next=/") + .userAgent(EDUDZIENNIK_USER_AGENT) + .contentType("application/x-www-form-urlencoded") + .addParameter("email", data.loginEmail) + .addParameter("password", data.loginPassword) + .addParameter("auth_method", "password") + .addParameter("next", "/") + .post() + .callback(callback) + .build() + .enqueue() } } diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/mobidziennik/firstlogin/MobidziennikFirstLogin.kt b/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/mobidziennik/firstlogin/MobidziennikFirstLogin.kt index 716f4937..e69aba2f 100644 --- a/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/mobidziennik/firstlogin/MobidziennikFirstLogin.kt +++ b/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/mobidziennik/firstlogin/MobidziennikFirstLogin.kt @@ -7,7 +7,7 @@ import pl.szczodrzynski.edziennik.data.api.edziennik.mobidziennik.login.Mobidzie import pl.szczodrzynski.edziennik.data.api.events.FirstLoginFinishedEvent import pl.szczodrzynski.edziennik.data.db.modules.profiles.Profile import pl.szczodrzynski.edziennik.fixName -import pl.szczodrzynski.edziennik.utils.models.Date +import pl.szczodrzynski.edziennik.utils.Utils class MobidziennikFirstLogin(val data: DataMobidziennik, val onSuccess: () -> Unit) { companion object { @@ -39,12 +39,11 @@ class MobidziennikFirstLogin(val data: DataMobidziennik, val onSuccess: () -> Un if (student1.size == 2) return@forEach - val today = Date.getToday() val profile = Profile() profile.studentNameLong = "${student1[2]} ${student1[4]}".fixName() profile.studentNameShort = "${student1[2]} ${student1[4][0]}.".fixName() profile.accountNameLong = if (accountNameLong == profile.studentNameLong) null else accountNameLong - profile.studentSchoolYear = "${today.year}/${today.year+1}" + profile.studentSchoolYear = Utils.getCurrentSchoolYear() profile.name = profile.studentNameLong profile.subname = data.loginUsername profile.empty = true diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/data/db/modules/profiles/ProfileFull.kt b/app/src/main/java/pl/szczodrzynski/edziennik/data/db/modules/profiles/ProfileFull.kt index ecbdafdb..67f636e6 100644 --- a/app/src/main/java/pl/szczodrzynski/edziennik/data/db/modules/profiles/ProfileFull.kt +++ b/app/src/main/java/pl/szczodrzynski/edziennik/data/db/modules/profiles/ProfileFull.kt @@ -12,6 +12,7 @@ import pl.szczodrzynski.edziennik.MainActivity.Companion.DRAWER_ITEM_GRADES import pl.szczodrzynski.edziennik.MainActivity.Companion.DRAWER_ITEM_HOMEWORK import pl.szczodrzynski.edziennik.MainActivity.Companion.DRAWER_ITEM_MESSAGES import pl.szczodrzynski.edziennik.MainActivity.Companion.DRAWER_ITEM_TIMETABLE +import pl.szczodrzynski.edziennik.data.api.LOGIN_TYPE_EDUDZIENNIK import pl.szczodrzynski.edziennik.data.db.modules.login.LoginStore import pl.szczodrzynski.edziennik.data.db.modules.login.LoginStore.* import java.util.* @@ -57,19 +58,7 @@ class ProfileFull : Profile { fragmentIds.add(DRAWER_ITEM_ATTENDANCE) return fragmentIds } - LOGIN_TYPE_LIBRUS -> { - fragmentIds = ArrayList() - fragmentIds.add(DRAWER_ITEM_TIMETABLE) - fragmentIds.add(DRAWER_ITEM_AGENDA) - fragmentIds.add(DRAWER_ITEM_GRADES) - fragmentIds.add(DRAWER_ITEM_MESSAGES) - fragmentIds.add(DRAWER_ITEM_HOMEWORK) - fragmentIds.add(DRAWER_ITEM_BEHAVIOUR) - fragmentIds.add(DRAWER_ITEM_ATTENDANCE) - fragmentIds.add(DRAWER_ITEM_ANNOUNCEMENTS) - return fragmentIds - } - LOGIN_TYPE_IUCZNIOWIE -> { + LOGIN_TYPE_LIBRUS, LOGIN_TYPE_IUCZNIOWIE, LOGIN_TYPE_EDUDZIENNIK -> { fragmentIds = ArrayList() fragmentIds.add(DRAWER_ITEM_TIMETABLE) fragmentIds.add(DRAWER_ITEM_AGENDA) 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 index a23009c4..2d8e2920 100644 --- 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 @@ -11,15 +11,27 @@ import android.view.ViewGroup import androidx.fragment.app.Fragment import androidx.navigation.NavController import androidx.navigation.Navigation +import kotlinx.coroutines.CoroutineScope +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.Job +import kotlinx.coroutines.launch import pl.szczodrzynski.edziennik.App import pl.szczodrzynski.edziennik.R +import pl.szczodrzynski.edziennik.data.api.ERROR_LOGIN_EDUDZIENNIK_WEB_INVALID_LOGIN +import pl.szczodrzynski.edziennik.data.api.LOGIN_TYPE_EDUDZIENNIK import pl.szczodrzynski.edziennik.databinding.FragmentLoginEdudziennikBinding +import pl.szczodrzynski.edziennik.startCoroutineTimer import pl.szczodrzynski.edziennik.ui.modules.error.ErrorSnackbar +import kotlin.coroutines.CoroutineContext -class LoginEdudziennikFragment : Fragment() { +class LoginEdudziennikFragment : Fragment(), CoroutineScope { private val app by lazy { activity?.application as App? } + private var job = Job() + override val coroutineContext: CoroutineContext + get() = job + Dispatchers.Main + private lateinit var b: FragmentLoginEdudziennikBinding private lateinit var nav: NavController @@ -35,7 +47,51 @@ class LoginEdudziennikFragment : Fragment() { return b.root } - override fun onViewCreated(view: View, savedInstanceState: Bundle?) { + override fun onViewCreated(view: View, savedInstanceState: Bundle?) { launch { + startCoroutineTimer(delayMillis = 100) { + val error = LoginActivity.error + if (error != null) { + when (error.errorCode) { + ERROR_LOGIN_EDUDZIENNIK_WEB_INVALID_LOGIN -> + b.loginPasswordLayout.error = getString(R.string.login_error_incorrect_login_or_password) + } + + errorSnackbar.addError(error) + LoginActivity.error = null + } + } + + b.backButton.setOnClickListener { nav.navigateUp() } + b.loginButton.setOnClickListener { login() } + }} + + private fun login() { + var errors = false + + b.loginEmailLayout.error = null + b.loginPasswordLayout.error = null + + val emailEditable = b.loginEmail.text + val passwordEditable = b.loginPassword.text + + if (emailEditable.isNullOrBlank()) { + b.loginEmailLayout.error = getString(R.string.login_error_no_email) + errors = true + } + + if (passwordEditable.isNullOrBlank()) { + b.loginPasswordLayout.error = getString(R.string.login_error_no_password) + errors = true + } + + if (errors) + return + + nav.navigate(R.id.loginProgressFragment, Bundle().apply { + putInt("loginType", LOGIN_TYPE_EDUDZIENNIK) + putString("email", emailEditable.toString()) + putString("password", passwordEditable.toString()) + }, LoginActivity.navOptions) } } diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/ui/modules/login/LoginSummaryFragment.java b/app/src/main/java/pl/szczodrzynski/edziennik/ui/modules/login/LoginSummaryFragment.java index cc1df127..f82aa249 100644 --- a/app/src/main/java/pl/szczodrzynski/edziennik/ui/modules/login/LoginSummaryFragment.java +++ b/app/src/main/java/pl/szczodrzynski/edziennik/ui/modules/login/LoginSummaryFragment.java @@ -31,6 +31,7 @@ import pl.szczodrzynski.edziennik.databinding.RowLoginProfileListItemBinding; import static pl.szczodrzynski.edziennik.data.api.LoginMethodsKt.LOGIN_MODE_LIBRUS_EMAIL; import static pl.szczodrzynski.edziennik.data.api.LoginMethodsKt.LOGIN_MODE_VULCAN_API; import static pl.szczodrzynski.edziennik.data.api.LoginMethodsKt.LOGIN_MODE_VULCAN_WEB; +import static pl.szczodrzynski.edziennik.data.api.LoginMethodsKt.LOGIN_TYPE_EDUDZIENNIK; import static pl.szczodrzynski.edziennik.data.api.LoginMethodsKt.LOGIN_TYPE_IDZIENNIK; import static pl.szczodrzynski.edziennik.data.api.LoginMethodsKt.LOGIN_TYPE_LIBRUS; import static pl.szczodrzynski.edziennik.data.api.LoginMethodsKt.LOGIN_TYPE_MOBIDZIENNIK; @@ -225,6 +226,9 @@ public class LoginSummaryFragment extends Fragment { imageRes = R.drawable.logo_dzienniczek; } } + else if (m.loginType == LOGIN_TYPE_EDUDZIENNIK) { + imageRes = R.drawable.logo_edudziennik; + } if (imageRes != 0) { b.registerIcon.setImageResource(imageRes); } diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/utils/Utils.java b/app/src/main/java/pl/szczodrzynski/edziennik/utils/Utils.java index 776488db..df78e3a1 100644 --- a/app/src/main/java/pl/szczodrzynski/edziennik/utils/Utils.java +++ b/app/src/main/java/pl/szczodrzynski/edziennik/utils/Utils.java @@ -39,6 +39,7 @@ import java.io.InputStream; import java.io.InputStreamReader; import java.io.OutputStreamWriter; import java.nio.channels.FileChannel; +import java.nio.charset.StandardCharsets; import java.security.GeneralSecurityException; import java.security.InvalidKeyException; import java.security.Key; @@ -418,7 +419,7 @@ public class Utils { byte[] iv = new byte[16]; IvParameterSpec ivSpec = new IvParameterSpec(iv); cipher.init(Cipher.ENCRYPT_MODE, keyObj, ivSpec); - byte [] encryptedByteValue = cipher.doFinal(value.getBytes("utf-8")); + byte [] encryptedByteValue = cipher.doFinal(value.getBytes(StandardCharsets.UTF_8)); String encryptedValue64 = Base64.encodeToString(encryptedByteValue, Base64.DEFAULT); return encryptedValue64; @@ -433,7 +434,7 @@ public class Utils { cipher.init(Cipher.DECRYPT_MODE, keyObj, ivSpec); byte[] decryptedValue64 = Base64.decode(value, Base64.DEFAULT); byte [] decryptedByteValue = cipher.doFinal(decryptedValue64); - String decryptedValue = new String(decryptedByteValue,"utf-8"); + String decryptedValue = new String(decryptedByteValue, StandardCharsets.UTF_8); return decryptedValue; } @@ -612,7 +613,7 @@ public class Utils { if (sourceFile.isDirectory()) { zipSubFolder(out, sourceFile, sourceFile.getParent().length()); } else { - byte data[] = new byte[BUFFER]; + byte[] data = new byte[BUFFER]; FileInputStream fi = new FileInputStream(sourcePath); origin = new BufferedInputStream(fi, BUFFER); ZipEntry entry = new ZipEntry(getLastPathComponent(sourcePath)); @@ -648,7 +649,7 @@ public class Utils { if (file.isDirectory()) { zipSubFolder(out, file, basePathLength); } else { - byte data[] = new byte[BUFFER]; + byte[] data = new byte[BUFFER]; String unmodifiedFilePath = file.getPath(); String relativePath = unmodifiedFilePath .substring(basePathLength); @@ -797,4 +798,10 @@ public class Utils { DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss", Locale.getDefault()); return dateFormat.format(date); } + + public static String getCurrentSchoolYear() { + pl.szczodrzynski.edziennik.utils.models.Date today = pl.szczodrzynski.edziennik.utils.models.Date.getToday(); + if (today.month >= 9) return today.year + "/" + (today.year + 1); + else return (today.year - 1) + "/" + today.year; + } } diff --git a/app/src/main/res/drawable-hdpi/login_logo_edudziennik.png b/app/src/main/res/drawable/login_logo_edudziennik.png similarity index 100% rename from app/src/main/res/drawable-hdpi/login_logo_edudziennik.png rename to app/src/main/res/drawable/login_logo_edudziennik.png diff --git a/app/src/main/res/drawable/logo_edudziennik.png b/app/src/main/res/drawable/logo_edudziennik.png new file mode 100644 index 00000000..040a8ef2 Binary files /dev/null and b/app/src/main/res/drawable/logo_edudziennik.png differ