feat: アカウント削除をすることができるように

This commit is contained in:
usbharu 2023-12-13 16:45:14 +09:00
parent c98a90e2fc
commit 9f05e296a6
6 changed files with 60 additions and 2 deletions

View File

@ -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.Delete
import dev.usbharu.hideout.activitypub.domain.model.Tombstone 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.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.domain.model.post.Post
import dev.usbharu.hideout.core.external.job.DeliverDeleteJob import dev.usbharu.hideout.core.external.job.DeliverDeleteJob
import dev.usbharu.hideout.core.external.job.DeliverDeleteJobParam import dev.usbharu.hideout.core.external.job.DeliverDeleteJobParam
@ -14,6 +16,7 @@ import java.time.Instant
interface APSendDeleteService { interface APSendDeleteService {
suspend fun sendDeleteNote(deletedPost: Post) suspend fun sendDeleteNote(deletedPost: Post)
suspend fun sendDeleteActor(deletedActor: Actor)
} }
@Service @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
)
}
}
} }

View File

@ -33,4 +33,8 @@ class PostQueryServiceImpl(
.select { Posts.apId eq string } .select { Posts.apId eq string }
.let(postQueryMapper::map) .let(postQueryMapper::map)
.singleOr { FailedToGetResourcesException("apId: $string is duplicate or does not exist.", it) } .singleOr { FailedToGetResourcesException("apId: $string is duplicate or does not exist.", it) }
override suspend fun findByActorId(actorId: Long): List<Post> {
return Posts.leftJoin(PostsMedia).select { Posts.actorId eq actorId }.let(postQueryMapper::map)
}
} }

View File

@ -8,4 +8,5 @@ interface PostQueryService {
suspend fun findById(id: Long): Post suspend fun findById(id: Long): Post
suspend fun findByUrl(url: String): Post suspend fun findByUrl(url: String): Post
suspend fun findByApId(string: String): Post suspend fun findByApId(string: String): Post
suspend fun findByActorId(actorId: Long): List<Post>
} }

View File

@ -9,4 +9,5 @@ interface PostService {
suspend fun createRemote(post: Post): Post suspend fun createRemote(post: Post): Post
suspend fun deleteLocal(post: Post) suspend fun deleteLocal(post: Post)
suspend fun deleteRemote(post: Post) suspend fun deleteRemote(post: Post)
suspend fun deleteByActor(actorId: Long)
} }

View File

@ -56,6 +56,10 @@ class PostServiceImpl(
postRepository.save(post.delete()) 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 { private suspend fun internalCreate(post: Post, isLocal: Boolean): Post {
return try { return try {
if (postRepository.save(post)) { if (postRepository.save(post)) {

View File

@ -1,5 +1,6 @@
package dev.usbharu.hideout.core.service.user 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.application.config.ApplicationConfig
import dev.usbharu.hideout.core.domain.exception.FailedToGetResourcesException 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.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.ActorQueryService
import dev.usbharu.hideout.core.query.DeletedActorQueryService import dev.usbharu.hideout.core.query.DeletedActorQueryService
import dev.usbharu.hideout.core.service.instance.InstanceService import dev.usbharu.hideout.core.service.instance.InstanceService
import dev.usbharu.hideout.core.service.post.PostService
import org.jetbrains.exposed.exceptions.ExposedSQLException import org.jetbrains.exposed.exceptions.ExposedSQLException
import org.slf4j.LoggerFactory import org.slf4j.LoggerFactory
import org.springframework.stereotype.Service import org.springframework.stereotype.Service
@ -31,7 +33,9 @@ class UserServiceImpl(
private val deletedActorRepository: DeletedActorRepository, private val deletedActorRepository: DeletedActorRepository,
private val deletedActorQueryService: DeletedActorQueryService, private val deletedActorQueryService: DeletedActorQueryService,
private val reactionRepository: ReactionRepository, private val reactionRepository: ReactionRepository,
private val relationshipRepository: RelationshipRepository private val relationshipRepository: RelationshipRepository,
private val postService: PostService,
private val apSendDeleteService: APSendDeleteService
) : ) :
UserService { UserService {
@ -149,11 +153,33 @@ class UserServiceImpl(
reactionRepository.deleteByActorId(actorId) reactionRepository.deleteByActorId(actorId)
postService.deleteByActor(actorId)
actorRepository.delete(actor.id)
deletedActorRepository.save(deletedActor) deletedActorRepository.save(deletedActor)
} }
override suspend fun deleteLocalUser(userId: Long) { 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 { companion object {