diff --git a/src/main/kotlin/dev/usbharu/hideout/activitypub/service/activity/reject/ApRejectProcessor.kt b/src/main/kotlin/dev/usbharu/hideout/activitypub/service/activity/reject/ApRejectProcessor.kt new file mode 100644 index 00000000..53e4c4bb --- /dev/null +++ b/src/main/kotlin/dev/usbharu/hideout/activitypub/service/activity/reject/ApRejectProcessor.kt @@ -0,0 +1,51 @@ +package dev.usbharu.hideout.activitypub.service.activity.reject + +import dev.usbharu.hideout.activitypub.domain.model.Follow +import dev.usbharu.hideout.activitypub.domain.model.Reject +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.UserQueryService +import dev.usbharu.hideout.core.service.relationship.RelationshipService +import org.springframework.stereotype.Service + + +@Service +class ApRejectProcessor( + private val relationshipService: RelationshipService, + private val userQueryService: UserQueryService, + transaction: Transaction +) : + AbstractActivityPubProcessor(transaction) { + override suspend fun internalProcess(activity: ActivityPubProcessContext) { + + val activityType = activity.activity.apObject.type.firstOrNull { it == "Follow" } + + if (activityType == null) { + logger.warn("FAILED Process Reject Activity type: {}", activity.activity.apObject.type) + return + } + when (activityType) { + "Follow" -> { + val user = userQueryService.findByUrl(activity.activity.actor) + + activity.activity.apObject as Follow + + val actor = activity.activity.apObject.actor + + val target = userQueryService.findByUrl(actor) + + logger.debug("REJECT Follow user {} target {}", user.url, target.url) + + relationshipService.rejectFollowRequest(user.id, target.id) + } + + else -> {} + } + } + + override fun isSupported(activityType: ActivityType): Boolean = activityType == ActivityType.Reject + + override fun type(): Class = Reject::class.java +} diff --git a/src/main/kotlin/dev/usbharu/hideout/core/service/relationship/RelationshipServiceImpl.kt b/src/main/kotlin/dev/usbharu/hideout/core/service/relationship/RelationshipServiceImpl.kt index c056a381..a94332f9 100644 --- a/src/main/kotlin/dev/usbharu/hideout/core/service/relationship/RelationshipServiceImpl.kt +++ b/src/main/kotlin/dev/usbharu/hideout/core/service/relationship/RelationshipServiceImpl.kt @@ -166,7 +166,7 @@ class RelationshipServiceImpl( } override suspend fun rejectFollowRequest(userId: Long, targetId: Long) { - val relationship = relationshipRepository.findByUserIdAndTargetUserId(userId, targetId) + val relationship = relationshipRepository.findByUserIdAndTargetUserId(targetId, userId) if (relationship == null) { logger.warn("FAILED Follow Request Not Found. (Relationship) userId: {} targetId: {}", userId, targetId) diff --git a/src/main/kotlin/dev/usbharu/hideout/mastodon/interfaces/api/account/MastodonAccountApiController.kt b/src/main/kotlin/dev/usbharu/hideout/mastodon/interfaces/api/account/MastodonAccountApiController.kt index 8311596f..f9af1c7d 100644 --- a/src/main/kotlin/dev/usbharu/hideout/mastodon/interfaces/api/account/MastodonAccountApiController.kt +++ b/src/main/kotlin/dev/usbharu/hideout/mastodon/interfaces/api/account/MastodonAccountApiController.kt @@ -133,4 +133,14 @@ class MastodonAccountApiController( return ResponseEntity.ok(unfollow) } + + override suspend fun apiV1AccountsIdRemoveFromFollowersPost(id: String): ResponseEntity { + val principal = SecurityContextHolder.getContext().getAuthentication().principal as Jwt + + val userid = principal.getClaim("uid").toLong() + + val removeFromFollowers = accountApiService.removeFromFollowers(userid, id.toLong()) + + return ResponseEntity.ok(removeFromFollowers) + } } diff --git a/src/main/kotlin/dev/usbharu/hideout/mastodon/service/account/AccountApiService.kt b/src/main/kotlin/dev/usbharu/hideout/mastodon/service/account/AccountApiService.kt index 955603cb..f639afc8 100644 --- a/src/main/kotlin/dev/usbharu/hideout/mastodon/service/account/AccountApiService.kt +++ b/src/main/kotlin/dev/usbharu/hideout/mastodon/service/account/AccountApiService.kt @@ -44,6 +44,7 @@ interface AccountApiService { suspend fun block(userid: Long, target: Long): Relationship suspend fun unblock(userid: Long, target: Long): Relationship suspend fun unfollow(userid: Long, target: Long): Relationship + suspend fun removeFromFollowers(userid: Long, target: Long): Relationship } @Service @@ -146,6 +147,12 @@ class AccountApiServiceImpl( return@transaction fetchRelationship(userid, target) } + override suspend fun removeFromFollowers(userid: Long, target: Long): Relationship = transaction.transaction { + relationshipService.rejectFollowRequest(userid, target) + + return@transaction fetchRelationship(userid, target) + } + private fun from(account: Account): CredentialAccount { return CredentialAccount( id = account.id, diff --git a/src/main/resources/openapi/mastodon.yaml b/src/main/resources/openapi/mastodon.yaml index fa3ea430..a43da7de 100644 --- a/src/main/resources/openapi/mastodon.yaml +++ b/src/main/resources/openapi/mastodon.yaml @@ -349,7 +349,26 @@ paths: application/json: schema: $ref: "#/components/schemas/Relationship" - + /api/v1/accounts/{id}/remove_from_followers: + post: + tags: + - account + security: + - OAuth2: + - "write:follows" + parameters: + - in: path + name: id + required: true + schema: + type: string + responses: + 200: + description: 成功 + content: + application/json: + schema: + $ref: "#/components/schemas/Relationship" /api/v1/accounts/{id}/statuses: get: