refactor: UserServiceをインターフェースに抽出

This commit is contained in:
usbharu 2023-04-28 16:00:01 +09:00
parent 2f29cf882f
commit 25b6f8caea
16 changed files with 106 additions and 46 deletions

View File

@ -8,13 +8,17 @@ import dev.usbharu.hideout.config.ConfigData
import dev.usbharu.hideout.domain.model.job.DeliverPostJob
import dev.usbharu.hideout.domain.model.job.ReceiveFollowJob
import dev.usbharu.hideout.plugins.*
import dev.usbharu.hideout.repository.*
import dev.usbharu.hideout.repository.IPostRepository
import dev.usbharu.hideout.repository.IUserRepository
import dev.usbharu.hideout.repository.PostRepositoryImpl
import dev.usbharu.hideout.repository.UserRepository
import dev.usbharu.hideout.routing.register
import dev.usbharu.hideout.service.IPostService
import dev.usbharu.hideout.service.IUserAuthService
import dev.usbharu.hideout.service.IdGenerateService
import dev.usbharu.hideout.service.TwitterSnowflakeIdGenerateService
import dev.usbharu.hideout.service.activitypub.*
import dev.usbharu.hideout.service.impl.IUserService
import dev.usbharu.hideout.service.impl.PostService
import dev.usbharu.hideout.service.impl.UserAuthService
import dev.usbharu.hideout.service.impl.UserService
@ -79,7 +83,7 @@ fun Application.parent() {
}
single<ActivityPubFollowService> { ActivityPubFollowServiceImpl(get(), get(), get(), get()) }
single<ActivityPubService> { ActivityPubServiceImpl(get(), get()) }
single<UserService> { UserService(get(),get()) }
single<IUserService> { UserService(get(),get()) }
single<ActivityPubUserService> { ActivityPubUserServiceImpl(get(), get()) }
single<ActivityPubNoteService> { ActivityPubNoteServiceImpl(get(), get(), get()) }
single<IPostService> { PostService(get(), get()) }
@ -93,11 +97,11 @@ fun Application.parent() {
configureStaticRouting()
configureMonitoring()
configureSerialization()
register(inject<UserService>().value)
register(inject<IUserService>().value)
configureRouting(
inject<HttpSignatureVerifyService>().value,
inject<ActivityPubService>().value,
inject<UserService>().value,
inject<IUserService>().value,
inject<ActivityPubUserService>().value,
inject<IPostService>().value
)

View File

@ -8,7 +8,7 @@ import dev.usbharu.hideout.routing.wellknown.webfinger
import dev.usbharu.hideout.service.IPostService
import dev.usbharu.hideout.service.activitypub.ActivityPubService
import dev.usbharu.hideout.service.activitypub.ActivityPubUserService
import dev.usbharu.hideout.service.impl.UserService
import dev.usbharu.hideout.service.impl.IUserService
import dev.usbharu.hideout.service.signature.HttpSignatureVerifyService
import io.ktor.server.application.*
import io.ktor.server.plugins.autohead.*
@ -17,7 +17,7 @@ import io.ktor.server.routing.*
fun Application.configureRouting(
httpSignatureVerifyService: HttpSignatureVerifyService,
activityPubService: ActivityPubService,
userService: UserService,
userService: IUserService,
activityPubUserService: ActivityPubUserService,
postService: IPostService
) {

View File

@ -1,7 +1,7 @@
package dev.usbharu.hideout.routing
import dev.usbharu.hideout.domain.model.hideout.dto.UserCreateDto
import dev.usbharu.hideout.service.impl.UserService
import dev.usbharu.hideout.service.impl.IUserService
import io.ktor.http.*
import io.ktor.server.application.*
import io.ktor.server.auth.*
@ -9,7 +9,7 @@ import io.ktor.server.request.*
import io.ktor.server.response.*
import io.ktor.server.routing.*
fun Application.register(userService: UserService) {
fun Application.register(userService: IUserService) {
routing {
get("/register") {

View File

@ -1,10 +1,9 @@
package dev.usbharu.hideout.routing.activitypub
import dev.usbharu.hideout.config.Config
import dev.usbharu.hideout.exception.ParameterNotExistException
import dev.usbharu.hideout.plugins.respondAp
import dev.usbharu.hideout.service.activitypub.ActivityPubUserService
import dev.usbharu.hideout.service.impl.UserService
import dev.usbharu.hideout.service.impl.IUserService
import dev.usbharu.hideout.util.HttpUtil.Activity
import dev.usbharu.hideout.util.HttpUtil.JsonLd
import io.ktor.http.*
@ -13,7 +12,7 @@ import io.ktor.server.request.*
import io.ktor.server.response.*
import io.ktor.server.routing.*
fun Routing.usersAP(activityPubUserService: ActivityPubUserService, userService: UserService) {
fun Routing.usersAP(activityPubUserService: ActivityPubUserService, userService: IUserService) {
route("/users/{name}") {
createChild(ContentTypeRouteSelector(ContentType.Application.Activity, ContentType.Application.JsonLd)).handle {
val name =

View File

@ -4,14 +4,14 @@ import dev.usbharu.hideout.config.Config
import dev.usbharu.hideout.domain.model.wellknown.WebFinger
import dev.usbharu.hideout.exception.IllegalParameterException
import dev.usbharu.hideout.exception.ParameterNotExistException
import dev.usbharu.hideout.service.impl.UserService
import dev.usbharu.hideout.service.impl.IUserService
import dev.usbharu.hideout.util.HttpUtil.Activity
import io.ktor.http.*
import io.ktor.server.application.*
import io.ktor.server.response.*
import io.ktor.server.routing.*
fun Routing.webfinger(userService:UserService){
fun Routing.webfinger(userService: IUserService){
route("/.well-known/webfinger"){
get {
val acct = call.request.queryParameters["resource"]?.decodeURLPart()

View File

@ -1,14 +1,14 @@
package dev.usbharu.hideout.service.activitypub
import com.fasterxml.jackson.module.kotlin.readValue
import dev.usbharu.hideout.domain.model.ap.Accept
import dev.usbharu.hideout.domain.model.ap.Follow
import dev.usbharu.hideout.config.Config
import dev.usbharu.hideout.domain.model.ActivityPubResponse
import dev.usbharu.hideout.domain.model.ActivityPubStringResponse
import dev.usbharu.hideout.domain.model.ap.Accept
import dev.usbharu.hideout.domain.model.ap.Follow
import dev.usbharu.hideout.domain.model.job.ReceiveFollowJob
import dev.usbharu.hideout.plugins.postAp
import dev.usbharu.hideout.service.impl.UserService
import dev.usbharu.hideout.service.impl.IUserService
import dev.usbharu.hideout.service.job.JobQueueParentService
import io.ktor.client.*
import io.ktor.http.*
@ -17,7 +17,7 @@ import kjob.core.job.JobProps
class ActivityPubFollowServiceImpl(
private val jobQueueParentService: JobQueueParentService,
private val activityPubUserService: ActivityPubUserService,
private val userService: UserService,
private val userService: IUserService,
private val httpClient: HttpClient
) : ActivityPubFollowService {
override suspend fun receiveFollow(follow: Follow): ActivityPubResponse {

View File

@ -7,7 +7,7 @@ import dev.usbharu.hideout.domain.model.ap.Create
import dev.usbharu.hideout.domain.model.ap.Note
import dev.usbharu.hideout.domain.model.job.DeliverPostJob
import dev.usbharu.hideout.plugins.postAp
import dev.usbharu.hideout.service.impl.UserService
import dev.usbharu.hideout.service.impl.IUserService
import dev.usbharu.hideout.service.job.JobQueueParentService
import io.ktor.client.*
import kjob.core.job.JobProps
@ -17,7 +17,7 @@ import java.time.Instant
class ActivityPubNoteServiceImpl(
private val httpClient: HttpClient,
private val jobQueueParentService: JobQueueParentService,
private val userService: UserService
private val userService: IUserService
) : ActivityPubNoteService {
private val logger = LoggerFactory.getLogger(this::class.java)

View File

@ -8,7 +8,7 @@ import dev.usbharu.hideout.domain.model.ap.Person
import dev.usbharu.hideout.domain.model.hideout.dto.RemoteUserCreateDto
import dev.usbharu.hideout.exception.UserNotFoundException
import dev.usbharu.hideout.exception.ap.IllegalActivityPubObjectException
import dev.usbharu.hideout.service.impl.UserService
import dev.usbharu.hideout.service.impl.IUserService
import dev.usbharu.hideout.util.HttpUtil.Activity
import io.ktor.client.*
import io.ktor.client.request.*
@ -17,7 +17,7 @@ import io.ktor.http.*
import org.slf4j.LoggerFactory
class ActivityPubUserServiceImpl(
private val userService: UserService,
private val userService: IUserService,
private val httpClient: HttpClient
) :
ActivityPubUserService {

View File

@ -0,0 +1,33 @@
package dev.usbharu.hideout.service.impl
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
interface IUserService {
suspend fun findAll(limit: Int? = 100, offset: Long? = 0): List<User>
suspend fun findById(id: Long): User
suspend fun findByIds(ids: List<Long>): List<User>
suspend fun findByName(name: String): List<User>
suspend fun findByNameLocalUser(name: String): User
suspend fun findByNameAndDomains(names: List<Pair<String, String>>): List<User>
suspend fun findByUrl(url: String): User
suspend fun findByUrls(urls: List<String>): List<User>
suspend fun usernameAlreadyUse(username: String): Boolean
suspend fun createLocalUser(user: UserCreateDto): User
suspend fun createRemoteUser(user: RemoteUserCreateDto): User
suspend fun findFollowersById(id: Long): List<User>
suspend fun addFollowers(id: Long, follower: Long)
}

View File

@ -10,10 +10,11 @@ import dev.usbharu.hideout.service.IUserAuthService
import java.lang.Integer.min
import java.time.Instant
class UserService(private val userRepository: IUserRepository, private val userAuthService: IUserAuthService) {
class UserService(private val userRepository: IUserRepository, private val userAuthService: IUserAuthService) :
IUserService {
private val maxLimit = 100
suspend fun findAll(limit: Int? = maxLimit, offset: Long? = 0): List<User> {
override suspend fun findAll(limit: Int?, offset: Long?): List<User> {
return userRepository.findAllByLimitAndByOffset(
min(limit ?: maxLimit, maxLimit),
@ -21,41 +22,41 @@ class UserService(private val userRepository: IUserRepository, private val userA
)
}
suspend fun findById(id: Long): User {
override suspend fun findById(id: Long): User {
return userRepository.findById(id) ?: throw UserNotFoundException("$id was not found.")
}
suspend fun findByIds(ids: List<Long>): List<User> {
override suspend fun findByIds(ids: List<Long>): List<User> {
return userRepository.findByIds(ids)
}
suspend fun findByName(name: String): List<User> {
override suspend fun findByName(name: String): List<User> {
return userRepository.findByName(name)
}
suspend fun findByNameLocalUser(name: String): User {
override suspend fun findByNameLocalUser(name: String): User {
return userRepository.findByNameAndDomain(name, Config.configData.domain)
?: throw UserNotFoundException("$name was not found.")
}
suspend fun findByNameAndDomains(names: List<Pair<String, String>>): List<User> {
override suspend fun findByNameAndDomains(names: List<Pair<String, String>>): List<User> {
return userRepository.findByNameAndDomains(names)
}
suspend fun findByUrl(url: String): User {
override suspend fun findByUrl(url: String): User {
return userRepository.findByUrl(url) ?: throw UserNotFoundException("$url was not found.")
}
suspend fun findByUrls(urls: List<String>): List<User> {
override suspend fun findByUrls(urls: List<String>): List<User> {
return userRepository.findByUrls(urls)
}
suspend fun usernameAlreadyUse(username: String): Boolean {
override suspend fun usernameAlreadyUse(username: String): Boolean {
val findByNameAndDomain = userRepository.findByNameAndDomain(username, Config.configData.domain)
return findByNameAndDomain != null
}
suspend fun createLocalUser(user: UserCreateDto): User {
override suspend fun createLocalUser(user: UserCreateDto): User {
val nextId = userRepository.nextId()
val HashedPassword = userAuthService.hash(user.password)
val keyPair = userAuthService.generateKeyPair()
@ -76,7 +77,7 @@ class UserService(private val userRepository: IUserRepository, private val userA
return userRepository.save(userEntity)
}
suspend fun createRemoteUser(user: RemoteUserCreateDto): User {
override suspend fun createRemoteUser(user: RemoteUserCreateDto): User {
val nextId = userRepository.nextId()
val userEntity = User(
id = nextId,
@ -93,11 +94,11 @@ class UserService(private val userRepository: IUserRepository, private val userA
return userRepository.save(userEntity)
}
suspend fun findFollowersById(id: Long): List<User> {
override suspend fun findFollowersById(id: Long): List<User> {
return userRepository.findFollowersById(id)
}
suspend fun addFollowers(id: Long, follower: Long) {
override suspend fun addFollowers(id: Long, follower: Long) {
return userRepository.createFollower(id, follower)
}

View File

@ -1,7 +1,7 @@
package dev.usbharu.hideout.plugins
import dev.usbharu.hideout.domain.model.hideout.entity.User
import dev.usbharu.hideout.domain.model.ap.JsonLd
import dev.usbharu.hideout.domain.model.hideout.entity.User
import dev.usbharu.hideout.repository.IUserRepository
import dev.usbharu.hideout.service.impl.toPem
import io.ktor.client.*
@ -29,7 +29,11 @@ class ActivityPubKtTest {
TODO("Not yet implemented")
}
override suspend fun findByName(name: String): User {
override suspend fun findByName(name: String): List<User> {
TODO()
}
override suspend fun findByNameAndDomain(name: String, domain: String): User? {
val keyPairGenerator = KeyPairGenerator.getInstance("RSA")
keyPairGenerator.initialize(1024)
val generateKeyPair = keyPairGenerator.generateKeyPair()
@ -49,6 +53,10 @@ class ActivityPubKtTest {
)
}
override suspend fun findByDomain(domain: String): List<User> {
TODO("Not yet implemented")
}
override suspend fun findByNameAndDomains(names: List<Pair<String, String>>): List<User> {
TODO("Not yet implemented")
}
@ -85,6 +93,10 @@ class ActivityPubKtTest {
TODO("Not yet implemented")
}
override suspend fun nextId(): Long {
TODO("Not yet implemented")
}
})
val httpClient = HttpClient(MockEngine { httpRequestData ->

View File

@ -24,7 +24,11 @@ class KtorKeyMapTest {
TODO("Not yet implemented")
}
override suspend fun findByName(name: String): User {
override suspend fun findByName(name: String): List<User> {
TODO()
}
override suspend fun findByNameAndDomain(name: String, domain: String): User? {
val keyPairGenerator = KeyPairGenerator.getInstance("RSA")
keyPairGenerator.initialize(1024)
val generateKeyPair = keyPairGenerator.generateKeyPair()
@ -42,6 +46,11 @@ class KtorKeyMapTest {
generateKeyPair.private.toPem(),
createdAt = Instant.now()
)
}
override suspend fun findByDomain(domain: String): List<User> {
TODO("Not yet implemented")
}
override suspend fun findByNameAndDomains(names: List<Pair<String, String>>): List<User> {

View File

@ -6,6 +6,7 @@ import dev.usbharu.hideout.plugins.configureSerialization
import dev.usbharu.hideout.plugins.configureStatusPages
import dev.usbharu.hideout.service.activitypub.ActivityPubService
import dev.usbharu.hideout.service.activitypub.ActivityPubUserService
import dev.usbharu.hideout.service.impl.IUserService
import dev.usbharu.hideout.service.impl.UserService
import dev.usbharu.hideout.service.signature.HttpSignatureVerifyService
import io.ktor.client.request.*
@ -45,7 +46,7 @@ class InboxRoutingKtTest {
val activityPubService = mock<ActivityPubService>{
on { parseActivity(any()) } doThrow JsonParseException()
}
val userService = mock<UserService>()
val userService = mock<IUserService>()
val activityPubUserService = mock<ActivityPubUserService>()
application {
configureStatusPages()
@ -82,7 +83,7 @@ class InboxRoutingKtTest {
val activityPubService = mock<ActivityPubService>{
on { parseActivity(any()) } doThrow JsonParseException()
}
val userService = mock<UserService>()
val userService = mock<IUserService>()
val activityPubUserService = mock<ActivityPubUserService>()
application {
configureStatusPages()

View File

@ -13,6 +13,7 @@ import dev.usbharu.hideout.plugins.configureRouting
import dev.usbharu.hideout.plugins.configureSerialization
import dev.usbharu.hideout.service.activitypub.ActivityPubService
import dev.usbharu.hideout.service.activitypub.ActivityPubUserService
import dev.usbharu.hideout.service.impl.IUserService
import dev.usbharu.hideout.service.impl.UserService
import dev.usbharu.hideout.service.signature.HttpSignatureVerifyService
import dev.usbharu.hideout.util.HttpUtil.Activity
@ -62,7 +63,7 @@ class UsersAPTest {
val httpSignatureVerifyService = mock<HttpSignatureVerifyService> {}
val activityPubService = mock<ActivityPubService> {}
val userService = mock<UserService> {}
val userService = mock<IUserService> {}
val activityPubUserService = mock<ActivityPubUserService> {
onBlocking { getPersonByName(anyString()) } doReturn person

View File

@ -6,10 +6,10 @@ package dev.usbharu.hideout.service.activitypub
import com.fasterxml.jackson.module.kotlin.readValue
import dev.usbharu.hideout.config.Config
import dev.usbharu.hideout.config.ConfigData
import dev.usbharu.hideout.domain.model.hideout.entity.User
import dev.usbharu.hideout.domain.model.ap.*
import dev.usbharu.hideout.domain.model.hideout.entity.User
import dev.usbharu.hideout.domain.model.job.ReceiveFollowJob
import dev.usbharu.hideout.service.impl.UserService
import dev.usbharu.hideout.service.impl.IUserService
import dev.usbharu.hideout.service.job.JobQueueParentService
import io.ktor.client.*
import io.ktor.client.engine.mock.*
@ -87,7 +87,7 @@ class ActivityPubFollowServiceImplTest {
val activityPubUserService = mock<ActivityPubUserService> {
onBlocking { fetchPerson(anyString()) } doReturn person
}
val userService = mock<UserService> {
val userService = mock<IUserService> {
onBlocking { findByUrls(any()) } doReturn listOf(
User(
id = 1L,

View File

@ -8,7 +8,7 @@ import dev.usbharu.hideout.config.ConfigData
import dev.usbharu.hideout.domain.model.PostEntity
import dev.usbharu.hideout.domain.model.hideout.entity.User
import dev.usbharu.hideout.domain.model.job.DeliverPostJob
import dev.usbharu.hideout.service.impl.UserService
import dev.usbharu.hideout.service.impl.IUserService
import dev.usbharu.hideout.service.job.JobQueueParentService
import io.ktor.client.*
import io.ktor.client.engine.mock.*
@ -54,7 +54,7 @@ class ActivityPubNoteServiceImplTest {
createdAt = Instant.now()
)
)
val userService = mock<UserService> {
val userService = mock<IUserService> {
onBlocking { findById(eq(1L)) } doReturn User(
1L,
"test",