From 507c1d8932e0db7191573407680fef4da2a08708 Mon Sep 17 00:00:00 2001 From: usbharu <64310155+usbharu@users.noreply.github.com> Date: Sun, 11 Aug 2024 00:28:32 +0900 Subject: [PATCH 1/7] =?UTF-8?q?refactor:=20principal=E3=81=AEactorId?= =?UTF-8?q?=E3=82=92=E4=BD=BF=E7=94=A8=E3=81=99=E3=82=8B=E3=82=88=E3=81=86?= =?UTF-8?q?=E3=81=AB?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../block/UserBlockApplicationService.kt | 7 +++--- .../UserFollowRequestApplicationService.kt | 8 +++---- .../get/GetRelationshipApplicationService.kt | 22 +++++++++---------- .../mute/UserMuteApplicationService.kt | 8 +++---- ...erRejectFollowRequestApplicationService.kt | 8 +++---- ...erRemoveFromFollowersApplicationService.kt | 8 +++---- .../unblock/UserUnblockApplicationService.kt | 8 +++---- .../UserUnfollowApplicationService.kt | 8 +++---- .../unmute/UserUnmuteApplicationService.kt | 8 +++---- 9 files changed, 35 insertions(+), 50 deletions(-) diff --git a/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/application/relationship/block/UserBlockApplicationService.kt b/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/application/relationship/block/UserBlockApplicationService.kt index 91a99c4f..c78b6702 100644 --- a/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/application/relationship/block/UserBlockApplicationService.kt +++ b/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/application/relationship/block/UserBlockApplicationService.kt @@ -23,7 +23,6 @@ import dev.usbharu.hideout.core.domain.model.actor.ActorRepository import dev.usbharu.hideout.core.domain.model.relationship.Relationship import dev.usbharu.hideout.core.domain.model.relationship.RelationshipRepository import dev.usbharu.hideout.core.domain.model.support.principal.FromApi -import dev.usbharu.hideout.core.domain.model.userdetails.UserDetailRepository import dev.usbharu.hideout.core.domain.service.relationship.RelationshipDomainService import org.slf4j.LoggerFactory import org.springframework.stereotype.Service @@ -33,14 +32,14 @@ class UserBlockApplicationService( private val relationshipRepository: RelationshipRepository, transaction: Transaction, private val actorRepository: ActorRepository, - private val userDetailRepository: UserDetailRepository, private val relationshipDomainService: RelationshipDomainService, ) : LocalUserAbstractApplicationService(transaction, logger) { override suspend fun internalExecute(command: Block, principal: FromApi) { - val userDetail = userDetailRepository.findById(principal.userDetailId)!! - val actor = actorRepository.findById(userDetail.actorId)!! + + val actor = actorRepository.findById(principal.actorId) + ?: throw IllegalStateException("Actor ${principal.actorId} not found") val targetId = ActorId(command.targetActorId) val relationship = relationshipRepository.findByActorIdAndTargetId(actor.id, targetId) ?: Relationship.default( diff --git a/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/application/relationship/followrequest/UserFollowRequestApplicationService.kt b/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/application/relationship/followrequest/UserFollowRequestApplicationService.kt index 0c9d967d..21cabd81 100644 --- a/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/application/relationship/followrequest/UserFollowRequestApplicationService.kt +++ b/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/application/relationship/followrequest/UserFollowRequestApplicationService.kt @@ -16,6 +16,7 @@ package dev.usbharu.hideout.core.application.relationship.followrequest +import dev.usbharu.hideout.core.application.exception.InternalServerException import dev.usbharu.hideout.core.application.shared.LocalUserAbstractApplicationService import dev.usbharu.hideout.core.application.shared.Transaction import dev.usbharu.hideout.core.domain.model.actor.ActorId @@ -23,7 +24,6 @@ import dev.usbharu.hideout.core.domain.model.actor.ActorRepository import dev.usbharu.hideout.core.domain.model.relationship.Relationship import dev.usbharu.hideout.core.domain.model.relationship.RelationshipRepository import dev.usbharu.hideout.core.domain.model.support.principal.FromApi -import dev.usbharu.hideout.core.domain.model.userdetails.UserDetailRepository import org.slf4j.LoggerFactory import org.springframework.stereotype.Service @@ -32,16 +32,14 @@ class UserFollowRequestApplicationService( private val relationshipRepository: RelationshipRepository, transaction: Transaction, private val actorRepository: ActorRepository, - private val userDetailRepository: UserDetailRepository, ) : LocalUserAbstractApplicationService( transaction, logger ) { override suspend fun internalExecute(command: FollowRequest, principal: FromApi) { - - val userDetail = userDetailRepository.findById(principal.userDetailId)!! - val actor = actorRepository.findById(userDetail.actorId)!! + val actor = actorRepository.findById(principal.actorId) + ?: throw InternalServerException("Actor ${principal.actorId} not found.") val targetId = ActorId(command.targetActorId) val relationship = relationshipRepository.findByActorIdAndTargetId(actor.id, targetId) ?: Relationship.default( diff --git a/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/application/relationship/get/GetRelationshipApplicationService.kt b/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/application/relationship/get/GetRelationshipApplicationService.kt index b832710d..2e3a7b98 100644 --- a/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/application/relationship/get/GetRelationshipApplicationService.kt +++ b/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/application/relationship/get/GetRelationshipApplicationService.kt @@ -16,6 +16,7 @@ package dev.usbharu.hideout.core.application.relationship.get +import dev.usbharu.hideout.core.application.exception.InternalServerException import dev.usbharu.hideout.core.application.shared.LocalUserAbstractApplicationService import dev.usbharu.hideout.core.application.shared.Transaction import dev.usbharu.hideout.core.domain.model.actor.ActorId @@ -24,7 +25,6 @@ import dev.usbharu.hideout.core.domain.model.actorinstancerelationship.ActorInst import dev.usbharu.hideout.core.domain.model.actorinstancerelationship.ActorInstanceRelationshipRepository import dev.usbharu.hideout.core.domain.model.relationship.RelationshipRepository import dev.usbharu.hideout.core.domain.model.support.principal.FromApi -import dev.usbharu.hideout.core.domain.model.userdetails.UserDetailRepository import org.slf4j.LoggerFactory import org.springframework.stereotype.Service @@ -32,7 +32,6 @@ import org.springframework.stereotype.Service class GetRelationshipApplicationService( private val relationshipRepository: RelationshipRepository, private val actorRepository: ActorRepository, - private val userDetailRepository: UserDetailRepository, private val actorInstanceRelationshipRepository: ActorInstanceRelationshipRepository, transaction: Transaction, ) : @@ -41,19 +40,20 @@ class GetRelationshipApplicationService( logger ) { override suspend fun internalExecute(command: GetRelationship, principal: FromApi): Relationship { - val userDetail = userDetailRepository.findById(principal.userDetailId)!! - val actor = actorRepository.findById(userDetail.actorId)!! + val actor = actorRepository.findById(principal.actorId) + ?: throw InternalServerException("Actor ${principal.actorId} not found.") val targetId = ActorId(command.targetActorId) - val target = actorRepository.findById(targetId)!! + val target = actorRepository.findById(targetId) + ?: throw IllegalArgumentException("Actor ${command.targetActorId} not found.") val relationship = ( - relationshipRepository.findByActorIdAndTargetId(actor.id, targetId) - ?: dev.usbharu.hideout.core.domain.model.relationship.Relationship.default(actor.id, targetId) - ) + relationshipRepository.findByActorIdAndTargetId(actor.id, targetId) + ?: dev.usbharu.hideout.core.domain.model.relationship.Relationship.default(actor.id, targetId) + ) val relationship1 = ( - relationshipRepository.findByActorIdAndTargetId(targetId, actor.id) - ?: dev.usbharu.hideout.core.domain.model.relationship.Relationship.default(targetId, actor.id) - ) + relationshipRepository.findByActorIdAndTargetId(targetId, actor.id) + ?: dev.usbharu.hideout.core.domain.model.relationship.Relationship.default(targetId, actor.id) + ) val actorInstanceRelationship = actorInstanceRelationshipRepository.findByActorIdAndInstanceId(actor.id, target.instance) diff --git a/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/application/relationship/mute/UserMuteApplicationService.kt b/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/application/relationship/mute/UserMuteApplicationService.kt index 7c611d24..bb330b61 100644 --- a/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/application/relationship/mute/UserMuteApplicationService.kt +++ b/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/application/relationship/mute/UserMuteApplicationService.kt @@ -16,6 +16,7 @@ package dev.usbharu.hideout.core.application.relationship.mute +import dev.usbharu.hideout.core.application.exception.InternalServerException import dev.usbharu.hideout.core.application.relationship.block.UserBlockApplicationService import dev.usbharu.hideout.core.application.shared.LocalUserAbstractApplicationService import dev.usbharu.hideout.core.application.shared.Transaction @@ -24,7 +25,6 @@ import dev.usbharu.hideout.core.domain.model.actor.ActorRepository import dev.usbharu.hideout.core.domain.model.relationship.Relationship import dev.usbharu.hideout.core.domain.model.relationship.RelationshipRepository import dev.usbharu.hideout.core.domain.model.support.principal.FromApi -import dev.usbharu.hideout.core.domain.model.userdetails.UserDetailRepository import org.slf4j.LoggerFactory import org.springframework.stereotype.Service @@ -33,13 +33,11 @@ class UserMuteApplicationService( private val relationshipRepository: RelationshipRepository, transaction: Transaction, private val actorRepository: ActorRepository, - private val userDetailRepository: UserDetailRepository, ) : LocalUserAbstractApplicationService(transaction, logger) { override suspend fun internalExecute(command: Mute, principal: FromApi) { - - val userDetail = userDetailRepository.findById(principal.userDetailId)!! - val actor = actorRepository.findById(userDetail.actorId)!! + val actor = actorRepository.findById(principal.actorId) + ?: throw InternalServerException("Actor ${principal.actorId} not found.") val targetId = ActorId(command.targetActorId) val relationship = relationshipRepository.findByActorIdAndTargetId(actor.id, targetId) ?: Relationship.default( diff --git a/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/application/relationship/rejectfollowrequest/UserRejectFollowRequestApplicationService.kt b/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/application/relationship/rejectfollowrequest/UserRejectFollowRequestApplicationService.kt index 97adbdd0..eac8320a 100644 --- a/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/application/relationship/rejectfollowrequest/UserRejectFollowRequestApplicationService.kt +++ b/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/application/relationship/rejectfollowrequest/UserRejectFollowRequestApplicationService.kt @@ -16,6 +16,7 @@ package dev.usbharu.hideout.core.application.relationship.rejectfollowrequest +import dev.usbharu.hideout.core.application.exception.InternalServerException import dev.usbharu.hideout.core.application.relationship.block.UserBlockApplicationService import dev.usbharu.hideout.core.application.shared.LocalUserAbstractApplicationService import dev.usbharu.hideout.core.application.shared.Transaction @@ -23,7 +24,6 @@ import dev.usbharu.hideout.core.domain.model.actor.ActorId import dev.usbharu.hideout.core.domain.model.actor.ActorRepository import dev.usbharu.hideout.core.domain.model.relationship.RelationshipRepository import dev.usbharu.hideout.core.domain.model.support.principal.FromApi -import dev.usbharu.hideout.core.domain.model.userdetails.UserDetailRepository import org.slf4j.LoggerFactory import org.springframework.stereotype.Service @@ -32,13 +32,11 @@ class UserRejectFollowRequestApplicationService( private val relationshipRepository: RelationshipRepository, transaction: Transaction, private val actorRepository: ActorRepository, - private val userDetailRepository: UserDetailRepository, ) : LocalUserAbstractApplicationService(transaction, logger) { override suspend fun internalExecute(command: RejectFollowRequest, principal: FromApi) { - - val userDetail = userDetailRepository.findById(principal.userDetailId)!! - val actor = actorRepository.findById(userDetail.actorId)!! + val actor = actorRepository.findById(principal.actorId) + ?: throw InternalServerException("Actor ${principal.actorId} not found.") val targetId = ActorId(command.sourceActorId) diff --git a/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/application/relationship/removefromfollowers/UserRemoveFromFollowersApplicationService.kt b/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/application/relationship/removefromfollowers/UserRemoveFromFollowersApplicationService.kt index d3e50e50..957b5be2 100644 --- a/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/application/relationship/removefromfollowers/UserRemoveFromFollowersApplicationService.kt +++ b/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/application/relationship/removefromfollowers/UserRemoveFromFollowersApplicationService.kt @@ -16,6 +16,7 @@ package dev.usbharu.hideout.core.application.relationship.removefromfollowers +import dev.usbharu.hideout.core.application.exception.InternalServerException import dev.usbharu.hideout.core.application.relationship.block.UserBlockApplicationService import dev.usbharu.hideout.core.application.shared.LocalUserAbstractApplicationService import dev.usbharu.hideout.core.application.shared.Transaction @@ -24,7 +25,6 @@ import dev.usbharu.hideout.core.domain.model.actor.ActorRepository import dev.usbharu.hideout.core.domain.model.relationship.Relationship import dev.usbharu.hideout.core.domain.model.relationship.RelationshipRepository import dev.usbharu.hideout.core.domain.model.support.principal.FromApi -import dev.usbharu.hideout.core.domain.model.userdetails.UserDetailRepository import org.slf4j.LoggerFactory import org.springframework.stereotype.Service @@ -33,13 +33,11 @@ class UserRemoveFromFollowersApplicationService( private val relationshipRepository: RelationshipRepository, transaction: Transaction, private val actorRepository: ActorRepository, - private val userDetailRepository: UserDetailRepository, ) : LocalUserAbstractApplicationService(transaction, logger) { override suspend fun internalExecute(command: RemoveFromFollowers, principal: FromApi) { - - val userDetail = userDetailRepository.findById(principal.userDetailId)!! - val actor = actorRepository.findById(userDetail.actorId)!! + val actor = actorRepository.findById(principal.actorId) + ?: throw InternalServerException("Actor ${principal.actorId} not found.") val targetId = ActorId(command.targetActorId) val relationship = relationshipRepository.findByActorIdAndTargetId(targetId, actor.id) ?: Relationship.default( diff --git a/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/application/relationship/unblock/UserUnblockApplicationService.kt b/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/application/relationship/unblock/UserUnblockApplicationService.kt index d5417799..efba1a83 100644 --- a/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/application/relationship/unblock/UserUnblockApplicationService.kt +++ b/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/application/relationship/unblock/UserUnblockApplicationService.kt @@ -16,6 +16,7 @@ package dev.usbharu.hideout.core.application.relationship.unblock +import dev.usbharu.hideout.core.application.exception.InternalServerException import dev.usbharu.hideout.core.application.relationship.block.UserBlockApplicationService import dev.usbharu.hideout.core.application.shared.LocalUserAbstractApplicationService import dev.usbharu.hideout.core.application.shared.Transaction @@ -24,7 +25,6 @@ import dev.usbharu.hideout.core.domain.model.actor.ActorRepository import dev.usbharu.hideout.core.domain.model.relationship.Relationship import dev.usbharu.hideout.core.domain.model.relationship.RelationshipRepository import dev.usbharu.hideout.core.domain.model.support.principal.FromApi -import dev.usbharu.hideout.core.domain.model.userdetails.UserDetailRepository import org.slf4j.LoggerFactory import org.springframework.stereotype.Service @@ -33,13 +33,11 @@ class UserUnblockApplicationService( private val relationshipRepository: RelationshipRepository, transaction: Transaction, private val actorRepository: ActorRepository, - private val userDetailRepository: UserDetailRepository, ) : LocalUserAbstractApplicationService(transaction, logger) { override suspend fun internalExecute(command: Unblock, principal: FromApi) { - - val userDetail = userDetailRepository.findById(principal.userDetailId)!! - val actor = actorRepository.findById(userDetail.actorId)!! + val actor = actorRepository.findById(principal.actorId) + ?: throw InternalServerException("Actor ${principal.actorId} not found.") val targetId = ActorId(command.targetActorId) val relationship = relationshipRepository.findByActorIdAndTargetId(actor.id, targetId) ?: Relationship.default( diff --git a/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/application/relationship/unfollow/UserUnfollowApplicationService.kt b/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/application/relationship/unfollow/UserUnfollowApplicationService.kt index a7068d00..87809a0d 100644 --- a/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/application/relationship/unfollow/UserUnfollowApplicationService.kt +++ b/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/application/relationship/unfollow/UserUnfollowApplicationService.kt @@ -16,6 +16,7 @@ package dev.usbharu.hideout.core.application.relationship.unfollow +import dev.usbharu.hideout.core.application.exception.InternalServerException import dev.usbharu.hideout.core.application.relationship.block.UserBlockApplicationService import dev.usbharu.hideout.core.application.shared.LocalUserAbstractApplicationService import dev.usbharu.hideout.core.application.shared.Transaction @@ -24,7 +25,6 @@ import dev.usbharu.hideout.core.domain.model.actor.ActorRepository import dev.usbharu.hideout.core.domain.model.relationship.Relationship import dev.usbharu.hideout.core.domain.model.relationship.RelationshipRepository import dev.usbharu.hideout.core.domain.model.support.principal.FromApi -import dev.usbharu.hideout.core.domain.model.userdetails.UserDetailRepository import org.slf4j.LoggerFactory import org.springframework.stereotype.Service @@ -33,13 +33,11 @@ class UserUnfollowApplicationService( private val relationshipRepository: RelationshipRepository, transaction: Transaction, private val actorRepository: ActorRepository, - private val userDetailRepository: UserDetailRepository, ) : LocalUserAbstractApplicationService(transaction, logger) { override suspend fun internalExecute(command: Unfollow, principal: FromApi) { - - val userDetail = userDetailRepository.findById(principal.userDetailId)!! - val actor = actorRepository.findById(userDetail.actorId)!! + val actor = actorRepository.findById(principal.actorId) + ?: throw InternalServerException("Actor ${principal.actorId} not found.") val targetId = ActorId(command.targetActorId) val relationship = relationshipRepository.findByActorIdAndTargetId(actor.id, targetId) ?: Relationship.default( diff --git a/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/application/relationship/unmute/UserUnmuteApplicationService.kt b/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/application/relationship/unmute/UserUnmuteApplicationService.kt index b90ba059..5681c066 100644 --- a/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/application/relationship/unmute/UserUnmuteApplicationService.kt +++ b/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/application/relationship/unmute/UserUnmuteApplicationService.kt @@ -16,6 +16,7 @@ package dev.usbharu.hideout.core.application.relationship.unmute +import dev.usbharu.hideout.core.application.exception.InternalServerException import dev.usbharu.hideout.core.application.relationship.block.UserBlockApplicationService import dev.usbharu.hideout.core.application.shared.LocalUserAbstractApplicationService import dev.usbharu.hideout.core.application.shared.Transaction @@ -24,7 +25,6 @@ import dev.usbharu.hideout.core.domain.model.actor.ActorRepository import dev.usbharu.hideout.core.domain.model.relationship.Relationship import dev.usbharu.hideout.core.domain.model.relationship.RelationshipRepository import dev.usbharu.hideout.core.domain.model.support.principal.FromApi -import dev.usbharu.hideout.core.domain.model.userdetails.UserDetailRepository import org.slf4j.LoggerFactory import org.springframework.stereotype.Service @@ -33,7 +33,6 @@ class UserUnmuteApplicationService( private val relationshipRepository: RelationshipRepository, transaction: Transaction, private val actorRepository: ActorRepository, - private val userDetailRepository: UserDetailRepository, ) : LocalUserAbstractApplicationService(transaction, logger) { companion object { @@ -41,9 +40,8 @@ class UserUnmuteApplicationService( } override suspend fun internalExecute(command: Unmute, principal: FromApi) { - - val userDetail = userDetailRepository.findById(principal.userDetailId)!! - val actor = actorRepository.findById(userDetail.actorId)!! + val actor = actorRepository.findById(principal.actorId) + ?: throw InternalServerException("Actor ${principal.actorId} not found.") val targetId = ActorId(command.targetActorId) val relationship = relationshipRepository.findByActorIdAndTargetId(actor.id, targetId) ?: Relationship.default( From 1a3fc05dad2ac0739a0eb2ee9e086399f232f42a Mon Sep 17 00:00:00 2001 From: usbharu <64310155+usbharu@users.noreply.github.com> Date: Sun, 11 Aug 2024 00:30:24 +0900 Subject: [PATCH 2/7] =?UTF-8?q?feat:=20=E3=83=AD=E3=83=BC=E3=82=AB?= =?UTF-8?q?=E3=83=AB=E3=83=A6=E3=83=BC=E3=82=B6=E3=83=BC=E3=81=AE=E3=81=BF?= =?UTF-8?q?=E4=BD=BF=E7=94=A8=E3=81=A7=E3=81=8D=E3=82=8B=E9=83=A8=E5=88=86?= =?UTF-8?q?=E3=82=92=E5=A4=89=E6=9B=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../UserAddTimelineRelationshipApplicationService.kt | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/application/timeline/UserAddTimelineRelationshipApplicationService.kt b/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/application/timeline/UserAddTimelineRelationshipApplicationService.kt index 5bd0721f..712ab270 100644 --- a/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/application/timeline/UserAddTimelineRelationshipApplicationService.kt +++ b/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/application/timeline/UserAddTimelineRelationshipApplicationService.kt @@ -1,8 +1,8 @@ package dev.usbharu.hideout.core.application.timeline -import dev.usbharu.hideout.core.application.shared.AbstractApplicationService +import dev.usbharu.hideout.core.application.shared.LocalUserAbstractApplicationService import dev.usbharu.hideout.core.application.shared.Transaction -import dev.usbharu.hideout.core.domain.model.support.principal.Principal +import dev.usbharu.hideout.core.domain.model.support.principal.FromApi import dev.usbharu.hideout.core.domain.model.timelinerelationship.TimelineRelationshipRepository import org.slf4j.LoggerFactory import org.springframework.stereotype.Service @@ -12,12 +12,11 @@ class UserAddTimelineRelationshipApplicationService( private val timelineRelationshipRepository: TimelineRelationshipRepository, transaction: Transaction ) : - AbstractApplicationService( + LocalUserAbstractApplicationService( transaction, logger ) { - override suspend fun internalExecute(command: AddTimelineRelationship, principal: Principal) { + override suspend fun internalExecute(command: AddTimelineRelationship, principal: FromApi) { timelineRelationshipRepository.save(command.timelineRelationship) - } companion object { From 540fe0eaa55268f2b299c16818e10c7e92d00a05 Mon Sep 17 00:00:00 2001 From: usbharu <64310155+usbharu@users.noreply.github.com> Date: Sun, 11 Aug 2024 01:22:43 +0900 Subject: [PATCH 3/7] =?UTF-8?q?feat:=20=E6=A8=A9=E9=99=90=E3=83=81?= =?UTF-8?q?=E3=82=A7=E3=83=83=E3=82=AF=E7=AD=89=E3=82=92=E8=BF=BD=E5=8A=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../accounts/GetAccountApplicationService.kt | 8 +++---- .../DeleteFilterV1ApplicationService.kt | 22 +++++++++++-------- .../filter/GetFilterV1ApplicationService.kt | 7 +++++- .../status/GetStatusApplicationService.kt | 12 +++++----- .../exposedquery/ExposedStatusQueryService.kt | 3 ++- .../mastodon/query/StatusQueryService.kt | 3 ++- 6 files changed, 34 insertions(+), 21 deletions(-) diff --git a/hideout-mastodon/src/main/kotlin/dev/usbharu/hideout/mastodon/application/accounts/GetAccountApplicationService.kt b/hideout-mastodon/src/main/kotlin/dev/usbharu/hideout/mastodon/application/accounts/GetAccountApplicationService.kt index d2611534..04d274a4 100644 --- a/hideout-mastodon/src/main/kotlin/dev/usbharu/hideout/mastodon/application/accounts/GetAccountApplicationService.kt +++ b/hideout-mastodon/src/main/kotlin/dev/usbharu/hideout/mastodon/application/accounts/GetAccountApplicationService.kt @@ -16,9 +16,9 @@ package dev.usbharu.hideout.mastodon.application.accounts -import dev.usbharu.hideout.core.application.shared.AbstractApplicationService +import dev.usbharu.hideout.core.application.shared.LocalUserAbstractApplicationService import dev.usbharu.hideout.core.application.shared.Transaction -import dev.usbharu.hideout.core.domain.model.support.principal.Principal +import dev.usbharu.hideout.core.domain.model.support.principal.FromApi import dev.usbharu.hideout.mastodon.interfaces.api.generated.model.Account import dev.usbharu.hideout.mastodon.query.AccountQueryService import org.slf4j.LoggerFactory @@ -26,11 +26,11 @@ import org.springframework.stereotype.Service @Service class GetAccountApplicationService(private val accountQueryService: AccountQueryService, transaction: Transaction) : - AbstractApplicationService( + LocalUserAbstractApplicationService( transaction, logger ) { - override suspend fun internalExecute(command: GetAccount, principal: Principal): Account { + override suspend fun internalExecute(command: GetAccount, principal: FromApi): Account { return accountQueryService.findById(command.accountId.toLong()) ?: throw Exception("Account not found") } diff --git a/hideout-mastodon/src/main/kotlin/dev/usbharu/hideout/mastodon/application/filter/DeleteFilterV1ApplicationService.kt b/hideout-mastodon/src/main/kotlin/dev/usbharu/hideout/mastodon/application/filter/DeleteFilterV1ApplicationService.kt index 2a722f01..919d51ef 100644 --- a/hideout-mastodon/src/main/kotlin/dev/usbharu/hideout/mastodon/application/filter/DeleteFilterV1ApplicationService.kt +++ b/hideout-mastodon/src/main/kotlin/dev/usbharu/hideout/mastodon/application/filter/DeleteFilterV1ApplicationService.kt @@ -16,26 +16,30 @@ package dev.usbharu.hideout.mastodon.application.filter -import dev.usbharu.hideout.core.application.shared.AbstractApplicationService +import dev.usbharu.hideout.core.application.exception.PermissionDeniedException +import dev.usbharu.hideout.core.application.shared.LocalUserAbstractApplicationService import dev.usbharu.hideout.core.application.shared.Transaction import dev.usbharu.hideout.core.domain.model.filter.FilterKeywordId import dev.usbharu.hideout.core.domain.model.filter.FilterRepository -import dev.usbharu.hideout.core.domain.model.support.principal.Principal +import dev.usbharu.hideout.core.domain.model.support.principal.FromApi import org.slf4j.LoggerFactory import org.springframework.stereotype.Service @Service class DeleteFilterV1ApplicationService(private val filterRepository: FilterRepository, transaction: Transaction) : - AbstractApplicationService( + LocalUserAbstractApplicationService( transaction, logger ) { + override suspend fun internalExecute(command: DeleteFilterV1, principal: FromApi) { + val filter = filterRepository.findByFilterKeywordId(FilterKeywordId(command.filterKeywordId)) + ?: throw IllegalArgumentException("Filter ${command.filterKeywordId} not found") + if (principal.userDetailId != filter.userDetailId) { + throw PermissionDeniedException() + } + filterRepository.delete(filter) + } + companion object { private val logger = LoggerFactory.getLogger(DeleteFilterV1ApplicationService::class.java) } - - override suspend fun internalExecute(command: DeleteFilterV1, principal: Principal) { - val filter = filterRepository.findByFilterKeywordId(FilterKeywordId(command.filterKeywordId)) - ?: throw Exception("Not Found") - filterRepository.delete(filter) - } } \ No newline at end of file diff --git a/hideout-mastodon/src/main/kotlin/dev/usbharu/hideout/mastodon/application/filter/GetFilterV1ApplicationService.kt b/hideout-mastodon/src/main/kotlin/dev/usbharu/hideout/mastodon/application/filter/GetFilterV1ApplicationService.kt index 057b7b1a..e79c8513 100644 --- a/hideout-mastodon/src/main/kotlin/dev/usbharu/hideout/mastodon/application/filter/GetFilterV1ApplicationService.kt +++ b/hideout-mastodon/src/main/kotlin/dev/usbharu/hideout/mastodon/application/filter/GetFilterV1ApplicationService.kt @@ -16,6 +16,7 @@ package dev.usbharu.hideout.mastodon.application.filter +import dev.usbharu.hideout.core.application.exception.PermissionDeniedException import dev.usbharu.hideout.core.application.shared.AbstractApplicationService import dev.usbharu.hideout.core.application.shared.Transaction import dev.usbharu.hideout.core.domain.model.filter.FilterContext.* @@ -34,7 +35,11 @@ class GetFilterV1ApplicationService(private val filterRepository: FilterReposito ) { override suspend fun internalExecute(command: GetFilterV1, principal: Principal): V1Filter { val filter = filterRepository.findByFilterKeywordId(FilterKeywordId(command.filterKeywordId)) - ?: throw Exception("Not Found") + ?: throw IllegalArgumentException("Filter ${command.filterKeywordId} not found") + + if (filter.userDetailId != principal.userDetailId) { + throw PermissionDeniedException() + } val filterKeyword = filter.filterKeywords.find { it.id.id == command.filterKeywordId } return V1Filter( diff --git a/hideout-mastodon/src/main/kotlin/dev/usbharu/hideout/mastodon/application/status/GetStatusApplicationService.kt b/hideout-mastodon/src/main/kotlin/dev/usbharu/hideout/mastodon/application/status/GetStatusApplicationService.kt index 63bccc23..3121de94 100644 --- a/hideout-mastodon/src/main/kotlin/dev/usbharu/hideout/mastodon/application/status/GetStatusApplicationService.kt +++ b/hideout-mastodon/src/main/kotlin/dev/usbharu/hideout/mastodon/application/status/GetStatusApplicationService.kt @@ -16,9 +16,9 @@ package dev.usbharu.hideout.mastodon.application.status -import dev.usbharu.hideout.core.application.shared.AbstractApplicationService +import dev.usbharu.hideout.core.application.shared.LocalUserAbstractApplicationService import dev.usbharu.hideout.core.application.shared.Transaction -import dev.usbharu.hideout.core.domain.model.support.principal.Principal +import dev.usbharu.hideout.core.domain.model.support.principal.FromApi import dev.usbharu.hideout.mastodon.interfaces.api.generated.model.Status import dev.usbharu.hideout.mastodon.query.StatusQueryService import org.slf4j.LoggerFactory @@ -28,7 +28,7 @@ import org.springframework.stereotype.Service class GetStatusApplicationService( private val statusQueryService: StatusQueryService, transaction: Transaction, -) : AbstractApplicationService( +) : LocalUserAbstractApplicationService( transaction, logger ) { @@ -36,7 +36,9 @@ class GetStatusApplicationService( val logger = LoggerFactory.getLogger(GetStatusApplicationService::class.java)!! } - override suspend fun internalExecute(command: GetStatus, principal: Principal): Status { - return statusQueryService.findByPostId(command.id.toLong()) ?: throw Exception("Not fount") + override suspend fun internalExecute(command: GetStatus, principal: FromApi): Status { + return statusQueryService.findByPostId(command.id.toLong()) + ?: throw IllegalArgumentException("Post ${command.id} not found.") + } } \ No newline at end of file diff --git a/hideout-mastodon/src/main/kotlin/dev/usbharu/hideout/mastodon/infrastructure/exposedquery/ExposedStatusQueryService.kt b/hideout-mastodon/src/main/kotlin/dev/usbharu/hideout/mastodon/infrastructure/exposedquery/ExposedStatusQueryService.kt index 98a8a4c4..2d3a4bc7 100644 --- a/hideout-mastodon/src/main/kotlin/dev/usbharu/hideout/mastodon/infrastructure/exposedquery/ExposedStatusQueryService.kt +++ b/hideout-mastodon/src/main/kotlin/dev/usbharu/hideout/mastodon/infrastructure/exposedquery/ExposedStatusQueryService.kt @@ -19,6 +19,7 @@ package dev.usbharu.hideout.mastodon.infrastructure.exposedquery import dev.usbharu.hideout.core.domain.model.emoji.CustomEmoji import dev.usbharu.hideout.core.domain.model.media.* import dev.usbharu.hideout.core.domain.model.post.Visibility +import dev.usbharu.hideout.core.domain.model.support.principal.Principal import dev.usbharu.hideout.core.infrastructure.exposedrepository.* import dev.usbharu.hideout.mastodon.interfaces.api.generated.model.Account import dev.usbharu.hideout.mastodon.interfaces.api.generated.model.MediaAttachment @@ -117,7 +118,7 @@ class StatusQueryServiceImpl : StatusQueryService { return statuses } - override suspend fun findByPostId(id: Long): Status? { + override suspend fun findByPostId(id: Long, principal: Principal?): Status? { val map = Posts .leftJoin(PostsMedia) .leftJoin(Actors) diff --git a/hideout-mastodon/src/main/kotlin/dev/usbharu/hideout/mastodon/query/StatusQueryService.kt b/hideout-mastodon/src/main/kotlin/dev/usbharu/hideout/mastodon/query/StatusQueryService.kt index dc7cc88e..34bf05da 100644 --- a/hideout-mastodon/src/main/kotlin/dev/usbharu/hideout/mastodon/query/StatusQueryService.kt +++ b/hideout-mastodon/src/main/kotlin/dev/usbharu/hideout/mastodon/query/StatusQueryService.kt @@ -16,6 +16,7 @@ package dev.usbharu.hideout.mastodon.query +import dev.usbharu.hideout.core.domain.model.support.principal.Principal import dev.usbharu.hideout.mastodon.interfaces.api.generated.model.Status interface StatusQueryService { @@ -33,7 +34,7 @@ interface StatusQueryService { includeFollowers: Boolean = false, ): List - suspend fun findByPostId(id: Long): Status? + suspend fun findByPostId(id: Long, principal: Principal? = null): Status? } data class StatusQuery( From 146b907c694aa6929dc77b2ff745a0df6ff081af Mon Sep 17 00:00:00 2001 From: usbharu <64310155+usbharu@users.noreply.github.com> Date: Sun, 11 Aug 2024 12:33:37 +0900 Subject: [PATCH 4/7] =?UTF-8?q?feat:=20QueryService=E3=81=AE=E8=AA=8D?= =?UTF-8?q?=E5=8F=AF=E5=87=A6=E7=90=86=E3=82=92=E8=BF=BD=E5=8A=A0=E3=81=97?= =?UTF-8?q?=E3=81=A6=E8=B5=B7=E5=8B=95=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 --- .../actor/GetUserDetailApplicationService.kt | 15 ++-- .../LocalUserAbstractApplicationService.kt | 5 +- .../ExposedPostRepository.kt | 3 + ...ingSecurityOauth2PrincipalContextHolder.kt | 29 ++++--- .../resources/db/migration/V1__Init_DB.sql | 18 +++- .../exposedquery/ExposedStatusQueryService.kt | 83 +++++++++++++------ .../interfaces/api/SpringAccountApi.kt | 3 +- .../interfaces/api/SpringStatusApi.kt | 5 +- 8 files changed, 110 insertions(+), 51 deletions(-) diff --git a/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/application/actor/GetUserDetailApplicationService.kt b/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/application/actor/GetUserDetailApplicationService.kt index 6d990ee2..0d67740d 100644 --- a/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/application/actor/GetUserDetailApplicationService.kt +++ b/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/application/actor/GetUserDetailApplicationService.kt @@ -17,12 +17,11 @@ package dev.usbharu.hideout.core.application.actor import dev.usbharu.hideout.core.application.exception.InternalServerException -import dev.usbharu.hideout.core.application.shared.AbstractApplicationService +import dev.usbharu.hideout.core.application.shared.LocalUserAbstractApplicationService import dev.usbharu.hideout.core.application.shared.Transaction import dev.usbharu.hideout.core.domain.model.actor.ActorRepository import dev.usbharu.hideout.core.domain.model.emoji.CustomEmojiRepository -import dev.usbharu.hideout.core.domain.model.support.principal.Principal -import dev.usbharu.hideout.core.domain.model.userdetails.UserDetailId +import dev.usbharu.hideout.core.domain.model.support.principal.FromApi import dev.usbharu.hideout.core.domain.model.userdetails.UserDetailRepository import org.slf4j.LoggerFactory import org.springframework.stereotype.Service @@ -34,10 +33,10 @@ class GetUserDetailApplicationService( private val customEmojiRepository: CustomEmojiRepository, transaction: Transaction, ) : - AbstractApplicationService(transaction, Companion.logger) { - override suspend fun internalExecute(command: GetUserDetail, principal: Principal): UserDetail { - val userDetail = userDetailRepository.findById(UserDetailId(command.id)) - ?: throw IllegalArgumentException("User ${command.id} does not exist") + LocalUserAbstractApplicationService(transaction, Companion.logger) { + override suspend fun internalExecute(command: Unit, principal: FromApi): UserDetail { + val userDetail = userDetailRepository.findById(principal.userDetailId) + ?: throw IllegalArgumentException("User ${principal.userDetailId} does not exist") val actor = actorRepository.findById(userDetail.actorId) ?: throw InternalServerException("Actor ${userDetail.actorId} not found") @@ -47,6 +46,6 @@ class GetUserDetailApplicationService( } companion object { - val logger = LoggerFactory.getLogger(GetUserDetailApplicationService::class.java) + private val logger = LoggerFactory.getLogger(GetUserDetailApplicationService::class.java) } } diff --git a/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/application/shared/LocalUserAbstractApplicationService.kt b/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/application/shared/LocalUserAbstractApplicationService.kt index cc4ddef8..1bcd4b26 100644 --- a/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/application/shared/LocalUserAbstractApplicationService.kt +++ b/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/application/shared/LocalUserAbstractApplicationService.kt @@ -1,5 +1,6 @@ package dev.usbharu.hideout.core.application.shared +import dev.usbharu.hideout.core.application.exception.PermissionDeniedException import dev.usbharu.hideout.core.domain.model.support.principal.FromApi import dev.usbharu.hideout.core.domain.model.support.principal.Principal import org.slf4j.Logger @@ -7,7 +8,9 @@ import org.slf4j.Logger abstract class LocalUserAbstractApplicationService(transaction: Transaction, logger: Logger) : AbstractApplicationService(transaction, logger) { override suspend fun internalExecute(command: T, principal: Principal): R { - require(principal is FromApi) + if (principal !is FromApi) { + throw PermissionDeniedException() + } return internalExecute(command, principal) } diff --git a/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/exposedrepository/ExposedPostRepository.kt b/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/exposedrepository/ExposedPostRepository.kt index e9b09eba..e0bb4f46 100644 --- a/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/exposedrepository/ExposedPostRepository.kt +++ b/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/exposedrepository/ExposedPostRepository.kt @@ -30,6 +30,7 @@ import dev.usbharu.hideout.core.infrastructure.exposedrepository.Posts.createdAt import dev.usbharu.hideout.core.infrastructure.exposedrepository.Posts.deleted import dev.usbharu.hideout.core.infrastructure.exposedrepository.Posts.hide import dev.usbharu.hideout.core.infrastructure.exposedrepository.Posts.id +import dev.usbharu.hideout.core.infrastructure.exposedrepository.Posts.instanceId import dev.usbharu.hideout.core.infrastructure.exposedrepository.Posts.moveTo import dev.usbharu.hideout.core.infrastructure.exposedrepository.Posts.overview import dev.usbharu.hideout.core.infrastructure.exposedrepository.Posts.replyId @@ -61,6 +62,7 @@ class ExposedPostRepository( Posts.upsert { it[id] = post.id.id it[actorId] = post.actorId.id + it[instanceId] = post.instanceId.instanceId it[overview] = post.overview?.overview it[content] = post.content.content it[text] = post.content.text @@ -106,6 +108,7 @@ class ExposedPostRepository( Posts.batchUpsert(posts, id) { this[id] = it.id.id this[actorId] = it.actorId.id + this[instanceId] = it.instanceId.instanceId this[overview] = it.overview?.overview this[content] = it.content.content this[text] = it.content.text diff --git a/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/springframework/oauth2/SpringSecurityOauth2PrincipalContextHolder.kt b/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/springframework/oauth2/SpringSecurityOauth2PrincipalContextHolder.kt index 68341349..ebf56530 100644 --- a/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/springframework/oauth2/SpringSecurityOauth2PrincipalContextHolder.kt +++ b/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/infrastructure/springframework/oauth2/SpringSecurityOauth2PrincipalContextHolder.kt @@ -1,7 +1,10 @@ package dev.usbharu.hideout.core.infrastructure.springframework.oauth2 +import dev.usbharu.hideout.core.application.shared.Transaction import dev.usbharu.hideout.core.domain.model.support.acct.Acct +import dev.usbharu.hideout.core.domain.model.support.principal.Anonymous import dev.usbharu.hideout.core.domain.model.support.principal.FromApi +import dev.usbharu.hideout.core.domain.model.support.principal.Principal import dev.usbharu.hideout.core.domain.model.support.principal.PrincipalContextHolder import dev.usbharu.hideout.core.domain.model.userdetails.UserDetailId import dev.usbharu.hideout.core.query.principal.PrincipalQueryService @@ -10,18 +13,24 @@ import org.springframework.security.oauth2.jwt.Jwt import org.springframework.stereotype.Component @Component -class SpringSecurityOauth2PrincipalContextHolder(private val principalQueryService: PrincipalQueryService) : +class SpringSecurityOauth2PrincipalContextHolder( + private val principalQueryService: PrincipalQueryService, + private val transaction: Transaction +) : PrincipalContextHolder { - override suspend fun getPrincipal(): FromApi { - val principal = SecurityContextHolder.getContext().authentication?.principal as Jwt + override suspend fun getPrincipal(): Principal { + val principal = + SecurityContextHolder.getContext().authentication?.principal as? Jwt ?: return Anonymous - val id = principal.getClaim("uid").toLong() - val userDetail = principalQueryService.findByUserDetailId(UserDetailId(id)) + return transaction.transaction { + val id = principal.getClaim("uid").toLong() + val userDetail = principalQueryService.findByUserDetailId(UserDetailId(id)) - return FromApi( - userDetail.actorId, - userDetail.userDetailId, - Acct(userDetail.username, userDetail.host) - ) + return@transaction FromApi( + userDetail.actorId, + userDetail.userDetailId, + Acct(userDetail.username, userDetail.host) + ) + } } } \ No newline at end of file diff --git a/hideout-core/src/main/resources/db/migration/V1__Init_DB.sql b/hideout-core/src/main/resources/db/migration/V1__Init_DB.sql index d6f0c0f4..c42a3f7f 100644 --- a/hideout-core/src/main/resources/db/migration/V1__Init_DB.sql +++ b/hideout-core/src/main/resources/db/migration/V1__Init_DB.sql @@ -71,6 +71,14 @@ create table if not exists actor_alsoknownas constraint fk_actor_alsoknownas_actors__also_known_as foreign key ("also_known_as") references actors (id) on delete cascade on update cascade ); +create table timelines +( + id bigint primary key, + user_detail_id bigint not null, + name varchar(255) not null, + visibility varchar(100) not null, + is_system boolean not null default false +); create table if not exists user_details ( id bigserial primary key, @@ -78,9 +86,14 @@ create table if not exists user_details password varchar(255) not null, auto_accept_followee_follow_request boolean not null, last_migration timestamp null default null, - constraint fk_user_details_actor_id__id foreign key (actor_id) references actors (id) on delete restrict on update restrict + home_timeline_id bigint null default null, + constraint fk_user_details_actor_id__id foreign key (actor_id) references actors (id) on delete restrict on update restrict, + constraint fk_user_details_timelines_id__id foreign key (home_timeline_id) references timelines (id) on delete cascade on update cascade ); +alter table timelines + add constraint fk_timelines_user_details__user_detail_id foreign key ("user_detail_id") references user_details (id) on delete cascade on update cascade; + create table if not exists media ( id bigint primary key, @@ -104,6 +117,7 @@ create table if not exists posts ( id bigint primary key, actor_id bigint not null, + instance_id bigint not null, overview varchar(100) null, content varchar(5000) not null, text varchar(3000) not null, @@ -118,6 +132,8 @@ create table if not exists posts hide boolean default false not null, move_to bigint default null null ); +alter table posts + add constraint fk_posts_instance_id__id foreign key (instance_id) references instance (id) on delete cascade on update cascade; alter table posts add constraint fk_posts_actor_id__id foreign key (actor_id) references actors (id) on delete restrict on update restrict; alter table posts diff --git a/hideout-mastodon/src/main/kotlin/dev/usbharu/hideout/mastodon/infrastructure/exposedquery/ExposedStatusQueryService.kt b/hideout-mastodon/src/main/kotlin/dev/usbharu/hideout/mastodon/infrastructure/exposedquery/ExposedStatusQueryService.kt index 2d3a4bc7..4fdc95c1 100644 --- a/hideout-mastodon/src/main/kotlin/dev/usbharu/hideout/mastodon/infrastructure/exposedquery/ExposedStatusQueryService.kt +++ b/hideout-mastodon/src/main/kotlin/dev/usbharu/hideout/mastodon/infrastructure/exposedquery/ExposedStatusQueryService.kt @@ -27,10 +27,7 @@ import dev.usbharu.hideout.mastodon.interfaces.api.generated.model.Status import dev.usbharu.hideout.mastodon.interfaces.api.generated.model.Status.Visibility.* import dev.usbharu.hideout.mastodon.query.StatusQuery import dev.usbharu.hideout.mastodon.query.StatusQueryService -import org.jetbrains.exposed.sql.ResultRow -import org.jetbrains.exposed.sql.andWhere -import org.jetbrains.exposed.sql.leftJoin -import org.jetbrains.exposed.sql.selectAll +import org.jetbrains.exposed.sql.* import org.springframework.stereotype.Repository import java.net.URI import dev.usbharu.hideout.core.domain.model.media.Media as EntityMedia @@ -39,6 +36,33 @@ import dev.usbharu.hideout.mastodon.interfaces.api.generated.model.CustomEmoji a @Suppress("IncompleteDestructuring") @Repository class StatusQueryServiceImpl : StatusQueryService { + + protected fun authorizedQuery(principal: Principal? = null): QueryAlias { + if (principal == null) { + return Posts + .selectAll() + .where { + Posts.visibility eq Visibility.PUBLIC.name or (Posts.visibility eq Visibility.UNLISTED.name) + } + .alias("authorized_table") + } + + val relationshipsAlias = Relationships.alias("inverse_relationships") + + return Posts + .leftJoin(PostsVisibleActors) + .leftJoin(Relationships, otherColumn = { actorId }) + .leftJoin(relationshipsAlias, otherColumn = { relationshipsAlias[Relationships.actorId] }) + .selectAll() + .where { + Posts.visibility eq Visibility.PUBLIC.name or + (Posts.visibility eq Visibility.UNLISTED.name) or + (Posts.visibility eq Visibility.DIRECT.name and (PostsVisibleActors.actorId eq principal.actorId.id)) or + (Posts.visibility eq Visibility.FOLLOWERS.name and (Relationships.blocking eq false and (relationshipsAlias[Relationships.following] eq true))) + } + .alias("authorized_table") + } + override suspend fun findByPostIds(ids: List): List = findByPostIdsWithMedia(ids) override suspend fun findByPostIdsWithMediaIds(statusQueries: List): List { @@ -50,10 +74,12 @@ class StatusQueryServiceImpl : StatusQueryService { val emojiIdSet = mutableSetOf() emojiIdSet.addAll(statusQueries.flatMap { it.emojiIds }) + val qa = authorizedQuery() + val postMap = Posts .leftJoin(Actors) .selectAll().where { Posts.id inList postIdSet } - .associate { it[Posts.id] to toStatus(it) } + .associate { it[Posts.id] to toStatus(it, qa) } val mediaMap = Media.selectAll().where { Media.id inList mediaIdSet } .associate { it[Media.id] to it.toMedia().toMediaAttachments() @@ -82,7 +108,8 @@ class StatusQueryServiceImpl : StatusQueryService { tagged: String?, includeFollowers: Boolean, ): List { - val query = Posts + val qa = authorizedQuery() + val query = qa .leftJoin(PostsMedia) .leftJoin(Actors) .leftJoin(Media) @@ -107,7 +134,7 @@ class StatusQueryServiceImpl : StatusQueryService { .groupBy { it[Posts.id] } .map { it.value } .map { - toStatus(it.first()).copy( + toStatus(it.first(), qa).copy( mediaAttachments = it.mapNotNull { resultRow -> resultRow.toMediaOrNull()?.toMediaAttachments() } @@ -119,21 +146,22 @@ class StatusQueryServiceImpl : StatusQueryService { } override suspend fun findByPostId(id: Long, principal: Principal?): Status? { - val map = Posts - .leftJoin(PostsMedia) - .leftJoin(Actors) - .leftJoin(Media,{PostsMedia.mediaId},{Media.id}) + val aq = authorizedQuery(principal) + val map = aq + .leftJoin(PostsMedia, { aq[Posts.id] }, { PostsMedia.postId }) + .leftJoin(Actors, { aq[Posts.actorId] }, { Actors.id }) + .leftJoin(Media, { PostsMedia.mediaId }, { Media.id }) .selectAll() - .where { Posts.id eq id } - .groupBy { it[Posts.id] } + .where { aq[Posts.id] eq id } + .groupBy { it[aq[Posts.id]] } .map { it.value } .map { - toStatus(it.first()).copy( + toStatus(it.first(), aq).copy( mediaAttachments = it.mapNotNull { resultRow -> resultRow.toMediaOrNull()?.toMediaAttachments() }, emojis = it.mapNotNull { resultRow -> resultRow.toCustomEmojiOrNull()?.toMastodonEmoji() } - ) to it.first()[Posts.repostId] + ) to it.first()[aq[Posts.repostId]] } return resolveReplyAndRepost(map).singleOrNull() } @@ -160,6 +188,7 @@ class StatusQueryServiceImpl : StatusQueryService { } private suspend fun findByPostIdsWithMedia(ids: List): List { + val qa = authorizedQuery() val pairs = Posts .leftJoin(PostsMedia) .leftJoin(PostsEmojis) @@ -170,7 +199,7 @@ class StatusQueryServiceImpl : StatusQueryService { .groupBy { it[Posts.id] } .map { it.value } .map { - toStatus(it.first()).copy( + toStatus(it.first(), qa).copy( mediaAttachments = it.mapNotNull { resultRow -> resultRow.toMediaOrNull()?.toMediaAttachments() }, @@ -189,10 +218,10 @@ private fun CustomEmoji.toMastodonEmoji(): MastodonEmoji = MastodonEmoji( category = this.category.orEmpty() ) -private fun toStatus(it: ResultRow) = Status( - id = it[Posts.id].toString(), - uri = it[Posts.apId], - createdAt = it[Posts.createdAt].toString(), +private fun toStatus(it: ResultRow, queryAlias: QueryAlias) = Status( + id = it[queryAlias[Posts.id]].toString(), + uri = it[queryAlias[Posts.apId]], + createdAt = it[queryAlias[Posts.createdAt]].toString(), account = Account( id = it[Actors.id].toString(), username = it[Actors.name], @@ -220,15 +249,15 @@ private fun toStatus(it: ResultRow) = Status( suspended = false, limited = false ), - content = it[Posts.text], - visibility = when (Visibility.valueOf(it[Posts.visibility])) { + content = it[queryAlias[Posts.text]], + visibility = when (Visibility.valueOf(it[queryAlias[Posts.visibility]])) { Visibility.PUBLIC -> public Visibility.UNLISTED -> unlisted Visibility.FOLLOWERS -> private Visibility.DIRECT -> direct }, - sensitive = it[Posts.sensitive], - spoilerText = it[Posts.overview].orEmpty(), + sensitive = it[queryAlias[Posts.sensitive]], + spoilerText = it[queryAlias[Posts.overview]].orEmpty(), mediaAttachments = emptyList(), mentions = emptyList(), tags = emptyList(), @@ -236,11 +265,11 @@ private fun toStatus(it: ResultRow) = Status( reblogsCount = 0, favouritesCount = 0, repliesCount = 0, - url = it[Posts.apId], - inReplyToId = it[Posts.replyId]?.toString(), + url = it[queryAlias[Posts.apId]], + inReplyToId = it[queryAlias[Posts.replyId]]?.toString(), inReplyToAccountId = null, language = null, - text = it[Posts.text], + text = it[queryAlias[Posts.text]], editedAt = null ) diff --git a/hideout-mastodon/src/main/kotlin/dev/usbharu/hideout/mastodon/interfaces/api/SpringAccountApi.kt b/hideout-mastodon/src/main/kotlin/dev/usbharu/hideout/mastodon/interfaces/api/SpringAccountApi.kt index 4a3dd110..a860cded 100644 --- a/hideout-mastodon/src/main/kotlin/dev/usbharu/hideout/mastodon/interfaces/api/SpringAccountApi.kt +++ b/hideout-mastodon/src/main/kotlin/dev/usbharu/hideout/mastodon/interfaces/api/SpringAccountApi.kt @@ -16,7 +16,6 @@ package dev.usbharu.hideout.mastodon.interfaces.api -import dev.usbharu.hideout.core.application.actor.GetUserDetail import dev.usbharu.hideout.core.application.actor.GetUserDetailApplicationService import dev.usbharu.hideout.core.application.relationship.acceptfollowrequest.AcceptFollowRequest import dev.usbharu.hideout.core.application.relationship.acceptfollowrequest.UserAcceptFollowRequestApplicationService @@ -160,7 +159,7 @@ class SpringAccountApi( override suspend fun apiV1AccountsVerifyCredentialsGet(): ResponseEntity { val principal = principalContextHolder.getPrincipal() val localActor = - getUserDetailApplicationService.execute(GetUserDetail(principal.userDetailId.id), principal) + getUserDetailApplicationService.execute(Unit, principal) return ResponseEntity.ok( CredentialAccount( diff --git a/hideout-mastodon/src/main/kotlin/dev/usbharu/hideout/mastodon/interfaces/api/SpringStatusApi.kt b/hideout-mastodon/src/main/kotlin/dev/usbharu/hideout/mastodon/interfaces/api/SpringStatusApi.kt index 0fe04e58..6c2f468a 100644 --- a/hideout-mastodon/src/main/kotlin/dev/usbharu/hideout/mastodon/interfaces/api/SpringStatusApi.kt +++ b/hideout-mastodon/src/main/kotlin/dev/usbharu/hideout/mastodon/interfaces/api/SpringStatusApi.kt @@ -54,6 +54,7 @@ class SpringStatusApi( override suspend fun apiV1StatusesPost(statusesRequest: StatusesRequest): ResponseEntity { + val principal = principalContextHolder.getPrincipal() val execute = registerLocalPostApplicationService.execute( RegisterLocalPost( content = statusesRequest.status.orEmpty(), @@ -69,12 +70,12 @@ class SpringStatusApi( replyId = statusesRequest.inReplyToId?.toLong(), sensitive = statusesRequest.sensitive == true, mediaIds = statusesRequest.mediaIds.orEmpty().map { it.toLong() } - ), principalContextHolder.getPrincipal() + ), principal ) val status = - getStatusApplicationService.execute(GetStatus(execute.toString()), principalContextHolder.getPrincipal()) + getStatusApplicationService.execute(GetStatus(execute.toString()), principal) return ResponseEntity.ok( status ) From ed3b3f07fbc0f4b1eb43671e4ca3a7ce9ef170fa Mon Sep 17 00:00:00 2001 From: usbharu <64310155+usbharu@users.noreply.github.com> Date: Sun, 11 Aug 2024 13:10:10 +0900 Subject: [PATCH 5/7] =?UTF-8?q?fix:=20=E8=87=AA=E5=88=86=E8=87=AA=E8=BA=AB?= =?UTF-8?q?=E3=81=AE=E6=8A=95=E7=A8=BF=E3=81=8C=E8=A6=8B=E3=81=88=E3=81=AA?= =?UTF-8?q?=E3=81=84=E3=82=88=E3=81=86=E3=81=AB=E3=81=AA=E3=81=A3=E3=81=A6?= =?UTF-8?q?=E3=81=84=E3=81=9F=E5=95=8F=E9=A1=8C=E3=82=92=E4=BF=AE=E6=AD=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- hideout-core/src/main/resources/application.yml | 4 +++- .../src/main/resources/db/migration/V1__Init_DB.sql | 4 ++-- hideout-core/src/main/resources/log4j2.xml | 1 + hideout-core/src/main/resources/logback.xml | 2 +- .../status/GetStatusApplicationService.kt | 2 +- .../exposedquery/ExposedStatusQueryService.kt | 12 ++++++++---- 6 files changed, 16 insertions(+), 9 deletions(-) diff --git a/hideout-core/src/main/resources/application.yml b/hideout-core/src/main/resources/application.yml index 29c5fb19..95ad5a20 100644 --- a/hideout-core/src/main/resources/application.yml +++ b/hideout-core/src/main/resources/application.yml @@ -12,7 +12,9 @@ hideout: private-key: "MIIEvwIBADANBgkqhkiG9w0BAQEFAASCBKkwggSlAgEAAoIBAQC7VJTUt9Us8cKjMzEfYyjiWA4R4/M2bS1GB4t7NXp98C3SC6dVMvDuictGeurT8jNbvJZHtCSuYEvuNMoSfm76oqFvAp8Gy0iz5sxjZmSnXyCdPEovGhLa0VzMaQ8s+CLOyS56YyCFGeJZqgtzJ6GR3eqoYSW9b9UMvkBpZODSctWSNGj3P7jRFDO5VoTwCQAWbFnOjDfH5Ulgp2PKSQnSJP3AJLQNFNe7br1XbrhV//eO+t51mIpGSDCUv3E0DDFcWDTH9cXDTTlRZVEiR2BwpZOOkE/Z0/BVnhZYL71oZV34bKfWjQIt6V/isSMahdsAASACp4ZTGtwiVuNd9tybAgMBAAECggEBAKTmjaS6tkK8BlPXClTQ2vpz/N6uxDeS35mXpqasqskVlaAidgg/sWqpjXDbXr93otIMLlWsM+X0CqMDgSXKejLS2jx4GDjI1ZTXg++0AMJ8sJ74pWzVDOfmCEQ/7wXs3+cbnXhKriO8Z036q92Qc1+N87SI38nkGa0ABH9CN83HmQqt4fB7UdHzuIRe/me2PGhIq5ZBzj6h3BpoPGzEP+x3l9YmK8t/1cN0pqI+dQwYdgfGjackLu/2qH80MCF7IyQaseZUOJyKrCLtSD/Iixv/hzDEUPfOCjFDgTpzf3cwta8+oE4wHCo1iI1/4TlPkwmXx4qSXtmw4aQPz7IDQvECgYEA8KNThCO2gsC2I9PQDM/8Cw0O983WCDY+oi+7JPiNAJwv5DYBqEZB1QYdj06YD16XlC/HAZMsMku1na2TN0driwenQQWzoev3g2S7gRDoS/FCJSI3jJ+kjgtaA7Qmzlgk1TxODN+G1H91HW7t0l7VnL27IWyYo2qRRK3jzxqUiPUCgYEAx0oQs2reBQGMVZnApD1jeq7n4MvNLcPvt8b/eU9iUv6Y4Mj0Suo/AU8lYZXm8ubbqAlwz2VSVunD2tOplHyMUrtCtObAfVDUAhCndKaA9gApgfb3xw1IKbuQ1u4IF1FJl3VtumfQn//LiH1B3rXhcdyo3/vIttEk48RakUKClU8CgYEAzV7W3COOlDDcQd935DdtKBFRAPRPAlspQUnzMi5eSHMD/ISLDY5IiQHbIH83D4bvXq0X7qQoSBSNP7Dvv3HYuqMhf0DaegrlBuJllFVVq9qPVRnKxt1Il2HgxOBvbhOT+9in1BzA+YJ99UzC85O0Qz06A+CmtHEy4aZ2kj5hHjECgYEAmNS4+A8Fkss8Js1RieK2LniBxMgmYml3pfVLKGnzmng7H2+cwPLhPIzIuwytXywh2bzbsYEfYx3EoEVgMEpPhoarQnYPukrJO4gwE2o5Te6T5mJSZGlQJQj9q4ZB2Dfzet6INsK0oG8XVGXSpQvQh3RUYekCZQkBBFcpqWpbIEsCgYAnM3DQf3FJoSnXaMhrVBIovic5l0xFkEHskAjFTevO86Fsz1C2aSeRKSqGFoOQ0tmJzBEs1R6KqnHInicDTQrKhArgLXX4v3CddjfTRJkFWDbE/CkvKZNOrcf1nhaGCPspRJj2KUkj1Fhl9Cncdn/RsYEONbwQSjIfMPkvxF+8HQ==" public-key: "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAu1SU1LfVLPHCozMxH2Mo4lgOEePzNm0tRgeLezV6ffAt0gunVTLw7onLRnrq0/IzW7yWR7QkrmBL7jTKEn5u+qKhbwKfBstIs+bMY2Zkp18gnTxKLxoS2tFczGkPLPgizskuemMghRniWaoLcyehkd3qqGElvW/VDL5AaWTg0nLVkjRo9z+40RQzuVaE8AkAFmxZzow3x+VJYKdjykkJ0iT9wCS0DRTXu269V264Vf/3jvredZiKRkgwlL9xNAwxXFg0x/XFw005UWVRIkdgcKWTjpBP2dPwVZ4WWC+9aGVd+Gyn1o0CLelf4rEjGoXbAAEgAqeGUxrcIlbjXfbcmwIDAQAB" private: true - + debug: + trace-query-exception: true + trace-query-call: true diff --git a/hideout-core/src/main/resources/db/migration/V1__Init_DB.sql b/hideout-core/src/main/resources/db/migration/V1__Init_DB.sql index c42a3f7f..e7330e1b 100644 --- a/hideout-core/src/main/resources/db/migration/V1__Init_DB.sql +++ b/hideout-core/src/main/resources/db/migration/V1__Init_DB.sql @@ -188,8 +188,8 @@ create table if not exists relationships following boolean not null, blocking boolean not null, muting boolean not null, - follow_request boolean not null, - ignore_follow_request boolean not null, + follow_requesting boolean not null, + muting_follow_request boolean not null, 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) diff --git a/hideout-core/src/main/resources/log4j2.xml b/hideout-core/src/main/resources/log4j2.xml index 4a2ec926..3a225230 100644 --- a/hideout-core/src/main/resources/log4j2.xml +++ b/hideout-core/src/main/resources/log4j2.xml @@ -12,5 +12,6 @@ + \ No newline at end of file diff --git a/hideout-core/src/main/resources/logback.xml b/hideout-core/src/main/resources/logback.xml index ea1c0ecd..8a8ec24f 100644 --- a/hideout-core/src/main/resources/logback.xml +++ b/hideout-core/src/main/resources/logback.xml @@ -27,7 +27,7 @@ - + diff --git a/hideout-mastodon/src/main/kotlin/dev/usbharu/hideout/mastodon/application/status/GetStatusApplicationService.kt b/hideout-mastodon/src/main/kotlin/dev/usbharu/hideout/mastodon/application/status/GetStatusApplicationService.kt index 3121de94..48f71791 100644 --- a/hideout-mastodon/src/main/kotlin/dev/usbharu/hideout/mastodon/application/status/GetStatusApplicationService.kt +++ b/hideout-mastodon/src/main/kotlin/dev/usbharu/hideout/mastodon/application/status/GetStatusApplicationService.kt @@ -37,7 +37,7 @@ class GetStatusApplicationService( } override suspend fun internalExecute(command: GetStatus, principal: FromApi): Status { - return statusQueryService.findByPostId(command.id.toLong()) + return statusQueryService.findByPostId(command.id.toLong(), principal) ?: throw IllegalArgumentException("Post ${command.id} not found.") } diff --git a/hideout-mastodon/src/main/kotlin/dev/usbharu/hideout/mastodon/infrastructure/exposedquery/ExposedStatusQueryService.kt b/hideout-mastodon/src/main/kotlin/dev/usbharu/hideout/mastodon/infrastructure/exposedquery/ExposedStatusQueryService.kt index 4fdc95c1..2e172a33 100644 --- a/hideout-mastodon/src/main/kotlin/dev/usbharu/hideout/mastodon/infrastructure/exposedquery/ExposedStatusQueryService.kt +++ b/hideout-mastodon/src/main/kotlin/dev/usbharu/hideout/mastodon/infrastructure/exposedquery/ExposedStatusQueryService.kt @@ -51,14 +51,18 @@ class StatusQueryServiceImpl : StatusQueryService { return Posts .leftJoin(PostsVisibleActors) - .leftJoin(Relationships, otherColumn = { actorId }) - .leftJoin(relationshipsAlias, otherColumn = { relationshipsAlias[Relationships.actorId] }) - .selectAll() + .leftJoin(Relationships, onColumn = { Posts.actorId }, otherColumn = { actorId }) + .leftJoin( + relationshipsAlias, + onColumn = { Posts.actorId }, + otherColumn = { relationshipsAlias[Relationships.targetActorId] }) + .select(Posts.columns) .where { Posts.visibility eq Visibility.PUBLIC.name or (Posts.visibility eq Visibility.UNLISTED.name) or (Posts.visibility eq Visibility.DIRECT.name and (PostsVisibleActors.actorId eq principal.actorId.id)) or - (Posts.visibility eq Visibility.FOLLOWERS.name and (Relationships.blocking eq false and (relationshipsAlias[Relationships.following] eq true))) + (Posts.visibility eq Visibility.FOLLOWERS.name and (Relationships.blocking eq false and (relationshipsAlias[Relationships.following] eq true))) or + (Posts.actorId eq principal.actorId.id) } .alias("authorized_table") } From 94f790d0398ad8740368ec44406e9861e2b3c0fc Mon Sep 17 00:00:00 2001 From: usbharu <64310155+usbharu@users.noreply.github.com> Date: Sun, 11 Aug 2024 16:07:10 +0900 Subject: [PATCH 6/7] =?UTF-8?q?test:=20=E6=A8=A9=E9=99=90=E3=83=81?= =?UTF-8?q?=E3=82=A7=E3=83=83=E3=82=AF=E3=81=AE=E3=83=86=E3=82=B9=E3=83=88?= =?UTF-8?q?=E3=82=92=E8=BF=BD=E5=8A=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- hideout-mastodon/build.gradle.kts | 27 ++++++++++++++ .../StatusQueryServiceImplTest.kt | 33 +++++++++++++++++ .../src/test/resources/application.yml | 12 +++++++ .../src/test/resources/sql/actors.sql | 35 +++++++++++++++++++ .../src/test/resources/sql/posts.sql | 15 ++++++++ .../src/test/resources/sql/relationships.sql | 5 +++ 6 files changed, 127 insertions(+) create mode 100644 hideout-mastodon/src/test/kotlin/dev/usbharu/hideout/mastodon/infrastructure/exposedquery/StatusQueryServiceImplTest.kt create mode 100644 hideout-mastodon/src/test/resources/application.yml create mode 100644 hideout-mastodon/src/test/resources/sql/actors.sql create mode 100644 hideout-mastodon/src/test/resources/sql/posts.sql create mode 100644 hideout-mastodon/src/test/resources/sql/relationships.sql diff --git a/hideout-mastodon/build.gradle.kts b/hideout-mastodon/build.gradle.kts index 597af703..5eafc93e 100644 --- a/hideout-mastodon/build.gradle.kts +++ b/hideout-mastodon/build.gradle.kts @@ -17,6 +17,27 @@ version = "1.0-SNAPSHOT" repositories { mavenCentral() + maven { + url = uri("https://git.usbharu.dev/api/packages/usbharu/maven") + } + maven { + name = "GitHubPackages" + url = uri("https://maven.pkg.github.com/usbharu/http-signature") + credentials { + + username = project.findProperty("gpr.user") as String? ?: System.getenv("USERNAME") + password = project.findProperty("gpr.key") as String? ?: System.getenv("TOKEN") + } + } + maven { + name = "GitHubPackages2" + url = uri("https://maven.pkg.github.com/multim-dev/emoji-kt") + credentials { + + username = project.findProperty("gpr.user") as String? ?: System.getenv("USERNAME") + password = project.findProperty("gpr.key") as String? ?: System.getenv("TOKEN") + } + } } configurations { @@ -42,8 +63,14 @@ dependencies { implementation(libs.bundles.exposed) implementation(libs.bundles.openapi) implementation(libs.bundles.coroutines) + + testImplementation("org.springframework.boot:spring-boot-starter-test") + testImplementation(libs.kotlin.junit) + testImplementation(libs.coroutines.test) + testImplementation(libs.h2db) } + tasks { test { useJUnitPlatform() diff --git a/hideout-mastodon/src/test/kotlin/dev/usbharu/hideout/mastodon/infrastructure/exposedquery/StatusQueryServiceImplTest.kt b/hideout-mastodon/src/test/kotlin/dev/usbharu/hideout/mastodon/infrastructure/exposedquery/StatusQueryServiceImplTest.kt new file mode 100644 index 00000000..a23dd3ef --- /dev/null +++ b/hideout-mastodon/src/test/kotlin/dev/usbharu/hideout/mastodon/infrastructure/exposedquery/StatusQueryServiceImplTest.kt @@ -0,0 +1,33 @@ +package dev.usbharu.hideout.mastodon.infrastructure.exposedquery + +import dev.usbharu.hideout.SpringApplication +import dev.usbharu.hideout.core.domain.model.actor.ActorId +import dev.usbharu.hideout.core.domain.model.support.acct.Acct +import dev.usbharu.hideout.core.domain.model.support.principal.FromApi +import dev.usbharu.hideout.core.domain.model.userdetails.UserDetailId +import kotlinx.coroutines.test.runTest +import org.junit.jupiter.api.Assertions.assertNull +import org.junit.jupiter.api.Test +import org.springframework.beans.factory.annotation.Autowired +import org.springframework.boot.test.context.SpringBootTest +import org.springframework.test.context.jdbc.Sql +import org.springframework.transaction.annotation.Transactional + + +@Sql("/sql/actors.sql", executionPhase = Sql.ExecutionPhase.BEFORE_TEST_METHOD) +@Sql("/sql/relationships.sql", executionPhase = Sql.ExecutionPhase.BEFORE_TEST_METHOD) +@Transactional +@SpringBootTest(classes = [SpringApplication::class]) +class StatusQueryServiceImplTest { + + @Autowired + lateinit var statusQueryServiceImpl: StatusQueryServiceImpl + + @Test + fun フォロワー限定をフォロワー以外は見れない() = runTest { + val status = + statusQueryServiceImpl.findByPostId(4, FromApi(ActorId(1), UserDetailId(1), Acct("test", "example.com"))) + + assertNull(status) + } +} \ No newline at end of file diff --git a/hideout-mastodon/src/test/resources/application.yml b/hideout-mastodon/src/test/resources/application.yml new file mode 100644 index 00000000..05671a3f --- /dev/null +++ b/hideout-mastodon/src/test/resources/application.yml @@ -0,0 +1,12 @@ +spring: + datasource: + url: "jdbc:h2:mem:test;MODE=POSTGRESQL;DB_CLOSE_DELAY=-1;CASE_INSENSITIVE_IDENTIFIERS=true;TRACE_LEVEL_FILE=4;" + driver-class-name: org.h2.Driver +hideout: + url: "https://test-hideout-dev.usbharu.dev" + security: + jwt: + generate: true + key-id: a + private-key: "MIIEvwIBADANBgkqhkiG9w0BAQEFAASCBKkwggSlAgEAAoIBAQC7VJTUt9Us8cKjMzEfYyjiWA4R4/M2bS1GB4t7NXp98C3SC6dVMvDuictGeurT8jNbvJZHtCSuYEvuNMoSfm76oqFvAp8Gy0iz5sxjZmSnXyCdPEovGhLa0VzMaQ8s+CLOyS56YyCFGeJZqgtzJ6GR3eqoYSW9b9UMvkBpZODSctWSNGj3P7jRFDO5VoTwCQAWbFnOjDfH5Ulgp2PKSQnSJP3AJLQNFNe7br1XbrhV//eO+t51mIpGSDCUv3E0DDFcWDTH9cXDTTlRZVEiR2BwpZOOkE/Z0/BVnhZYL71oZV34bKfWjQIt6V/isSMahdsAASACp4ZTGtwiVuNd9tybAgMBAAECggEBAKTmjaS6tkK8BlPXClTQ2vpz/N6uxDeS35mXpqasqskVlaAidgg/sWqpjXDbXr93otIMLlWsM+X0CqMDgSXKejLS2jx4GDjI1ZTXg++0AMJ8sJ74pWzVDOfmCEQ/7wXs3+cbnXhKriO8Z036q92Qc1+N87SI38nkGa0ABH9CN83HmQqt4fB7UdHzuIRe/me2PGhIq5ZBzj6h3BpoPGzEP+x3l9YmK8t/1cN0pqI+dQwYdgfGjackLu/2qH80MCF7IyQaseZUOJyKrCLtSD/Iixv/hzDEUPfOCjFDgTpzf3cwta8+oE4wHCo1iI1/4TlPkwmXx4qSXtmw4aQPz7IDQvECgYEA8KNThCO2gsC2I9PQDM/8Cw0O983WCDY+oi+7JPiNAJwv5DYBqEZB1QYdj06YD16XlC/HAZMsMku1na2TN0driwenQQWzoev3g2S7gRDoS/FCJSI3jJ+kjgtaA7Qmzlgk1TxODN+G1H91HW7t0l7VnL27IWyYo2qRRK3jzxqUiPUCgYEAx0oQs2reBQGMVZnApD1jeq7n4MvNLcPvt8b/eU9iUv6Y4Mj0Suo/AU8lYZXm8ubbqAlwz2VSVunD2tOplHyMUrtCtObAfVDUAhCndKaA9gApgfb3xw1IKbuQ1u4IF1FJl3VtumfQn//LiH1B3rXhcdyo3/vIttEk48RakUKClU8CgYEAzV7W3COOlDDcQd935DdtKBFRAPRPAlspQUnzMi5eSHMD/ISLDY5IiQHbIH83D4bvXq0X7qQoSBSNP7Dvv3HYuqMhf0DaegrlBuJllFVVq9qPVRnKxt1Il2HgxOBvbhOT+9in1BzA+YJ99UzC85O0Qz06A+CmtHEy4aZ2kj5hHjECgYEAmNS4+A8Fkss8Js1RieK2LniBxMgmYml3pfVLKGnzmng7H2+cwPLhPIzIuwytXywh2bzbsYEfYx3EoEVgMEpPhoarQnYPukrJO4gwE2o5Te6T5mJSZGlQJQj9q4ZB2Dfzet6INsK0oG8XVGXSpQvQh3RUYekCZQkBBFcpqWpbIEsCgYAnM3DQf3FJoSnXaMhrVBIovic5l0xFkEHskAjFTevO86Fsz1C2aSeRKSqGFoOQ0tmJzBEs1R6KqnHInicDTQrKhArgLXX4v3CddjfTRJkFWDbE/CkvKZNOrcf1nhaGCPspRJj2KUkj1Fhl9Cncdn/RsYEONbwQSjIfMPkvxF+8HQ==" + public-key: "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAu1SU1LfVLPHCozMxH2Mo4lgOEePzNm0tRgeLezV6ffAt0gunVTLw7onLRnrq0/IzW7yWR7QkrmBL7jTKEn5u+qKhbwKfBstIs+bMY2Zkp18gnTxKLxoS2tFczGkPLPgizskuemMghRniWaoLcyehkd3qqGElvW/VDL5AaWTg0nLVkjRo9z+40RQzuVaE8AkAFmxZzow3x+VJYKdjykkJ0iT9wCS0DRTXu269V264Vf/3jvredZiKRkgwlL9xNAwxXFg0x/XFw005UWVRIkdgcKWTjpBP2dPwVZ4WWC+9aGVd+Gyn1o0CLelf4rEjGoXbAAEgAqeGUxrcIlbjXfbcmwIDAQAB" \ No newline at end of file diff --git a/hideout-mastodon/src/test/resources/sql/actors.sql b/hideout-mastodon/src/test/resources/sql/actors.sql new file mode 100644 index 00000000..cf62085d --- /dev/null +++ b/hideout-mastodon/src/test/resources/sql/actors.sql @@ -0,0 +1,35 @@ +insert into instance(id, name, description, url, icon_url, shared_inbox, software, version, is_blocked, is_muted, + moderation_note, created_at) +VALUES (1, 'instance', 'description', 'https://example.com', 'https://example.com', 'https://example.com', 'software', + 'version', false, false, 'note', current_timestamp) + , (2, 'instance', 'description', 'https://remote.example.com', 'https://example.com', 'https://remote.example.com', + 'software', + 'version', false, false, 'note', current_timestamp) + , (3, 'instance', 'description', 'https://remote2.example.com', 'https://example.com', + 'https://remote2.example.com', 'software', + 'version', false, false, 'note', current_timestamp); + +insert into actors(id, name, domain, screen_name, description, inbox, outbox, url, public_key, private_key, created_at, + key_id, following, followers, instance, locked, following_count, followers_count, posts_count, + last_post_at, last_update_at, suspend, move_to, icon, banner) +VALUES (1, 'test', 'example.com', 'test-actor', 'actor_description', 'https://example.com/test/inbox', + 'https://example.com/outbox', 'https://example.com/test', '---BEGIN PUBLIC KEY---', '---BEGIN PRIVATE KEY---', + current_timestamp, 'https://example.com/test#main-key', 'https://example.com/test/following', + 'https://example.com/test/followers', 1, false, 1, 0, 0, null, current_timestamp, false, null, null, null), + (2, 'test', 'remote.example.com', 'test-actor', 'actor_description', 'https://remote.example.com/test/inbox', + 'https://remote.example.com/outbox', 'https://remote.example.com', '---BEGIN PUBLIC KEY---', + '---BEGIN PRIVATE KEY---', + current_timestamp, 'https://remote.example.com/test#main-key', 'https://remote.example.com/test/following', + 'https://remote.example.com/test/followers', 2, false, 1, 0, 0, null, current_timestamp, false, null, null, + null), + (3, 'test', 'remote2.example.com', 'test-actor', 'actor_description', 'https://remote2.example.com/test/inbox', + 'https://remote2.example.com/test/outbox', 'https://remote2.example.com/test', '---BEGIN PUBLIC KEY---', + '---BEGIN PRIVATE KEY---', + current_timestamp, 'https://remote2.example.com/test#main-key', 'https://remote2.example.com/test/following', + 'https://example.com/followers', 3, false, 1, 0, 0, null, current_timestamp, false, null, null, null), + (4, 'test2', 'remote2.example.com', 'test-actor', 'actor_description', 'https://example.com/inbox', + 'https://remote2.example.com/test2/outbox', 'https://remote2.example.com/test2', '---BEGIN PUBLIC KEY---', + '---BEGIN PRIVATE KEY---', + current_timestamp, 'https://remote2.example.com/test2#main-key', 'https://remote2.example.com/test2/following', + 'https://remote2.example.com/test2/followers', 3, false, 1, 0, 0, null, current_timestamp, false, null, null, + null); \ No newline at end of file diff --git a/hideout-mastodon/src/test/resources/sql/posts.sql b/hideout-mastodon/src/test/resources/sql/posts.sql new file mode 100644 index 00000000..f8dec6b9 --- /dev/null +++ b/hideout-mastodon/src/test/resources/sql/posts.sql @@ -0,0 +1,15 @@ +insert into posts (id, actor_id, instance_id, overview, content, text, created_at, visibility, url, repost_id, reply_id, + sensitive, ap_id, deleted, hide, move_to) +values (1, 1, 1, null, 'content', 'text', current_timestamp, 'PUBLIC', 'https://example.com', null, null, false, + 'https://example.com', false, false, null), + (2, 2, 2, null, 'content', 'text', current_timestamp, 'FOLLOWERS', 'https://example.com', null, null, false, + 'https://example.com', false, false, null), + (3, 3, 1, null, 'content', 'text', current_timestamp, 'PUBLIC', 'https://example.com', null, null, false, + 'https://example.com', false, false, null), + (4, 4, 1, null, 'content', 'text', current_timestamp, 'FOLLOWERS', 'https://example.com', null, null, false, + 'https://example.com', false, false, null), + (5, 4, 1, null, 'content', 'text', current_timestamp, 'DIRECT', 'https://example.com', null, null, false, + 'https://example.com', false, false, null); + +insert into posts_visible_actors(post_id, actor_id) +VALUES (5, 2); \ No newline at end of file diff --git a/hideout-mastodon/src/test/resources/sql/relationships.sql b/hideout-mastodon/src/test/resources/sql/relationships.sql new file mode 100644 index 00000000..1470b2d9 --- /dev/null +++ b/hideout-mastodon/src/test/resources/sql/relationships.sql @@ -0,0 +1,5 @@ +insert into relationships(id, actor_id, target_actor_id, following, blocking, muting, follow_requesting, + muting_follow_request) +VALUES (1, 1, 2, true, false, false, false, false), + (2, 2, 1, true, false, false, false, false), + (3, 1, 3, false, true, false, false, false); \ No newline at end of file From 7ec997c1d5b1292c56489deaee7bec41772e42e1 Mon Sep 17 00:00:00 2001 From: usbharu <64310155+usbharu@users.noreply.github.com> Date: Sun, 11 Aug 2024 16:33:22 +0900 Subject: [PATCH 7/7] =?UTF-8?q?fix:=20=E3=82=88=E3=81=8F=E3=81=AA=E3=81=84?= =?UTF-8?q?=E4=BF=AE=E6=AD=A3=E3=81=A0=E3=81=A3=E3=81=9F=E3=81=AE=E3=81=A7?= =?UTF-8?q?=E3=83=AD=E3=83=BC=E3=83=AB=E3=83=90=E3=83=83=E3=82=AF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../actor/GetUserDetailApplicationService.kt | 15 ++++++++------- .../LocalUserAbstractApplicationServiceTest.kt | 3 ++- .../mastodon/interfaces/api/SpringAccountApi.kt | 8 +++++++- 3 files changed, 17 insertions(+), 9 deletions(-) diff --git a/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/application/actor/GetUserDetailApplicationService.kt b/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/application/actor/GetUserDetailApplicationService.kt index 0d67740d..6d990ee2 100644 --- a/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/application/actor/GetUserDetailApplicationService.kt +++ b/hideout-core/src/main/kotlin/dev/usbharu/hideout/core/application/actor/GetUserDetailApplicationService.kt @@ -17,11 +17,12 @@ package dev.usbharu.hideout.core.application.actor import dev.usbharu.hideout.core.application.exception.InternalServerException -import dev.usbharu.hideout.core.application.shared.LocalUserAbstractApplicationService +import dev.usbharu.hideout.core.application.shared.AbstractApplicationService import dev.usbharu.hideout.core.application.shared.Transaction import dev.usbharu.hideout.core.domain.model.actor.ActorRepository import dev.usbharu.hideout.core.domain.model.emoji.CustomEmojiRepository -import dev.usbharu.hideout.core.domain.model.support.principal.FromApi +import dev.usbharu.hideout.core.domain.model.support.principal.Principal +import dev.usbharu.hideout.core.domain.model.userdetails.UserDetailId import dev.usbharu.hideout.core.domain.model.userdetails.UserDetailRepository import org.slf4j.LoggerFactory import org.springframework.stereotype.Service @@ -33,10 +34,10 @@ class GetUserDetailApplicationService( private val customEmojiRepository: CustomEmojiRepository, transaction: Transaction, ) : - LocalUserAbstractApplicationService(transaction, Companion.logger) { - override suspend fun internalExecute(command: Unit, principal: FromApi): UserDetail { - val userDetail = userDetailRepository.findById(principal.userDetailId) - ?: throw IllegalArgumentException("User ${principal.userDetailId} does not exist") + AbstractApplicationService(transaction, Companion.logger) { + override suspend fun internalExecute(command: GetUserDetail, principal: Principal): UserDetail { + val userDetail = userDetailRepository.findById(UserDetailId(command.id)) + ?: throw IllegalArgumentException("User ${command.id} does not exist") val actor = actorRepository.findById(userDetail.actorId) ?: throw InternalServerException("Actor ${userDetail.actorId} not found") @@ -46,6 +47,6 @@ class GetUserDetailApplicationService( } companion object { - private val logger = LoggerFactory.getLogger(GetUserDetailApplicationService::class.java) + val logger = LoggerFactory.getLogger(GetUserDetailApplicationService::class.java) } } diff --git a/hideout-core/src/test/kotlin/dev/usbharu/hideout/core/application/shared/LocalUserAbstractApplicationServiceTest.kt b/hideout-core/src/test/kotlin/dev/usbharu/hideout/core/application/shared/LocalUserAbstractApplicationServiceTest.kt index a52a29d7..581bac6a 100644 --- a/hideout-core/src/test/kotlin/dev/usbharu/hideout/core/application/shared/LocalUserAbstractApplicationServiceTest.kt +++ b/hideout-core/src/test/kotlin/dev/usbharu/hideout/core/application/shared/LocalUserAbstractApplicationServiceTest.kt @@ -1,5 +1,6 @@ package dev.usbharu.hideout.core.application.shared +import dev.usbharu.hideout.core.application.exception.PermissionDeniedException import dev.usbharu.hideout.core.domain.model.support.principal.Anonymous import dev.usbharu.hideout.core.domain.model.support.principal.FromApi import kotlinx.coroutines.test.runTest @@ -17,7 +18,7 @@ class LocalUserAbstractApplicationServiceTest { } } - org.junit.jupiter.api.assertThrows { + org.junit.jupiter.api.assertThrows { value.execute(Unit, Anonymous) } } diff --git a/hideout-mastodon/src/main/kotlin/dev/usbharu/hideout/mastodon/interfaces/api/SpringAccountApi.kt b/hideout-mastodon/src/main/kotlin/dev/usbharu/hideout/mastodon/interfaces/api/SpringAccountApi.kt index a860cded..15b9226b 100644 --- a/hideout-mastodon/src/main/kotlin/dev/usbharu/hideout/mastodon/interfaces/api/SpringAccountApi.kt +++ b/hideout-mastodon/src/main/kotlin/dev/usbharu/hideout/mastodon/interfaces/api/SpringAccountApi.kt @@ -16,7 +16,9 @@ package dev.usbharu.hideout.mastodon.interfaces.api +import dev.usbharu.hideout.core.application.actor.GetUserDetail import dev.usbharu.hideout.core.application.actor.GetUserDetailApplicationService +import dev.usbharu.hideout.core.application.exception.PermissionDeniedException import dev.usbharu.hideout.core.application.relationship.acceptfollowrequest.AcceptFollowRequest import dev.usbharu.hideout.core.application.relationship.acceptfollowrequest.UserAcceptFollowRequestApplicationService import dev.usbharu.hideout.core.application.relationship.block.Block @@ -159,7 +161,11 @@ class SpringAccountApi( override suspend fun apiV1AccountsVerifyCredentialsGet(): ResponseEntity { val principal = principalContextHolder.getPrincipal() val localActor = - getUserDetailApplicationService.execute(Unit, principal) + getUserDetailApplicationService.execute( + GetUserDetail( + principal.userDetailId?.id ?: throw PermissionDeniedException() + ), principal + ) return ResponseEntity.ok( CredentialAccount(