mirror of https://github.com/usbharu/Hideout.git
refactor: 不要なコードを削除、古い構成を更新
This commit is contained in:
parent
b5a8c0ff35
commit
0bb74b3a5f
|
@ -2,7 +2,7 @@ package dev.usbharu.hideout.service.ap
|
||||||
|
|
||||||
import com.fasterxml.jackson.databind.ObjectMapper
|
import com.fasterxml.jackson.databind.ObjectMapper
|
||||||
import com.fasterxml.jackson.module.kotlin.readValue
|
import com.fasterxml.jackson.module.kotlin.readValue
|
||||||
import dev.usbharu.hideout.config.Config
|
import dev.usbharu.hideout.config.ApplicationConfig
|
||||||
import dev.usbharu.hideout.domain.model.ap.Like
|
import dev.usbharu.hideout.domain.model.ap.Like
|
||||||
import dev.usbharu.hideout.domain.model.ap.Undo
|
import dev.usbharu.hideout.domain.model.ap.Undo
|
||||||
import dev.usbharu.hideout.domain.model.hideout.entity.Reaction
|
import dev.usbharu.hideout.domain.model.hideout.entity.Reaction
|
||||||
|
@ -35,6 +35,7 @@ class APReactionServiceImpl(
|
||||||
private val followerQueryService: FollowerQueryService,
|
private val followerQueryService: FollowerQueryService,
|
||||||
private val postQueryService: PostQueryService,
|
private val postQueryService: PostQueryService,
|
||||||
@Qualifier("activitypub") private val objectMapper: ObjectMapper,
|
@Qualifier("activitypub") private val objectMapper: ObjectMapper,
|
||||||
|
private val applicationConfig: ApplicationConfig
|
||||||
|
|
||||||
) : APReactionService {
|
) : APReactionService {
|
||||||
override suspend fun reaction(like: Reaction) {
|
override suspend fun reaction(like: Reaction) {
|
||||||
|
@ -63,7 +64,7 @@ class APReactionServiceImpl(
|
||||||
props[DeliverRemoveReactionJob.actor] = user.url
|
props[DeliverRemoveReactionJob.actor] = user.url
|
||||||
props[DeliverRemoveReactionJob.inbox] = follower.inbox
|
props[DeliverRemoveReactionJob.inbox] = follower.inbox
|
||||||
props[DeliverRemoveReactionJob.id] = post.id.toString()
|
props[DeliverRemoveReactionJob.id] = post.id.toString()
|
||||||
props[DeliverRemoveReactionJob.like] = Config.configData.objectMapper.writeValueAsString(like)
|
props[DeliverRemoveReactionJob.like] = objectMapper.writeValueAsString(like)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -81,7 +82,7 @@ class APReactionServiceImpl(
|
||||||
name = "Like",
|
name = "Like",
|
||||||
actor = actor,
|
actor = actor,
|
||||||
`object` = postUrl,
|
`object` = postUrl,
|
||||||
id = "${Config.configData.url}/like/note/$id",
|
id = "${applicationConfig.url}/like/note/$id",
|
||||||
content = content
|
content = content
|
||||||
),
|
),
|
||||||
objectMapper
|
objectMapper
|
||||||
|
@ -91,7 +92,7 @@ class APReactionServiceImpl(
|
||||||
override suspend fun removeReactionJob(props: JobProps<DeliverRemoveReactionJob>) {
|
override suspend fun removeReactionJob(props: JobProps<DeliverRemoveReactionJob>) {
|
||||||
val inbox = props[DeliverRemoveReactionJob.inbox]
|
val inbox = props[DeliverRemoveReactionJob.inbox]
|
||||||
val actor = props[DeliverRemoveReactionJob.actor]
|
val actor = props[DeliverRemoveReactionJob.actor]
|
||||||
val like = Config.configData.objectMapper.readValue<Like>(props[DeliverRemoveReactionJob.like])
|
val like = objectMapper.readValue<Like>(props[DeliverRemoveReactionJob.like])
|
||||||
httpClient.postAp(
|
httpClient.postAp(
|
||||||
urlString = inbox,
|
urlString = inbox,
|
||||||
username = "$actor#pubkey",
|
username = "$actor#pubkey",
|
||||||
|
@ -99,7 +100,7 @@ class APReactionServiceImpl(
|
||||||
name = "Undo Reaction",
|
name = "Undo Reaction",
|
||||||
actor = actor,
|
actor = actor,
|
||||||
`object` = like,
|
`object` = like,
|
||||||
id = "${Config.configData.url}/undo/note/${like.id}",
|
id = "${applicationConfig.url}/undo/note/${like.id}",
|
||||||
published = Instant.now()
|
published = Instant.now()
|
||||||
),
|
),
|
||||||
objectMapper
|
objectMapper
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
package dev.usbharu.hideout.service.api
|
package dev.usbharu.hideout.service.api
|
||||||
|
|
||||||
import dev.usbharu.hideout.config.Config
|
import dev.usbharu.hideout.config.ApplicationConfig
|
||||||
import dev.usbharu.hideout.domain.model.hideout.dto.PostCreateDto
|
import dev.usbharu.hideout.domain.model.hideout.dto.PostCreateDto
|
||||||
import dev.usbharu.hideout.domain.model.hideout.dto.PostResponse
|
import dev.usbharu.hideout.domain.model.hideout.dto.PostResponse
|
||||||
import dev.usbharu.hideout.domain.model.hideout.dto.ReactionResponse
|
import dev.usbharu.hideout.domain.model.hideout.dto.ReactionResponse
|
||||||
|
@ -51,7 +51,8 @@ class PostApiServiceImpl(
|
||||||
private val postResponseQueryService: PostResponseQueryService,
|
private val postResponseQueryService: PostResponseQueryService,
|
||||||
private val reactionQueryService: ReactionQueryService,
|
private val reactionQueryService: ReactionQueryService,
|
||||||
private val reactionService: ReactionService,
|
private val reactionService: ReactionService,
|
||||||
private val transaction: Transaction
|
private val transaction: Transaction,
|
||||||
|
private val applicationConfig: ApplicationConfig
|
||||||
) : PostApiService {
|
) : PostApiService {
|
||||||
override suspend fun createPost(postForm: Post, userId: Long): PostResponse {
|
override suspend fun createPost(postForm: Post, userId: Long): PostResponse {
|
||||||
return transaction.transaction {
|
return transaction.transaction {
|
||||||
|
@ -102,7 +103,10 @@ class PostApiServiceImpl(
|
||||||
val idOrNull = nameOrId.toLongOrNull()
|
val idOrNull = nameOrId.toLongOrNull()
|
||||||
return if (idOrNull == null) {
|
return if (idOrNull == null) {
|
||||||
val acct = AcctUtil.parse(nameOrId)
|
val acct = AcctUtil.parse(nameOrId)
|
||||||
postResponseQueryService.findByUserNameAndUserDomain(acct.username, acct.domain ?: Config.configData.domain)
|
postResponseQueryService.findByUserNameAndUserDomain(
|
||||||
|
acct.username,
|
||||||
|
acct.domain ?: applicationConfig.url.host
|
||||||
|
)
|
||||||
} else {
|
} else {
|
||||||
postResponseQueryService.findByUserId(idOrNull)
|
postResponseQueryService.findByUserId(idOrNull)
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
package dev.usbharu.hideout.service.api
|
package dev.usbharu.hideout.service.api
|
||||||
|
|
||||||
import dev.usbharu.hideout.config.Config
|
import dev.usbharu.hideout.config.ApplicationConfig
|
||||||
import dev.usbharu.hideout.domain.model.Acct
|
import dev.usbharu.hideout.domain.model.Acct
|
||||||
import dev.usbharu.hideout.domain.model.hideout.dto.UserCreateDto
|
import dev.usbharu.hideout.domain.model.hideout.dto.UserCreateDto
|
||||||
import dev.usbharu.hideout.domain.model.hideout.dto.UserResponse
|
import dev.usbharu.hideout.domain.model.hideout.dto.UserResponse
|
||||||
|
@ -42,7 +42,8 @@ class UserApiServiceImpl(
|
||||||
private val userQueryService: UserQueryService,
|
private val userQueryService: UserQueryService,
|
||||||
private val followerQueryService: FollowerQueryService,
|
private val followerQueryService: FollowerQueryService,
|
||||||
private val userService: UserService,
|
private val userService: UserService,
|
||||||
private val transaction: Transaction
|
private val transaction: Transaction,
|
||||||
|
private val applicationConfig: ApplicationConfig
|
||||||
) : UserApiService {
|
) : UserApiService {
|
||||||
override suspend fun findAll(limit: Int?, offset: Long): List<UserResponse> = transaction.transaction {
|
override suspend fun findAll(limit: Int?, offset: Long): List<UserResponse> = transaction.transaction {
|
||||||
userQueryService.findAll(min(limit ?: 100, 100), offset).map { UserResponse.from(it) }
|
userQueryService.findAll(min(limit ?: 100, 100), offset).map { UserResponse.from(it) }
|
||||||
|
@ -62,7 +63,7 @@ class UserApiServiceImpl(
|
||||||
UserResponse.from(
|
UserResponse.from(
|
||||||
userQueryService.findByNameAndDomain(
|
userQueryService.findByNameAndDomain(
|
||||||
acct.username,
|
acct.username,
|
||||||
acct.domain ?: Config.configData.domain
|
acct.domain ?: applicationConfig.url.host
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
@ -77,18 +78,18 @@ class UserApiServiceImpl(
|
||||||
}
|
}
|
||||||
|
|
||||||
override suspend fun findFollowersByAcct(acct: Acct): List<UserResponse> = transaction.transaction {
|
override suspend fun findFollowersByAcct(acct: Acct): List<UserResponse> = transaction.transaction {
|
||||||
followerQueryService.findFollowersByNameAndDomain(acct.username, acct.domain ?: Config.configData.domain)
|
followerQueryService.findFollowersByNameAndDomain(acct.username, acct.domain ?: applicationConfig.url.host)
|
||||||
.map { UserResponse.from(it) }
|
.map { UserResponse.from(it) }
|
||||||
}
|
}
|
||||||
|
|
||||||
override suspend fun findFollowingsByAcct(acct: Acct): List<UserResponse> = transaction.transaction {
|
override suspend fun findFollowingsByAcct(acct: Acct): List<UserResponse> = transaction.transaction {
|
||||||
followerQueryService.findFollowingByNameAndDomain(acct.username, acct.domain ?: Config.configData.domain)
|
followerQueryService.findFollowingByNameAndDomain(acct.username, acct.domain ?: applicationConfig.url.host)
|
||||||
.map { UserResponse.from(it) }
|
.map { UserResponse.from(it) }
|
||||||
}
|
}
|
||||||
|
|
||||||
override suspend fun createUser(username: String, password: String): UserResponse {
|
override suspend fun createUser(username: String, password: String): UserResponse {
|
||||||
return transaction.transaction {
|
return transaction.transaction {
|
||||||
if (userQueryService.existByNameAndDomain(username, Config.configData.domain)) {
|
if (userQueryService.existByNameAndDomain(username, applicationConfig.url.host)) {
|
||||||
throw UsernameAlreadyExistException()
|
throw UsernameAlreadyExistException()
|
||||||
}
|
}
|
||||||
UserResponse.from(userService.createLocalUser(UserCreateDto(username, username, "", password)))
|
UserResponse.from(userService.createLocalUser(UserCreateDto(username, username, "", password)))
|
||||||
|
@ -106,7 +107,7 @@ class UserApiServiceImpl(
|
||||||
userService.followRequest(
|
userService.followRequest(
|
||||||
userQueryService.findByNameAndDomain(
|
userQueryService.findByNameAndDomain(
|
||||||
targetAcct.username,
|
targetAcct.username,
|
||||||
targetAcct.domain ?: Config.configData.domain
|
targetAcct.domain ?: applicationConfig.url.host
|
||||||
).id,
|
).id,
|
||||||
sourceId
|
sourceId
|
||||||
)
|
)
|
||||||
|
|
|
@ -1,41 +0,0 @@
|
||||||
package dev.usbharu.hideout.service.api
|
|
||||||
|
|
||||||
import dev.usbharu.hideout.config.Config
|
|
||||||
import dev.usbharu.hideout.domain.model.hideout.dto.JwtToken
|
|
||||||
import dev.usbharu.hideout.domain.model.hideout.form.RefreshToken
|
|
||||||
import dev.usbharu.hideout.exception.InvalidUsernameOrPasswordException
|
|
||||||
import dev.usbharu.hideout.query.UserQueryService
|
|
||||||
import dev.usbharu.hideout.service.auth.JwtService
|
|
||||||
import dev.usbharu.hideout.service.core.Transaction
|
|
||||||
import dev.usbharu.hideout.service.user.UserAuthServiceImpl
|
|
||||||
import org.springframework.stereotype.Service
|
|
||||||
|
|
||||||
@Service
|
|
||||||
interface UserAuthApiService {
|
|
||||||
suspend fun login(username: String, password: String): JwtToken
|
|
||||||
suspend fun refreshToken(refreshToken: RefreshToken): JwtToken
|
|
||||||
}
|
|
||||||
|
|
||||||
@Service
|
|
||||||
class UserAuthApiServiceImpl(
|
|
||||||
private val userAuthService: UserAuthServiceImpl,
|
|
||||||
private val userQueryService: UserQueryService,
|
|
||||||
private val jwtService: JwtService,
|
|
||||||
private val transaction: Transaction
|
|
||||||
) : UserAuthApiService {
|
|
||||||
override suspend fun login(username: String, password: String): JwtToken {
|
|
||||||
return transaction.transaction {
|
|
||||||
if (userAuthService.verifyAccount(username, password).not()) {
|
|
||||||
throw InvalidUsernameOrPasswordException()
|
|
||||||
}
|
|
||||||
val user = userQueryService.findByNameAndDomain(username, Config.configData.domain)
|
|
||||||
jwtService.createToken(user)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
override suspend fun refreshToken(refreshToken: RefreshToken): JwtToken {
|
|
||||||
return transaction.transaction {
|
|
||||||
jwtService.refreshToken(refreshToken)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,105 +0,0 @@
|
||||||
package dev.usbharu.hideout.service.auth
|
|
||||||
|
|
||||||
import com.auth0.jwt.JWT
|
|
||||||
import com.auth0.jwt.algorithms.Algorithm
|
|
||||||
import dev.usbharu.hideout.config.Config
|
|
||||||
import dev.usbharu.hideout.domain.model.hideout.dto.JwtToken
|
|
||||||
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.JwtRefreshTokenRepository
|
|
||||||
import dev.usbharu.hideout.service.core.MetaService
|
|
||||||
import dev.usbharu.hideout.util.RsaUtil
|
|
||||||
import kotlinx.coroutines.runBlocking
|
|
||||||
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
|
|
||||||
|
|
||||||
suspend fun revokeToken(refreshToken: RefreshToken)
|
|
||||||
suspend fun revokeToken(user: User)
|
|
||||||
suspend fun revokeAll()
|
|
||||||
}
|
|
||||||
|
|
||||||
@Suppress("InjectDispatcher")
|
|
||||||
@Service
|
|
||||||
class JwtServiceImpl(
|
|
||||||
private val metaService: MetaService,
|
|
||||||
private val refreshTokenRepository: JwtRefreshTokenRepository,
|
|
||||||
private val userQueryService: UserQueryService,
|
|
||||||
private val refreshTokenQueryService: JwtRefreshTokenQueryService
|
|
||||||
) : JwtService {
|
|
||||||
|
|
||||||
private val privateKey = runBlocking {
|
|
||||||
RsaUtil.decodeRsaPrivateKey(metaService.getJwtMeta().privateKey)
|
|
||||||
}
|
|
||||||
|
|
||||||
private val publicKey = runBlocking {
|
|
||||||
RsaUtil.decodeRsaPublicKey(metaService.getJwtMeta().publicKey)
|
|
||||||
}
|
|
||||||
|
|
||||||
private val keyId = runBlocking { metaService.getJwtMeta().kid }
|
|
||||||
|
|
||||||
@Suppress("MagicNumber")
|
|
||||||
override suspend fun createToken(user: User): JwtToken {
|
|
||||||
val now = Instant.now()
|
|
||||||
val token = JWT.create()
|
|
||||||
.withAudience("${Config.configData.url}/users/${user.name}")
|
|
||||||
.withIssuer(Config.configData.url)
|
|
||||||
.withKeyId(keyId.toString())
|
|
||||||
.withClaim("uid", user.id)
|
|
||||||
.withExpiresAt(now.plus(30, ChronoUnit.MINUTES))
|
|
||||||
.sign(Algorithm.RSA256(publicKey, privateKey))
|
|
||||||
|
|
||||||
val jwtRefreshToken = JwtRefreshToken(
|
|
||||||
id = refreshTokenRepository.generateId(),
|
|
||||||
userId = user.id,
|
|
||||||
refreshToken = UUID.randomUUID().toString(),
|
|
||||||
createdAt = now,
|
|
||||||
expiresAt = now.plus(14, ChronoUnit.DAYS)
|
|
||||||
)
|
|
||||||
refreshTokenRepository.save(jwtRefreshToken)
|
|
||||||
return JwtToken(token, jwtRefreshToken.refreshToken)
|
|
||||||
}
|
|
||||||
|
|
||||||
override suspend fun refreshToken(refreshToken: RefreshToken): JwtToken {
|
|
||||||
val token = try {
|
|
||||||
refreshTokenQueryService.findByToken(refreshToken.refreshToken)
|
|
||||||
} catch (_: NoSuchElementException) {
|
|
||||||
throw InvalidRefreshTokenException("Invalid Refresh Token")
|
|
||||||
}
|
|
||||||
|
|
||||||
val user = userQueryService.findById(token.userId)
|
|
||||||
|
|
||||||
val now = Instant.now()
|
|
||||||
if (token.createdAt.isAfter(now)) {
|
|
||||||
throw InvalidRefreshTokenException("Invalid Refresh Token")
|
|
||||||
}
|
|
||||||
|
|
||||||
if (token.expiresAt.isBefore(now)) {
|
|
||||||
throw InvalidRefreshTokenException("Refresh Token Expired")
|
|
||||||
}
|
|
||||||
|
|
||||||
return createToken(user)
|
|
||||||
}
|
|
||||||
|
|
||||||
override suspend fun revokeToken(refreshToken: RefreshToken) {
|
|
||||||
refreshTokenQueryService.deleteByToken(refreshToken.refreshToken)
|
|
||||||
}
|
|
||||||
|
|
||||||
override suspend fun revokeToken(user: User) {
|
|
||||||
refreshTokenQueryService.deleteByUserId(user.id)
|
|
||||||
}
|
|
||||||
|
|
||||||
override suspend fun revokeAll() {
|
|
||||||
refreshTokenQueryService.deleteAll()
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,6 +1,6 @@
|
||||||
package dev.usbharu.hideout.service.user
|
package dev.usbharu.hideout.service.user
|
||||||
|
|
||||||
import dev.usbharu.hideout.config.Config
|
import dev.usbharu.hideout.config.ApplicationConfig
|
||||||
import dev.usbharu.hideout.query.UserQueryService
|
import dev.usbharu.hideout.query.UserQueryService
|
||||||
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder
|
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder
|
||||||
import org.springframework.stereotype.Service
|
import org.springframework.stereotype.Service
|
||||||
|
@ -9,7 +9,8 @@ import java.util.*
|
||||||
|
|
||||||
@Service
|
@Service
|
||||||
class UserAuthServiceImpl(
|
class UserAuthServiceImpl(
|
||||||
val userQueryService: UserQueryService
|
val userQueryService: UserQueryService,
|
||||||
|
private val applicationConfig: ApplicationConfig
|
||||||
) : UserAuthService {
|
) : UserAuthService {
|
||||||
|
|
||||||
override fun hash(password: String): String = BCryptPasswordEncoder().encode(password)
|
override fun hash(password: String): String = BCryptPasswordEncoder().encode(password)
|
||||||
|
@ -20,7 +21,7 @@ class UserAuthServiceImpl(
|
||||||
}
|
}
|
||||||
|
|
||||||
override suspend fun verifyAccount(username: String, password: String): Boolean {
|
override suspend fun verifyAccount(username: String, password: String): Boolean {
|
||||||
val userEntity = userQueryService.findByNameAndDomain(username, Config.configData.domain)
|
val userEntity = userQueryService.findByNameAndDomain(username, applicationConfig.url.host)
|
||||||
return userEntity.password == hash(password)
|
return userEntity.password == hash(password)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue