From 5c6987f2b06e43213cdb4c598e4e1b1d49e23562 Mon Sep 17 00:00:00 2001 From: usbharu <64310155+usbharu@users.noreply.github.com> Date: Fri, 3 Nov 2023 00:52:33 +0900 Subject: [PATCH] =?UTF-8?q?feat:=20=E3=83=AA=E3=83=A2=E3=83=BC=E3=83=88?= =?UTF-8?q?=E3=81=AENote=E3=81=AEDelete=20Activity=E3=81=AE=E5=8F=97?= =?UTF-8?q?=E4=BF=A1=E3=81=AB=E5=AF=BE=E5=BF=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../activitypub/domain/model/Delete.kt | 49 +++++++++++++++++++ .../activitypub/domain/model/Tombstone.kt | 12 +++++ .../model/objects/ObjectDeserializer.kt | 4 +- .../activity/delete/APReceiveDeleteService.kt | 8 +++ .../delete/APReceiveDeleteServiceImpl.kt | 31 ++++++++++++ .../activitypub/service/common/APService.kt | 5 +- 6 files changed, 106 insertions(+), 3 deletions(-) create mode 100644 src/main/kotlin/dev/usbharu/hideout/activitypub/domain/model/Delete.kt create mode 100644 src/main/kotlin/dev/usbharu/hideout/activitypub/domain/model/Tombstone.kt create mode 100644 src/main/kotlin/dev/usbharu/hideout/activitypub/service/activity/delete/APReceiveDeleteService.kt create mode 100644 src/main/kotlin/dev/usbharu/hideout/activitypub/service/activity/delete/APReceiveDeleteServiceImpl.kt diff --git a/src/main/kotlin/dev/usbharu/hideout/activitypub/domain/model/Delete.kt b/src/main/kotlin/dev/usbharu/hideout/activitypub/domain/model/Delete.kt new file mode 100644 index 00000000..c26461be --- /dev/null +++ b/src/main/kotlin/dev/usbharu/hideout/activitypub/domain/model/Delete.kt @@ -0,0 +1,49 @@ +package dev.usbharu.hideout.activitypub.domain.model + +import com.fasterxml.jackson.databind.annotation.JsonDeserialize +import dev.usbharu.hideout.activitypub.domain.model.objects.Object +import dev.usbharu.hideout.activitypub.domain.model.objects.ObjectDeserializer + +open class Delete : Object { + @JsonDeserialize(using = ObjectDeserializer::class) + var `object`: Object? = null + var published: String? = null + + constructor( + type: List = emptyList(), + name: String = "Delete", + actor: String, + id: String, + `object`: Object, + published: String? + ) : super(add(type, "Delete"), name, actor, id) { + this.`object` = `object` + this.published = published + } + + protected constructor() : super() + + override fun equals(other: Any?): Boolean { + if (this === other) return true + if (other !is Delete) return false + if (!super.equals(other)) return false + + if (`object` != other.`object`) return false + if (published != other.published) return false + + return true + } + + override fun hashCode(): Int { + var result = super.hashCode() + result = 31 * result + (`object`?.hashCode() ?: 0) + result = 31 * result + (published?.hashCode() ?: 0) + return result + } + + override fun toString(): String { + return "Delete(`object`=$`object`, published=$published) ${super.toString()}" + } + + +} diff --git a/src/main/kotlin/dev/usbharu/hideout/activitypub/domain/model/Tombstone.kt b/src/main/kotlin/dev/usbharu/hideout/activitypub/domain/model/Tombstone.kt new file mode 100644 index 00000000..0017eac4 --- /dev/null +++ b/src/main/kotlin/dev/usbharu/hideout/activitypub/domain/model/Tombstone.kt @@ -0,0 +1,12 @@ +package dev.usbharu.hideout.activitypub.domain.model + +import dev.usbharu.hideout.activitypub.domain.model.objects.Object + +open class Tombstone : Object { + constructor( + type: List = emptyList(), + name: String = "Tombstone", + actor: String? = null, + id: String + ) : super(add(type, "Tombstone"), name, actor, id) +} diff --git a/src/main/kotlin/dev/usbharu/hideout/activitypub/domain/model/objects/ObjectDeserializer.kt b/src/main/kotlin/dev/usbharu/hideout/activitypub/domain/model/objects/ObjectDeserializer.kt index ad9969a2..377dfcff 100644 --- a/src/main/kotlin/dev/usbharu/hideout/activitypub/domain/model/objects/ObjectDeserializer.kt +++ b/src/main/kotlin/dev/usbharu/hideout/activitypub/domain/model/objects/ObjectDeserializer.kt @@ -56,7 +56,7 @@ class ObjectDeserializer : JsonDeserializer() { ExtendedActivityVocabulary.Arrive -> TODO() ExtendedActivityVocabulary.Block -> TODO() ExtendedActivityVocabulary.Create -> p.codec.treeToValue(treeNode, Create::class.java) - ExtendedActivityVocabulary.Delete -> TODO() + ExtendedActivityVocabulary.Delete -> p.codec.treeToValue(treeNode, Delete::class.java) ExtendedActivityVocabulary.Dislike -> TODO() ExtendedActivityVocabulary.Flag -> TODO() ExtendedActivityVocabulary.Ignore -> TODO() @@ -91,7 +91,7 @@ class ObjectDeserializer : JsonDeserializer() { ExtendedActivityVocabulary.Place -> TODO() ExtendedActivityVocabulary.Profile -> TODO() ExtendedActivityVocabulary.Relationship -> TODO() - ExtendedActivityVocabulary.Tombstone -> TODO() + ExtendedActivityVocabulary.Tombstone -> p.codec.treeToValue(treeNode, Tombstone::class.java) ExtendedActivityVocabulary.Video -> TODO() ExtendedActivityVocabulary.Mention -> TODO() ExtendedActivityVocabulary.Emoji -> p.codec.treeToValue(treeNode, Emoji::class.java) 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 new file mode 100644 index 00000000..9d047605 --- /dev/null +++ b/src/main/kotlin/dev/usbharu/hideout/activitypub/service/activity/delete/APReceiveDeleteService.kt @@ -0,0 +1,8 @@ +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 +} 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 new file mode 100644 index 00000000..d5272203 --- /dev/null +++ b/src/main/kotlin/dev/usbharu/hideout/activitypub/service/activity/delete/APReceiveDeleteServiceImpl.kt @@ -0,0 +1,31 @@ +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 +class APReceiveDeleteServiceImpl( + private val postQueryService: PostQueryService, + private val postRepository: PostRepository, + private val transaction: Transaction +) : APReceiveDeleteService { + override suspend fun receiveDelete(delete: Delete): ActivityPubResponse = transaction.transaction { + val deleteId = delete.`object`?.id ?: throw IllegalActivityPubObjectException("object.id is null") + + val post = try { + postQueryService.findByApId(deleteId) + } catch (e: FailedToGetResourcesException) { + return@transaction ActivityPubStringResponse(HttpStatusCode.OK, "Resource not found or already deleted") + } + postRepository.delete(post.id) + return@transaction ActivityPubStringResponse(HttpStatusCode.OK, "Resource was deleted.") + } +} 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 102929da..26a68664 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 @@ -8,6 +8,7 @@ import dev.usbharu.hideout.activitypub.domain.model.Follow import dev.usbharu.hideout.activitypub.interfaces.api.common.ActivityPubResponse 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 @@ -180,7 +181,8 @@ class APServiceImpl( private val apAcceptService: APAcceptService, private val apCreateService: APCreateService, private val apLikeService: APLikeService, - @Qualifier("activitypub") private val objectMapper: ObjectMapper + @Qualifier("activitypub") private val objectMapper: ObjectMapper, + private val apReceiveDeleteService: APReceiveDeleteService ) : APService { val logger: Logger = LoggerFactory.getLogger(APServiceImpl::class.java) @@ -234,6 +236,7 @@ class APServiceImpl( 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.")