From d4157a3b386a4206e35a0e9b9cd41f831712b6b0 Mon Sep 17 00:00:00 2001 From: usbharu Date: Fri, 14 Feb 2025 17:48:39 +0900 Subject: [PATCH] =?UTF-8?q?feat:=20/users/:username=E3=81=AB=E3=82=A2?= =?UTF-8?q?=E3=82=AF=E3=82=BB=E3=82=B9=E3=81=99=E3=82=8B=E3=81=93=E3=81=A8?= =?UTF-8?q?=E3=81=A7Activity=E3=82=92=E5=BE=97=E3=82=89=E3=82=8C=E3=82=8B?= =?UTF-8?q?=E3=82=88=E3=81=86=E3=81=AB?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../actor/GetActorApplicationService.kt | 21 ++++++--- .../config/ActivityPubWebMvcConfigurer.kt | 16 +++++++ .../ActivityStreamHttpMessageConverter.kt | 45 +++++++++++++++++++ .../interface/api/APActorController.kt | 7 +-- .../hideout/core/config/SpringMvcConfig.kt | 4 +- .../model/support/principal/RemoteUser.kt | 6 +++ 6 files changed, 90 insertions(+), 9 deletions(-) create mode 100644 hideout/hideout-activitypub/src/main/kotlin/dev/usbharu/hideout/activitypub/config/ActivityPubWebMvcConfigurer.kt create mode 100644 hideout/hideout-activitypub/src/main/kotlin/dev/usbharu/hideout/activitypub/external/activitystreams/ActivityStreamHttpMessageConverter.kt create mode 100644 hideout/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/domain/model/support/principal/RemoteUser.kt diff --git a/hideout/hideout-activitypub/src/main/kotlin/dev/usbharu/hideout/activitypub/application/actor/GetActorApplicationService.kt b/hideout/hideout-activitypub/src/main/kotlin/dev/usbharu/hideout/activitypub/application/actor/GetActorApplicationService.kt index 1f2711f7..ba32b94c 100644 --- a/hideout/hideout-activitypub/src/main/kotlin/dev/usbharu/hideout/activitypub/application/actor/GetActorApplicationService.kt +++ b/hideout/hideout-activitypub/src/main/kotlin/dev/usbharu/hideout/activitypub/application/actor/GetActorApplicationService.kt @@ -1,19 +1,30 @@ package dev.usbharu.hideout.activitypub.application.actor +import dev.usbharu.activitystreamsserialization.other.JsonLd +import dev.usbharu.hideout.activitypub.external.activitystreams.ActorTranslator import dev.usbharu.hideout.core.application.shared.AbstractApplicationService import dev.usbharu.hideout.core.application.shared.Transaction -import dev.usbharu.hideout.core.domain.model.actor.Actor +import dev.usbharu.hideout.core.config.ApplicationConfig +import dev.usbharu.hideout.core.domain.model.actor.ActorRepository +import dev.usbharu.hideout.core.domain.model.support.domain.apHost import dev.usbharu.hideout.core.domain.model.support.principal.Principal import org.slf4j.LoggerFactory import org.springframework.stereotype.Service @Service -class GetActorApplicationService(transaction: Transaction) : AbstractApplicationService( +class GetActorApplicationService( + private val actorRepository: ActorRepository, + private val applicationConfig: ApplicationConfig, + private val actorTranslator: ActorTranslator, + transaction: Transaction, +) : AbstractApplicationService( transaction, - logger + logger, ) { - override suspend fun internalExecute(command: String, principal: Principal): Actor { - TODO() + override suspend fun internalExecute(command: String, principal: Principal): JsonLd { + val actor = actorRepository.findByNameAndDomain(command, applicationConfig.url.apHost) + ?: throw IllegalArgumentException("Actor $command not found") + return actorTranslator.translate(actor, null, null) } companion object { diff --git a/hideout/hideout-activitypub/src/main/kotlin/dev/usbharu/hideout/activitypub/config/ActivityPubWebMvcConfigurer.kt b/hideout/hideout-activitypub/src/main/kotlin/dev/usbharu/hideout/activitypub/config/ActivityPubWebMvcConfigurer.kt new file mode 100644 index 00000000..8d1a88ad --- /dev/null +++ b/hideout/hideout-activitypub/src/main/kotlin/dev/usbharu/hideout/activitypub/config/ActivityPubWebMvcConfigurer.kt @@ -0,0 +1,16 @@ +package dev.usbharu.hideout.activitypub.config + +import dev.usbharu.hideout.activitypub.external.activitystreams.ActivityStreamHttpMessageConverter +import org.springframework.context.annotation.Configuration +import org.springframework.core.annotation.Order +import org.springframework.http.converter.HttpMessageConverter +import org.springframework.web.servlet.config.annotation.WebMvcConfigurer + +@Configuration +@Order(2) +class ActivityPubWebMvcConfigurer(private val activityStreamsHttpMessageConverter: ActivityStreamHttpMessageConverter) : + WebMvcConfigurer { + override fun extendMessageConverters(converters: MutableList>) { + converters.add(activityStreamsHttpMessageConverter) + } +} \ No newline at end of file diff --git a/hideout/hideout-activitypub/src/main/kotlin/dev/usbharu/hideout/activitypub/external/activitystreams/ActivityStreamHttpMessageConverter.kt b/hideout/hideout-activitypub/src/main/kotlin/dev/usbharu/hideout/activitypub/external/activitystreams/ActivityStreamHttpMessageConverter.kt new file mode 100644 index 00000000..c5ee2afd --- /dev/null +++ b/hideout/hideout-activitypub/src/main/kotlin/dev/usbharu/hideout/activitypub/external/activitystreams/ActivityStreamHttpMessageConverter.kt @@ -0,0 +1,45 @@ +package dev.usbharu.hideout.activitypub.external.activitystreams + +import com.github.jsonldjava.core.JsonLdOptions +import com.github.jsonldjava.core.JsonLdProcessor +import com.github.jsonldjava.utils.JsonUtils +import dev.usbharu.activitystreamsserialization.json.impl.JacksonSerializationConverter +import dev.usbharu.activitystreamsserialization.other.JsonLd +import org.springframework.http.HttpInputMessage +import org.springframework.http.HttpOutputMessage +import org.springframework.http.MediaType +import org.springframework.http.converter.HttpMessageConverter +import org.springframework.stereotype.Component + +@Component +class ActivityStreamHttpMessageConverter : HttpMessageConverter { + override fun canRead(clazz: Class<*>, mediaType: MediaType?): Boolean { + return false + } + + override fun canWrite(clazz: Class<*>, mediaType: MediaType?): Boolean { + return JsonLd::class.java.isAssignableFrom(clazz) + } + + override fun getSupportedMediaTypes(): MutableList { + return mutableListOf() + } + + override fun write(t: JsonLd, contentType: MediaType?, outputMessage: HttpOutputMessage) { + outputMessage.headers.contentType = MediaType.APPLICATION_JSON + outputMessage.body.bufferedWriter() + .use { + it.write(JsonUtils.toString( + JsonLdProcessor.compact( + JsonUtils.fromString(JacksonSerializationConverter.convert(t.json).toString()), "https://www.w3.org/ns/activitystreams", + JsonLdOptions() + ) + )) + } + } + + override fun read(clazz: Class, inputMessage: HttpInputMessage): JsonLd { + TODO("Not yet implemented") + } + +} \ No newline at end of file diff --git a/hideout/hideout-activitypub/src/main/kotlin/dev/usbharu/hideout/activitypub/interface/api/APActorController.kt b/hideout/hideout-activitypub/src/main/kotlin/dev/usbharu/hideout/activitypub/interface/api/APActorController.kt index 36b4e170..444f3a94 100644 --- a/hideout/hideout-activitypub/src/main/kotlin/dev/usbharu/hideout/activitypub/interface/api/APActorController.kt +++ b/hideout/hideout-activitypub/src/main/kotlin/dev/usbharu/hideout/activitypub/interface/api/APActorController.kt @@ -1,8 +1,9 @@ package dev.usbharu.hideout.activitypub.`interface`.api +import dev.usbharu.activitystreamsserialization.other.JsonLd import dev.usbharu.hideout.activitypub.application.actor.GetActorApplicationService -import dev.usbharu.hideout.core.domain.model.actor.Actor import dev.usbharu.hideout.core.domain.model.support.principal.Anonymous +import org.springframework.http.ResponseEntity import org.springframework.stereotype.Controller import org.springframework.web.bind.annotation.GetMapping import org.springframework.web.bind.annotation.PathVariable @@ -14,7 +15,7 @@ class APActorController(private val getActorApplicationService: GetActorApplicat consumes = ["application/activity+json"], produces = ["application/activity+json"] ) - suspend fun user(@PathVariable username: String): Actor { - return getActorApplicationService.execute(username, Anonymous) + suspend fun user(@PathVariable username: String): ResponseEntity { + return ResponseEntity.ok(getActorApplicationService.execute(username, Anonymous)) } } \ No newline at end of file diff --git a/hideout/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/config/SpringMvcConfig.kt b/hideout/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/config/SpringMvcConfig.kt index 696e7fca..ca5bd05d 100644 --- a/hideout/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/config/SpringMvcConfig.kt +++ b/hideout/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/config/SpringMvcConfig.kt @@ -23,6 +23,7 @@ import dev.usbharu.hideout.generate.JsonOrFormModelMethodProcessor import org.springframework.boot.web.servlet.FilterRegistrationBean import org.springframework.context.annotation.Bean import org.springframework.context.annotation.Configuration +import org.springframework.core.annotation.Order import org.springframework.http.converter.HttpMessageConverter import org.springframework.web.method.support.HandlerMethodArgumentResolver import org.springframework.web.servlet.config.annotation.InterceptorRegistry @@ -31,10 +32,11 @@ import org.springframework.web.servlet.mvc.method.annotation.RequestResponseBody import org.springframework.web.servlet.mvc.method.annotation.ServletModelAttributeMethodProcessor @Configuration +@Order(2) class MvcConfigurer( private val jsonOrFormModelMethodProcessor: JsonOrFormModelMethodProcessor, private val spaInterceptor: SPAInterceptor, - private val applicationRequestLogInterceptor: ApplicationRequestLogInterceptor + private val applicationRequestLogInterceptor: ApplicationRequestLogInterceptor, ) : WebMvcConfigurer { override fun addArgumentResolvers(resolvers: MutableList) { resolvers.add(jsonOrFormModelMethodProcessor) diff --git a/hideout/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/domain/model/support/principal/RemoteUser.kt b/hideout/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/domain/model/support/principal/RemoteUser.kt new file mode 100644 index 00000000..3e0a114f --- /dev/null +++ b/hideout/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/domain/model/support/principal/RemoteUser.kt @@ -0,0 +1,6 @@ +package dev.usbharu.hideout.core.domain.model.support.principal + +import dev.usbharu.hideout.core.domain.model.actor.ActorId +import dev.usbharu.hideout.core.domain.model.support.acct.Acct + +class RemoteUser(actorId: ActorId, acct: Acct?) : Principal(actorId, null, acct) \ No newline at end of file