diff --git a/backend/src/main/java/net/pengcook/user/aop/BlockedUserFilterAspect.java b/backend/src/main/java/net/pengcook/user/aop/BlockedUserFilterAspect.java index b382e93f..eb5136e4 100644 --- a/backend/src/main/java/net/pengcook/user/aop/BlockedUserFilterAspect.java +++ b/backend/src/main/java/net/pengcook/user/aop/BlockedUserFilterAspect.java @@ -4,8 +4,10 @@ import java.util.Optional; import lombok.RequiredArgsConstructor; import net.pengcook.authentication.domain.UserInfo; +import net.pengcook.user.domain.BlockeeGroup; +import net.pengcook.user.domain.BlockerGroup; import net.pengcook.user.domain.Ownable; -import net.pengcook.user.domain.BlockedUserGroup; +import net.pengcook.user.exception.ForbiddenException; import net.pengcook.user.service.UserService; import org.aspectj.lang.ProceedingJoinPoint; import org.aspectj.lang.annotation.Around; @@ -35,9 +37,10 @@ public Object filterBlockedAuthorsFromList(ProceedingJoinPoint joinPoint) throws return ownables; } - BlockedUserGroup blockedUserGroup = userService.getBlockedUserGroup(userInfo.getId()); + BlockeeGroup blockeeGroup = userService.getBlockeeGroup(userInfo.getId()); + BlockerGroup blockerGroup = userService.getBlockerGroup(userInfo.getId()); - return filterBlockedUsers(ownables, blockedUserGroup); + return filterBlockedUsers(ownables, blockeeGroup, blockerGroup); } @Pointcut("execution(java.util.Optional net.pengcook..repository..*(..))") @@ -53,19 +56,24 @@ public Object filterBlockedAuthorFromOptional(ProceedingJoinPoint joinPoint) thr return ownableOptional; } - BlockedUserGroup blockedUserGroup = userService.getBlockedUserGroup(userInfo.getId()); - if (blockedUserGroup.isBlocked(ownableOptional.get().getOwnerId())) { - return Optional.empty(); + BlockeeGroup blockeeGroup = userService.getBlockeeGroup(userInfo.getId()); + if (blockeeGroup.contains(ownableOptional.get().getOwnerId())) { + throw new ForbiddenException("차단한 사용자입니다."); + } + + BlockerGroup blockerGroup = userService.getBlockerGroup(userInfo.getId()); + if (blockerGroup.contains(ownableOptional.get().getOwnerId())) { + throw new ForbiddenException("게시글을 이용할 수 없습니다."); } return ownableOptional; } @Pointcut("execution(net.pengcook.user.domain.Ownable+ net.pengcook..repository..*(..))") - public void repositoryMethodsReturningOwnable() { + public void repositoryMethodsReturningAuthorAble() { } - @Around("repositoryMethodsReturningOwnable()") + @Around("repositoryMethodsReturningAuthorAble()") public Object filterBlockedAuthor(ProceedingJoinPoint joinPoint) throws Throwable { Ownable ownable = (Ownable) joinPoint.proceed(); @@ -74,9 +82,14 @@ public Object filterBlockedAuthor(ProceedingJoinPoint joinPoint) throws Throwabl return ownable; } - BlockedUserGroup blockedUserGroup = userService.getBlockedUserGroup(userInfo.getId()); - if (blockedUserGroup.isBlocked(ownable.getOwnerId())) { - return null; + BlockeeGroup blockeeGroup = userService.getBlockeeGroup(userInfo.getId()); + if (blockeeGroup.contains(ownable.getOwnerId())) { + throw new ForbiddenException("차단한 사용자입니다."); + } + + BlockerGroup blockerGroup = userService.getBlockerGroup(userInfo.getId()); + if (blockerGroup.contains(ownable.getOwnerId())) { + throw new ForbiddenException("게시글을 이용할 수 없습니다."); } return ownable; @@ -91,9 +104,14 @@ private UserInfo getCurrentUserInfo() { } } - private List filterBlockedUsers(List ownables, BlockedUserGroup blockedUserGroup) { - return ownables.stream() - .filter(item -> !blockedUserGroup.isBlocked(item.getOwnerId())) + private List filterBlockedUsers( + List authorAbles, + BlockeeGroup blockeeGroup, + BlockerGroup blockerGroup + ) { + return authorAbles.stream() + .filter(item -> !blockeeGroup.contains(item.getOwnerId())) + .filter(item -> !blockerGroup.contains(item.getOwnerId())) .toList(); } } diff --git a/backend/src/main/java/net/pengcook/user/domain/BlockedUserGroup.java b/backend/src/main/java/net/pengcook/user/domain/BlockeeGroup.java similarity index 76% rename from backend/src/main/java/net/pengcook/user/domain/BlockedUserGroup.java rename to backend/src/main/java/net/pengcook/user/domain/BlockeeGroup.java index 14e9b23e..a7578e02 100644 --- a/backend/src/main/java/net/pengcook/user/domain/BlockedUserGroup.java +++ b/backend/src/main/java/net/pengcook/user/domain/BlockeeGroup.java @@ -4,11 +4,11 @@ import lombok.AllArgsConstructor; @AllArgsConstructor -public class BlockedUserGroup { +public class BlockeeGroup { private final Set users; - public boolean isBlocked(long userId) { + public boolean contains(long userId) { return users.stream() .anyMatch(user -> user.isSameUser(userId)); } diff --git a/backend/src/main/java/net/pengcook/user/domain/BlockerGroup.java b/backend/src/main/java/net/pengcook/user/domain/BlockerGroup.java new file mode 100644 index 00000000..4db43fed --- /dev/null +++ b/backend/src/main/java/net/pengcook/user/domain/BlockerGroup.java @@ -0,0 +1,15 @@ +package net.pengcook.user.domain; + +import java.util.Set; +import lombok.AllArgsConstructor; + +@AllArgsConstructor +public class BlockerGroup { + + private final Set users; + + public boolean contains(long userId) { + return users.stream() + .anyMatch(user -> user.isSameUser(userId)); + } +} diff --git a/backend/src/main/java/net/pengcook/user/exception/ForbiddenException.java b/backend/src/main/java/net/pengcook/user/exception/ForbiddenException.java new file mode 100644 index 00000000..977b2860 --- /dev/null +++ b/backend/src/main/java/net/pengcook/user/exception/ForbiddenException.java @@ -0,0 +1,9 @@ +package net.pengcook.user.exception; + +import org.springframework.http.HttpStatus; + +public class ForbiddenException extends UserException { + public ForbiddenException(String message) { + super(HttpStatus.FORBIDDEN, message); + } +} diff --git a/backend/src/main/java/net/pengcook/user/repository/UserBlockRepository.java b/backend/src/main/java/net/pengcook/user/repository/UserBlockRepository.java index 3c4970c0..f8a802d2 100644 --- a/backend/src/main/java/net/pengcook/user/repository/UserBlockRepository.java +++ b/backend/src/main/java/net/pengcook/user/repository/UserBlockRepository.java @@ -9,6 +9,8 @@ public interface UserBlockRepository extends JpaRepository { List findAllByBlockerId(long blockerId); + List findAllByBlockeeId(long blockeeId); + void deleteByBlockeeId(long blockeeId); void deleteByBlockerId(long blockerId); diff --git a/backend/src/main/java/net/pengcook/user/service/UserService.java b/backend/src/main/java/net/pengcook/user/service/UserService.java index c61a0c3d..4885892b 100644 --- a/backend/src/main/java/net/pengcook/user/service/UserService.java +++ b/backend/src/main/java/net/pengcook/user/service/UserService.java @@ -9,7 +9,8 @@ import net.pengcook.like.repository.RecipeLikeRepository; import net.pengcook.recipe.repository.RecipeRepository; import net.pengcook.recipe.service.RecipeService; -import net.pengcook.user.domain.BlockedUserGroup; +import net.pengcook.user.domain.BlockeeGroup; +import net.pengcook.user.domain.BlockerGroup; import net.pengcook.user.domain.User; import net.pengcook.user.domain.UserBlock; import net.pengcook.user.domain.UserReport; @@ -109,11 +110,19 @@ public ReportResponse report(long reporterId, ReportRequest reportRequest) { } @Transactional(readOnly = true) - public BlockedUserGroup getBlockedUserGroup(long blockerId) { + public BlockeeGroup getBlockeeGroup(long blockerId) { return userBlockRepository.findAllByBlockerId(blockerId).stream() .map(UserBlock::getBlockee) - .collect(Collectors.collectingAndThen(Collectors.toSet(), BlockedUserGroup::new)); + .collect(Collectors.collectingAndThen(Collectors.toSet(), BlockeeGroup::new)); + } + + @Transactional(readOnly = true) + public BlockerGroup getBlockerGroup(long blockeeId) { + + return userBlockRepository.findAllByBlockeeId(blockeeId).stream() + .map(UserBlock::getBlocker) + .collect(Collectors.collectingAndThen(Collectors.toSet(), BlockerGroup::new)); } @Transactional diff --git a/backend/src/test/java/net/pengcook/user/domain/BlockedUserGroupTest.java b/backend/src/test/java/net/pengcook/user/domain/BlockeeGroupTest.java similarity index 62% rename from backend/src/test/java/net/pengcook/user/domain/BlockedUserGroupTest.java rename to backend/src/test/java/net/pengcook/user/domain/BlockeeGroupTest.java index ce86a53c..8db15bf5 100644 --- a/backend/src/test/java/net/pengcook/user/domain/BlockedUserGroupTest.java +++ b/backend/src/test/java/net/pengcook/user/domain/BlockeeGroupTest.java @@ -6,18 +6,18 @@ import java.util.Set; import org.junit.jupiter.api.Test; -class BlockedUserGroupTest { +class BlockeeGroupTest { @Test void isBlocked() { User loki = new User(1L, "loki@pengcook.net", "loki", "로키", "loki.jpg", "KOREA"); User pond = new User(2L, "pond@pengcook.net", "pond", "폰드", "pond.jpg", "KOREA"); - BlockedUserGroup blockedUserGroup = new BlockedUserGroup(Set.of(pond)); + BlockeeGroup blockeeGroup = new BlockeeGroup(Set.of(pond)); assertAll( - () -> assertThat(blockedUserGroup.isBlocked(loki.getId())).isFalse(), - () -> assertThat(blockedUserGroup.isBlocked(pond.getId())).isTrue() + () -> assertThat(blockeeGroup.contains(loki.getId())).isFalse(), + () -> assertThat(blockeeGroup.contains(pond.getId())).isTrue() ); } } diff --git a/backend/src/test/java/net/pengcook/user/service/UserServiceTest.java b/backend/src/test/java/net/pengcook/user/service/UserServiceTest.java index 5c7a6c38..87f0f7b7 100644 --- a/backend/src/test/java/net/pengcook/user/service/UserServiceTest.java +++ b/backend/src/test/java/net/pengcook/user/service/UserServiceTest.java @@ -9,7 +9,7 @@ import net.pengcook.image.service.ImageClientService; import net.pengcook.like.repository.RecipeLikeRepository; import net.pengcook.recipe.repository.RecipeRepository; -import net.pengcook.user.domain.BlockedUserGroup; +import net.pengcook.user.domain.BlockeeGroup; import net.pengcook.user.domain.Reason; import net.pengcook.user.domain.Type; import net.pengcook.user.domain.UserReport; @@ -192,15 +192,15 @@ void blockUserWhenNotExistBlockee() { @Test @DisplayName("차단한 사용자들의 목록을 불러올 수 있다.") - void getBlockedUserGroup() { + void getBlockeeGroup() { long blockerId = 1L; - BlockedUserGroup blockedUserGroup = userService.getBlockedUserGroup(blockerId); + BlockeeGroup blockeeGroup = userService.getBlockeeGroup(blockerId); assertAll( - () -> assertThat(blockedUserGroup.isBlocked(2L)).isTrue(), - () -> assertThat(blockedUserGroup.isBlocked(3L)).isTrue(), - () -> assertThat(blockedUserGroup.isBlocked(4L)).isFalse() + () -> assertThat(blockeeGroup.contains(2L)).isTrue(), + () -> assertThat(blockeeGroup.contains(3L)).isTrue(), + () -> assertThat(blockeeGroup.contains(4L)).isFalse() ); }