Add domain suffix parameter

This commit is contained in:
Mikołaj Pich 2023-05-26 19:35:17 +02:00
parent d6bdb4e74a
commit 4a67e1e3fa
15 changed files with 103 additions and 25 deletions

View file

@ -22,6 +22,7 @@ public final class io/github/wulkanowy/sdk/scrapper/Scrapper {
public static synthetic fun getDeletedMessages$default (Lio/github/wulkanowy/sdk/scrapper/Scrapper;Ljava/lang/String;IILkotlin/coroutines/Continuation;ILjava/lang/Object;)Ljava/lang/Object;
public final fun getDiaryId ()I
public final fun getDirectorInformation (Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
public final fun getDomainSuffix ()Ljava/lang/String;
public final fun getEmail ()Ljava/lang/String;
public final fun getExams (Ljava/time/LocalDate;Ljava/time/LocalDate;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
public static synthetic fun getExams$default (Lio/github/wulkanowy/sdk/scrapper/Scrapper;Ljava/time/LocalDate;Ljava/time/LocalDate;Lkotlin/coroutines/Continuation;ILjava/lang/Object;)Ljava/lang/Object;
@ -84,6 +85,7 @@ public final class io/github/wulkanowy/sdk/scrapper/Scrapper {
public final fun setBuildTag (Ljava/lang/String;)V
public final fun setClassId (I)V
public final fun setDiaryId (I)V
public final fun setDomainSuffix (Ljava/lang/String;)V
public final fun setEmail (Ljava/lang/String;)V
public final fun setHost (Ljava/lang/String;)V
public final fun setKindergartenDiaryId (I)V

View file

@ -87,6 +87,12 @@ class Scrapper {
field = value
}
var domainSuffix: String = ""
set(value) {
if (field != value) changeManager.reset()
field = value
}
var loginType: LoginType = LoginType.AUTO
set(value) {
if (field != value) changeManager.reset()
@ -190,6 +196,7 @@ class Scrapper {
loginType = loginType,
schema = schema,
host = host,
domainSuffix = domainSuffix,
symbol = normalizedSymbol,
email = email,
password = password,
@ -219,6 +226,7 @@ class Scrapper {
loginType = loginType,
schema = schema,
host = host,
domainSuffix = domainSuffix,
symbol = normalizedSymbol,
cookies = serviceManager.getCookieManager(),
api = serviceManager.getLoginService(),
@ -252,10 +260,10 @@ class Scrapper {
HomepageRepository(serviceManager.getHomepageService())
}
suspend fun getPasswordResetCaptcha(registerBaseUrl: String, symbol: String): Pair<String, String> = account.getPasswordResetCaptcha(registerBaseUrl, symbol)
suspend fun getPasswordResetCaptcha(registerBaseUrl: String, symbol: String): Pair<String, String> = account.getPasswordResetCaptcha(registerBaseUrl, domainSuffix, symbol)
suspend fun sendPasswordResetRequest(registerBaseUrl: String, symbol: String, email: String, captchaCode: String): String {
return account.sendPasswordResetRequest(registerBaseUrl, symbol, email.trim(), captchaCode)
return account.sendPasswordResetRequest(registerBaseUrl, symbol, email.trim(), domainSuffix, captchaCode)
}
suspend fun getUserSubjects(): RegisterUser = register.getUserSubjects()

View file

@ -24,6 +24,7 @@ internal class LoginHelper(
var loginType: Scrapper.LoginType,
private val schema: String,
private val host: String,
private val domainSuffix: String,
private val symbol: String,
private val cookies: CookieManager,
private val api: LoginService,
@ -39,7 +40,7 @@ internal class LoginHelper(
}
private val firstStepReturnUrl by lazy {
encode("$schema://uonetplus.$host/$symbol/LoginEndpoint.aspx").let {
encode("$schema://uonetplus$domainSuffix.$host/$symbol/LoginEndpoint.aspx").let {
"/$symbol/FS/LS?wa=wsignin1.0&wtrealm=$it&wctx=$it"
}
}
@ -92,7 +93,7 @@ internal class LoginHelper(
suspend fun sendCertificate(cert: CertificateResponse, email: String, url: String = cert.action): HomePageResponse {
cookies.cookieStore.removeAll()
val res = api.sendCertificate(
referer = "$schema://cufs.$host/",
referer = "$schema://cufs$domainSuffix.$host/",
url = url,
certificate = mapOf(
"wa" to cert.wa,
@ -221,7 +222,7 @@ internal class LoginHelper(
}
val query = "?wa=wsignin1.0" +
"&wtrealm=" + encode("http${if (ADFSCards != type) "s" else ""}://cufs.$host/$symbol/Account/LogOn") +
"&wtrealm=" + encode("http${if (ADFSCards != type) "s" else ""}://cufs$domainSuffix.$host/$symbol/Account/LogOn") +
"&wctx=" + encode("rm=0&id=$id&ru=" + encode(firstStepReturnUrl)) +
"&wct=" + encode(now(ZoneId.of("UTC")).format(DateTimeFormatter.ISO_LOCAL_DATE_TIME) + "Z")

View file

@ -5,19 +5,24 @@ import java.net.URL
internal class UrlGenerator(
private val schema: String,
private val host: String,
private val domainSuffix: String,
var symbol: String,
var schoolId: String,
) {
constructor(url: URL, symbol: String, schoolId: String) : this(url.protocol, url.host, symbol, schoolId)
constructor(url: URL, domainSuffix: String, symbol: String, schoolId: String) : this(url.protocol, url.host, domainSuffix, symbol, schoolId)
enum class Site {
BASE, LOGIN, HOME, STUDENT, MESSAGES
BASE,
LOGIN,
HOME,
STUDENT,
MESSAGES,
}
fun generate(type: Site): String {
if (type == Site.BASE) return "$schema://$host"
return "$schema://${getSubDomain(type)}.$host/$symbol/${if (type == Site.STUDENT) "$schoolId/" else ""}"
return "$schema://${getSubDomain(type)}$domainSuffix.$host/$symbol/${if (type == Site.STUDENT) "$schoolId/" else ""}"
}
private fun getSubDomain(type: Site): String {

View file

@ -26,14 +26,14 @@ internal class AccountRepository(private val account: AccountService) {
const val SELECTOR_ADFS_CARDS = "#__VIEWSTATE"
}
suspend fun getPasswordResetCaptcha(registerBaseUrl: String, symbol: String): Pair<String, String> {
val (_, resetUrl) = getPasswordResetUrl(registerBaseUrl, symbol.trim())
suspend fun getPasswordResetCaptcha(registerBaseUrl: String, domainSuffix: String, symbol: String): Pair<String, String> {
val (_, resetUrl) = getPasswordResetUrl(registerBaseUrl, domainSuffix, symbol.trim())
val res = account.getPasswordResetPageWithCaptcha(resetUrl)
return resetUrl to res.recaptchaSiteKey
}
suspend fun sendPasswordResetRequest(registerBaseUrl: String, symbol: String, email: String, captchaCode: String): String {
val (type, url) = getPasswordResetUrl(registerBaseUrl, symbol.trim())
suspend fun sendPasswordResetRequest(registerBaseUrl: String, domainSuffix: String, symbol: String, email: String, captchaCode: String): String {
val (type, url) = getPasswordResetUrl(registerBaseUrl, domainSuffix, symbol.trim())
val res = when (type) {
STANDARD -> account.sendPasswordResetRequest(url, email, captchaCode)
@ -70,7 +70,7 @@ internal class AccountRepository(private val account: AccountService) {
return res.message.ifBlank { "Wysłano wiadomość na zapisany w systemie adres e-mail" }
}
private suspend fun getPasswordResetUrl(registerBaseUrl: String, symbol: String): Pair<Scrapper.LoginType, String> {
private suspend fun getPasswordResetUrl(registerBaseUrl: String, domainSuffix: String, symbol: String): Pair<Scrapper.LoginType, String> {
val url = URL(registerBaseUrl)
val unlockUrl = when (url.host) {
"fakelog.cf" -> STANDARD to "https://cufs.fakelog.cf/Default/AccountManage/UnlockAccount"
@ -85,7 +85,7 @@ internal class AccountRepository(private val account: AccountService) {
}
return if (unlockUrl.first == AUTO) {
val loginType = getLoginType(UrlGenerator(url, symbol, ""))
val loginType = getLoginType(UrlGenerator(url, domainSuffix, symbol, ""))
loginType to when (loginType) {
STANDARD -> "https://cufs.vulcan.net.pl/$symbol/AccountManage/UnlockAccount"
ADFSLightScoped -> "https://adfslight.vulcan.net.pl/$symbol/AccountManage/UnlockAccountRequest"

View file

@ -40,6 +40,7 @@ internal class ServiceManager(
private val loginType: Scrapper.LoginType,
private val schema: String,
private val host: String,
private val domainSuffix: String,
private val symbol: String,
private val email: String,
private val password: String,
@ -60,11 +61,25 @@ internal class ServiceManager(
}
private val loginHelper by lazy {
LoginHelper(loginType, schema, host, symbol, cookies, getLoginService())
LoginHelper(
loginType = loginType,
schema = schema,
host = host,
domainSuffix = domainSuffix,
symbol = symbol,
cookies = cookies,
api = getLoginService(),
)
}
val urlGenerator by lazy {
UrlGenerator(schema, host, symbol, schoolId)
UrlGenerator(
schema = schema,
host = host,
domainSuffix = domainSuffix,
symbol = symbol,
schoolId = schoolId,
)
}
@OptIn(ExperimentalSerializationApi::class)

View file

@ -98,8 +98,15 @@ abstract class BaseLocalTest : BaseTest() {
private fun getAutoLoginInterceptor(loginType: Scrapper.LoginType, autoLogin: Boolean): AutoLoginInterceptor {
return AutoLoginInterceptor(loginType, CookieManager()) {
if (autoLogin) {
LoginHelper(loginType, "http", "localhost", "powiatwulkanowy", CookieManager(), getService(LoginService::class.java))
.login("jan", "kowalski")
LoginHelper(
loginType = loginType,
schema = "http",
host = "localhost",
domainSuffix = "",
symbol = "powiatwulkanowy",
cookies = CookieManager(),
api = getService(LoginService::class.java),
).login("jan", "kowalski")
}
}
}

View file

@ -225,7 +225,7 @@ class ScrapperRemoteTest : BaseTest() {
@Test
fun gradesTest() {
val grades = runBlocking { api.getGrades(865).details }
val grades = runBlocking { api.getGrades(57).details }
// dynamic grade
grades[7].run {

View file

@ -124,6 +124,7 @@ class AutoLoginInterceptorTest : BaseLocalTest() {
loginType = Scrapper.LoginType.STANDARD,
schema = "http",
host = "${server.hostName}:${server.port}",
domainSuffix = "",
symbol = "powiatwulkanowy",
cookies = CookieManager(),
api = loginService,

View file

@ -20,6 +20,7 @@ class LoginTest : BaseLocalTest() {
loginType = Scrapper.LoginType.STANDARD,
schema = "http",
host = "fakelog.localhost:3000",
domainSuffix = "",
symbol = "default",
cookies = CookieManager(),
api = getService(LoginService::class.java, "http://fakelog.localhost:3000/"),
@ -31,6 +32,7 @@ class LoginTest : BaseLocalTest() {
loginType = Scrapper.LoginType.ADFS,
schema = "http",
host = "fakelog.localhost:3000",
domainSuffix = "",
symbol = "default",
cookies = CookieManager(),
api = getService(

View file

@ -9,13 +9,11 @@ import io.github.wulkanowy.sdk.scrapper.repository.RegisterRepository
import io.github.wulkanowy.sdk.scrapper.service.LoginService
import io.github.wulkanowy.sdk.scrapper.service.RegisterService
import io.github.wulkanowy.sdk.scrapper.service.StudentService
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.test.runTest
import org.junit.Assert.assertEquals
import org.junit.Test
import java.net.CookieManager
@OptIn(ExperimentalCoroutinesApi::class)
class RegisterTest : BaseLocalTest() {
private val login by lazy {
@ -23,6 +21,7 @@ class RegisterTest : BaseLocalTest() {
loginType = Scrapper.LoginType.STANDARD,
schema = "http",
host = "fakelog.localhost:3000",
domainSuffix = "",
symbol = "default",
cookies = CookieManager(),
api = getService(
@ -54,7 +53,13 @@ class RegisterTest : BaseLocalTest() {
),
),
student = getService(StudentService::class.java, "http://fakelog.localhost:3000", false),
url = UrlGenerator("http", "fakelog.localhost:3000", "default", "123"),
url = UrlGenerator(
schema = "http",
host = "fakelog.localhost:3000",
domainSuffix = "",
symbol = "default",
schoolId = "123",
),
)
}

View file

@ -12,14 +12,12 @@ import io.github.wulkanowy.sdk.scrapper.register.RegisterTest
import io.github.wulkanowy.sdk.scrapper.service.LoginService
import io.github.wulkanowy.sdk.scrapper.service.RegisterService
import io.github.wulkanowy.sdk.scrapper.service.StudentService
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.test.runTest
import org.junit.Assert.assertEquals
import org.junit.Assert.assertTrue
import org.junit.Test
import java.net.CookieManager
@OptIn(ExperimentalCoroutinesApi::class)
class RegisterRepositoryTest : BaseLocalTest() {
private val normal by lazy { getRegisterRepository("Default") }
@ -33,6 +31,7 @@ class RegisterRepositoryTest : BaseLocalTest() {
loginType = Scrapper.LoginType.STANDARD,
schema = "http",
host = "fakelog.localhost:3000",
domainSuffix = "",
symbol = symbol,
cookies = CookieManager(),
api = getService(LoginService::class.java, "http://fakelog.localhost:3000/"),
@ -43,7 +42,13 @@ class RegisterRepositoryTest : BaseLocalTest() {
okHttp = getOkHttp(errorInterceptor = false, autoLoginInterceptorOn = false),
),
student = getService(service = StudentService::class.java, html = false),
url = UrlGenerator("http", "fakelog.localhost:3000", symbol, ""),
url = UrlGenerator(
schema = "http",
host = "fakelog.localhost:3000",
domainSuffix = "",
symbol = symbol,
schoolId = "",
),
)
}

View file

@ -26,6 +26,7 @@ class ServiceManagerTest : BaseLocalTest() {
loginType = Scrapper.LoginType.STANDARD,
schema = "http",
host = "fakelog.localhost:3000",
domainSuffix = "",
symbol = "default",
email = "email",
password = "password",
@ -57,6 +58,7 @@ class ServiceManagerTest : BaseLocalTest() {
loginType = Scrapper.LoginType.STANDARD,
schema = "http",
host = "fakelog.localhost:3000",
domainSuffix = "",
symbol = "default",
email = "email",
password = "password",
@ -126,6 +128,7 @@ class ServiceManagerTest : BaseLocalTest() {
loginType = Scrapper.LoginType.STANDARD,
schema = "http",
host = "fakelog.localhost:3000",
domainSuffix = "",
symbol = "default",
email = "email",
password = "password",

View file

@ -21,6 +21,7 @@ public final class io/github/wulkanowy/sdk/Sdk {
public static synthetic fun getDeletedMessages$default (Lio/github/wulkanowy/sdk/Sdk;Ljava/lang/String;Lkotlin/coroutines/Continuation;ILjava/lang/Object;)Ljava/lang/Object;
public final fun getDiaryId ()I
public final fun getDirectorInformation (Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
public final fun getDomainSuffix ()Ljava/lang/String;
public final fun getEmail ()Ljava/lang/String;
public final fun getExams (Ljava/time/LocalDate;Ljava/time/LocalDate;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
public final fun getFreeDays (Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
@ -81,6 +82,7 @@ public final class io/github/wulkanowy/sdk/Sdk {
public final fun getTimetable (Ljava/time/LocalDate;Ljava/time/LocalDate;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
public final fun getToken (Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
public final fun getUserAgentTemplate ()Ljava/lang/String;
public final fun getUserSubjectsFromScrapper (Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
public final fun getUserSubjectsFromScrapper (Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
public static synthetic fun getUserSubjectsFromScrapper$default (Lio/github/wulkanowy/sdk/Sdk;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Lkotlin/coroutines/Continuation;ILjava/lang/Object;)Ljava/lang/Object;
public final fun sendMessage (Ljava/lang/String;Ljava/lang/String;Ljava/util/List;Ljava/lang/String;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
@ -89,6 +91,7 @@ public final class io/github/wulkanowy/sdk/Sdk {
public final fun setBuildTag (Ljava/lang/String;)V
public final fun setClassId (I)V
public final fun setDiaryId (I)V
public final fun setDomainSuffix (Ljava/lang/String;)V
public final fun setEmail (Ljava/lang/String;)V
public final fun setKeyId (Ljava/lang/String;)V
public final fun setKindergartenDiaryId (I)V

View file

@ -123,6 +123,12 @@ class Sdk {
scrapper.baseUrl = value
}
var domainSuffix: String = ""
set(value) {
field = value
scrapper.domainSuffix = value
}
var email = ""
set(value) {
field = value
@ -248,9 +254,24 @@ class Sdk {
password: String,
scrapperBaseUrl: String,
symbol: String = "Default",
): RegisterUser = getUserSubjectsFromScrapper(
email = email,
password = password,
scrapperBaseUrl = scrapperBaseUrl,
domainSuffix = domainSuffix,
symbol = symbol,
)
suspend fun getUserSubjectsFromScrapper(
email: String,
password: String,
scrapperBaseUrl: String,
domainSuffix: String,
symbol: String,
): RegisterUser = withContext(Dispatchers.IO) {
scrapper.let {
it.baseUrl = scrapperBaseUrl
it.domainSuffix = domainSuffix
it.email = email
it.password = password
it.symbol = symbol