diff --git a/build.gradle b/build.gradle index 889112b2..ddabf21a 100644 --- a/build.gradle +++ b/build.gradle @@ -18,7 +18,7 @@ apply plugin: 'com.jfrog.bintray' apply plugin: 'com.github.dcendents.android-maven' def libName = 'KotlinInside' -def libVersion = '1.1.3' +def libVersion = '1.2.0' def libDesc = 'Unofficial DCInside API written in Kotlin' group = 'be.zvz' diff --git a/src/main/kotlin/be/zvz/kotlininside/KotlinInside.kt b/src/main/kotlin/be/zvz/kotlininside/KotlinInside.kt index 4d1bf369..03826ccd 100644 --- a/src/main/kotlin/be/zvz/kotlininside/KotlinInside.kt +++ b/src/main/kotlin/be/zvz/kotlininside/KotlinInside.kt @@ -11,15 +11,12 @@ class KotlinInside private constructor( val httpInterface: HttpInterface ) { val auth: Auth = Auth() - var hashedAppKey: String + lateinit var hashedAppKey: String lateinit var app: App lateinit var session: Session - init { - this.hashedAppKey = auth.generateHashedAppKey() - } - private fun init() { + this.hashedAppKey = auth.generateHashedAppKey() this.app = App(hashedAppKey, auth.fetchAppId(hashedAppKey)) this.session = auth.login(user) } diff --git a/src/main/kotlin/be/zvz/kotlininside/security/Auth.kt b/src/main/kotlin/be/zvz/kotlininside/security/Auth.kt index 72019afd..83b8cf93 100644 --- a/src/main/kotlin/be/zvz/kotlininside/security/Auth.kt +++ b/src/main/kotlin/be/zvz/kotlininside/security/Auth.kt @@ -14,7 +14,6 @@ import be.zvz.kotlininside.session.user.UserType import be.zvz.kotlininside.value.ApiUrl import be.zvz.kotlininside.value.Const import org.apache.commons.codec.digest.DigestUtils -import java.lang.RuntimeException import java.text.SimpleDateFormat import java.util.TimeZone import java.util.Date @@ -27,6 +26,7 @@ class Auth { */ private val simpleDateFormat = SimpleDateFormat("yyyyMMddHH", Locale.getDefault()) + private lateinit var time: String init { simpleDateFormat.timeZone = TimeZone.getTimeZone("Asia/Seoul") @@ -34,56 +34,76 @@ class Auth { data class AppCheck( val result: Boolean, - val version: String, - val notice: Boolean, - val noticeUpdate: Boolean, - val date: String + val version: String? = null, + val notice: Boolean? = null, + val noticeUpdate: Boolean? = null, + val date: String? = null ) /** * app_check에서 정보를 얻어오는 메소드입니다. - * @return [AppCheck]|null AppCheck 또는 null을 반환합니다. + * @return [AppCheck] AppCheck 또는 null을 반환합니다. + * @exception [HttpException] app_check에 접근 할 수 없는 경우, HttpException이 발생합니다. */ - fun getAppCheck(): AppCheck? { - val appCheck = try { - KotlinInside.getInstance().httpInterface.get(ApiUrl.Auth.APP_CHECK, Request.getDefaultOption()) - } catch (e: HttpException) { - throw RuntimeException("app_check에 접근할 수 없습니다") - } - - appCheck?.let { - if (!it.safeGet("result").isNull) - throw RuntimeException("app_check를 얻어올 수 없습니다") - - val json = it.index(0) - - return AppCheck( - result = it.get("result").`as`(Boolean::class.java), - version = it.get("ver").text(), - notice = it.get("notice").`as`(Boolean::class.java), - noticeUpdate = it.get("notice_update").`as`(Boolean::class.java), - date = it.get("date").text() + fun getAppCheck(): AppCheck { + val appCheck = KotlinInside.getInstance().httpInterface.get(ApiUrl.Auth.APP_CHECK, Request.getDefaultOption()) + + when { + appCheck !== null -> { + if (!appCheck.safeGet("result").isNull) + return AppCheck( + result = appCheck.get("result").`as`(Boolean::class.java) + ) + + val json = appCheck.index(0) + + return AppCheck( + result = json.get("result").`as`(Boolean::class.java), + version = json.get("ver").text(), + notice = json.get("notice").`as`(Boolean::class.java), + noticeUpdate = json.get("notice_update").`as`(Boolean::class.java), + date = json.get("date").text() + ) + } + else -> return AppCheck( + result = false ) } - - return null } fun generateHashedAppKey(): String { - val count = ((System.currentTimeMillis() / 1000) - 1_559_142_000) / (12 * 60 * 60) //2019/5/30 0:0:0 - return DigestUtils.sha256Hex("dcArdchk_${simpleDateFormat.format(Date())}$count") + val now = simpleDateFormat.format(Date()) + + if (!::time.isInitialized || time.substring(0, 10) != now) { //time이 아직 초기화되지 않았거나, time의 앞자리 (년월일시간)와 now가 다를때 + try { + getAppCheck().run { + date?.let { + time = it + return DigestUtils.sha256Hex("dcArdchk_$time") + } + } + } catch (e: Exception) { + } + } else { //now와 time 앞자리가 같을 때 + return DigestUtils.sha256Hex("dcArdchk_$time") + } + + // 예외가 발생했거나, 값이 null이어서 time을 제대로 설정하지 못한 경우 + val count = (((System.currentTimeMillis() / 1000) - 1_559_142_000) / (12 * 60 * 60)) - 1 //2019/5/30 0:0:0 + time = "$now$count" + return DigestUtils.sha256Hex("dcArdchk_$time") } - @Throws(RuntimeException::class) - fun getAppId(): String = when (val hashedAppKey = generateHashedAppKey()) { - KotlinInside.getInstance().app.token -> KotlinInside.getInstance().app.id - else -> { - KotlinInside.getInstance().app = App(hashedAppKey, fetchAppId(hashedAppKey)) - KotlinInside.getInstance().app.id + fun getAppId(): String { + return when (val hashedAppKey = generateHashedAppKey()) { + KotlinInside.getInstance().app.token -> KotlinInside.getInstance().app.id + else -> { + KotlinInside.getInstance().app = App(hashedAppKey, fetchAppId(hashedAppKey)) + KotlinInside.getInstance().app.id + } } } - @Throws(RuntimeException::class) fun fetchAppId(hashedAppKey: String): String { val appId = try { val option = Request.getDefaultOption() diff --git a/src/test/kotlin/be/zvz/kotlininside/KotlinInsideTest.kt b/src/test/kotlin/be/zvz/kotlininside/KotlinInsideTest.kt index 8e9632a5..87c4f3d9 100644 --- a/src/test/kotlin/be/zvz/kotlininside/KotlinInsideTest.kt +++ b/src/test/kotlin/be/zvz/kotlininside/KotlinInsideTest.kt @@ -1,12 +1,10 @@ /* - * This Kotlin source file was generated by the Gradle 'init' task. + * KotlinInside Junit5 Test */ package be.zvz.kotlininside import be.zvz.kotlininside.api.article.* -import be.zvz.kotlininside.api.type.Article -import be.zvz.kotlininside.api.type.StringContent -import be.zvz.kotlininside.api.type.HeadText +import be.zvz.kotlininside.api.type.* import be.zvz.kotlininside.http.DefaultHttpClient import be.zvz.kotlininside.session.user.Anonymous import org.junit.jupiter.api.MethodOrderer @@ -63,6 +61,12 @@ class KotlinInsideTest { content = mutableListOf( StringContent( string = "글은 곧 자동으로 삭제됩니다.\n글의 비밀번호는 1234입니다." + ), + MarkdownContent( + markdownString = "**Bold**\n~~취소선~~\n- [ ] Task List\n# 큰 글씨" + ), + HtmlContent( + htmlString = "취소선" ) ), headText = HeadText( @@ -70,7 +74,7 @@ class KotlinInsideTest { name = "일반", level = 0, selected = false - ) + ) //옵션입니다. 없어도 글 작성됩니다. ), session = KotlinInside.getInstance().session )