Skip to content

Commit

Permalink
[bug] 채팅 메시지 목록 조회시 제 3자가 읽을 수 없도록 검증문 추가 (#156)
Browse files Browse the repository at this point in the history
* #153 fix: 채팅창 목록 조회 문제 해결

- 채팅창만이 존재하고 채팅 로그가 없는 경우가 원인이었습니다.

* #153 fix: nextMessageId가 응답되도록 수정

* #153 fix: 필드멤버 명 변경

* #153 fix: 오타 수정

* #153 fix: 채팅 메시지 목록 조회시 새로운 메시지가 없는 경우 408 -> 200으로 변경

* #153 feat; 채팅방에 없는 회원이 채팅 메시지 목록 조회 요청시 인가 오류 구현

* #153 feat; equalItemId 조건절 별도의 메소드로 구현
  • Loading branch information
yonghwankim-dev authored Oct 5, 2023
1 parent 9c4d16c commit 52b662a
Show file tree
Hide file tree
Showing 5 changed files with 66 additions and 1 deletion.
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
import codesquard.app.api.chat.response.ChatLogMessageResponse;
import codesquard.app.api.chat.response.ChatLogSendResponse;
import codesquard.app.api.errors.errorcode.ErrorCode;
import codesquard.app.api.errors.exception.ForBiddenException;
import codesquard.app.api.errors.exception.NotFoundResourceException;
import codesquard.app.domain.chat.ChatLog;
import codesquard.app.domain.chat.ChatLogPaginationRepository;
Expand Down Expand Up @@ -51,6 +52,10 @@ public ChatLogListResponse readMessages(Long chatRoomId, Principal principal, Lo
ChatRoom chatRoom = findChatRoomBy(chatRoomId);
Item item = findItemBy(chatRoom);

if (!principal.isSeller(chatRoom.getSeller()) && !principal.isBuyer(chatRoom.getBuyer())) {
throw new ForBiddenException(ErrorCode.FORBIDDEN_CHAT_LOG);
}

String chatPartnerName = principal.getChatPartnerName(item, chatRoom);
BooleanBuilder whereBuilder = new BooleanBuilder();
whereBuilder.orAllOf(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -144,7 +144,7 @@ public ChatRoomListResponse readAllChatRoomByItem(Long itemId, Principal princip

Item item = findItemBy(itemId);
BooleanBuilder whereBuilder = new BooleanBuilder();
whereBuilder.andAnyOf(QChatRoom.chatRoom.item.eq(item));
whereBuilder.andAnyOf(chatRoomRepository.equalItemId(item.getId()));

Slice<ChatRoom> slice = chatRoomPaginationRepository.searchBySlice(whereBuilder, pageable);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@ public enum ErrorCode {

// ChatLog
NOT_FOUND_CHAT_LOG(HttpStatus.NOT_FOUND, "채팅이 존재하지 않습니다."),
FORBIDDEN_CHAT_LOG(HttpStatus.FORBIDDEN, "채팅에 대한 권한이 없습니다."),

// ChatRoom
NOT_FOUND_CHATROOM(HttpStatus.NOT_FOUND, "채팅방을 찾을 수 없습니다.");
Expand Down
Original file line number Diff line number Diff line change
@@ -1,13 +1,25 @@
package codesquard.app.domain.chat;

import static codesquard.app.domain.chat.QChatRoom.*;

import java.util.Optional;

import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.query.Param;

import com.querydsl.core.types.dsl.BooleanExpression;

public interface ChatRoomRepository extends JpaRepository<ChatRoom, Long> {

default BooleanExpression equalItemId(Long itemId) {
if (itemId == null) {
return null;
}

return chatRoom.item.id.eq(itemId);
}

int deleteByItemId(Long itemId);

@Query("select chatRoom.id from ChatRoom chatRoom where chatRoom.item.id = :itemId and chatRoom.buyer.id = :memberId")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
import codesquard.app.api.chat.request.ChatLogSendRequest;
import codesquard.app.api.chat.response.ChatLogListResponse;
import codesquard.app.api.chat.response.ChatLogSendResponse;
import codesquard.app.api.errors.exception.ForBiddenException;
import codesquard.app.domain.category.Category;
import codesquard.app.domain.category.CategoryRepository;
import codesquard.app.domain.chat.ChatLog;
Expand Down Expand Up @@ -176,4 +177,50 @@ public void readMessage() {
);
}

@DisplayName("구매자와 판매자가 아닌 제 3자가 채팅방의 채팅 메시지를 읽을 수 없다.")
@Test
public void readMessageWithOtherMember() {
// given
Member seller = memberRepository.save(createMember("avatarUrlValue1", "[email protected]", "23Yong"));
Member buyer = memberRepository.save(createMember("avatarUrlValue2", "[email protected]", "bruni"));
Member anonymous = memberRepository.save(createMember("avatarUrlValue3", "[email protected]", "lee1234"));

Region region = regionRepository.save(RegionTestSupport.createRegion("서울 종로구 청운동"));

memberTownRepository.saveAll(List.of(
createMemberTown(seller, region, true),
createMemberTown(buyer, region, true)));

Category sport = categoryRepository.save(findByName("스포츠/레저"));
Item item = createItem("빈티지 롤러 블레이드", "어린시절 추억의향수를 불러 일으키는 롤러 스케이트입니다.", 200000L, ON_SALE,
"가락동", "thumbnailUrl", seller, sport);

Item saveItem = itemRepository.save(item);
List<Image> images = List.of(
new Image("imageUrlValue1", saveItem, true),
new Image("imageUrlValue2", saveItem, false));
imageRepository.saveAll(images);

ChatRoom chatRoom = chatRoomRepository.save(new ChatRoom(buyer, item));

chatLogRepository.saveAll(List.of(
ChatLog.createBySender("롤러 블레이드 사고 싶음", chatRoom, Principal.from(buyer)),
ChatLog.createBySender("깍아주세요.", chatRoom, Principal.from(buyer))
));

Long cursor = null;
Pageable pageable = Pageable.ofSize(10);

// when
Throwable throwable = catchThrowable(
() -> chatLogService.readMessages(chatRoom.getId(), Principal.from(anonymous), cursor,
pageable));

// then
assertThat(throwable)
.isInstanceOf(ForBiddenException.class)
.extracting("errorCode.message")
.isEqualTo("채팅에 대한 권한이 없습니다.");
}

}

0 comments on commit 52b662a

Please sign in to comment.