-
Notifications
You must be signed in to change notification settings - Fork 0
[FIX] 채팅방이 없으면 생성 후 시스템 메시지 전송 #388
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -1,7 +1,5 @@ | ||||||||||||||||||||||||
| package com.example.RealMatch.chat.application.event.proposal; | ||||||||||||||||||||||||
|
|
||||||||||||||||||||||||
| import java.util.Optional; | ||||||||||||||||||||||||
|
|
||||||||||||||||||||||||
| import org.slf4j.Logger; | ||||||||||||||||||||||||
| import org.slf4j.LoggerFactory; | ||||||||||||||||||||||||
| import org.springframework.context.ApplicationEventPublisher; | ||||||||||||||||||||||||
|
|
@@ -12,7 +10,7 @@ | |||||||||||||||||||||||
| import com.example.RealMatch.business.application.event.CampaignProposalSentEvent; | ||||||||||||||||||||||||
| import com.example.RealMatch.business.domain.enums.ProposalDirection; | ||||||||||||||||||||||||
| import com.example.RealMatch.business.domain.enums.ProposalStatus; | ||||||||||||||||||||||||
| import com.example.RealMatch.chat.application.service.room.ChatRoomQueryService; | ||||||||||||||||||||||||
| import com.example.RealMatch.chat.application.service.room.ChatRoomCommandService; | ||||||||||||||||||||||||
| import com.example.RealMatch.chat.domain.enums.ChatProposalDirection; | ||||||||||||||||||||||||
| import com.example.RealMatch.chat.presentation.dto.enums.ChatProposalDecisionStatus; | ||||||||||||||||||||||||
| import com.example.RealMatch.chat.presentation.dto.response.ChatProposalCardPayloadResponse; | ||||||||||||||||||||||||
|
|
@@ -29,7 +27,7 @@ public class CampaignProposalSentEventListener { | |||||||||||||||||||||||
|
|
||||||||||||||||||||||||
| private static final Logger LOG = LoggerFactory.getLogger(CampaignProposalSentEventListener.class); | ||||||||||||||||||||||||
|
|
||||||||||||||||||||||||
| private final ChatRoomQueryService chatRoomQueryService; | ||||||||||||||||||||||||
| private final ChatRoomCommandService chatRoomCommandService; | ||||||||||||||||||||||||
| private final ApplicationEventPublisher eventPublisher; | ||||||||||||||||||||||||
|
|
||||||||||||||||||||||||
| @TransactionalEventListener(phase = TransactionPhase.AFTER_COMMIT) | ||||||||||||||||||||||||
|
|
@@ -42,16 +40,8 @@ public void handleCampaignProposalSent(CampaignProposalSentEvent event) { | |||||||||||||||||||||||
| LOG.info("[ProposalBoundary] Received business event. proposalId={}, isReProposal={}", | ||||||||||||||||||||||||
| event.proposalId(), event.isReProposal()); | ||||||||||||||||||||||||
|
|
||||||||||||||||||||||||
| Optional<Long> roomIdOpt = chatRoomQueryService.getRoomIdByUserPair( | ||||||||||||||||||||||||
| event.brandUserId(), event.creatorUserId()); | ||||||||||||||||||||||||
|
|
||||||||||||||||||||||||
| if (roomIdOpt.isEmpty()) { | ||||||||||||||||||||||||
| LOG.debug("[ProposalBoundary] Chat room not found. brandUserId={}, creatorUserId={}", | ||||||||||||||||||||||||
| event.brandUserId(), event.creatorUserId()); | ||||||||||||||||||||||||
| return; | ||||||||||||||||||||||||
| } | ||||||||||||||||||||||||
|
|
||||||||||||||||||||||||
| Long roomId = roomIdOpt.get(); | ||||||||||||||||||||||||
| // 채팅방이 없으면 생성 | ||||||||||||||||||||||||
| Long roomId = ensureRoomAndGetId(event.brandUserId(), event.creatorUserId()); | ||||||||||||||||||||||||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||||||||||||||||||||
| ChatProposalCardPayloadResponse payload = createPayload(event); | ||||||||||||||||||||||||
| String eventId = ProposalSentEvent.generateEventId(event.proposalId(), event.isReProposal()); | ||||||||||||||||||||||||
|
|
||||||||||||||||||||||||
|
|
@@ -88,6 +78,16 @@ private ChatProposalDecisionStatus toChatDecisionStatus(ProposalStatus proposalS | |||||||||||||||||||||||
| }; | ||||||||||||||||||||||||
| } | ||||||||||||||||||||||||
|
|
||||||||||||||||||||||||
| /** | ||||||||||||||||||||||||
| * 채팅방이 없으면 생성하고, roomId를 반환합니다. | ||||||||||||||||||||||||
| * 이 리스너는 AFTER_COMMIT 컨텍스트에서 실행되므로 createOrGetRoom이 별도 트랜잭션으로 처리됩니다. | ||||||||||||||||||||||||
| */ | ||||||||||||||||||||||||
| private Long ensureRoomAndGetId(Long brandUserId, Long creatorUserId) { | ||||||||||||||||||||||||
| return chatRoomCommandService | ||||||||||||||||||||||||
| .createOrGetRoom(brandUserId, brandUserId, creatorUserId) | ||||||||||||||||||||||||
| .roomId(); | ||||||||||||||||||||||||
| } | ||||||||||||||||||||||||
|
Comment on lines
+85
to
+89
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This
Suggested change
|
||||||||||||||||||||||||
|
|
||||||||||||||||||||||||
| private ChatProposalDirection toChatProposalDirection(ProposalDirection direction) { | ||||||||||||||||||||||||
| if (direction == null) { | ||||||||||||||||||||||||
| return ChatProposalDirection.NONE; | ||||||||||||||||||||||||
|
|
||||||||||||||||||||||||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This
ensureRoomAndGetIdmethod has a logical flaw leading to a Broken Access Control vulnerability. It incorrectly passesbrandUserIdas the actor's ID tocreateOrGetRoom. In the context of aCampaignApplySentEvent, thecreatorUserIdis the actual actor, meaning authorization checks are performed against the wrong user identity. This should be corrected to passcreatorUserIdas the actor.