fix(block-member): 양방향 차단 관계의 댓글·응원·콘텐츠 노출을 차단한다
This commit is contained in:
@@ -133,6 +133,6 @@ class ExplorerController(
|
||||
pageable: Pageable
|
||||
) = run {
|
||||
if (member == null) throw SodaException(messageKey = "common.error.bad_credentials")
|
||||
ApiResponse.ok(service.getCreatorProfileCheers(creatorId, timezone, pageable))
|
||||
ApiResponse.ok(service.getCreatorProfileCheers(creatorId, timezone, member, pageable))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -451,30 +451,52 @@ class ExplorerQueryRepository(
|
||||
.fetchFirst() ?: ""
|
||||
}
|
||||
|
||||
fun getCheersList(creatorId: Long, timezone: String, offset: Long, limit: Long): GetCheersResponse {
|
||||
fun getCheersList(creatorId: Long, memberId: Long, timezone: String, offset: Long, limit: Long): GetCheersResponse {
|
||||
val cheersDatePattern = messageSource
|
||||
.getMessage("explorer.date.cheers.format", langContext.lang)
|
||||
?: messageSource.getMessage("explorer.date.cheers.format", Lang.KO).orEmpty()
|
||||
val cheersDateFormatter = DateTimeFormatter.ofPattern(cheersDatePattern)
|
||||
.withLocale(langContext.lang.locale)
|
||||
|
||||
val blockedByMemberIdSet = queryFactory
|
||||
.select(blockMember.blockedMember.id)
|
||||
.from(blockMember)
|
||||
.where(
|
||||
blockMember.member.id.eq(memberId)
|
||||
.and(blockMember.isActive.isTrue)
|
||||
)
|
||||
.fetch()
|
||||
.toSet()
|
||||
|
||||
val blockingMemberIdSet = queryFactory
|
||||
.select(blockMember.member.id)
|
||||
.from(blockMember)
|
||||
.where(
|
||||
blockMember.blockedMember.id.eq(memberId)
|
||||
.and(blockMember.isActive.isTrue)
|
||||
)
|
||||
.fetch()
|
||||
.toSet()
|
||||
|
||||
val blockedMemberIdSet = blockedByMemberIdSet + blockingMemberIdSet
|
||||
|
||||
var where = creatorCheers.creator.id.eq(creatorId)
|
||||
.and(creatorCheers.isActive.isTrue)
|
||||
.and(creatorCheers.parent.isNull)
|
||||
|
||||
if (blockedMemberIdSet.isNotEmpty()) {
|
||||
where = where.and(creatorCheers.member.id.notIn(blockedMemberIdSet))
|
||||
}
|
||||
|
||||
val totalCount = queryFactory
|
||||
.selectFrom(creatorCheers)
|
||||
.where(
|
||||
creatorCheers.creator.id.eq(creatorId)
|
||||
.and(creatorCheers.isActive.isTrue)
|
||||
.and(creatorCheers.parent.isNull)
|
||||
)
|
||||
.where(where)
|
||||
.fetch()
|
||||
.count()
|
||||
|
||||
val cheers = queryFactory
|
||||
.selectFrom(creatorCheers)
|
||||
.where(
|
||||
creatorCheers.creator.id.eq(creatorId)
|
||||
.and(creatorCheers.isActive.isTrue)
|
||||
.and(creatorCheers.parent.isNull)
|
||||
)
|
||||
.where(where)
|
||||
.offset(offset)
|
||||
.limit(limit)
|
||||
.orderBy(creatorCheers.id.desc())
|
||||
@@ -498,6 +520,9 @@ class ExplorerQueryRepository(
|
||||
languageCode = it.languageCode,
|
||||
date = date.format(cheersDateFormatter),
|
||||
replyList = it.children.asSequence()
|
||||
.filterNot { cheers ->
|
||||
cheers.member?.id != null && blockedMemberIdSet.contains(cheers.member!!.id!!)
|
||||
}
|
||||
.map { cheers ->
|
||||
val replyDate = cheers.createdAt!!
|
||||
.atZone(ZoneId.of("UTC"))
|
||||
|
||||
@@ -65,7 +65,7 @@ class ExplorerService(
|
||||
fun getCreatorRank(memberId: Long): GetExplorerSectionResponse {
|
||||
val creatorRankings = queryRepository
|
||||
.getCreatorRankings()
|
||||
.filter { !memberService.isBlocked(blockedMemberId = memberId, memberId = it.id!!) }
|
||||
.filter { !isBlockedBetweenMembers(memberId = memberId, otherMemberId = it.id!!) }
|
||||
.map { it.toExplorerSectionCreator(cloudFrontHost) }
|
||||
|
||||
val currentDateTime = LocalDateTime.now()
|
||||
@@ -101,7 +101,7 @@ class ExplorerService(
|
||||
// 인기 크리에이터
|
||||
val creatorRankings = queryRepository
|
||||
.getCreatorRankings()
|
||||
.filter { !memberService.isBlocked(blockedMemberId = member.id!!, memberId = it.id!!) }
|
||||
.filter { !isBlockedBetweenMembers(memberId = member.id!!, otherMemberId = it.id!!) }
|
||||
.map { it.toExplorerSectionCreator(cloudFrontHost) }
|
||||
|
||||
val currentDateTime = LocalDateTime.now()
|
||||
@@ -134,7 +134,7 @@ class ExplorerService(
|
||||
// 새로 시작 (newCreators)
|
||||
val newCreators = queryRepository
|
||||
.getNewCreators()
|
||||
.filter { !memberService.isBlocked(blockedMemberId = member.id!!, memberId = it.id!!) }
|
||||
.filter { !isBlockedBetweenMembers(memberId = member.id!!, otherMemberId = it.id!!) }
|
||||
.map { it.toExplorerSectionCreator(cloudFrontHost) }
|
||||
|
||||
val newCreatorsSection = GetExplorerSectionResponse(
|
||||
@@ -153,7 +153,7 @@ class ExplorerService(
|
||||
color = "39abde",
|
||||
creators = queryRepository
|
||||
.findCreatorByGender(1)
|
||||
.filter { !memberService.isBlocked(blockedMemberId = member.id!!, memberId = it.id!!) }
|
||||
.filter { !isBlockedBetweenMembers(memberId = member.id!!, otherMemberId = it.id!!) }
|
||||
.map { it.toExplorerSectionCreator(cloudFrontHost) }
|
||||
)
|
||||
|
||||
@@ -164,7 +164,7 @@ class ExplorerService(
|
||||
color = "ffa517",
|
||||
creators = queryRepository
|
||||
.findCreatorByGender(0)
|
||||
.filter { !memberService.isBlocked(blockedMemberId = member.id!!, memberId = it.id!!) }
|
||||
.filter { !isBlockedBetweenMembers(memberId = member.id!!, otherMemberId = it.id!!) }
|
||||
.map { it.toExplorerSectionCreator(cloudFrontHost) }
|
||||
)
|
||||
|
||||
@@ -187,7 +187,7 @@ class ExplorerService(
|
||||
|
||||
return queryRepository.getSearchChannel(channel, member.id!!)
|
||||
.asSequence()
|
||||
.filter { !memberService.isBlocked(blockedMemberId = member.id!!, memberId = it.id!!) }
|
||||
.filter { !isBlockedBetweenMembers(memberId = member.id!!, otherMemberId = it.id!!) }
|
||||
.map { GetRoomDetailUser(it, cloudFrontHost) }
|
||||
.toList()
|
||||
}
|
||||
@@ -203,8 +203,9 @@ class ExplorerService(
|
||||
?: throw SodaException(messageKey = "member.validation.user_not_found")
|
||||
|
||||
// 차단된 사용자 체크
|
||||
val isBlocked = memberService.isBlocked(blockedMemberId = member.id!!, memberId = creatorId)
|
||||
if (isBlocked) {
|
||||
val isBlockedByCreator = memberService.isBlocked(blockedMemberId = member.id!!, memberId = creatorId)
|
||||
val isBlock = memberService.isBlocked(blockedMemberId = creatorId, memberId = member.id!!)
|
||||
if (isBlockedByCreator || isBlock) {
|
||||
val messageTemplate = messageSource
|
||||
.getMessage("explorer.creator.blocked_access", langContext.lang)
|
||||
.orEmpty()
|
||||
@@ -240,7 +241,7 @@ class ExplorerService(
|
||||
}
|
||||
|
||||
// 라이브
|
||||
val liveRoomList = if (isCreator) {
|
||||
val liveRoomList = if (isCreator && !isBlock) {
|
||||
queryRepository.getLiveRoomList(
|
||||
creatorId,
|
||||
userMember = member,
|
||||
@@ -251,7 +252,7 @@ class ExplorerService(
|
||||
}
|
||||
|
||||
// 오디오 콘텐츠
|
||||
val contentList = if (isCreator) {
|
||||
val contentList = if (isCreator && !isBlock) {
|
||||
audioContentService.getAudioContentList(
|
||||
creatorId = creatorId,
|
||||
sortType = SortType.NEWEST,
|
||||
@@ -284,7 +285,7 @@ class ExplorerService(
|
||||
}
|
||||
|
||||
// 크리에이터의 최신 오디오 콘텐츠 1개
|
||||
val latestContent = if (isCreator) {
|
||||
val latestContent = if (isCreator && !isBlock) {
|
||||
audioContentService.getLatestCreatorAudioContent(creatorId, member, isAdultContentVisible)
|
||||
} else {
|
||||
null
|
||||
@@ -326,11 +327,15 @@ class ExplorerService(
|
||||
}
|
||||
|
||||
// 응원
|
||||
val cheers = queryRepository.getCheersList(creatorId, timezone = timezone, offset = 0, limit = 4)
|
||||
val cheers = queryRepository.getCheersList(
|
||||
creatorId = creatorId,
|
||||
memberId = member.id!!,
|
||||
timezone = timezone,
|
||||
offset = 0,
|
||||
limit = 4
|
||||
)
|
||||
|
||||
// 차단한 크리에이터 인지 체크
|
||||
val isBlock = memberService.isBlocked(blockedMemberId = creatorId, memberId = member.id!!)
|
||||
|
||||
val activitySummary = if (isCreator) {
|
||||
// 활동요약 (라이브 횟수, 라이브 시간, 라이브 참여자, 콘텐츠 수)
|
||||
val liveCount = queryRepository.getLiveCount(creatorId) ?: 0
|
||||
@@ -347,7 +352,7 @@ class ExplorerService(
|
||||
GetCreatorActivitySummary(0, 0, 0, 0)
|
||||
}
|
||||
|
||||
val seriesList = if (isCreator) {
|
||||
val seriesList = if (isCreator && !isBlock) {
|
||||
seriesService
|
||||
.getSeriesList(
|
||||
creatorId = creatorId,
|
||||
@@ -516,7 +521,7 @@ class ExplorerService(
|
||||
val creator = queryRepository.getMember(request.creatorId)
|
||||
?: throw SodaException(messageKey = "member.validation.user_not_found")
|
||||
|
||||
val isBlocked = memberService.isBlocked(blockedMemberId = member.id!!, memberId = request.creatorId)
|
||||
val isBlocked = isBlockedBetweenMembers(memberId = member.id!!, otherMemberId = request.creatorId)
|
||||
if (isBlocked) {
|
||||
val messageTemplate = messageSource
|
||||
.getMessage("explorer.creator.blocked_cheers", langContext.lang)
|
||||
@@ -555,10 +560,16 @@ class ExplorerService(
|
||||
fun getCreatorProfileCheers(
|
||||
creatorId: Long,
|
||||
timezone: String,
|
||||
member: Member,
|
||||
pageable: Pageable
|
||||
): GetCheersResponse {
|
||||
if (isBlockedBetweenMembers(memberId = member.id!!, otherMemberId = creatorId)) {
|
||||
throw SodaException(messageKey = "common.error.invalid_request")
|
||||
}
|
||||
|
||||
return queryRepository.getCheersList(
|
||||
creatorId = creatorId,
|
||||
memberId = member.id!!,
|
||||
timezone = timezone,
|
||||
offset = pageable.offset,
|
||||
limit = pageable.pageSize.toLong()
|
||||
@@ -607,4 +618,9 @@ class ExplorerService(
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
private fun isBlockedBetweenMembers(memberId: Long, otherMemberId: Long): Boolean {
|
||||
return memberService.isBlocked(blockedMemberId = memberId, memberId = otherMemberId) ||
|
||||
memberService.isBlocked(blockedMemberId = otherMemberId, memberId = memberId)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -179,6 +179,7 @@ class CreatorCommunityController(private val service: CreatorCommunityService) {
|
||||
ApiResponse.ok(
|
||||
service.getCommentReplyList(
|
||||
commentId = commentId,
|
||||
memberId = member.id!!,
|
||||
timezone = timezone,
|
||||
offset = pageable.offset,
|
||||
limit = pageable.pageSize.toLong()
|
||||
|
||||
@@ -181,7 +181,7 @@ class CreatorCommunityService(
|
||||
limit: Long,
|
||||
isAdult: Boolean
|
||||
): List<GetCommunityPostListResponse> {
|
||||
if (blockMemberRepository.isBlocked(blockedMemberId = memberId, memberId = creatorId)) {
|
||||
if (isBlockedBetweenMembers(memberId = memberId, creatorId = creatorId)) {
|
||||
return listOf()
|
||||
}
|
||||
|
||||
@@ -275,7 +275,7 @@ class CreatorCommunityService(
|
||||
val post = repository.getCommunityPost(postId, isAdult = isAdult)
|
||||
?: throw SodaException(messageKey = "creator.community.invalid_request_retry")
|
||||
|
||||
val isBlocked = blockMemberRepository.isBlocked(blockedMemberId = memberId, memberId = post.creatorId)
|
||||
val isBlocked = isBlockedBetweenMembers(memberId = memberId, creatorId = post.creatorId)
|
||||
if (isBlocked) {
|
||||
val messageTemplate = messageSource
|
||||
.getMessage("creator.community.blocked_access", langContext.lang)
|
||||
@@ -375,6 +375,11 @@ class CreatorCommunityService(
|
||||
) {
|
||||
val post = repository.findByIdOrNull(id = postId)
|
||||
?: throw SodaException(messageKey = "creator.community.invalid_post_retry")
|
||||
|
||||
if (isBlockedBetweenMembers(memberId = member.id!!, creatorId = post.member!!.id!!)) {
|
||||
throw SodaException(messageKey = "creator.community.invalid_access_retry")
|
||||
}
|
||||
|
||||
val isExistOrdered = useCanRepository.isExistCommunityPostOrdered(postId = postId, memberId = member.id!!)
|
||||
|
||||
if (isSecret && !isExistOrdered) {
|
||||
@@ -425,6 +430,11 @@ class CreatorCommunityService(
|
||||
offset: Long,
|
||||
limit: Long
|
||||
): GetCommunityPostCommentListResponse {
|
||||
val post = repository.findByIdOrNull(id = postId)
|
||||
if (post != null && isBlockedBetweenMembers(memberId = memberId, creatorId = post.member!!.id!!)) {
|
||||
return GetCommunityPostCommentListResponse(totalCount = 0, items = listOf())
|
||||
}
|
||||
|
||||
val commentList = commentRepository.findByPostId(
|
||||
id = postId,
|
||||
memberId = memberId,
|
||||
@@ -444,18 +454,28 @@ class CreatorCommunityService(
|
||||
|
||||
fun getCommentReplyList(
|
||||
commentId: Long,
|
||||
memberId: Long,
|
||||
timezone: String,
|
||||
offset: Long,
|
||||
limit: Long
|
||||
): GetCommunityPostCommentListResponse {
|
||||
val parentComment = commentRepository.findByIdOrNull(id = commentId)
|
||||
if (
|
||||
parentComment != null &&
|
||||
isBlockedBetweenMembers(memberId = memberId, creatorId = parentComment.creatorCommunity!!.member!!.id!!)
|
||||
) {
|
||||
return GetCommunityPostCommentListResponse(totalCount = 0, items = listOf())
|
||||
}
|
||||
|
||||
val commentList = commentRepository.getCommunityCommentReplyList(
|
||||
commentId = commentId,
|
||||
memberId = memberId,
|
||||
timezone = timezone,
|
||||
offset = offset,
|
||||
limit = limit
|
||||
)
|
||||
|
||||
val totalCount = commentRepository.commentReplyCountByCommentId(commentId)
|
||||
val totalCount = commentRepository.commentReplyCountByCommentId(commentId, memberId)
|
||||
return GetCommunityPostCommentListResponse(totalCount = totalCount, items = commentList)
|
||||
}
|
||||
|
||||
@@ -469,10 +489,7 @@ class CreatorCommunityService(
|
||||
|
||||
return postList
|
||||
.filter {
|
||||
!blockMemberRepository.isBlocked(
|
||||
blockedMemberId = memberId,
|
||||
memberId = it.creatorId
|
||||
)
|
||||
!isBlockedBetweenMembers(memberId = memberId, creatorId = it.creatorId)
|
||||
}
|
||||
.map {
|
||||
val isLike =
|
||||
@@ -541,7 +558,7 @@ class CreatorCommunityService(
|
||||
val post = repository.findByIdAndActive(postId, isAdult)
|
||||
?: throw SodaException(messageKey = "creator.community.invalid_request_retry")
|
||||
|
||||
val isBlocked = blockMemberRepository.isBlocked(blockedMemberId = memberId, memberId = post.member!!.id!!)
|
||||
val isBlocked = isBlockedBetweenMembers(memberId = memberId, creatorId = post.member!!.id!!)
|
||||
if (isBlocked) {
|
||||
val messageTemplate = messageSource
|
||||
.getMessage("creator.community.blocked_access", langContext.lang)
|
||||
@@ -616,4 +633,9 @@ class CreatorCommunityService(
|
||||
firstComment = firstComment
|
||||
)
|
||||
}
|
||||
|
||||
private fun isBlockedBetweenMembers(memberId: Long, creatorId: Long): Boolean {
|
||||
return blockMemberRepository.isBlocked(blockedMemberId = memberId, memberId = creatorId) ||
|
||||
blockMemberRepository.isBlocked(blockedMemberId = creatorId, memberId = memberId)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,9 +1,11 @@
|
||||
package kr.co.vividnext.sodalive.explorer.profile.creatorCommunity.comment
|
||||
|
||||
import com.querydsl.core.types.dsl.Expressions
|
||||
import com.querydsl.jpa.JPAExpressions
|
||||
import com.querydsl.jpa.impl.JPAQueryFactory
|
||||
import kr.co.vividnext.sodalive.explorer.profile.creatorCommunity.comment.QCreatorCommunityComment.creatorCommunityComment
|
||||
import kr.co.vividnext.sodalive.extensions.removeDeletedNicknamePrefix
|
||||
import kr.co.vividnext.sodalive.member.block.QBlockMember.blockMember
|
||||
import org.springframework.beans.factory.annotation.Value
|
||||
import org.springframework.data.jpa.repository.JpaRepository
|
||||
import java.time.LocalDateTime
|
||||
@@ -21,7 +23,7 @@ interface CreatorCommunityCommentQueryRepository {
|
||||
limit: Long
|
||||
): List<GetCommunityPostCommentListItem>
|
||||
|
||||
fun commentReplyCountByCommentId(commentId: Long): Int
|
||||
fun commentReplyCountByCommentId(commentId: Long, memberId: Long): Int
|
||||
|
||||
fun totalCountCommentByPostId(
|
||||
postId: Long,
|
||||
@@ -31,6 +33,7 @@ interface CreatorCommunityCommentQueryRepository {
|
||||
|
||||
fun getCommunityCommentReplyList(
|
||||
commentId: Long,
|
||||
memberId: Long,
|
||||
timezone: String,
|
||||
offset: Long,
|
||||
limit: Long
|
||||
@@ -66,6 +69,8 @@ class CreatorCommunityCommentQueryRepositoryImpl(
|
||||
var where = creatorCommunityComment.isActive.isTrue
|
||||
.and(creatorCommunityComment.creatorCommunity.id.eq(id))
|
||||
.and(creatorCommunityComment.parent.isNull)
|
||||
.and(creatorCommunityComment.member.id.notIn(blockedMemberIdSubQuery(memberId)))
|
||||
.and(creatorCommunityComment.member.id.notIn(blockingMemberIdSubQuery(memberId)))
|
||||
|
||||
if (!isContentCreator) {
|
||||
where = where.and(
|
||||
@@ -96,18 +101,20 @@ class CreatorCommunityCommentQueryRepositoryImpl(
|
||||
.map {
|
||||
it.copy(
|
||||
nickname = it.nickname.removeDeletedNicknamePrefix(),
|
||||
replyCount = commentReplyCountByCommentId(it.id)
|
||||
replyCount = commentReplyCountByCommentId(it.id, memberId)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
override fun commentReplyCountByCommentId(commentId: Long): Int {
|
||||
override fun commentReplyCountByCommentId(commentId: Long, memberId: Long): Int {
|
||||
return queryFactory.select(creatorCommunityComment.id)
|
||||
.from(creatorCommunityComment)
|
||||
.where(
|
||||
creatorCommunityComment.isActive.isTrue
|
||||
.and(creatorCommunityComment.parent.isNotNull)
|
||||
.and(creatorCommunityComment.parent.id.eq(commentId))
|
||||
.and(creatorCommunityComment.member.id.notIn(blockedMemberIdSubQuery(memberId)))
|
||||
.and(creatorCommunityComment.member.id.notIn(blockingMemberIdSubQuery(memberId)))
|
||||
)
|
||||
.fetch()
|
||||
.size
|
||||
@@ -121,6 +128,8 @@ class CreatorCommunityCommentQueryRepositoryImpl(
|
||||
var where = creatorCommunityComment.creatorCommunity.id.eq(postId)
|
||||
.and(creatorCommunityComment.isActive.isTrue)
|
||||
.and(creatorCommunityComment.parent.isNull)
|
||||
.and(creatorCommunityComment.member.id.notIn(blockedMemberIdSubQuery(memberId)))
|
||||
.and(creatorCommunityComment.member.id.notIn(blockingMemberIdSubQuery(memberId)))
|
||||
|
||||
if (!isContentCreator) {
|
||||
where = where.and(
|
||||
@@ -138,6 +147,7 @@ class CreatorCommunityCommentQueryRepositoryImpl(
|
||||
|
||||
override fun getCommunityCommentReplyList(
|
||||
commentId: Long,
|
||||
memberId: Long,
|
||||
timezone: String,
|
||||
offset: Long,
|
||||
limit: Long
|
||||
@@ -172,6 +182,8 @@ class CreatorCommunityCommentQueryRepositoryImpl(
|
||||
creatorCommunityComment.isActive.isTrue
|
||||
.and(creatorCommunityComment.parent.isNotNull)
|
||||
.and(creatorCommunityComment.parent.id.eq(commentId))
|
||||
.and(creatorCommunityComment.member.id.notIn(blockedMemberIdSubQuery(memberId)))
|
||||
.and(creatorCommunityComment.member.id.notIn(blockingMemberIdSubQuery(memberId)))
|
||||
)
|
||||
.offset(offset)
|
||||
.limit(limit)
|
||||
@@ -181,4 +193,20 @@ class CreatorCommunityCommentQueryRepositoryImpl(
|
||||
it.copy(nickname = it.nickname.removeDeletedNicknamePrefix())
|
||||
}
|
||||
}
|
||||
|
||||
private fun blockedMemberIdSubQuery(memberId: Long) = JPAExpressions
|
||||
.select(blockMember.blockedMember.id)
|
||||
.from(blockMember)
|
||||
.where(
|
||||
blockMember.member.id.eq(memberId)
|
||||
.and(blockMember.isActive.isTrue)
|
||||
)
|
||||
|
||||
private fun blockingMemberIdSubQuery(memberId: Long) = JPAExpressions
|
||||
.select(blockMember.member.id)
|
||||
.from(blockMember)
|
||||
.where(
|
||||
blockMember.blockedMember.id.eq(memberId)
|
||||
.and(blockMember.isActive.isTrue)
|
||||
)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user