diff --git a/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/exposedquery/RelationshipQueryServiceImpl.kt b/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/exposedquery/RelationshipQueryServiceImpl.kt index 5a5127e5..43d8206a 100644 --- a/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/exposedquery/RelationshipQueryServiceImpl.kt +++ b/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/exposedquery/RelationshipQueryServiceImpl.kt @@ -5,6 +5,7 @@ import dev.usbharu.hideout.core.domain.model.relationship.Relationships import dev.usbharu.hideout.core.domain.model.relationship.toRelationships import dev.usbharu.hideout.core.query.RelationshipQueryService import org.jetbrains.exposed.sql.and +import org.jetbrains.exposed.sql.andWhere import org.jetbrains.exposed.sql.select import org.springframework.stereotype.Service @@ -15,16 +16,28 @@ class RelationshipQueryServiceImpl : RelationshipQueryService { .map { it.toRelationships() } override suspend fun findByTargetIdAndFollowRequestAndIgnoreFollowRequest( + maxId: Long?, + sinceId: Long?, + limit: Int, targetId: Long, followRequest: Boolean, ignoreFollowRequest: Boolean ): List { - return Relationships + val query = Relationships .select { Relationships.targetActorId.eq(targetId) .and(Relationships.followRequest.eq(followRequest)) .and(Relationships.ignoreFollowRequestFromTarget.eq(ignoreFollowRequest)) - } - .map { it.toRelationships() } + }.limit(limit) + + if (maxId != null) { + query.andWhere { Relationships.id greater maxId } + } + + if (sinceId != null) { + query.andWhere { Relationships.id less sinceId } + } + + return query.map { it.toRelationships() } } } 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 324dc171..6278ae30 100644 --- a/src/main/kotlin/dev/usbharu/hideout/core/query/RelationshipQueryService.kt +++ b/src/main/kotlin/dev/usbharu/hideout/core/query/RelationshipQueryService.kt @@ -6,6 +6,9 @@ interface RelationshipQueryService { suspend fun findByTargetIdAndFollowing(targetId: Long, following: Boolean): List suspend fun findByTargetIdAndFollowRequestAndIgnoreFollowRequest( + maxId: Long?, + sinceId: Long?, + limit: Int, targetId: Long, followRequest: Boolean, ignoreFollowRequest: Boolean 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 67bd1bfe..966163e8 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 @@ -73,14 +73,17 @@ class RelationshipServiceImpl( relationshipRepository.save(relationship) + val remoteUser = isRemoteUser(targetId) if (remoteUser != null) { val user = actorQueryService.findById(actorId) apSendFollowService.sendFollow(SendFollowDto(user, remoteUser)) } else { - // TODO: フォロー許可制ユーザーを実装したら消す - acceptFollowRequest(targetId, actorId) + val target = actorQueryService.findById(targetId) + if (target.locked.not()) { + acceptFollowRequest(targetId, actorId) + } } logger.info("SUCCESS Follow Request userId: {} targetId: {}", actorId, 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 b516c3ec..124f1e75 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 @@ -153,4 +153,36 @@ class MastodonAccountApiController( return ResponseEntity.ok(removeFromFollowers) } + + override suspend fun apiV1FollowRequestsAccountIdAuthorizePost(accountId: String): ResponseEntity { + val principal = SecurityContextHolder.getContext().getAuthentication().principal as Jwt + + val userid = principal.getClaim("uid").toLong() + + val acceptFollowRequest = accountApiService.acceptFollowRequest(userid, accountId.toLong()) + + return ResponseEntity.ok(acceptFollowRequest) + } + + override suspend fun apiV1FollowRequestsAccountIdRejectPost(accountId: String): ResponseEntity { + val principal = SecurityContextHolder.getContext().getAuthentication().principal as Jwt + + val userid = principal.getClaim("uid").toLong() + + val rejectFollowRequest = accountApiService.rejectFollowRequest(userid, accountId.toLong()) + + return ResponseEntity.ok(rejectFollowRequest) + } + + override fun apiV1FollowRequestsGet(maxId: String?, sinceId: String?, limit: Int?): ResponseEntity> = + runBlocking { + val principal = SecurityContextHolder.getContext().getAuthentication().principal as Jwt + + val userid = principal.getClaim("uid").toLong() + + val accountFlow = + accountApiService.followRequests(userid, maxId?.toLong(), sinceId?.toLong(), limit ?: 20, false) + .asFlow() + ResponseEntity.ok(accountFlow) + } } 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 8bb262c2..91731004 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 @@ -50,7 +50,14 @@ interface AccountApiService { suspend fun unfollow(userid: Long, target: Long): Relationship suspend fun removeFromFollowers(userid: Long, target: Long): Relationship suspend fun updateProfile(userid: Long, updateCredentials: UpdateCredentials?): Account - suspend fun followRequests(loginUser: Long): List + suspend fun followRequests( + loginUser: Long, + maxId: Long?, + sinceId: Long?, + limit: Int = 20, + withIgnore: Boolean + ): List + suspend fun acceptFollowRequest(loginUser: Long, target: Long): Relationship suspend fun rejectFollowRequest(loginUser: Long, target: Long): Relationship } @@ -208,9 +215,22 @@ class AccountApiServiceImpl( accountService.findById(userid) } - override suspend fun followRequests(loginUser: Long): List = transaction.transaction { + override suspend fun followRequests( + loginUser: Long, + maxId: Long?, + sinceId: Long?, + limit: Int, + withIgnore: Boolean + ): List = transaction.transaction { val actorIdList = relationshipQueryService - .findByTargetIdAndFollowRequestAndIgnoreFollowRequest(loginUser, true, true) + .findByTargetIdAndFollowRequestAndIgnoreFollowRequest( + maxId = maxId, + sinceId = sinceId, + limit = limit, + targetId = loginUser, + followRequest = true, + ignoreFollowRequest = withIgnore + ) .map { it.actorId } return@transaction accountService.findByIds(actorIdList) diff --git a/src/main/kotlin/dev/usbharu/hideout/mastodon/service/account/AccountService.kt b/src/main/kotlin/dev/usbharu/hideout/mastodon/service/account/AccountService.kt index 330ea164..9904e6ce 100644 --- a/src/main/kotlin/dev/usbharu/hideout/mastodon/service/account/AccountService.kt +++ b/src/main/kotlin/dev/usbharu/hideout/mastodon/service/account/AccountService.kt @@ -36,7 +36,7 @@ class AccountServiceImpl( avatarStatic = "$userUrl/icon.jpg", header = "$userUrl/header.jpg", headerStatic = "$userUrl/header.jpg", - locked = false, + locked = findById.locked, fields = emptyList(), emojis = emptyList(), bot = false, diff --git a/src/main/resources/openapi/mastodon.yaml b/src/main/resources/openapi/mastodon.yaml index 854e8f68..15df90d9 100644 --- a/src/main/resources/openapi/mastodon.yaml +++ b/src/main/resources/openapi/mastodon.yaml @@ -579,7 +579,7 @@ paths: /api/v1/follow_requests: get: tags: - - accounts + - account security: - OAuth2: - "read:follows" @@ -587,12 +587,12 @@ paths: - in: query name: max_id schema: - type: integer + type: string required: false - in: query name: since_id schema: - type: integer + type: string required: false - in: query name: limit @@ -617,7 +617,7 @@ paths: /api/v1/follow_requests/{account_id}/authorize: post: tags: - - accounts + - account security: - OAuth2: - "write:follows" @@ -638,7 +638,7 @@ paths: /api/v1/follow_requests/{account_id}/reject: post: tags: - - accounts + - account security: - OAuth2: - "write:follows"