From 194a648862976588f8c48f1a1a4169cb144ebff7 Mon Sep 17 00:00:00 2001 From: usbharu <64310155+usbharu@users.noreply.github.com> Date: Mon, 22 May 2023 16:08:28 +0900 Subject: [PATCH] =?UTF-8?q?feat:=20Follow=E3=82=92=E9=80=81=E3=82=8C?= =?UTF-8?q?=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 --- .../domain/model/hideout/dto/SendFollowDto.kt | 5 ++++ .../ActivityPubSendFollowService.kt | 7 ++++++ .../ActivityPubSendFollowServiceImpl.kt | 23 ++++++++++++++++++ .../hideout/service/impl/UserService.kt | 24 +++++++++++++++---- .../hideout/service/impl/UserServiceTest.kt | 4 ++-- 5 files changed, 57 insertions(+), 6 deletions(-) create mode 100644 src/main/kotlin/dev/usbharu/hideout/domain/model/hideout/dto/SendFollowDto.kt create mode 100644 src/main/kotlin/dev/usbharu/hideout/service/activitypub/ActivityPubSendFollowService.kt create mode 100644 src/main/kotlin/dev/usbharu/hideout/service/activitypub/ActivityPubSendFollowServiceImpl.kt diff --git a/src/main/kotlin/dev/usbharu/hideout/domain/model/hideout/dto/SendFollowDto.kt b/src/main/kotlin/dev/usbharu/hideout/domain/model/hideout/dto/SendFollowDto.kt new file mode 100644 index 00000000..595bb695 --- /dev/null +++ b/src/main/kotlin/dev/usbharu/hideout/domain/model/hideout/dto/SendFollowDto.kt @@ -0,0 +1,5 @@ +package dev.usbharu.hideout.domain.model.hideout.dto + +import dev.usbharu.hideout.domain.model.hideout.entity.User + +data class SendFollowDto(val userId: User, val followTargetUserId: User) diff --git a/src/main/kotlin/dev/usbharu/hideout/service/activitypub/ActivityPubSendFollowService.kt b/src/main/kotlin/dev/usbharu/hideout/service/activitypub/ActivityPubSendFollowService.kt new file mode 100644 index 00000000..8d0dd1f2 --- /dev/null +++ b/src/main/kotlin/dev/usbharu/hideout/service/activitypub/ActivityPubSendFollowService.kt @@ -0,0 +1,7 @@ +package dev.usbharu.hideout.service.activitypub + +import dev.usbharu.hideout.domain.model.hideout.dto.SendFollowDto + +interface ActivityPubSendFollowService { + suspend fun sendFollow(sendFollowDto: SendFollowDto) +} diff --git a/src/main/kotlin/dev/usbharu/hideout/service/activitypub/ActivityPubSendFollowServiceImpl.kt b/src/main/kotlin/dev/usbharu/hideout/service/activitypub/ActivityPubSendFollowServiceImpl.kt new file mode 100644 index 00000000..e73e9266 --- /dev/null +++ b/src/main/kotlin/dev/usbharu/hideout/service/activitypub/ActivityPubSendFollowServiceImpl.kt @@ -0,0 +1,23 @@ +package dev.usbharu.hideout.service.activitypub + +import dev.usbharu.hideout.domain.model.ap.Follow +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 + +@Single +class ActivityPubSendFollowServiceImpl(private val httpClient: HttpClient) : ActivityPubSendFollowService { + override suspend fun sendFollow(sendFollowDto: SendFollowDto) { + val follow = Follow( + name = "Follow", + `object` = sendFollowDto.followTargetUserId.url, + actor = sendFollowDto.userId.url + ) + httpClient.postAp( + urlString = sendFollowDto.followTargetUserId.inbox, + username = sendFollowDto.userId.url, + jsonLd = follow + ) + } +} diff --git a/src/main/kotlin/dev/usbharu/hideout/service/impl/UserService.kt b/src/main/kotlin/dev/usbharu/hideout/service/impl/UserService.kt index d2037fa7..23ccaa6c 100644 --- a/src/main/kotlin/dev/usbharu/hideout/service/impl/UserService.kt +++ b/src/main/kotlin/dev/usbharu/hideout/service/impl/UserService.kt @@ -2,17 +2,23 @@ package dev.usbharu.hideout.service.impl import dev.usbharu.hideout.config.Config import dev.usbharu.hideout.domain.model.hideout.dto.RemoteUserCreateDto +import dev.usbharu.hideout.domain.model.hideout.dto.SendFollowDto import dev.usbharu.hideout.domain.model.hideout.dto.UserCreateDto import dev.usbharu.hideout.domain.model.hideout.entity.User import dev.usbharu.hideout.exception.UserNotFoundException import dev.usbharu.hideout.repository.IUserRepository import dev.usbharu.hideout.service.IUserAuthService +import dev.usbharu.hideout.service.activitypub.ActivityPubSendFollowService import org.koin.core.annotation.Single import java.lang.Integer.min import java.time.Instant @Single -class UserService(private val userRepository: IUserRepository, private val userAuthService: IUserAuthService) : +class UserService( + private val userRepository: IUserRepository, + private val userAuthService: IUserAuthService, + private val activityPubSendFollowService: ActivityPubSendFollowService +) : IUserService { private val maxLimit = 100 @@ -105,9 +111,19 @@ class UserService(private val userRepository: IUserRepository, private val userA } // TODO APのフォロー処理を作る - override suspend fun follow(id: Long, follower: Long): Boolean { - userRepository.createFollower(id, follower) - return false + override suspend fun follow(id: Long, followerId: Long): Boolean { + val user = userRepository.findById(id) ?: throw UserNotFoundException("$id was not found.") + val follower = userRepository.findById(followerId) ?: throw UserNotFoundException("$followerId was not found.") + if (follower.domain != Config.configData.domain) { + throw IllegalArgumentException("follower is not local user.") + } + return if (user.domain == Config.configData.domain) { + userRepository.createFollower(id, followerId) + true + } else { + activityPubSendFollowService.sendFollow(SendFollowDto(follower, user)) + false + } } override suspend fun unfollow(id: Long, follower: Long): Boolean { diff --git a/src/test/kotlin/dev/usbharu/hideout/service/impl/UserServiceTest.kt b/src/test/kotlin/dev/usbharu/hideout/service/impl/UserServiceTest.kt index deab1ce6..3b182e3b 100644 --- a/src/test/kotlin/dev/usbharu/hideout/service/impl/UserServiceTest.kt +++ b/src/test/kotlin/dev/usbharu/hideout/service/impl/UserServiceTest.kt @@ -29,7 +29,7 @@ class UserServiceTest { onBlocking { hash(anyString()) } doReturn "hashedPassword" onBlocking { generateKeyPair() } doReturn generateKeyPair } - val userService = UserService(userRepository, userAuthService) + val userService = UserService(userRepository, userAuthService, mock()) userService.createLocalUser(UserCreateDto("test", "testUser", "XXXXXXXXXXXXX", "test")) verify(userRepository, times(1)).save(any()) argumentCaptor { @@ -55,7 +55,7 @@ class UserServiceTest { val userRepository = mock { onBlocking { nextId() } doReturn 113345L } - val userService = UserService(userRepository, mock()) + val userService = UserService(userRepository, mock(), mock()) val user = RemoteUserCreateDto( "test", "example.com",