From 60706ee41320ecbcf511ca33874f9c4e91d88204 Mon Sep 17 00:00:00 2001 From: usbharu <64310155+usbharu@users.noreply.github.com> Date: Fri, 18 Aug 2023 12:01:32 +0900 Subject: [PATCH 01/15] =?UTF-8?q?feat:=20SpringBoot=E3=81=A7=E8=B5=B7?= =?UTF-8?q?=E5=8B=95=E3=81=A7=E3=81=8D=E3=82=8B=E3=82=88=E3=81=86=E3=81=AB?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- build.gradle.kts | 20 +++++++++++++++++-- gradle.properties | 2 +- .../dev/usbharu/hideout/SpringApplication.kt | 12 +++++++++++ src/main/resources/logback.xml | 2 +- 4 files changed, 32 insertions(+), 4 deletions(-) create mode 100644 src/main/kotlin/dev/usbharu/hideout/SpringApplication.kt diff --git a/build.gradle.kts b/build.gradle.kts index 8cc4ad0e..8b799706 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -1,4 +1,5 @@ import com.github.jengelman.gradle.plugins.shadow.tasks.ShadowJar +import org.jetbrains.kotlin.gradle.tasks.KotlinCompile val ktor_version: String by project val kotlin_version: String by project @@ -13,13 +14,19 @@ plugins { id("org.graalvm.buildtools.native") version "0.9.21" id("io.gitlab.arturbosch.detekt") version "1.22.0" id("com.google.devtools.ksp") version "1.8.21-1.0.11" + id("org.springframework.boot") version "3.1.2" + kotlin("plugin.spring") version "1.8.21" // id("org.jetbrains.kotlin.plugin.serialization") version "1.8.10" } +apply { + plugin("io.spring.dependency-management") +} + group = "dev.usbharu" version = "0.0.1" application { - mainClass.set("io.ktor.server.cio.EngineMain") + mainClass.set("dev.usbharu.hideout.SpringApplicationKt") val isDevelopment: Boolean = project.ext.has("development") applicationDefaultJvmArgs = listOf("-Dio.ktor.development=$isDevelopment") @@ -34,6 +41,12 @@ tasks.withType>().con compilerOptions.apiVersion.set(org.jetbrains.kotlin.gradle.dsl.KotlinVersion.KOTLIN_1_8) } +tasks.withType { + kotlinOptions { + freeCompilerArgs += "-Xjsr305=strict" + } +} + tasks.withType { manifest { attributes( @@ -53,7 +66,7 @@ repositories { kotlin { target { compilations.all { - kotlinOptions.jvmTarget = JavaVersion.VERSION_11.toString() + kotlinOptions.jvmTarget = JavaVersion.VERSION_17.toString() } } } @@ -90,6 +103,9 @@ dependencies { implementation("io.ktor:ktor-server-compression-jvm:2.3.0") ksp("io.insert-koin:koin-ksp-compiler:1.2.0") + implementation("org.springframework.boot:spring-boot-starter-web") + + implementation("io.ktor:ktor-client-logging-jvm:$ktor_version") implementation("io.ktor:ktor-server-host-common-jvm:$ktor_version") diff --git a/gradle.properties b/gradle.properties index 9ee92fa5..31697ea3 100644 --- a/gradle.properties +++ b/gradle.properties @@ -4,7 +4,7 @@ logback_version=1.4.6 kotlin.code.style=official exposed_version=0.41.1 h2_version=2.1.214 -koin_version=3.3.1 +koin_version=3.4.3 org.gradle.parallel=true org.gradle.configureondemand=true org.gradle.caching=true diff --git a/src/main/kotlin/dev/usbharu/hideout/SpringApplication.kt b/src/main/kotlin/dev/usbharu/hideout/SpringApplication.kt new file mode 100644 index 00000000..5d30de45 --- /dev/null +++ b/src/main/kotlin/dev/usbharu/hideout/SpringApplication.kt @@ -0,0 +1,12 @@ +package dev.usbharu.hideout + +import org.springframework.boot.autoconfigure.SpringBootApplication +import org.springframework.boot.runApplication + + +@SpringBootApplication +class SpringApplication + +fun main(args: Array) { + runApplication(*args) +} diff --git a/src/main/resources/logback.xml b/src/main/resources/logback.xml index ad457f2b..9129b1b2 100644 --- a/src/main/resources/logback.xml +++ b/src/main/resources/logback.xml @@ -4,7 +4,7 @@ %d{YYYY-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n - + From e5b744eef00548a9286536530abea1d737bd1a19 Mon Sep 17 00:00:00 2001 From: usbharu <64310155+usbharu@users.noreply.github.com> Date: Fri, 18 Aug 2023 12:24:26 +0900 Subject: [PATCH 02/15] =?UTF-8?q?feat:=20service=E3=81=A8repository?= =?UTF-8?q?=E3=81=AB=E3=82=A2=E3=83=8E=E3=83=86=E3=83=BC=E3=82=B7=E3=83=A7?= =?UTF-8?q?=E3=83=B3=E3=82=92=E8=BF=BD=E5=8A=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../kotlin/dev/usbharu/hideout/query/FollowerQueryService.kt | 2 ++ .../dev/usbharu/hideout/query/FollowerQueryServiceImpl.kt | 2 ++ .../dev/usbharu/hideout/query/JwtRefreshTokenQueryService.kt | 2 ++ .../usbharu/hideout/query/JwtRefreshTokenQueryServiceImpl.kt | 2 ++ src/main/kotlin/dev/usbharu/hideout/query/PostQueryService.kt | 2 ++ .../kotlin/dev/usbharu/hideout/query/PostQueryServiceImpl.kt | 2 ++ .../dev/usbharu/hideout/query/PostResponseQueryService.kt | 2 ++ .../dev/usbharu/hideout/query/PostResponseQueryServiceImpl.kt | 2 ++ .../kotlin/dev/usbharu/hideout/query/ReactionQueryService.kt | 2 ++ .../dev/usbharu/hideout/query/ReactionQueryServiceImpl.kt | 2 ++ src/main/kotlin/dev/usbharu/hideout/query/UserQueryService.kt | 2 ++ .../kotlin/dev/usbharu/hideout/query/UserQueryServiceImpl.kt | 2 ++ .../usbharu/hideout/repository/JwtRefreshTokenRepository.kt | 2 ++ .../hideout/repository/JwtRefreshTokenRepositoryImpl.kt | 2 ++ .../kotlin/dev/usbharu/hideout/repository/MetaRepository.kt | 2 ++ .../dev/usbharu/hideout/repository/MetaRepositoryImpl.kt | 2 ++ .../kotlin/dev/usbharu/hideout/repository/PostRepository.kt | 2 ++ .../dev/usbharu/hideout/repository/PostRepositoryImpl.kt | 2 ++ .../dev/usbharu/hideout/repository/ReactionRepository.kt | 2 ++ .../dev/usbharu/hideout/repository/ReactionRepositoryImpl.kt | 2 ++ .../kotlin/dev/usbharu/hideout/repository/UserRepository.kt | 2 ++ .../dev/usbharu/hideout/repository/UserRepositoryImpl.kt | 2 ++ .../kotlin/dev/usbharu/hideout/service/ap/APAcceptService.kt | 3 +++ .../kotlin/dev/usbharu/hideout/service/ap/APCreateService.kt | 4 ++++ .../kotlin/dev/usbharu/hideout/service/ap/APLikeService.kt | 3 +++ .../kotlin/dev/usbharu/hideout/service/ap/APNoteService.kt | 3 +++ .../dev/usbharu/hideout/service/ap/APReactionService.kt | 3 +++ .../dev/usbharu/hideout/service/ap/APReceiveFollowService.kt | 3 +++ .../dev/usbharu/hideout/service/ap/APSendFollowService.kt | 3 +++ src/main/kotlin/dev/usbharu/hideout/service/ap/APService.kt | 3 +++ .../kotlin/dev/usbharu/hideout/service/ap/APUndoService.kt | 4 ++++ .../kotlin/dev/usbharu/hideout/service/ap/APUserService.kt | 3 +++ .../kotlin/dev/usbharu/hideout/service/api/PostApiService.kt | 3 +++ .../kotlin/dev/usbharu/hideout/service/api/UserApiService.kt | 3 +++ .../dev/usbharu/hideout/service/api/UserAuthApiService.kt | 3 +++ .../dev/usbharu/hideout/service/api/WebFingerApiService.kt | 3 +++ .../hideout/service/auth/HttpSignatureVerifyService.kt | 3 +++ .../kotlin/dev/usbharu/hideout/service/auth/JwtService.kt | 3 +++ .../dev/usbharu/hideout/service/core/ExposedTransaction.kt | 2 ++ .../dev/usbharu/hideout/service/core/IdGenerateService.kt | 3 +++ .../kotlin/dev/usbharu/hideout/service/core/MetaService.kt | 2 ++ .../dev/usbharu/hideout/service/core/MetaServiceImpl.kt | 2 ++ .../usbharu/hideout/service/core/ServerInitialiseService.kt | 3 +++ .../hideout/service/core/ServerInitialiseServiceImpl.kt | 2 ++ .../hideout/service/core/SnowflakeIdGenerateService.kt | 2 ++ .../kotlin/dev/usbharu/hideout/service/core/Transaction.kt | 3 +++ .../hideout/service/core/TwitterSnowflakeIdGenerateService.kt | 3 +++ .../dev/usbharu/hideout/service/job/JobQueueParentService.kt | 2 ++ .../dev/usbharu/hideout/service/job/JobQueueWorkerService.kt | 2 ++ .../usbharu/hideout/service/job/KJobJobQueueParentService.kt | 2 ++ .../usbharu/hideout/service/job/KJobJobQueueWorkerService.kt | 2 ++ .../kotlin/dev/usbharu/hideout/service/post/PostService.kt | 2 ++ .../dev/usbharu/hideout/service/post/PostServiceImpl.kt | 2 ++ .../dev/usbharu/hideout/service/reaction/ReactionService.kt | 3 +++ .../usbharu/hideout/service/reaction/ReactionServiceImpl.kt | 2 ++ .../dev/usbharu/hideout/service/user/UserAuthService.kt | 2 ++ .../dev/usbharu/hideout/service/user/UserAuthServiceImpl.kt | 2 ++ .../kotlin/dev/usbharu/hideout/service/user/UserService.kt | 2 ++ .../dev/usbharu/hideout/service/user/UserServiceImpl.kt | 2 ++ 59 files changed, 141 insertions(+) diff --git a/src/main/kotlin/dev/usbharu/hideout/query/FollowerQueryService.kt b/src/main/kotlin/dev/usbharu/hideout/query/FollowerQueryService.kt index 4922b268..4cc73ef1 100644 --- a/src/main/kotlin/dev/usbharu/hideout/query/FollowerQueryService.kt +++ b/src/main/kotlin/dev/usbharu/hideout/query/FollowerQueryService.kt @@ -1,7 +1,9 @@ package dev.usbharu.hideout.query import dev.usbharu.hideout.domain.model.hideout.entity.User +import org.springframework.stereotype.Repository +@Repository interface FollowerQueryService { suspend fun findFollowersById(id: Long): List suspend fun findFollowersByNameAndDomain(name: String, domain: String): List diff --git a/src/main/kotlin/dev/usbharu/hideout/query/FollowerQueryServiceImpl.kt b/src/main/kotlin/dev/usbharu/hideout/query/FollowerQueryServiceImpl.kt index 3a938620..831c715c 100644 --- a/src/main/kotlin/dev/usbharu/hideout/query/FollowerQueryServiceImpl.kt +++ b/src/main/kotlin/dev/usbharu/hideout/query/FollowerQueryServiceImpl.kt @@ -6,9 +6,11 @@ import dev.usbharu.hideout.repository.UsersFollowers import org.jetbrains.exposed.sql.* import org.jetbrains.exposed.sql.SqlExpressionBuilder.eq import org.koin.core.annotation.Single +import org.springframework.stereotype.Repository import java.time.Instant @Single +@Repository class FollowerQueryServiceImpl : FollowerQueryService { override suspend fun findFollowersById(id: Long): List { val followers = Users.alias("FOLLOWERS") diff --git a/src/main/kotlin/dev/usbharu/hideout/query/JwtRefreshTokenQueryService.kt b/src/main/kotlin/dev/usbharu/hideout/query/JwtRefreshTokenQueryService.kt index 9ce1ad57..44c5675c 100644 --- a/src/main/kotlin/dev/usbharu/hideout/query/JwtRefreshTokenQueryService.kt +++ b/src/main/kotlin/dev/usbharu/hideout/query/JwtRefreshTokenQueryService.kt @@ -1,7 +1,9 @@ package dev.usbharu.hideout.query import dev.usbharu.hideout.domain.model.hideout.entity.JwtRefreshToken +import org.springframework.stereotype.Repository +@Repository interface JwtRefreshTokenQueryService { suspend fun findById(id: Long): JwtRefreshToken suspend fun findByToken(token: String): JwtRefreshToken diff --git a/src/main/kotlin/dev/usbharu/hideout/query/JwtRefreshTokenQueryServiceImpl.kt b/src/main/kotlin/dev/usbharu/hideout/query/JwtRefreshTokenQueryServiceImpl.kt index 7b6affff..ce217c42 100644 --- a/src/main/kotlin/dev/usbharu/hideout/query/JwtRefreshTokenQueryServiceImpl.kt +++ b/src/main/kotlin/dev/usbharu/hideout/query/JwtRefreshTokenQueryServiceImpl.kt @@ -10,8 +10,10 @@ import org.jetbrains.exposed.sql.deleteAll import org.jetbrains.exposed.sql.deleteWhere import org.jetbrains.exposed.sql.select import org.koin.core.annotation.Single +import org.springframework.stereotype.Repository @Single +@Repository class JwtRefreshTokenQueryServiceImpl : JwtRefreshTokenQueryService { override suspend fun findById(id: Long): JwtRefreshToken = JwtRefreshTokens.select { JwtRefreshTokens.id.eq(id) } diff --git a/src/main/kotlin/dev/usbharu/hideout/query/PostQueryService.kt b/src/main/kotlin/dev/usbharu/hideout/query/PostQueryService.kt index 8ad102ab..2a67b1fe 100644 --- a/src/main/kotlin/dev/usbharu/hideout/query/PostQueryService.kt +++ b/src/main/kotlin/dev/usbharu/hideout/query/PostQueryService.kt @@ -1,7 +1,9 @@ package dev.usbharu.hideout.query import dev.usbharu.hideout.domain.model.hideout.entity.Post +import org.springframework.stereotype.Repository +@Repository interface PostQueryService { suspend fun findById(id: Long): Post suspend fun findByUrl(url: String): Post diff --git a/src/main/kotlin/dev/usbharu/hideout/query/PostQueryServiceImpl.kt b/src/main/kotlin/dev/usbharu/hideout/query/PostQueryServiceImpl.kt index 4f98710b..a3293b06 100644 --- a/src/main/kotlin/dev/usbharu/hideout/query/PostQueryServiceImpl.kt +++ b/src/main/kotlin/dev/usbharu/hideout/query/PostQueryServiceImpl.kt @@ -7,8 +7,10 @@ import dev.usbharu.hideout.repository.toPost import dev.usbharu.hideout.util.singleOr import org.jetbrains.exposed.sql.select import org.koin.core.annotation.Single +import org.springframework.stereotype.Repository @Single +@Repository class PostQueryServiceImpl : PostQueryService { override suspend fun findById(id: Long): Post = Posts.select { Posts.id eq id } diff --git a/src/main/kotlin/dev/usbharu/hideout/query/PostResponseQueryService.kt b/src/main/kotlin/dev/usbharu/hideout/query/PostResponseQueryService.kt index 65441189..9c5263b8 100644 --- a/src/main/kotlin/dev/usbharu/hideout/query/PostResponseQueryService.kt +++ b/src/main/kotlin/dev/usbharu/hideout/query/PostResponseQueryService.kt @@ -1,8 +1,10 @@ package dev.usbharu.hideout.query import dev.usbharu.hideout.domain.model.hideout.dto.PostResponse +import org.springframework.stereotype.Repository @Suppress("LongParameterList") +@Repository interface PostResponseQueryService { suspend fun findById(id: Long, userId: Long?): PostResponse suspend fun findAll( diff --git a/src/main/kotlin/dev/usbharu/hideout/query/PostResponseQueryServiceImpl.kt b/src/main/kotlin/dev/usbharu/hideout/query/PostResponseQueryServiceImpl.kt index a8ef3930..ce350fc1 100644 --- a/src/main/kotlin/dev/usbharu/hideout/query/PostResponseQueryServiceImpl.kt +++ b/src/main/kotlin/dev/usbharu/hideout/query/PostResponseQueryServiceImpl.kt @@ -12,8 +12,10 @@ import org.jetbrains.exposed.sql.innerJoin import org.jetbrains.exposed.sql.select import org.jetbrains.exposed.sql.selectAll import org.koin.core.annotation.Single +import org.springframework.stereotype.Repository @Single +@Repository class PostResponseQueryServiceImpl : PostResponseQueryService { override suspend fun findById(id: Long, userId: Long?): PostResponse { return Posts diff --git a/src/main/kotlin/dev/usbharu/hideout/query/ReactionQueryService.kt b/src/main/kotlin/dev/usbharu/hideout/query/ReactionQueryService.kt index 72e0c316..fa81a62c 100644 --- a/src/main/kotlin/dev/usbharu/hideout/query/ReactionQueryService.kt +++ b/src/main/kotlin/dev/usbharu/hideout/query/ReactionQueryService.kt @@ -2,7 +2,9 @@ package dev.usbharu.hideout.query import dev.usbharu.hideout.domain.model.hideout.dto.ReactionResponse import dev.usbharu.hideout.domain.model.hideout.entity.Reaction +import org.springframework.stereotype.Repository +@Repository interface ReactionQueryService { suspend fun findByPostId(postId: Long, userId: Long? = null): List diff --git a/src/main/kotlin/dev/usbharu/hideout/query/ReactionQueryServiceImpl.kt b/src/main/kotlin/dev/usbharu/hideout/query/ReactionQueryServiceImpl.kt index de41d1cb..9536ca61 100644 --- a/src/main/kotlin/dev/usbharu/hideout/query/ReactionQueryServiceImpl.kt +++ b/src/main/kotlin/dev/usbharu/hideout/query/ReactionQueryServiceImpl.kt @@ -11,8 +11,10 @@ import dev.usbharu.hideout.util.singleOr import org.jetbrains.exposed.sql.* import org.jetbrains.exposed.sql.SqlExpressionBuilder.eq import org.koin.core.annotation.Single +import org.springframework.stereotype.Repository @Single +@Repository class ReactionQueryServiceImpl : ReactionQueryService { override suspend fun findByPostId(postId: Long, userId: Long?): List { return Reactions.select { diff --git a/src/main/kotlin/dev/usbharu/hideout/query/UserQueryService.kt b/src/main/kotlin/dev/usbharu/hideout/query/UserQueryService.kt index 6b7f7db6..09e5972a 100644 --- a/src/main/kotlin/dev/usbharu/hideout/query/UserQueryService.kt +++ b/src/main/kotlin/dev/usbharu/hideout/query/UserQueryService.kt @@ -1,7 +1,9 @@ package dev.usbharu.hideout.query import dev.usbharu.hideout.domain.model.hideout.entity.User +import org.springframework.stereotype.Repository +@Repository interface UserQueryService { suspend fun findAll(limit: Int, offset: Long): List suspend fun findById(id: Long): User diff --git a/src/main/kotlin/dev/usbharu/hideout/query/UserQueryServiceImpl.kt b/src/main/kotlin/dev/usbharu/hideout/query/UserQueryServiceImpl.kt index 647b8d5f..fc2bc9b3 100644 --- a/src/main/kotlin/dev/usbharu/hideout/query/UserQueryServiceImpl.kt +++ b/src/main/kotlin/dev/usbharu/hideout/query/UserQueryServiceImpl.kt @@ -10,8 +10,10 @@ import org.jetbrains.exposed.sql.select import org.jetbrains.exposed.sql.selectAll import org.koin.core.annotation.Single import org.slf4j.LoggerFactory +import org.springframework.stereotype.Repository @Single +@Repository class UserQueryServiceImpl : UserQueryService { private val logger = LoggerFactory.getLogger(UserQueryServiceImpl::class.java) diff --git a/src/main/kotlin/dev/usbharu/hideout/repository/JwtRefreshTokenRepository.kt b/src/main/kotlin/dev/usbharu/hideout/repository/JwtRefreshTokenRepository.kt index d6bc5638..81c6aa35 100644 --- a/src/main/kotlin/dev/usbharu/hideout/repository/JwtRefreshTokenRepository.kt +++ b/src/main/kotlin/dev/usbharu/hideout/repository/JwtRefreshTokenRepository.kt @@ -1,7 +1,9 @@ package dev.usbharu.hideout.repository import dev.usbharu.hideout.domain.model.hideout.entity.JwtRefreshToken +import org.springframework.stereotype.Repository +@Repository interface JwtRefreshTokenRepository { suspend fun generateId(): Long diff --git a/src/main/kotlin/dev/usbharu/hideout/repository/JwtRefreshTokenRepositoryImpl.kt b/src/main/kotlin/dev/usbharu/hideout/repository/JwtRefreshTokenRepositoryImpl.kt index 0fdc79dd..c1bf8ad3 100644 --- a/src/main/kotlin/dev/usbharu/hideout/repository/JwtRefreshTokenRepositoryImpl.kt +++ b/src/main/kotlin/dev/usbharu/hideout/repository/JwtRefreshTokenRepositoryImpl.kt @@ -6,9 +6,11 @@ import org.jetbrains.exposed.sql.* import org.jetbrains.exposed.sql.SqlExpressionBuilder.eq import org.jetbrains.exposed.sql.transactions.transaction import org.koin.core.annotation.Single +import org.springframework.stereotype.Repository import java.time.Instant @Single +@Repository class JwtRefreshTokenRepositoryImpl( private val database: Database, private val idGenerateService: IdGenerateService diff --git a/src/main/kotlin/dev/usbharu/hideout/repository/MetaRepository.kt b/src/main/kotlin/dev/usbharu/hideout/repository/MetaRepository.kt index 5fda5200..af4eb65f 100644 --- a/src/main/kotlin/dev/usbharu/hideout/repository/MetaRepository.kt +++ b/src/main/kotlin/dev/usbharu/hideout/repository/MetaRepository.kt @@ -1,7 +1,9 @@ package dev.usbharu.hideout.repository import dev.usbharu.hideout.domain.model.hideout.entity.Meta +import org.springframework.stereotype.Repository +@Repository interface MetaRepository { suspend fun save(meta: Meta) diff --git a/src/main/kotlin/dev/usbharu/hideout/repository/MetaRepositoryImpl.kt b/src/main/kotlin/dev/usbharu/hideout/repository/MetaRepositoryImpl.kt index d0de63a1..543bb1fb 100644 --- a/src/main/kotlin/dev/usbharu/hideout/repository/MetaRepositoryImpl.kt +++ b/src/main/kotlin/dev/usbharu/hideout/repository/MetaRepositoryImpl.kt @@ -4,9 +4,11 @@ import dev.usbharu.hideout.domain.model.hideout.entity.Jwt import org.jetbrains.exposed.sql.* import org.jetbrains.exposed.sql.transactions.transaction import org.koin.core.annotation.Single +import org.springframework.stereotype.Repository import java.util.* @Single +@Repository class MetaRepositoryImpl(private val database: Database) : MetaRepository { init { diff --git a/src/main/kotlin/dev/usbharu/hideout/repository/PostRepository.kt b/src/main/kotlin/dev/usbharu/hideout/repository/PostRepository.kt index 21a9bec8..8011f282 100644 --- a/src/main/kotlin/dev/usbharu/hideout/repository/PostRepository.kt +++ b/src/main/kotlin/dev/usbharu/hideout/repository/PostRepository.kt @@ -1,8 +1,10 @@ package dev.usbharu.hideout.repository import dev.usbharu.hideout.domain.model.hideout.entity.Post +import org.springframework.stereotype.Repository @Suppress("LongParameterList") +@Repository interface PostRepository { suspend fun generateId(): Long suspend fun save(post: Post): Post diff --git a/src/main/kotlin/dev/usbharu/hideout/repository/PostRepositoryImpl.kt b/src/main/kotlin/dev/usbharu/hideout/repository/PostRepositoryImpl.kt index 79698826..08998c15 100644 --- a/src/main/kotlin/dev/usbharu/hideout/repository/PostRepositoryImpl.kt +++ b/src/main/kotlin/dev/usbharu/hideout/repository/PostRepositoryImpl.kt @@ -8,8 +8,10 @@ import org.jetbrains.exposed.sql.* import org.jetbrains.exposed.sql.SqlExpressionBuilder.eq import org.jetbrains.exposed.sql.transactions.transaction import org.koin.core.annotation.Single +import org.springframework.stereotype.Repository @Single +@Repository class PostRepositoryImpl(database: Database, private val idGenerateService: IdGenerateService) : PostRepository { init { diff --git a/src/main/kotlin/dev/usbharu/hideout/repository/ReactionRepository.kt b/src/main/kotlin/dev/usbharu/hideout/repository/ReactionRepository.kt index f2aad560..d98a0c84 100644 --- a/src/main/kotlin/dev/usbharu/hideout/repository/ReactionRepository.kt +++ b/src/main/kotlin/dev/usbharu/hideout/repository/ReactionRepository.kt @@ -1,7 +1,9 @@ package dev.usbharu.hideout.repository import dev.usbharu.hideout.domain.model.hideout.entity.Reaction +import org.springframework.stereotype.Repository +@Repository interface ReactionRepository { suspend fun generateId(): Long suspend fun save(reaction: Reaction): Reaction diff --git a/src/main/kotlin/dev/usbharu/hideout/repository/ReactionRepositoryImpl.kt b/src/main/kotlin/dev/usbharu/hideout/repository/ReactionRepositoryImpl.kt index 628a995e..00f74d01 100644 --- a/src/main/kotlin/dev/usbharu/hideout/repository/ReactionRepositoryImpl.kt +++ b/src/main/kotlin/dev/usbharu/hideout/repository/ReactionRepositoryImpl.kt @@ -7,8 +7,10 @@ import org.jetbrains.exposed.sql.* import org.jetbrains.exposed.sql.SqlExpressionBuilder.eq import org.jetbrains.exposed.sql.transactions.transaction import org.koin.core.annotation.Single +import org.springframework.stereotype.Repository @Single +@Repository class ReactionRepositoryImpl( private val database: Database, private val idGenerateService: IdGenerateService diff --git a/src/main/kotlin/dev/usbharu/hideout/repository/UserRepository.kt b/src/main/kotlin/dev/usbharu/hideout/repository/UserRepository.kt index 17344d24..b00d66c4 100644 --- a/src/main/kotlin/dev/usbharu/hideout/repository/UserRepository.kt +++ b/src/main/kotlin/dev/usbharu/hideout/repository/UserRepository.kt @@ -1,8 +1,10 @@ package dev.usbharu.hideout.repository import dev.usbharu.hideout.domain.model.hideout.entity.User +import org.springframework.stereotype.Repository @Suppress("TooManyFunctions") +@Repository interface UserRepository { suspend fun save(user: User): User diff --git a/src/main/kotlin/dev/usbharu/hideout/repository/UserRepositoryImpl.kt b/src/main/kotlin/dev/usbharu/hideout/repository/UserRepositoryImpl.kt index 961a089c..c57a7ab7 100644 --- a/src/main/kotlin/dev/usbharu/hideout/repository/UserRepositoryImpl.kt +++ b/src/main/kotlin/dev/usbharu/hideout/repository/UserRepositoryImpl.kt @@ -8,9 +8,11 @@ import org.jetbrains.exposed.sql.* import org.jetbrains.exposed.sql.SqlExpressionBuilder.eq import org.jetbrains.exposed.sql.transactions.transaction import org.koin.core.annotation.Single +import org.springframework.stereotype.Repository import java.time.Instant @Single +@Repository class UserRepositoryImpl(private val database: Database, private val idGenerateService: IdGenerateService) : UserRepository { init { diff --git a/src/main/kotlin/dev/usbharu/hideout/service/ap/APAcceptService.kt b/src/main/kotlin/dev/usbharu/hideout/service/ap/APAcceptService.kt index 3af3fbcb..9c3f10ed 100644 --- a/src/main/kotlin/dev/usbharu/hideout/service/ap/APAcceptService.kt +++ b/src/main/kotlin/dev/usbharu/hideout/service/ap/APAcceptService.kt @@ -11,12 +11,15 @@ import dev.usbharu.hideout.service.core.Transaction import dev.usbharu.hideout.service.user.UserService import io.ktor.http.* import org.koin.core.annotation.Single +import org.springframework.stereotype.Service +@Service interface APAcceptService { suspend fun receiveAccept(accept: Accept): ActivityPubResponse } @Single +@Service class APAcceptServiceImpl( private val userService: UserService, private val userQueryService: UserQueryService, diff --git a/src/main/kotlin/dev/usbharu/hideout/service/ap/APCreateService.kt b/src/main/kotlin/dev/usbharu/hideout/service/ap/APCreateService.kt index b3e84557..bc684bb4 100644 --- a/src/main/kotlin/dev/usbharu/hideout/service/ap/APCreateService.kt +++ b/src/main/kotlin/dev/usbharu/hideout/service/ap/APCreateService.kt @@ -8,12 +8,16 @@ import dev.usbharu.hideout.exception.ap.IllegalActivityPubObjectException import dev.usbharu.hideout.service.core.Transaction import io.ktor.http.* import org.koin.core.annotation.Single +import org.springframework.stereotype.Service + +@Service interface APCreateService { suspend fun receiveCreate(create: Create): ActivityPubResponse } @Single +@Service class APCreateServiceImpl( private val apNoteService: APNoteService, private val transaction: Transaction diff --git a/src/main/kotlin/dev/usbharu/hideout/service/ap/APLikeService.kt b/src/main/kotlin/dev/usbharu/hideout/service/ap/APLikeService.kt index 6bf2132e..c98b8cfc 100644 --- a/src/main/kotlin/dev/usbharu/hideout/service/ap/APLikeService.kt +++ b/src/main/kotlin/dev/usbharu/hideout/service/ap/APLikeService.kt @@ -9,12 +9,15 @@ import dev.usbharu.hideout.service.core.Transaction import dev.usbharu.hideout.service.reaction.ReactionService import io.ktor.http.* import org.koin.core.annotation.Single +import org.springframework.stereotype.Service +@Service interface APLikeService { suspend fun receiveLike(like: Like): ActivityPubResponse } @Single +@Service class APLikeServiceImpl( private val reactionService: ReactionService, private val apUserService: APUserService, diff --git a/src/main/kotlin/dev/usbharu/hideout/service/ap/APNoteService.kt b/src/main/kotlin/dev/usbharu/hideout/service/ap/APNoteService.kt index 9e1875b6..b706c4fa 100644 --- a/src/main/kotlin/dev/usbharu/hideout/service/ap/APNoteService.kt +++ b/src/main/kotlin/dev/usbharu/hideout/service/ap/APNoteService.kt @@ -21,8 +21,10 @@ import io.ktor.client.statement.* import kjob.core.job.JobProps import org.koin.core.annotation.Single import org.slf4j.LoggerFactory +import org.springframework.stereotype.Service import java.time.Instant +@Service interface APNoteService { suspend fun createNote(post: Post) @@ -33,6 +35,7 @@ interface APNoteService { } @Single +@Service class APNoteServiceImpl( private val httpClient: HttpClient, private val jobQueueParentService: JobQueueParentService, diff --git a/src/main/kotlin/dev/usbharu/hideout/service/ap/APReactionService.kt b/src/main/kotlin/dev/usbharu/hideout/service/ap/APReactionService.kt index ba7ff79c..78698512 100644 --- a/src/main/kotlin/dev/usbharu/hideout/service/ap/APReactionService.kt +++ b/src/main/kotlin/dev/usbharu/hideout/service/ap/APReactionService.kt @@ -15,8 +15,10 @@ import dev.usbharu.hideout.service.job.JobQueueParentService import io.ktor.client.* import kjob.core.job.JobProps import org.koin.core.annotation.Single +import org.springframework.stereotype.Service import java.time.Instant +@Service interface APReactionService { suspend fun reaction(like: Reaction) suspend fun removeReaction(like: Reaction) @@ -25,6 +27,7 @@ interface APReactionService { } @Single +@Service class APReactionServiceImpl( private val jobQueueParentService: JobQueueParentService, private val httpClient: HttpClient, diff --git a/src/main/kotlin/dev/usbharu/hideout/service/ap/APReceiveFollowService.kt b/src/main/kotlin/dev/usbharu/hideout/service/ap/APReceiveFollowService.kt index 9156abfd..602a8740 100644 --- a/src/main/kotlin/dev/usbharu/hideout/service/ap/APReceiveFollowService.kt +++ b/src/main/kotlin/dev/usbharu/hideout/service/ap/APReceiveFollowService.kt @@ -16,13 +16,16 @@ import io.ktor.client.* import io.ktor.http.* import kjob.core.job.JobProps import org.koin.core.annotation.Single +import org.springframework.stereotype.Service +@Service interface APReceiveFollowService { suspend fun receiveFollow(follow: Follow): ActivityPubResponse suspend fun receiveFollowJob(props: JobProps) } @Single +@Service class APReceiveFollowServiceImpl( private val jobQueueParentService: JobQueueParentService, private val apUserService: APUserService, diff --git a/src/main/kotlin/dev/usbharu/hideout/service/ap/APSendFollowService.kt b/src/main/kotlin/dev/usbharu/hideout/service/ap/APSendFollowService.kt index 58ae74f5..ad67b955 100644 --- a/src/main/kotlin/dev/usbharu/hideout/service/ap/APSendFollowService.kt +++ b/src/main/kotlin/dev/usbharu/hideout/service/ap/APSendFollowService.kt @@ -5,12 +5,15 @@ import dev.usbharu.hideout.domain.model.hideout.dto.SendFollowDto import dev.usbharu.hideout.plugins.postAp import io.ktor.client.* import org.koin.core.annotation.Single +import org.springframework.stereotype.Service +@Service interface APSendFollowService { suspend fun sendFollow(sendFollowDto: SendFollowDto) } @Single +@Service class APSendFollowServiceImpl(private val httpClient: HttpClient) : APSendFollowService { override suspend fun sendFollow(sendFollowDto: SendFollowDto) { val follow = Follow( diff --git a/src/main/kotlin/dev/usbharu/hideout/service/ap/APService.kt b/src/main/kotlin/dev/usbharu/hideout/service/ap/APService.kt index baf1b023..4c93439d 100644 --- a/src/main/kotlin/dev/usbharu/hideout/service/ap/APService.kt +++ b/src/main/kotlin/dev/usbharu/hideout/service/ap/APService.kt @@ -12,7 +12,9 @@ import kjob.core.job.JobProps import org.koin.core.annotation.Single import org.slf4j.Logger import org.slf4j.LoggerFactory +import org.springframework.stereotype.Service +@Service interface APService { fun parseActivity(json: String): ActivityType @@ -173,6 +175,7 @@ enum class ExtendedVocabulary { } @Single +@Service class APServiceImpl( private val apReceiveFollowService: APReceiveFollowService, private val apNoteService: APNoteService, diff --git a/src/main/kotlin/dev/usbharu/hideout/service/ap/APUndoService.kt b/src/main/kotlin/dev/usbharu/hideout/service/ap/APUndoService.kt index 8ae5ab13..6ad4f67e 100644 --- a/src/main/kotlin/dev/usbharu/hideout/service/ap/APUndoService.kt +++ b/src/main/kotlin/dev/usbharu/hideout/service/ap/APUndoService.kt @@ -9,12 +9,16 @@ import dev.usbharu.hideout.service.core.Transaction import dev.usbharu.hideout.service.user.UserService import io.ktor.http.* import org.koin.core.annotation.Single +import org.springframework.stereotype.Service + +@Service interface APUndoService { suspend fun receiveUndo(undo: Undo): ActivityPubResponse } @Single +@Service @Suppress("UnsafeCallOnNullableType") class APUndoServiceImpl( private val userService: UserService, diff --git a/src/main/kotlin/dev/usbharu/hideout/service/ap/APUserService.kt b/src/main/kotlin/dev/usbharu/hideout/service/ap/APUserService.kt index 2f095a6a..6e6e11bc 100644 --- a/src/main/kotlin/dev/usbharu/hideout/service/ap/APUserService.kt +++ b/src/main/kotlin/dev/usbharu/hideout/service/ap/APUserService.kt @@ -19,7 +19,9 @@ import io.ktor.client.request.* import io.ktor.client.statement.* import io.ktor.http.* import org.koin.core.annotation.Single +import org.springframework.stereotype.Service +@Service interface APUserService { suspend fun getPersonByName(name: String): Person @@ -36,6 +38,7 @@ interface APUserService { } @Single +@Service class APUserServiceImpl( private val userService: UserService, private val httpClient: HttpClient, diff --git a/src/main/kotlin/dev/usbharu/hideout/service/api/PostApiService.kt b/src/main/kotlin/dev/usbharu/hideout/service/api/PostApiService.kt index 8edee9a7..71a904f0 100644 --- a/src/main/kotlin/dev/usbharu/hideout/service/api/PostApiService.kt +++ b/src/main/kotlin/dev/usbharu/hideout/service/api/PostApiService.kt @@ -13,9 +13,11 @@ import dev.usbharu.hideout.service.post.PostService import dev.usbharu.hideout.service.reaction.ReactionService import dev.usbharu.hideout.util.AcctUtil import org.koin.core.annotation.Single +import org.springframework.stereotype.Service import java.time.Instant @Suppress("LongParameterList") +@Service interface PostApiService { suspend fun createPost(postForm: dev.usbharu.hideout.domain.model.hideout.form.Post, userId: Long): PostResponse suspend fun getById(id: Long, userId: Long?): PostResponse @@ -44,6 +46,7 @@ interface PostApiService { } @Single +@Service class PostApiServiceImpl( private val postService: PostService, private val userRepository: UserRepository, diff --git a/src/main/kotlin/dev/usbharu/hideout/service/api/UserApiService.kt b/src/main/kotlin/dev/usbharu/hideout/service/api/UserApiService.kt index 8fed3222..935cad11 100644 --- a/src/main/kotlin/dev/usbharu/hideout/service/api/UserApiService.kt +++ b/src/main/kotlin/dev/usbharu/hideout/service/api/UserApiService.kt @@ -10,9 +10,11 @@ import dev.usbharu.hideout.query.UserQueryService import dev.usbharu.hideout.service.core.Transaction import dev.usbharu.hideout.service.user.UserService import org.koin.core.annotation.Single +import org.springframework.stereotype.Service import kotlin.math.min @Suppress("TooManyFunctions") +@Service interface UserApiService { suspend fun findAll(limit: Int? = 100, offset: Long = 0): List @@ -37,6 +39,7 @@ interface UserApiService { } @Single +@Service class UserApiServiceImpl( private val userQueryService: UserQueryService, private val followerQueryService: FollowerQueryService, diff --git a/src/main/kotlin/dev/usbharu/hideout/service/api/UserAuthApiService.kt b/src/main/kotlin/dev/usbharu/hideout/service/api/UserAuthApiService.kt index e576f8ef..fd8e64b3 100644 --- a/src/main/kotlin/dev/usbharu/hideout/service/api/UserAuthApiService.kt +++ b/src/main/kotlin/dev/usbharu/hideout/service/api/UserAuthApiService.kt @@ -9,13 +9,16 @@ import dev.usbharu.hideout.service.auth.JwtService import dev.usbharu.hideout.service.core.Transaction import dev.usbharu.hideout.service.user.UserAuthServiceImpl import org.koin.core.annotation.Single +import org.springframework.stereotype.Service +@Service interface UserAuthApiService { suspend fun login(username: String, password: String): JwtToken suspend fun refreshToken(refreshToken: RefreshToken): JwtToken } @Single +@Service class UserAuthApiServiceImpl( private val userAuthService: UserAuthServiceImpl, private val userQueryService: UserQueryService, diff --git a/src/main/kotlin/dev/usbharu/hideout/service/api/WebFingerApiService.kt b/src/main/kotlin/dev/usbharu/hideout/service/api/WebFingerApiService.kt index 5311723c..f2ff9f81 100644 --- a/src/main/kotlin/dev/usbharu/hideout/service/api/WebFingerApiService.kt +++ b/src/main/kotlin/dev/usbharu/hideout/service/api/WebFingerApiService.kt @@ -4,12 +4,15 @@ import dev.usbharu.hideout.domain.model.hideout.entity.User import dev.usbharu.hideout.query.UserQueryService import dev.usbharu.hideout.service.core.Transaction import org.koin.core.annotation.Single +import org.springframework.stereotype.Service +@Service interface WebFingerApiService { suspend fun findByNameAndDomain(name: String, domain: String): User } @Single +@Service class WebFingerApiServiceImpl(private val transaction: Transaction, private val userQueryService: UserQueryService) : WebFingerApiService { override suspend fun findByNameAndDomain(name: String, domain: String): User { diff --git a/src/main/kotlin/dev/usbharu/hideout/service/auth/HttpSignatureVerifyService.kt b/src/main/kotlin/dev/usbharu/hideout/service/auth/HttpSignatureVerifyService.kt index eb30c903..e7697992 100644 --- a/src/main/kotlin/dev/usbharu/hideout/service/auth/HttpSignatureVerifyService.kt +++ b/src/main/kotlin/dev/usbharu/hideout/service/auth/HttpSignatureVerifyService.kt @@ -5,13 +5,16 @@ import dev.usbharu.hideout.query.UserQueryService import dev.usbharu.hideout.service.core.Transaction import io.ktor.http.* import org.koin.core.annotation.Single +import org.springframework.stereotype.Service import tech.barbero.http.message.signing.SignatureHeaderVerifier +@Service interface HttpSignatureVerifyService { fun verify(headers: Headers): Boolean } @Single +@Service class HttpSignatureVerifyServiceImpl( private val userQueryService: UserQueryService, private val transaction: Transaction diff --git a/src/main/kotlin/dev/usbharu/hideout/service/auth/JwtService.kt b/src/main/kotlin/dev/usbharu/hideout/service/auth/JwtService.kt index 462430ac..53dc2ae4 100644 --- a/src/main/kotlin/dev/usbharu/hideout/service/auth/JwtService.kt +++ b/src/main/kotlin/dev/usbharu/hideout/service/auth/JwtService.kt @@ -15,10 +15,12 @@ import dev.usbharu.hideout.service.core.MetaService import dev.usbharu.hideout.util.RsaUtil import kotlinx.coroutines.runBlocking import org.koin.core.annotation.Single +import org.springframework.stereotype.Service import java.time.Instant import java.time.temporal.ChronoUnit import java.util.* +@Service interface JwtService { suspend fun createToken(user: User): JwtToken suspend fun refreshToken(refreshToken: RefreshToken): JwtToken @@ -30,6 +32,7 @@ interface JwtService { @Suppress("InjectDispatcher") @Single +@Service class JwtServiceImpl( private val metaService: MetaService, private val refreshTokenRepository: JwtRefreshTokenRepository, diff --git a/src/main/kotlin/dev/usbharu/hideout/service/core/ExposedTransaction.kt b/src/main/kotlin/dev/usbharu/hideout/service/core/ExposedTransaction.kt index c15327a4..283fa7c8 100644 --- a/src/main/kotlin/dev/usbharu/hideout/service/core/ExposedTransaction.kt +++ b/src/main/kotlin/dev/usbharu/hideout/service/core/ExposedTransaction.kt @@ -2,8 +2,10 @@ package dev.usbharu.hideout.service.core import org.jetbrains.exposed.sql.transactions.experimental.newSuspendedTransaction import org.koin.core.annotation.Single +import org.springframework.stereotype.Service @Single +@Service class ExposedTransaction : Transaction { override suspend fun transaction(block: suspend () -> T): T { return newSuspendedTransaction(transactionIsolation = java.sql.Connection.TRANSACTION_SERIALIZABLE) { diff --git a/src/main/kotlin/dev/usbharu/hideout/service/core/IdGenerateService.kt b/src/main/kotlin/dev/usbharu/hideout/service/core/IdGenerateService.kt index 2962f4e3..fae8a683 100644 --- a/src/main/kotlin/dev/usbharu/hideout/service/core/IdGenerateService.kt +++ b/src/main/kotlin/dev/usbharu/hideout/service/core/IdGenerateService.kt @@ -1,5 +1,8 @@ package dev.usbharu.hideout.service.core +import org.springframework.stereotype.Service + +@Service interface IdGenerateService { suspend fun generateId(): Long } diff --git a/src/main/kotlin/dev/usbharu/hideout/service/core/MetaService.kt b/src/main/kotlin/dev/usbharu/hideout/service/core/MetaService.kt index 91da1a90..a455d1b1 100644 --- a/src/main/kotlin/dev/usbharu/hideout/service/core/MetaService.kt +++ b/src/main/kotlin/dev/usbharu/hideout/service/core/MetaService.kt @@ -2,7 +2,9 @@ package dev.usbharu.hideout.service.core import dev.usbharu.hideout.domain.model.hideout.entity.Jwt import dev.usbharu.hideout.domain.model.hideout.entity.Meta +import org.springframework.stereotype.Service +@Service interface MetaService { suspend fun getMeta(): Meta suspend fun updateMeta(meta: Meta) diff --git a/src/main/kotlin/dev/usbharu/hideout/service/core/MetaServiceImpl.kt b/src/main/kotlin/dev/usbharu/hideout/service/core/MetaServiceImpl.kt index e35ff3f7..1492c7a8 100644 --- a/src/main/kotlin/dev/usbharu/hideout/service/core/MetaServiceImpl.kt +++ b/src/main/kotlin/dev/usbharu/hideout/service/core/MetaServiceImpl.kt @@ -5,8 +5,10 @@ import dev.usbharu.hideout.domain.model.hideout.entity.Meta import dev.usbharu.hideout.exception.NotInitException import dev.usbharu.hideout.repository.MetaRepository import org.koin.core.annotation.Single +import org.springframework.stereotype.Service @Single +@Service class MetaServiceImpl(private val metaRepository: MetaRepository, private val transaction: Transaction) : MetaService { override suspend fun getMeta(): Meta = diff --git a/src/main/kotlin/dev/usbharu/hideout/service/core/ServerInitialiseService.kt b/src/main/kotlin/dev/usbharu/hideout/service/core/ServerInitialiseService.kt index d65f8fa6..edd234cd 100644 --- a/src/main/kotlin/dev/usbharu/hideout/service/core/ServerInitialiseService.kt +++ b/src/main/kotlin/dev/usbharu/hideout/service/core/ServerInitialiseService.kt @@ -1,5 +1,8 @@ package dev.usbharu.hideout.service.core +import org.springframework.stereotype.Service + +@Service interface ServerInitialiseService { suspend fun init() } diff --git a/src/main/kotlin/dev/usbharu/hideout/service/core/ServerInitialiseServiceImpl.kt b/src/main/kotlin/dev/usbharu/hideout/service/core/ServerInitialiseServiceImpl.kt index 4fc950c1..2917b15b 100644 --- a/src/main/kotlin/dev/usbharu/hideout/service/core/ServerInitialiseServiceImpl.kt +++ b/src/main/kotlin/dev/usbharu/hideout/service/core/ServerInitialiseServiceImpl.kt @@ -7,10 +7,12 @@ import dev.usbharu.hideout.util.ServerUtil import org.koin.core.annotation.Single import org.slf4j.Logger import org.slf4j.LoggerFactory +import org.springframework.stereotype.Service import java.security.KeyPairGenerator import java.util.* @Single +@Service class ServerInitialiseServiceImpl( private val metaRepository: MetaRepository, private val transaction: Transaction diff --git a/src/main/kotlin/dev/usbharu/hideout/service/core/SnowflakeIdGenerateService.kt b/src/main/kotlin/dev/usbharu/hideout/service/core/SnowflakeIdGenerateService.kt index e90ea2d6..a4fbbf15 100644 --- a/src/main/kotlin/dev/usbharu/hideout/service/core/SnowflakeIdGenerateService.kt +++ b/src/main/kotlin/dev/usbharu/hideout/service/core/SnowflakeIdGenerateService.kt @@ -3,9 +3,11 @@ package dev.usbharu.hideout.service.core import kotlinx.coroutines.delay import kotlinx.coroutines.sync.Mutex import kotlinx.coroutines.sync.withLock +import org.springframework.stereotype.Service import java.time.Instant @Suppress("MagicNumber") +@Service open class SnowflakeIdGenerateService(private val baseTime: Long) : IdGenerateService { var lastTimeStamp: Long = -1 var sequenceId: Int = 0 diff --git a/src/main/kotlin/dev/usbharu/hideout/service/core/Transaction.kt b/src/main/kotlin/dev/usbharu/hideout/service/core/Transaction.kt index 105420ed..a5c787a2 100644 --- a/src/main/kotlin/dev/usbharu/hideout/service/core/Transaction.kt +++ b/src/main/kotlin/dev/usbharu/hideout/service/core/Transaction.kt @@ -1,5 +1,8 @@ package dev.usbharu.hideout.service.core +import org.springframework.stereotype.Service + +@Service interface Transaction { suspend fun transaction(block: suspend () -> T): T suspend fun transaction(transactionLevel: Int, block: suspend () -> T): T diff --git a/src/main/kotlin/dev/usbharu/hideout/service/core/TwitterSnowflakeIdGenerateService.kt b/src/main/kotlin/dev/usbharu/hideout/service/core/TwitterSnowflakeIdGenerateService.kt index 35a9cd14..17459f2b 100644 --- a/src/main/kotlin/dev/usbharu/hideout/service/core/TwitterSnowflakeIdGenerateService.kt +++ b/src/main/kotlin/dev/usbharu/hideout/service/core/TwitterSnowflakeIdGenerateService.kt @@ -1,5 +1,8 @@ package dev.usbharu.hideout.service.core +import org.springframework.stereotype.Service + // 2010-11-04T01:42:54.657 @Suppress("MagicNumber") +@Service object TwitterSnowflakeIdGenerateService : SnowflakeIdGenerateService(1288834974657L) diff --git a/src/main/kotlin/dev/usbharu/hideout/service/job/JobQueueParentService.kt b/src/main/kotlin/dev/usbharu/hideout/service/job/JobQueueParentService.kt index f553c227..dfecf8a4 100644 --- a/src/main/kotlin/dev/usbharu/hideout/service/job/JobQueueParentService.kt +++ b/src/main/kotlin/dev/usbharu/hideout/service/job/JobQueueParentService.kt @@ -2,7 +2,9 @@ package dev.usbharu.hideout.service.job import kjob.core.Job import kjob.core.dsl.ScheduleContext +import org.springframework.stereotype.Service +@Service interface JobQueueParentService { fun init(jobDefines: List) diff --git a/src/main/kotlin/dev/usbharu/hideout/service/job/JobQueueWorkerService.kt b/src/main/kotlin/dev/usbharu/hideout/service/job/JobQueueWorkerService.kt index 567f9e21..80413c79 100644 --- a/src/main/kotlin/dev/usbharu/hideout/service/job/JobQueueWorkerService.kt +++ b/src/main/kotlin/dev/usbharu/hideout/service/job/JobQueueWorkerService.kt @@ -2,9 +2,11 @@ package dev.usbharu.hideout.service.job import kjob.core.Job import kjob.core.dsl.KJobFunctions +import org.springframework.stereotype.Service import kjob.core.dsl.JobContextWithProps as JCWP import kjob.core.dsl.JobRegisterContext as JRC +@Service interface JobQueueWorkerService { fun init(defines: List>.(Job) -> KJobFunctions>>>) } diff --git a/src/main/kotlin/dev/usbharu/hideout/service/job/KJobJobQueueParentService.kt b/src/main/kotlin/dev/usbharu/hideout/service/job/KJobJobQueueParentService.kt index d5367d80..e7d9fc30 100644 --- a/src/main/kotlin/dev/usbharu/hideout/service/job/KJobJobQueueParentService.kt +++ b/src/main/kotlin/dev/usbharu/hideout/service/job/KJobJobQueueParentService.kt @@ -7,7 +7,9 @@ import kjob.core.dsl.ScheduleContext import kjob.core.kjob import org.jetbrains.exposed.sql.Database import org.slf4j.LoggerFactory +import org.springframework.stereotype.Service +@Service class KJobJobQueueParentService(private val database: Database) : JobQueueParentService { private val logger = LoggerFactory.getLogger(this::class.java) diff --git a/src/main/kotlin/dev/usbharu/hideout/service/job/KJobJobQueueWorkerService.kt b/src/main/kotlin/dev/usbharu/hideout/service/job/KJobJobQueueWorkerService.kt index 67d84821..368aae99 100644 --- a/src/main/kotlin/dev/usbharu/hideout/service/job/KJobJobQueueWorkerService.kt +++ b/src/main/kotlin/dev/usbharu/hideout/service/job/KJobJobQueueWorkerService.kt @@ -5,9 +5,11 @@ import kjob.core.Job import kjob.core.dsl.KJobFunctions import kjob.core.kjob import org.jetbrains.exposed.sql.Database +import org.springframework.stereotype.Service import kjob.core.dsl.JobContextWithProps as JCWP import kjob.core.dsl.JobRegisterContext as JRC +@Service class KJobJobQueueWorkerService(private val database: Database) : JobQueueWorkerService { val kjob by lazy { diff --git a/src/main/kotlin/dev/usbharu/hideout/service/post/PostService.kt b/src/main/kotlin/dev/usbharu/hideout/service/post/PostService.kt index 28c90710..0eed9d72 100644 --- a/src/main/kotlin/dev/usbharu/hideout/service/post/PostService.kt +++ b/src/main/kotlin/dev/usbharu/hideout/service/post/PostService.kt @@ -2,7 +2,9 @@ package dev.usbharu.hideout.service.post import dev.usbharu.hideout.domain.model.hideout.dto.PostCreateDto import dev.usbharu.hideout.domain.model.hideout.entity.Post +import org.springframework.stereotype.Service +@Service interface PostService { suspend fun createLocal(post: PostCreateDto): Post } diff --git a/src/main/kotlin/dev/usbharu/hideout/service/post/PostServiceImpl.kt b/src/main/kotlin/dev/usbharu/hideout/service/post/PostServiceImpl.kt index c1b58d1b..2e81aeef 100644 --- a/src/main/kotlin/dev/usbharu/hideout/service/post/PostServiceImpl.kt +++ b/src/main/kotlin/dev/usbharu/hideout/service/post/PostServiceImpl.kt @@ -7,8 +7,10 @@ import dev.usbharu.hideout.repository.PostRepository import dev.usbharu.hideout.repository.UserRepository import dev.usbharu.hideout.service.ap.APNoteService import org.koin.core.annotation.Single +import org.springframework.stereotype.Service import java.time.Instant +@Service @Single class PostServiceImpl( private val postRepository: PostRepository, diff --git a/src/main/kotlin/dev/usbharu/hideout/service/reaction/ReactionService.kt b/src/main/kotlin/dev/usbharu/hideout/service/reaction/ReactionService.kt index a7b9ed0d..d39dc483 100644 --- a/src/main/kotlin/dev/usbharu/hideout/service/reaction/ReactionService.kt +++ b/src/main/kotlin/dev/usbharu/hideout/service/reaction/ReactionService.kt @@ -1,5 +1,8 @@ package dev.usbharu.hideout.service.reaction +import org.springframework.stereotype.Service + +@Service interface ReactionService { suspend fun receiveReaction(name: String, domain: String, userId: Long, postId: Long) suspend fun sendReaction(name: String, userId: Long, postId: Long) diff --git a/src/main/kotlin/dev/usbharu/hideout/service/reaction/ReactionServiceImpl.kt b/src/main/kotlin/dev/usbharu/hideout/service/reaction/ReactionServiceImpl.kt index f8c24df9..cc822a18 100644 --- a/src/main/kotlin/dev/usbharu/hideout/service/reaction/ReactionServiceImpl.kt +++ b/src/main/kotlin/dev/usbharu/hideout/service/reaction/ReactionServiceImpl.kt @@ -5,8 +5,10 @@ import dev.usbharu.hideout.query.ReactionQueryService import dev.usbharu.hideout.repository.ReactionRepository import dev.usbharu.hideout.service.ap.APReactionService import org.koin.core.annotation.Single +import org.springframework.stereotype.Service @Single +@Service class ReactionServiceImpl( private val reactionRepository: ReactionRepository, private val apReactionService: APReactionService, diff --git a/src/main/kotlin/dev/usbharu/hideout/service/user/UserAuthService.kt b/src/main/kotlin/dev/usbharu/hideout/service/user/UserAuthService.kt index 61853b73..9630f8fa 100644 --- a/src/main/kotlin/dev/usbharu/hideout/service/user/UserAuthService.kt +++ b/src/main/kotlin/dev/usbharu/hideout/service/user/UserAuthService.kt @@ -1,7 +1,9 @@ package dev.usbharu.hideout.service.user +import org.springframework.stereotype.Service import java.security.KeyPair +@Service interface UserAuthService { fun hash(password: String): String diff --git a/src/main/kotlin/dev/usbharu/hideout/service/user/UserAuthServiceImpl.kt b/src/main/kotlin/dev/usbharu/hideout/service/user/UserAuthServiceImpl.kt index 0c234430..a4e0bba6 100644 --- a/src/main/kotlin/dev/usbharu/hideout/service/user/UserAuthServiceImpl.kt +++ b/src/main/kotlin/dev/usbharu/hideout/service/user/UserAuthServiceImpl.kt @@ -4,10 +4,12 @@ import dev.usbharu.hideout.config.Config import dev.usbharu.hideout.query.UserQueryService import io.ktor.util.* import org.koin.core.annotation.Single +import org.springframework.stereotype.Service import java.security.* import java.util.* @Single +@Service class UserAuthServiceImpl( val userQueryService: UserQueryService ) : UserAuthService { diff --git a/src/main/kotlin/dev/usbharu/hideout/service/user/UserService.kt b/src/main/kotlin/dev/usbharu/hideout/service/user/UserService.kt index a141fa24..665d14f5 100644 --- a/src/main/kotlin/dev/usbharu/hideout/service/user/UserService.kt +++ b/src/main/kotlin/dev/usbharu/hideout/service/user/UserService.kt @@ -3,8 +3,10 @@ package dev.usbharu.hideout.service.user import dev.usbharu.hideout.domain.model.hideout.dto.RemoteUserCreateDto import dev.usbharu.hideout.domain.model.hideout.dto.UserCreateDto import dev.usbharu.hideout.domain.model.hideout.entity.User +import org.springframework.stereotype.Service @Suppress("TooManyFunctions") +@Service interface UserService { suspend fun usernameAlreadyUse(username: String): Boolean diff --git a/src/main/kotlin/dev/usbharu/hideout/service/user/UserServiceImpl.kt b/src/main/kotlin/dev/usbharu/hideout/service/user/UserServiceImpl.kt index 3d2a93dd..22cc6001 100644 --- a/src/main/kotlin/dev/usbharu/hideout/service/user/UserServiceImpl.kt +++ b/src/main/kotlin/dev/usbharu/hideout/service/user/UserServiceImpl.kt @@ -11,9 +11,11 @@ import dev.usbharu.hideout.query.UserQueryService import dev.usbharu.hideout.repository.UserRepository import dev.usbharu.hideout.service.ap.APSendFollowService import org.koin.core.annotation.Single +import org.springframework.stereotype.Service import java.time.Instant @Single +@Service class UserServiceImpl( private val userRepository: UserRepository, private val userAuthService: UserAuthService, From 7f1aec33981eaeb7c80f3ed532f905626f172520 Mon Sep 17 00:00:00 2001 From: usbharu <64310155+usbharu@users.noreply.github.com> Date: Fri, 18 Aug 2023 13:29:08 +0900 Subject: [PATCH 03/15] =?UTF-8?q?feat:=20=E4=BE=9D=E5=AD=98=E9=96=A2?= =?UTF-8?q?=E4=BF=82=E3=82=92=E4=BF=AE=E6=AD=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../dev/usbharu/hideout/SpringApplication.kt | 2 ++ .../usbharu/hideout/config/DatabaseConfig.kt | 35 +++++++++++++++++++ .../hideout/config/HttpClientConfig.kt | 12 +++++++ .../core/SnowflakeIdGenerateService.kt | 2 -- .../core/TwitterSnowflakeIdGenerateService.kt | 2 ++ src/main/resources/application.yml | 6 ++++ 6 files changed, 57 insertions(+), 2 deletions(-) create mode 100644 src/main/kotlin/dev/usbharu/hideout/config/DatabaseConfig.kt create mode 100644 src/main/kotlin/dev/usbharu/hideout/config/HttpClientConfig.kt create mode 100644 src/main/resources/application.yml diff --git a/src/main/kotlin/dev/usbharu/hideout/SpringApplication.kt b/src/main/kotlin/dev/usbharu/hideout/SpringApplication.kt index 5d30de45..8385ee79 100644 --- a/src/main/kotlin/dev/usbharu/hideout/SpringApplication.kt +++ b/src/main/kotlin/dev/usbharu/hideout/SpringApplication.kt @@ -1,10 +1,12 @@ package dev.usbharu.hideout import org.springframework.boot.autoconfigure.SpringBootApplication +import org.springframework.boot.context.properties.ConfigurationPropertiesScan import org.springframework.boot.runApplication @SpringBootApplication +@ConfigurationPropertiesScan class SpringApplication fun main(args: Array) { diff --git a/src/main/kotlin/dev/usbharu/hideout/config/DatabaseConfig.kt b/src/main/kotlin/dev/usbharu/hideout/config/DatabaseConfig.kt new file mode 100644 index 00000000..b597249a --- /dev/null +++ b/src/main/kotlin/dev/usbharu/hideout/config/DatabaseConfig.kt @@ -0,0 +1,35 @@ +package dev.usbharu.hideout.config + +import org.jetbrains.exposed.sql.Database +import org.springframework.beans.factory.annotation.Autowired +import org.springframework.boot.context.properties.ConfigurationProperties +import org.springframework.context.annotation.Bean +import org.springframework.context.annotation.Configuration + + +@Configuration +class DatabaseConfig { + + @Autowired + lateinit var dbConfig: DatabaseConnectConfig + + @Bean + fun database(): Database { + return Database.connect( + url = dbConfig.url, + driver = dbConfig.driver, + user = dbConfig.user ?: "", + password = dbConfig.password ?: "" + ) + } + +} + + +@ConfigurationProperties("hideout.database") +data class DatabaseConnectConfig( + val url: String, + val driver: String, + val user: String?, + val password: String? +) diff --git a/src/main/kotlin/dev/usbharu/hideout/config/HttpClientConfig.kt b/src/main/kotlin/dev/usbharu/hideout/config/HttpClientConfig.kt new file mode 100644 index 00000000..85483577 --- /dev/null +++ b/src/main/kotlin/dev/usbharu/hideout/config/HttpClientConfig.kt @@ -0,0 +1,12 @@ +package dev.usbharu.hideout.config + +import io.ktor.client.* +import io.ktor.client.engine.cio.* +import org.springframework.context.annotation.Bean +import org.springframework.context.annotation.Configuration + +@Configuration +class HttpClientConfig { + @Bean + fun httpClient(): HttpClient = HttpClient(CIO) +} diff --git a/src/main/kotlin/dev/usbharu/hideout/service/core/SnowflakeIdGenerateService.kt b/src/main/kotlin/dev/usbharu/hideout/service/core/SnowflakeIdGenerateService.kt index a4fbbf15..e90ea2d6 100644 --- a/src/main/kotlin/dev/usbharu/hideout/service/core/SnowflakeIdGenerateService.kt +++ b/src/main/kotlin/dev/usbharu/hideout/service/core/SnowflakeIdGenerateService.kt @@ -3,11 +3,9 @@ package dev.usbharu.hideout.service.core import kotlinx.coroutines.delay import kotlinx.coroutines.sync.Mutex import kotlinx.coroutines.sync.withLock -import org.springframework.stereotype.Service import java.time.Instant @Suppress("MagicNumber") -@Service open class SnowflakeIdGenerateService(private val baseTime: Long) : IdGenerateService { var lastTimeStamp: Long = -1 var sequenceId: Int = 0 diff --git a/src/main/kotlin/dev/usbharu/hideout/service/core/TwitterSnowflakeIdGenerateService.kt b/src/main/kotlin/dev/usbharu/hideout/service/core/TwitterSnowflakeIdGenerateService.kt index 17459f2b..e3e46739 100644 --- a/src/main/kotlin/dev/usbharu/hideout/service/core/TwitterSnowflakeIdGenerateService.kt +++ b/src/main/kotlin/dev/usbharu/hideout/service/core/TwitterSnowflakeIdGenerateService.kt @@ -1,8 +1,10 @@ package dev.usbharu.hideout.service.core +import org.springframework.context.annotation.Primary import org.springframework.stereotype.Service // 2010-11-04T01:42:54.657 @Suppress("MagicNumber") @Service +@Primary object TwitterSnowflakeIdGenerateService : SnowflakeIdGenerateService(1288834974657L) diff --git a/src/main/resources/application.yml b/src/main/resources/application.yml new file mode 100644 index 00000000..f792e465 --- /dev/null +++ b/src/main/resources/application.yml @@ -0,0 +1,6 @@ +hideout: + database: + url: "jdbc:h2:./test;MODE=POSTGRESQL" + driver: "org.h2.Driver" + username: "" + password: "" From ebbf153b9b8e4da4436a6c3a7d3b5ab2ead28651 Mon Sep 17 00:00:00 2001 From: usbharu <64310155+usbharu@users.noreply.github.com> Date: Fri, 18 Aug 2023 13:36:18 +0900 Subject: [PATCH 04/15] =?UTF-8?q?fix:=20=E3=83=97=E3=83=AD=E3=83=91?= =?UTF-8?q?=E3=83=86=E3=82=A3=E5=90=8D=E9=96=93=E9=81=95=E3=81=88=E3=81=A6?= =?UTF-8?q?=E3=81=84=E3=81=9F=E3=81=AE=E3=81=A7=E4=BF=AE=E6=AD=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../kotlin/dev/usbharu/hideout/config/DatabaseConfig.kt | 8 ++++---- src/main/resources/application.yml | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/main/kotlin/dev/usbharu/hideout/config/DatabaseConfig.kt b/src/main/kotlin/dev/usbharu/hideout/config/DatabaseConfig.kt index b597249a..dfe744ac 100644 --- a/src/main/kotlin/dev/usbharu/hideout/config/DatabaseConfig.kt +++ b/src/main/kotlin/dev/usbharu/hideout/config/DatabaseConfig.kt @@ -18,8 +18,8 @@ class DatabaseConfig { return Database.connect( url = dbConfig.url, driver = dbConfig.driver, - user = dbConfig.user ?: "", - password = dbConfig.password ?: "" + user = dbConfig.user, + password = dbConfig.password ) } @@ -30,6 +30,6 @@ class DatabaseConfig { data class DatabaseConnectConfig( val url: String, val driver: String, - val user: String?, - val password: String? + val user: String, + val password: String ) diff --git a/src/main/resources/application.yml b/src/main/resources/application.yml index f792e465..567c1259 100644 --- a/src/main/resources/application.yml +++ b/src/main/resources/application.yml @@ -2,5 +2,5 @@ hideout: database: url: "jdbc:h2:./test;MODE=POSTGRESQL" driver: "org.h2.Driver" - username: "" + user: "" password: "" From ef6f9ae6ab52edf04ce26fc60a3b0835449882f9 Mon Sep 17 00:00:00 2001 From: usbharu <64310155+usbharu@users.noreply.github.com> Date: Fri, 18 Aug 2023 15:25:42 +0900 Subject: [PATCH 05/15] =?UTF-8?q?feat:=20Controller=E3=81=AE=E8=87=AA?= =?UTF-8?q?=E5=8B=95=E7=94=9F=E6=88=90?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- build.gradle.kts | 43 +++++++++++++++++++++++++---- src/main/resources/openapi/api.yaml | 15 ++++++---- 2 files changed, 47 insertions(+), 11 deletions(-) diff --git a/build.gradle.kts b/build.gradle.kts index 8b799706..1f52b4a9 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -1,5 +1,6 @@ import com.github.jengelman.gradle.plugins.shadow.tasks.ShadowJar import org.jetbrains.kotlin.gradle.tasks.KotlinCompile +import org.openapitools.generator.gradle.plugin.tasks.GenerateTask val ktor_version: String by project val kotlin_version: String by project @@ -16,6 +17,7 @@ plugins { id("com.google.devtools.ksp") version "1.8.21-1.0.11" id("org.springframework.boot") version "3.1.2" kotlin("plugin.spring") version "1.8.21" + id("org.openapi.generator") version "6.6.0" // id("org.jetbrains.kotlin.plugin.serialization") version "1.8.10" } @@ -59,6 +61,35 @@ tasks.clean { delete += listOf("$rootDir/src/main/resources/static") } +tasks.create("openApiGenerateServer", GenerateTask::class) { + generatorName.set("kotlin-spring") + inputSpec.set("$rootDir/src/main/resources/openapi/api.yaml") + outputDir.set("$buildDir/generated/sources/openapi") + apiPackage.set("dev.usbharu.hideout.controller") + modelPackage.set("dev.usbharu.hideout.domain.model.generated") + configOptions.put("interfaceOnly", "true") + configOptions.put("useSpringBoot3", "true") + additionalProperties.put("useTags", "true") + schemaMappings.putAll( + mapOf( + "ReactionResponse" to "dev.usbharu.hideout.domain.model.hideout.dto.ReactionResponse", + "Account" to "dev.usbharu.hideout.domain.model.hideout.dto.Account", + "JwtToken" to "dev.usbharu.hideout.domain.model.hideout.dto.JwtToken", + "PostRequest" to "dev.usbharu.hideout.domain.model.hideout.form.Post", + "PostResponse" to "dev.usbharu.hideout.domain.model.hideout.dto.PostResponse", + "Reaction" to "dev.usbharu.hideout.domain.model.hideout.form.Reaction", + "RefreshToken" to "dev.usbharu.hideout.domain.model.hideout.form.RefreshToken", + "UserLogin" to "dev.usbharu.hideout.domain.model.hideout.form.UserLogin", + "UserResponse" to "dev.usbharu.hideout.domain.model.hideout.dto.UserResponse", + "UserCreate" to "dev.usbharu.hideout.domain.model.hideout.form.UserCreate", + "Visibility" to "dev.usbharu.hideout.domain.model.hideout.entity.Visibility", + ) + ) + +// importMappings.putAll(mapOf("ReactionResponse" to "ReactionResponse")) +// typeMappings.putAll(mapOf("ReactionResponse" to "ReactionResponse")) +} + repositories { mavenCentral() } @@ -72,7 +103,7 @@ kotlin { } sourceSets.main { - kotlin.srcDirs("$buildDir/generated/ksp/main") + kotlin.srcDirs("$buildDir/generated/ksp/main", "$buildDir/generated/sources/openapi/src/main/kotlin") } dependencies { @@ -104,8 +135,10 @@ dependencies { ksp("io.insert-koin:koin-ksp-compiler:1.2.0") implementation("org.springframework.boot:spring-boot-starter-web") - - + implementation("jakarta.validation:jakarta.validation-api") + implementation("jakarta.annotation:jakarta.annotation-api:2.1.0") + compileOnly("io.swagger.core.v3:swagger-annotations:2.2.6") + implementation("io.swagger.core.v3:swagger-models:2.2.6") implementation("io.ktor:ktor-client-logging-jvm:$ktor_version") implementation("io.ktor:ktor-server-host-common-jvm:$ktor_version") @@ -113,7 +146,7 @@ dependencies { testImplementation("io.ktor:ktor-server-tests-jvm:$ktor_version") testImplementation("org.jetbrains.kotlin:kotlin-test-junit:$kotlin_version") - testImplementation ("org.jetbrains.kotlinx:kotlinx-coroutines-test:1.6.4") + testImplementation("org.jetbrains.kotlinx:kotlinx-coroutines-test:1.6.4") implementation("io.ktor:ktor-client-core:$ktor_version") implementation("io.ktor:ktor-client-cio:$ktor_version") @@ -153,7 +186,7 @@ graalvmNative { named("main") { fallback.set(false) verbose.set(true) - agent{ + agent { enabled.set(false) } diff --git a/src/main/resources/openapi/api.yaml b/src/main/resources/openapi/api.yaml index 840daedd..8cbfd648 100644 --- a/src/main/resources/openapi/api.yaml +++ b/src/main/resources/openapi/api.yaml @@ -214,12 +214,7 @@ paths: content: application/json: schema: - type: object - properties: - username: - type: string - password: - type: string + $ref: "#/components/schemas/UserCreate" responses: 201: description: ユーザーが作成された @@ -509,6 +504,14 @@ components: url: type: string + UserCreate: + type: object + properties: + username: + type: string + password: + type: string + securitySchemes: BearerAuth: type: http From 6aaf01a026e1c5523aaf0da31cead6acadc171d0 Mon Sep 17 00:00:00 2001 From: usbharu <64310155+usbharu@users.noreply.github.com> Date: Mon, 28 Aug 2023 21:05:34 +0900 Subject: [PATCH 06/15] =?UTF-8?q?feat:=20Spring=20Security=E3=81=AE?= =?UTF-8?q?=E5=B0=8E=E5=85=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- build.gradle.kts | 5 + .../usbharu/hideout/config/SecurityConfig.kt | 112 ++++++ .../hideout/controller/DefaultApiImpl.kt | 14 + .../RegisteredClientRepositoryImpl.kt | 170 +++++++++ ...xposedOAuth2AuthorizationConsentService.kt | 65 ++++ .../auth/ExposedOAuth2AuthorizationService.kt | 329 ++++++++++++++++++ .../service/auth/UserDetailsServiceImpl.kt | 26 ++ .../auth/UsernamePasswordAuthFilter.kt | 17 + .../dev/usbharu/hideout/util/JsonUtil.kt | 16 + 9 files changed, 754 insertions(+) create mode 100644 src/main/kotlin/dev/usbharu/hideout/config/SecurityConfig.kt create mode 100644 src/main/kotlin/dev/usbharu/hideout/controller/DefaultApiImpl.kt create mode 100644 src/main/kotlin/dev/usbharu/hideout/repository/RegisteredClientRepositoryImpl.kt create mode 100644 src/main/kotlin/dev/usbharu/hideout/service/auth/ExposedOAuth2AuthorizationConsentService.kt create mode 100644 src/main/kotlin/dev/usbharu/hideout/service/auth/ExposedOAuth2AuthorizationService.kt create mode 100644 src/main/kotlin/dev/usbharu/hideout/service/auth/UserDetailsServiceImpl.kt create mode 100644 src/main/kotlin/dev/usbharu/hideout/service/auth/UsernamePasswordAuthFilter.kt create mode 100644 src/main/kotlin/dev/usbharu/hideout/util/JsonUtil.kt diff --git a/build.gradle.kts b/build.gradle.kts index 1f52b4a9..4d19ebab 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -135,10 +135,15 @@ dependencies { ksp("io.insert-koin:koin-ksp-compiler:1.2.0") implementation("org.springframework.boot:spring-boot-starter-web") + implementation("org.springframework.boot:spring-boot-starter-security") + implementation("org.springframework.boot:spring-boot-starter-oauth2-authorization-server") + implementation("org.springframework.boot:spring-boot-starter-oauth2-resource-server") implementation("jakarta.validation:jakarta.validation-api") implementation("jakarta.annotation:jakarta.annotation-api:2.1.0") compileOnly("io.swagger.core.v3:swagger-annotations:2.2.6") implementation("io.swagger.core.v3:swagger-models:2.2.6") + implementation("org.jetbrains.exposed:exposed-java-time:$exposed_version") + implementation("org.jetbrains.exposed:spring-transaction:$exposed_version") implementation("io.ktor:ktor-client-logging-jvm:$ktor_version") implementation("io.ktor:ktor-server-host-common-jvm:$ktor_version") diff --git a/src/main/kotlin/dev/usbharu/hideout/config/SecurityConfig.kt b/src/main/kotlin/dev/usbharu/hideout/config/SecurityConfig.kt new file mode 100644 index 00000000..a127762a --- /dev/null +++ b/src/main/kotlin/dev/usbharu/hideout/config/SecurityConfig.kt @@ -0,0 +1,112 @@ +package dev.usbharu.hideout.config + +import com.nimbusds.jose.jwk.JWKSet +import com.nimbusds.jose.jwk.RSAKey +import com.nimbusds.jose.jwk.source.ImmutableJWKSet +import com.nimbusds.jose.jwk.source.JWKSource +import com.nimbusds.jose.proc.SecurityContext +import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty +import org.springframework.boot.context.properties.ConfigurationProperties +import org.springframework.context.annotation.Bean +import org.springframework.context.annotation.Configuration +import org.springframework.core.annotation.Order +import org.springframework.http.MediaType +import org.springframework.security.config.Customizer +import org.springframework.security.config.annotation.web.builders.HttpSecurity +import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity +import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder +import org.springframework.security.crypto.password.PasswordEncoder +import org.springframework.security.oauth2.jwt.JwtDecoder +import org.springframework.security.oauth2.server.authorization.config.annotation.web.configuration.OAuth2AuthorizationServerConfiguration +import org.springframework.security.oauth2.server.authorization.settings.AuthorizationServerSettings +import org.springframework.security.web.SecurityFilterChain +import org.springframework.security.web.authentication.LoginUrlAuthenticationEntryPoint +import org.springframework.security.web.util.matcher.MediaTypeRequestMatcher +import java.security.KeyPairGenerator +import java.security.interfaces.RSAPrivateKey +import java.security.interfaces.RSAPublicKey +import java.util.* + +@EnableWebSecurity +@Configuration +class SecurityConfig { + + @Bean + @Order(1) + fun oauth2SecurityFilterChain(http: HttpSecurity): SecurityFilterChain { + OAuth2AuthorizationServerConfiguration.applyDefaultSecurity(http) + http + .exceptionHandling { + it.defaultAuthenticationEntryPointFor( + LoginUrlAuthenticationEntryPoint("/login"), MediaTypeRequestMatcher(MediaType.TEXT_HTML) + ) + } + .oauth2ResourceServer { + it.jwt(Customizer.withDefaults()) + } + return http.build() + } + + + @Bean + @Order(2) + fun defaultSecurityFilterChain(http: HttpSecurity): SecurityFilterChain { + http + .authorizeHttpRequests { + it.anyRequest().authenticated() + } + .formLogin(Customizer.withDefaults()) + return http.build() + } + + @Bean + fun passwordEncoder(): PasswordEncoder { + return BCryptPasswordEncoder() + } + + @Bean + fun genJwkSource(): JWKSource { + val keyPairGenerator = KeyPairGenerator.getInstance("RSA") + keyPairGenerator.initialize(2048) + val generateKeyPair = keyPairGenerator.generateKeyPair() + val rsaPublicKey = generateKeyPair.public as RSAPublicKey + val rsaPrivateKey = generateKeyPair.private as RSAPrivateKey + val rsaKey = RSAKey + .Builder(rsaPublicKey) + .privateKey(rsaPrivateKey) + .keyID(UUID.randomUUID().toString()) + .build() + + val jwkSet = JWKSet(rsaKey) + return ImmutableJWKSet(jwkSet) + } + + @Bean + @ConditionalOnProperty(name = ["hideout.security.jwt.generate"], havingValue = "") + fun loadJwkSource(jwkConfig: JwkConfig): JWKSource { + val rsaKey = RSAKey.Builder(jwkConfig.publicKey) + .privateKey(jwkConfig.privateKey) + .keyID(jwkConfig.keyId) + .build() + return ImmutableJWKSet(JWKSet(rsaKey)) + } + + @Bean + fun jwtDecoder(jwkSource: JWKSource): JwtDecoder { + return OAuth2AuthorizationServerConfiguration.jwtDecoder(jwkSource) + } + + @Bean + fun authorizationServerSettings(): AuthorizationServerSettings { + return AuthorizationServerSettings.builder().build() + } +} + + +@ConfigurationProperties("hideout.security.jwt") +@ConditionalOnProperty(name = ["hideout.security.jwt.generate"], havingValue = "") +data class JwkConfig( + val keyId: String, + val publicKey: RSAPublicKey, + val privateKey: RSAPrivateKey +) diff --git a/src/main/kotlin/dev/usbharu/hideout/controller/DefaultApiImpl.kt b/src/main/kotlin/dev/usbharu/hideout/controller/DefaultApiImpl.kt new file mode 100644 index 00000000..32e21fb2 --- /dev/null +++ b/src/main/kotlin/dev/usbharu/hideout/controller/DefaultApiImpl.kt @@ -0,0 +1,14 @@ +package dev.usbharu.hideout.controller + +import dev.usbharu.hideout.domain.model.hideout.dto.JwtToken +import dev.usbharu.hideout.service.api.UserAuthApiService +import org.springframework.http.HttpStatus +import org.springframework.http.ResponseEntity +import org.springframework.stereotype.Controller + +@Controller +class DefaultApiImpl(private val userAuthApiService: UserAuthApiService) : DefaultApi { + override fun refreshTokenPost(): ResponseEntity { + return ResponseEntity(HttpStatus.OK) + } +} diff --git a/src/main/kotlin/dev/usbharu/hideout/repository/RegisteredClientRepositoryImpl.kt b/src/main/kotlin/dev/usbharu/hideout/repository/RegisteredClientRepositoryImpl.kt new file mode 100644 index 00000000..cb43f90a --- /dev/null +++ b/src/main/kotlin/dev/usbharu/hideout/repository/RegisteredClientRepositoryImpl.kt @@ -0,0 +1,170 @@ +package dev.usbharu.hideout.repository + +import dev.usbharu.hideout.repository.RegisteredClient.clientId +import dev.usbharu.hideout.repository.RegisteredClient.clientSettings +import dev.usbharu.hideout.repository.RegisteredClient.tokenSettings +import dev.usbharu.hideout.util.JsonUtil +import org.jetbrains.exposed.sql.* +import org.jetbrains.exposed.sql.javatime.CurrentTimestamp +import org.jetbrains.exposed.sql.javatime.timestamp +import org.jetbrains.exposed.sql.transactions.transaction +import org.springframework.security.oauth2.core.AuthorizationGrantType +import org.springframework.security.oauth2.core.ClientAuthenticationMethod +import org.springframework.security.oauth2.server.authorization.client.RegisteredClientRepository +import org.springframework.security.oauth2.server.authorization.settings.ClientSettings +import org.springframework.security.oauth2.server.authorization.settings.ConfigurationSettingNames +import org.springframework.security.oauth2.server.authorization.settings.OAuth2TokenFormat +import org.springframework.security.oauth2.server.authorization.settings.TokenSettings +import org.springframework.stereotype.Repository +import java.time.Instant +import org.springframework.security.oauth2.server.authorization.client.RegisteredClient as SpringRegisteredClient + +@Repository +class RegisteredClientRepositoryImpl(private val database: Database) : RegisteredClientRepository { + + init { + transaction(database) { + SchemaUtils.create(RegisteredClient) + SchemaUtils.createMissingTablesAndColumns(RegisteredClient) + } + } + + override fun save(registeredClient: SpringRegisteredClient?) { + requireNotNull(registeredClient) + val singleOrNull = RegisteredClient.select { RegisteredClient.id eq registeredClient.id }.singleOrNull() + if (singleOrNull == null) { + RegisteredClient.insert { + it[id] = registeredClient.id + it[clientId] = registeredClient.clientId + it[clientIdIssuedAt] = registeredClient.clientIdIssuedAt ?: Instant.now() + it[clientSecret] = registeredClient.clientSecret + it[clientSecretExpiresAt] = registeredClient.clientSecretExpiresAt + it[clientName] = registeredClient.clientName + it[clientAuthenticationMethods] = registeredClient.clientAuthenticationMethods.joinToString(",") + it[authorizationGrantTypes] = registeredClient.authorizationGrantTypes.joinToString(",") + it[redirectUris] = registeredClient.redirectUris.joinToString(",") + it[postLogoutRedirectUris] = registeredClient.postLogoutRedirectUris.joinToString(",") + it[scopes] = registeredClient.scopes.joinToString(",") + it[clientSettings] = JsonUtil.mapToJson(registeredClient.clientSettings.settings) + it[tokenSettings] = JsonUtil.mapToJson(registeredClient.tokenSettings.settings) + } + } else { + RegisteredClient.update({ RegisteredClient.id eq registeredClient.id }) { + it[clientId] = registeredClient.clientId + it[clientIdIssuedAt] = registeredClient.clientIdIssuedAt ?: Instant.now() + it[clientSecret] = registeredClient.clientSecret + it[clientSecretExpiresAt] = registeredClient.clientSecretExpiresAt + it[clientName] = registeredClient.clientName + it[clientAuthenticationMethods] = registeredClient.clientAuthenticationMethods.joinToString(",") + it[authorizationGrantTypes] = registeredClient.authorizationGrantTypes.joinToString(",") + it[redirectUris] = registeredClient.redirectUris.joinToString(",") + it[postLogoutRedirectUris] = registeredClient.postLogoutRedirectUris.joinToString(",") + it[scopes] = registeredClient.scopes.joinToString(",") + it[clientSettings] = JsonUtil.mapToJson(registeredClient.clientSettings.settings) + it[tokenSettings] = JsonUtil.mapToJson(registeredClient.tokenSettings.settings) + } + } + } + + override fun findById(id: String?): SpringRegisteredClient? { + if (id == null) { + return null + } + return RegisteredClient.select { + RegisteredClient.id eq id + }.singleOrNull()?.toRegisteredClient() + } + + override fun findByClientId(clientId: String?): SpringRegisteredClient? { + if (clientId == null) { + return null + } + return RegisteredClient.select { + RegisteredClient.clientId eq clientId + }.singleOrNull()?.toRegisteredClient() + } +} + + +// org/springframework/security/oauth2/server/authorization/client/oauth2-registered-client-schema.sql +object RegisteredClient : Table("registered_client") { + val id = varchar("id", 100) + val clientId = varchar("client_id", 100) + val clientIdIssuedAt = timestamp("client_id_issued_at").defaultExpression(CurrentTimestamp()) + val clientSecret = varchar("client_secret", 200).nullable().default(null) + val clientSecretExpiresAt = timestamp("client_secret_expires_at").nullable().default(null) + val clientName = varchar("client_name", 200) + val clientAuthenticationMethods = varchar("client_authentication_methods", 1000) + val authorizationGrantTypes = varchar("authorization_grant_types", 1000) + val redirectUris = varchar("redirect_uris", 1000).nullable().default(null) + val postLogoutRedirectUris = varchar("post_logout_redirect_uris", 1000).nullable().default(null) + val scopes = varchar("scopes", 1000) + val clientSettings = varchar("client_settings", 2000) + val tokenSettings = varchar("token_settings", 2000) + + override val primaryKey = PrimaryKey(id) +} + +fun ResultRow.toRegisteredClient(): SpringRegisteredClient { + + fun resolveClientAuthenticationMethods(string: String): ClientAuthenticationMethod { + return when (string) { + ClientAuthenticationMethod.CLIENT_SECRET_BASIC.value -> ClientAuthenticationMethod.CLIENT_SECRET_BASIC + ClientAuthenticationMethod.CLIENT_SECRET_JWT.value -> ClientAuthenticationMethod.CLIENT_SECRET_JWT + ClientAuthenticationMethod.CLIENT_SECRET_POST.value -> ClientAuthenticationMethod.CLIENT_SECRET_POST + ClientAuthenticationMethod.NONE.value -> ClientAuthenticationMethod.NONE + else -> { + ClientAuthenticationMethod(string) + } + } + } + + fun resolveAuthorizationGrantType(string: String): AuthorizationGrantType { + return when (string) { + AuthorizationGrantType.AUTHORIZATION_CODE.value -> AuthorizationGrantType.AUTHORIZATION_CODE + AuthorizationGrantType.CLIENT_CREDENTIALS.value -> AuthorizationGrantType.CLIENT_CREDENTIALS + AuthorizationGrantType.REFRESH_TOKEN.value -> AuthorizationGrantType.REFRESH_TOKEN + else -> { + AuthorizationGrantType(string) + } + } + } + + val clientAuthenticationMethods = this[RegisteredClient.clientAuthenticationMethods].split(",").toSet() + val authorizationGrantTypes = this[RegisteredClient.authorizationGrantTypes].split(",").toSet() + val redirectUris = this[RegisteredClient.redirectUris]?.split(",").orEmpty().toSet() + val postLogoutRedirectUris = this[RegisteredClient.postLogoutRedirectUris]?.split(",").orEmpty().toSet() + val clientScopes = this[RegisteredClient.scopes].split(",").toSet() + + val builder = SpringRegisteredClient + .withId(this[RegisteredClient.id]) + .clientId(this[clientId]) + .clientIdIssuedAt(this[RegisteredClient.clientIdIssuedAt]) + .clientSecret(this[RegisteredClient.clientSecret]) + .clientSecretExpiresAt(this[RegisteredClient.clientSecretExpiresAt]) + .clientName(this[RegisteredClient.clientName]) + .clientAuthenticationMethods { + clientAuthenticationMethods.forEach { s -> + it.add(resolveClientAuthenticationMethods(s)) + } + } + .authorizationGrantTypes { + authorizationGrantTypes.forEach { s -> + it.add(resolveAuthorizationGrantType(s)) + } + } + .redirectUris { it.addAll(redirectUris) } + .postLogoutRedirectUris { it.addAll(postLogoutRedirectUris) } + .scopes { it.addAll(clientScopes) } + .clientSettings(ClientSettings.withSettings(JsonUtil.jsonToMap(this[clientSettings])).build()) + + + val tokenSettingsMap = JsonUtil.jsonToMap(this[tokenSettings]) + val withSettings = TokenSettings.withSettings(tokenSettingsMap) + if (tokenSettingsMap.containsKey(ConfigurationSettingNames.Token.ACCESS_TOKEN_FORMAT)) { + withSettings.accessTokenFormat(OAuth2TokenFormat.SELF_CONTAINED) + } + builder.tokenSettings(withSettings.build()) + + return builder.build() +} diff --git a/src/main/kotlin/dev/usbharu/hideout/service/auth/ExposedOAuth2AuthorizationConsentService.kt b/src/main/kotlin/dev/usbharu/hideout/service/auth/ExposedOAuth2AuthorizationConsentService.kt new file mode 100644 index 00000000..45958141 --- /dev/null +++ b/src/main/kotlin/dev/usbharu/hideout/service/auth/ExposedOAuth2AuthorizationConsentService.kt @@ -0,0 +1,65 @@ +package dev.usbharu.hideout.service.auth + +import org.jetbrains.exposed.sql.* +import org.jetbrains.exposed.sql.SqlExpressionBuilder.eq +import org.springframework.security.core.authority.SimpleGrantedAuthority +import org.springframework.security.oauth2.server.authorization.OAuth2AuthorizationConsentService +import org.springframework.security.oauth2.server.authorization.client.RegisteredClientRepository +import org.springframework.stereotype.Service +import org.springframework.security.oauth2.server.authorization.OAuth2AuthorizationConsent as AuthorizationConsent + +@Service +class ExposedOAuth2AuthorizationConsentService(private val registeredClientRepository: RegisteredClientRepository) : + OAuth2AuthorizationConsentService { + override fun save(authorizationConsent: AuthorizationConsent?) { + requireNotNull(authorizationConsent) + val singleOrNull = + OAuth2AuthorizationConsent.select { OAuth2AuthorizationConsent.registeredClientId eq authorizationConsent.registeredClientId and (OAuth2AuthorizationConsent.principalName eq authorizationConsent.principalName) } + .singleOrNull() + if (singleOrNull == null) { + OAuth2AuthorizationConsent.insert { + it[registeredClientId] = authorizationConsent.registeredClientId + it[principalName] = authorizationConsent.principalName + it[authorities] = authorizationConsent.authorities.joinToString(",") + } + } + } + + override fun remove(authorizationConsent: AuthorizationConsent?) { + if (authorizationConsent == null) { + return + } + OAuth2AuthorizationConsent.deleteWhere { + registeredClientId eq authorizationConsent.registeredClientId and (principalName eq principalName) + } + } + + override fun findById(registeredClientId: String?, principalName: String?): AuthorizationConsent? { + requireNotNull(registeredClientId) + requireNotNull(principalName) + + return OAuth2AuthorizationConsent.select { OAuth2AuthorizationConsent.registeredClientId eq registeredClientId and (OAuth2AuthorizationConsent.principalName eq principalName) } + .singleOrNull()?.toAuthorizationConsent() + } + + fun ResultRow.toAuthorizationConsent(): AuthorizationConsent { + val registeredClientId = this[OAuth2AuthorizationConsent.registeredClientId] + val registeredClient = registeredClientRepository.findById(registeredClientId) + + val principalName = this[OAuth2AuthorizationConsent.principalName] + val builder = AuthorizationConsent.withId(registeredClientId, principalName) + + this[OAuth2AuthorizationConsent.authorities].split(",").forEach { + builder.authority(SimpleGrantedAuthority(it)) + } + + return builder.build() + } +} + +object OAuth2AuthorizationConsent : Table("oauth2_authorization_consent") { + val registeredClientId = varchar("registered_client_id", 100) + val principalName = varchar("principal_name", 200) + val authorities = varchar("authorities", 1000) + override val primaryKey = PrimaryKey(registeredClientId, principalName) +} diff --git a/src/main/kotlin/dev/usbharu/hideout/service/auth/ExposedOAuth2AuthorizationService.kt b/src/main/kotlin/dev/usbharu/hideout/service/auth/ExposedOAuth2AuthorizationService.kt new file mode 100644 index 00000000..8abea597 --- /dev/null +++ b/src/main/kotlin/dev/usbharu/hideout/service/auth/ExposedOAuth2AuthorizationService.kt @@ -0,0 +1,329 @@ +package dev.usbharu.hideout.service.auth + +import dev.usbharu.hideout.util.JsonUtil +import org.jetbrains.exposed.sql.* +import org.jetbrains.exposed.sql.SqlExpressionBuilder.eq +import org.jetbrains.exposed.sql.javatime.timestamp +import org.springframework.security.oauth2.core.* +import org.springframework.security.oauth2.core.endpoint.OAuth2ParameterNames +import org.springframework.security.oauth2.core.oidc.OidcIdToken +import org.springframework.security.oauth2.core.oidc.endpoint.OidcParameterNames +import org.springframework.security.oauth2.server.authorization.OAuth2Authorization +import org.springframework.security.oauth2.server.authorization.OAuth2AuthorizationCode +import org.springframework.security.oauth2.server.authorization.OAuth2AuthorizationService +import org.springframework.security.oauth2.server.authorization.OAuth2TokenType +import org.springframework.security.oauth2.server.authorization.client.RegisteredClientRepository +import org.springframework.stereotype.Service + +@Service +class ExposedOAuth2AuthorizationService(private val registeredClientRepository: RegisteredClientRepository) : + OAuth2AuthorizationService { + override fun save(authorization: OAuth2Authorization?) { + requireNotNull(authorization) + val singleOrNull = Authorization.select { Authorization.id eq authorization.id }.singleOrNull() + if (singleOrNull == null) { + val authorizationCodeToken = authorization.getToken(OAuth2AuthorizationCode::class.java) + val accessToken = authorization.getToken(OAuth2AccessToken::class.java) + val refreshToken = authorization.getToken(OAuth2RefreshToken::class.java) + val oidcIdToken = authorization.getToken(OidcIdToken::class.java) + val userCode = authorization.getToken(OAuth2UserCode::class.java) + val deviceCode = authorization.getToken(OAuth2DeviceCode::class.java) + Authorization.insert { + it[id] = authorization.id + it[registeredClientId] = authorization.registeredClientId + it[principalName] = authorization.principalName + it[authorizationGrantType] = authorization.authorizationGrantType.value + it[authorizedScopes] = authorization.authorizedScopes.joinToString(",").takeIf { it.isEmpty() } + it[attributes] = JsonUtil.mapToJson(authorization.attributes) + it[state] = authorization.getAttribute(OAuth2ParameterNames.STATE) + it[authorizationCodeValue] = authorizationCodeToken?.token?.tokenValue + it[authorizationCodeIssuedAt] = authorizationCodeToken?.token?.issuedAt + it[authorizationCodeExpiresAt] = authorizationCodeToken?.token?.expiresAt + it[authorizationCodeMetadata] = authorizationCodeToken?.metadata?.let { it1 -> JsonUtil.mapToJson(it1) } + it[accessTokenValue] = accessToken?.token?.tokenValue + it[accessTokenIssuedAt] = accessToken?.token?.issuedAt + it[accessTokenExpiresAt] = accessToken?.token?.expiresAt + it[accessTokenMetadata] = accessToken?.metadata?.let { it1 -> JsonUtil.mapToJson(it1) } + it[accessTokenType] = accessToken?.token?.tokenType?.value + it[accessTokenScopes] = accessToken?.token?.scopes?.joinToString(",")?.takeIf { it.isEmpty() } + it[refreshTokenValue] = refreshToken?.token?.tokenValue + it[refreshTokenIssuedAt] = refreshToken?.token?.issuedAt + it[refreshTokenExpiresAt] = refreshToken?.token?.expiresAt + it[refreshTokenMetadata] = refreshToken?.metadata?.let { it1 -> JsonUtil.mapToJson(it1) } + it[oidcIdTokenValue] = oidcIdToken?.token?.tokenValue + it[oidcIdTokenIssuedAt] = oidcIdToken?.token?.issuedAt + it[oidcIdTokenExpiresAt] = oidcIdToken?.token?.expiresAt + it[oidcIdTokenMetadata] = oidcIdToken?.metadata?.let { it1 -> JsonUtil.mapToJson(it1) } + it[userCodeValue] = userCode?.token?.tokenValue + it[userCodeIssuedAt] = userCode?.token?.issuedAt + it[userCodeExpiresAt] = userCode?.token?.expiresAt + it[userCodeMetadata] = userCode?.metadata?.let { it1 -> JsonUtil.mapToJson(it1) } + it[deviceCodeValue] = deviceCode?.token?.tokenValue + it[deviceCodeIssuedAt] = deviceCode?.token?.issuedAt + it[deviceCodeExpiresAt] = deviceCode?.token?.expiresAt + it[deviceCodeMetadata] = deviceCode?.metadata?.let { it1 -> JsonUtil.mapToJson(it1) } + } + } else { + val authorizationCodeToken = authorization.getToken(OAuth2AuthorizationCode::class.java) + val accessToken = authorization.getToken(OAuth2AccessToken::class.java) + val refreshToken = authorization.getToken(OAuth2RefreshToken::class.java) + val oidcIdToken = authorization.getToken(OidcIdToken::class.java) + val userCode = authorization.getToken(OAuth2UserCode::class.java) + val deviceCode = authorization.getToken(OAuth2DeviceCode::class.java) + Authorization.update({ Authorization.id eq authorization.id }) { + it[registeredClientId] = authorization.registeredClientId + it[principalName] = authorization.principalName + it[authorizationGrantType] = authorization.authorizationGrantType.value + it[authorizedScopes] = authorization.authorizedScopes.joinToString(",").takeIf { it.isEmpty() } + it[attributes] = JsonUtil.mapToJson(authorization.attributes) + it[state] = authorization.getAttribute(OAuth2ParameterNames.STATE) + it[authorizationCodeValue] = authorizationCodeToken?.token?.tokenValue + it[authorizationCodeIssuedAt] = authorizationCodeToken?.token?.issuedAt + it[authorizationCodeExpiresAt] = authorizationCodeToken?.token?.expiresAt + it[authorizationCodeMetadata] = authorizationCodeToken?.metadata?.let { it1 -> JsonUtil.mapToJson(it1) } + it[accessTokenValue] = accessToken?.token?.tokenValue + it[accessTokenIssuedAt] = accessToken?.token?.issuedAt + it[accessTokenExpiresAt] = accessToken?.token?.expiresAt + it[accessTokenMetadata] = accessToken?.metadata?.let { it1 -> JsonUtil.mapToJson(it1) } + it[accessTokenType] = accessToken?.token?.tokenType?.value + it[accessTokenScopes] = accessToken?.token?.scopes?.joinToString(",")?.takeIf { it.isEmpty() } + it[refreshTokenValue] = refreshToken?.token?.tokenValue + it[refreshTokenIssuedAt] = refreshToken?.token?.issuedAt + it[refreshTokenExpiresAt] = refreshToken?.token?.expiresAt + it[refreshTokenMetadata] = refreshToken?.metadata?.let { it1 -> JsonUtil.mapToJson(it1) } + it[oidcIdTokenValue] = oidcIdToken?.token?.tokenValue + it[oidcIdTokenIssuedAt] = oidcIdToken?.token?.issuedAt + it[oidcIdTokenExpiresAt] = oidcIdToken?.token?.expiresAt + it[oidcIdTokenMetadata] = oidcIdToken?.metadata?.let { it1 -> JsonUtil.mapToJson(it1) } + it[userCodeValue] = userCode?.token?.tokenValue + it[userCodeIssuedAt] = userCode?.token?.issuedAt + it[userCodeExpiresAt] = userCode?.token?.expiresAt + it[userCodeMetadata] = userCode?.metadata?.let { it1 -> JsonUtil.mapToJson(it1) } + it[deviceCodeValue] = deviceCode?.token?.tokenValue + it[deviceCodeIssuedAt] = deviceCode?.token?.issuedAt + it[deviceCodeExpiresAt] = deviceCode?.token?.expiresAt + it[deviceCodeMetadata] = deviceCode?.metadata?.let { it1 -> JsonUtil.mapToJson(it1) } + } + } + + } + + override fun remove(authorization: OAuth2Authorization?) { + if (authorization == null) { + return + } + Authorization.deleteWhere { Authorization.id eq authorization.id } + } + + override fun findById(id: String?): OAuth2Authorization? { + if (id == null) { + return null + } + return Authorization.select { Authorization.id eq id }.singleOrNull()?.toAuthorization() + } + + override fun findByToken(token: String?, tokenType: OAuth2TokenType?): OAuth2Authorization? { + requireNotNull(token) + return when (tokenType?.value) { + null -> { + Authorization.select { + Authorization.authorizationCodeValue eq token + }.orWhere { + Authorization.accessTokenValue eq token + }.orWhere { + Authorization.oidcIdTokenValue eq token + }.orWhere { + Authorization.refreshTokenValue eq token + }.orWhere { + Authorization.userCodeValue eq token + }.orWhere { + Authorization.deviceCodeValue eq token + } + } + + OAuth2ParameterNames.STATE -> { + Authorization.select { Authorization.state eq token } + } + + OAuth2ParameterNames.CODE -> { + Authorization.select { Authorization.authorizationCodeValue eq token } + } + + OAuth2ParameterNames.ACCESS_TOKEN -> { + Authorization.select { Authorization.accessTokenValue eq token } + } + + OidcParameterNames.ID_TOKEN -> { + Authorization.select { Authorization.oidcIdTokenValue eq token } + } + + OAuth2ParameterNames.REFRESH_TOKEN -> { + Authorization.select { Authorization.refreshTokenValue eq token } + } + + OAuth2ParameterNames.USER_CODE -> { + Authorization.select { Authorization.userCodeValue eq token } + } + + OAuth2ParameterNames.DEVICE_CODE -> { + Authorization.select { Authorization.deviceCodeValue eq token } + } + + else -> { + null + } + }?.singleOrNull()?.toAuthorization() + } + + fun ResultRow.toAuthorization(): OAuth2Authorization { + + val registeredClientId = this[Authorization.registeredClientId] + + val registeredClient = registeredClientRepository.findById(registeredClientId) + + val builder = OAuth2Authorization.withRegisteredClient(registeredClient) + val id = this[Authorization.id] + val principalName = this[Authorization.principalName] + val authorizationGrantType = this[Authorization.authorizationGrantType] + val authorizedScopes = this[Authorization.authorizedScopes]?.split(",").orEmpty().toSet() + val attributes = this[Authorization.attributes]?.let { JsonUtil.jsonToMap(it) } ?: emptyMap() + + builder.id(id).principalName(principalName) + .authorizationGrantType(AuthorizationGrantType(authorizationGrantType)).authorizedScopes(authorizedScopes) + .attributes { it.putAll(attributes) } + + val state = this[Authorization.state].orEmpty() + if (state.isNotBlank()) { + builder.attribute(OAuth2ParameterNames.STATE, state) + } + + val authorizationCodeValue = this[Authorization.authorizationCodeValue] + if (authorizationCodeValue.isNullOrBlank()) { + val authorizationCodeIssuedAt = this[Authorization.authorizationCodeIssuedAt] + val authorizationCodeExpiresAt = this[Authorization.authorizationCodeExpiresAt] + val authorizationCodeMetadata = this[Authorization.authorizationCodeMetadata]?.let { + JsonUtil.jsonToMap( + it + ) + } ?: emptyMap() + val oAuth2AuthorizationCode = + OAuth2AuthorizationCode(authorizationCodeValue, authorizationCodeIssuedAt, authorizationCodeExpiresAt) + builder.token(oAuth2AuthorizationCode) { + it.putAll(authorizationCodeMetadata) + } + } + + val accessTokenValue = this[Authorization.accessTokenValue].orEmpty() + if (accessTokenValue.isNotBlank()) { + val accessTokenIssuedAt = this[Authorization.accessTokenIssuedAt] + val accessTokenExpiresAt = this[Authorization.accessTokenExpiresAt] + val accessTokenMetadata = + this[Authorization.accessTokenMetadata]?.let { JsonUtil.jsonToMap(it) } ?: emptyMap() + val accessTokenType = + if (this[Authorization.accessTokenType].equals(OAuth2AccessToken.TokenType.BEARER.value, true)) { + OAuth2AccessToken.TokenType.BEARER + } else { + null + } + + val accessTokenScope = this[Authorization.accessTokenScopes]?.split(",").orEmpty().toSet() + + val oAuth2AccessToken = OAuth2AccessToken( + accessTokenType, accessTokenValue, accessTokenIssuedAt, accessTokenExpiresAt, accessTokenScope + ) + + builder.token(oAuth2AccessToken) { it.putAll(accessTokenMetadata) } + } + + val oidcIdTokenValue = this[Authorization.oidcIdTokenValue].orEmpty() + if (oidcIdTokenValue.isNotBlank()) { + val oidcTokenIssuedAt = this[Authorization.oidcIdTokenIssuedAt] + val oidcTokenExpiresAt = this[Authorization.oidcIdTokenExpiresAt] + val oidcTokenMetadata = + this[Authorization.oidcIdTokenMetadata]?.let { JsonUtil.jsonToMap(it) } ?: emptyMap() + + val oidcIdToken = OidcIdToken( + oidcIdTokenValue, + oidcTokenIssuedAt, + oidcTokenExpiresAt, + oidcTokenMetadata.getValue(OAuth2Authorization.Token.CLAIMS_METADATA_NAME) as MutableMap? + ) + + builder.token(oidcIdToken) { it.putAll(oidcTokenMetadata) } + } + + val refreshTokenValue = this[Authorization.refreshTokenValue].orEmpty() + if (refreshTokenValue.isNotBlank()) { + val refreshTokenIssuedAt = this[Authorization.refreshTokenIssuedAt] + val refreshTokenExpiresAt = this[Authorization.refreshTokenExpiresAt] + val refreshTokenMetadata = + this[Authorization.refreshTokenMetadata]?.let { JsonUtil.jsonToMap(it) } ?: emptyMap() + + val oAuth2RefreshToken = OAuth2RefreshToken(refreshTokenValue, refreshTokenIssuedAt, refreshTokenExpiresAt) + + builder.token(oAuth2RefreshToken) { it.putAll(refreshTokenMetadata) } + } + + val userCodeValue = this[Authorization.userCodeValue].orEmpty() + if (userCodeValue.isNotBlank()) { + val userCodeIssuedAt = this[Authorization.userCodeIssuedAt] + val userCodeExpiresAt = this[Authorization.userCodeExpiresAt] + val userCodeMetadata = + this[Authorization.userCodeMetadata]?.let { JsonUtil.jsonToMap(it) } ?: emptyMap() + val oAuth2UserCode = OAuth2UserCode(userCodeValue, userCodeIssuedAt, userCodeExpiresAt) + builder.token(oAuth2UserCode) { it.putAll(userCodeMetadata) } + } + + val deviceCodeValue = this[Authorization.deviceCodeValue].orEmpty() + if (deviceCodeValue.isNotBlank()) { + val deviceCodeIssuedAt = this[Authorization.deviceCodeIssuedAt] + val deviceCodeExpiresAt = this[Authorization.deviceCodeExpiresAt] + val deviceCodeMetadata = + this[Authorization.deviceCodeMetadata]?.let { JsonUtil.jsonToMap(it) } ?: emptyMap() + + val oAuth2DeviceCode = OAuth2DeviceCode(deviceCodeValue, deviceCodeIssuedAt, deviceCodeExpiresAt) + builder.token(oAuth2DeviceCode) { it.putAll(deviceCodeMetadata) } + } + + return builder.build() + } +} + +object Authorization : Table("authorization") { + val id = varchar("id", 255) + val registeredClientId = varchar("registered_client_id", 255) + val principalName = varchar("principal_name", 255) + val authorizationGrantType = varchar("authorization_grant_type", 255) + val authorizedScopes = varchar("authorized_scopes", 1000).nullable().default(null) + val attributes = varchar("attributes", 4000).nullable().default(null) + val state = varchar("state", 500).nullable().default(null) + val authorizationCodeValue = varchar("authorization_code_value", 4000).nullable().default(null) + val authorizationCodeIssuedAt = timestamp("authorization_code_issued_at").nullable().default(null) + val authorizationCodeExpiresAt = timestamp("authorization_code_expires_at").nullable().default(null) + val authorizationCodeMetadata = varchar("authorization_code_metadata", 2000).nullable().default(null) + val accessTokenValue = varchar("access_token_value", 4000).nullable().default(null) + val accessTokenIssuedAt = timestamp("access_token_issued_at").nullable().default(null) + val accessTokenExpiresAt = timestamp("access_token_expires_at").nullable().default(null) + val accessTokenMetadata = varchar("access_token_metadata", 2000).nullable().default(null) + val accessTokenType = varchar("access_token_type", 255).nullable().default(null) + val accessTokenScopes = varchar("access_token_scopes", 1000).nullable().default(null) + val refreshTokenValue = varchar("refresh_token_value", 4000).nullable().default(null) + val refreshTokenIssuedAt = timestamp("refresh_token_issued_at").nullable().default(null) + val refreshTokenExpiresAt = timestamp("refresh_token_expires_at").nullable().default(null) + val refreshTokenMetadata = varchar("refresh_token_metadata", 2000).nullable().default(null) + val oidcIdTokenValue = varchar("oidc_id_token_value", 4000).nullable().default(null) + val oidcIdTokenIssuedAt = timestamp("oidc_id_token_issued_at").nullable().default(null) + val oidcIdTokenExpiresAt = timestamp("oidc_id_token_expires_at").nullable().default(null) + val oidcIdTokenMetadata = varchar("oidc_id_token_metadata", 2000).nullable().default(null) + val oidcIdTokenClaims = varchar("oidc_id_token_claims", 2000).nullable().default(null) + val userCodeValue = varchar("user_code_value", 4000).nullable().default(null) + val userCodeIssuedAt = timestamp("user_code_issued_at").nullable().default(null) + val userCodeExpiresAt = timestamp("user_code_expires_at").nullable().default(null) + val userCodeMetadata = varchar("user_code_metadata", 2000).nullable().default(null) + val deviceCodeValue = varchar("device_code_value", 4000).nullable().default(null) + val deviceCodeIssuedAt = timestamp("device_code_issued_at").nullable().default(null) + val deviceCodeExpiresAt = timestamp("device_code_expires_at").nullable().default(null) + val deviceCodeMetadata = varchar("device_code_metadata", 2000).nullable().default(null) + + override val primaryKey = PrimaryKey(id) +} diff --git a/src/main/kotlin/dev/usbharu/hideout/service/auth/UserDetailsServiceImpl.kt b/src/main/kotlin/dev/usbharu/hideout/service/auth/UserDetailsServiceImpl.kt new file mode 100644 index 00000000..a889e79a --- /dev/null +++ b/src/main/kotlin/dev/usbharu/hideout/service/auth/UserDetailsServiceImpl.kt @@ -0,0 +1,26 @@ +package dev.usbharu.hideout.service.auth + +import dev.usbharu.hideout.query.UserQueryService +import dev.usbharu.hideout.service.core.Transaction +import kotlinx.coroutines.runBlocking +import org.springframework.security.core.userdetails.User +import org.springframework.security.core.userdetails.UserDetails +import org.springframework.security.core.userdetails.UserDetailsService +import org.springframework.security.core.userdetails.UsernameNotFoundException +import org.springframework.stereotype.Service + +@Service +class UserDetailsServiceImpl(private val userQueryService: UserQueryService, private val transaction: Transaction) : + UserDetailsService { + override fun loadUserByUsername(username: String?): UserDetails = runBlocking { + if (username == null) { + throw UsernameNotFoundException("$username not found") + } + transaction.transaction { + val findById = userQueryService.findByNameAndDomain(username, "") + User( + findById.name, findById.password, listOf() + ) + } + } +} diff --git a/src/main/kotlin/dev/usbharu/hideout/service/auth/UsernamePasswordAuthFilter.kt b/src/main/kotlin/dev/usbharu/hideout/service/auth/UsernamePasswordAuthFilter.kt new file mode 100644 index 00000000..5655e8b4 --- /dev/null +++ b/src/main/kotlin/dev/usbharu/hideout/service/auth/UsernamePasswordAuthFilter.kt @@ -0,0 +1,17 @@ +package dev.usbharu.hideout.service.auth + +import org.springframework.security.authentication.AuthenticationManager +import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter +import org.springframework.security.web.util.matcher.AntPathRequestMatcher + + +class UsernamePasswordAuthFilter(jwtService: JwtService, authenticationManager: AuthenticationManager?) : + UsernamePasswordAuthenticationFilter(authenticationManager) { + init { + setRequiresAuthenticationRequestMatcher(AntPathRequestMatcher("/api/internal/v1/login", "POST")) + + this.setAuthenticationSuccessHandler { request, response, authentication -> + + } + } +} diff --git a/src/main/kotlin/dev/usbharu/hideout/util/JsonUtil.kt b/src/main/kotlin/dev/usbharu/hideout/util/JsonUtil.kt new file mode 100644 index 00000000..fcd97a9f --- /dev/null +++ b/src/main/kotlin/dev/usbharu/hideout/util/JsonUtil.kt @@ -0,0 +1,16 @@ +package dev.usbharu.hideout.util + +import com.fasterxml.jackson.databind.ObjectMapper +import com.fasterxml.jackson.module.kotlin.jacksonObjectMapper +import com.fasterxml.jackson.module.kotlin.readValue + +object JsonUtil { + val objectMapper = jacksonObjectMapper() + + fun mapToJson(map: Map<*, *>, objectMapper: ObjectMapper = this.objectMapper): String = + objectMapper.writeValueAsString(map) + + fun jsonToMap(json: String, objectMapper: ObjectMapper = this.objectMapper): Map = + objectMapper.readValue(json) + +} From 656e935ce2c57c3f022fc6462860396ddd511d1c Mon Sep 17 00:00:00 2001 From: usbharu <64310155+usbharu@users.noreply.github.com> Date: Tue, 19 Sep 2023 11:01:55 +0900 Subject: [PATCH 07/15] =?UTF-8?q?feat:=20Spring=20Framework=E3=81=A7?= =?UTF-8?q?=E8=B5=B7=E5=8B=95=E3=81=A7=E3=81=8D=E3=82=8B=E3=82=88=E3=81=86?= =?UTF-8?q?=E3=81=AB?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- build.gradle.kts | 3 +++ .../usbharu/hideout/config/SecurityConfig.kt | 6 +++++- .../hideout/config/SpringTransactionConfig.kt | 19 +++++++++++++++++++ .../RegisteredClientRepositoryImpl.kt | 2 ++ src/main/resources/application.yml | 6 ++++++ 5 files changed, 35 insertions(+), 1 deletion(-) create mode 100644 src/main/kotlin/dev/usbharu/hideout/config/SpringTransactionConfig.kt diff --git a/build.gradle.kts b/build.gradle.kts index 4d19ebab..e3482bc4 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -144,6 +144,9 @@ dependencies { implementation("io.swagger.core.v3:swagger-models:2.2.6") implementation("org.jetbrains.exposed:exposed-java-time:$exposed_version") implementation("org.jetbrains.exposed:spring-transaction:$exposed_version") + implementation("org.springframework.data:spring-data-commons") + implementation("org.springframework.boot:spring-boot-starter-jdbc") + implementation("org.springframework.boot:spring-boot-starter-data-jdbc") implementation("io.ktor:ktor-client-logging-jvm:$ktor_version") implementation("io.ktor:ktor-server-host-common-jvm:$ktor_version") diff --git a/src/main/kotlin/dev/usbharu/hideout/config/SecurityConfig.kt b/src/main/kotlin/dev/usbharu/hideout/config/SecurityConfig.kt index a127762a..92fd756f 100644 --- a/src/main/kotlin/dev/usbharu/hideout/config/SecurityConfig.kt +++ b/src/main/kotlin/dev/usbharu/hideout/config/SecurityConfig.kt @@ -98,7 +98,11 @@ class SecurityConfig { @Bean fun authorizationServerSettings(): AuthorizationServerSettings { - return AuthorizationServerSettings.builder().build() + return AuthorizationServerSettings.builder() + .authorizationEndpoint("/oauth/authorize") + .tokenEndpoint("/oauth/token") + .tokenRevocationEndpoint("/oauth/revoke") + .build() } } diff --git a/src/main/kotlin/dev/usbharu/hideout/config/SpringTransactionConfig.kt b/src/main/kotlin/dev/usbharu/hideout/config/SpringTransactionConfig.kt new file mode 100644 index 00000000..a9d76420 --- /dev/null +++ b/src/main/kotlin/dev/usbharu/hideout/config/SpringTransactionConfig.kt @@ -0,0 +1,19 @@ +package dev.usbharu.hideout.config + +import org.jetbrains.exposed.spring.SpringTransactionManager +import org.springframework.context.annotation.Bean +import org.springframework.context.annotation.Configuration +import org.springframework.transaction.PlatformTransactionManager +import org.springframework.transaction.annotation.EnableTransactionManagement +import org.springframework.transaction.annotation.TransactionManagementConfigurer +import javax.sql.DataSource + + +@Configuration +@EnableTransactionManagement +class SpringTransactionConfig(val datasource: DataSource) : TransactionManagementConfigurer { + @Bean + override fun annotationDrivenTransactionManager(): PlatformTransactionManager { + return SpringTransactionManager(datasource) + } +} diff --git a/src/main/kotlin/dev/usbharu/hideout/repository/RegisteredClientRepositoryImpl.kt b/src/main/kotlin/dev/usbharu/hideout/repository/RegisteredClientRepositoryImpl.kt index cb43f90a..7a825c0c 100644 --- a/src/main/kotlin/dev/usbharu/hideout/repository/RegisteredClientRepositoryImpl.kt +++ b/src/main/kotlin/dev/usbharu/hideout/repository/RegisteredClientRepositoryImpl.kt @@ -16,6 +16,7 @@ import org.springframework.security.oauth2.server.authorization.settings.Configu import org.springframework.security.oauth2.server.authorization.settings.OAuth2TokenFormat import org.springframework.security.oauth2.server.authorization.settings.TokenSettings import org.springframework.stereotype.Repository +import org.springframework.transaction.annotation.Transactional import java.time.Instant import org.springframework.security.oauth2.server.authorization.client.RegisteredClient as SpringRegisteredClient @@ -75,6 +76,7 @@ class RegisteredClientRepositoryImpl(private val database: Database) : Registere }.singleOrNull()?.toRegisteredClient() } + @Transactional override fun findByClientId(clientId: String?): SpringRegisteredClient? { if (clientId == null) { return null diff --git a/src/main/resources/application.yml b/src/main/resources/application.yml index 567c1259..5683266b 100644 --- a/src/main/resources/application.yml +++ b/src/main/resources/application.yml @@ -4,3 +4,9 @@ hideout: driver: "org.h2.Driver" user: "" password: "" +spring: + datasource: + driver-class-name: org.h2.Driver + url: "jdbc:h2:./test;MODE=POSTGRESQL" + username: "" + password: "" From afb606c9e26e536499396c0d49e5e84d73f1a640 Mon Sep 17 00:00:00 2001 From: usbharu <64310155+usbharu@users.noreply.github.com> Date: Tue, 19 Sep 2023 12:49:39 +0900 Subject: [PATCH 08/15] =?UTF-8?q?feat:=20Spring=20MVC=E3=81=AEController?= =?UTF-8?q?=E3=81=A7ActivityPub=E3=81=AE=E3=82=A8=E3=83=B3=E3=83=89?= =?UTF-8?q?=E3=83=9D=E3=82=A4=E3=83=B3=E3=83=88=E3=82=92=E5=AE=9F=E8=A3=85?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../hideout/controller/InboxController.kt | 21 +++++++++++++++++++ .../hideout/controller/InboxControllerImpl.kt | 15 +++++++++++++ .../hideout/controller/OutboxController.kt | 16 ++++++++++++++ .../controller/OutboxControllerImpl.kt | 13 ++++++++++++ .../hideout/controller/UserAPController.kt | 13 ++++++++++++ .../controller/UserAPControllerImpl.kt | 15 +++++++++++++ 6 files changed, 93 insertions(+) create mode 100644 src/main/kotlin/dev/usbharu/hideout/controller/InboxController.kt create mode 100644 src/main/kotlin/dev/usbharu/hideout/controller/InboxControllerImpl.kt create mode 100644 src/main/kotlin/dev/usbharu/hideout/controller/OutboxController.kt create mode 100644 src/main/kotlin/dev/usbharu/hideout/controller/OutboxControllerImpl.kt create mode 100644 src/main/kotlin/dev/usbharu/hideout/controller/UserAPController.kt create mode 100644 src/main/kotlin/dev/usbharu/hideout/controller/UserAPControllerImpl.kt diff --git a/src/main/kotlin/dev/usbharu/hideout/controller/InboxController.kt b/src/main/kotlin/dev/usbharu/hideout/controller/InboxController.kt new file mode 100644 index 00000000..0cba64e3 --- /dev/null +++ b/src/main/kotlin/dev/usbharu/hideout/controller/InboxController.kt @@ -0,0 +1,21 @@ +package dev.usbharu.hideout.controller + +import org.springframework.http.HttpStatus +import org.springframework.http.ResponseEntity +import org.springframework.web.bind.annotation.RequestBody +import org.springframework.web.bind.annotation.RequestMapping +import org.springframework.web.bind.annotation.RequestMethod +import org.springframework.web.bind.annotation.RestController + +@RestController +interface InboxController { + @RequestMapping( + "/inbox", + "/users/{username}/inbox", + produces = ["application/activity+json", "application/ld+json; profile=\"https://www.w3.org/ns/activitystreams\""], + method = [RequestMethod.GET, RequestMethod.POST] + ) + suspend fun inbox(@RequestBody string: String): ResponseEntity { + return ResponseEntity(HttpStatus.ACCEPTED) + } +} diff --git a/src/main/kotlin/dev/usbharu/hideout/controller/InboxControllerImpl.kt b/src/main/kotlin/dev/usbharu/hideout/controller/InboxControllerImpl.kt new file mode 100644 index 00000000..002dee31 --- /dev/null +++ b/src/main/kotlin/dev/usbharu/hideout/controller/InboxControllerImpl.kt @@ -0,0 +1,15 @@ +package dev.usbharu.hideout.controller + +import dev.usbharu.hideout.service.ap.APService +import org.springframework.http.HttpStatus +import org.springframework.http.ResponseEntity +import org.springframework.web.bind.annotation.RestController + +@RestController +class InboxControllerImpl(private val apService: APService) : InboxController { + override suspend fun inbox(string: String): ResponseEntity { + val parseActivity = apService.parseActivity(string) + apService.processActivity(string, parseActivity) + return ResponseEntity(HttpStatus.ACCEPTED) + } +} diff --git a/src/main/kotlin/dev/usbharu/hideout/controller/OutboxController.kt b/src/main/kotlin/dev/usbharu/hideout/controller/OutboxController.kt new file mode 100644 index 00000000..ee003682 --- /dev/null +++ b/src/main/kotlin/dev/usbharu/hideout/controller/OutboxController.kt @@ -0,0 +1,16 @@ +package dev.usbharu.hideout.controller + +import org.springframework.http.HttpStatus +import org.springframework.http.ResponseEntity +import org.springframework.web.bind.annotation.RequestBody +import org.springframework.web.bind.annotation.RequestMapping +import org.springframework.web.bind.annotation.RequestMethod +import org.springframework.web.bind.annotation.RestController + +@RestController +interface OutboxController { + @RequestMapping("/outbox", "/users/{username}/outbox", method = [RequestMethod.POST, RequestMethod.GET]) + fun outbox(@RequestBody string: String): ResponseEntity { + return ResponseEntity(HttpStatus.ACCEPTED) + } +} diff --git a/src/main/kotlin/dev/usbharu/hideout/controller/OutboxControllerImpl.kt b/src/main/kotlin/dev/usbharu/hideout/controller/OutboxControllerImpl.kt new file mode 100644 index 00000000..04dc227f --- /dev/null +++ b/src/main/kotlin/dev/usbharu/hideout/controller/OutboxControllerImpl.kt @@ -0,0 +1,13 @@ +package dev.usbharu.hideout.controller + +import org.springframework.http.HttpStatus +import org.springframework.http.ResponseEntity +import org.springframework.web.bind.annotation.RequestBody +import org.springframework.web.bind.annotation.RestController + +@RestController +class OutboxControllerImpl : OutboxController { + override fun outbox(@RequestBody string: String): ResponseEntity { + return ResponseEntity(HttpStatus.NOT_IMPLEMENTED) + } +} diff --git a/src/main/kotlin/dev/usbharu/hideout/controller/UserAPController.kt b/src/main/kotlin/dev/usbharu/hideout/controller/UserAPController.kt new file mode 100644 index 00000000..5390fff2 --- /dev/null +++ b/src/main/kotlin/dev/usbharu/hideout/controller/UserAPController.kt @@ -0,0 +1,13 @@ +package dev.usbharu.hideout.controller + +import dev.usbharu.hideout.domain.model.ap.Person +import org.springframework.http.ResponseEntity +import org.springframework.web.bind.annotation.GetMapping +import org.springframework.web.bind.annotation.PathVariable +import org.springframework.web.bind.annotation.RestController + +@RestController +interface UserAPController { + @GetMapping("/users/{username}") + suspend fun userAp(@PathVariable("username") username: String): ResponseEntity +} diff --git a/src/main/kotlin/dev/usbharu/hideout/controller/UserAPControllerImpl.kt b/src/main/kotlin/dev/usbharu/hideout/controller/UserAPControllerImpl.kt new file mode 100644 index 00000000..90fb6155 --- /dev/null +++ b/src/main/kotlin/dev/usbharu/hideout/controller/UserAPControllerImpl.kt @@ -0,0 +1,15 @@ +package dev.usbharu.hideout.controller + +import dev.usbharu.hideout.domain.model.ap.Person +import dev.usbharu.hideout.service.ap.APUserService +import org.springframework.http.HttpStatus +import org.springframework.http.ResponseEntity +import org.springframework.web.bind.annotation.RestController + +@RestController +class UserAPControllerImpl(private val apUserService: APUserService) : UserAPController { + override suspend fun userAp(username: String): ResponseEntity { + val person = apUserService.getPersonByName(username) + return ResponseEntity(person, HttpStatus.OK) + } +} From 4361fb2db51aff07bc10ed7dc8eb375771dbf8f2 Mon Sep 17 00:00:00 2001 From: usbharu <64310155+usbharu@users.noreply.github.com> Date: Tue, 19 Sep 2023 13:05:40 +0900 Subject: [PATCH 09/15] =?UTF-8?q?chore:=20Ktor=E3=82=92=E9=9D=9E=E6=8E=A8?= =?UTF-8?q?=E5=A5=A8=E3=81=AB?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../kotlin/dev/usbharu/hideout/Application.kt | 3 +++ .../dev/usbharu/hideout/config/Config.kt | 7 ++++++ .../usbharu/hideout/plugins/Compression.kt | 1 + .../dev/usbharu/hideout/plugins/HTTP.kt | 1 + .../dev/usbharu/hideout/plugins/Koin.kt | 1 + .../dev/usbharu/hideout/plugins/Monitoring.kt | 1 + .../dev/usbharu/hideout/plugins/Routing.kt | 1 + .../dev/usbharu/hideout/plugins/Security.kt | 1 + .../usbharu/hideout/plugins/Serialization.kt | 1 + .../usbharu/hideout/plugins/StaticRouting.kt | 1 + .../usbharu/hideout/plugins/StatusPages.kt | 1 + .../hideout/routing/RegisterRouting.kt | 1 + .../routing/activitypub/InboxRouting.kt | 1 + .../routing/activitypub/OutboxRouting.kt | 1 + .../routing/activitypub/UserRouting.kt | 2 ++ .../hideout/routing/api/internal/v1/Auth.kt | 1 + .../hideout/routing/api/internal/v1/Posts.kt | 1 + .../hideout/routing/api/internal/v1/Users.kt | 1 + .../routing/wellknown/WebfingerRouting.kt | 1 + src/main/resources/openapi/mastodon.yaml | 22 +++++++++++++++++++ 20 files changed, 50 insertions(+) create mode 100644 src/main/resources/openapi/mastodon.yaml diff --git a/src/main/kotlin/dev/usbharu/hideout/Application.kt b/src/main/kotlin/dev/usbharu/hideout/Application.kt index 6a745122..5b1530a4 100644 --- a/src/main/kotlin/dev/usbharu/hideout/Application.kt +++ b/src/main/kotlin/dev/usbharu/hideout/Application.kt @@ -39,6 +39,7 @@ import org.koin.ksp.generated.module import org.koin.ktor.ext.inject import java.util.concurrent.TimeUnit +@Deprecated("Ktor is deprecated") fun main(args: Array): Unit = io.ktor.server.cio.EngineMain.main(args) val Application.property: Application.(propertyName: String) -> String @@ -52,6 +53,7 @@ val Application.propertyOrNull: Application.(propertyName: String) -> String? } // application.conf references the main function. This annotation prevents the IDE from marking it as unused. +@Deprecated("Ktor is deprecated") @Suppress("unused", "LongMethod") fun Application.parent() { Config.configData = ConfigData( @@ -136,6 +138,7 @@ fun Application.parent() { ) } +@Deprecated("Ktor is deprecated") @Suppress("unused") fun Application.worker() { val kJob = kjob(ExposedKJob) { diff --git a/src/main/kotlin/dev/usbharu/hideout/config/Config.kt b/src/main/kotlin/dev/usbharu/hideout/config/Config.kt index 8acf1113..1623ff25 100644 --- a/src/main/kotlin/dev/usbharu/hideout/config/Config.kt +++ b/src/main/kotlin/dev/usbharu/hideout/config/Config.kt @@ -3,10 +3,12 @@ package dev.usbharu.hideout.config import com.fasterxml.jackson.databind.ObjectMapper import com.fasterxml.jackson.module.kotlin.jacksonObjectMapper +@Deprecated("Config is deprecated") object Config { var configData: ConfigData = ConfigData() } +@Deprecated("Config is deprecated") data class ConfigData( val url: String = "", val domain: String = url.substringAfter("://").substringBeforeLast(":"), @@ -14,12 +16,14 @@ data class ConfigData( val characterLimit: CharacterLimit = CharacterLimit() ) +@Deprecated("Config is deprecated") data class CharacterLimit( val general: General = General.of(), val post: Post = Post(), val account: Account = Account(), val instance: Instance = Instance() ) { + @Deprecated("Config is deprecated") data class General private constructor( val url: Int, val domain: Int, @@ -39,17 +43,20 @@ data class CharacterLimit( } } + @Deprecated("Config is deprecated") data class Post( val text: Int = 3000, val overview: Int = 3000 ) + @Deprecated("Config is deprecated") data class Account( val id: Int = 300, val name: Int = 300, val description: Int = 10000 ) + @Deprecated("Config is deprecated") data class Instance( val name: Int = 600, val description: Int = 10000 diff --git a/src/main/kotlin/dev/usbharu/hideout/plugins/Compression.kt b/src/main/kotlin/dev/usbharu/hideout/plugins/Compression.kt index e13fa4c9..d1387d28 100644 --- a/src/main/kotlin/dev/usbharu/hideout/plugins/Compression.kt +++ b/src/main/kotlin/dev/usbharu/hideout/plugins/Compression.kt @@ -4,6 +4,7 @@ import io.ktor.http.* import io.ktor.server.application.* import io.ktor.server.plugins.compression.* +@Deprecated("Ktor is deprecated") fun Application.configureCompression() { install(Compression) { gzip { diff --git a/src/main/kotlin/dev/usbharu/hideout/plugins/HTTP.kt b/src/main/kotlin/dev/usbharu/hideout/plugins/HTTP.kt index 98e5e259..44f88bbd 100644 --- a/src/main/kotlin/dev/usbharu/hideout/plugins/HTTP.kt +++ b/src/main/kotlin/dev/usbharu/hideout/plugins/HTTP.kt @@ -4,6 +4,7 @@ import io.ktor.server.application.* import io.ktor.server.plugins.defaultheaders.* import io.ktor.server.plugins.forwardedheaders.* +@Deprecated("Ktor is deprecated") fun Application.configureHTTP() { // install(CORS) { // allowMethod(HttpMethod.Options) diff --git a/src/main/kotlin/dev/usbharu/hideout/plugins/Koin.kt b/src/main/kotlin/dev/usbharu/hideout/plugins/Koin.kt index e7a9e249..a7b1ed16 100644 --- a/src/main/kotlin/dev/usbharu/hideout/plugins/Koin.kt +++ b/src/main/kotlin/dev/usbharu/hideout/plugins/Koin.kt @@ -5,6 +5,7 @@ import org.koin.core.module.Module import org.koin.ktor.plugin.Koin import org.koin.logger.slf4jLogger +@Deprecated("Ktor is deprecated") fun Application.configureKoin(vararg module: Module) { install(Koin) { slf4jLogger() diff --git a/src/main/kotlin/dev/usbharu/hideout/plugins/Monitoring.kt b/src/main/kotlin/dev/usbharu/hideout/plugins/Monitoring.kt index 2f33df7a..a2345312 100644 --- a/src/main/kotlin/dev/usbharu/hideout/plugins/Monitoring.kt +++ b/src/main/kotlin/dev/usbharu/hideout/plugins/Monitoring.kt @@ -4,6 +4,7 @@ import io.ktor.server.application.* import io.ktor.server.plugins.callloging.* import org.slf4j.event.Level +@Deprecated("Ktor is deprecated") fun Application.configureMonitoring() { install(CallLogging) { level = Level.INFO diff --git a/src/main/kotlin/dev/usbharu/hideout/plugins/Routing.kt b/src/main/kotlin/dev/usbharu/hideout/plugins/Routing.kt index 178127b5..7a11e3be 100644 --- a/src/main/kotlin/dev/usbharu/hideout/plugins/Routing.kt +++ b/src/main/kotlin/dev/usbharu/hideout/plugins/Routing.kt @@ -22,6 +22,7 @@ import io.ktor.server.application.* import io.ktor.server.plugins.autohead.* import io.ktor.server.routing.* +@Deprecated("Ktor is deprecated") @Suppress("LongParameterList") fun Application.configureRouting( httpSignatureVerifyService: HttpSignatureVerifyService, diff --git a/src/main/kotlin/dev/usbharu/hideout/plugins/Security.kt b/src/main/kotlin/dev/usbharu/hideout/plugins/Security.kt index a4d7d34d..104c5844 100644 --- a/src/main/kotlin/dev/usbharu/hideout/plugins/Security.kt +++ b/src/main/kotlin/dev/usbharu/hideout/plugins/Security.kt @@ -13,6 +13,7 @@ import io.ktor.server.routing.* const val TOKEN_AUTH = "jwt-auth" +@Deprecated("Ktor is deprecated") @Suppress("MagicNumber") fun Application.configureSecurity( jwkProvider: JwkProvider, diff --git a/src/main/kotlin/dev/usbharu/hideout/plugins/Serialization.kt b/src/main/kotlin/dev/usbharu/hideout/plugins/Serialization.kt index 09edfe72..1e81e2e7 100644 --- a/src/main/kotlin/dev/usbharu/hideout/plugins/Serialization.kt +++ b/src/main/kotlin/dev/usbharu/hideout/plugins/Serialization.kt @@ -8,6 +8,7 @@ import io.ktor.serialization.jackson.* import io.ktor.server.application.* import io.ktor.server.plugins.contentnegotiation.* +@Deprecated("Ktor is deprecated") fun Application.configureSerialization() { install(ContentNegotiation) { jackson { diff --git a/src/main/kotlin/dev/usbharu/hideout/plugins/StaticRouting.kt b/src/main/kotlin/dev/usbharu/hideout/plugins/StaticRouting.kt index 58888b99..c4cc37d6 100644 --- a/src/main/kotlin/dev/usbharu/hideout/plugins/StaticRouting.kt +++ b/src/main/kotlin/dev/usbharu/hideout/plugins/StaticRouting.kt @@ -6,6 +6,7 @@ import io.ktor.server.http.content.* import io.ktor.server.response.* import io.ktor.server.routing.* +@Deprecated("Ktor is deprecated") fun Application.configureStaticRouting() { routing { get("/") { diff --git a/src/main/kotlin/dev/usbharu/hideout/plugins/StatusPages.kt b/src/main/kotlin/dev/usbharu/hideout/plugins/StatusPages.kt index e0305692..9a9ea5ac 100644 --- a/src/main/kotlin/dev/usbharu/hideout/plugins/StatusPages.kt +++ b/src/main/kotlin/dev/usbharu/hideout/plugins/StatusPages.kt @@ -6,6 +6,7 @@ import io.ktor.server.application.* import io.ktor.server.plugins.statuspages.* import io.ktor.server.response.* +@Deprecated("Ktor is deprecated") fun Application.configureStatusPages() { install(StatusPages) { exception { call, cause -> diff --git a/src/main/kotlin/dev/usbharu/hideout/routing/RegisterRouting.kt b/src/main/kotlin/dev/usbharu/hideout/routing/RegisterRouting.kt index 8628f340..232ee918 100644 --- a/src/main/kotlin/dev/usbharu/hideout/routing/RegisterRouting.kt +++ b/src/main/kotlin/dev/usbharu/hideout/routing/RegisterRouting.kt @@ -8,6 +8,7 @@ import io.ktor.server.request.* import io.ktor.server.response.* import io.ktor.server.routing.* +@Deprecated("Ktor is deprecated") fun Application.register(userApiService: UserApiService) { routing { get("/register") { diff --git a/src/main/kotlin/dev/usbharu/hideout/routing/activitypub/InboxRouting.kt b/src/main/kotlin/dev/usbharu/hideout/routing/activitypub/InboxRouting.kt index dbdcd666..e1204f39 100644 --- a/src/main/kotlin/dev/usbharu/hideout/routing/activitypub/InboxRouting.kt +++ b/src/main/kotlin/dev/usbharu/hideout/routing/activitypub/InboxRouting.kt @@ -11,6 +11,7 @@ import io.ktor.server.request.* import io.ktor.server.response.* import io.ktor.server.routing.* +@Deprecated("Ktor is deprecated") fun Routing.inbox( httpSignatureVerifyService: HttpSignatureVerifyService, apService: dev.usbharu.hideout.service.ap.APService diff --git a/src/main/kotlin/dev/usbharu/hideout/routing/activitypub/OutboxRouting.kt b/src/main/kotlin/dev/usbharu/hideout/routing/activitypub/OutboxRouting.kt index 3ad07137..9f6c2689 100644 --- a/src/main/kotlin/dev/usbharu/hideout/routing/activitypub/OutboxRouting.kt +++ b/src/main/kotlin/dev/usbharu/hideout/routing/activitypub/OutboxRouting.kt @@ -5,6 +5,7 @@ import io.ktor.server.application.* import io.ktor.server.response.* import io.ktor.server.routing.* +@Deprecated("Ktor is deprecated") fun Routing.outbox() { route("/outbox") { get { 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 0d0dbea5..39d7a299 100644 --- a/src/main/kotlin/dev/usbharu/hideout/routing/activitypub/UserRouting.kt +++ b/src/main/kotlin/dev/usbharu/hideout/routing/activitypub/UserRouting.kt @@ -15,6 +15,7 @@ import io.ktor.server.request.* import io.ktor.server.response.* import io.ktor.server.routing.* +@Deprecated("Ktor is deprecated") fun Routing.usersAP( apUserService: APUserService, userQueryService: UserQueryService, @@ -50,6 +51,7 @@ fun Routing.usersAP( } } +@Deprecated("Ktor is deprecated") class ContentTypeRouteSelector(private vararg val contentType: ContentType) : RouteSelector() { override fun evaluate(context: RoutingResolveContext, segmentIndex: Int): RouteSelectorEvaluation { context.call.application.log.debug("Accept: ${context.call.request.accept()}") diff --git a/src/main/kotlin/dev/usbharu/hideout/routing/api/internal/v1/Auth.kt b/src/main/kotlin/dev/usbharu/hideout/routing/api/internal/v1/Auth.kt index 610d39b4..4a70ab5b 100644 --- a/src/main/kotlin/dev/usbharu/hideout/routing/api/internal/v1/Auth.kt +++ b/src/main/kotlin/dev/usbharu/hideout/routing/api/internal/v1/Auth.kt @@ -11,6 +11,7 @@ import io.ktor.server.request.* import io.ktor.server.response.* import io.ktor.server.routing.* +@Deprecated("Ktor is deprecated") fun Route.auth(userAuthApiService: UserAuthApiService) { post("/login") { val loginUser = call.receive() diff --git a/src/main/kotlin/dev/usbharu/hideout/routing/api/internal/v1/Posts.kt b/src/main/kotlin/dev/usbharu/hideout/routing/api/internal/v1/Posts.kt index a3c3cd23..3137bc6c 100644 --- a/src/main/kotlin/dev/usbharu/hideout/routing/api/internal/v1/Posts.kt +++ b/src/main/kotlin/dev/usbharu/hideout/routing/api/internal/v1/Posts.kt @@ -14,6 +14,7 @@ import io.ktor.server.request.* import io.ktor.server.response.* import io.ktor.server.routing.* +@Deprecated("Ktor is deprecated") @Suppress("LongMethod") fun Route.posts(postApiService: PostApiService) { route("/posts") { diff --git a/src/main/kotlin/dev/usbharu/hideout/routing/api/internal/v1/Users.kt b/src/main/kotlin/dev/usbharu/hideout/routing/api/internal/v1/Users.kt index dd7b64f9..96f4f198 100644 --- a/src/main/kotlin/dev/usbharu/hideout/routing/api/internal/v1/Users.kt +++ b/src/main/kotlin/dev/usbharu/hideout/routing/api/internal/v1/Users.kt @@ -16,6 +16,7 @@ import io.ktor.server.request.* import io.ktor.server.response.* import io.ktor.server.routing.* +@Deprecated("Ktor is deprecated") @Suppress("LongMethod", "CognitiveComplexMethod") fun Route.users(userService: UserService, userApiService: UserApiService) { route("/users") { diff --git a/src/main/kotlin/dev/usbharu/hideout/routing/wellknown/WebfingerRouting.kt b/src/main/kotlin/dev/usbharu/hideout/routing/wellknown/WebfingerRouting.kt index 9642afd0..efa782c9 100644 --- a/src/main/kotlin/dev/usbharu/hideout/routing/wellknown/WebfingerRouting.kt +++ b/src/main/kotlin/dev/usbharu/hideout/routing/wellknown/WebfingerRouting.kt @@ -11,6 +11,7 @@ import io.ktor.server.application.* import io.ktor.server.response.* import io.ktor.server.routing.* +@Deprecated("Ktor is deprecated") fun Routing.webfinger(webFingerApiService: WebFingerApiService) { route("/.well-known/webfinger") { get { diff --git a/src/main/resources/openapi/mastodon.yaml b/src/main/resources/openapi/mastodon.yaml new file mode 100644 index 00000000..dbcf6195 --- /dev/null +++ b/src/main/resources/openapi/mastodon.yaml @@ -0,0 +1,22 @@ +openapi: 3.0.3 +info: + title: Hideout Mastodon Compatible API + description: Hideout Mastodon Compatible API + version: 1.0.0 +servers: + - url: 'https://test-hideout.usbharu.dev' +paths: + +components: + schemas: + Account: + type: object + properties: + id: + type: string + username: + type: string + acct: + type: string + url: + type: string From e05db6dd9191c0a7c8949eb32d7f533759e2e7bd Mon Sep 17 00:00:00 2001 From: usbharu <64310155+usbharu@users.noreply.github.com> Date: Tue, 19 Sep 2023 15:46:51 +0900 Subject: [PATCH 10/15] =?UTF-8?q?feat:=20Security=E3=81=AE=E8=A8=AD?= =?UTF-8?q?=E5=AE=9A=E3=82=92=E5=A4=89=E6=9B=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- build.gradle.kts | 2 ++ .../dev/usbharu/hideout/config/SecurityConfig.kt | 15 +++++++++++++++ .../hideout/controller/InboxControllerImpl.kt | 3 ++- src/main/resources/logback.xml | 2 +- 4 files changed, 20 insertions(+), 2 deletions(-) diff --git a/build.gradle.kts b/build.gradle.kts index e3482bc4..5b6bc454 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -147,6 +147,8 @@ dependencies { implementation("org.springframework.data:spring-data-commons") implementation("org.springframework.boot:spring-boot-starter-jdbc") implementation("org.springframework.boot:spring-boot-starter-data-jdbc") + implementation("org.springframework.boot:spring-boot-starter-webflux") + implementation("org.jetbrains.kotlinx:kotlinx-coroutines-reactor") implementation("io.ktor:ktor-client-logging-jvm:$ktor_version") implementation("io.ktor:ktor-server-host-common-jvm:$ktor_version") diff --git a/src/main/kotlin/dev/usbharu/hideout/config/SecurityConfig.kt b/src/main/kotlin/dev/usbharu/hideout/config/SecurityConfig.kt index 92fd756f..3217acea 100644 --- a/src/main/kotlin/dev/usbharu/hideout/config/SecurityConfig.kt +++ b/src/main/kotlin/dev/usbharu/hideout/config/SecurityConfig.kt @@ -44,6 +44,9 @@ class SecurityConfig { .oauth2ResourceServer { it.jwt(Customizer.withDefaults()) } + .csrf { + it.disable() + } return http.build() } @@ -52,10 +55,22 @@ class SecurityConfig { @Order(2) fun defaultSecurityFilterChain(http: HttpSecurity): SecurityFilterChain { http + .authorizeHttpRequests { + it.requestMatchers( + "/inbox", + "/users/*/inbox", + "/outbox", + "/users/*/outbox" + ) + .permitAll() + } .authorizeHttpRequests { it.anyRequest().authenticated() } .formLogin(Customizer.withDefaults()) + .csrf { + it.disable() + } return http.build() } diff --git a/src/main/kotlin/dev/usbharu/hideout/controller/InboxControllerImpl.kt b/src/main/kotlin/dev/usbharu/hideout/controller/InboxControllerImpl.kt index 002dee31..fb47a3f0 100644 --- a/src/main/kotlin/dev/usbharu/hideout/controller/InboxControllerImpl.kt +++ b/src/main/kotlin/dev/usbharu/hideout/controller/InboxControllerImpl.kt @@ -3,11 +3,12 @@ package dev.usbharu.hideout.controller import dev.usbharu.hideout.service.ap.APService import org.springframework.http.HttpStatus import org.springframework.http.ResponseEntity +import org.springframework.web.bind.annotation.RequestBody import org.springframework.web.bind.annotation.RestController @RestController class InboxControllerImpl(private val apService: APService) : InboxController { - override suspend fun inbox(string: String): ResponseEntity { + override suspend fun inbox(@RequestBody string: String): ResponseEntity { val parseActivity = apService.parseActivity(string) apService.processActivity(string, parseActivity) return ResponseEntity(HttpStatus.ACCEPTED) diff --git a/src/main/resources/logback.xml b/src/main/resources/logback.xml index 9129b1b2..4593b633 100644 --- a/src/main/resources/logback.xml +++ b/src/main/resources/logback.xml @@ -4,7 +4,7 @@ %d{YYYY-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n - + From 8ab55cb248bb40c652a24a2027fe0d980dd5ad47 Mon Sep 17 00:00:00 2001 From: usbharu <64310155+usbharu@users.noreply.github.com> Date: Tue, 19 Sep 2023 16:21:35 +0900 Subject: [PATCH 11/15] =?UTF-8?q?style:=20=E3=82=B9=E3=82=BF=E3=82=A4?= =?UTF-8?q?=E3=83=AB=E3=82=92=E4=BF=AE=E6=AD=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- build.gradle.kts | 18 ++++++++++++++---- .../dev/usbharu/hideout/SpringApplication.kt | 1 - .../usbharu/hideout/config/DatabaseConfig.kt | 3 --- .../usbharu/hideout/config/SecurityConfig.kt | 5 ++--- .../hideout/config/SpringTransactionConfig.kt | 1 - .../hideout/controller/DefaultApiImpl.kt | 1 + .../RegisteredClientRepositoryImpl.kt | 3 --- .../hideout/service/ap/APCreateService.kt | 1 - .../hideout/service/ap/APUndoService.kt | 1 - .../auth/ExposedOAuth2AuthorizationService.kt | 14 ++++++++------ .../service/auth/UserDetailsServiceImpl.kt | 4 +++- .../service/auth/UsernamePasswordAuthFilter.kt | 2 -- .../dev/usbharu/hideout/util/JsonUtil.kt | 1 - 13 files changed, 28 insertions(+), 27 deletions(-) diff --git a/build.gradle.kts b/build.gradle.kts index 5b6bc454..18442d5e 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -13,7 +13,7 @@ plugins { kotlin("jvm") version "1.8.21" id("io.ktor.plugin") version "2.3.0" id("org.graalvm.buildtools.native") version "0.9.21" - id("io.gitlab.arturbosch.detekt") version "1.22.0" + id("io.gitlab.arturbosch.detekt") version "1.23.1" id("com.google.devtools.ksp") version "1.8.21-1.0.11" id("org.springframework.boot") version "3.1.2" kotlin("plugin.spring") version "1.8.21" @@ -65,7 +65,7 @@ tasks.create("openApiGenerateServer", GenerateTask::class) { generatorName.set("kotlin-spring") inputSpec.set("$rootDir/src/main/resources/openapi/api.yaml") outputDir.set("$buildDir/generated/sources/openapi") - apiPackage.set("dev.usbharu.hideout.controller") + apiPackage.set("dev.usbharu.hideout.controller.generated") modelPackage.set("dev.usbharu.hideout.domain.model.generated") configOptions.put("interfaceOnly", "true") configOptions.put("useSpringBoot3", "true") @@ -149,6 +149,8 @@ dependencies { implementation("org.springframework.boot:spring-boot-starter-data-jdbc") implementation("org.springframework.boot:spring-boot-starter-webflux") implementation("org.jetbrains.kotlinx:kotlinx-coroutines-reactor") + testImplementation("org.springframework.boot:spring-boot-test-autoconfigure") + testImplementation("org.springframework.boot:spring-boot-starter-test") implementation("io.ktor:ktor-client-logging-jvm:$ktor_version") implementation("io.ktor:ktor-server-host-common-jvm:$ktor_version") @@ -226,9 +228,17 @@ detekt { } tasks.withType().configureEach { - exclude("**/org/koin/ksp/generated/**") + exclude("**/org/koin/ksp/generated/**", "**/generated/**") } tasks.withType().configureEach { - exclude("**/org/koin/ksp/generated/**") + exclude("**/org/koin/ksp/generated/**", "**/generated/**") +} + +configurations.matching { it.name == "detekt" }.all { + resolutionStrategy.eachDependency { + if (requested.group == "org.jetbrains.kotlin") { + useVersion("1.9.0") + } + } } diff --git a/src/main/kotlin/dev/usbharu/hideout/SpringApplication.kt b/src/main/kotlin/dev/usbharu/hideout/SpringApplication.kt index 8385ee79..0cc32e48 100644 --- a/src/main/kotlin/dev/usbharu/hideout/SpringApplication.kt +++ b/src/main/kotlin/dev/usbharu/hideout/SpringApplication.kt @@ -4,7 +4,6 @@ import org.springframework.boot.autoconfigure.SpringBootApplication import org.springframework.boot.context.properties.ConfigurationPropertiesScan import org.springframework.boot.runApplication - @SpringBootApplication @ConfigurationPropertiesScan class SpringApplication diff --git a/src/main/kotlin/dev/usbharu/hideout/config/DatabaseConfig.kt b/src/main/kotlin/dev/usbharu/hideout/config/DatabaseConfig.kt index dfe744ac..03064946 100644 --- a/src/main/kotlin/dev/usbharu/hideout/config/DatabaseConfig.kt +++ b/src/main/kotlin/dev/usbharu/hideout/config/DatabaseConfig.kt @@ -6,7 +6,6 @@ import org.springframework.boot.context.properties.ConfigurationProperties import org.springframework.context.annotation.Bean import org.springframework.context.annotation.Configuration - @Configuration class DatabaseConfig { @@ -22,10 +21,8 @@ class DatabaseConfig { password = dbConfig.password ) } - } - @ConfigurationProperties("hideout.database") data class DatabaseConnectConfig( val url: String, diff --git a/src/main/kotlin/dev/usbharu/hideout/config/SecurityConfig.kt b/src/main/kotlin/dev/usbharu/hideout/config/SecurityConfig.kt index 3217acea..75505da3 100644 --- a/src/main/kotlin/dev/usbharu/hideout/config/SecurityConfig.kt +++ b/src/main/kotlin/dev/usbharu/hideout/config/SecurityConfig.kt @@ -38,7 +38,8 @@ class SecurityConfig { http .exceptionHandling { it.defaultAuthenticationEntryPointFor( - LoginUrlAuthenticationEntryPoint("/login"), MediaTypeRequestMatcher(MediaType.TEXT_HTML) + LoginUrlAuthenticationEntryPoint("/login"), + MediaTypeRequestMatcher(MediaType.TEXT_HTML) ) } .oauth2ResourceServer { @@ -50,7 +51,6 @@ class SecurityConfig { return http.build() } - @Bean @Order(2) fun defaultSecurityFilterChain(http: HttpSecurity): SecurityFilterChain { @@ -121,7 +121,6 @@ class SecurityConfig { } } - @ConfigurationProperties("hideout.security.jwt") @ConditionalOnProperty(name = ["hideout.security.jwt.generate"], havingValue = "") data class JwkConfig( diff --git a/src/main/kotlin/dev/usbharu/hideout/config/SpringTransactionConfig.kt b/src/main/kotlin/dev/usbharu/hideout/config/SpringTransactionConfig.kt index a9d76420..92caf4f1 100644 --- a/src/main/kotlin/dev/usbharu/hideout/config/SpringTransactionConfig.kt +++ b/src/main/kotlin/dev/usbharu/hideout/config/SpringTransactionConfig.kt @@ -8,7 +8,6 @@ import org.springframework.transaction.annotation.EnableTransactionManagement import org.springframework.transaction.annotation.TransactionManagementConfigurer import javax.sql.DataSource - @Configuration @EnableTransactionManagement class SpringTransactionConfig(val datasource: DataSource) : TransactionManagementConfigurer { diff --git a/src/main/kotlin/dev/usbharu/hideout/controller/DefaultApiImpl.kt b/src/main/kotlin/dev/usbharu/hideout/controller/DefaultApiImpl.kt index 32e21fb2..b6253251 100644 --- a/src/main/kotlin/dev/usbharu/hideout/controller/DefaultApiImpl.kt +++ b/src/main/kotlin/dev/usbharu/hideout/controller/DefaultApiImpl.kt @@ -1,5 +1,6 @@ package dev.usbharu.hideout.controller +import dev.usbharu.hideout.controller.generated.DefaultApi import dev.usbharu.hideout.domain.model.hideout.dto.JwtToken import dev.usbharu.hideout.service.api.UserAuthApiService import org.springframework.http.HttpStatus diff --git a/src/main/kotlin/dev/usbharu/hideout/repository/RegisteredClientRepositoryImpl.kt b/src/main/kotlin/dev/usbharu/hideout/repository/RegisteredClientRepositoryImpl.kt index 7a825c0c..7199a949 100644 --- a/src/main/kotlin/dev/usbharu/hideout/repository/RegisteredClientRepositoryImpl.kt +++ b/src/main/kotlin/dev/usbharu/hideout/repository/RegisteredClientRepositoryImpl.kt @@ -87,7 +87,6 @@ class RegisteredClientRepositoryImpl(private val database: Database) : Registere } } - // org/springframework/security/oauth2/server/authorization/client/oauth2-registered-client-schema.sql object RegisteredClient : Table("registered_client") { val id = varchar("id", 100) @@ -108,7 +107,6 @@ object RegisteredClient : Table("registered_client") { } fun ResultRow.toRegisteredClient(): SpringRegisteredClient { - fun resolveClientAuthenticationMethods(string: String): ClientAuthenticationMethod { return when (string) { ClientAuthenticationMethod.CLIENT_SECRET_BASIC.value -> ClientAuthenticationMethod.CLIENT_SECRET_BASIC @@ -160,7 +158,6 @@ fun ResultRow.toRegisteredClient(): SpringRegisteredClient { .scopes { it.addAll(clientScopes) } .clientSettings(ClientSettings.withSettings(JsonUtil.jsonToMap(this[clientSettings])).build()) - val tokenSettingsMap = JsonUtil.jsonToMap(this[tokenSettings]) val withSettings = TokenSettings.withSettings(tokenSettingsMap) if (tokenSettingsMap.containsKey(ConfigurationSettingNames.Token.ACCESS_TOKEN_FORMAT)) { diff --git a/src/main/kotlin/dev/usbharu/hideout/service/ap/APCreateService.kt b/src/main/kotlin/dev/usbharu/hideout/service/ap/APCreateService.kt index bc684bb4..51ea4eee 100644 --- a/src/main/kotlin/dev/usbharu/hideout/service/ap/APCreateService.kt +++ b/src/main/kotlin/dev/usbharu/hideout/service/ap/APCreateService.kt @@ -10,7 +10,6 @@ import io.ktor.http.* import org.koin.core.annotation.Single import org.springframework.stereotype.Service - @Service interface APCreateService { suspend fun receiveCreate(create: Create): ActivityPubResponse diff --git a/src/main/kotlin/dev/usbharu/hideout/service/ap/APUndoService.kt b/src/main/kotlin/dev/usbharu/hideout/service/ap/APUndoService.kt index 6ad4f67e..03bb22f4 100644 --- a/src/main/kotlin/dev/usbharu/hideout/service/ap/APUndoService.kt +++ b/src/main/kotlin/dev/usbharu/hideout/service/ap/APUndoService.kt @@ -11,7 +11,6 @@ import io.ktor.http.* import org.koin.core.annotation.Single import org.springframework.stereotype.Service - @Service interface APUndoService { suspend fun receiveUndo(undo: Undo): ActivityPubResponse diff --git a/src/main/kotlin/dev/usbharu/hideout/service/auth/ExposedOAuth2AuthorizationService.kt b/src/main/kotlin/dev/usbharu/hideout/service/auth/ExposedOAuth2AuthorizationService.kt index 8abea597..dac35033 100644 --- a/src/main/kotlin/dev/usbharu/hideout/service/auth/ExposedOAuth2AuthorizationService.kt +++ b/src/main/kotlin/dev/usbharu/hideout/service/auth/ExposedOAuth2AuthorizationService.kt @@ -105,7 +105,6 @@ class ExposedOAuth2AuthorizationService(private val registeredClientRepository: it[deviceCodeMetadata] = deviceCode?.metadata?.let { it1 -> JsonUtil.mapToJson(it1) } } } - } override fun remove(authorization: OAuth2Authorization?) { @@ -176,7 +175,6 @@ class ExposedOAuth2AuthorizationService(private val registeredClientRepository: } fun ResultRow.toAuthorization(): OAuth2Authorization { - val registeredClientId = this[Authorization.registeredClientId] val registeredClient = registeredClientRepository.findById(registeredClientId) @@ -186,7 +184,7 @@ class ExposedOAuth2AuthorizationService(private val registeredClientRepository: val principalName = this[Authorization.principalName] val authorizationGrantType = this[Authorization.authorizationGrantType] val authorizedScopes = this[Authorization.authorizedScopes]?.split(",").orEmpty().toSet() - val attributes = this[Authorization.attributes]?.let { JsonUtil.jsonToMap(it) } ?: emptyMap() + val attributes = this[Authorization.attributes]?.let { JsonUtil.jsonToMap(it) }.orEmpty() builder.id(id).principalName(principalName) .authorizationGrantType(AuthorizationGrantType(authorizationGrantType)).authorizedScopes(authorizedScopes) @@ -218,7 +216,7 @@ class ExposedOAuth2AuthorizationService(private val registeredClientRepository: val accessTokenIssuedAt = this[Authorization.accessTokenIssuedAt] val accessTokenExpiresAt = this[Authorization.accessTokenExpiresAt] val accessTokenMetadata = - this[Authorization.accessTokenMetadata]?.let { JsonUtil.jsonToMap(it) } ?: emptyMap() + this[Authorization.accessTokenMetadata]?.let { JsonUtil.jsonToMap(it) }.orEmpty() val accessTokenType = if (this[Authorization.accessTokenType].equals(OAuth2AccessToken.TokenType.BEARER.value, true)) { OAuth2AccessToken.TokenType.BEARER @@ -229,7 +227,11 @@ class ExposedOAuth2AuthorizationService(private val registeredClientRepository: val accessTokenScope = this[Authorization.accessTokenScopes]?.split(",").orEmpty().toSet() val oAuth2AccessToken = OAuth2AccessToken( - accessTokenType, accessTokenValue, accessTokenIssuedAt, accessTokenExpiresAt, accessTokenScope + accessTokenType, + accessTokenValue, + accessTokenIssuedAt, + accessTokenExpiresAt, + accessTokenScope ) builder.token(oAuth2AccessToken) { it.putAll(accessTokenMetadata) } @@ -240,7 +242,7 @@ class ExposedOAuth2AuthorizationService(private val registeredClientRepository: val oidcTokenIssuedAt = this[Authorization.oidcIdTokenIssuedAt] val oidcTokenExpiresAt = this[Authorization.oidcIdTokenExpiresAt] val oidcTokenMetadata = - this[Authorization.oidcIdTokenMetadata]?.let { JsonUtil.jsonToMap(it) } ?: emptyMap() + this[Authorization.oidcIdTokenMetadata]?.let { JsonUtil.jsonToMap(it) }.or val oidcIdToken = OidcIdToken( oidcIdTokenValue, diff --git a/src/main/kotlin/dev/usbharu/hideout/service/auth/UserDetailsServiceImpl.kt b/src/main/kotlin/dev/usbharu/hideout/service/auth/UserDetailsServiceImpl.kt index a889e79a..76bb81a9 100644 --- a/src/main/kotlin/dev/usbharu/hideout/service/auth/UserDetailsServiceImpl.kt +++ b/src/main/kotlin/dev/usbharu/hideout/service/auth/UserDetailsServiceImpl.kt @@ -19,7 +19,9 @@ class UserDetailsServiceImpl(private val userQueryService: UserQueryService, pri transaction.transaction { val findById = userQueryService.findByNameAndDomain(username, "") User( - findById.name, findById.password, listOf() + findById.name, + findById.password, + listOf() ) } } diff --git a/src/main/kotlin/dev/usbharu/hideout/service/auth/UsernamePasswordAuthFilter.kt b/src/main/kotlin/dev/usbharu/hideout/service/auth/UsernamePasswordAuthFilter.kt index 5655e8b4..208f4c6a 100644 --- a/src/main/kotlin/dev/usbharu/hideout/service/auth/UsernamePasswordAuthFilter.kt +++ b/src/main/kotlin/dev/usbharu/hideout/service/auth/UsernamePasswordAuthFilter.kt @@ -4,14 +4,12 @@ import org.springframework.security.authentication.AuthenticationManager import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter import org.springframework.security.web.util.matcher.AntPathRequestMatcher - class UsernamePasswordAuthFilter(jwtService: JwtService, authenticationManager: AuthenticationManager?) : UsernamePasswordAuthenticationFilter(authenticationManager) { init { setRequiresAuthenticationRequestMatcher(AntPathRequestMatcher("/api/internal/v1/login", "POST")) this.setAuthenticationSuccessHandler { request, response, authentication -> - } } } diff --git a/src/main/kotlin/dev/usbharu/hideout/util/JsonUtil.kt b/src/main/kotlin/dev/usbharu/hideout/util/JsonUtil.kt index fcd97a9f..25d282bc 100644 --- a/src/main/kotlin/dev/usbharu/hideout/util/JsonUtil.kt +++ b/src/main/kotlin/dev/usbharu/hideout/util/JsonUtil.kt @@ -12,5 +12,4 @@ object JsonUtil { fun jsonToMap(json: String, objectMapper: ObjectMapper = this.objectMapper): Map = objectMapper.readValue(json) - } From ec1285e6fb6483e4d237f6bc3aa8427d12c92940 Mon Sep 17 00:00:00 2001 From: usbharu <64310155+usbharu@users.noreply.github.com> Date: Tue, 19 Sep 2023 16:27:45 +0900 Subject: [PATCH 12/15] =?UTF-8?q?style:=20=E3=82=B9=E3=82=BF=E3=82=A4?= =?UTF-8?q?=E3=83=AB=E3=82=92=E4=BF=AE=E6=AD=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../ExposedOAuth2AuthorizationConsentService.kt | 13 ++++++++++--- .../auth/ExposedOAuth2AuthorizationService.kt | 12 ++++++------ .../service/auth/UserDetailsServiceImpl.kt | 2 +- .../service/auth/UsernamePasswordAuthFilter.kt | 15 --------------- 4 files changed, 17 insertions(+), 25 deletions(-) delete mode 100644 src/main/kotlin/dev/usbharu/hideout/service/auth/UsernamePasswordAuthFilter.kt diff --git a/src/main/kotlin/dev/usbharu/hideout/service/auth/ExposedOAuth2AuthorizationConsentService.kt b/src/main/kotlin/dev/usbharu/hideout/service/auth/ExposedOAuth2AuthorizationConsentService.kt index 45958141..aff981c3 100644 --- a/src/main/kotlin/dev/usbharu/hideout/service/auth/ExposedOAuth2AuthorizationConsentService.kt +++ b/src/main/kotlin/dev/usbharu/hideout/service/auth/ExposedOAuth2AuthorizationConsentService.kt @@ -14,7 +14,11 @@ class ExposedOAuth2AuthorizationConsentService(private val registeredClientRepos override fun save(authorizationConsent: AuthorizationConsent?) { requireNotNull(authorizationConsent) val singleOrNull = - OAuth2AuthorizationConsent.select { OAuth2AuthorizationConsent.registeredClientId eq authorizationConsent.registeredClientId and (OAuth2AuthorizationConsent.principalName eq authorizationConsent.principalName) } + OAuth2AuthorizationConsent.select { + OAuth2AuthorizationConsent.registeredClientId + .eq(authorizationConsent.registeredClientId) + .and(OAuth2AuthorizationConsent.principalName.eq(authorizationConsent.principalName)) + } .singleOrNull() if (singleOrNull == null) { OAuth2AuthorizationConsent.insert { @@ -38,13 +42,16 @@ class ExposedOAuth2AuthorizationConsentService(private val registeredClientRepos requireNotNull(registeredClientId) requireNotNull(principalName) - return OAuth2AuthorizationConsent.select { OAuth2AuthorizationConsent.registeredClientId eq registeredClientId and (OAuth2AuthorizationConsent.principalName eq principalName) } + return OAuth2AuthorizationConsent.select { + (OAuth2AuthorizationConsent.registeredClientId eq registeredClientId) + .and(OAuth2AuthorizationConsent.principalName eq principalName) + } .singleOrNull()?.toAuthorizationConsent() } fun ResultRow.toAuthorizationConsent(): AuthorizationConsent { val registeredClientId = this[OAuth2AuthorizationConsent.registeredClientId] - val registeredClient = registeredClientRepository.findById(registeredClientId) + registeredClientRepository.findById(registeredClientId) val principalName = this[OAuth2AuthorizationConsent.principalName] val builder = AuthorizationConsent.withId(registeredClientId, principalName) diff --git a/src/main/kotlin/dev/usbharu/hideout/service/auth/ExposedOAuth2AuthorizationService.kt b/src/main/kotlin/dev/usbharu/hideout/service/auth/ExposedOAuth2AuthorizationService.kt index dac35033..9e25e117 100644 --- a/src/main/kotlin/dev/usbharu/hideout/service/auth/ExposedOAuth2AuthorizationService.kt +++ b/src/main/kotlin/dev/usbharu/hideout/service/auth/ExposedOAuth2AuthorizationService.kt @@ -45,7 +45,7 @@ class ExposedOAuth2AuthorizationService(private val registeredClientRepository: it[accessTokenExpiresAt] = accessToken?.token?.expiresAt it[accessTokenMetadata] = accessToken?.metadata?.let { it1 -> JsonUtil.mapToJson(it1) } it[accessTokenType] = accessToken?.token?.tokenType?.value - it[accessTokenScopes] = accessToken?.token?.scopes?.joinToString(",")?.takeIf { it.isEmpty() } + it[accessTokenScopes] = accessToken?.run { token.scopes.joinToString(",").takeIf { it.isEmpty() } } it[refreshTokenValue] = refreshToken?.token?.tokenValue it[refreshTokenIssuedAt] = refreshToken?.token?.issuedAt it[refreshTokenExpiresAt] = refreshToken?.token?.expiresAt @@ -203,7 +203,7 @@ class ExposedOAuth2AuthorizationService(private val registeredClientRepository: JsonUtil.jsonToMap( it ) - } ?: emptyMap() + }.orEmpty() val oAuth2AuthorizationCode = OAuth2AuthorizationCode(authorizationCodeValue, authorizationCodeIssuedAt, authorizationCodeExpiresAt) builder.token(oAuth2AuthorizationCode) { @@ -242,7 +242,7 @@ class ExposedOAuth2AuthorizationService(private val registeredClientRepository: val oidcTokenIssuedAt = this[Authorization.oidcIdTokenIssuedAt] val oidcTokenExpiresAt = this[Authorization.oidcIdTokenExpiresAt] val oidcTokenMetadata = - this[Authorization.oidcIdTokenMetadata]?.let { JsonUtil.jsonToMap(it) }.or + this[Authorization.oidcIdTokenMetadata]?.let { JsonUtil.jsonToMap(it) }.orEmpty() val oidcIdToken = OidcIdToken( oidcIdTokenValue, @@ -259,7 +259,7 @@ class ExposedOAuth2AuthorizationService(private val registeredClientRepository: val refreshTokenIssuedAt = this[Authorization.refreshTokenIssuedAt] val refreshTokenExpiresAt = this[Authorization.refreshTokenExpiresAt] val refreshTokenMetadata = - this[Authorization.refreshTokenMetadata]?.let { JsonUtil.jsonToMap(it) } ?: emptyMap() + this[Authorization.refreshTokenMetadata]?.let { JsonUtil.jsonToMap(it) }.orEmpty() val oAuth2RefreshToken = OAuth2RefreshToken(refreshTokenValue, refreshTokenIssuedAt, refreshTokenExpiresAt) @@ -271,7 +271,7 @@ class ExposedOAuth2AuthorizationService(private val registeredClientRepository: val userCodeIssuedAt = this[Authorization.userCodeIssuedAt] val userCodeExpiresAt = this[Authorization.userCodeExpiresAt] val userCodeMetadata = - this[Authorization.userCodeMetadata]?.let { JsonUtil.jsonToMap(it) } ?: emptyMap() + this[Authorization.userCodeMetadata]?.let { JsonUtil.jsonToMap(it) }.orEmpty() val oAuth2UserCode = OAuth2UserCode(userCodeValue, userCodeIssuedAt, userCodeExpiresAt) builder.token(oAuth2UserCode) { it.putAll(userCodeMetadata) } } @@ -281,7 +281,7 @@ class ExposedOAuth2AuthorizationService(private val registeredClientRepository: val deviceCodeIssuedAt = this[Authorization.deviceCodeIssuedAt] val deviceCodeExpiresAt = this[Authorization.deviceCodeExpiresAt] val deviceCodeMetadata = - this[Authorization.deviceCodeMetadata]?.let { JsonUtil.jsonToMap(it) } ?: emptyMap() + this[Authorization.deviceCodeMetadata]?.let { JsonUtil.jsonToMap(it) }.orEmpty() val oAuth2DeviceCode = OAuth2DeviceCode(deviceCodeValue, deviceCodeIssuedAt, deviceCodeExpiresAt) builder.token(oAuth2DeviceCode) { it.putAll(deviceCodeMetadata) } diff --git a/src/main/kotlin/dev/usbharu/hideout/service/auth/UserDetailsServiceImpl.kt b/src/main/kotlin/dev/usbharu/hideout/service/auth/UserDetailsServiceImpl.kt index 76bb81a9..34bd9b60 100644 --- a/src/main/kotlin/dev/usbharu/hideout/service/auth/UserDetailsServiceImpl.kt +++ b/src/main/kotlin/dev/usbharu/hideout/service/auth/UserDetailsServiceImpl.kt @@ -21,7 +21,7 @@ class UserDetailsServiceImpl(private val userQueryService: UserQueryService, pri User( findById.name, findById.password, - listOf() + emptyList() ) } } diff --git a/src/main/kotlin/dev/usbharu/hideout/service/auth/UsernamePasswordAuthFilter.kt b/src/main/kotlin/dev/usbharu/hideout/service/auth/UsernamePasswordAuthFilter.kt deleted file mode 100644 index 208f4c6a..00000000 --- a/src/main/kotlin/dev/usbharu/hideout/service/auth/UsernamePasswordAuthFilter.kt +++ /dev/null @@ -1,15 +0,0 @@ -package dev.usbharu.hideout.service.auth - -import org.springframework.security.authentication.AuthenticationManager -import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter -import org.springframework.security.web.util.matcher.AntPathRequestMatcher - -class UsernamePasswordAuthFilter(jwtService: JwtService, authenticationManager: AuthenticationManager?) : - UsernamePasswordAuthenticationFilter(authenticationManager) { - init { - setRequiresAuthenticationRequestMatcher(AntPathRequestMatcher("/api/internal/v1/login", "POST")) - - this.setAuthenticationSuccessHandler { request, response, authentication -> - } - } -} From 5f44510010dde957a3eec161cda7d7fef3720864 Mon Sep 17 00:00:00 2001 From: usbharu <64310155+usbharu@users.noreply.github.com> Date: Tue, 19 Sep 2023 16:30:42 +0900 Subject: [PATCH 13/15] =?UTF-8?q?chore:=20Github=20Actions=E3=81=AEJava?= =?UTF-8?q?=E3=81=AE=E3=83=90=E3=83=BC=E3=82=B8=E3=83=A7=E3=83=B3=E3=82=92?= =?UTF-8?q?=E5=A4=89=E6=9B=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/test.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index df48f282..d8840f11 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -21,10 +21,10 @@ jobs: steps: - uses: actions/checkout@v3 - - name: Set up JDK 11 + - name: Set up JDK 17 uses: actions/setup-java@v3 with: - java-version: '11' + java-version: '17' distribution: 'temurin' - name: Build with Gradle uses: gradle/gradle-build-action@67421db6bd0bf253fb4bd25b31ebb98943c375e1 From 3f2cff7e6481350677e6143af9db6a5da01128bc Mon Sep 17 00:00:00 2001 From: usbharu <64310155+usbharu@users.noreply.github.com> Date: Tue, 19 Sep 2023 16:43:07 +0900 Subject: [PATCH 14/15] =?UTF-8?q?chore:=20=E3=83=93=E3=83=AB=E3=83=89?= =?UTF-8?q?=E6=99=82=E3=81=AB=E5=BC=B7=E5=88=B6=E7=9A=84=E3=81=AB=E3=82=B3?= =?UTF-8?q?=E3=83=BC=E3=83=89=E7=94=9F=E6=88=90=E3=82=92=E8=A1=8C=E3=81=86?= =?UTF-8?q?=E3=82=88=E3=81=86=E3=81=AB?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- build.gradle.kts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/build.gradle.kts b/build.gradle.kts index 18442d5e..7e8bd200 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -47,6 +47,8 @@ tasks.withType { kotlinOptions { freeCompilerArgs += "-Xjsr305=strict" } + dependsOn("openApiGenerateServer") + mustRunAfter("openApiGenerateServer") } tasks.withType { From 4b84a833040e90983757591e51b02a7011470c97 Mon Sep 17 00:00:00 2001 From: usbharu <64310155+usbharu@users.noreply.github.com> Date: Tue, 19 Sep 2023 16:44:54 +0900 Subject: [PATCH 15/15] =?UTF-8?q?chore:=20Github=20Actions=E3=81=AEJava?= =?UTF-8?q?=E3=81=AE=E3=83=90=E3=83=BC=E3=82=B8=E3=83=A7=E3=83=B3=E3=82=92?= =?UTF-8?q?=E5=A4=89=E6=9B=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/lint.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml index 66a5c04a..de183e3e 100644 --- a/.github/workflows/lint.yml +++ b/.github/workflows/lint.yml @@ -21,10 +21,10 @@ jobs: steps: - uses: actions/checkout@v3 - - name: Set up JDK 11 + - name: Set up JDK 17 uses: actions/setup-java@v3 with: - java-version: '11' + java-version: '17' distribution: 'temurin' - name: Build with Gradle uses: gradle/gradle-build-action@67421db6bd0bf253fb4bd25b31ebb98943c375e1