mirror of https://github.com/usbharu/Hideout.git
feat: その他のActivityPubプロセッサーを追加
This commit is contained in:
parent
2cfb6bd9e9
commit
0790f4b0ef
|
@ -10,6 +10,7 @@ import dev.usbharu.hideout.core.service.user.UserService
|
||||||
import org.slf4j.LoggerFactory
|
import org.slf4j.LoggerFactory
|
||||||
import org.springframework.stereotype.Service
|
import org.springframework.stereotype.Service
|
||||||
|
|
||||||
|
@Deprecated("use activitypub processor")
|
||||||
interface APAcceptService {
|
interface APAcceptService {
|
||||||
suspend fun receiveAccept(accept: Accept)
|
suspend fun receiveAccept(accept: Accept)
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,50 @@
|
||||||
|
package dev.usbharu.hideout.activitypub.service.activity.accept
|
||||||
|
|
||||||
|
import dev.usbharu.hideout.activitypub.domain.exception.IllegalActivityPubObjectException
|
||||||
|
import dev.usbharu.hideout.activitypub.domain.model.Accept
|
||||||
|
import dev.usbharu.hideout.activitypub.domain.model.Follow
|
||||||
|
import dev.usbharu.hideout.activitypub.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.query.FollowerQueryService
|
||||||
|
import dev.usbharu.hideout.core.query.UserQueryService
|
||||||
|
import dev.usbharu.hideout.core.service.user.UserService
|
||||||
|
|
||||||
|
class ApAcceptProcessor(
|
||||||
|
private val transaction: Transaction,
|
||||||
|
private val userQueryService: UserQueryService,
|
||||||
|
private val followerQueryService: FollowerQueryService,
|
||||||
|
private val userService: UserService
|
||||||
|
) :
|
||||||
|
AbstractActivityPubProcessor<Accept>(transaction) {
|
||||||
|
|
||||||
|
override suspend fun internalProcess(activity: ActivityPubProcessContext<Accept>) {
|
||||||
|
val value = activity.activity.`object` ?: throw IllegalActivityPubObjectException("object is null")
|
||||||
|
|
||||||
|
if (value.type.contains("Follow").not()) {
|
||||||
|
logger.warn("FAILED Activity type is not Follow.")
|
||||||
|
throw IllegalActivityPubObjectException("Invalid type ${value.type}")
|
||||||
|
}
|
||||||
|
|
||||||
|
val follow = value as Follow
|
||||||
|
|
||||||
|
val userUrl = follow.`object` ?: throw IllegalActivityPubObjectException("object is null")
|
||||||
|
val followerUrl = follow.actor ?: throw IllegalActivityPubObjectException("actor is null")
|
||||||
|
|
||||||
|
val user = userQueryService.findByUrl(userUrl)
|
||||||
|
val follower = userQueryService.findByUrl(followerUrl)
|
||||||
|
|
||||||
|
if (followerQueryService.alreadyFollow(user.id, follower.id)) {
|
||||||
|
logger.debug("END User already follow from ${follower.url} to ${user.url}.")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
userService.follow(user.id, follower.id)
|
||||||
|
logger.debug("SUCCESS Follow from ${follower.url} to ${user.url}.")
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun isSupported(activityType: ActivityType): Boolean = activityType == ActivityType.Accept
|
||||||
|
|
||||||
|
override fun type(): Class<Accept> = Accept::class.java
|
||||||
|
}
|
|
@ -0,0 +1,35 @@
|
||||||
|
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.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.domain.model.post.PostRepository
|
||||||
|
import dev.usbharu.hideout.core.query.PostQueryService
|
||||||
|
|
||||||
|
class APDeleteProcessor(
|
||||||
|
transaction: Transaction,
|
||||||
|
private val postQueryService: PostQueryService,
|
||||||
|
private val postRepository: PostRepository
|
||||||
|
) :
|
||||||
|
AbstractActivityPubProcessor<Delete>(transaction) {
|
||||||
|
override suspend fun internalProcess(activity: ActivityPubProcessContext<Delete>) {
|
||||||
|
val deleteId = activity.activity.`object`?.id ?: throw IllegalActivityPubObjectException("object.id is null")
|
||||||
|
|
||||||
|
val post = try {
|
||||||
|
postQueryService.findByApId(deleteId)
|
||||||
|
} catch (e: FailedToGetResourcesException) {
|
||||||
|
logger.warn("FAILED delete id: {} is not found.", deleteId)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
postRepository.delete(post.id)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun isSupported(activityType: ActivityType): Boolean = activityType == ActivityType.Delete
|
||||||
|
|
||||||
|
override fun type(): Class<Delete> = Delete::class.java
|
||||||
|
}
|
|
@ -0,0 +1,35 @@
|
||||||
|
package dev.usbharu.hideout.activitypub.service.activity.follow
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.databind.ObjectMapper
|
||||||
|
import dev.usbharu.hideout.activitypub.domain.exception.IllegalActivityPubObjectException
|
||||||
|
import dev.usbharu.hideout.activitypub.domain.model.Follow
|
||||||
|
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.external.job.ReceiveFollowJob
|
||||||
|
import dev.usbharu.hideout.core.external.job.ReceiveFollowJobParam
|
||||||
|
import dev.usbharu.hideout.core.service.job.JobQueueParentService
|
||||||
|
|
||||||
|
class APFollowProcessor(
|
||||||
|
transaction: Transaction,
|
||||||
|
private val jobQueueParentService: JobQueueParentService,
|
||||||
|
private val objectMapper: ObjectMapper
|
||||||
|
) :
|
||||||
|
AbstractActivityPubProcessor<Follow>(transaction) {
|
||||||
|
override suspend fun internalProcess(activity: ActivityPubProcessContext<Follow>) {
|
||||||
|
logger.info("FOLLOW from: {} to {}", activity.activity.actor, activity.activity.`object`)
|
||||||
|
|
||||||
|
// inboxをジョブキューに乗せているので既に不要だが、フォロー承認制アカウントを実装する際に必要なので残す
|
||||||
|
val jobProps = ReceiveFollowJobParam(
|
||||||
|
activity.activity.actor ?: throw IllegalActivityPubObjectException("actor is null"),
|
||||||
|
objectMapper.writeValueAsString(activity.activity),
|
||||||
|
activity.activity.`object` ?: throw IllegalActivityPubObjectException("object is null")
|
||||||
|
)
|
||||||
|
jobQueueParentService.scheduleTypeSafe(ReceiveFollowJob, jobProps)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun isSupported(activityType: ActivityType): Boolean = activityType == ActivityType.Follow
|
||||||
|
|
||||||
|
override fun type(): Class<Follow> = Follow::class.java
|
||||||
|
}
|
|
@ -3,6 +3,7 @@ package dev.usbharu.hideout.activitypub.service.activity.follow
|
||||||
import dev.usbharu.hideout.core.external.job.ReceiveFollowJob
|
import dev.usbharu.hideout.core.external.job.ReceiveFollowJob
|
||||||
import kjob.core.job.JobProps
|
import kjob.core.job.JobProps
|
||||||
|
|
||||||
|
@Deprecated("use activitypub processor")
|
||||||
interface APReceiveFollowJobService {
|
interface APReceiveFollowJobService {
|
||||||
suspend fun receiveFollowJob(props: JobProps<ReceiveFollowJob>)
|
suspend fun receiveFollowJob(props: JobProps<ReceiveFollowJob>)
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,6 +16,7 @@ import org.springframework.beans.factory.annotation.Qualifier
|
||||||
import org.springframework.stereotype.Component
|
import org.springframework.stereotype.Component
|
||||||
|
|
||||||
@Component
|
@Component
|
||||||
|
@Deprecated("use activitypub processor")
|
||||||
class APReceiveFollowJobServiceImpl(
|
class APReceiveFollowJobServiceImpl(
|
||||||
private val apUserService: APUserService,
|
private val apUserService: APUserService,
|
||||||
private val userQueryService: UserQueryService,
|
private val userQueryService: UserQueryService,
|
||||||
|
|
|
@ -0,0 +1,54 @@
|
||||||
|
package dev.usbharu.hideout.activitypub.service.activity.like
|
||||||
|
|
||||||
|
import dev.usbharu.hideout.activitypub.domain.exception.FailedToGetActivityPubResourceException
|
||||||
|
import dev.usbharu.hideout.activitypub.domain.exception.IllegalActivityPubObjectException
|
||||||
|
import dev.usbharu.hideout.activitypub.domain.model.Like
|
||||||
|
import dev.usbharu.hideout.activitypub.service.common.AbstractActivityPubProcessor
|
||||||
|
import dev.usbharu.hideout.activitypub.service.common.ActivityPubProcessContext
|
||||||
|
import dev.usbharu.hideout.activitypub.service.common.ActivityType
|
||||||
|
import dev.usbharu.hideout.activitypub.service.objects.note.APNoteService
|
||||||
|
import dev.usbharu.hideout.activitypub.service.objects.user.APUserService
|
||||||
|
import dev.usbharu.hideout.application.external.Transaction
|
||||||
|
import dev.usbharu.hideout.core.query.PostQueryService
|
||||||
|
import dev.usbharu.hideout.core.service.reaction.ReactionService
|
||||||
|
|
||||||
|
class APLikeProcessor(
|
||||||
|
transaction: Transaction,
|
||||||
|
private val apUserService: APUserService,
|
||||||
|
private val apNoteService: APNoteService,
|
||||||
|
private val postQueryService: PostQueryService,
|
||||||
|
private val reactionService: ReactionService
|
||||||
|
) :
|
||||||
|
AbstractActivityPubProcessor<Like>(transaction) {
|
||||||
|
override suspend fun internalProcess(activity: ActivityPubProcessContext<Like>) {
|
||||||
|
val actor = activity.activity.actor ?: throw IllegalActivityPubObjectException("actor is null")
|
||||||
|
val content = activity.activity.content ?: throw IllegalActivityPubObjectException("content is null")
|
||||||
|
|
||||||
|
val target = activity.activity.`object` ?: throw IllegalActivityPubObjectException("object is null")
|
||||||
|
|
||||||
|
val personWithEntity = apUserService.fetchPersonWithEntity(actor)
|
||||||
|
|
||||||
|
try {
|
||||||
|
apNoteService.fetchNoteAsync(target).await()
|
||||||
|
} catch (e: FailedToGetActivityPubResourceException) {
|
||||||
|
logger.debug("FAILED failed to get {}", target)
|
||||||
|
logger.trace("", e)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
val post = postQueryService.findByUrl(target)
|
||||||
|
|
||||||
|
reactionService.receiveReaction(
|
||||||
|
content,
|
||||||
|
actor.substringAfter("://").substringBefore("/"),
|
||||||
|
personWithEntity.second.id,
|
||||||
|
post.id
|
||||||
|
)
|
||||||
|
|
||||||
|
logger.debug("SUCCESS Add Like($content) from ${personWithEntity.second.url} to ${post.url}")
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun isSupported(activityType: ActivityType): Boolean = activityType == ActivityType.Like
|
||||||
|
|
||||||
|
override fun type(): Class<Like> = Like::class.java
|
||||||
|
}
|
|
@ -0,0 +1,53 @@
|
||||||
|
package dev.usbharu.hideout.activitypub.service.activity.undo
|
||||||
|
|
||||||
|
import dev.usbharu.hideout.activitypub.domain.model.Follow
|
||||||
|
import dev.usbharu.hideout.activitypub.domain.model.Undo
|
||||||
|
import dev.usbharu.hideout.activitypub.service.common.AbstractActivityPubProcessor
|
||||||
|
import dev.usbharu.hideout.activitypub.service.common.ActivityPubProcessContext
|
||||||
|
import dev.usbharu.hideout.activitypub.service.common.ActivityType
|
||||||
|
import dev.usbharu.hideout.activitypub.service.objects.user.APUserService
|
||||||
|
import dev.usbharu.hideout.application.external.Transaction
|
||||||
|
import dev.usbharu.hideout.core.query.UserQueryService
|
||||||
|
import dev.usbharu.hideout.core.service.user.UserService
|
||||||
|
|
||||||
|
class APUndoProcessor(
|
||||||
|
transaction: Transaction,
|
||||||
|
private val apUserService: APUserService,
|
||||||
|
private val userQueryService: UserQueryService,
|
||||||
|
private val userService: UserService
|
||||||
|
) :
|
||||||
|
AbstractActivityPubProcessor<Undo>(transaction) {
|
||||||
|
override suspend fun internalProcess(activity: ActivityPubProcessContext<Undo>) {
|
||||||
|
val undo = activity.activity
|
||||||
|
if (undo.actor == null) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
val type =
|
||||||
|
undo.`object`?.type.orEmpty()
|
||||||
|
.firstOrNull { it == "Block" || it == "Follow" || it == "Like" || it == "Announce" || it == "Accept" }
|
||||||
|
?: return
|
||||||
|
|
||||||
|
when (type) {
|
||||||
|
"Follow" -> {
|
||||||
|
val follow = undo.`object` as Follow
|
||||||
|
|
||||||
|
if (follow.`object` == null) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
apUserService.fetchPerson(undo.actor!!, follow.`object`)
|
||||||
|
val follower = userQueryService.findByUrl(undo.actor!!)
|
||||||
|
val target = userQueryService.findByUrl(follow.`object`!!)
|
||||||
|
userService.unfollow(target.id, follower.id)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
else -> {}
|
||||||
|
}
|
||||||
|
TODO()
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun isSupported(activityType: ActivityType): Boolean = activityType == ActivityType.Undo
|
||||||
|
|
||||||
|
override fun type(): Class<Undo> = Undo::class.java
|
||||||
|
}
|
|
@ -11,7 +11,7 @@ abstract class AbstractActivityPubProcessor<T : Object>(
|
||||||
private val transaction: Transaction,
|
private val transaction: Transaction,
|
||||||
private val allowUnauthorized: Boolean = false
|
private val allowUnauthorized: Boolean = false
|
||||||
) : ActivityPubProcessor<T> {
|
) : ActivityPubProcessor<T> {
|
||||||
private val logger = LoggerFactory.getLogger(this::class.java)
|
protected val logger = LoggerFactory.getLogger(this::class.java)
|
||||||
|
|
||||||
override suspend fun process(activity: ActivityPubProcessContext<T>) {
|
override suspend fun process(activity: ActivityPubProcessContext<T>) {
|
||||||
if (activity.isAuthorized.not() && allowUnauthorized.not()) {
|
if (activity.isAuthorized.not() && allowUnauthorized.not()) {
|
||||||
|
|
Loading…
Reference in New Issue