diff --git a/build.gradle.kts b/build.gradle.kts index 63d100c7..a3b71261 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -163,3 +163,11 @@ detekt { basePath = rootDir.absolutePath autoCorrect = true } + +tasks.withType().configureEach { + exclude("**/org/koin/ksp/generated/**") +} + +tasks.withType().configureEach { + exclude("**/org/koin/ksp/generated/**") +} diff --git a/src/main/kotlin/dev/usbharu/hideout/plugins/ActivityPub.kt b/src/main/kotlin/dev/usbharu/hideout/plugins/ActivityPub.kt index a85eb163..1a720bf9 100644 --- a/src/main/kotlin/dev/usbharu/hideout/plugins/ActivityPub.kt +++ b/src/main/kotlin/dev/usbharu/hideout/plugins/ActivityPub.kt @@ -75,7 +75,7 @@ val httpSignaturePlugin = createClientPlugin("HttpSign", ::HttpSignaturePluginCo } if (request.headers.contains("Signature")) { - val all = request.headers.getAll("Signature")!! + val all = request.headers.getAll("Signature").orEmpty() val parameters = mutableListOf() for (s in all) { s.split(",").forEach { parameters.add(it) } @@ -170,8 +170,12 @@ class KtorKeyMap(private val userAuthRepository: IUserRepository) : KeyMap { userAuthRepository.findByNameAndDomain( username, Config.configData.domain - )?.publicKey?.replace("-----BEGIN PUBLIC KEY-----", "-----END PUBLIC KEY-----")?.replace("", "") - ?.replace("\n", "") + )?.run { + publicKey + .replace("-----BEGIN PUBLIC KEY-----", "") + .replace("-----END PUBLIC KEY-----", "") + .replace("\n", "") + } ) val x509EncodedKeySpec = X509EncodedKeySpec(publicBytes) return@runBlocking KeyFactory.getInstance("RSA").generatePublic(x509EncodedKeySpec) @@ -184,8 +188,11 @@ class KtorKeyMap(private val userAuthRepository: IUserRepository) : KeyMap { userAuthRepository.findByNameAndDomain( username, Config.configData.domain - )?.privateKey?.replace("-----BEGIN PRIVATE KEY-----", "")?.replace("-----END PRIVATE KEY-----", "") - ?.replace("\n", "") + )?.privateKey?.run { + replace("-----BEGIN PRIVATE KEY-----", "") + .replace("-----END PRIVATE KEY-----", "") + .replace("\n", "") + } ) val x509EncodedKeySpec = PKCS8EncodedKeySpec(publicBytes) return@runBlocking KeyFactory.getInstance("RSA").generatePrivate(x509EncodedKeySpec) diff --git a/src/main/kotlin/dev/usbharu/hideout/routing/activitypub/UserRouting.kt b/src/main/kotlin/dev/usbharu/hideout/routing/activitypub/UserRouting.kt index 5a9edcb4..1814c62e 100644 --- a/src/main/kotlin/dev/usbharu/hideout/routing/activitypub/UserRouting.kt +++ b/src/main/kotlin/dev/usbharu/hideout/routing/activitypub/UserRouting.kt @@ -37,7 +37,7 @@ class ContentTypeRouteSelector(private vararg val contentType: ContentType) : Ro context.call.application.log.debug("Accept: ${context.call.request.accept()}") val requestContentType = context.call.request.accept() ?: return RouteSelectorEvaluation.FailedParameter return if (requestContentType.split(",") - .find { contentType.find { contentType -> contentType.match(it) } != null } != null + .any { contentType.any { contentType -> contentType.match(it) } } ) { RouteSelectorEvaluation.Constant } else { diff --git a/src/main/kotlin/dev/usbharu/kjob/exposed/ExposedJobRepository.kt b/src/main/kotlin/dev/usbharu/kjob/exposed/ExposedJobRepository.kt index af71d07f..f2cccc4d 100644 --- a/src/main/kotlin/dev/usbharu/kjob/exposed/ExposedJobRepository.kt +++ b/src/main/kotlin/dev/usbharu/kjob/exposed/ExposedJobRepository.kt @@ -279,35 +279,34 @@ class ExposedJobRepository( private fun ResultRow.toScheduledJob(): ScheduledJob { val single = this - jobs.run { - return ScheduledJob( - id = single[this.id].value.toString(), - status = JobStatus.valueOf(single[status]), - runAt = single[runAt]?.let { Instant.ofEpochMilli(it) }, - statusMessage = single[statusMessage], - retries = single[retries], - kjobId = single[kjobId]?.let { - try { - @Suppress("SwallowedException") - UUID.fromString(it) - } catch (ignored: IllegalArgumentException) { - null - } - }, - createdAt = Instant.ofEpochMilli(single[createdAt]), - updatedAt = Instant.ofEpochMilli(single[updatedAt]), - settings = JobSettings( - id = single[jobId], - name = single[name], - properties = single[properties].parseJsonMap() - ), - progress = JobProgress( - step = single[step].toLong(), - max = single[max]?.toLong(), - startedAt = single[startedAt]?.let { Instant.ofEpochMilli(it) }, - completedAt = single[completedAt]?.let { Instant.ofEpochMilli(it) } - ) + + return ScheduledJob( + id = single[jobs.id].value.toString(), + status = JobStatus.valueOf(single[jobs.status]), + runAt = single[jobs.runAt]?.let { Instant.ofEpochMilli(it) }, + statusMessage = single[jobs.statusMessage], + retries = single[jobs.retries], + kjobId = single[jobs.kjobId]?.let { + try { + @Suppress("SwallowedException") + UUID.fromString(it) + } catch (ignored: IllegalArgumentException) { + null + } + }, + createdAt = Instant.ofEpochMilli(single[jobs.createdAt]), + updatedAt = Instant.ofEpochMilli(single[jobs.updatedAt]), + settings = JobSettings( + id = single[jobs.jobId], + name = single[jobs.name], + properties = single[jobs.properties].parseJsonMap() + ), + progress = JobProgress( + step = single[jobs.step].toLong(), + max = single[jobs.max]?.toLong(), + startedAt = single[jobs.startedAt]?.let { Instant.ofEpochMilli(it) }, + completedAt = single[jobs.completedAt]?.let { Instant.ofEpochMilli(it) } ) - } + ) } } diff --git a/src/test/kotlin/dev/usbharu/hideout/routing/activitypub/ContentTypeRouteSelectorTest.kt b/src/test/kotlin/dev/usbharu/hideout/routing/activitypub/ContentTypeRouteSelectorTest.kt new file mode 100644 index 00000000..71513fef --- /dev/null +++ b/src/test/kotlin/dev/usbharu/hideout/routing/activitypub/ContentTypeRouteSelectorTest.kt @@ -0,0 +1,134 @@ +package dev.usbharu.hideout.routing.activitypub + +import io.ktor.client.request.* +import io.ktor.client.statement.* +import io.ktor.http.* +import io.ktor.server.application.* +import io.ktor.server.config.* +import io.ktor.server.response.* +import io.ktor.server.routing.* +import io.ktor.server.testing.* +import org.junit.jupiter.api.Test +import kotlin.test.assertEquals + +class ContentTypeRouteSelectorTest { + @Test + fun `Content-Typeが一つでマッチする`() = testApplication { + environment { + config = ApplicationConfig("empty.conf") + } + application { + routing { + route("/test") { + createChild(ContentTypeRouteSelector(ContentType.Application.Json)).handle { + call.respondText("OK") + } + get { + call.respondText("NG") + } + } + } + } + + client.get("/test"){ + accept(ContentType.Text.Html) + }.apply { + assertEquals("NG", bodyAsText()) + } + client.get("/test") { + accept(ContentType.Application.Json) + }.apply { + assertEquals("OK", bodyAsText()) + } + } + + @Test + fun `Content-Typeが一つのとき違うとマッチしない`() = testApplication { + environment { + config = ApplicationConfig("empty.conf") + } + application { + routing { + route("/test") { + createChild(ContentTypeRouteSelector(ContentType.Application.Json)).handle { + call.respondText("OK") + } + get { + call.respondText("NG") + } + } + } + } + + client.get("/test"){ + accept(ContentType.Text.Html) + }.apply { + assertEquals("NG", bodyAsText()) + } + } + + @Test + fun `Content-Typeがからのときマッチしない`() = testApplication { + environment { + config = ApplicationConfig("empty.conf") + } + application { + routing { + route("/test") { + createChild(ContentTypeRouteSelector()).handle { + call.respondText("OK") + } + get { + call.respondText("NG") + } + } + } + } + + client.get("/test"){ + accept(ContentType.Text.Html) + }.apply { + assertEquals("NG", bodyAsText()) + } + + client.get("/test").apply { + assertEquals("NG", bodyAsText()) + } + } + + @Test + fun `Content-Typeが複数指定されていてマッチする`() = testApplication { + environment { + config = ApplicationConfig("empty.conf") + } + application { + routing { + route("/test") { + createChild(ContentTypeRouteSelector(ContentType.Application.Json, ContentType.Text.Html)).handle { + call.respondText("OK") + } + get { + call.respondText("NG") + } + } + } + } + + client.get("/test"){ + accept(ContentType.Text.Html) + }.apply { + assertEquals("OK", bodyAsText()) + } + + client.get("/test"){ + accept(ContentType.Application.Json) + }.apply { + assertEquals("OK", bodyAsText()) + } + client.get("/test"){ + accept(ContentType.Application.Xml) + }.apply { + assertEquals("NG", bodyAsText()) + } + } +}