Try to login to studentplus module if there is a url to that module for selected school on homepage

This commit is contained in:
Mikołaj Pich 2024-01-18 17:13:47 +01:00
parent 7017d55c81
commit 06a2e33822
6 changed files with 48 additions and 68 deletions

View file

@ -16,7 +16,6 @@ import io.github.wulkanowy.sdk.scrapper.home.GovernmentUnit
import io.github.wulkanowy.sdk.scrapper.home.LuckyNumber
import io.github.wulkanowy.sdk.scrapper.homework.Homework
import io.github.wulkanowy.sdk.scrapper.login.LoginHelper
import io.github.wulkanowy.sdk.scrapper.login.UrlGenerator
import io.github.wulkanowy.sdk.scrapper.menu.Menu
import io.github.wulkanowy.sdk.scrapper.messages.Folder
import io.github.wulkanowy.sdk.scrapper.messages.Mailbox
@ -241,8 +240,8 @@ class Scrapper {
buildTag = buildTag,
emptyCookieJarIntercept = emptyCookieJarInterceptor,
userAgentTemplate = userAgentTemplate,
onUserLoggedIn = { studentModuleUrls ->
isEduOne = isCurrentLoginHasEduOne(studentModuleUrls)
isEduOneStudent = {
isEduOne = it
},
).apply {
appInterceptors.forEach { (interceptor, isNetwork) ->
@ -251,15 +250,6 @@ class Scrapper {
}
}
private fun isCurrentLoginHasEduOne(studentModuleUrls: List<String>): Boolean {
return studentModuleUrls.any {
it.startsWith(
prefix = serviceManager.urlGenerator.generate(UrlGenerator.Site.STUDENT_PLUS),
ignoreCase = true,
)
}
}
private val account by lazy { AccountRepository(serviceManager.getAccountService()) }
private val register by resettableLazy(changeManager) {

View file

@ -12,6 +12,7 @@ import io.github.wulkanowy.sdk.scrapper.exception.VulcanClientError
import io.github.wulkanowy.sdk.scrapper.getScriptParam
import io.github.wulkanowy.sdk.scrapper.login.ModuleHeaders
import io.github.wulkanowy.sdk.scrapper.login.NotLoggedInException
import io.github.wulkanowy.sdk.scrapper.login.UrlGenerator
import io.github.wulkanowy.sdk.scrapper.register.HomePageResponse
import io.github.wulkanowy.sdk.scrapper.repository.AccountRepository.Companion.SELECTOR_ADFS
import io.github.wulkanowy.sdk.scrapper.repository.AccountRepository.Companion.SELECTOR_ADFS_CARDS
@ -46,9 +47,9 @@ internal class AutoLoginInterceptor(
private val cookieJarCabinet: CookieJarCabinet,
private val emptyCookieJarIntercept: Boolean = false,
private val notLoggedInCallback: suspend () -> HomePageResponse,
private val fetchStudentCookies: () -> Pair<HttpUrl, Document>,
private val fetchMessagesCookies: () -> Pair<HttpUrl, Document>,
private val onUserLoggedIn: (studentModuleUrls: List<String>) -> Unit = {},
private val fetchModuleCookies: (UrlGenerator.Site) -> Pair<HttpUrl, Document>,
private val isEduOneStudent: (Boolean) -> Unit = {},
private val urlGenerator: UrlGenerator,
) : Interceptor {
companion object {
@ -85,16 +86,17 @@ internal class AutoLoginInterceptor(
try {
val homePageResponse = runBlocking { notLoggedInCallback() }
val studentModuleUrls = homePageResponse.studentSchools.map { it.attr("href") }
onUserLoggedIn(studentModuleUrls)
val isEduOne = isCurrentLoginHasEduOne(studentModuleUrls)
isEduOneStudent(isEduOne)
studentModuleHeaders = null
messagesModuleHeaders = null
val messages = runCatching { fetchMessagesCookies() }
.onFailure { logger.error("Error in messages login", it) }
.onSuccess { (url, doc) -> saveModuleHeaders(doc, url) }
val student = runCatching { fetchStudentCookies() }
.onFailure { logger.error("Error in student login", it) }
.onSuccess { (url, doc) -> saveModuleHeaders(doc, url) }
val messages = getModuleCookies(UrlGenerator.Site.MESSAGES)
val student = getModuleCookies(
site = if (isEduOne) {
UrlGenerator.Site.STUDENT_PLUS
} else UrlGenerator.Site.STUDENT,
)
when {
"wiadomosciplus" in uri.host -> messages.getOrThrow()
"uczen" in uri.host -> student.getOrThrow()
@ -129,6 +131,12 @@ internal class AutoLoginInterceptor(
return response
}
private fun getModuleCookies(site: UrlGenerator.Site): Result<Pair<HttpUrl, Document>> {
return runCatching { fetchModuleCookies(site) }
.onFailure { logger.error("Error in $site login", it) }
.onSuccess { (url, doc) -> saveModuleHeaders(doc, url) }
}
private fun saveModuleHeaders(doc: Document, url: HttpUrl) {
when {
"uonetplus-uczen" in url.host -> {
@ -151,6 +159,15 @@ internal class AutoLoginInterceptor(
}
}
private fun isCurrentLoginHasEduOne(studentModuleUrls: List<String>): Boolean {
return studentModuleUrls.any {
it.startsWith(
prefix = urlGenerator.generate(UrlGenerator.Site.STUDENT_PLUS),
ignoreCase = true,
)
}
}
private fun Request.attachModuleHeaders(): Request {
val headers = when {
"uonetplus-uczen" in url.host -> studentModuleHeaders

View file

@ -73,15 +73,15 @@ internal class LoginHelper(
return cert
}
fun loginStudent(): Pair<HttpUrl, Document> {
val studentPageUrl = urlGenerator.generate(UrlGenerator.Site.STUDENT) + "LoginEndpoint.aspx"
val startHtml = api.getModuleStart(studentPageUrl).execute().handleErrors().body().orEmpty()
fun loginModule(site: UrlGenerator.Site): Pair<HttpUrl, Document> {
val moduleUrl = urlGenerator.generate(site) + "LoginEndpoint.aspx"
val startHtml = api.getModuleStart(moduleUrl).execute().handleErrors().body().orEmpty()
val startDoc = Jsoup.parse(startHtml)
if ("Working" in startDoc.title()) {
val cert = certificateAdapter.fromHtml(startHtml)
val certResponseHtml = api.sendCertificateModule(
referer = urlGenerator.createReferer(UrlGenerator.Site.STUDENT),
referer = urlGenerator.createReferer(site),
url = cert.action,
certificate = mapOf(
"wa" to cert.wa,
@ -93,41 +93,12 @@ internal class LoginHelper(
if ("antiForgeryToken" !in certResponseHtml) {
throw IOException("Unknown module start page: ${certResponseDoc.title()}")
} else {
logger.debug("Student cookies fetch successfully!")
return studentPageUrl.toHttpUrl() to certResponseDoc
logger.debug("{} cookies fetch successfully!", site)
return moduleUrl.toHttpUrl() to Jsoup.parse(certResponseHtml)
}
} else {
logger.debug("Student cookies already fetched!")
return studentPageUrl.toHttpUrl() to startDoc
}
}
fun loginMessages(): Pair<HttpUrl, Document> {
val messagesPageUrl = urlGenerator.generate(UrlGenerator.Site.MESSAGES) + "LoginEndpoint.aspx"
val startHtml = api.getModuleStart(messagesPageUrl).execute().handleErrors().body().orEmpty()
val startDoc = Jsoup.parse(startHtml)
if ("Working" in startDoc.title()) {
val cert = certificateAdapter.fromHtml(startHtml)
val certResponseHtml = api.sendCertificateModule(
referer = urlGenerator.createReferer(UrlGenerator.Site.MESSAGES),
url = cert.action,
certificate = mapOf(
"wa" to cert.wa,
"wresult" to cert.wresult,
"wctx" to cert.wctx,
),
).execute().handleErrors().body().orEmpty()
val certResponseDoc = Jsoup.parse(certResponseHtml)
if ("antiForgeryToken" !in certResponseHtml) {
throw IOException("Unknown module start page: ${certResponseDoc.title()}")
} else {
logger.debug("Messages cookies fetch successfully!")
return messagesPageUrl.toHttpUrl() to Jsoup.parse(certResponseHtml)
}
} else {
logger.debug("Messages cookies already fetched!")
return messagesPageUrl.toHttpUrl() to startDoc
logger.debug("{} cookies already fetched!", site)
return moduleUrl.toHttpUrl() to startDoc
}
}

View file

@ -49,7 +49,7 @@ internal class ServiceManager(
private val diaryId: Int,
private val kindergartenDiaryId: Int,
private val schoolYear: Int,
onUserLoggedIn: (studentModuleUrls: List<String>) -> Unit = {},
isEduOneStudent: (Boolean) -> Unit = {},
emptyCookieJarIntercept: Boolean,
androidVersion: String,
buildTag: String,
@ -100,9 +100,9 @@ internal class ServiceManager(
cookieJarCabinet = cookieJarCabinet,
emptyCookieJarIntercept = emptyCookieJarIntercept,
notLoggedInCallback = { loginHelper.login(email, password) },
fetchStudentCookies = { loginHelper.loginStudent() },
fetchMessagesCookies = { loginHelper.loginMessages() },
onUserLoggedIn = onUserLoggedIn,
fetchModuleCookies = { loginHelper.loginModule(it) },
isEduOneStudent = isEduOneStudent,
urlGenerator = urlGenerator,
) to false,
UserAgentInterceptor(androidVersion, buildTag, userAgentTemplate) to false,
HttpErrorInterceptor() to false,

View file

@ -103,6 +103,7 @@ abstract class BaseLocalTest : BaseTest() {
.build()
private fun getAutoLoginInterceptor(loginType: Scrapper.LoginType, autoLogin: Boolean): AutoLoginInterceptor {
val urlGenerator = UrlGenerator(URL("http://localhost/"), "", "lodz", "")
return AutoLoginInterceptor(
loginType = loginType,
cookieJarCabinet = CookieJarCabinet(),
@ -116,14 +117,14 @@ abstract class BaseLocalTest : BaseTest() {
symbol = "powiatwulkanowy",
cookieJarCabinet = CookieJarCabinet(),
api = getService(LoginService::class.java),
urlGenerator = UrlGenerator(URL("http://localhost/"), "", "lodz", ""),
urlGenerator = urlGenerator,
).login("jan", "kowalski")
} else {
HomePageResponse()
}
},
fetchStudentCookies = { "http://localhost".toHttpUrl() to Document("") },
fetchMessagesCookies = { "http://localhost".toHttpUrl() to Document("") },
fetchModuleCookies = { "http://localhost".toHttpUrl() to Document("") },
urlGenerator = urlGenerator,
)
}
}

View file

@ -138,13 +138,14 @@ class AutoLoginInterceptorTest : BaseLocalTest() {
}
private fun getService(checkJar: Boolean = false, notLoggedInCallback: suspend () -> HomePageResponse): StudentService {
val urlGenerator = UrlGenerator(URL("http://localhost/"), "", "lodz", "")
val interceptor = AutoLoginInterceptor(
loginType = Scrapper.LoginType.STANDARD,
cookieJarCabinet = CookieJarCabinet(),
emptyCookieJarIntercept = checkJar,
notLoggedInCallback = notLoggedInCallback,
fetchStudentCookies = { "http://localhost".toHttpUrl() to Document("") },
fetchMessagesCookies = { "http://localhost".toHttpUrl() to Document("") },
fetchModuleCookies = { "http://localhost".toHttpUrl() to Document("") },
urlGenerator = urlGenerator,
)
val okHttp = getOkHttp(autoLogin = true, autoLoginInterceptorOn = true, autoLoginInterceptor = interceptor)
return getService(StudentService::class.java, html = false, okHttp = okHttp)