From e4eaef7277cf9d95bdedb45b963557f4e9a678c9 Mon Sep 17 00:00:00 2001 From: usbharu <64310155+usbharu@users.noreply.github.com> Date: Tue, 21 Nov 2023 17:58:13 +0900 Subject: [PATCH 1/4] =?UTF-8?q?feat:=20inbox=E3=82=92=E3=82=B8=E3=83=A7?= =?UTF-8?q?=E3=83=96=E3=82=AD=E3=83=A5=E3=83=BC=E3=81=AB=E8=BC=89=E3=81=9B?= =?UTF-8?q?=E3=81=9F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../activitypub/service/common/APService.kt | 26 +++++------- .../service/common/ApJobServiceImpl.kt | 40 ++++++++++++++++++- .../hideout/core/external/job/HideoutJob.kt | 6 +++ 3 files changed, 54 insertions(+), 18 deletions(-) diff --git a/src/main/kotlin/dev/usbharu/hideout/activitypub/service/common/APService.kt b/src/main/kotlin/dev/usbharu/hideout/activitypub/service/common/APService.kt index c7df1df2..78c2a52a 100644 --- a/src/main/kotlin/dev/usbharu/hideout/activitypub/service/common/APService.kt +++ b/src/main/kotlin/dev/usbharu/hideout/activitypub/service/common/APService.kt @@ -2,16 +2,17 @@ package dev.usbharu.hideout.activitypub.service.common import com.fasterxml.jackson.databind.JsonNode import com.fasterxml.jackson.databind.ObjectMapper -import com.fasterxml.jackson.module.kotlin.readValue import dev.usbharu.hideout.activitypub.domain.exception.JsonParseException -import dev.usbharu.hideout.activitypub.domain.model.Follow import dev.usbharu.hideout.activitypub.interfaces.api.common.ActivityPubResponse +import dev.usbharu.hideout.activitypub.interfaces.api.common.ActivityPubStringResponse import dev.usbharu.hideout.activitypub.service.activity.accept.APAcceptService import dev.usbharu.hideout.activitypub.service.activity.create.APCreateService import dev.usbharu.hideout.activitypub.service.activity.delete.APReceiveDeleteService import dev.usbharu.hideout.activitypub.service.activity.follow.APReceiveFollowService import dev.usbharu.hideout.activitypub.service.activity.like.APLikeService import dev.usbharu.hideout.activitypub.service.activity.undo.APUndoService +import dev.usbharu.hideout.core.external.job.InboxJob +import dev.usbharu.hideout.core.service.job.JobQueueParentService import org.slf4j.Logger import org.slf4j.LoggerFactory import org.springframework.beans.factory.annotation.Qualifier @@ -182,7 +183,8 @@ class APServiceImpl( private val apCreateService: APCreateService, private val apLikeService: APLikeService, private val apReceiveDeleteService: APReceiveDeleteService, - @Qualifier("activitypub") private val objectMapper: ObjectMapper + @Qualifier("activitypub") private val objectMapper: ObjectMapper, + private val jobQueueParentService: JobQueueParentService ) : APService { val logger: Logger = LoggerFactory.getLogger(APServiceImpl::class.java) @@ -227,20 +229,10 @@ class APServiceImpl( @Suppress("CyclomaticComplexMethod", "NotImplementedDeclaration") override suspend fun processActivity(json: String, type: ActivityType): ActivityPubResponse { logger.debug("process activity: {}", type) - return when (type) { - ActivityType.Accept -> apAcceptService.receiveAccept(objectMapper.readValue(json)) - ActivityType.Follow -> - apReceiveFollowService - .receiveFollow(objectMapper.readValue(json, Follow::class.java)) - - ActivityType.Create -> apCreateService.receiveCreate(objectMapper.readValue(json)) - ActivityType.Like -> apLikeService.receiveLike(objectMapper.readValue(json)) - ActivityType.Undo -> apUndoService.receiveUndo(objectMapper.readValue(json)) - ActivityType.Delete -> apReceiveDeleteService.receiveDelete(objectMapper.readValue(json)) - - else -> { - throw IllegalArgumentException("$type is not supported.") - } + jobQueueParentService.schedule(InboxJob) { + props[it.json] = json + props[it.type] = type.name } + return ActivityPubStringResponse(message = "") } } diff --git a/src/main/kotlin/dev/usbharu/hideout/activitypub/service/common/ApJobServiceImpl.kt b/src/main/kotlin/dev/usbharu/hideout/activitypub/service/common/ApJobServiceImpl.kt index 7057ccc5..13d23f57 100644 --- a/src/main/kotlin/dev/usbharu/hideout/activitypub/service/common/ApJobServiceImpl.kt +++ b/src/main/kotlin/dev/usbharu/hideout/activitypub/service/common/ApJobServiceImpl.kt @@ -1,19 +1,37 @@ package dev.usbharu.hideout.activitypub.service.common +import com.fasterxml.jackson.databind.ObjectMapper +import com.fasterxml.jackson.module.kotlin.readValue +import dev.usbharu.hideout.activitypub.domain.model.Follow +import dev.usbharu.hideout.activitypub.service.activity.accept.APAcceptServiceImpl +import dev.usbharu.hideout.activitypub.service.activity.create.APCreateServiceImpl +import dev.usbharu.hideout.activitypub.service.activity.delete.APReceiveDeleteServiceImpl import dev.usbharu.hideout.activitypub.service.activity.follow.APReceiveFollowJobService +import dev.usbharu.hideout.activitypub.service.activity.follow.APReceiveFollowServiceImpl +import dev.usbharu.hideout.activitypub.service.activity.like.APLikeServiceImpl import dev.usbharu.hideout.activitypub.service.activity.like.ApReactionJobService +import dev.usbharu.hideout.activitypub.service.activity.undo.APUndoServiceImpl import dev.usbharu.hideout.activitypub.service.objects.note.ApNoteJobService import dev.usbharu.hideout.core.external.job.* + import kjob.core.dsl.JobContextWithProps import kjob.core.job.JobProps import org.slf4j.LoggerFactory +import org.springframework.beans.factory.annotation.Qualifier import org.springframework.stereotype.Service @Service class ApJobServiceImpl( private val apReceiveFollowJobService: APReceiveFollowJobService, private val apNoteJobService: ApNoteJobService, - private val apReactionJobService: ApReactionJobService + private val apReactionJobService: ApReactionJobService, + private val APAcceptServiceImpl: APAcceptServiceImpl, + private val APReceiveFollowServiceImpl: APReceiveFollowServiceImpl, + private val APCreateServiceImpl: APCreateServiceImpl, + private val APLikeServiceImpl: APLikeServiceImpl, + private val APUndoServiceImpl: APUndoServiceImpl, + private val APReceiveDeleteServiceImpl: APReceiveDeleteServiceImpl, + @Qualifier("activitypub") private val objectMapper: ObjectMapper ) : ApJobService { @Suppress("REDUNDANT_ELSE_IN_WHEN") override suspend fun processActivity(job: JobContextWithProps, hideoutJob: HideoutJob) { @@ -22,6 +40,26 @@ class ApJobServiceImpl( @Suppress("ElseCaseInsteadOfExhaustiveWhen") // Springで作成されるプロキシの都合上パターンマッチングが壊れるので必須 when (hideoutJob) { + is InboxJob -> { + val typeString = (job.props as JobProps)[InboxJob.type] + val json = (job.props as JobProps)[InboxJob.json] + val type = ActivityType.valueOf(typeString) + when (type) { + ActivityType.Accept -> APAcceptServiceImpl.receiveAccept(objectMapper.readValue(json)) + ActivityType.Follow -> + APReceiveFollowServiceImpl + .receiveFollow(objectMapper.readValue(json, Follow::class.java)) + + ActivityType.Create -> APCreateServiceImpl.receiveCreate(objectMapper.readValue(json)) + ActivityType.Like -> APLikeServiceImpl.receiveLike(objectMapper.readValue(json)) + ActivityType.Undo -> APUndoServiceImpl.receiveUndo(objectMapper.readValue(json)) + ActivityType.Delete -> APReceiveDeleteServiceImpl.receiveDelete(objectMapper.readValue(json)) + + else -> { + throw IllegalArgumentException("$type is not supported.") + } + } + } is ReceiveFollowJob -> { apReceiveFollowJobService.receiveFollowJob( job.props as JobProps diff --git a/src/main/kotlin/dev/usbharu/hideout/core/external/job/HideoutJob.kt b/src/main/kotlin/dev/usbharu/hideout/core/external/job/HideoutJob.kt index 62f989d0..94fa81da 100644 --- a/src/main/kotlin/dev/usbharu/hideout/core/external/job/HideoutJob.kt +++ b/src/main/kotlin/dev/usbharu/hideout/core/external/job/HideoutJob.kt @@ -36,3 +36,9 @@ object DeliverRemoveReactionJob : HideoutJob("DeliverRemoveReactionJob") { val actor: Prop = string("actor") val like: Prop = string("like") } + +@Component +object InboxJob : HideoutJob("InboxJob") { + val json = string("json") + val type = string("type") +} From 65b37cbb5e85c7dfa0c85ec9fc6e0411cbefbb29 Mon Sep 17 00:00:00 2001 From: usbharu <64310155+usbharu@users.noreply.github.com> Date: Tue, 21 Nov 2023 18:00:53 +0900 Subject: [PATCH 2/4] =?UTF-8?q?refactor:=20=E4=B8=8D=E8=A6=81=E3=81=AA?= =?UTF-8?q?=E4=BE=9D=E5=AD=98=E9=96=A2=E4=BF=82=E3=82=92=E5=89=8A=E9=99=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../hideout/activitypub/service/common/APService.kt | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/src/main/kotlin/dev/usbharu/hideout/activitypub/service/common/APService.kt b/src/main/kotlin/dev/usbharu/hideout/activitypub/service/common/APService.kt index 78c2a52a..2db01861 100644 --- a/src/main/kotlin/dev/usbharu/hideout/activitypub/service/common/APService.kt +++ b/src/main/kotlin/dev/usbharu/hideout/activitypub/service/common/APService.kt @@ -5,12 +5,6 @@ import com.fasterxml.jackson.databind.ObjectMapper import dev.usbharu.hideout.activitypub.domain.exception.JsonParseException import dev.usbharu.hideout.activitypub.interfaces.api.common.ActivityPubResponse import dev.usbharu.hideout.activitypub.interfaces.api.common.ActivityPubStringResponse -import dev.usbharu.hideout.activitypub.service.activity.accept.APAcceptService -import dev.usbharu.hideout.activitypub.service.activity.create.APCreateService -import dev.usbharu.hideout.activitypub.service.activity.delete.APReceiveDeleteService -import dev.usbharu.hideout.activitypub.service.activity.follow.APReceiveFollowService -import dev.usbharu.hideout.activitypub.service.activity.like.APLikeService -import dev.usbharu.hideout.activitypub.service.activity.undo.APUndoService import dev.usbharu.hideout.core.external.job.InboxJob import dev.usbharu.hideout.core.service.job.JobQueueParentService import org.slf4j.Logger @@ -177,12 +171,6 @@ enum class ExtendedVocabulary { @Service class APServiceImpl( - private val apReceiveFollowService: APReceiveFollowService, - private val apUndoService: APUndoService, - private val apAcceptService: APAcceptService, - private val apCreateService: APCreateService, - private val apLikeService: APLikeService, - private val apReceiveDeleteService: APReceiveDeleteService, @Qualifier("activitypub") private val objectMapper: ObjectMapper, private val jobQueueParentService: JobQueueParentService ) : APService { From 986d16f442a41921123a7eb9bdeb8fed5fdb7712 Mon Sep 17 00:00:00 2001 From: usbharu <64310155+usbharu@users.noreply.github.com> Date: Wed, 22 Nov 2023 00:07:38 +0900 Subject: [PATCH 3/4] =?UTF-8?q?feat:=20=E3=82=B8=E3=83=A7=E3=83=96?= =?UTF-8?q?=E3=82=AD=E3=83=A5=E3=83=BC=E3=81=A7HTTP=20Signature=E3=81=AE?= =?UTF-8?q?=E6=A4=9C=E8=A8=BC=E3=82=92=E8=A1=8C=E3=81=86=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 --- .../api/inbox/InboxControllerImpl.kt | 38 ++++++++++++++++- .../activitypub/service/common/APService.kt | 19 ++++++++- .../service/common/ApJobServiceImpl.kt | 42 ++++++++++++++++++- .../application/config/HttpSignatureConfig.kt | 20 +++++++++ .../hideout/core/external/job/HideoutJob.kt | 2 + 5 files changed, 115 insertions(+), 6 deletions(-) create mode 100644 src/main/kotlin/dev/usbharu/hideout/application/config/HttpSignatureConfig.kt diff --git a/src/main/kotlin/dev/usbharu/hideout/activitypub/interfaces/api/inbox/InboxControllerImpl.kt b/src/main/kotlin/dev/usbharu/hideout/activitypub/interfaces/api/inbox/InboxControllerImpl.kt index 04f1d6f3..fc8acf7f 100644 --- a/src/main/kotlin/dev/usbharu/hideout/activitypub/interfaces/api/inbox/InboxControllerImpl.kt +++ b/src/main/kotlin/dev/usbharu/hideout/activitypub/interfaces/api/inbox/InboxControllerImpl.kt @@ -1,16 +1,28 @@ package dev.usbharu.hideout.activitypub.interfaces.api.inbox import dev.usbharu.hideout.activitypub.service.common.APService +import dev.usbharu.httpsignature.common.HttpHeaders +import dev.usbharu.httpsignature.common.HttpMethod +import dev.usbharu.httpsignature.common.HttpRequest import org.slf4j.LoggerFactory import org.springframework.http.HttpStatus import org.springframework.http.ResponseEntity import org.springframework.web.bind.annotation.RequestBody import org.springframework.web.bind.annotation.RestController +import org.springframework.web.context.request.RequestContextHolder +import org.springframework.web.context.request.ServletRequestAttributes +import java.net.URL + @RestController class InboxControllerImpl(private val apService: APService) : InboxController { @Suppress("TooGenericExceptionCaught") - override suspend fun inbox(@RequestBody string: String): ResponseEntity { + override suspend fun inbox( + @RequestBody string: String + ): ResponseEntity { + + val request = (requireNotNull(RequestContextHolder.getRequestAttributes()) as ServletRequestAttributes).request + val parseActivity = try { apService.parseActivity(string) } catch (e: Exception) { @@ -19,7 +31,29 @@ class InboxControllerImpl(private val apService: APService) : InboxController { } LOGGER.info("INBOX Processing Activity Type: {}", parseActivity) try { - apService.processActivity(string, parseActivity) + val url = request.requestURL.toString() + + val headersList = request.headerNames?.toList().orEmpty() + val headers = + headersList.associateWith { header -> request.getHeaders(header)?.toList().orEmpty() } + + val method = when (val method = request.method.lowercase()) { + "get" -> HttpMethod.GET + "post" -> HttpMethod.POST + else -> { + throw IllegalArgumentException("Unsupported method: $method") + } + } + + println(headers) + + apService.processActivity( + string, parseActivity, HttpRequest( + URL(url + request.queryString.orEmpty()), + HttpHeaders(headers), + method + ), headers + ) } catch (e: Exception) { LOGGER.warn("FAILED Process Activity $parseActivity", e) return ResponseEntity(HttpStatus.ACCEPTED) diff --git a/src/main/kotlin/dev/usbharu/hideout/activitypub/service/common/APService.kt b/src/main/kotlin/dev/usbharu/hideout/activitypub/service/common/APService.kt index 2db01861..e6e10495 100644 --- a/src/main/kotlin/dev/usbharu/hideout/activitypub/service/common/APService.kt +++ b/src/main/kotlin/dev/usbharu/hideout/activitypub/service/common/APService.kt @@ -7,6 +7,7 @@ import dev.usbharu.hideout.activitypub.interfaces.api.common.ActivityPubResponse import dev.usbharu.hideout.activitypub.interfaces.api.common.ActivityPubStringResponse import dev.usbharu.hideout.core.external.job.InboxJob import dev.usbharu.hideout.core.service.job.JobQueueParentService +import dev.usbharu.httpsignature.common.HttpRequest import org.slf4j.Logger import org.slf4j.LoggerFactory import org.springframework.beans.factory.annotation.Qualifier @@ -15,7 +16,12 @@ import org.springframework.stereotype.Service interface APService { fun parseActivity(json: String): ActivityType - suspend fun processActivity(json: String, type: ActivityType): ActivityPubResponse? + suspend fun processActivity( + json: String, + type: ActivityType, + httpRequest: HttpRequest, + map: Map> + ): ActivityPubResponse? } enum class ActivityType { @@ -215,11 +221,20 @@ class APServiceImpl( } @Suppress("CyclomaticComplexMethod", "NotImplementedDeclaration") - override suspend fun processActivity(json: String, type: ActivityType): ActivityPubResponse { + override suspend fun processActivity( + json: String, + type: ActivityType, + httpRequest: HttpRequest, + map: Map> + ): ActivityPubResponse { logger.debug("process activity: {}", type) jobQueueParentService.schedule(InboxJob) { props[it.json] = json props[it.type] = type.name + val writeValueAsString = objectMapper.writeValueAsString(httpRequest) + println(writeValueAsString) + props[it.httpRequest] = writeValueAsString + props[it.headers] = objectMapper.writeValueAsString(map) } return ActivityPubStringResponse(message = "") } diff --git a/src/main/kotlin/dev/usbharu/hideout/activitypub/service/common/ApJobServiceImpl.kt b/src/main/kotlin/dev/usbharu/hideout/activitypub/service/common/ApJobServiceImpl.kt index 13d23f57..0020fbd0 100644 --- a/src/main/kotlin/dev/usbharu/hideout/activitypub/service/common/ApJobServiceImpl.kt +++ b/src/main/kotlin/dev/usbharu/hideout/activitypub/service/common/ApJobServiceImpl.kt @@ -12,8 +12,17 @@ import dev.usbharu.hideout.activitypub.service.activity.like.APLikeServiceImpl import dev.usbharu.hideout.activitypub.service.activity.like.ApReactionJobService import dev.usbharu.hideout.activitypub.service.activity.undo.APUndoServiceImpl import dev.usbharu.hideout.activitypub.service.objects.note.ApNoteJobService +import dev.usbharu.hideout.activitypub.service.objects.user.APUserService +import dev.usbharu.hideout.application.external.Transaction +import dev.usbharu.hideout.core.domain.exception.FailedToGetResourcesException import dev.usbharu.hideout.core.external.job.* - +import dev.usbharu.hideout.core.query.UserQueryService +import dev.usbharu.hideout.util.RsaUtil +import dev.usbharu.httpsignature.common.HttpHeaders +import dev.usbharu.httpsignature.common.HttpRequest +import dev.usbharu.httpsignature.common.PublicKey +import dev.usbharu.httpsignature.verify.DefaultSignatureHeaderParser +import dev.usbharu.httpsignature.verify.RsaSha256HttpSignatureVerifier import kjob.core.dsl.JobContextWithProps import kjob.core.job.JobProps import org.slf4j.LoggerFactory @@ -31,7 +40,12 @@ class ApJobServiceImpl( private val APLikeServiceImpl: APLikeServiceImpl, private val APUndoServiceImpl: APUndoServiceImpl, private val APReceiveDeleteServiceImpl: APReceiveDeleteServiceImpl, - @Qualifier("activitypub") private val objectMapper: ObjectMapper + @Qualifier("activitypub") private val objectMapper: ObjectMapper, + private val httpSignatureVerifier: RsaSha256HttpSignatureVerifier, + private val signatureHeaderParser: DefaultSignatureHeaderParser, + private val apUserService: APUserService, + private val userQueryService: UserQueryService, + private val transaction: Transaction ) : ApJobService { @Suppress("REDUNDANT_ELSE_IN_WHEN") override suspend fun processActivity(job: JobContextWithProps, hideoutJob: HideoutJob) { @@ -41,6 +55,29 @@ class ApJobServiceImpl( // Springで作成されるプロキシの都合上パターンマッチングが壊れるので必須 when (hideoutJob) { is InboxJob -> { + val httpRequestString = (job.props as JobProps)[InboxJob.httpRequest] + println(httpRequestString) + val headerString = (job.props as JobProps)[InboxJob.headers] + + val readValue = objectMapper.readValue>>(headerString) + + val httpRequest = + objectMapper.readValue(httpRequestString).copy(headers = HttpHeaders(readValue)) + val signature = signatureHeaderParser.parse(httpRequest.headers) + + val publicKey = transaction.transaction { + try { + userQueryService.findByKeyId(signature.keyId) + } catch (e: FailedToGetResourcesException) { + apUserService.fetchPersonWithEntity(signature.keyId).second + }.publicKey + } + + httpSignatureVerifier.verify( + httpRequest, + PublicKey(RsaUtil.decodeRsaPublicKeyPem(publicKey), signature.keyId) + ) + val typeString = (job.props as JobProps)[InboxJob.type] val json = (job.props as JobProps)[InboxJob.json] val type = ActivityType.valueOf(typeString) @@ -60,6 +97,7 @@ class ApJobServiceImpl( } } } + is ReceiveFollowJob -> { apReceiveFollowJobService.receiveFollowJob( job.props as JobProps diff --git a/src/main/kotlin/dev/usbharu/hideout/application/config/HttpSignatureConfig.kt b/src/main/kotlin/dev/usbharu/hideout/application/config/HttpSignatureConfig.kt new file mode 100644 index 00000000..ee3bc409 --- /dev/null +++ b/src/main/kotlin/dev/usbharu/hideout/application/config/HttpSignatureConfig.kt @@ -0,0 +1,20 @@ +package dev.usbharu.hideout.application.config + +import dev.usbharu.httpsignature.sign.RsaSha256HttpSignatureSigner +import dev.usbharu.httpsignature.verify.DefaultSignatureHeaderParser +import dev.usbharu.httpsignature.verify.RsaSha256HttpSignatureVerifier +import dev.usbharu.httpsignature.verify.SignatureHeaderParser +import org.springframework.context.annotation.Bean +import org.springframework.context.annotation.Configuration + +@Configuration +class HttpSignatureConfig { + @Bean + fun defaultSignatureHeaderParser(): DefaultSignatureHeaderParser = DefaultSignatureHeaderParser() + + @Bean + fun rsaSha256HttpSignatureVerifier( + signatureHeaderParser: SignatureHeaderParser, + signatureSigner: RsaSha256HttpSignatureSigner + ): RsaSha256HttpSignatureVerifier = RsaSha256HttpSignatureVerifier(signatureHeaderParser, signatureSigner) +} diff --git a/src/main/kotlin/dev/usbharu/hideout/core/external/job/HideoutJob.kt b/src/main/kotlin/dev/usbharu/hideout/core/external/job/HideoutJob.kt index 94fa81da..238b809f 100644 --- a/src/main/kotlin/dev/usbharu/hideout/core/external/job/HideoutJob.kt +++ b/src/main/kotlin/dev/usbharu/hideout/core/external/job/HideoutJob.kt @@ -41,4 +41,6 @@ object DeliverRemoveReactionJob : HideoutJob("DeliverRemoveReactionJob") { object InboxJob : HideoutJob("InboxJob") { val json = string("json") val type = string("type") + val httpRequest = string("http_request") + val headers = string("headers") } From cedebb794b98b25e1c79da69e09c83b839ce2a40 Mon Sep 17 00:00:00 2001 From: usbharu <64310155+usbharu@users.noreply.github.com> Date: Wed, 22 Nov 2023 00:27:44 +0900 Subject: [PATCH 4/4] =?UTF-8?q?refactor:=20ActivityPubStringResponse?= =?UTF-8?q?=E3=82=92=E5=89=8A=E9=99=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../api/common/ActivityPubStringResponse.kt | 68 ------------------- .../activity/accept/APAcceptService.kt | 11 ++- .../activity/create/APCreateService.kt | 8 +-- .../activity/delete/APReceiveDeleteService.kt | 3 +- .../delete/APReceiveDeleteServiceImpl.kt | 9 +-- .../activity/follow/APReceiveFollowService.kt | 9 +-- .../service/activity/like/APLikeService.kt | 9 +-- .../service/activity/undo/APUndoService.kt | 15 ++-- .../activitypub/service/common/APService.kt | 8 +-- .../api/inbox/InboxControllerImplTest.kt | 1 - .../accept/APAcceptServiceImplTest.kt | 1 - .../create/APCreateServiceImplTest.kt | 1 - .../activity/like/APLikeServiceImplTest.kt | 1 - .../activity/undo/APUndoServiceImplTest.kt | 1 - 14 files changed, 25 insertions(+), 120 deletions(-) delete mode 100644 src/main/kotlin/dev/usbharu/hideout/activitypub/interfaces/api/common/ActivityPubStringResponse.kt diff --git a/src/main/kotlin/dev/usbharu/hideout/activitypub/interfaces/api/common/ActivityPubStringResponse.kt b/src/main/kotlin/dev/usbharu/hideout/activitypub/interfaces/api/common/ActivityPubStringResponse.kt deleted file mode 100644 index 60b58404..00000000 --- a/src/main/kotlin/dev/usbharu/hideout/activitypub/interfaces/api/common/ActivityPubStringResponse.kt +++ /dev/null @@ -1,68 +0,0 @@ -package dev.usbharu.hideout.activitypub.interfaces.api.common - -import dev.usbharu.hideout.activitypub.domain.model.JsonLd -import dev.usbharu.hideout.util.HttpUtil.Activity -import io.ktor.http.* - -sealed class ActivityPubResponse( - val httpStatusCode: HttpStatusCode, - val contentType: ContentType = ContentType.Application.Activity -) { - - override fun equals(other: Any?): Boolean { - if (this === other) return true - if (other !is ActivityPubResponse) return false - - if (httpStatusCode != other.httpStatusCode) return false - if (contentType != other.contentType) return false - - return true - } - - override fun hashCode(): Int { - var result = httpStatusCode.hashCode() - result = 31 * result + contentType.hashCode() - return result - } - - override fun toString(): String = "ActivityPubResponse(httpStatusCode=$httpStatusCode, contentType=$contentType)" -} - -class ActivityPubStringResponse( - httpStatusCode: HttpStatusCode = HttpStatusCode.OK, - val message: String, - contentType: ContentType = ContentType.Application.Activity -) : ActivityPubResponse(httpStatusCode, contentType) { - - override fun equals(other: Any?): Boolean { - if (this === other) return true - if (other !is ActivityPubStringResponse) return false - - if (message != other.message) return false - - return true - } - - override fun hashCode(): Int = message.hashCode() - - override fun toString(): String = "ActivityPubStringResponse(message='$message') ${super.toString()}" -} - -class ActivityPubObjectResponse( - httpStatusCode: HttpStatusCode = HttpStatusCode.OK, - val message: JsonLd, - contentType: ContentType = ContentType.Application.Activity -) : ActivityPubResponse(httpStatusCode, contentType) { - override fun equals(other: Any?): Boolean { - if (this === other) return true - if (other !is ActivityPubObjectResponse) return false - - if (message != other.message) return false - - return true - } - - override fun hashCode(): Int = message.hashCode() - - override fun toString(): String = "ActivityPubObjectResponse(message=$message) ${super.toString()}" -} diff --git a/src/main/kotlin/dev/usbharu/hideout/activitypub/service/activity/accept/APAcceptService.kt b/src/main/kotlin/dev/usbharu/hideout/activitypub/service/activity/accept/APAcceptService.kt index 72c3f8c3..2e845715 100644 --- a/src/main/kotlin/dev/usbharu/hideout/activitypub/service/activity/accept/APAcceptService.kt +++ b/src/main/kotlin/dev/usbharu/hideout/activitypub/service/activity/accept/APAcceptService.kt @@ -3,18 +3,15 @@ package dev.usbharu.hideout.activitypub.service.activity.accept import dev.usbharu.hideout.activitypub.domain.exception.IllegalActivityPubObjectException import dev.usbharu.hideout.activitypub.domain.model.Accept import dev.usbharu.hideout.activitypub.domain.model.Follow -import dev.usbharu.hideout.activitypub.interfaces.api.common.ActivityPubResponse -import dev.usbharu.hideout.activitypub.interfaces.api.common.ActivityPubStringResponse import dev.usbharu.hideout.application.external.Transaction import dev.usbharu.hideout.core.query.FollowerQueryService import dev.usbharu.hideout.core.query.UserQueryService import dev.usbharu.hideout.core.service.user.UserService -import io.ktor.http.* import org.slf4j.LoggerFactory import org.springframework.stereotype.Service interface APAcceptService { - suspend fun receiveAccept(accept: Accept): ActivityPubResponse + suspend fun receiveAccept(accept: Accept) } @Service @@ -24,7 +21,7 @@ class APAcceptServiceImpl( private val followerQueryService: FollowerQueryService, private val transaction: Transaction ) : APAcceptService { - override suspend fun receiveAccept(accept: Accept): ActivityPubResponse { + override suspend fun receiveAccept(accept: Accept) { return transaction.transaction { LOGGER.debug("START Follow") LOGGER.trace("{}", accept) @@ -43,11 +40,11 @@ class APAcceptServiceImpl( if (followerQueryService.alreadyFollow(user.id, follower.id)) { LOGGER.debug("END User already follow from ${follower.url} to ${user.url}") - return@transaction ActivityPubStringResponse(HttpStatusCode.OK, "accepted") + return@transaction } userService.follow(user.id, follower.id) LOGGER.debug("SUCCESS Follow from ${follower.url} to ${user.url}.") - ActivityPubStringResponse(HttpStatusCode.OK, "accepted") + } } diff --git a/src/main/kotlin/dev/usbharu/hideout/activitypub/service/activity/create/APCreateService.kt b/src/main/kotlin/dev/usbharu/hideout/activitypub/service/activity/create/APCreateService.kt index e0d179ea..afcf4881 100644 --- a/src/main/kotlin/dev/usbharu/hideout/activitypub/service/activity/create/APCreateService.kt +++ b/src/main/kotlin/dev/usbharu/hideout/activitypub/service/activity/create/APCreateService.kt @@ -3,16 +3,13 @@ package dev.usbharu.hideout.activitypub.service.activity.create import dev.usbharu.hideout.activitypub.domain.exception.IllegalActivityPubObjectException import dev.usbharu.hideout.activitypub.domain.model.Create import dev.usbharu.hideout.activitypub.domain.model.Note -import dev.usbharu.hideout.activitypub.interfaces.api.common.ActivityPubResponse -import dev.usbharu.hideout.activitypub.interfaces.api.common.ActivityPubStringResponse import dev.usbharu.hideout.activitypub.service.objects.note.APNoteService import dev.usbharu.hideout.application.external.Transaction -import io.ktor.http.* import org.slf4j.LoggerFactory import org.springframework.stereotype.Service interface APCreateService { - suspend fun receiveCreate(create: Create): ActivityPubResponse + suspend fun receiveCreate(create: Create) } @Service @@ -20,7 +17,7 @@ class APCreateServiceImpl( private val apNoteService: APNoteService, private val transaction: Transaction ) : APCreateService { - override suspend fun receiveCreate(create: Create): ActivityPubResponse { + override suspend fun receiveCreate(create: Create) { LOGGER.debug("START Create new remote note.") LOGGER.trace("{}", create) @@ -34,7 +31,6 @@ class APCreateServiceImpl( val note = value as Note apNoteService.fetchNote(note) LOGGER.debug("SUCCESS Create new remote note. ${note.id} by ${note.attributedTo}") - ActivityPubStringResponse(HttpStatusCode.OK, "Created") } } diff --git a/src/main/kotlin/dev/usbharu/hideout/activitypub/service/activity/delete/APReceiveDeleteService.kt b/src/main/kotlin/dev/usbharu/hideout/activitypub/service/activity/delete/APReceiveDeleteService.kt index 9d047605..68505f22 100644 --- a/src/main/kotlin/dev/usbharu/hideout/activitypub/service/activity/delete/APReceiveDeleteService.kt +++ b/src/main/kotlin/dev/usbharu/hideout/activitypub/service/activity/delete/APReceiveDeleteService.kt @@ -1,8 +1,7 @@ package dev.usbharu.hideout.activitypub.service.activity.delete import dev.usbharu.hideout.activitypub.domain.model.Delete -import dev.usbharu.hideout.activitypub.interfaces.api.common.ActivityPubResponse interface APReceiveDeleteService { - suspend fun receiveDelete(delete: Delete): ActivityPubResponse + suspend fun receiveDelete(delete: Delete) } diff --git a/src/main/kotlin/dev/usbharu/hideout/activitypub/service/activity/delete/APReceiveDeleteServiceImpl.kt b/src/main/kotlin/dev/usbharu/hideout/activitypub/service/activity/delete/APReceiveDeleteServiceImpl.kt index c00aeda6..e75fa90c 100644 --- a/src/main/kotlin/dev/usbharu/hideout/activitypub/service/activity/delete/APReceiveDeleteServiceImpl.kt +++ b/src/main/kotlin/dev/usbharu/hideout/activitypub/service/activity/delete/APReceiveDeleteServiceImpl.kt @@ -2,13 +2,10 @@ package dev.usbharu.hideout.activitypub.service.activity.delete import dev.usbharu.hideout.activitypub.domain.exception.IllegalActivityPubObjectException import dev.usbharu.hideout.activitypub.domain.model.Delete -import dev.usbharu.hideout.activitypub.interfaces.api.common.ActivityPubResponse -import dev.usbharu.hideout.activitypub.interfaces.api.common.ActivityPubStringResponse import dev.usbharu.hideout.application.external.Transaction import dev.usbharu.hideout.core.domain.exception.FailedToGetResourcesException import dev.usbharu.hideout.core.domain.model.post.PostRepository import dev.usbharu.hideout.core.query.PostQueryService -import io.ktor.http.* import org.springframework.stereotype.Service @Service @@ -17,15 +14,15 @@ class APReceiveDeleteServiceImpl( private val postRepository: PostRepository, private val transaction: Transaction ) : APReceiveDeleteService { - override suspend fun receiveDelete(delete: Delete): ActivityPubResponse = transaction.transaction { + override suspend fun receiveDelete(delete: Delete) = transaction.transaction { val deleteId = delete.`object`?.id ?: throw IllegalActivityPubObjectException("object.id is null") val post = try { postQueryService.findByApId(deleteId) } catch (_: FailedToGetResourcesException) { - return@transaction ActivityPubStringResponse(HttpStatusCode.OK, "Resource not found or already deleted") + return@transaction } postRepository.delete(post.id) - return@transaction ActivityPubStringResponse(HttpStatusCode.OK, "Resource was deleted.") + return@transaction } } diff --git a/src/main/kotlin/dev/usbharu/hideout/activitypub/service/activity/follow/APReceiveFollowService.kt b/src/main/kotlin/dev/usbharu/hideout/activitypub/service/activity/follow/APReceiveFollowService.kt index 95b47ad1..2011fce1 100644 --- a/src/main/kotlin/dev/usbharu/hideout/activitypub/service/activity/follow/APReceiveFollowService.kt +++ b/src/main/kotlin/dev/usbharu/hideout/activitypub/service/activity/follow/APReceiveFollowService.kt @@ -2,17 +2,14 @@ package dev.usbharu.hideout.activitypub.service.activity.follow import com.fasterxml.jackson.databind.ObjectMapper import dev.usbharu.hideout.activitypub.domain.model.Follow -import dev.usbharu.hideout.activitypub.interfaces.api.common.ActivityPubResponse -import dev.usbharu.hideout.activitypub.interfaces.api.common.ActivityPubStringResponse import dev.usbharu.hideout.core.external.job.ReceiveFollowJob import dev.usbharu.hideout.core.service.job.JobQueueParentService -import io.ktor.http.* import org.slf4j.LoggerFactory import org.springframework.beans.factory.annotation.Qualifier import org.springframework.stereotype.Service interface APReceiveFollowService { - suspend fun receiveFollow(follow: Follow): ActivityPubResponse + suspend fun receiveFollow(follow: Follow) } @Service @@ -20,14 +17,14 @@ class APReceiveFollowServiceImpl( private val jobQueueParentService: JobQueueParentService, @Qualifier("activitypub") private val objectMapper: ObjectMapper ) : APReceiveFollowService { - override suspend fun receiveFollow(follow: Follow): ActivityPubResponse { + override suspend fun receiveFollow(follow: Follow) { logger.info("FOLLOW from: {} to: {}", follow.actor, follow.`object`) jobQueueParentService.schedule(ReceiveFollowJob) { props[ReceiveFollowJob.actor] = follow.actor props[ReceiveFollowJob.follow] = objectMapper.writeValueAsString(follow) props[ReceiveFollowJob.targetActor] = follow.`object` } - return ActivityPubStringResponse(HttpStatusCode.OK, "{}", ContentType.Application.Json) + return } companion object { diff --git a/src/main/kotlin/dev/usbharu/hideout/activitypub/service/activity/like/APLikeService.kt b/src/main/kotlin/dev/usbharu/hideout/activitypub/service/activity/like/APLikeService.kt index c37af164..5b59550e 100644 --- a/src/main/kotlin/dev/usbharu/hideout/activitypub/service/activity/like/APLikeService.kt +++ b/src/main/kotlin/dev/usbharu/hideout/activitypub/service/activity/like/APLikeService.kt @@ -3,19 +3,16 @@ package dev.usbharu.hideout.activitypub.service.activity.like import dev.usbharu.hideout.activitypub.domain.exception.FailedToGetActivityPubResourceException import dev.usbharu.hideout.activitypub.domain.exception.IllegalActivityPubObjectException import dev.usbharu.hideout.activitypub.domain.model.Like -import dev.usbharu.hideout.activitypub.interfaces.api.common.ActivityPubResponse -import dev.usbharu.hideout.activitypub.interfaces.api.common.ActivityPubStringResponse import dev.usbharu.hideout.activitypub.service.objects.note.APNoteService import dev.usbharu.hideout.activitypub.service.objects.user.APUserService import dev.usbharu.hideout.application.external.Transaction import dev.usbharu.hideout.core.query.PostQueryService import dev.usbharu.hideout.core.service.reaction.ReactionService -import io.ktor.http.* import org.slf4j.LoggerFactory import org.springframework.stereotype.Service interface APLikeService { - suspend fun receiveLike(like: Like): ActivityPubResponse + suspend fun receiveLike(like: Like) } @Service @@ -26,7 +23,7 @@ class APLikeServiceImpl( private val postQueryService: PostQueryService, private val transaction: Transaction ) : APLikeService { - override suspend fun receiveLike(like: Like): ActivityPubResponse { + override suspend fun receiveLike(like: Like) { LOGGER.debug("START Add Like") LOGGER.trace("{}", like) @@ -57,7 +54,7 @@ class APLikeServiceImpl( ) LOGGER.debug("SUCCESS Add Like($content) from ${person.second.url} to ${post.url}") } - return ActivityPubStringResponse(HttpStatusCode.OK, "") + return } companion object { diff --git a/src/main/kotlin/dev/usbharu/hideout/activitypub/service/activity/undo/APUndoService.kt b/src/main/kotlin/dev/usbharu/hideout/activitypub/service/activity/undo/APUndoService.kt index 372ff33c..e0348b6c 100644 --- a/src/main/kotlin/dev/usbharu/hideout/activitypub/service/activity/undo/APUndoService.kt +++ b/src/main/kotlin/dev/usbharu/hideout/activitypub/service/activity/undo/APUndoService.kt @@ -2,17 +2,14 @@ package dev.usbharu.hideout.activitypub.service.activity.undo import dev.usbharu.hideout.activitypub.domain.model.Follow import dev.usbharu.hideout.activitypub.domain.model.Undo -import dev.usbharu.hideout.activitypub.interfaces.api.common.ActivityPubResponse -import dev.usbharu.hideout.activitypub.interfaces.api.common.ActivityPubStringResponse import dev.usbharu.hideout.activitypub.service.objects.user.APUserService import dev.usbharu.hideout.application.external.Transaction import dev.usbharu.hideout.core.query.UserQueryService import dev.usbharu.hideout.core.service.user.UserService -import io.ktor.http.* import org.springframework.stereotype.Service interface APUndoService { - suspend fun receiveUndo(undo: Undo): ActivityPubResponse + suspend fun receiveUndo(undo: Undo) } @Service @@ -23,22 +20,22 @@ class APUndoServiceImpl( private val userQueryService: UserQueryService, private val transaction: Transaction ) : APUndoService { - override suspend fun receiveUndo(undo: Undo): ActivityPubResponse { + override suspend fun receiveUndo(undo: Undo) { if (undo.actor == null) { - return ActivityPubStringResponse(HttpStatusCode.BadRequest, "actor is null") + return } val type = undo.`object`?.type.orEmpty() .firstOrNull { it == "Block" || it == "Follow" || it == "Like" || it == "Announce" || it == "Accept" } - ?: return ActivityPubStringResponse(HttpStatusCode.BadRequest, "unknown type ${undo.`object`?.type}") + ?: return when (type) { "Follow" -> { val follow = undo.`object` as Follow if (follow.`object` == null) { - return ActivityPubStringResponse(HttpStatusCode.BadRequest, "object.object is null") + return } transaction.transaction { apUserService.fetchPerson(undo.actor!!, follow.`object`) @@ -46,7 +43,7 @@ class APUndoServiceImpl( val target = userQueryService.findByUrl(follow.`object`!!) userService.unfollow(target.id, follower.id) } - return ActivityPubStringResponse(HttpStatusCode.OK, "Accept") + return } else -> {} diff --git a/src/main/kotlin/dev/usbharu/hideout/activitypub/service/common/APService.kt b/src/main/kotlin/dev/usbharu/hideout/activitypub/service/common/APService.kt index e6e10495..e23ed018 100644 --- a/src/main/kotlin/dev/usbharu/hideout/activitypub/service/common/APService.kt +++ b/src/main/kotlin/dev/usbharu/hideout/activitypub/service/common/APService.kt @@ -3,8 +3,6 @@ package dev.usbharu.hideout.activitypub.service.common import com.fasterxml.jackson.databind.JsonNode import com.fasterxml.jackson.databind.ObjectMapper import dev.usbharu.hideout.activitypub.domain.exception.JsonParseException -import dev.usbharu.hideout.activitypub.interfaces.api.common.ActivityPubResponse -import dev.usbharu.hideout.activitypub.interfaces.api.common.ActivityPubStringResponse import dev.usbharu.hideout.core.external.job.InboxJob import dev.usbharu.hideout.core.service.job.JobQueueParentService import dev.usbharu.httpsignature.common.HttpRequest @@ -21,7 +19,7 @@ interface APService { type: ActivityType, httpRequest: HttpRequest, map: Map> - ): ActivityPubResponse? + ) } enum class ActivityType { @@ -226,7 +224,7 @@ class APServiceImpl( type: ActivityType, httpRequest: HttpRequest, map: Map> - ): ActivityPubResponse { + ) { logger.debug("process activity: {}", type) jobQueueParentService.schedule(InboxJob) { props[it.json] = json @@ -236,6 +234,6 @@ class APServiceImpl( props[it.httpRequest] = writeValueAsString props[it.headers] = objectMapper.writeValueAsString(map) } - return ActivityPubStringResponse(message = "") + return } } diff --git a/src/test/kotlin/dev/usbharu/hideout/activitypub/interfaces/api/inbox/InboxControllerImplTest.kt b/src/test/kotlin/dev/usbharu/hideout/activitypub/interfaces/api/inbox/InboxControllerImplTest.kt index a91e5b7f..1f2ee0a0 100644 --- a/src/test/kotlin/dev/usbharu/hideout/activitypub/interfaces/api/inbox/InboxControllerImplTest.kt +++ b/src/test/kotlin/dev/usbharu/hideout/activitypub/interfaces/api/inbox/InboxControllerImplTest.kt @@ -1,7 +1,6 @@ package dev.usbharu.hideout.activitypub.interfaces.api.inbox import dev.usbharu.hideout.activitypub.domain.exception.JsonParseException -import dev.usbharu.hideout.activitypub.interfaces.api.common.ActivityPubStringResponse import dev.usbharu.hideout.activitypub.service.common.APService import dev.usbharu.hideout.activitypub.service.common.ActivityType import dev.usbharu.hideout.core.domain.exception.FailedToGetResourcesException diff --git a/src/test/kotlin/dev/usbharu/hideout/activitypub/service/activity/accept/APAcceptServiceImplTest.kt b/src/test/kotlin/dev/usbharu/hideout/activitypub/service/activity/accept/APAcceptServiceImplTest.kt index 77b3f74d..8f5ab942 100644 --- a/src/test/kotlin/dev/usbharu/hideout/activitypub/service/activity/accept/APAcceptServiceImplTest.kt +++ b/src/test/kotlin/dev/usbharu/hideout/activitypub/service/activity/accept/APAcceptServiceImplTest.kt @@ -4,7 +4,6 @@ import dev.usbharu.hideout.activitypub.domain.exception.IllegalActivityPubObject import dev.usbharu.hideout.activitypub.domain.model.Accept import dev.usbharu.hideout.activitypub.domain.model.Follow import dev.usbharu.hideout.activitypub.domain.model.Like -import dev.usbharu.hideout.activitypub.interfaces.api.common.ActivityPubStringResponse import dev.usbharu.hideout.core.query.FollowerQueryService import dev.usbharu.hideout.core.query.UserQueryService import dev.usbharu.hideout.core.service.user.UserService diff --git a/src/test/kotlin/dev/usbharu/hideout/activitypub/service/activity/create/APCreateServiceImplTest.kt b/src/test/kotlin/dev/usbharu/hideout/activitypub/service/activity/create/APCreateServiceImplTest.kt index 87e66044..5eaff691 100644 --- a/src/test/kotlin/dev/usbharu/hideout/activitypub/service/activity/create/APCreateServiceImplTest.kt +++ b/src/test/kotlin/dev/usbharu/hideout/activitypub/service/activity/create/APCreateServiceImplTest.kt @@ -4,7 +4,6 @@ import dev.usbharu.hideout.activitypub.domain.exception.IllegalActivityPubObject import dev.usbharu.hideout.activitypub.domain.model.Create import dev.usbharu.hideout.activitypub.domain.model.Like import dev.usbharu.hideout.activitypub.domain.model.Note -import dev.usbharu.hideout.activitypub.interfaces.api.common.ActivityPubStringResponse import dev.usbharu.hideout.activitypub.service.objects.note.APNoteService import io.ktor.http.* import kotlinx.coroutines.test.runTest diff --git a/src/test/kotlin/dev/usbharu/hideout/activitypub/service/activity/like/APLikeServiceImplTest.kt b/src/test/kotlin/dev/usbharu/hideout/activitypub/service/activity/like/APLikeServiceImplTest.kt index 3b37fffc..0cb421f5 100644 --- a/src/test/kotlin/dev/usbharu/hideout/activitypub/service/activity/like/APLikeServiceImplTest.kt +++ b/src/test/kotlin/dev/usbharu/hideout/activitypub/service/activity/like/APLikeServiceImplTest.kt @@ -4,7 +4,6 @@ import dev.usbharu.hideout.activitypub.domain.exception.FailedToGetActivityPubRe import dev.usbharu.hideout.activitypub.domain.model.Like import dev.usbharu.hideout.activitypub.domain.model.Note import dev.usbharu.hideout.activitypub.domain.model.Person -import dev.usbharu.hideout.activitypub.interfaces.api.common.ActivityPubStringResponse import dev.usbharu.hideout.activitypub.service.objects.note.APNoteService import dev.usbharu.hideout.activitypub.service.objects.user.APUserService import dev.usbharu.hideout.core.query.PostQueryService diff --git a/src/test/kotlin/dev/usbharu/hideout/activitypub/service/activity/undo/APUndoServiceImplTest.kt b/src/test/kotlin/dev/usbharu/hideout/activitypub/service/activity/undo/APUndoServiceImplTest.kt index fb187aec..e465944e 100644 --- a/src/test/kotlin/dev/usbharu/hideout/activitypub/service/activity/undo/APUndoServiceImplTest.kt +++ b/src/test/kotlin/dev/usbharu/hideout/activitypub/service/activity/undo/APUndoServiceImplTest.kt @@ -2,7 +2,6 @@ package dev.usbharu.hideout.activitypub.service.activity.undo import dev.usbharu.hideout.activitypub.domain.model.Follow import dev.usbharu.hideout.activitypub.domain.model.Undo -import dev.usbharu.hideout.activitypub.interfaces.api.common.ActivityPubStringResponse import dev.usbharu.hideout.core.query.UserQueryService import io.ktor.http.* import kotlinx.coroutines.test.runTest