Add CookieJarCabinet to manage multiple cookie stores

This commit is contained in:
Mikołaj Pich 2024-01-12 14:52:59 +01:00
parent 212f0e33d5
commit a7f5fa26af
16 changed files with 123 additions and 93 deletions

View file

@ -6,7 +6,6 @@ public final class io/github/wulkanowy/sdk/scrapper/Scrapper {
public final fun deleteMessages (Ljava/util/List;ZLkotlin/coroutines/Continuation;)Ljava/lang/Object; public final fun deleteMessages (Ljava/util/List;ZLkotlin/coroutines/Continuation;)Ljava/lang/Object;
public final fun excuseForAbsence (Ljava/util/List;Ljava/lang/String;Lkotlin/coroutines/Continuation;)Ljava/lang/Object; public final fun excuseForAbsence (Ljava/util/List;Ljava/lang/String;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
public static synthetic fun excuseForAbsence$default (Lio/github/wulkanowy/sdk/scrapper/Scrapper;Ljava/util/List;Ljava/lang/String;Lkotlin/coroutines/Continuation;ILjava/lang/Object;)Ljava/lang/Object; public static synthetic fun excuseForAbsence$default (Lio/github/wulkanowy/sdk/scrapper/Scrapper;Ljava/util/List;Ljava/lang/String;Lkotlin/coroutines/Continuation;ILjava/lang/Object;)Ljava/lang/Object;
public final fun getAlternativeCookieManager ()Ljava/net/CookieManager;
public final fun getAndroidVersion ()Ljava/lang/String; public final fun getAndroidVersion ()Ljava/lang/String;
public final fun getAttendance (Ljava/time/LocalDate;Ljava/time/LocalDate;Lkotlin/coroutines/Continuation;)Ljava/lang/Object; public final fun getAttendance (Ljava/time/LocalDate;Ljava/time/LocalDate;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
public static synthetic fun getAttendance$default (Lio/github/wulkanowy/sdk/scrapper/Scrapper;Ljava/time/LocalDate;Ljava/time/LocalDate;Lkotlin/coroutines/Continuation;ILjava/lang/Object;)Ljava/lang/Object; public static synthetic fun getAttendance$default (Lio/github/wulkanowy/sdk/scrapper/Scrapper;Ljava/time/LocalDate;Ljava/time/LocalDate;Lkotlin/coroutines/Continuation;ILjava/lang/Object;)Ljava/lang/Object;
@ -18,7 +17,6 @@ public final class io/github/wulkanowy/sdk/scrapper/Scrapper {
public final fun getCompletedLessons (Ljava/time/LocalDate;Ljava/time/LocalDate;ILkotlin/coroutines/Continuation;)Ljava/lang/Object; public final fun getCompletedLessons (Ljava/time/LocalDate;Ljava/time/LocalDate;ILkotlin/coroutines/Continuation;)Ljava/lang/Object;
public static synthetic fun getCompletedLessons$default (Lio/github/wulkanowy/sdk/scrapper/Scrapper;Ljava/time/LocalDate;Ljava/time/LocalDate;ILkotlin/coroutines/Continuation;ILjava/lang/Object;)Ljava/lang/Object; public static synthetic fun getCompletedLessons$default (Lio/github/wulkanowy/sdk/scrapper/Scrapper;Ljava/time/LocalDate;Ljava/time/LocalDate;ILkotlin/coroutines/Continuation;ILjava/lang/Object;)Ljava/lang/Object;
public final fun getConferences (Lkotlin/coroutines/Continuation;)Ljava/lang/Object; public final fun getConferences (Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
public final fun getCookieManager ()Ljava/net/CookieManager;
public final fun getCurrentStudent (Lkotlin/coroutines/Continuation;)Ljava/lang/Object; public final fun getCurrentStudent (Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
public final fun getDeletedMessages (Ljava/lang/String;IILkotlin/coroutines/Continuation;)Ljava/lang/Object; public final fun getDeletedMessages (Ljava/lang/String;IILkotlin/coroutines/Continuation;)Ljava/lang/Object;
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 static synthetic fun getDeletedMessages$default (Lio/github/wulkanowy/sdk/scrapper/Scrapper;Ljava/lang/String;IILkotlin/coroutines/Continuation;ILjava/lang/Object;)Ljava/lang/Object;
@ -83,6 +81,7 @@ public final class io/github/wulkanowy/sdk/scrapper/Scrapper {
public final fun getUserSubjects (Lkotlin/coroutines/Continuation;)Ljava/lang/Object; public final fun getUserSubjects (Lkotlin/coroutines/Continuation;)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; public final fun sendMessage (Ljava/lang/String;Ljava/lang/String;Ljava/util/List;Ljava/lang/String;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
public final fun sendPasswordResetRequest (Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Lkotlin/coroutines/Continuation;)Ljava/lang/Object; public final fun sendPasswordResetRequest (Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
public final fun setAdditionalCookieManager (Ljava/net/CookieManager;)V
public final fun setAndroidVersion (Ljava/lang/String;)V public final fun setAndroidVersion (Ljava/lang/String;)V
public final fun setBaseUrl (Ljava/lang/String;)V public final fun setBaseUrl (Ljava/lang/String;)V
public final fun setBuildTag (Ljava/lang/String;)V public final fun setBuildTag (Ljava/lang/String;)V

View file

@ -0,0 +1,62 @@
package io.github.wulkanowy.sdk.scrapper
import java.net.CookieManager
import java.net.CookiePolicy
import java.net.HttpCookie
import java.net.URI
internal class CookieJarCabinet {
val userCookieManager = CookieManager().apply {
setCookiePolicy(CookiePolicy.ACCEPT_ALL)
}
val alternativeCookieManager = CookieManager().apply {
setCookiePolicy(CookiePolicy.ACCEPT_ALL)
}
private var additionalCookieManager: CookieManager? = null
fun isUserCookiesExist(): Boolean {
return userCookieManager.cookieStore.cookies.isNotEmpty()
}
fun onUserChange() {
clearUserCookieStore()
}
fun beforeUserLogIn() {
clearUserCookieStore()
}
fun onLoginServiceError() {
clearUserCookieStore()
}
fun addStudentCookie(uri: URI, cookie: HttpCookie) {
userCookieManager.cookieStore.add(uri, cookie)
}
fun setAdditionalCookieManager(cookieManager: CookieManager) {
additionalCookieManager = cookieManager
appendUserCookiesWithAdditionalCookies()
}
private fun clearUserCookieStore() {
userCookieManager.cookieStore.removeAll()
appendUserCookiesWithAdditionalCookies()
}
private fun appendUserCookiesWithAdditionalCookies() {
val additionalJar = additionalCookieManager?.cookieStore ?: return
val cookiesWithUris = additionalJar.urIs.map {
it to additionalJar.get(it)
}
cookiesWithUris.forEach { (uri, cookies) ->
cookies.forEach {
userCookieManager.cookieStore.add(uri, it)
}
}
}
}

View file

@ -45,7 +45,6 @@ import io.github.wulkanowy.sdk.scrapper.timetable.Timetable
import okhttp3.Interceptor import okhttp3.Interceptor
import okhttp3.logging.HttpLoggingInterceptor import okhttp3.logging.HttpLoggingInterceptor
import java.net.CookieManager import java.net.CookieManager
import java.net.CookiePolicy
import java.net.URL import java.net.URL
import java.time.LocalDate import java.time.LocalDate
@ -64,13 +63,7 @@ class Scrapper {
private val changeManager = resettableManager() private val changeManager = resettableManager()
val cookieManager = CookieManager().apply { private val cookieJarCabinet = CookieJarCabinet()
setCookiePolicy(CookiePolicy.ACCEPT_ALL)
}
val alternativeCookieManager = CookieManager().apply {
setCookiePolicy(CookiePolicy.ACCEPT_ALL)
}
var logLevel: HttpLoggingInterceptor.Level = HttpLoggingInterceptor.Level.BASIC var logLevel: HttpLoggingInterceptor.Level = HttpLoggingInterceptor.Level.BASIC
set(value) { set(value) {
@ -113,7 +106,7 @@ class Scrapper {
set(value) { set(value) {
if (field != value) { if (field != value) {
changeManager.reset() changeManager.reset()
cookieManager.cookieStore.removeAll() cookieJarCabinet.onUserChange()
} }
field = value field = value
} }
@ -122,7 +115,7 @@ class Scrapper {
set(value) { set(value) {
if (field != value) { if (field != value) {
changeManager.reset() changeManager.reset()
cookieManager.cookieStore.removeAll() cookieJarCabinet.onUserChange()
} }
field = value field = value
} }
@ -131,7 +124,7 @@ class Scrapper {
set(value) { set(value) {
if (field != value) { if (field != value) {
changeManager.reset() changeManager.reset()
cookieManager.cookieStore.removeAll() cookieJarCabinet.onUserChange()
} }
field = value field = value
} }
@ -217,8 +210,7 @@ class Scrapper {
private val serviceManager by resettableLazy(changeManager) { private val serviceManager by resettableLazy(changeManager) {
ServiceManager( ServiceManager(
okHttpClientBuilderFactory = okHttpFactory, okHttpClientBuilderFactory = okHttpFactory,
cookies = cookieManager, cookieJarCabinet = cookieJarCabinet,
alternativeCookies = alternativeCookieManager,
logLevel = logLevel, logLevel = logLevel,
loginType = loginType, loginType = loginType,
schema = schema, schema = schema,
@ -256,7 +248,7 @@ class Scrapper {
host = host, host = host,
domainSuffix = domainSuffix, domainSuffix = domainSuffix,
symbol = normalizedSymbol, symbol = normalizedSymbol,
cookies = serviceManager.getCookieManager(), cookieJarCabinet = cookieJarCabinet,
api = serviceManager.getLoginService(), api = serviceManager.getLoginService(),
urlGenerator = serviceManager.urlGenerator, urlGenerator = serviceManager.urlGenerator,
), ),
@ -294,6 +286,10 @@ class Scrapper {
HomepageRepository(serviceManager.getHomepageService()) HomepageRepository(serviceManager.getHomepageService())
} }
fun setAdditionalCookieManager(cookieManager: CookieManager) {
cookieJarCabinet.setAdditionalCookieManager(cookieManager)
}
suspend fun getPasswordResetCaptcha(registerBaseUrl: String, symbol: String): Pair<String, String> = account.getPasswordResetCaptcha(registerBaseUrl, domainSuffix, 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 { suspend fun sendPasswordResetRequest(registerBaseUrl: String, symbol: String, email: String, captchaCode: String): String {

View file

@ -1,5 +1,6 @@
package io.github.wulkanowy.sdk.scrapper.interceptor package io.github.wulkanowy.sdk.scrapper.interceptor
import io.github.wulkanowy.sdk.scrapper.CookieJarCabinet
import io.github.wulkanowy.sdk.scrapper.Scrapper.LoginType import io.github.wulkanowy.sdk.scrapper.Scrapper.LoginType
import io.github.wulkanowy.sdk.scrapper.Scrapper.LoginType.ADFS import io.github.wulkanowy.sdk.scrapper.Scrapper.LoginType.ADFS
import io.github.wulkanowy.sdk.scrapper.Scrapper.LoginType.ADFSCards import io.github.wulkanowy.sdk.scrapper.Scrapper.LoginType.ADFSCards
@ -14,9 +15,7 @@ import io.github.wulkanowy.sdk.scrapper.repository.AccountRepository.Companion.S
import io.github.wulkanowy.sdk.scrapper.repository.AccountRepository.Companion.SELECTOR_ADFS_LIGHT import io.github.wulkanowy.sdk.scrapper.repository.AccountRepository.Companion.SELECTOR_ADFS_LIGHT
import io.github.wulkanowy.sdk.scrapper.repository.AccountRepository.Companion.SELECTOR_STANDARD import io.github.wulkanowy.sdk.scrapper.repository.AccountRepository.Companion.SELECTOR_STANDARD
import kotlinx.coroutines.runBlocking import kotlinx.coroutines.runBlocking
import okhttp3.Cookie
import okhttp3.Interceptor import okhttp3.Interceptor
import okhttp3.JavaNetCookieJar
import okhttp3.MediaType import okhttp3.MediaType
import okhttp3.Protocol import okhttp3.Protocol
import okhttp3.Request import okhttp3.Request
@ -30,7 +29,6 @@ import org.jsoup.select.Elements
import org.slf4j.LoggerFactory import org.slf4j.LoggerFactory
import retrofit2.HttpException import retrofit2.HttpException
import java.io.IOException import java.io.IOException
import java.net.CookieManager
import java.net.HttpURLConnection import java.net.HttpURLConnection
import java.util.concurrent.locks.ReentrantLock import java.util.concurrent.locks.ReentrantLock
@ -38,7 +36,7 @@ private val lock = ReentrantLock(true)
internal class AutoLoginInterceptor( internal class AutoLoginInterceptor(
private val loginType: LoginType, private val loginType: LoginType,
private val jar: CookieManager, private val cookieJarCabinet: CookieJarCabinet,
private val emptyCookieJarIntercept: Boolean = false, private val emptyCookieJarIntercept: Boolean = false,
private val notLoggedInCallback: suspend () -> Unit, private val notLoggedInCallback: suspend () -> Unit,
private val fetchStudentCookies: () -> Unit, private val fetchStudentCookies: () -> Unit,
@ -50,8 +48,6 @@ internal class AutoLoginInterceptor(
private val logger = LoggerFactory.getLogger(this::class.java) private val logger = LoggerFactory.getLogger(this::class.java)
} }
private val cookieJar = JavaNetCookieJar(jar)
@Volatile @Volatile
private var lastError: Throwable? = null private var lastError: Throwable? = null
@ -76,6 +72,7 @@ internal class AutoLoginInterceptor(
val body = response.peekBody(Long.MAX_VALUE).byteStream() val body = response.peekBody(Long.MAX_VALUE).byteStream()
checkResponse(Jsoup.parse(body, null, url), url) checkResponse(Jsoup.parse(body, null, url), url)
} }
lastError = null
} catch (e: NotLoggedInException) { } catch (e: NotLoggedInException) {
return if (lock.tryLock()) { return if (lock.tryLock()) {
logger.debug("Not logged in. Login in...") logger.debug("Not logged in. Login in...")
@ -90,7 +87,7 @@ internal class AutoLoginInterceptor(
"uczen" in uri.host -> student.getOrThrow() "uczen" in uri.host -> student.getOrThrow()
else -> logger.info("Resource don't need further login") else -> logger.info("Resource don't need further login")
} }
chain.retryRequest() chain.proceed(chain.request().newBuilder().build())
} catch (e: IOException) { } catch (e: IOException) {
logger.debug("Error occurred on login") logger.debug("Error occurred on login")
lastError = e lastError = e
@ -121,36 +118,15 @@ internal class AutoLoginInterceptor(
logger.debug("User logged in. Retry after login...") logger.debug("User logged in. Retry after login...")
} }
chain.retryRequest() chain.proceed(chain.request().newBuilder().build())
} }
} }
return response return response
} }
private fun Interceptor.Chain.retryRequest(): Response {
Thread.sleep(10)
val newRequest = request()
.newBuilder()
.header("Cookie", cookieJar.loadForRequest(request().url).cookieHeader())
.build()
return proceed(newRequest)
}
private fun List<Cookie>.cookieHeader(): String = buildString {
this@cookieHeader.forEachIndexed { index, cookie ->
if (index > 0) append("; ")
append(cookie.name).append('=').append(cookie.value)
}
}
/**
* @see [okhttp3.internal.http.BridgeInterceptor]
*/
private fun checkRequest() { private fun checkRequest() {
if (emptyCookieJarIntercept && jar.cookieStore.cookies.isEmpty()) { if (emptyCookieJarIntercept && !cookieJarCabinet.isUserCookiesExist()) {
throw NotLoggedInException("No cookie found! You are not logged in yet") throw NotLoggedInException("No cookie found! You are not logged in yet")
} }
} }

View file

@ -1,5 +1,6 @@
package io.github.wulkanowy.sdk.scrapper.interceptor package io.github.wulkanowy.sdk.scrapper.interceptor
import io.github.wulkanowy.sdk.scrapper.CookieJarCabinet
import io.github.wulkanowy.sdk.scrapper.exception.AccountInactiveException import io.github.wulkanowy.sdk.scrapper.exception.AccountInactiveException
import io.github.wulkanowy.sdk.scrapper.exception.ConnectionBlockedException import io.github.wulkanowy.sdk.scrapper.exception.ConnectionBlockedException
import io.github.wulkanowy.sdk.scrapper.exception.ScrapperException import io.github.wulkanowy.sdk.scrapper.exception.ScrapperException
@ -15,11 +16,10 @@ import okhttp3.Response
import org.jsoup.Jsoup import org.jsoup.Jsoup
import org.jsoup.nodes.Document import org.jsoup.nodes.Document
import org.slf4j.LoggerFactory import org.slf4j.LoggerFactory
import java.net.CookieManager
import java.net.HttpURLConnection.HTTP_NOT_FOUND import java.net.HttpURLConnection.HTTP_NOT_FOUND
internal class ErrorInterceptor( internal class ErrorInterceptor(
private val cookies: CookieManager, private val cookieJarCabinet: CookieJarCabinet,
) : Interceptor { ) : Interceptor {
companion object { companion object {
@ -105,7 +105,7 @@ internal class ErrorInterceptor(
) )
"Login Service" -> { "Login Service" -> {
cookies.cookieStore.removeAll() // workaround for very strange (random) errors cookieJarCabinet.onLoginServiceError() // workaround for very strange (random) errors
throw ScrapperException(doc.select("#MainDiv > div").text(), httpCode) throw ScrapperException(doc.select("#MainDiv > div").text(), httpCode)
} }

View file

@ -1,13 +1,13 @@
package io.github.wulkanowy.sdk.scrapper.interceptor package io.github.wulkanowy.sdk.scrapper.interceptor
import io.github.wulkanowy.sdk.scrapper.CookieJarCabinet
import okhttp3.Interceptor import okhttp3.Interceptor
import okhttp3.Response import okhttp3.Response
import java.net.CookieManager
import java.net.HttpCookie import java.net.HttpCookie
import java.net.URI import java.net.URI
internal class StudentCookieInterceptor( internal class StudentCookieInterceptor(
private val cookies: CookieManager, private val cookieJarCabinet: CookieJarCabinet,
private val schema: String, private val schema: String,
private val host: String, private val host: String,
private val domainSuffix: String, private val domainSuffix: String,
@ -27,7 +27,7 @@ internal class StudentCookieInterceptor(
HttpCookie(name, value.toString()).let { HttpCookie(name, value.toString()).let {
it.path = "/" it.path = "/"
it.domain = "uonetplus-uczen$domainSuffix.$host" it.domain = "uonetplus-uczen$domainSuffix.$host"
cookies.cookieStore.add(URI("$schema://${it.domain}"), it) cookieJarCabinet.addStudentCookie(URI("$schema://${it.domain}"), it)
} }
} }

View file

@ -1,5 +1,6 @@
package io.github.wulkanowy.sdk.scrapper.login package io.github.wulkanowy.sdk.scrapper.login
import io.github.wulkanowy.sdk.scrapper.CookieJarCabinet
import io.github.wulkanowy.sdk.scrapper.Scrapper import io.github.wulkanowy.sdk.scrapper.Scrapper
import io.github.wulkanowy.sdk.scrapper.Scrapper.LoginType.ADFS import io.github.wulkanowy.sdk.scrapper.Scrapper.LoginType.ADFS
import io.github.wulkanowy.sdk.scrapper.Scrapper.LoginType.ADFSCards import io.github.wulkanowy.sdk.scrapper.Scrapper.LoginType.ADFSCards
@ -19,7 +20,6 @@ import pl.droidsonroids.jspoon.Jspoon
import retrofit2.HttpException import retrofit2.HttpException
import retrofit2.Response import retrofit2.Response
import java.io.IOException import java.io.IOException
import java.net.CookieManager
import java.net.URLEncoder import java.net.URLEncoder
import java.time.Instant import java.time.Instant
import java.time.ZoneId import java.time.ZoneId
@ -35,7 +35,7 @@ internal class LoginHelper(
private val host: String, private val host: String,
private val domainSuffix: String, private val domainSuffix: String,
private val symbol: String, private val symbol: String,
private val cookies: CookieManager, private val cookieJarCabinet: CookieJarCabinet,
private val api: LoginService, private val api: LoginService,
private val urlGenerator: UrlGenerator, private val urlGenerator: UrlGenerator,
) { ) {
@ -145,12 +145,12 @@ internal class LoginHelper(
} }
fun logout() { fun logout() {
cookies.cookieStore.removeAll() cookieJarCabinet.onUserChange()
} }
suspend fun sendCredentials(email: String, password: String): CertificateResponse { suspend fun sendCredentials(email: String, password: String): CertificateResponse {
// always clear cookies to avoid problems with "request too large" errors // always clear cookies to avoid problems with "request too large" errors
cookies.cookieStore.removeAll() cookieJarCabinet.beforeUserLogIn()
email.substringBefore("||").let { email.substringBefore("||").let {
return when (loginType) { return when (loginType) {
AUTO -> throw ScrapperException("You must first specify Api.loginType before logging in") AUTO -> throw ScrapperException("You must first specify Api.loginType before logging in")

View file

@ -1,6 +1,7 @@
package io.github.wulkanowy.sdk.scrapper.service package io.github.wulkanowy.sdk.scrapper.service
import com.jakewharton.retrofit2.converter.kotlinx.serialization.asConverterFactory import com.jakewharton.retrofit2.converter.kotlinx.serialization.asConverterFactory
import io.github.wulkanowy.sdk.scrapper.CookieJarCabinet
import io.github.wulkanowy.sdk.scrapper.OkHttpClientBuilderFactory import io.github.wulkanowy.sdk.scrapper.OkHttpClientBuilderFactory
import io.github.wulkanowy.sdk.scrapper.Scrapper import io.github.wulkanowy.sdk.scrapper.Scrapper
import io.github.wulkanowy.sdk.scrapper.TLSSocketFactory import io.github.wulkanowy.sdk.scrapper.TLSSocketFactory
@ -26,7 +27,6 @@ import pl.droidsonroids.retrofit2.JspoonConverterFactory
import retrofit2.Retrofit import retrofit2.Retrofit
import retrofit2.converter.scalars.ScalarsConverterFactory import retrofit2.converter.scalars.ScalarsConverterFactory
import retrofit2.create import retrofit2.create
import java.net.CookieManager
import java.security.KeyStore import java.security.KeyStore
import java.time.LocalDate import java.time.LocalDate
import java.util.concurrent.TimeUnit.SECONDS import java.util.concurrent.TimeUnit.SECONDS
@ -35,8 +35,7 @@ import javax.net.ssl.X509TrustManager
internal class ServiceManager( internal class ServiceManager(
private val okHttpClientBuilderFactory: OkHttpClientBuilderFactory, private val okHttpClientBuilderFactory: OkHttpClientBuilderFactory,
private val cookies: CookieManager, private val cookieJarCabinet: CookieJarCabinet,
private val alternativeCookies: CookieManager,
logLevel: HttpLoggingInterceptor.Level, logLevel: HttpLoggingInterceptor.Level,
private val loginType: Scrapper.LoginType, private val loginType: Scrapper.LoginType,
private val schema: String, private val schema: String,
@ -73,7 +72,7 @@ internal class ServiceManager(
host = host, host = host,
domainSuffix = domainSuffix, domainSuffix = domainSuffix,
symbol = symbol, symbol = symbol,
cookies = cookies, cookieJarCabinet = cookieJarCabinet,
api = getLoginService(), api = getLoginService(),
urlGenerator = urlGenerator, urlGenerator = urlGenerator,
) )
@ -94,10 +93,10 @@ internal class ServiceManager(
private val interceptors: MutableList<Pair<Interceptor, Boolean>> = mutableListOf( private val interceptors: MutableList<Pair<Interceptor, Boolean>> = mutableListOf(
HttpLoggingInterceptor().setLevel(logLevel) to true, HttpLoggingInterceptor().setLevel(logLevel) to true,
ErrorInterceptor(cookies) to false, ErrorInterceptor(cookieJarCabinet) to false,
AutoLoginInterceptor( AutoLoginInterceptor(
loginType = loginType, loginType = loginType,
jar = cookies, cookieJarCabinet = cookieJarCabinet,
emptyCookieJarIntercept = emptyCookieJarIntercept, emptyCookieJarIntercept = emptyCookieJarIntercept,
notLoggedInCallback = { loginHelper.login(email, password) }, notLoggedInCallback = { loginHelper.login(email, password) },
fetchStudentCookies = { loginHelper.loginStudent() }, fetchStudentCookies = { loginHelper.loginStudent() },
@ -125,8 +124,6 @@ internal class ServiceManager(
interceptors.add(0, interceptor to network) interceptors.add(0, interceptor to network)
} }
fun getCookieManager() = cookies
fun getLoginService(): LoginService { fun getLoginService(): LoginService {
if (email.isBlank() && password.isBlank()) throw ScrapperException("Email and password are not set") if (email.isBlank() && password.isBlank()) throw ScrapperException("Email and password are not set")
if (email.isBlank()) throw ScrapperException("Email is not set") if (email.isBlank()) throw ScrapperException("Email is not set")
@ -175,7 +172,7 @@ internal class ServiceManager(
client.addInterceptor( client.addInterceptor(
StudentCookieInterceptor( StudentCookieInterceptor(
cookies = cookies, cookieJarCabinet = cookieJarCabinet,
schema = schema, schema = schema,
host = host, host = host,
domainSuffix = domainSuffix, domainSuffix = domainSuffix,
@ -234,7 +231,12 @@ internal class ServiceManager(
-> sslSocketFactory(TLSSocketFactory(), trustManager) -> sslSocketFactory(TLSSocketFactory(), trustManager)
} }
} }
.cookieJar(if (!separateJar) JavaNetCookieJar(cookies) else JavaNetCookieJar(alternativeCookies)) .cookieJar(
when {
separateJar -> JavaNetCookieJar(cookieJarCabinet.alternativeCookieManager)
else -> JavaNetCookieJar(cookieJarCabinet.userCookieManager)
},
)
.apply { .apply {
interceptors.forEach { interceptors.forEach {
if (it.first is ErrorInterceptor || it.first is AutoLoginInterceptor) { if (it.first is ErrorInterceptor || it.first is AutoLoginInterceptor) {

View file

@ -24,7 +24,6 @@ import org.junit.After
import pl.droidsonroids.retrofit2.JspoonConverterFactory import pl.droidsonroids.retrofit2.JspoonConverterFactory
import retrofit2.Retrofit import retrofit2.Retrofit
import retrofit2.converter.scalars.ScalarsConverterFactory import retrofit2.converter.scalars.ScalarsConverterFactory
import java.net.CookieManager
import java.net.URL import java.net.URL
abstract class BaseLocalTest : BaseTest() { abstract class BaseLocalTest : BaseTest() {
@ -95,7 +94,7 @@ abstract class BaseLocalTest : BaseTest() {
autoLoginInterceptor: AutoLoginInterceptor = getAutoLoginInterceptor(loginType, autoLogin), autoLoginInterceptor: AutoLoginInterceptor = getAutoLoginInterceptor(loginType, autoLogin),
): OkHttpClient = OkHttpClient.Builder() ): OkHttpClient = OkHttpClient.Builder()
.apply { .apply {
if (errorInterceptor) addInterceptor(ErrorInterceptor(CookieManager())) if (errorInterceptor) addInterceptor(ErrorInterceptor(CookieJarCabinet()))
if (autoLoginInterceptorOn) addInterceptor(autoLoginInterceptor) if (autoLoginInterceptorOn) addInterceptor(autoLoginInterceptor)
} }
.addInterceptor(HttpLoggingInterceptor().setLevel(HttpLoggingInterceptor.Level.BASIC)) .addInterceptor(HttpLoggingInterceptor().setLevel(HttpLoggingInterceptor.Level.BASIC))
@ -105,7 +104,7 @@ abstract class BaseLocalTest : BaseTest() {
private fun getAutoLoginInterceptor(loginType: Scrapper.LoginType, autoLogin: Boolean): AutoLoginInterceptor { private fun getAutoLoginInterceptor(loginType: Scrapper.LoginType, autoLogin: Boolean): AutoLoginInterceptor {
return AutoLoginInterceptor( return AutoLoginInterceptor(
loginType = loginType, loginType = loginType,
jar = CookieManager(), cookieJarCabinet = CookieJarCabinet(),
notLoggedInCallback = { notLoggedInCallback = {
if (autoLogin) { if (autoLogin) {
LoginHelper( LoginHelper(
@ -114,7 +113,7 @@ abstract class BaseLocalTest : BaseTest() {
host = "localhost", host = "localhost",
domainSuffix = "", domainSuffix = "",
symbol = "powiatwulkanowy", symbol = "powiatwulkanowy",
cookies = CookieManager(), cookieJarCabinet = CookieJarCabinet(),
api = getService(LoginService::class.java), api = getService(LoginService::class.java),
urlGenerator = UrlGenerator(URL("http://localhost/"), "", "lodz", ""), urlGenerator = UrlGenerator(URL("http://localhost/"), "", "lodz", ""),
).login("jan", "kowalski") ).login("jan", "kowalski")

View file

@ -1,6 +1,7 @@
package io.github.wulkanowy.sdk.scrapper.interceptor package io.github.wulkanowy.sdk.scrapper.interceptor
import io.github.wulkanowy.sdk.scrapper.BaseLocalTest import io.github.wulkanowy.sdk.scrapper.BaseLocalTest
import io.github.wulkanowy.sdk.scrapper.CookieJarCabinet
import io.github.wulkanowy.sdk.scrapper.Scrapper import io.github.wulkanowy.sdk.scrapper.Scrapper
import io.github.wulkanowy.sdk.scrapper.login.LoginHelper import io.github.wulkanowy.sdk.scrapper.login.LoginHelper
import io.github.wulkanowy.sdk.scrapper.login.LoginTest import io.github.wulkanowy.sdk.scrapper.login.LoginTest
@ -16,7 +17,6 @@ import kotlinx.coroutines.supervisorScope
import org.junit.Assert.assertEquals import org.junit.Assert.assertEquals
import org.junit.Assert.assertTrue import org.junit.Assert.assertTrue
import org.junit.Test import org.junit.Test
import java.net.CookieManager
import java.net.URL import java.net.URL
class AutoLoginInterceptorTest : BaseLocalTest() { class AutoLoginInterceptorTest : BaseLocalTest() {
@ -128,7 +128,7 @@ class AutoLoginInterceptorTest : BaseLocalTest() {
host = "${server.hostName}:${server.port}", host = "${server.hostName}:${server.port}",
domainSuffix = "", domainSuffix = "",
symbol = "powiatwulkanowy", symbol = "powiatwulkanowy",
cookies = CookieManager(), cookieJarCabinet = CookieJarCabinet(),
api = loginService, api = loginService,
urlGenerator = UrlGenerator(URL("http://localhost/"), "", "lodz", ""), urlGenerator = UrlGenerator(URL("http://localhost/"), "", "lodz", ""),
) )
@ -137,7 +137,7 @@ class AutoLoginInterceptorTest : BaseLocalTest() {
private fun getService(checkJar: Boolean = false, notLoggedInCallback: suspend () -> Unit): StudentService { private fun getService(checkJar: Boolean = false, notLoggedInCallback: suspend () -> Unit): StudentService {
val interceptor = AutoLoginInterceptor( val interceptor = AutoLoginInterceptor(
loginType = Scrapper.LoginType.STANDARD, loginType = Scrapper.LoginType.STANDARD,
jar = CookieManager(), cookieJarCabinet = CookieJarCabinet(),
emptyCookieJarIntercept = checkJar, emptyCookieJarIntercept = checkJar,
notLoggedInCallback = notLoggedInCallback, notLoggedInCallback = notLoggedInCallback,
fetchStudentCookies = {}, fetchStudentCookies = {},

View file

@ -1,6 +1,7 @@
package io.github.wulkanowy.sdk.scrapper.login package io.github.wulkanowy.sdk.scrapper.login
import io.github.wulkanowy.sdk.scrapper.BaseLocalTest import io.github.wulkanowy.sdk.scrapper.BaseLocalTest
import io.github.wulkanowy.sdk.scrapper.CookieJarCabinet
import io.github.wulkanowy.sdk.scrapper.Scrapper import io.github.wulkanowy.sdk.scrapper.Scrapper
import io.github.wulkanowy.sdk.scrapper.exception.AccountInactiveException import io.github.wulkanowy.sdk.scrapper.exception.AccountInactiveException
import io.github.wulkanowy.sdk.scrapper.exception.VulcanException import io.github.wulkanowy.sdk.scrapper.exception.VulcanException
@ -11,7 +12,6 @@ import org.junit.Assert.assertEquals
import org.junit.Assert.assertFalse import org.junit.Assert.assertFalse
import org.junit.Assert.assertTrue import org.junit.Assert.assertTrue
import org.junit.Test import org.junit.Test
import java.net.CookieManager
import java.net.URL import java.net.URL
class LoginTest : BaseLocalTest() { class LoginTest : BaseLocalTest() {
@ -23,7 +23,7 @@ class LoginTest : BaseLocalTest() {
host = "fakelog.localhost:3000", host = "fakelog.localhost:3000",
domainSuffix = "", domainSuffix = "",
symbol = "default", symbol = "default",
cookies = CookieManager(), cookieJarCabinet = CookieJarCabinet(),
api = getService(LoginService::class.java, "http://fakelog.localhost:3000/"), api = getService(LoginService::class.java, "http://fakelog.localhost:3000/"),
urlGenerator = UrlGenerator(URL("http://localhost/"), "", "lodz", ""), urlGenerator = UrlGenerator(URL("http://localhost/"), "", "lodz", ""),
) )
@ -36,7 +36,7 @@ class LoginTest : BaseLocalTest() {
host = "fakelog.localhost:3000", host = "fakelog.localhost:3000",
domainSuffix = "", domainSuffix = "",
symbol = "default", symbol = "default",
cookies = CookieManager(), cookieJarCabinet = CookieJarCabinet(),
api = getService( api = getService(
service = LoginService::class.java, service = LoginService::class.java,
url = "http://fakelog.localhost:3000/", url = "http://fakelog.localhost:3000/",

View file

@ -1,6 +1,7 @@
package io.github.wulkanowy.sdk.scrapper.register package io.github.wulkanowy.sdk.scrapper.register
import io.github.wulkanowy.sdk.scrapper.BaseLocalTest import io.github.wulkanowy.sdk.scrapper.BaseLocalTest
import io.github.wulkanowy.sdk.scrapper.CookieJarCabinet
import io.github.wulkanowy.sdk.scrapper.Scrapper import io.github.wulkanowy.sdk.scrapper.Scrapper
import io.github.wulkanowy.sdk.scrapper.login.LoginHelper import io.github.wulkanowy.sdk.scrapper.login.LoginHelper
import io.github.wulkanowy.sdk.scrapper.login.LoginTest import io.github.wulkanowy.sdk.scrapper.login.LoginTest
@ -12,7 +13,6 @@ import io.github.wulkanowy.sdk.scrapper.service.StudentService
import kotlinx.coroutines.test.runTest import kotlinx.coroutines.test.runTest
import org.junit.Assert.assertEquals import org.junit.Assert.assertEquals
import org.junit.Test import org.junit.Test
import java.net.CookieManager
import java.net.URL import java.net.URL
class RegisterTest : BaseLocalTest() { class RegisterTest : BaseLocalTest() {
@ -24,7 +24,7 @@ class RegisterTest : BaseLocalTest() {
host = "fakelog.localhost:3000", host = "fakelog.localhost:3000",
domainSuffix = "", domainSuffix = "",
symbol = "default", symbol = "default",
cookies = CookieManager(), cookieJarCabinet = CookieJarCabinet(),
api = getService( api = getService(
service = LoginService::class.java, service = LoginService::class.java,
url = "http://fakelog.localhost:3000/", url = "http://fakelog.localhost:3000/",

View file

@ -1,6 +1,7 @@
package io.github.wulkanowy.sdk.scrapper.repository package io.github.wulkanowy.sdk.scrapper.repository
import io.github.wulkanowy.sdk.scrapper.BaseLocalTest import io.github.wulkanowy.sdk.scrapper.BaseLocalTest
import io.github.wulkanowy.sdk.scrapper.CookieJarCabinet
import io.github.wulkanowy.sdk.scrapper.Scrapper import io.github.wulkanowy.sdk.scrapper.Scrapper
import io.github.wulkanowy.sdk.scrapper.exception.VulcanException import io.github.wulkanowy.sdk.scrapper.exception.VulcanException
import io.github.wulkanowy.sdk.scrapper.interceptor.ErrorInterceptorTest import io.github.wulkanowy.sdk.scrapper.interceptor.ErrorInterceptorTest
@ -16,7 +17,6 @@ import kotlinx.coroutines.test.runTest
import org.junit.Assert.assertEquals import org.junit.Assert.assertEquals
import org.junit.Assert.assertTrue import org.junit.Assert.assertTrue
import org.junit.Test import org.junit.Test
import java.net.CookieManager
import java.net.URL import java.net.URL
class RegisterRepositoryTest : BaseLocalTest() { class RegisterRepositoryTest : BaseLocalTest() {
@ -34,7 +34,7 @@ class RegisterRepositoryTest : BaseLocalTest() {
host = "fakelog.localhost:3000", host = "fakelog.localhost:3000",
domainSuffix = "", domainSuffix = "",
symbol = symbol, symbol = symbol,
cookies = CookieManager(), cookieJarCabinet = CookieJarCabinet(),
api = getService(LoginService::class.java, "http://fakelog.localhost:3000/"), api = getService(LoginService::class.java, "http://fakelog.localhost:3000/"),
urlGenerator = UrlGenerator(URL("http://localhost/"), "", "Default", ""), urlGenerator = UrlGenerator(URL("http://localhost/"), "", "Default", ""),
), ),

View file

@ -1,6 +1,7 @@
package io.github.wulkanowy.sdk.scrapper.service package io.github.wulkanowy.sdk.scrapper.service
import io.github.wulkanowy.sdk.scrapper.BaseLocalTest import io.github.wulkanowy.sdk.scrapper.BaseLocalTest
import io.github.wulkanowy.sdk.scrapper.CookieJarCabinet
import io.github.wulkanowy.sdk.scrapper.OkHttpClientBuilderFactory import io.github.wulkanowy.sdk.scrapper.OkHttpClientBuilderFactory
import io.github.wulkanowy.sdk.scrapper.Scrapper import io.github.wulkanowy.sdk.scrapper.Scrapper
import io.github.wulkanowy.sdk.scrapper.exception.ScrapperException import io.github.wulkanowy.sdk.scrapper.exception.ScrapperException
@ -14,7 +15,6 @@ import okhttp3.mockwebserver.MockResponse
import org.junit.Assert.assertEquals import org.junit.Assert.assertEquals
import org.junit.Assert.assertTrue import org.junit.Assert.assertTrue
import org.junit.Test import org.junit.Test
import java.net.CookieManager
import java.net.URL import java.net.URL
class ServiceManagerTest : BaseLocalTest() { class ServiceManagerTest : BaseLocalTest() {
@ -23,8 +23,7 @@ class ServiceManagerTest : BaseLocalTest() {
fun interceptorTest() { fun interceptorTest() {
val manager = ServiceManager( val manager = ServiceManager(
okHttpClientBuilderFactory = OkHttpClientBuilderFactory(), okHttpClientBuilderFactory = OkHttpClientBuilderFactory(),
cookies = CookieManager(), cookieJarCabinet = CookieJarCabinet(),
alternativeCookies = CookieManager(),
logLevel = HttpLoggingInterceptor.Level.NONE, logLevel = HttpLoggingInterceptor.Level.NONE,
loginType = Scrapper.LoginType.STANDARD, loginType = Scrapper.LoginType.STANDARD,
schema = "http", schema = "http",
@ -58,8 +57,7 @@ class ServiceManagerTest : BaseLocalTest() {
server.start(3000) server.start(3000)
val manager = ServiceManager( val manager = ServiceManager(
okHttpClientBuilderFactory = OkHttpClientBuilderFactory(), okHttpClientBuilderFactory = OkHttpClientBuilderFactory(),
cookies = CookieManager(), cookieJarCabinet = CookieJarCabinet(),
alternativeCookies = CookieManager(),
logLevel = HttpLoggingInterceptor.Level.NONE, logLevel = HttpLoggingInterceptor.Level.NONE,
loginType = Scrapper.LoginType.STANDARD, loginType = Scrapper.LoginType.STANDARD,
schema = "http", schema = "http",
@ -131,8 +129,7 @@ class ServiceManagerTest : BaseLocalTest() {
server.start(3000) server.start(3000)
val manager = ServiceManager( val manager = ServiceManager(
okHttpClientBuilderFactory = OkHttpClientBuilderFactory(), okHttpClientBuilderFactory = OkHttpClientBuilderFactory(),
cookies = CookieManager(), cookieJarCabinet = CookieJarCabinet(),
alternativeCookies = CookieManager(),
logLevel = HttpLoggingInterceptor.Level.NONE, logLevel = HttpLoggingInterceptor.Level.NONE,
loginType = Scrapper.LoginType.STANDARD, loginType = Scrapper.LoginType.STANDARD,
schema = "http", schema = "http",

View file

@ -7,7 +7,6 @@ public final class io/github/wulkanowy/sdk/Sdk {
public static synthetic fun deleteMessages$default (Lio/github/wulkanowy/sdk/Sdk;Ljava/util/List;ZLkotlin/coroutines/Continuation;ILjava/lang/Object;)Ljava/lang/Object; public static synthetic fun deleteMessages$default (Lio/github/wulkanowy/sdk/Sdk;Ljava/util/List;ZLkotlin/coroutines/Continuation;ILjava/lang/Object;)Ljava/lang/Object;
public final fun excuseForAbsence (Ljava/util/List;Ljava/lang/String;Lkotlin/coroutines/Continuation;)Ljava/lang/Object; public final fun excuseForAbsence (Ljava/util/List;Ljava/lang/String;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
public static synthetic fun excuseForAbsence$default (Lio/github/wulkanowy/sdk/Sdk;Ljava/util/List;Ljava/lang/String;Lkotlin/coroutines/Continuation;ILjava/lang/Object;)Ljava/lang/Object; public static synthetic fun excuseForAbsence$default (Lio/github/wulkanowy/sdk/Sdk;Ljava/util/List;Ljava/lang/String;Lkotlin/coroutines/Continuation;ILjava/lang/Object;)Ljava/lang/Object;
public final fun getAlternativeCookieManager ()Ljava/net/CookieManager;
public final fun getAndroidVersion ()Ljava/lang/String; public final fun getAndroidVersion ()Ljava/lang/String;
public final fun getAttendance (Ljava/time/LocalDate;Ljava/time/LocalDate;Lkotlin/coroutines/Continuation;)Ljava/lang/Object; public final fun getAttendance (Ljava/time/LocalDate;Ljava/time/LocalDate;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
public final fun getAttendanceSummary (Ljava/lang/Integer;Lkotlin/coroutines/Continuation;)Ljava/lang/Object; public final fun getAttendanceSummary (Ljava/lang/Integer;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
@ -17,7 +16,6 @@ public final class io/github/wulkanowy/sdk/Sdk {
public final fun getCompletedLessons (Ljava/time/LocalDate;Ljava/time/LocalDate;ILkotlin/coroutines/Continuation;)Ljava/lang/Object; public final fun getCompletedLessons (Ljava/time/LocalDate;Ljava/time/LocalDate;ILkotlin/coroutines/Continuation;)Ljava/lang/Object;
public static synthetic fun getCompletedLessons$default (Lio/github/wulkanowy/sdk/Sdk;Ljava/time/LocalDate;Ljava/time/LocalDate;ILkotlin/coroutines/Continuation;ILjava/lang/Object;)Ljava/lang/Object; public static synthetic fun getCompletedLessons$default (Lio/github/wulkanowy/sdk/Sdk;Ljava/time/LocalDate;Ljava/time/LocalDate;ILkotlin/coroutines/Continuation;ILjava/lang/Object;)Ljava/lang/Object;
public final fun getConferences (Lkotlin/coroutines/Continuation;)Ljava/lang/Object; public final fun getConferences (Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
public final fun getCookieManager ()Ljava/net/CookieManager;
public final fun getCurrentStudent (Lkotlin/coroutines/Continuation;)Ljava/lang/Object; public final fun getCurrentStudent (Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
public final fun getDeletedMessages (Ljava/lang/String;Lkotlin/coroutines/Continuation;)Ljava/lang/Object; public final fun getDeletedMessages (Ljava/lang/String;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
public static synthetic fun getDeletedMessages$default (Lio/github/wulkanowy/sdk/Sdk;Ljava/lang/String;Lkotlin/coroutines/Continuation;ILjava/lang/Object;)Ljava/lang/Object; public static synthetic fun getDeletedMessages$default (Lio/github/wulkanowy/sdk/Sdk;Ljava/lang/String;Lkotlin/coroutines/Continuation;ILjava/lang/Object;)Ljava/lang/Object;
@ -90,6 +88,7 @@ public final class io/github/wulkanowy/sdk/Sdk {
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 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; public final fun sendMessage (Ljava/lang/String;Ljava/lang/String;Ljava/util/List;Ljava/lang/String;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
public final fun sendPasswordResetRequest (Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Lkotlin/coroutines/Continuation;)Ljava/lang/Object; public final fun sendPasswordResetRequest (Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
public final fun setAdditionalCookieManager (Ljava/net/CookieManager;)V
public final fun setAndroidVersion (Ljava/lang/String;)V public final fun setAndroidVersion (Ljava/lang/String;)V
public final fun setBuildTag (Ljava/lang/String;)V public final fun setBuildTag (Ljava/lang/String;)V
public final fun setClassId (I)V public final fun setClassId (I)V

View file

@ -98,10 +98,6 @@ class Sdk {
private val registerTimeZone = ZoneId.of("Europe/Warsaw") private val registerTimeZone = ZoneId.of("Europe/Warsaw")
val cookieManager: CookieManager = scrapper.cookieManager
val alternativeCookieManager: CookieManager = scrapper.alternativeCookieManager
var mode = Mode.SCRAPPER var mode = Mode.SCRAPPER
var mobileBaseUrl = "" var mobileBaseUrl = ""
@ -244,6 +240,10 @@ class Sdk {
interceptors.add(interceptor to network) interceptors.add(interceptor to network)
} }
fun setAdditionalCookieManager(cookieManager: CookieManager) {
scrapper.setAdditionalCookieManager(cookieManager)
}
fun switchDiary(diaryId: Int, kindergartenDiaryId: Int, schoolYear: Int): Sdk { fun switchDiary(diaryId: Int, kindergartenDiaryId: Int, schoolYear: Int): Sdk {
return also { return also {
it.diaryId = diaryId it.diaryId = diaryId