[Edudziennik] Add first login.

This commit is contained in:
Kacper Ziubryniewicz 2019-12-23 15:15:38 +01:00
parent 90e7b1e9c7
commit ec14ba76c9
15 changed files with 283 additions and 158 deletions

View File

@ -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_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_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_PUSH = "mobile-api/Uczen.v3.Uczen/UstawPushToken"
val EDUDZIENNIK_USER_AGENT = SYSTEM_USER_AGENT

View File

@ -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_ACCESS_DENIED = 450
const val ERROR_IDZIENNIK_API_OTHER = 451 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 ERROR_TEMPLATE_WEB_OTHER = 801
const val EXCEPTION_API_TASK = 900 const val EXCEPTION_API_TASK = 900

View File

@ -82,4 +82,10 @@ object Regexes {
val LIBRUS_ATTACHMENT_KEY by lazy { val LIBRUS_ATTACHMENT_KEY by lazy {
"""singleUseKey=([0-9A-f_]+)""".toRegex() """singleUseKey=([0-9A-f_]+)""".toRegex()
} }
val EDUDZIENNIK_STUDENT_ID by lazy {
"""""".toRegex()
}
} }

View File

@ -4,11 +4,9 @@
package pl.szczodrzynski.edziennik.data.api.edziennik.edudziennik package pl.szczodrzynski.edziennik.data.api.edziennik.edudziennik
import okhttp3.Cookie
import pl.szczodrzynski.edziennik.App import pl.szczodrzynski.edziennik.App
import pl.szczodrzynski.edziennik.currentTimeUnix import pl.szczodrzynski.edziennik.currentTimeUnix
import pl.szczodrzynski.edziennik.data.api.LOGIN_METHOD_TEMPLATE_API import pl.szczodrzynski.edziennik.data.api.LOGIN_METHOD_EDUDZIENNIK_WEB
import pl.szczodrzynski.edziennik.data.api.LOGIN_METHOD_TEMPLATE_WEB
import pl.szczodrzynski.edziennik.data.api.models.Data import pl.szczodrzynski.edziennik.data.api.models.Data
import pl.szczodrzynski.edziennik.data.db.modules.login.LoginStore import pl.szczodrzynski.edziennik.data.db.modules.login.LoginStore
import pl.szczodrzynski.edziennik.data.db.modules.profiles.Profile 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) { class DataEdudziennik(app: App, profile: Profile?, loginStore: LoginStore) : Data(app, profile, loginStore) {
fun isWebLoginValid() = webExpiryTime-30 > currentTimeUnix() && webCookie.isNotNullNorEmpty() fun isWebLoginValid() = webSessionIdExpiryTime-30 > currentTimeUnix() && webSessionId.isNotNullNorEmpty()
fun isApiLoginValid() = apiExpiryTime-30 > currentTimeUnix() && apiToken.isNotNullNorEmpty()
override fun satisfyLoginMethods() { override fun satisfyLoginMethods() {
loginMethods.clear() loginMethods.clear()
if (isWebLoginValid()) { if (isWebLoginValid()) {
loginMethods += LOGIN_METHOD_TEMPLATE_WEB loginMethods += LOGIN_METHOD_EDUDZIENNIK_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 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 private var mWebSessionId: String? = null
var webCookie: String? var webSessionId: String?
get() { mWebCookie = mWebCookie ?: profile?.getStudentData("webCookie", null); return mWebCookie } get() { mWebSessionId = mWebSessionId ?: loginStore.getLoginData("sessionId", null); return mWebSessionId }
set(value) { profile?.putStudentData("webCookie", value) ?: return; mWebCookie = value } set(value) { loginStore.putLoginData("sessionId", value); mWebSessionId = value }
private var mWebExpiryTime: Long? = null private var mWebSessionIdExpiryTime: Long? = null
var webExpiryTime: Long var webSessionIdExpiryTime: Long
get() { mWebExpiryTime = mWebExpiryTime ?: profile?.getStudentData("webExpiryTime", 0L); return mWebExpiryTime ?: 0L } get() { mWebSessionIdExpiryTime = mWebSessionIdExpiryTime ?: loginStore.getLoginData("webSessionIdExpiryTime", 0L); return mWebSessionIdExpiryTime ?: 0L }
set(value) { profile?.putStudentData("webExpiryTime", value) ?: return; mWebExpiryTime = value } set(value) { loginStore.putLoginData("webSessionIdExpiryTime", value); mWebSessionIdExpiryTime = value }
/* _ val studentEndpoint: String
/\ (_) get() = "Students/$studentId/"
/ \ _ __ _
/ /\ \ | '_ \| |
/ ____ \| |_) | |
/_/ \_\ .__/|_|
| |
|*/
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 val schoolEndpoint: String
var apiExpiryTime: Long get() = "Schools/$schoolId/"
get() { mApiExpiryTime = mApiExpiryTime ?: profile?.getStudentData("apiExpiryTime", 0L); return mApiExpiryTime ?: 0L }
set(value) { profile?.putStudentData("apiExpiryTime", value) ?: return; mApiExpiryTime = value } val courseEndpoint: String
get() = "Schools/$courseId/"
} }

View File

@ -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)
}
}

View File

@ -4,16 +4,20 @@
package pl.szczodrzynski.edziennik.data.api.edziennik.edudziennik.data package pl.szczodrzynski.edziennik.data.api.edziennik.edudziennik.data
import com.google.gson.JsonObject import im.wangchao.mhttp.Request
import pl.szczodrzynski.edziennik.currentTimeUnix import im.wangchao.mhttp.Response
import pl.szczodrzynski.edziennik.data.api.ERROR_TEMPLATE_WEB_OTHER import im.wangchao.mhttp.callback.TextCallbackHandler
import pl.szczodrzynski.edziennik.data.api.GET 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.edziennik.edudziennik.DataEdudziennik
import pl.szczodrzynski.edziennik.data.api.models.ApiError import pl.szczodrzynski.edziennik.data.api.models.ApiError
import pl.szczodrzynski.edziennik.utils.Utils.d
open class EdudziennikWeb(open val data: DataEdudziennik) { open class EdudziennikWeb(open val data: DataEdudziennik) {
companion object { companion object {
private const val TAG = "TemplateWeb" private const val TAG = "EdudziennikWeb"
} }
val profileId val profileId
@ -22,24 +26,51 @@ open class EdudziennikWeb(open val data: DataEdudziennik) {
val profile val profile
get() = data.profile get() = data.profile
/** fun webGet(tag: String, endpoint: String, onSuccess: (text: String) -> Unit) {
* This will be used by all TemplateWeb* endpoints. val url = "https://dziennikel.appspot.com/" + when (endpoint.endsWith('/') || endpoint.isEmpty()) {
* true -> endpoint
* You can customize this method's parameters to best fit the implemented e-register. else -> "$endpoint/"
* 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) 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()
} }
} }

View File

@ -4,28 +4,52 @@
package pl.szczodrzynski.edziennik.data.api.edziennik.edudziennik.firstlogin 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.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.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.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) { class EdudziennikFirstLogin(val data: DataEdudziennik, val onSuccess: () -> Unit) {
companion object { companion object {
private const val TAG = "TemplateFirstLogin" private const val TAG = "EdudziennikFirstLogin"
} }
private val web = EdudziennikWeb(data) private val web = EdudziennikWeb(data)
private val api = EdudziennikApi(data)
private val profileList = mutableListOf<Profile>() private val profileList = mutableListOf<Profile>()
init { init {
/*TemplateLoginWeb(data) { EdudziennikLoginWeb(data) {
web.webGet(TAG, "get all accounts") { text -> web.webGet(TAG, "") { text ->
//val accounts = json.getJsonArray("accounts") 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)) EventBus.getDefault().post(FirstLoginFinishedEvent(profileList, data.loginStore))
onSuccess() onSuccess()
} }
}*/ }
} }
} }

View File

@ -4,12 +4,15 @@
package pl.szczodrzynski.edziennik.data.api.edziennik.edudziennik.login package pl.szczodrzynski.edziennik.data.api.edziennik.edudziennik.login
import okhttp3.Cookie import im.wangchao.mhttp.Request
import pl.szczodrzynski.edziennik.currentTimeUnix import im.wangchao.mhttp.Response
import pl.szczodrzynski.edziennik.data.api.ERROR_LOGIN_DATA_MISSING import im.wangchao.mhttp.callback.TextCallbackHandler
import pl.szczodrzynski.edziennik.data.api.ERROR_PROFILE_MISSING import pl.szczodrzynski.edziennik.data.api.*
import pl.szczodrzynski.edziennik.data.api.edziennik.edudziennik.DataEdudziennik import pl.szczodrzynski.edziennik.data.api.edziennik.edudziennik.DataEdudziennik
import pl.szczodrzynski.edziennik.data.api.models.ApiError 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) { class EdudziennikLoginWeb(val data: DataEdudziennik, val onSuccess: () -> Unit) {
companion object { companion object {
@ -17,24 +20,12 @@ class EdudziennikLoginWeb(val data: DataEdudziennik, val onSuccess: () -> Unit)
} }
init { run { init { run {
if (data.profile == null) {
data.error(ApiError(TAG, ERROR_PROFILE_MISSING))
return@run
}
if (data.isWebLoginValid()) { if (data.isWebLoginValid()) {
data.app.cookieJar.saveFromResponse(null, listOf(
Cookie.Builder()
.name("AuthCookie")
.value(data.webCookie!!)
.domain("eregister.example.com")
.secure().httpOnly().build()
))
onSuccess() onSuccess()
} }
else { else {
data.app.cookieJar.clearForDomain("eregister.example.com") data.app.cookieJar.clearForDomain("dziennikel.appspot.com")
if (/*data.webLogin != null && data.webPassword != null && */true) { if (data.loginEmail.isNotNullNorEmpty() && data.loginPassword.isNotNullNorEmpty()) {
loginWithCredentials() loginWithCredentials()
} }
else { else {
@ -43,11 +34,64 @@ class EdudziennikLoginWeb(val data: DataEdudziennik, val onSuccess: () -> Unit)
} }
}} }}
fun loginWithCredentials() { private fun loginWithCredentials() {
// succeed immediately d(TAG, "Request: Edudziennik/Login/Web - https://dziennikel.appspot.com/login/?next=/")
data.webCookie = "ThisIsACookie" val callback = object : TextCallbackHandler() {
data.webExpiryTime = currentTimeUnix() + 45 * 60 /* 45min */ override fun onSuccess(text: String?, response: Response?) {
onSuccess() 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()
} }
} }

View File

@ -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.api.events.FirstLoginFinishedEvent
import pl.szczodrzynski.edziennik.data.db.modules.profiles.Profile import pl.szczodrzynski.edziennik.data.db.modules.profiles.Profile
import pl.szczodrzynski.edziennik.fixName 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) { class MobidziennikFirstLogin(val data: DataMobidziennik, val onSuccess: () -> Unit) {
companion object { companion object {
@ -39,12 +39,11 @@ class MobidziennikFirstLogin(val data: DataMobidziennik, val onSuccess: () -> Un
if (student1.size == 2) if (student1.size == 2)
return@forEach return@forEach
val today = Date.getToday()
val profile = Profile() val profile = Profile()
profile.studentNameLong = "${student1[2]} ${student1[4]}".fixName() profile.studentNameLong = "${student1[2]} ${student1[4]}".fixName()
profile.studentNameShort = "${student1[2]} ${student1[4][0]}.".fixName() profile.studentNameShort = "${student1[2]} ${student1[4][0]}.".fixName()
profile.accountNameLong = if (accountNameLong == profile.studentNameLong) null else accountNameLong 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.name = profile.studentNameLong
profile.subname = data.loginUsername profile.subname = data.loginUsername
profile.empty = true profile.empty = true

View File

@ -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_HOMEWORK
import pl.szczodrzynski.edziennik.MainActivity.Companion.DRAWER_ITEM_MESSAGES import pl.szczodrzynski.edziennik.MainActivity.Companion.DRAWER_ITEM_MESSAGES
import pl.szczodrzynski.edziennik.MainActivity.Companion.DRAWER_ITEM_TIMETABLE 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 pl.szczodrzynski.edziennik.data.db.modules.login.LoginStore.* import pl.szczodrzynski.edziennik.data.db.modules.login.LoginStore.*
import java.util.* import java.util.*
@ -57,19 +58,7 @@ class ProfileFull : Profile {
fragmentIds.add(DRAWER_ITEM_ATTENDANCE) fragmentIds.add(DRAWER_ITEM_ATTENDANCE)
return fragmentIds return fragmentIds
} }
LOGIN_TYPE_LIBRUS -> { LOGIN_TYPE_LIBRUS, LOGIN_TYPE_IUCZNIOWIE, LOGIN_TYPE_EDUDZIENNIK -> {
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 -> {
fragmentIds = ArrayList() fragmentIds = ArrayList()
fragmentIds.add(DRAWER_ITEM_TIMETABLE) fragmentIds.add(DRAWER_ITEM_TIMETABLE)
fragmentIds.add(DRAWER_ITEM_AGENDA) fragmentIds.add(DRAWER_ITEM_AGENDA)

View File

@ -11,15 +11,27 @@ import android.view.ViewGroup
import androidx.fragment.app.Fragment import androidx.fragment.app.Fragment
import androidx.navigation.NavController import androidx.navigation.NavController
import androidx.navigation.Navigation 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.App
import pl.szczodrzynski.edziennik.R 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.databinding.FragmentLoginEdudziennikBinding
import pl.szczodrzynski.edziennik.startCoroutineTimer
import pl.szczodrzynski.edziennik.ui.modules.error.ErrorSnackbar 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 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 b: FragmentLoginEdudziennikBinding
private lateinit var nav: NavController private lateinit var nav: NavController
@ -35,7 +47,51 @@ class LoginEdudziennikFragment : Fragment() {
return b.root 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)
} }
} }

View File

@ -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_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_API;
import static pl.szczodrzynski.edziennik.data.api.LoginMethodsKt.LOGIN_MODE_VULCAN_WEB; 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_IDZIENNIK;
import static pl.szczodrzynski.edziennik.data.api.LoginMethodsKt.LOGIN_TYPE_LIBRUS; import static pl.szczodrzynski.edziennik.data.api.LoginMethodsKt.LOGIN_TYPE_LIBRUS;
import static pl.szczodrzynski.edziennik.data.api.LoginMethodsKt.LOGIN_TYPE_MOBIDZIENNIK; 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; imageRes = R.drawable.logo_dzienniczek;
} }
} }
else if (m.loginType == LOGIN_TYPE_EDUDZIENNIK) {
imageRes = R.drawable.logo_edudziennik;
}
if (imageRes != 0) { if (imageRes != 0) {
b.registerIcon.setImageResource(imageRes); b.registerIcon.setImageResource(imageRes);
} }

View File

@ -39,6 +39,7 @@ import java.io.InputStream;
import java.io.InputStreamReader; import java.io.InputStreamReader;
import java.io.OutputStreamWriter; import java.io.OutputStreamWriter;
import java.nio.channels.FileChannel; import java.nio.channels.FileChannel;
import java.nio.charset.StandardCharsets;
import java.security.GeneralSecurityException; import java.security.GeneralSecurityException;
import java.security.InvalidKeyException; import java.security.InvalidKeyException;
import java.security.Key; import java.security.Key;
@ -418,7 +419,7 @@ public class Utils {
byte[] iv = new byte[16]; byte[] iv = new byte[16];
IvParameterSpec ivSpec = new IvParameterSpec(iv); IvParameterSpec ivSpec = new IvParameterSpec(iv);
cipher.init(Cipher.ENCRYPT_MODE, keyObj, ivSpec); 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); String encryptedValue64 = Base64.encodeToString(encryptedByteValue, Base64.DEFAULT);
return encryptedValue64; return encryptedValue64;
@ -433,7 +434,7 @@ public class Utils {
cipher.init(Cipher.DECRYPT_MODE, keyObj, ivSpec); cipher.init(Cipher.DECRYPT_MODE, keyObj, ivSpec);
byte[] decryptedValue64 = Base64.decode(value, Base64.DEFAULT); byte[] decryptedValue64 = Base64.decode(value, Base64.DEFAULT);
byte [] decryptedByteValue = cipher.doFinal(decryptedValue64); byte [] decryptedByteValue = cipher.doFinal(decryptedValue64);
String decryptedValue = new String(decryptedByteValue,"utf-8"); String decryptedValue = new String(decryptedByteValue, StandardCharsets.UTF_8);
return decryptedValue; return decryptedValue;
} }
@ -612,7 +613,7 @@ public class Utils {
if (sourceFile.isDirectory()) { if (sourceFile.isDirectory()) {
zipSubFolder(out, sourceFile, sourceFile.getParent().length()); zipSubFolder(out, sourceFile, sourceFile.getParent().length());
} else { } else {
byte data[] = new byte[BUFFER]; byte[] data = new byte[BUFFER];
FileInputStream fi = new FileInputStream(sourcePath); FileInputStream fi = new FileInputStream(sourcePath);
origin = new BufferedInputStream(fi, BUFFER); origin = new BufferedInputStream(fi, BUFFER);
ZipEntry entry = new ZipEntry(getLastPathComponent(sourcePath)); ZipEntry entry = new ZipEntry(getLastPathComponent(sourcePath));
@ -648,7 +649,7 @@ public class Utils {
if (file.isDirectory()) { if (file.isDirectory()) {
zipSubFolder(out, file, basePathLength); zipSubFolder(out, file, basePathLength);
} else { } else {
byte data[] = new byte[BUFFER]; byte[] data = new byte[BUFFER];
String unmodifiedFilePath = file.getPath(); String unmodifiedFilePath = file.getPath();
String relativePath = unmodifiedFilePath String relativePath = unmodifiedFilePath
.substring(basePathLength); .substring(basePathLength);
@ -797,4 +798,10 @@ public class Utils {
DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss", Locale.getDefault()); DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss", Locale.getDefault());
return dateFormat.format(date); 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;
}
} }

View File

Before

Width:  |  Height:  |  Size: 9.8 KiB

After

Width:  |  Height:  |  Size: 9.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB