chore: coreからmastodonにテンプレートを移動

This commit is contained in:
usbharu 2024-06-03 00:44:43 +09:00
parent 71eeb47169
commit 23507f1812
70 changed files with 236 additions and 38 deletions

View File

@ -16,13 +16,54 @@
plugins { plugins {
alias(libs.plugins.kotlin.jvm) alias(libs.plugins.kotlin.jvm)
alias(libs.plugins.spring.boot)
alias(libs.plugins.kotlin.spring)
}
apply {
plugin("io.spring.dependency-management")
}
repositories {
mavenCentral()
maven {
url = uri("https://git.usbharu.dev/api/packages/usbharu/maven")
}
maven {
name = "GitHubPackages"
url = uri("https://maven.pkg.github.com/usbharu/http-signature")
credentials {
username = project.findProperty("gpr.user") as String? ?: System.getenv("USERNAME")
password = project.findProperty("gpr.key") as String? ?: System.getenv("TOKEN")
}
}
maven {
name = "GitHubPackages2"
url = uri("https://maven.pkg.github.com/multim-dev/emoji-kt")
credentials {
username = project.findProperty("gpr.user") as String? ?: System.getenv("USERNAME")
password = project.findProperty("gpr.key") as String? ?: System.getenv("TOKEN")
}
}
}
configurations {
all {
exclude("org.springframework.boot", "spring-boot-starter-logging")
exclude("ch.qos.logback", "logback-classic")
}
} }
dependencies { dependencies {
implementation("dev.usbharu:hideout-core:0.0.1") implementation("dev.usbharu:hideout-core:0.0.1")
implementation("dev.usbharu:hideout-worker:0.0.1") implementation("dev.usbharu:hideout-mastodon:1.0-SNAPSHOT")
} }
tasks.register("run") { tasks.register("run") {
dependsOn(gradle.includedBuild("hideout-core").task(":run")) dependsOn(gradle.includedBuild("hideout-core").task(":run"))
} }
springBoot {
mainClass = "dev.usbharu.hideout.SpringApplicationKt"
}

View File

@ -4,14 +4,12 @@ import com.github.jk1.license.importer.DependencyDataImporter
import com.github.jk1.license.importer.XmlReportImporter import com.github.jk1.license.importer.XmlReportImporter
import com.github.jk1.license.render.* import com.github.jk1.license.render.*
import org.jetbrains.kotlin.gradle.tasks.KotlinCompile import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
import org.openapitools.generator.gradle.plugin.tasks.GenerateTask
plugins { plugins {
alias(libs.plugins.kotlin.jvm) alias(libs.plugins.kotlin.jvm)
alias(libs.plugins.detekt) alias(libs.plugins.detekt)
alias(libs.plugins.spring.boot) alias(libs.plugins.spring.boot)
alias(libs.plugins.kotlin.spring) alias(libs.plugins.kotlin.spring)
alias(libs.plugins.openapi.generator)
alias(libs.plugins.kover) alias(libs.plugins.kover)
alias(libs.plugins.license.report) alias(libs.plugins.license.report)
@ -102,26 +100,6 @@ tasks.clean {
delete += listOf("$rootDir/src/main/resources/static") delete += listOf("$rootDir/src/main/resources/static")
} }
tasks.create<GenerateTask>("openApiGenerateMastodonCompatibleApi", GenerateTask::class) {
generatorName.set("kotlin-spring")
inputSpec.set("$rootDir/src/main/resources/openapi/mastodon.yaml")
outputDir.set("$buildDir/generated/sources/mastodon")
apiPackage.set("dev.usbharu.hideout.controller.mastodon.generated")
modelPackage.set("dev.usbharu.hideout.domain.mastodon.model.generated")
configOptions.put("interfaceOnly", "true")
configOptions.put("useSpringBoot3", "true")
configOptions.put("reactive", "true")
additionalProperties.put("useTags", "true")
importMappings.put("org.springframework.core.io.Resource", "org.springframework.web.multipart.MultipartFile")
typeMappings.put("org.springframework.core.io.Resource", "org.springframework.web.multipart.MultipartFile")
schemaMappings.put(
"StatusesRequest",
"dev.usbharu.hideout.mastodon.interfaces.api.status.StatusesRequest"
)
templateDir.set("$rootDir/templates")
}
repositories { repositories {
mavenCentral() mavenCentral()
maven { maven {

View File

@ -16,8 +16,8 @@
package dev.usbharu.hideout.core.application.actor package dev.usbharu.hideout.core.application.actor
import dev.usbharu.hideout.application.config.ApplicationConfig
import dev.usbharu.hideout.core.application.shared.Transaction import dev.usbharu.hideout.core.application.shared.Transaction
import dev.usbharu.hideout.core.config.ApplicationConfig
import dev.usbharu.hideout.core.domain.model.actor.ActorRepository import dev.usbharu.hideout.core.domain.model.actor.ActorRepository
import dev.usbharu.hideout.core.domain.model.instance.InstanceRepository import dev.usbharu.hideout.core.domain.model.instance.InstanceRepository
import dev.usbharu.hideout.core.domain.model.userdetails.UserDetail import dev.usbharu.hideout.core.domain.model.userdetails.UserDetail

View File

@ -0,0 +1,26 @@
/*
* Copyright (C) 2024 usbharu
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package dev.usbharu.hideout.core.config
import org.springframework.boot.context.properties.ConfigurationProperties
import java.net.URL
@ConfigurationProperties("hideout")
data class ApplicationConfig(
val url: URL,
val private: Boolean = true,
)

View File

@ -16,7 +16,7 @@
package dev.usbharu.hideout.core.domain.service.actor package dev.usbharu.hideout.core.domain.service.actor
import dev.usbharu.hideout.application.config.ApplicationConfig import dev.usbharu.hideout.core.config.ApplicationConfig
import dev.usbharu.hideout.core.domain.model.actor.Actor import dev.usbharu.hideout.core.domain.model.actor.Actor
import org.springframework.stereotype.Service import org.springframework.stereotype.Service

View File

@ -16,7 +16,7 @@
package dev.usbharu.hideout.core.infrastructure.factory package dev.usbharu.hideout.core.infrastructure.factory
import dev.usbharu.hideout.application.config.ApplicationConfig import dev.usbharu.hideout.core.config.ApplicationConfig
import dev.usbharu.hideout.core.domain.model.actor.* import dev.usbharu.hideout.core.domain.model.actor.*
import dev.usbharu.hideout.core.domain.model.instance.InstanceId import dev.usbharu.hideout.core.domain.model.instance.InstanceId
import dev.usbharu.hideout.core.domain.model.shared.Domain import dev.usbharu.hideout.core.domain.model.shared.Domain

View File

@ -16,7 +16,7 @@
package dev.usbharu.hideout.core.infrastructure.factory package dev.usbharu.hideout.core.infrastructure.factory
import dev.usbharu.hideout.application.config.ApplicationConfig import dev.usbharu.hideout.core.config.ApplicationConfig
import dev.usbharu.hideout.core.domain.model.actor.ActorId import dev.usbharu.hideout.core.domain.model.actor.ActorId
import dev.usbharu.hideout.core.domain.model.actor.ActorName import dev.usbharu.hideout.core.domain.model.actor.ActorName
import dev.usbharu.hideout.core.domain.model.media.MediaId import dev.usbharu.hideout.core.domain.model.media.MediaId

View File

@ -0,0 +1,22 @@
/*
* Copyright (C) 2024 usbharu
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package dev.usbharu.hideout.generate
@MustBeDocumented
@Retention(AnnotationRetention.RUNTIME)
@Target(AnnotationTarget.VALUE_PARAMETER)
annotation class JsonOrFormBind

View File

@ -0,0 +1,78 @@
/*
* Copyright (C) 2024 usbharu
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package dev.usbharu.hideout.generate
import org.slf4j.Logger
import org.slf4j.LoggerFactory
import org.springframework.core.MethodParameter
import org.springframework.validation.BindException
import org.springframework.web.bind.support.WebDataBinderFactory
import org.springframework.web.context.request.NativeWebRequest
import org.springframework.web.method.annotation.ModelAttributeMethodProcessor
import org.springframework.web.method.support.HandlerMethodArgumentResolver
import org.springframework.web.method.support.ModelAndViewContainer
import org.springframework.web.servlet.mvc.method.annotation.RequestResponseBodyMethodProcessor
@Suppress("TooGenericExceptionCaught")
class JsonOrFormModelMethodProcessor(
private val modelAttributeMethodProcessor: ModelAttributeMethodProcessor,
private val requestResponseBodyMethodProcessor: RequestResponseBodyMethodProcessor,
) : HandlerMethodArgumentResolver {
private val isJsonRegex = Regex("application/((\\w*)\\+)?json")
override fun supportsParameter(parameter: MethodParameter): Boolean =
parameter.hasParameterAnnotation(JsonOrFormBind::class.java)
override fun resolveArgument(
parameter: MethodParameter,
mavContainer: ModelAndViewContainer?,
webRequest: NativeWebRequest,
binderFactory: WebDataBinderFactory?,
): Any? {
val contentType = webRequest.getHeader("Content-Type").orEmpty()
logger.trace("ContentType is {}", contentType)
if (contentType.contains(isJsonRegex)) {
logger.trace("Determine content type as json.")
return requestResponseBodyMethodProcessor.resolveArgument(
parameter,
mavContainer,
webRequest,
binderFactory
)
}
return try {
modelAttributeMethodProcessor.resolveArgument(parameter, mavContainer, webRequest, binderFactory)
} catch (e: BindException) {
throw e
} catch (exception: Exception) {
try {
requestResponseBodyMethodProcessor.resolveArgument(parameter, mavContainer, webRequest, binderFactory)
} catch (e: BindException) {
throw e
} catch (e: Exception) {
logger.warn("Failed to bind request (1)", exception)
logger.warn("Failed to bind request (2)", e)
throw IllegalArgumentException("Failed to bind request.")
}
}
}
companion object {
val logger: Logger = LoggerFactory.getLogger(JsonOrFormModelMethodProcessor::class.java)
}
}

View File

@ -17,9 +17,7 @@
package dev.usbharu.hideout.util package dev.usbharu.hideout.util
import java.security.KeyFactory import java.security.KeyFactory
import java.security.interfaces.RSAPrivateKey
import java.security.interfaces.RSAPublicKey import java.security.interfaces.RSAPublicKey
import java.security.spec.PKCS8EncodedKeySpec
import java.security.spec.X509EncodedKeySpec import java.security.spec.X509EncodedKeySpec
object RsaUtil { object RsaUtil {
@ -38,10 +36,4 @@ object RsaUtil {
return decodeRsaPublicKey(replace) return decodeRsaPublicKey(replace)
} }
fun decodeRsaPrivateKey(byteArray: ByteArray): RSAPrivateKey {
val pkcS8EncodedKeySpec = PKCS8EncodedKeySpec(byteArray)
return KeyFactory.getInstance("RSA").generatePrivate(pkcS8EncodedKeySpec) as RSAPrivateKey
}
fun decodeRsaPrivateKey(encoded: String): RSAPrivateKey = decodeRsaPrivateKey(Base64Util.decode(encoded))
} }

View File

@ -1,5 +1,15 @@
import org.openapitools.generator.gradle.plugin.tasks.GenerateTask
plugins { plugins {
kotlin("jvm") version "1.9.23" alias(libs.plugins.kotlin.jvm)
alias(libs.plugins.openapi.generator)
alias(libs.plugins.spring.boot)
alias(libs.plugins.kotlin.spring)
}
apply {
plugin("io.spring.dependency-management")
} }
group = "dev.usbharu" group = "dev.usbharu"
@ -10,7 +20,19 @@ repositories {
} }
dependencies { dependencies {
testImplementation(kotlin("test")) implementation("org.springframework.boot:spring-boot-starter-web")
implementation("org.springframework.boot:spring-boot-starter-security")
implementation("com.fasterxml.jackson.datatype:jackson-datatype-jsr310")
implementation("dev.usbharu:hideout-core:0.0.1")
implementation(libs.jackson.databind)
implementation(libs.jackson.module.kotlin)
implementation(libs.jakarta.annotation)
implementation(libs.jakarta.validation)
implementation(libs.bundles.openapi)
implementation(libs.bundles.coroutines)
} }
tasks.test { tasks.test {
@ -19,3 +41,28 @@ tasks.test {
kotlin { kotlin {
jvmToolchain(21) jvmToolchain(21)
} }
tasks.create<GenerateTask>("openApiGenerateMastodonCompatibleApi", GenerateTask::class) {
generatorName.set("kotlin-spring")
inputSpec.set("$rootDir/src/main/resources/openapi/mastodon.yaml")
outputDir.set("$buildDir/generated/sources/mastodon")
apiPackage.set("dev.usbharu.hideout.mastodon.interfaces.api.generated")
modelPackage.set("dev.usbharu.hideout.mastodon.interfaces.api.generated.model")
configOptions.put("interfaceOnly", "true")
configOptions.put("useSpringBoot3", "true")
configOptions.put("reactive", "true")
configOptions.put("gradleBuildFile", "false")
configOptions.put("useSwaggerUI", "false")
configOptions.put("enumPropertyNaming", "UPPERCASE")
additionalProperties.put("useTags", "true")
importMappings.put("org.springframework.core.io.Resource", "org.springframework.web.multipart.MultipartFile")
typeMappings.put("org.springframework.core.io.Resource", "org.springframework.web.multipart.MultipartFile")
templateDir.set("$rootDir/templates")
}
sourceSets.main {
kotlin.srcDirs(
"$buildDir/generated/sources/mastodon/src/main/kotlin"
)
}

View File

@ -3,3 +3,16 @@ plugins {
} }
rootProject.name = "hideout-mastodon" rootProject.name = "hideout-mastodon"
includeBuild("../hideout-core")
dependencyResolutionManagement {
repositories {
mavenCentral()
}
versionCatalogs {
create("libs") {
from(files("../libs.versions.toml"))
}
}
}

View File

@ -21,6 +21,7 @@ rootProject.name = "hideout"
includeBuild("hideout-core") includeBuild("hideout-core")
includeBuild("hideout-worker") includeBuild("hideout-worker")
includeBuild("hideout-mastodon")
dependencyResolutionManagement { dependencyResolutionManagement {
repositories { repositories {