mirror of
https://github.com/szkolny-eu/szkolny-android.git
synced 2025-02-22 22:44:45 +01:00
[Edudziennik] Add first login.
This commit is contained in:
parent
90e7b1e9c7
commit
ec14ba76c9
@ -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
|
||||||
|
@ -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
|
||||||
|
@ -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()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -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/"
|
||||||
}
|
}
|
||||||
|
@ -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)
|
|
||||||
}
|
|
||||||
}
|
|
@ -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()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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()
|
||||||
}
|
}
|
||||||
}*/
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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
|
||||||
|
@ -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)
|
||||||
|
@ -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)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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);
|
||||||
}
|
}
|
||||||
|
@ -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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Before Width: | Height: | Size: 9.8 KiB After Width: | Height: | Size: 9.8 KiB |
BIN
app/src/main/res/drawable/logo_edudziennik.png
Normal file
BIN
app/src/main/res/drawable/logo_edudziennik.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 1.8 KiB |
Loading…
x
Reference in New Issue
Block a user