From 6f579486da7c2c8ea73847dc84bc38fa8252a4ec Mon Sep 17 00:00:00 2001 From: usbharu <64310155+usbharu@users.noreply.github.com> Date: Wed, 13 Dec 2023 15:02:17 +0900 Subject: [PATCH 01/15] =?UTF-8?q?feat:=20=E5=89=8A=E9=99=A4=E3=81=95?= =?UTF-8?q?=E3=82=8C=E3=81=9F=E6=8A=95=E7=A8=BF=E3=81=AF=E3=83=AC=E3=82=B3?= =?UTF-8?q?=E3=83=BC=E3=83=89=E3=82=92=E5=AE=8C=E5=85=A8=E3=81=AB=E5=89=8A?= =?UTF-8?q?=E9=99=A4=E3=81=9B=E3=81=9A=E3=80=81=E8=BF=94=E4=BF=A1=E3=81=AA?= =?UTF-8?q?=E3=81=A9=E3=81=AE=E6=83=85=E5=A0=B1=E3=82=92=E7=B6=AD=E6=8C=81?= =?UTF-8?q?=E3=81=97=E3=81=9F=E3=81=BE=E3=81=BE=E5=89=8A=E9=99=A4=E3=81=95?= =?UTF-8?q?=E3=82=8C=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 --- .../activity/delete/APDeleteProcessor.kt | 6 +-- .../delete/APDeliverDeleteJobProcessor.kt | 23 +++++++++ .../activity/delete/APSendDeleteService.kt | 50 +++++++++++++++++++ .../hideout/core/domain/model/post/Post.kt | 50 ++++++++++++++++++- .../model/reaction/ReactionRepository.kt | 2 + .../core/external/job/DeliverDeleteJob.kt | 36 +++++++++++++ .../exposed/PostResultRowMapper.kt | 11 ++++ .../exposedrepository/PostRepositoryImpl.kt | 1 + .../ReactionRepositoryImpl.kt | 18 ++++++- .../hideout/core/service/post/PostService.kt | 2 + .../core/service/post/PostServiceImpl.kt | 14 +++++- .../resources/db/migration/V1__Init_DB.sql | 11 ++-- 12 files changed, 213 insertions(+), 11 deletions(-) create mode 100644 src/main/kotlin/dev/usbharu/hideout/activitypub/service/activity/delete/APDeliverDeleteJobProcessor.kt create mode 100644 src/main/kotlin/dev/usbharu/hideout/activitypub/service/activity/delete/APSendDeleteService.kt create mode 100644 src/main/kotlin/dev/usbharu/hideout/core/external/job/DeliverDeleteJob.kt diff --git a/src/main/kotlin/dev/usbharu/hideout/activitypub/service/activity/delete/APDeleteProcessor.kt b/src/main/kotlin/dev/usbharu/hideout/activitypub/service/activity/delete/APDeleteProcessor.kt index efb37938..c628e491 100644 --- a/src/main/kotlin/dev/usbharu/hideout/activitypub/service/activity/delete/APDeleteProcessor.kt +++ b/src/main/kotlin/dev/usbharu/hideout/activitypub/service/activity/delete/APDeleteProcessor.kt @@ -8,15 +8,15 @@ import dev.usbharu.hideout.activitypub.service.common.ActivityPubProcessContext import dev.usbharu.hideout.activitypub.service.common.ActivityType 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 dev.usbharu.hideout.core.service.post.PostService import org.springframework.stereotype.Service @Service class APDeleteProcessor( transaction: Transaction, private val postQueryService: PostQueryService, - private val postRepository: PostRepository + private val postService: PostService ) : AbstractActivityPubProcessor(transaction) { override suspend fun internalProcess(activity: ActivityPubProcessContext) { @@ -33,7 +33,7 @@ class APDeleteProcessor( return } - postRepository.delete(post.id) + postService.deleteRemote(post) } override fun isSupported(activityType: ActivityType): Boolean = activityType == ActivityType.Delete diff --git a/src/main/kotlin/dev/usbharu/hideout/activitypub/service/activity/delete/APDeliverDeleteJobProcessor.kt b/src/main/kotlin/dev/usbharu/hideout/activitypub/service/activity/delete/APDeliverDeleteJobProcessor.kt new file mode 100644 index 00000000..5c72c304 --- /dev/null +++ b/src/main/kotlin/dev/usbharu/hideout/activitypub/service/activity/delete/APDeliverDeleteJobProcessor.kt @@ -0,0 +1,23 @@ +package dev.usbharu.hideout.activitypub.service.activity.delete + +import dev.usbharu.hideout.activitypub.service.common.APRequestService +import dev.usbharu.hideout.application.external.Transaction +import dev.usbharu.hideout.core.external.job.DeliverDeleteJob +import dev.usbharu.hideout.core.external.job.DeliverDeleteJobParam +import dev.usbharu.hideout.core.query.ActorQueryService +import dev.usbharu.hideout.core.service.job.JobProcessor +import org.springframework.stereotype.Service + +@Service +class APDeliverDeleteJobProcessor( + private val apRequestService: APRequestService, + private val actorQueryService: ActorQueryService, + private val transaction: Transaction, + private val deliverDeleteJob: DeliverDeleteJob +) : JobProcessor { + override suspend fun process(param: DeliverDeleteJobParam): Unit = transaction.transaction { + apRequestService.apPost(param.inbox, param.delete, actorQueryService.findById(param.signer)) + } + + override fun job(): DeliverDeleteJob = deliverDeleteJob +} diff --git a/src/main/kotlin/dev/usbharu/hideout/activitypub/service/activity/delete/APSendDeleteService.kt b/src/main/kotlin/dev/usbharu/hideout/activitypub/service/activity/delete/APSendDeleteService.kt new file mode 100644 index 00000000..2cb0f86c --- /dev/null +++ b/src/main/kotlin/dev/usbharu/hideout/activitypub/service/activity/delete/APSendDeleteService.kt @@ -0,0 +1,50 @@ +package dev.usbharu.hideout.activitypub.service.activity.delete + +import dev.usbharu.hideout.activitypub.domain.model.Delete +import dev.usbharu.hideout.activitypub.domain.model.Tombstone +import dev.usbharu.hideout.application.config.ApplicationConfig +import dev.usbharu.hideout.core.domain.model.post.Post +import dev.usbharu.hideout.core.external.job.DeliverDeleteJob +import dev.usbharu.hideout.core.external.job.DeliverDeleteJobParam +import dev.usbharu.hideout.core.query.ActorQueryService +import dev.usbharu.hideout.core.query.FollowerQueryService +import dev.usbharu.hideout.core.service.job.JobQueueParentService +import org.springframework.stereotype.Service +import java.time.Instant + +interface APSendDeleteService { + suspend fun sendDeleteNote(deletedPost: Post) +} + +@Service +class APSendDeleteServiceImpl( + private val jobQueueParentService: JobQueueParentService, + private val delverDeleteJob: DeliverDeleteJob, + private val followerQueryService: FollowerQueryService, + private val actorQueryService: ActorQueryService, + private val applicationConfig: ApplicationConfig +) : APSendDeleteService { + override suspend fun sendDeleteNote(deletedPost: Post) { + + + val actor = actorQueryService.findById(deletedPost.actorId) + val followersById = followerQueryService.findFollowersById(deletedPost.actorId) + + val delete = Delete( + actor = actor.url, + id = "${applicationConfig.url}/delete/note/${deletedPost.id}", + published = Instant.now().toString(), + `object` = Tombstone(id = deletedPost.apId) + ) + + followersById.forEach { + val jobProps = DeliverDeleteJobParam( + delete, + it.inbox, + actor.id + ) + jobQueueParentService.scheduleTypeSafe(delverDeleteJob, jobProps) + } + } + +} diff --git a/src/main/kotlin/dev/usbharu/hideout/core/domain/model/post/Post.kt b/src/main/kotlin/dev/usbharu/hideout/core/domain/model/post/Post.kt index 3a5989ab..6cbc765e 100644 --- a/src/main/kotlin/dev/usbharu/hideout/core/domain/model/post/Post.kt +++ b/src/main/kotlin/dev/usbharu/hideout/core/domain/model/post/Post.kt @@ -2,6 +2,7 @@ package dev.usbharu.hideout.core.domain.model.post import dev.usbharu.hideout.application.config.CharacterLimit import org.springframework.stereotype.Component +import java.time.Instant data class Post private constructor( val id: Long, @@ -15,7 +16,8 @@ data class Post private constructor( val replyId: Long? = null, val sensitive: Boolean = false, val apId: String = url, - val mediaIds: List = emptyList() + val mediaIds: List = emptyList(), + val delted: Boolean = false ) { @Component @@ -71,8 +73,52 @@ data class Post private constructor( replyId = replyId, sensitive = sensitive, apId = apId, - mediaIds = mediaIds + mediaIds = mediaIds, + delted = false + ) + } + + fun deleteOf( + id: Long, + visibility: Visibility, + url: String, + repostId: Long?, + replyId: Long?, + apId: String + ): Post { + return Post( + id = id, + actorId = 0, + overview = null, + text = "", + createdAt = Instant.EPOCH.toEpochMilli(), + visibility = visibility, + url = url, + repostId = repostId, + replyId = replyId, + sensitive = false, + apId = apId, + mediaIds = emptyList(), + delted = true ) } } + + fun delete(): Post { + return Post( + id = this.id, + actorId = 0, + overview = null, + text = "", + createdAt = Instant.EPOCH.toEpochMilli(), + visibility = visibility, + url = url, + repostId = repostId, + replyId = replyId, + sensitive = false, + apId = apId, + mediaIds = emptyList(), + delted = true + ) + } } diff --git a/src/main/kotlin/dev/usbharu/hideout/core/domain/model/reaction/ReactionRepository.kt b/src/main/kotlin/dev/usbharu/hideout/core/domain/model/reaction/ReactionRepository.kt index 5bfae20e..64b324ff 100644 --- a/src/main/kotlin/dev/usbharu/hideout/core/domain/model/reaction/ReactionRepository.kt +++ b/src/main/kotlin/dev/usbharu/hideout/core/domain/model/reaction/ReactionRepository.kt @@ -7,4 +7,6 @@ interface ReactionRepository { suspend fun generateId(): Long suspend fun save(reaction: Reaction): Reaction suspend fun delete(reaction: Reaction): Reaction + suspend fun deleteByPostId(postId: Long): Int + suspend fun deleteByActorId(actorId: Long): Int } diff --git a/src/main/kotlin/dev/usbharu/hideout/core/external/job/DeliverDeleteJob.kt b/src/main/kotlin/dev/usbharu/hideout/core/external/job/DeliverDeleteJob.kt new file mode 100644 index 00000000..9029f6b4 --- /dev/null +++ b/src/main/kotlin/dev/usbharu/hideout/core/external/job/DeliverDeleteJob.kt @@ -0,0 +1,36 @@ +package dev.usbharu.hideout.core.external.job + +import com.fasterxml.jackson.databind.ObjectMapper +import com.fasterxml.jackson.module.kotlin.readValue +import dev.usbharu.hideout.activitypub.domain.model.Delete +import kjob.core.dsl.ScheduleContext +import kjob.core.job.JobProps +import org.springframework.beans.factory.annotation.Qualifier +import org.springframework.stereotype.Component + +data class DeliverDeleteJobParam( + val delete: Delete, + val inbox: String, + val signer: Long +) + +@Component +class DeliverDeleteJob(@Qualifier("activitypub") private val objectMapper: ObjectMapper) : + HideoutJob("DeliverDeleteJob") { + + val delete = string("delete") + val inbox = string("inbox") + val signer = long("signer") + + override fun convert(value: DeliverDeleteJobParam): ScheduleContext.(DeliverDeleteJob) -> Unit = { + props[delete] = objectMapper.writeValueAsString(value.delete) + props[inbox] = value.inbox + props[signer] = value.signer + } + + override fun convert(props: JobProps): DeliverDeleteJobParam = DeliverDeleteJobParam( + objectMapper.readValue(props[delete]), + props[inbox], + props[signer] + ) +} diff --git a/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/exposed/PostResultRowMapper.kt b/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/exposed/PostResultRowMapper.kt index 88b4e50c..22faf1b2 100644 --- a/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/exposed/PostResultRowMapper.kt +++ b/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/exposed/PostResultRowMapper.kt @@ -10,6 +10,17 @@ import org.springframework.stereotype.Component @Component class PostResultRowMapper(private val postBuilder: Post.PostBuilder) : ResultRowMapper { override fun map(resultRow: ResultRow): Post { + if (resultRow[Posts.deleted]) { + return postBuilder.deleteOf( + resultRow[Posts.id], + Visibility.values().first { it.ordinal == resultRow[Posts.visibility] }, + url = resultRow[Posts.url], + repostId = resultRow[Posts.repostId], + replyId = resultRow[Posts.replyId], + apId = resultRow[Posts.apId] + ) + } + return postBuilder.of( id = resultRow[Posts.id], actorId = resultRow[Posts.actorId], diff --git a/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/exposedrepository/PostRepositoryImpl.kt b/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/exposedrepository/PostRepositoryImpl.kt index d71f0cab..f64e02d7 100644 --- a/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/exposedrepository/PostRepositoryImpl.kt +++ b/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/exposedrepository/PostRepositoryImpl.kt @@ -85,6 +85,7 @@ object Posts : Table() { val replyId: Column = long("reply_id").references(id).nullable() val sensitive: Column = bool("sensitive").default(false) val apId: Column = varchar("ap_id", 100).uniqueIndex() + val deleted = bool("deleted").default(false) override val primaryKey: PrimaryKey = PrimaryKey(id) } diff --git a/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/exposedrepository/ReactionRepositoryImpl.kt b/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/exposedrepository/ReactionRepositoryImpl.kt index e2b8cef7..0b14d787 100644 --- a/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/exposedrepository/ReactionRepositoryImpl.kt +++ b/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/exposedrepository/ReactionRepositoryImpl.kt @@ -42,6 +42,18 @@ class ReactionRepositoryImpl( } return reaction } + + override suspend fun deleteByPostId(postId: Long): Int { + return Reactions.deleteWhere { + Reactions.postId eq postId + } + } + + override suspend fun deleteByActorId(actorId: Long): Int { + return Reactions.deleteWhere { + Reactions.actorId eq actorId + } + } } fun ResultRow.toReaction(): Reaction { @@ -55,8 +67,10 @@ fun ResultRow.toReaction(): Reaction { object Reactions : LongIdTable("reactions") { val emojiId: Column = long("emoji_id") - val postId: Column = long("post_id").references(Posts.id) - val actorId: Column = long("actor_id").references(Actors.id) + val postId: Column = long("post_id") + .references(Posts.id, onDelete = ReferenceOption.CASCADE, onUpdate = ReferenceOption.CASCADE) + val actorId: Column = long("actor_id") + .references(Actors.id, onDelete = ReferenceOption.CASCADE, onUpdate = ReferenceOption.CASCADE) init { uniqueIndex(emojiId, postId, actorId) diff --git a/src/main/kotlin/dev/usbharu/hideout/core/service/post/PostService.kt b/src/main/kotlin/dev/usbharu/hideout/core/service/post/PostService.kt index 47c4974d..a20f0a66 100644 --- a/src/main/kotlin/dev/usbharu/hideout/core/service/post/PostService.kt +++ b/src/main/kotlin/dev/usbharu/hideout/core/service/post/PostService.kt @@ -7,4 +7,6 @@ import org.springframework.stereotype.Service interface PostService { suspend fun createLocal(post: PostCreateDto): Post suspend fun createRemote(post: Post): Post + suspend fun deleteLocal(post: Post) + suspend fun deleteRemote(post: Post) } diff --git a/src/main/kotlin/dev/usbharu/hideout/core/service/post/PostServiceImpl.kt b/src/main/kotlin/dev/usbharu/hideout/core/service/post/PostServiceImpl.kt index a5bb1d47..e35e0c40 100644 --- a/src/main/kotlin/dev/usbharu/hideout/core/service/post/PostServiceImpl.kt +++ b/src/main/kotlin/dev/usbharu/hideout/core/service/post/PostServiceImpl.kt @@ -5,6 +5,7 @@ import dev.usbharu.hideout.core.domain.exception.UserNotFoundException import dev.usbharu.hideout.core.domain.model.actor.ActorRepository import dev.usbharu.hideout.core.domain.model.post.Post import dev.usbharu.hideout.core.domain.model.post.PostRepository +import dev.usbharu.hideout.core.domain.model.reaction.ReactionRepository import dev.usbharu.hideout.core.query.PostQueryService import dev.usbharu.hideout.core.service.timeline.TimelineService import org.jetbrains.exposed.exceptions.ExposedSQLException @@ -20,7 +21,8 @@ class PostServiceImpl( private val timelineService: TimelineService, private val postQueryService: PostQueryService, private val postBuilder: Post.PostBuilder, - private val apSendCreateService: ApSendCreateService + private val apSendCreateService: ApSendCreateService, + private val reactionRepository: ReactionRepository ) : PostService { override suspend fun createLocal(post: PostCreateDto): Post { @@ -38,6 +40,16 @@ class PostServiceImpl( return createdPost } + override suspend fun deleteLocal(post: Post) { + reactionRepository.deleteByPostId(post.id) + postRepository.save(post.delete()) + } + + override suspend fun deleteRemote(post: Post) { + reactionRepository.deleteByPostId(post.id) + postRepository.save(post.delete()) + } + private suspend fun internalCreate(post: Post, isLocal: Boolean): Post { return try { if (postRepository.save(post)) { diff --git a/src/main/resources/db/migration/V1__Init_DB.sql b/src/main/resources/db/migration/V1__Init_DB.sql index 48223f60..f680516b 100644 --- a/src/main/resources/db/migration/V1__Init_DB.sql +++ b/src/main/resources/db/migration/V1__Init_DB.sql @@ -67,7 +67,7 @@ create table if not exists meta_info create table if not exists posts ( id bigint primary key, - actor_id bigint not null, + actor_id bigint not null, overview varchar(100) null, text varchar(3000) not null, created_at bigint not null, @@ -76,7 +76,8 @@ create table if not exists posts repost_id bigint null, reply_id bigint null, "sensitive" boolean default false not null, - ap_id varchar(100) not null unique + ap_id varchar(100) not null unique, + deleted boolean default false not null ); alter table posts add constraint fk_posts_actor_id__id foreign key (actor_id) references actors (id) on delete restrict on update restrict; @@ -196,4 +197,8 @@ create table if not exists relationships constraint fk_relationships_actor_id__id foreign key (actor_id) references actors (id) on delete restrict on update restrict, constraint fk_relationships_target_actor_id__id foreign key (target_actor_id) references actors (id) on delete restrict on update restrict, unique (actor_id, target_actor_id) -) +); + +insert into actors (id, name, domain, screen_name, description, inbox, outbox, url, public_key, private_key, created_at, + key_id, following, followers, instance, locked) +values (0, 'ghost', '', '', '', '', '', '', '', null, 0, '', '', '', null, true); From cb76d3f1ddc996ad90915c5dc1bbef9db13fca8f Mon Sep 17 00:00:00 2001 From: usbharu <64310155+usbharu@users.noreply.github.com> Date: Wed, 13 Dec 2023 15:04:18 +0900 Subject: [PATCH 02/15] =?UTF-8?q?fix:=20=E5=89=8A=E9=99=A4=E3=83=95?= =?UTF-8?q?=E3=83=A9=E3=82=B0=E3=81=8C=E6=B0=B8=E7=B6=9A=E5=8C=96=E3=81=95?= =?UTF-8?q?=E3=82=8C=E3=81=A6=E3=81=84=E3=81=AA=E3=81=8B=E3=81=A3=E3=81=9F?= =?UTF-8?q?=E3=81=AE=E3=82=92=E4=BF=AE=E6=AD=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../core/infrastructure/exposedrepository/PostRepositoryImpl.kt | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/exposedrepository/PostRepositoryImpl.kt b/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/exposedrepository/PostRepositoryImpl.kt index f64e02d7..e1e323e2 100644 --- a/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/exposedrepository/PostRepositoryImpl.kt +++ b/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/exposedrepository/PostRepositoryImpl.kt @@ -33,6 +33,7 @@ class PostRepositoryImpl( it[replyId] = post.replyId it[sensitive] = post.sensitive it[apId] = post.apId + it[deleted] = post.delted } PostsMedia.batchInsert(post.mediaIds) { this[PostsMedia.postId] = post.id @@ -57,6 +58,7 @@ class PostRepositoryImpl( it[replyId] = post.replyId it[sensitive] = post.sensitive it[apId] = post.apId + it[deleted] = post.delted } } return singleOrNull == null From 65cc57f3d5af27afbd6900735644abfa30c8afb3 Mon Sep 17 00:00:00 2001 From: usbharu <64310155+usbharu@users.noreply.github.com> Date: Wed, 13 Dec 2023 16:07:43 +0900 Subject: [PATCH 03/15] fix: #214 --- .../activitypub/domain/model/Person.kt | 36 +++++++++---------- .../service/objects/user/APUserService.kt | 2 +- 2 files changed, 19 insertions(+), 19 deletions(-) diff --git a/src/main/kotlin/dev/usbharu/hideout/activitypub/domain/model/Person.kt b/src/main/kotlin/dev/usbharu/hideout/activitypub/domain/model/Person.kt index f08b161e..af5e045c 100644 --- a/src/main/kotlin/dev/usbharu/hideout/activitypub/domain/model/Person.kt +++ b/src/main/kotlin/dev/usbharu/hideout/activitypub/domain/model/Person.kt @@ -6,9 +6,9 @@ open class Person @Suppress("LongParameterList") constructor( type: List = emptyList(), - override val name: String, + val name: String?, override val id: String, - var preferredUsername: String?, + var preferredUsername: String, var summary: String?, var inbox: String, var outbox: String, @@ -19,7 +19,7 @@ constructor( var followers: String?, var following: String?, val manuallyApprovesFollowers: Boolean? = false -) : Object(add(type, "Person")), HasId, HasName { +) : Object(add(type, "Person")), HasId { @Suppress("CyclomaticComplexMethod", "CognitiveComplexMethod") override fun equals(other: Any?): Boolean { @@ -67,20 +67,20 @@ constructor( override fun toString(): String { return "Person(" + - "name='$name', " + - "id='$id', " + - "preferredUsername=$preferredUsername, " + - "summary=$summary, " + - "inbox='$inbox', " + - "outbox='$outbox', " + - "url='$url', " + - "icon=$icon, " + - "publicKey=$publicKey, " + - "endpoints=$endpoints, " + - "followers=$followers, " + - "following=$following, " + - "manuallyApprovesFollowers=$manuallyApprovesFollowers" + - ")" + - " ${super.toString()}" + "name='$name', " + + "id='$id', " + + "preferredUsername=$preferredUsername, " + + "summary=$summary, " + + "inbox='$inbox', " + + "outbox='$outbox', " + + "url='$url', " + + "icon=$icon, " + + "publicKey=$publicKey, " + + "endpoints=$endpoints, " + + "followers=$followers, " + + "following=$following, " + + "manuallyApprovesFollowers=$manuallyApprovesFollowers" + + ")" + + " ${super.toString()}" } } diff --git a/src/main/kotlin/dev/usbharu/hideout/activitypub/service/objects/user/APUserService.kt b/src/main/kotlin/dev/usbharu/hideout/activitypub/service/objects/user/APUserService.kt index 3b540ebb..009c6821 100644 --- a/src/main/kotlin/dev/usbharu/hideout/activitypub/service/objects/user/APUserService.kt +++ b/src/main/kotlin/dev/usbharu/hideout/activitypub/service/objects/user/APUserService.kt @@ -96,7 +96,7 @@ class APUserServiceImpl( name = person.preferredUsername ?: throw IllegalActivityPubObjectException("preferredUsername is null"), domain = id.substringAfter("://").substringBefore("/"), - screenName = person.name, + screenName = person.name ?: person.preferredUsername, description = person.summary.orEmpty(), inbox = person.inbox, outbox = person.outbox, From 5bf85fefbef5b23a4296f6216ac98b90acd99be4 Mon Sep 17 00:00:00 2001 From: usbharu <64310155+usbharu@users.noreply.github.com> Date: Wed, 13 Dec 2023 16:08:05 +0900 Subject: [PATCH 04/15] =?UTF-8?q?feat:=20=E3=82=A2=E3=82=AB=E3=82=A6?= =?UTF-8?q?=E3=83=B3=E3=83=88=E5=89=8A=E9=99=A4=E3=81=AB=E5=AF=BE=E5=BF=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../domain/model/deletedActor/DeletedActor.kt | 11 +++ .../deletedActor/DeletedActorRepository.kt | 7 ++ .../relationship/RelationshipRepository.kt | 2 + .../RelationshipRepositoryImpl.kt | 7 ++ .../DeletedActorQueryServiceImpl.kt | 23 ++++++ .../DeletedActorRepositoryImpl.kt | 71 +++++++++++++++++++ .../core/query/DeletedActorQueryService.kt | 7 ++ .../core/service/post/PostServiceImpl.kt | 6 ++ .../hideout/core/service/user/UserService.kt | 4 ++ .../core/service/user/UserServiceImpl.kt | 41 ++++++++++- .../resources/db/migration/V1__Init_DB.sql | 10 +++ 11 files changed, 188 insertions(+), 1 deletion(-) create mode 100644 src/main/kotlin/dev/usbharu/hideout/core/domain/model/deletedActor/DeletedActor.kt create mode 100644 src/main/kotlin/dev/usbharu/hideout/core/domain/model/deletedActor/DeletedActorRepository.kt create mode 100644 src/main/kotlin/dev/usbharu/hideout/core/infrastructure/exposedquery/DeletedActorQueryServiceImpl.kt create mode 100644 src/main/kotlin/dev/usbharu/hideout/core/infrastructure/exposedrepository/DeletedActorRepositoryImpl.kt create mode 100644 src/main/kotlin/dev/usbharu/hideout/core/query/DeletedActorQueryService.kt diff --git a/src/main/kotlin/dev/usbharu/hideout/core/domain/model/deletedActor/DeletedActor.kt b/src/main/kotlin/dev/usbharu/hideout/core/domain/model/deletedActor/DeletedActor.kt new file mode 100644 index 00000000..ea5fb843 --- /dev/null +++ b/src/main/kotlin/dev/usbharu/hideout/core/domain/model/deletedActor/DeletedActor.kt @@ -0,0 +1,11 @@ +package dev.usbharu.hideout.core.domain.model.deletedActor + +import java.time.Instant + +data class DeletedActor( + val id: Long, + val name: String, + val domain: String, + val publicKey: String, + val deletedAt: Instant +) diff --git a/src/main/kotlin/dev/usbharu/hideout/core/domain/model/deletedActor/DeletedActorRepository.kt b/src/main/kotlin/dev/usbharu/hideout/core/domain/model/deletedActor/DeletedActorRepository.kt new file mode 100644 index 00000000..f2d18368 --- /dev/null +++ b/src/main/kotlin/dev/usbharu/hideout/core/domain/model/deletedActor/DeletedActorRepository.kt @@ -0,0 +1,7 @@ +package dev.usbharu.hideout.core.domain.model.deletedActor + +interface DeletedActorRepository { + suspend fun save(deletedActor: DeletedActor): DeletedActor + suspend fun delete(deletedActor: DeletedActor) + suspend fun findById(id: Long): DeletedActor +} diff --git a/src/main/kotlin/dev/usbharu/hideout/core/domain/model/relationship/RelationshipRepository.kt b/src/main/kotlin/dev/usbharu/hideout/core/domain/model/relationship/RelationshipRepository.kt index 75da4e35..6335a878 100644 --- a/src/main/kotlin/dev/usbharu/hideout/core/domain/model/relationship/RelationshipRepository.kt +++ b/src/main/kotlin/dev/usbharu/hideout/core/domain/model/relationship/RelationshipRepository.kt @@ -28,4 +28,6 @@ interface RelationshipRepository { * @return 取得された[Relationship] 存在しない場合nullが返ります */ suspend fun findByUserIdAndTargetUserId(actorId: Long, targetActorId: Long): Relationship? + + suspend fun deleteByActorIdOrTargetActorId(actorId: Long, targetActorId: Long) } diff --git a/src/main/kotlin/dev/usbharu/hideout/core/domain/model/relationship/RelationshipRepositoryImpl.kt b/src/main/kotlin/dev/usbharu/hideout/core/domain/model/relationship/RelationshipRepositoryImpl.kt index 09be85c8..844b886f 100644 --- a/src/main/kotlin/dev/usbharu/hideout/core/domain/model/relationship/RelationshipRepositoryImpl.kt +++ b/src/main/kotlin/dev/usbharu/hideout/core/domain/model/relationship/RelationshipRepositoryImpl.kt @@ -50,6 +50,7 @@ class RelationshipRepositoryImpl : RelationshipRepository { } } + override suspend fun findByUserIdAndTargetUserId(actorId: Long, targetActorId: Long): Relationship? { return Relationships.select { (Relationships.actorId eq actorId) @@ -57,6 +58,12 @@ class RelationshipRepositoryImpl : RelationshipRepository { }.singleOrNull() ?.toRelationships() } + + override suspend fun deleteByActorIdOrTargetActorId(actorId: Long, targetActorId: Long) { + Relationships.deleteWhere { + Relationships.actorId.eq(actorId).or(Relationships.targetActorId.eq(targetActorId)) + } + } } fun ResultRow.toRelationships(): Relationship = Relationship( diff --git a/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/exposedquery/DeletedActorQueryServiceImpl.kt b/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/exposedquery/DeletedActorQueryServiceImpl.kt new file mode 100644 index 00000000..f412b310 --- /dev/null +++ b/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/exposedquery/DeletedActorQueryServiceImpl.kt @@ -0,0 +1,23 @@ +package dev.usbharu.hideout.core.infrastructure.exposedquery + +import dev.usbharu.hideout.core.domain.exception.FailedToGetResourcesException +import dev.usbharu.hideout.core.domain.model.deletedActor.DeletedActor +import dev.usbharu.hideout.core.infrastructure.exposedrepository.DeletedActors +import dev.usbharu.hideout.core.infrastructure.exposedrepository.toDeletedActor +import dev.usbharu.hideout.core.query.DeletedActorQueryService +import dev.usbharu.hideout.util.singleOr +import org.jetbrains.exposed.sql.and +import org.jetbrains.exposed.sql.select +import org.springframework.stereotype.Repository + +@Repository +class DeletedActorQueryServiceImpl : DeletedActorQueryService { + override suspend fun findByNameAndDomain(name: String, domain: String): DeletedActor { + return DeletedActors + .select { DeletedActors.name eq name and (DeletedActors.domain eq domain) } + .singleOr { + FailedToGetResourcesException("name: $name domain: $domain was not exist or duplicate.", it) + } + .toDeletedActor() + } +} diff --git a/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/exposedrepository/DeletedActorRepositoryImpl.kt b/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/exposedrepository/DeletedActorRepositoryImpl.kt new file mode 100644 index 00000000..440c1a36 --- /dev/null +++ b/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/exposedrepository/DeletedActorRepositoryImpl.kt @@ -0,0 +1,71 @@ +package dev.usbharu.hideout.core.infrastructure.exposedrepository + +import dev.usbharu.hideout.core.domain.exception.FailedToGetResourcesException +import dev.usbharu.hideout.core.domain.model.deletedActor.DeletedActor +import dev.usbharu.hideout.core.domain.model.deletedActor.DeletedActorRepository +import dev.usbharu.hideout.util.singleOr +import org.jetbrains.exposed.sql.* +import org.jetbrains.exposed.sql.SqlExpressionBuilder.eq +import org.jetbrains.exposed.sql.javatime.timestamp +import org.springframework.stereotype.Repository + +@Repository +class DeletedActorRepositoryImpl : DeletedActorRepository { + override suspend fun save(deletedActor: DeletedActor): DeletedActor { + val singleOrNull = DeletedActors.select { DeletedActors.id eq deletedActor.id }.singleOrNull() + + if (singleOrNull == null) { + DeletedActors.insert { + it[DeletedActors.id] = deletedActor.id + it[DeletedActors.name] = deletedActor.name + it[DeletedActors.domain] = deletedActor.domain + it[DeletedActors.publicKey] = deletedActor.publicKey + it[DeletedActors.deletedAt] = deletedActor.deletedAt + } + } else { + DeletedActors.update({ DeletedActors.id eq deletedActor.id }) { + it[DeletedActors.name] = deletedActor.name + it[DeletedActors.domain] = deletedActor.domain + it[DeletedActors.publicKey] = deletedActor.publicKey + it[DeletedActors.deletedAt] = deletedActor.deletedAt + } + } + return deletedActor + } + + override suspend fun delete(deletedActor: DeletedActor) { + DeletedActors.deleteWhere { DeletedActors.id eq deletedActor.id } + } + + override suspend fun findById(id: Long): DeletedActor { + val singleOr = DeletedActors.select { DeletedActors.id eq id } + .singleOr { FailedToGetResourcesException("id: $id was not exist or duplicate", it) } + + return deletedActor(singleOr) + } +} + +fun ResultRow.toDeletedActor(): DeletedActor = deletedActor(this) + +private fun deletedActor(singleOr: ResultRow): DeletedActor { + return DeletedActor( + singleOr[DeletedActors.id], + singleOr[DeletedActors.name], + singleOr[DeletedActors.domain], + singleOr[DeletedActors.publicKey], + singleOr[DeletedActors.deletedAt] + ) +} + +object DeletedActors : Table("deleted_actors") { + val id = long("id") + val name = varchar("name", 300) + val domain = varchar("domain", 255) + val publicKey = varchar("public_key", 10000).uniqueIndex() + val deletedAt = timestamp("deleted_at") + override val primaryKey: PrimaryKey = PrimaryKey(id) + + init { + uniqueIndex(name, domain) + } +} diff --git a/src/main/kotlin/dev/usbharu/hideout/core/query/DeletedActorQueryService.kt b/src/main/kotlin/dev/usbharu/hideout/core/query/DeletedActorQueryService.kt new file mode 100644 index 00000000..de7fcc53 --- /dev/null +++ b/src/main/kotlin/dev/usbharu/hideout/core/query/DeletedActorQueryService.kt @@ -0,0 +1,7 @@ +package dev.usbharu.hideout.core.query + +import dev.usbharu.hideout.core.domain.model.deletedActor.DeletedActor + +interface DeletedActorQueryService { + suspend fun findByNameAndDomain(name: String, domain: String): DeletedActor +} diff --git a/src/main/kotlin/dev/usbharu/hideout/core/service/post/PostServiceImpl.kt b/src/main/kotlin/dev/usbharu/hideout/core/service/post/PostServiceImpl.kt index e35e0c40..4a0a7cff 100644 --- a/src/main/kotlin/dev/usbharu/hideout/core/service/post/PostServiceImpl.kt +++ b/src/main/kotlin/dev/usbharu/hideout/core/service/post/PostServiceImpl.kt @@ -41,11 +41,17 @@ class PostServiceImpl( } override suspend fun deleteLocal(post: Post) { + if (post.delted) { + return + } reactionRepository.deleteByPostId(post.id) postRepository.save(post.delete()) } override suspend fun deleteRemote(post: Post) { + if (post.delted) { + return + } reactionRepository.deleteByPostId(post.id) postRepository.save(post.delete()) } diff --git a/src/main/kotlin/dev/usbharu/hideout/core/service/user/UserService.kt b/src/main/kotlin/dev/usbharu/hideout/core/service/user/UserService.kt index 06715df5..29bb738d 100644 --- a/src/main/kotlin/dev/usbharu/hideout/core/service/user/UserService.kt +++ b/src/main/kotlin/dev/usbharu/hideout/core/service/user/UserService.kt @@ -13,4 +13,8 @@ interface UserService { suspend fun createRemoteUser(user: RemoteUserCreateDto): Actor suspend fun updateUser(userId: Long, updateUserDto: UpdateUserDto) + + suspend fun deleteRemoteActor(actorId: Long) + + suspend fun deleteLocalUser(userId: Long) } diff --git a/src/main/kotlin/dev/usbharu/hideout/core/service/user/UserServiceImpl.kt b/src/main/kotlin/dev/usbharu/hideout/core/service/user/UserServiceImpl.kt index 442b676b..988cac62 100644 --- a/src/main/kotlin/dev/usbharu/hideout/core/service/user/UserServiceImpl.kt +++ b/src/main/kotlin/dev/usbharu/hideout/core/service/user/UserServiceImpl.kt @@ -1,11 +1,17 @@ package dev.usbharu.hideout.core.service.user import dev.usbharu.hideout.application.config.ApplicationConfig +import dev.usbharu.hideout.core.domain.exception.FailedToGetResourcesException import dev.usbharu.hideout.core.domain.model.actor.Actor import dev.usbharu.hideout.core.domain.model.actor.ActorRepository +import dev.usbharu.hideout.core.domain.model.deletedActor.DeletedActor +import dev.usbharu.hideout.core.domain.model.deletedActor.DeletedActorRepository +import dev.usbharu.hideout.core.domain.model.reaction.ReactionRepository +import dev.usbharu.hideout.core.domain.model.relationship.RelationshipRepository import dev.usbharu.hideout.core.domain.model.userdetails.UserDetail import dev.usbharu.hideout.core.domain.model.userdetails.UserDetailRepository import dev.usbharu.hideout.core.query.ActorQueryService +import dev.usbharu.hideout.core.query.DeletedActorQueryService import dev.usbharu.hideout.core.service.instance.InstanceService import org.jetbrains.exposed.exceptions.ExposedSQLException import org.slf4j.LoggerFactory @@ -21,7 +27,12 @@ class UserServiceImpl( private val actorBuilder: Actor.UserBuilder, private val applicationConfig: ApplicationConfig, private val instanceService: InstanceService, - private val userDetailRepository: UserDetailRepository + private val userDetailRepository: UserDetailRepository, + private val deletedActorRepository: DeletedActorRepository, + private val deletedActorQueryService: DeletedActorQueryService, + private val reactionRepository: ReactionRepository, + private val relationshipRepository: RelationshipRepository + ) : UserService { @@ -60,6 +71,14 @@ class UserServiceImpl( @Transactional override suspend fun createRemoteUser(user: RemoteUserCreateDto): Actor { logger.info("START Create New remote user. name: {} url: {}", user.name, user.url) + + try { + deletedActorQueryService.findByNameAndDomain(user.name, user.domain) + logger.warn("FAILED Deleted actor. user: ${user.name} domain: ${user.domain}") + throw IllegalStateException("Cannot create Deleted actor.") + } catch (_: FailedToGetResourcesException) { + } + @Suppress("TooGenericExceptionCaught") val instance = try { instanceService.fetchInstance(user.url, user.sharedInbox) @@ -117,6 +136,26 @@ class UserServiceImpl( ) } + override suspend fun deleteRemoteActor(actorId: Long) { + val actor = actorQueryService.findById(actorId) + val deletedActor = DeletedActor( + actor.id, + actor.name, + actor.domain, + actor.publicKey, + Instant.now() + ) + relationshipRepository.deleteByActorIdOrTargetActorId(actorId, actorId) + + reactionRepository.deleteByActorId(actorId) + + deletedActorRepository.save(deletedActor) + } + + override suspend fun deleteLocalUser(userId: Long) { + TODO("Not yet implemented") + } + companion object { private val logger = LoggerFactory.getLogger(UserServiceImpl::class.java) } diff --git a/src/main/resources/db/migration/V1__Init_DB.sql b/src/main/resources/db/migration/V1__Init_DB.sql index f680516b..741844d4 100644 --- a/src/main/resources/db/migration/V1__Init_DB.sql +++ b/src/main/resources/db/migration/V1__Init_DB.sql @@ -202,3 +202,13 @@ create table if not exists relationships insert into actors (id, name, domain, screen_name, description, inbox, outbox, url, public_key, private_key, created_at, key_id, following, followers, instance, locked) values (0, 'ghost', '', '', '', '', '', '', '', null, 0, '', '', '', null, true); + +create table if not exists deleted_actors +( + id bigint primary key, + "name" varchar(300) not null, + domain varchar(255) not null, + public_key varchar(10000) not null, + deleted_at timestamp not null, + unique ("name", domain) +) From 60b5b1f0c533f5005355ed797a91ca1d6ab1f11e Mon Sep 17 00:00:00 2001 From: usbharu <64310155+usbharu@users.noreply.github.com> Date: Wed, 13 Dec 2023 16:21:23 +0900 Subject: [PATCH 05/15] =?UTF-8?q?feat:=20=E3=82=A2=E3=82=AB=E3=82=A6?= =?UTF-8?q?=E3=83=B3=E3=83=88=E5=89=8A=E9=99=A4=E3=82=A2=E3=82=AF=E3=83=86?= =?UTF-8?q?=E3=82=A3=E3=83=93=E3=83=86=E3=82=A3=E3=81=AB=E5=AF=BE=E5=BF=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../activity/delete/APDeleteProcessor.kt | 31 ++++++++++++++----- 1 file changed, 24 insertions(+), 7 deletions(-) diff --git a/src/main/kotlin/dev/usbharu/hideout/activitypub/service/activity/delete/APDeleteProcessor.kt b/src/main/kotlin/dev/usbharu/hideout/activitypub/service/activity/delete/APDeleteProcessor.kt index c628e491..ef3a6b6f 100644 --- a/src/main/kotlin/dev/usbharu/hideout/activitypub/service/activity/delete/APDeleteProcessor.kt +++ b/src/main/kotlin/dev/usbharu/hideout/activitypub/service/activity/delete/APDeleteProcessor.kt @@ -3,37 +3,54 @@ 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.domain.model.HasId +import dev.usbharu.hideout.activitypub.domain.model.objects.ObjectValue import dev.usbharu.hideout.activitypub.service.common.AbstractActivityPubProcessor import dev.usbharu.hideout.activitypub.service.common.ActivityPubProcessContext import dev.usbharu.hideout.activitypub.service.common.ActivityType import dev.usbharu.hideout.application.external.Transaction import dev.usbharu.hideout.core.domain.exception.FailedToGetResourcesException +import dev.usbharu.hideout.core.query.ActorQueryService import dev.usbharu.hideout.core.query.PostQueryService import dev.usbharu.hideout.core.service.post.PostService +import dev.usbharu.hideout.core.service.user.UserService import org.springframework.stereotype.Service @Service class APDeleteProcessor( transaction: Transaction, private val postQueryService: PostQueryService, + private val actorQueryService: ActorQueryService, + private val userService: UserService, private val postService: PostService ) : AbstractActivityPubProcessor(transaction) { override suspend fun internalProcess(activity: ActivityPubProcessContext) { val value = activity.activity.apObject - if (value !is HasId) { - throw IllegalActivityPubObjectException("object hasn't id") + val deleteId = if (value is HasId) { + value.id + } else if (value is ObjectValue) { + value.`object` + } else { + throw IllegalActivityPubObjectException("object hasn't id or object") } - val deleteId = value.id - val post = try { - postQueryService.findByApId(deleteId) + + try { + val actor = actorQueryService.findByUrl(deleteId) + userService.deleteRemoteActor(actor.id) + } catch (e: Exception) { + logger.warn("FAILED delete id: {} is not found.", deleteId, e) + } + + try { + val post = postQueryService.findByApId(deleteId) + postService.deleteRemote(post) } catch (e: FailedToGetResourcesException) { logger.warn("FAILED delete id: {} is not found.", deleteId, e) - return + } - postService.deleteRemote(post) + } override fun isSupported(activityType: ActivityType): Boolean = activityType == ActivityType.Delete From c92e15f2208e813b522b5796eed42b378d91380c Mon Sep 17 00:00:00 2001 From: usbharu <64310155+usbharu@users.noreply.github.com> Date: Wed, 13 Dec 2023 16:45:14 +0900 Subject: [PATCH 06/15] =?UTF-8?q?feat:=20=E3=82=A2=E3=82=AB=E3=82=A6?= =?UTF-8?q?=E3=83=B3=E3=83=88=E5=89=8A=E9=99=A4=E3=82=92=E3=81=99=E3=82=8B?= =?UTF-8?q?=E3=81=93=E3=81=A8=E3=81=8C=E3=81=A7=E3=81=8D=E3=82=8B=E3=82=88?= =?UTF-8?q?=E3=81=86=E3=81=AB?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../activity/delete/APSendDeleteService.kt | 22 ++++++++++++++ .../exposedquery/PostQueryServiceImpl.kt | 4 +++ .../hideout/core/query/PostQueryService.kt | 1 + .../hideout/core/service/post/PostService.kt | 1 + .../core/service/post/PostServiceImpl.kt | 4 +++ .../core/service/user/UserServiceImpl.kt | 30 +++++++++++++++++-- 6 files changed, 60 insertions(+), 2 deletions(-) diff --git a/src/main/kotlin/dev/usbharu/hideout/activitypub/service/activity/delete/APSendDeleteService.kt b/src/main/kotlin/dev/usbharu/hideout/activitypub/service/activity/delete/APSendDeleteService.kt index 2cb0f86c..00aab8db 100644 --- a/src/main/kotlin/dev/usbharu/hideout/activitypub/service/activity/delete/APSendDeleteService.kt +++ b/src/main/kotlin/dev/usbharu/hideout/activitypub/service/activity/delete/APSendDeleteService.kt @@ -2,7 +2,9 @@ package dev.usbharu.hideout.activitypub.service.activity.delete import dev.usbharu.hideout.activitypub.domain.model.Delete import dev.usbharu.hideout.activitypub.domain.model.Tombstone +import dev.usbharu.hideout.activitypub.domain.model.objects.ObjectValue import dev.usbharu.hideout.application.config.ApplicationConfig +import dev.usbharu.hideout.core.domain.model.actor.Actor import dev.usbharu.hideout.core.domain.model.post.Post import dev.usbharu.hideout.core.external.job.DeliverDeleteJob import dev.usbharu.hideout.core.external.job.DeliverDeleteJobParam @@ -14,6 +16,7 @@ import java.time.Instant interface APSendDeleteService { suspend fun sendDeleteNote(deletedPost: Post) + suspend fun sendDeleteActor(deletedActor: Actor) } @Service @@ -47,4 +50,23 @@ class APSendDeleteServiceImpl( } } + override suspend fun sendDeleteActor(deletedActor: Actor) { + val followers = followerQueryService.findFollowersById(deletedActor.id) + + val delete = Delete( + actor = deletedActor.url, + `object` = ObjectValue(emptyList(), `object` = deletedActor.url), + id = "${applicationConfig.url}/delete/actor/${deletedActor.id}", + published = Instant.now().toString() + ) + + followers.forEach { + DeliverDeleteJobParam( + delete = delete, + it.inbox, + deletedActor.id + ) + } + } + } diff --git a/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/exposedquery/PostQueryServiceImpl.kt b/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/exposedquery/PostQueryServiceImpl.kt index e4b45ef0..9d76ae02 100644 --- a/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/exposedquery/PostQueryServiceImpl.kt +++ b/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/exposedquery/PostQueryServiceImpl.kt @@ -33,4 +33,8 @@ class PostQueryServiceImpl( .select { Posts.apId eq string } .let(postQueryMapper::map) .singleOr { FailedToGetResourcesException("apId: $string is duplicate or does not exist.", it) } + + override suspend fun findByActorId(actorId: Long): List { + return Posts.leftJoin(PostsMedia).select { Posts.actorId eq actorId }.let(postQueryMapper::map) + } } diff --git a/src/main/kotlin/dev/usbharu/hideout/core/query/PostQueryService.kt b/src/main/kotlin/dev/usbharu/hideout/core/query/PostQueryService.kt index 415db265..64999e89 100644 --- a/src/main/kotlin/dev/usbharu/hideout/core/query/PostQueryService.kt +++ b/src/main/kotlin/dev/usbharu/hideout/core/query/PostQueryService.kt @@ -8,4 +8,5 @@ interface PostQueryService { suspend fun findById(id: Long): Post suspend fun findByUrl(url: String): Post suspend fun findByApId(string: String): Post + suspend fun findByActorId(actorId: Long): List } diff --git a/src/main/kotlin/dev/usbharu/hideout/core/service/post/PostService.kt b/src/main/kotlin/dev/usbharu/hideout/core/service/post/PostService.kt index a20f0a66..2c6d5307 100644 --- a/src/main/kotlin/dev/usbharu/hideout/core/service/post/PostService.kt +++ b/src/main/kotlin/dev/usbharu/hideout/core/service/post/PostService.kt @@ -9,4 +9,5 @@ interface PostService { suspend fun createRemote(post: Post): Post suspend fun deleteLocal(post: Post) suspend fun deleteRemote(post: Post) + suspend fun deleteByActor(actorId: Long) } diff --git a/src/main/kotlin/dev/usbharu/hideout/core/service/post/PostServiceImpl.kt b/src/main/kotlin/dev/usbharu/hideout/core/service/post/PostServiceImpl.kt index 4a0a7cff..54a4ae1b 100644 --- a/src/main/kotlin/dev/usbharu/hideout/core/service/post/PostServiceImpl.kt +++ b/src/main/kotlin/dev/usbharu/hideout/core/service/post/PostServiceImpl.kt @@ -56,6 +56,10 @@ class PostServiceImpl( postRepository.save(post.delete()) } + override suspend fun deleteByActor(actorId: Long) { + postQueryService.findByActorId(actorId).filterNot { it.delted }.forEach { postRepository.save(it.delete()) } + } + private suspend fun internalCreate(post: Post, isLocal: Boolean): Post { return try { if (postRepository.save(post)) { diff --git a/src/main/kotlin/dev/usbharu/hideout/core/service/user/UserServiceImpl.kt b/src/main/kotlin/dev/usbharu/hideout/core/service/user/UserServiceImpl.kt index 988cac62..a49e58b5 100644 --- a/src/main/kotlin/dev/usbharu/hideout/core/service/user/UserServiceImpl.kt +++ b/src/main/kotlin/dev/usbharu/hideout/core/service/user/UserServiceImpl.kt @@ -1,5 +1,6 @@ package dev.usbharu.hideout.core.service.user +import dev.usbharu.hideout.activitypub.service.activity.delete.APSendDeleteService import dev.usbharu.hideout.application.config.ApplicationConfig import dev.usbharu.hideout.core.domain.exception.FailedToGetResourcesException import dev.usbharu.hideout.core.domain.model.actor.Actor @@ -13,6 +14,7 @@ import dev.usbharu.hideout.core.domain.model.userdetails.UserDetailRepository import dev.usbharu.hideout.core.query.ActorQueryService import dev.usbharu.hideout.core.query.DeletedActorQueryService import dev.usbharu.hideout.core.service.instance.InstanceService +import dev.usbharu.hideout.core.service.post.PostService import org.jetbrains.exposed.exceptions.ExposedSQLException import org.slf4j.LoggerFactory import org.springframework.stereotype.Service @@ -31,7 +33,9 @@ class UserServiceImpl( private val deletedActorRepository: DeletedActorRepository, private val deletedActorQueryService: DeletedActorQueryService, private val reactionRepository: ReactionRepository, - private val relationshipRepository: RelationshipRepository + private val relationshipRepository: RelationshipRepository, + private val postService: PostService, + private val apSendDeleteService: APSendDeleteService ) : UserService { @@ -149,11 +153,33 @@ class UserServiceImpl( reactionRepository.deleteByActorId(actorId) + postService.deleteByActor(actorId) + + actorRepository.delete(actor.id) deletedActorRepository.save(deletedActor) } override suspend fun deleteLocalUser(userId: Long) { - TODO("Not yet implemented") + val actor = actorQueryService.findById(userId) + apSendDeleteService.sendDeleteActor(actor) + val deletedActor = DeletedActor( + actor.id, + actor.name, + actor.domain, + actor.publicKey, + Instant.now() + ) + relationshipRepository.deleteByActorIdOrTargetActorId(userId, userId) + + reactionRepository.deleteByActorId(actor.id) + + postService.deleteByActor(actor.id) + actorRepository.delete(actor.id) + val userDetail = + userDetailRepository.findByActorId(actor.id) ?: throw IllegalStateException("user detail not found.") + userDetailRepository.delete(userDetail) + deletedActorRepository.save(deletedActor) + } companion object { From 5093585c7ebd33b5c0d3e4604c2fd3538ca7a7f2 Mon Sep 17 00:00:00 2001 From: usbharu <64310155+usbharu@users.noreply.github.com> Date: Wed, 13 Dec 2023 17:02:00 +0900 Subject: [PATCH 07/15] =?UTF-8?q?test:=20=E3=83=86=E3=82=B9=E3=83=88?= =?UTF-8?q?=E3=82=92=E4=BF=AE=E6=AD=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../core/service/post/PostServiceImplTest.kt | 4 ++ .../core/service/user/ActorServiceTest.kt | 46 +++++++++++++++---- 2 files changed, 42 insertions(+), 8 deletions(-) diff --git a/src/test/kotlin/dev/usbharu/hideout/core/service/post/PostServiceImplTest.kt b/src/test/kotlin/dev/usbharu/hideout/core/service/post/PostServiceImplTest.kt index 9ebbae81..8efae4ec 100644 --- a/src/test/kotlin/dev/usbharu/hideout/core/service/post/PostServiceImplTest.kt +++ b/src/test/kotlin/dev/usbharu/hideout/core/service/post/PostServiceImplTest.kt @@ -5,6 +5,7 @@ import dev.usbharu.hideout.application.config.CharacterLimit import dev.usbharu.hideout.core.domain.model.actor.ActorRepository import dev.usbharu.hideout.core.domain.model.post.Post import dev.usbharu.hideout.core.domain.model.post.PostRepository +import dev.usbharu.hideout.core.domain.model.reaction.ReactionRepository import dev.usbharu.hideout.core.query.PostQueryService import dev.usbharu.hideout.core.service.timeline.TimelineService import kotlinx.coroutines.test.runTest @@ -45,6 +46,9 @@ class PostServiceImplTest { @Mock private lateinit var apSendCreateService: ApSendCreateService + @Mock + private lateinit var reactionRepository: ReactionRepository + @InjectMocks private lateinit var postServiceImpl: PostServiceImpl diff --git a/src/test/kotlin/dev/usbharu/hideout/core/service/user/ActorServiceTest.kt b/src/test/kotlin/dev/usbharu/hideout/core/service/user/ActorServiceTest.kt index 9d5b6f10..d41e7e32 100644 --- a/src/test/kotlin/dev/usbharu/hideout/core/service/user/ActorServiceTest.kt +++ b/src/test/kotlin/dev/usbharu/hideout/core/service/user/ActorServiceTest.kt @@ -4,9 +4,11 @@ package dev.usbharu.hideout.core.service.user import dev.usbharu.hideout.application.config.ApplicationConfig import dev.usbharu.hideout.application.config.CharacterLimit +import dev.usbharu.hideout.core.domain.exception.FailedToGetResourcesException import dev.usbharu.hideout.core.domain.model.actor.Actor import dev.usbharu.hideout.core.domain.model.actor.ActorRepository import dev.usbharu.hideout.core.domain.model.post.Post +import dev.usbharu.hideout.core.query.DeletedActorQueryService import kotlinx.coroutines.ExperimentalCoroutinesApi import kotlinx.coroutines.test.runTest import org.junit.jupiter.api.Test @@ -34,13 +36,19 @@ class ActorServiceTest { } val userService = UserServiceImpl( - actorRepository, - userAuthService, - mock(), - actorBuilder, - testApplicationConfig, - mock(), - mock() + actorRepository = actorRepository, + userAuthService = userAuthService, + actorQueryService = mock(), + actorBuilder = actorBuilder, + applicationConfig = testApplicationConfig, + instanceService = mock(), + userDetailRepository = mock(), + deletedActorRepository = mock(), + deletedActorQueryService = mock(), + reactionRepository = mock(), + relationshipRepository = mock(), + postService = mock(), + apSendDeleteService = mock() ) userService.createLocalUser(UserCreateDto("test", "testUser", "XXXXXXXXXXXXX", "test")) verify(actorRepository, times(1)).save(any()) @@ -65,8 +73,30 @@ class ActorServiceTest { val actorRepository = mock { onBlocking { nextId() } doReturn 113345L } + val deletedActorQueryService = mock { + onBlocking { + findByNameAndDomain( + eq("test"), + eq("remote.example.com") + ) + } doAnswer { throw FailedToGetResourcesException() } + } val userService = - UserServiceImpl(actorRepository, mock(), mock(), actorBuilder, testApplicationConfig, mock(), mock()) + UserServiceImpl( + actorRepository = actorRepository, + userAuthService = mock(), + actorQueryService = mock(), + actorBuilder = actorBuilder, + applicationConfig = testApplicationConfig, + instanceService = mock(), + userDetailRepository = mock(), + deletedActorRepository = mock(), + deletedActorQueryService = deletedActorQueryService, + reactionRepository = mock(), + relationshipRepository = mock(), + postService = mock(), + apSendDeleteService = mock() + ) val user = RemoteUserCreateDto( name = "test", domain = "remote.example.com", From 8aba7ecdc19acff9468ac506c949400926139f27 Mon Sep 17 00:00:00 2001 From: usbharu Date: Wed, 13 Dec 2023 17:30:55 +0900 Subject: [PATCH 08/15] Update src/main/kotlin/dev/usbharu/hideout/activitypub/domain/model/Person.kt Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> --- .../activitypub/domain/model/Person.kt | 30 +++++++++---------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/src/main/kotlin/dev/usbharu/hideout/activitypub/domain/model/Person.kt b/src/main/kotlin/dev/usbharu/hideout/activitypub/domain/model/Person.kt index af5e045c..369905ec 100644 --- a/src/main/kotlin/dev/usbharu/hideout/activitypub/domain/model/Person.kt +++ b/src/main/kotlin/dev/usbharu/hideout/activitypub/domain/model/Person.kt @@ -67,20 +67,20 @@ constructor( override fun toString(): String { return "Person(" + - "name='$name', " + - "id='$id', " + - "preferredUsername=$preferredUsername, " + - "summary=$summary, " + - "inbox='$inbox', " + - "outbox='$outbox', " + - "url='$url', " + - "icon=$icon, " + - "publicKey=$publicKey, " + - "endpoints=$endpoints, " + - "followers=$followers, " + - "following=$following, " + - "manuallyApprovesFollowers=$manuallyApprovesFollowers" + - ")" + - " ${super.toString()}" + "name='$name', " + + "id='$id', " + + "preferredUsername=$preferredUsername, " + + "summary=$summary, " + + "inbox='$inbox', " + + "outbox='$outbox', " + + "url='$url', " + + "icon=$icon, " + + "publicKey=$publicKey, " + + "endpoints=$endpoints, " + + "followers=$followers, " + + "following=$following, " + + "manuallyApprovesFollowers=$manuallyApprovesFollowers" + + ")" + + " ${super.toString()}" } } From 3214d2041e16fe3ac385b806024e4dfaada5c5f1 Mon Sep 17 00:00:00 2001 From: usbharu Date: Wed, 13 Dec 2023 17:31:11 +0900 Subject: [PATCH 09/15] Update src/main/kotlin/dev/usbharu/hideout/activitypub/service/activity/delete/APDeleteProcessor.kt Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> --- .../activitypub/service/activity/delete/APDeleteProcessor.kt | 1 - 1 file changed, 1 deletion(-) diff --git a/src/main/kotlin/dev/usbharu/hideout/activitypub/service/activity/delete/APDeleteProcessor.kt b/src/main/kotlin/dev/usbharu/hideout/activitypub/service/activity/delete/APDeleteProcessor.kt index ef3a6b6f..63f6883f 100644 --- a/src/main/kotlin/dev/usbharu/hideout/activitypub/service/activity/delete/APDeleteProcessor.kt +++ b/src/main/kotlin/dev/usbharu/hideout/activitypub/service/activity/delete/APDeleteProcessor.kt @@ -34,7 +34,6 @@ class APDeleteProcessor( throw IllegalActivityPubObjectException("object hasn't id or object") } - try { val actor = actorQueryService.findByUrl(deleteId) userService.deleteRemoteActor(actor.id) From 81965dee92fd8c2245cb128564568662016f0d17 Mon Sep 17 00:00:00 2001 From: usbharu Date: Wed, 13 Dec 2023 17:31:16 +0900 Subject: [PATCH 10/15] Update src/main/kotlin/dev/usbharu/hideout/activitypub/service/activity/delete/APDeleteProcessor.kt Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> --- .../activitypub/service/activity/delete/APDeleteProcessor.kt | 1 - 1 file changed, 1 deletion(-) diff --git a/src/main/kotlin/dev/usbharu/hideout/activitypub/service/activity/delete/APDeleteProcessor.kt b/src/main/kotlin/dev/usbharu/hideout/activitypub/service/activity/delete/APDeleteProcessor.kt index 63f6883f..1ebdf053 100644 --- a/src/main/kotlin/dev/usbharu/hideout/activitypub/service/activity/delete/APDeleteProcessor.kt +++ b/src/main/kotlin/dev/usbharu/hideout/activitypub/service/activity/delete/APDeleteProcessor.kt @@ -46,7 +46,6 @@ class APDeleteProcessor( postService.deleteRemote(post) } catch (e: FailedToGetResourcesException) { logger.warn("FAILED delete id: {} is not found.", deleteId, e) - } From 9e22206ed6dc72fe1b27b48fd7c6f3a87d121295 Mon Sep 17 00:00:00 2001 From: usbharu Date: Wed, 13 Dec 2023 17:31:23 +0900 Subject: [PATCH 11/15] Update src/main/kotlin/dev/usbharu/hideout/activitypub/service/activity/delete/APSendDeleteService.kt Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> --- .../activitypub/service/activity/delete/APSendDeleteService.kt | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/main/kotlin/dev/usbharu/hideout/activitypub/service/activity/delete/APSendDeleteService.kt b/src/main/kotlin/dev/usbharu/hideout/activitypub/service/activity/delete/APSendDeleteService.kt index 00aab8db..e4a4ea27 100644 --- a/src/main/kotlin/dev/usbharu/hideout/activitypub/service/activity/delete/APSendDeleteService.kt +++ b/src/main/kotlin/dev/usbharu/hideout/activitypub/service/activity/delete/APSendDeleteService.kt @@ -28,8 +28,6 @@ class APSendDeleteServiceImpl( private val applicationConfig: ApplicationConfig ) : APSendDeleteService { override suspend fun sendDeleteNote(deletedPost: Post) { - - val actor = actorQueryService.findById(deletedPost.actorId) val followersById = followerQueryService.findFollowersById(deletedPost.actorId) From 6dda54fb8f1e86a7cb43caba5f35599289e8c37e Mon Sep 17 00:00:00 2001 From: usbharu Date: Wed, 13 Dec 2023 17:31:43 +0900 Subject: [PATCH 12/15] Update src/main/kotlin/dev/usbharu/hideout/activitypub/service/activity/delete/APSendDeleteService.kt Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> --- .../activitypub/service/activity/delete/APSendDeleteService.kt | 1 - 1 file changed, 1 deletion(-) diff --git a/src/main/kotlin/dev/usbharu/hideout/activitypub/service/activity/delete/APSendDeleteService.kt b/src/main/kotlin/dev/usbharu/hideout/activitypub/service/activity/delete/APSendDeleteService.kt index e4a4ea27..2d1dde2a 100644 --- a/src/main/kotlin/dev/usbharu/hideout/activitypub/service/activity/delete/APSendDeleteService.kt +++ b/src/main/kotlin/dev/usbharu/hideout/activitypub/service/activity/delete/APSendDeleteService.kt @@ -66,5 +66,4 @@ class APSendDeleteServiceImpl( ) } } - } From eb634e4c7eb6d92ac94538ede7b262ebdc9c457b Mon Sep 17 00:00:00 2001 From: usbharu Date: Wed, 13 Dec 2023 17:31:53 +0900 Subject: [PATCH 13/15] Update src/main/kotlin/dev/usbharu/hideout/core/domain/model/relationship/RelationshipRepositoryImpl.kt Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> --- .../core/domain/model/relationship/RelationshipRepositoryImpl.kt | 1 - 1 file changed, 1 deletion(-) diff --git a/src/main/kotlin/dev/usbharu/hideout/core/domain/model/relationship/RelationshipRepositoryImpl.kt b/src/main/kotlin/dev/usbharu/hideout/core/domain/model/relationship/RelationshipRepositoryImpl.kt index 844b886f..57610d1d 100644 --- a/src/main/kotlin/dev/usbharu/hideout/core/domain/model/relationship/RelationshipRepositoryImpl.kt +++ b/src/main/kotlin/dev/usbharu/hideout/core/domain/model/relationship/RelationshipRepositoryImpl.kt @@ -50,7 +50,6 @@ class RelationshipRepositoryImpl : RelationshipRepository { } } - override suspend fun findByUserIdAndTargetUserId(actorId: Long, targetActorId: Long): Relationship? { return Relationships.select { (Relationships.actorId eq actorId) From c3a37b4ca700192aeef9d0524360b7d2883d5f12 Mon Sep 17 00:00:00 2001 From: usbharu Date: Wed, 13 Dec 2023 17:31:59 +0900 Subject: [PATCH 14/15] Update src/main/kotlin/dev/usbharu/hideout/core/service/user/UserServiceImpl.kt Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> --- .../dev/usbharu/hideout/core/service/user/UserServiceImpl.kt | 1 - 1 file changed, 1 deletion(-) diff --git a/src/main/kotlin/dev/usbharu/hideout/core/service/user/UserServiceImpl.kt b/src/main/kotlin/dev/usbharu/hideout/core/service/user/UserServiceImpl.kt index a49e58b5..d9a2086f 100644 --- a/src/main/kotlin/dev/usbharu/hideout/core/service/user/UserServiceImpl.kt +++ b/src/main/kotlin/dev/usbharu/hideout/core/service/user/UserServiceImpl.kt @@ -179,7 +179,6 @@ class UserServiceImpl( userDetailRepository.findByActorId(actor.id) ?: throw IllegalStateException("user detail not found.") userDetailRepository.delete(userDetail) deletedActorRepository.save(deletedActor) - } companion object { From e1fdb47220eabf7980024aeb6ad06d7a4b599661 Mon Sep 17 00:00:00 2001 From: usbharu <64310155+usbharu@users.noreply.github.com> Date: Wed, 13 Dec 2023 17:40:20 +0900 Subject: [PATCH 15/15] style: fix lint --- .../activitypub/service/activity/delete/APDeleteProcessor.kt | 2 -- .../dev/usbharu/hideout/core/domain/model/post/Post.kt | 1 + .../core/infrastructure/exposed/PostResultRowMapper.kt | 4 ++-- .../core/infrastructure/exposedquery/PostQueryServiceImpl.kt | 5 ++--- .../usbharu/hideout/core/query/RelationshipQueryService.kt | 2 +- .../dev/usbharu/hideout/core/service/user/UserServiceImpl.kt | 1 + 6 files changed, 7 insertions(+), 8 deletions(-) diff --git a/src/main/kotlin/dev/usbharu/hideout/activitypub/service/activity/delete/APDeleteProcessor.kt b/src/main/kotlin/dev/usbharu/hideout/activitypub/service/activity/delete/APDeleteProcessor.kt index 1ebdf053..508c3d45 100644 --- a/src/main/kotlin/dev/usbharu/hideout/activitypub/service/activity/delete/APDeleteProcessor.kt +++ b/src/main/kotlin/dev/usbharu/hideout/activitypub/service/activity/delete/APDeleteProcessor.kt @@ -47,8 +47,6 @@ class APDeleteProcessor( } catch (e: FailedToGetResourcesException) { logger.warn("FAILED delete id: {} is not found.", deleteId, e) } - - } override fun isSupported(activityType: ActivityType): Boolean = activityType == ActivityType.Delete diff --git a/src/main/kotlin/dev/usbharu/hideout/core/domain/model/post/Post.kt b/src/main/kotlin/dev/usbharu/hideout/core/domain/model/post/Post.kt index 6cbc765e..cc9edc51 100644 --- a/src/main/kotlin/dev/usbharu/hideout/core/domain/model/post/Post.kt +++ b/src/main/kotlin/dev/usbharu/hideout/core/domain/model/post/Post.kt @@ -78,6 +78,7 @@ data class Post private constructor( ) } + @Suppress("LongParameterList") fun deleteOf( id: Long, visibility: Visibility, diff --git a/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/exposed/PostResultRowMapper.kt b/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/exposed/PostResultRowMapper.kt index 22faf1b2..ed3802f6 100644 --- a/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/exposed/PostResultRowMapper.kt +++ b/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/exposed/PostResultRowMapper.kt @@ -12,8 +12,8 @@ class PostResultRowMapper(private val postBuilder: Post.PostBuilder) : ResultRow override fun map(resultRow: ResultRow): Post { if (resultRow[Posts.deleted]) { return postBuilder.deleteOf( - resultRow[Posts.id], - Visibility.values().first { it.ordinal == resultRow[Posts.visibility] }, + id = resultRow[Posts.id], + visibility = Visibility.values().first { it.ordinal == resultRow[Posts.visibility] }, url = resultRow[Posts.url], repostId = resultRow[Posts.repostId], replyId = resultRow[Posts.replyId], diff --git a/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/exposedquery/PostQueryServiceImpl.kt b/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/exposedquery/PostQueryServiceImpl.kt index 9d76ae02..65d8d492 100644 --- a/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/exposedquery/PostQueryServiceImpl.kt +++ b/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/exposedquery/PostQueryServiceImpl.kt @@ -34,7 +34,6 @@ class PostQueryServiceImpl( .let(postQueryMapper::map) .singleOr { FailedToGetResourcesException("apId: $string is duplicate or does not exist.", it) } - override suspend fun findByActorId(actorId: Long): List { - return Posts.leftJoin(PostsMedia).select { Posts.actorId eq actorId }.let(postQueryMapper::map) - } + override suspend fun findByActorId(actorId: Long): List = + Posts.leftJoin(PostsMedia).select { Posts.actorId eq actorId }.let(postQueryMapper::map) } diff --git a/src/main/kotlin/dev/usbharu/hideout/core/query/RelationshipQueryService.kt b/src/main/kotlin/dev/usbharu/hideout/core/query/RelationshipQueryService.kt index c4219711..c7b2fb18 100644 --- a/src/main/kotlin/dev/usbharu/hideout/core/query/RelationshipQueryService.kt +++ b/src/main/kotlin/dev/usbharu/hideout/core/query/RelationshipQueryService.kt @@ -6,7 +6,7 @@ interface RelationshipQueryService { suspend fun findByTargetIdAndFollowing(targetId: Long, following: Boolean): List - @Suppress("LongParameterList") + @Suppress("LongParameterList", "FunctionMaxLength") suspend fun findByTargetIdAndFollowRequestAndIgnoreFollowRequest( maxId: Long?, sinceId: Long?, diff --git a/src/main/kotlin/dev/usbharu/hideout/core/service/user/UserServiceImpl.kt b/src/main/kotlin/dev/usbharu/hideout/core/service/user/UserServiceImpl.kt index d9a2086f..36259740 100644 --- a/src/main/kotlin/dev/usbharu/hideout/core/service/user/UserServiceImpl.kt +++ b/src/main/kotlin/dev/usbharu/hideout/core/service/user/UserServiceImpl.kt @@ -22,6 +22,7 @@ import org.springframework.transaction.annotation.Transactional import java.time.Instant @Service +@Suppress("LongParameterList") class UserServiceImpl( private val actorRepository: ActorRepository, private val userAuthService: UserAuthService,