refactor: 不要なコードを削除

This commit is contained in:
usbharu 2023-08-11 11:25:26 +09:00
parent 8654c627d1
commit de79c91710
8 changed files with 129 additions and 131 deletions

View File

@ -0,0 +1,13 @@
package dev.usbharu.hideout.query
import dev.usbharu.hideout.domain.model.hideout.entity.JwtRefreshToken
interface JwtRefreshTokenQueryService {
suspend fun findById(id: Long): JwtRefreshToken
suspend fun findByToken(token: String): JwtRefreshToken
suspend fun findByUserId(userId: Long): JwtRefreshToken
suspend fun deleteById(id: Long)
suspend fun deleteByToken(token: String)
suspend fun deleteByUserId(userId: Long)
suspend fun deleteAll()
}

View File

@ -0,0 +1,38 @@
package dev.usbharu.hideout.query
import dev.usbharu.hideout.domain.model.hideout.entity.JwtRefreshToken
import dev.usbharu.hideout.repository.JwtRefreshTokens
import dev.usbharu.hideout.repository.toJwtRefreshToken
import org.jetbrains.exposed.sql.SqlExpressionBuilder.eq
import org.jetbrains.exposed.sql.deleteAll
import org.jetbrains.exposed.sql.deleteWhere
import org.jetbrains.exposed.sql.select
import org.koin.core.annotation.Single
@Single
class JwtRefreshTokenQueryServiceImpl : JwtRefreshTokenQueryService {
override suspend fun findById(id: Long): JwtRefreshToken =
JwtRefreshTokens.select { JwtRefreshTokens.id.eq(id) }.single().toJwtRefreshToken()
override suspend fun findByToken(token: String): JwtRefreshToken =
JwtRefreshTokens.select { JwtRefreshTokens.refreshToken.eq(token) }.single().toJwtRefreshToken()
override suspend fun findByUserId(userId: Long): JwtRefreshToken =
JwtRefreshTokens.select { JwtRefreshTokens.userId.eq(userId) }.single().toJwtRefreshToken()
override suspend fun deleteById(id: Long) {
JwtRefreshTokens.deleteWhere { JwtRefreshTokens.id eq id }
}
override suspend fun deleteByToken(token: String) {
JwtRefreshTokens.deleteWhere { refreshToken eq token }
}
override suspend fun deleteByUserId(userId: Long) {
JwtRefreshTokens.deleteWhere { JwtRefreshTokens.userId eq userId }
}
override suspend fun deleteAll() {
JwtRefreshTokens.deleteAll()
}
}

View File

@ -8,13 +8,6 @@ interface IJwtRefreshTokenRepository {
suspend fun save(token: JwtRefreshToken)
suspend fun findById(id: Long): JwtRefreshToken?
suspend fun findByToken(token: String): JwtRefreshToken?
suspend fun findByUserId(userId: Long): JwtRefreshToken?
suspend fun delete(token: JwtRefreshToken)
suspend fun deleteById(id: Long)
suspend fun deleteByToken(token: String)
suspend fun deleteByUserId(userId: Long)
suspend fun deleteAll()
}

View File

@ -2,10 +2,8 @@ package dev.usbharu.hideout.repository
import dev.usbharu.hideout.domain.model.hideout.entity.JwtRefreshToken
import dev.usbharu.hideout.service.core.IdGenerateService
import kotlinx.coroutines.Dispatchers
import org.jetbrains.exposed.sql.*
import org.jetbrains.exposed.sql.SqlExpressionBuilder.eq
import org.jetbrains.exposed.sql.transactions.experimental.newSuspendedTransaction
import org.jetbrains.exposed.sql.transactions.transaction
import org.koin.core.annotation.Single
import java.time.Instant
@ -24,79 +22,32 @@ class JwtRefreshTokenRepositoryImpl(
}
}
@Suppress("InjectDispatcher")
suspend fun <T> query(block: suspend () -> T): T =
newSuspendedTransaction(Dispatchers.IO) { block() }
override suspend fun generateId(): Long = idGenerateService.generateId()
override suspend fun save(token: JwtRefreshToken) {
query {
if (JwtRefreshTokens.select { JwtRefreshTokens.id.eq(token.id) }.empty()) {
JwtRefreshTokens.insert {
it[id] = token.id
it[userId] = token.userId
it[refreshToken] = token.refreshToken
it[createdAt] = token.createdAt.toEpochMilli()
it[expiresAt] = token.expiresAt.toEpochMilli()
}
} else {
JwtRefreshTokens.update({ JwtRefreshTokens.id eq token.id }) {
it[userId] = token.userId
it[refreshToken] = token.refreshToken
it[createdAt] = token.createdAt.toEpochMilli()
it[expiresAt] = token.expiresAt.toEpochMilli()
}
if (JwtRefreshTokens.select { JwtRefreshTokens.id.eq(token.id) }.empty()) {
JwtRefreshTokens.insert {
it[id] = token.id
it[userId] = token.userId
it[refreshToken] = token.refreshToken
it[createdAt] = token.createdAt.toEpochMilli()
it[expiresAt] = token.expiresAt.toEpochMilli()
}
} else {
JwtRefreshTokens.update({ JwtRefreshTokens.id eq token.id }) {
it[userId] = token.userId
it[refreshToken] = token.refreshToken
it[createdAt] = token.createdAt.toEpochMilli()
it[expiresAt] = token.expiresAt.toEpochMilli()
}
}
}
override suspend fun findById(id: Long): JwtRefreshToken? {
return query {
JwtRefreshTokens.select { JwtRefreshTokens.id.eq(id) }.singleOrNull()?.toJwtRefreshToken()
}
}
override suspend fun findByToken(token: String): JwtRefreshToken? {
return query {
JwtRefreshTokens.select { JwtRefreshTokens.refreshToken.eq(token) }.singleOrNull()?.toJwtRefreshToken()
}
}
override suspend fun findByUserId(userId: Long): JwtRefreshToken? {
return query {
JwtRefreshTokens.select { JwtRefreshTokens.userId.eq(userId) }.singleOrNull()?.toJwtRefreshToken()
}
}
override suspend fun findById(id: Long): JwtRefreshToken? =
JwtRefreshTokens.select { JwtRefreshTokens.id.eq(id) }.singleOrNull()?.toJwtRefreshToken()
override suspend fun delete(token: JwtRefreshToken) {
return query {
JwtRefreshTokens.deleteWhere { id eq token.id }
}
}
override suspend fun deleteById(id: Long) {
return query {
JwtRefreshTokens.deleteWhere { JwtRefreshTokens.id eq id }
}
}
override suspend fun deleteByToken(token: String) {
return query {
JwtRefreshTokens.deleteWhere { refreshToken eq token }
}
}
override suspend fun deleteByUserId(userId: Long) {
return query {
JwtRefreshTokens.deleteWhere { JwtRefreshTokens.userId eq userId }
}
}
override suspend fun deleteAll() {
return query {
JwtRefreshTokens.deleteAll()
}
JwtRefreshTokens.deleteWhere { id eq token.id }
}
}

View File

@ -1,9 +1,7 @@
package dev.usbharu.hideout.repository
import dev.usbharu.hideout.domain.model.hideout.entity.Jwt
import kotlinx.coroutines.Dispatchers
import org.jetbrains.exposed.sql.*
import org.jetbrains.exposed.sql.transactions.experimental.newSuspendedTransaction
import org.jetbrains.exposed.sql.transactions.transaction
import org.koin.core.annotation.Single
import java.util.*
@ -18,39 +16,31 @@ class MetaRepositoryImpl(private val database: Database) : IMetaRepository {
}
}
@Suppress("InjectDispatcher")
suspend fun <T> query(block: suspend () -> T): T =
newSuspendedTransaction(Dispatchers.IO) { block() }
override suspend fun save(meta: dev.usbharu.hideout.domain.model.hideout.entity.Meta) {
return query {
if (Meta.select { Meta.id eq 1 }.empty()) {
Meta.insert {
it[id] = 1
it[this.version] = meta.version
it[kid] = UUID.randomUUID().toString()
it[this.jwtPrivateKey] = meta.jwt.privateKey
it[this.jwtPublicKey] = meta.jwt.publicKey
}
} else {
Meta.update({ Meta.id eq 1 }) {
it[this.version] = meta.version
it[kid] = UUID.randomUUID().toString()
it[this.jwtPrivateKey] = meta.jwt.privateKey
it[this.jwtPublicKey] = meta.jwt.publicKey
}
if (Meta.select { Meta.id eq 1 }.empty()) {
Meta.insert {
it[id] = 1
it[this.version] = meta.version
it[kid] = UUID.randomUUID().toString()
it[this.jwtPrivateKey] = meta.jwt.privateKey
it[this.jwtPublicKey] = meta.jwt.publicKey
}
} else {
Meta.update({ Meta.id eq 1 }) {
it[this.version] = meta.version
it[kid] = UUID.randomUUID().toString()
it[this.jwtPrivateKey] = meta.jwt.privateKey
it[this.jwtPublicKey] = meta.jwt.publicKey
}
}
}
override suspend fun get(): dev.usbharu.hideout.domain.model.hideout.entity.Meta? {
return query {
Meta.select { Meta.id eq 1 }.singleOrNull()?.let {
dev.usbharu.hideout.domain.model.hideout.entity.Meta(
it[Meta.version],
Jwt(UUID.fromString(it[Meta.kid]), it[Meta.jwtPrivateKey], it[Meta.jwtPublicKey])
)
}
return Meta.select { Meta.id eq 1 }.singleOrNull()?.let {
dev.usbharu.hideout.domain.model.hideout.entity.Meta(
it[Meta.version],
Jwt(UUID.fromString(it[Meta.kid]), it[Meta.jwtPrivateKey], it[Meta.jwtPublicKey])
)
}
}
}

View File

@ -8,6 +8,7 @@ import dev.usbharu.hideout.domain.model.hideout.entity.JwtRefreshToken
import dev.usbharu.hideout.domain.model.hideout.entity.User
import dev.usbharu.hideout.domain.model.hideout.form.RefreshToken
import dev.usbharu.hideout.exception.InvalidRefreshTokenException
import dev.usbharu.hideout.query.JwtRefreshTokenQueryService
import dev.usbharu.hideout.query.UserQueryService
import dev.usbharu.hideout.repository.IJwtRefreshTokenRepository
import dev.usbharu.hideout.service.core.IMetaService
@ -25,7 +26,8 @@ import java.util.*
class JwtServiceImpl(
private val metaService: IMetaService,
private val refreshTokenRepository: IJwtRefreshTokenRepository,
private val userQueryService: UserQueryService
private val userQueryService: UserQueryService,
private val refreshTokenQueryService: JwtRefreshTokenQueryService
) : IJwtService {
private val privateKey by lazy {
@ -69,8 +71,11 @@ class JwtServiceImpl(
}
override suspend fun refreshToken(refreshToken: RefreshToken): JwtToken {
val token = refreshTokenRepository.findByToken(refreshToken.refreshToken)
?: throw InvalidRefreshTokenException("Invalid Refresh Token")
val token = try {
refreshTokenQueryService.findByToken(refreshToken.refreshToken)
} catch (_: NoSuchElementException) {
throw InvalidRefreshTokenException("Invalid Refresh Token")
}
val user = userQueryService.findById(token.userId)
@ -87,14 +92,14 @@ class JwtServiceImpl(
}
override suspend fun revokeToken(refreshToken: RefreshToken) {
refreshTokenRepository.deleteByToken(refreshToken.refreshToken)
refreshTokenQueryService.deleteByToken(refreshToken.refreshToken)
}
override suspend fun revokeToken(user: User) {
refreshTokenRepository.deleteByUserId(user.id)
refreshTokenQueryService.deleteByUserId(user.id)
}
override suspend fun revokeAll() {
refreshTokenRepository.deleteAll()
refreshTokenQueryService.deleteAll()
}
}

View File

@ -10,6 +10,7 @@ import org.jetbrains.exposed.sql.Database
import org.jetbrains.exposed.sql.SchemaUtils
import org.jetbrains.exposed.sql.insert
import org.jetbrains.exposed.sql.select
import org.jetbrains.exposed.sql.transactions.experimental.newSuspendedTransaction
import org.jetbrains.exposed.sql.transactions.transaction
import org.junit.jupiter.api.AfterEach
import org.junit.jupiter.api.BeforeEach
@ -53,9 +54,11 @@ class JwtRefreshTokenRepositoryImplTest {
val expiresAt = now.plus(10, ChronoUnit.MINUTES)
val expect = JwtRefreshToken(1L, 2L, "refreshToken", now, expiresAt)
repository.save(expect)
val actual = repository.findById(1L)
assertEquals(expect, actual)
newSuspendedTransaction {
repository.save(expect)
val actual = repository.findById(1L)
assertEquals(expect, actual)
}
}
@Test
@ -68,7 +71,7 @@ class JwtRefreshTokenRepositoryImplTest {
}
}
)
transaction {
newSuspendedTransaction {
JwtRefreshTokens.insert {
it[id] = 1L
it[userId] = 2L
@ -76,17 +79,17 @@ class JwtRefreshTokenRepositoryImplTest {
it[createdAt] = Instant.now().toEpochMilli()
it[expiresAt] = Instant.now().plus(10, ChronoUnit.MINUTES).toEpochMilli()
}
repository.save(
JwtRefreshToken(
id = 1L,
userId = 2L,
refreshToken = "refreshToken2",
createdAt = Instant.now(),
expiresAt = Instant.now().plus(10, ChronoUnit.MINUTES)
)
)
}
repository.save(
JwtRefreshToken(
id = 1L,
userId = 2L,
refreshToken = "refreshToken2",
createdAt = Instant.now(),
expiresAt = Instant.now().plus(10, ChronoUnit.MINUTES)
)
)
transaction {
val toJwtRefreshToken = JwtRefreshTokens.select { JwtRefreshTokens.id.eq(1L) }.single().toJwtRefreshToken()
assertEquals("refreshToken2", toJwtRefreshToken.refreshToken)

View File

@ -12,6 +12,7 @@ import dev.usbharu.hideout.domain.model.hideout.entity.JwtRefreshToken
import dev.usbharu.hideout.domain.model.hideout.entity.User
import dev.usbharu.hideout.domain.model.hideout.form.RefreshToken
import dev.usbharu.hideout.exception.InvalidRefreshTokenException
import dev.usbharu.hideout.query.JwtRefreshTokenQueryService
import dev.usbharu.hideout.query.UserQueryService
import dev.usbharu.hideout.repository.IJwtRefreshTokenRepository
import dev.usbharu.hideout.service.core.IMetaService
@ -21,6 +22,7 @@ import kotlinx.coroutines.test.runTest
import org.junit.jupiter.api.Test
import org.junit.jupiter.api.assertThrows
import org.mockito.kotlin.doReturn
import org.mockito.kotlin.doThrow
import org.mockito.kotlin.mock
import java.security.KeyPairGenerator
import java.security.interfaces.RSAPrivateKey
@ -50,7 +52,7 @@ class JwtServiceImplTest {
val refreshTokenRepository = mock<IJwtRefreshTokenRepository> {
onBlocking { generateId() } doReturn 1L
}
val jwtService = JwtServiceImpl(metaService, refreshTokenRepository, mock())
val jwtService = JwtServiceImpl(metaService, refreshTokenRepository, mock(), mock())
val token = jwtService.createToken(
User(
id = 1L,
@ -93,6 +95,10 @@ class JwtServiceImplTest {
val generateKeyPair = keyPairGenerator.generateKeyPair()
val refreshTokenRepository = mock<IJwtRefreshTokenRepository> {
onBlocking { generateId() } doReturn 2L
}
val jwtRefreshTokenQueryService = mock<JwtRefreshTokenQueryService> {
onBlocking { findByToken("refreshToken") } doReturn JwtRefreshToken(
id = 1L,
userId = 1L,
@ -100,7 +106,6 @@ class JwtServiceImplTest {
createdAt = Instant.now().minus(60, ChronoUnit.MINUTES),
expiresAt = Instant.now().plus(14, ChronoUnit.DAYS).minus(60, ChronoUnit.MINUTES)
)
onBlocking { generateId() } doReturn 2L
}
val userService = mock<UserQueryService> {
onBlocking { findById(1L) } doReturn User(
@ -125,7 +130,7 @@ class JwtServiceImplTest {
Base64Util.encode(generateKeyPair.public.encoded)
)
}
val jwtService = JwtServiceImpl(metaService, refreshTokenRepository, userService)
val jwtService = JwtServiceImpl(metaService, refreshTokenRepository, userService, jwtRefreshTokenQueryService)
val refreshToken = jwtService.refreshToken(RefreshToken("refreshToken"))
assertNotEquals("", refreshToken.token)
assertNotEquals("", refreshToken.refreshToken)
@ -147,16 +152,16 @@ class JwtServiceImplTest {
@Test
fun `refreshToken 無効なリフレッシュトークンは失敗する`() = runTest {
val refreshTokenRepository = mock<IJwtRefreshTokenRepository> {
onBlocking { findByToken("InvalidRefreshToken") } doReturn null
val refreshTokenRepository = mock<JwtRefreshTokenQueryService> {
onBlocking { findByToken("InvalidRefreshToken") } doThrow NoSuchElementException()
}
val jwtService = JwtServiceImpl(mock(), refreshTokenRepository, mock())
val jwtService = JwtServiceImpl(mock(), mock(), mock(), refreshTokenRepository)
assertThrows<InvalidRefreshTokenException> { jwtService.refreshToken(RefreshToken("InvalidRefreshToken")) }
}
@Test
fun `refreshToken 未来に作成されたリフレッシュトークンは失敗する`() = runTest {
val refreshTokenRepository = mock<IJwtRefreshTokenRepository> {
val refreshTokenRepository = mock<JwtRefreshTokenQueryService> {
onBlocking { findByToken("refreshToken") } doReturn JwtRefreshToken(
id = 1L,
userId = 1L,
@ -165,13 +170,13 @@ class JwtServiceImplTest {
expiresAt = Instant.now().plus(10, ChronoUnit.MINUTES).plus(14, ChronoUnit.DAYS)
)
}
val jwtService = JwtServiceImpl(mock(), refreshTokenRepository, mock())
val jwtService = JwtServiceImpl(mock(), mock(), mock(), refreshTokenRepository)
assertThrows<InvalidRefreshTokenException> { jwtService.refreshToken(RefreshToken("refreshToken")) }
}
@Test
fun `refreshToken 期限切れのリフレッシュトークンでは失敗する`() = runTest {
val refreshTokenRepository = mock<IJwtRefreshTokenRepository> {
val refreshTokenRepository = mock<JwtRefreshTokenQueryService> {
onBlocking { findByToken("refreshToken") } doReturn JwtRefreshToken(
id = 1L,
userId = 1L,
@ -180,7 +185,7 @@ class JwtServiceImplTest {
expiresAt = Instant.now().minus(16, ChronoUnit.DAYS)
)
}
val jwtService = JwtServiceImpl(mock(), refreshTokenRepository, mock())
val jwtService = JwtServiceImpl(mock(), mock(), mock(), refreshTokenRepository)
assertThrows<InvalidRefreshTokenException> { jwtService.refreshToken(RefreshToken("refreshToken")) }
}
}