Skip to content

Commit

Permalink
Merge pull request #284 from minisundev/feat/chatroom-unsubscribe
Browse files Browse the repository at this point in the history
[Chat] 채팅방에 Event가 일어났을 때 해당 채팅방을 구독하는 사용자들에게 보내기
  • Loading branch information
minisundev authored Nov 10, 2024
2 parents 5e3a21e + 4b01179 commit f913714
Show file tree
Hide file tree
Showing 2 changed files with 39 additions and 25 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ class ChatController(
private val authClient: AuthClient,
private val serverClient: ServerClient,
) {
@Deprecated("WebSocketChatController를 대신 사용")
@PostMapping("/chat")
fun createChat(
@Validated @RequestBody request: CreateChatRequest,
Expand All @@ -43,6 +44,7 @@ class ChatController(
return ResponseEntity(ApiResponse<Nothing>(status = 201), HttpStatus.CREATED)
}

@Deprecated("WebSocketChatController를 대신 사용")
@GetMapping("/chat")
fun getChats(
@RequestParam("type") type: ChatType,
Expand All @@ -69,6 +71,7 @@ class ChatController(
return ResponseEntity.ok().body(ApiResponse(data = result, status = 200))
}

@Deprecated("WebSocketChatController를 대신 사용")
@PatchMapping("/chat")
fun updateChat(
@Validated @RequestBody request: UpdateChatRequest,
Expand All @@ -79,6 +82,7 @@ class ChatController(
return ResponseEntity.ok().body(ApiResponse<Nothing>(status = 200))
}

@Deprecated("WebSocketChatController를 대신 사용")
@DeleteMapping("/chat/{chatId}")
fun deleteChat(
@PathVariable("chatId") chatId: String,
Expand Down
60 changes: 35 additions & 25 deletions chat/src/main/kotlin/kpring/chat/global/config/WebSocketConfig.kt
Original file line number Diff line number Diff line change
Expand Up @@ -59,15 +59,16 @@ class WebSocketConfig(
): Message<*> {
val simpMessageType = SimpMessageHeaderAccessor.getMessageType(message.headers)
return when (simpMessageType) {
SimpMessageType.CONNECT -> handleConnectMessage(message)
SimpMessageType.SUBSCRIBE -> handleSubscribeMessage(message)
SimpMessageType.CONNECT -> authenticateAndSetPrincipal(message)
SimpMessageType.SUBSCRIBE -> verifyAccess(message)
SimpMessageType.MESSAGE -> verifyAccess(message)
else -> message
}
}
}
}

private fun handleConnectMessage(message: Message<*>): Message<*> {
private fun authenticateAndSetPrincipal(message: Message<*>): Message<*> {
val headerAccessor = SimpMessageHeaderAccessor.wrap(message)
val token =
headerAccessor.getFirstNativeHeader("Authorization")
Expand All @@ -84,31 +85,25 @@ class WebSocketConfig(
return message
}

private fun handleSubscribeMessage(message: Message<*>): Message<*> {
private fun verifyAccess(message: Message<*>): Message<*> {
val headerAccessor = SimpMessageHeaderAccessor.wrap(message)
val token = getTokenFromHeader(headerAccessor)
val contextId = getContextIdFromHeader(headerAccessor)
val type = ChatType.valueOf(getContext(headerAccessor))
verifyAccessByType(type, token, contextId)
return message
}

val token =
headerAccessor.getFirstNativeHeader("Authorization")
?.removePrefix("Bearer ")
?: throw GlobalException(ErrorCode.MISSING_TOKEN)

val contextId =
headerAccessor.getFirstNativeHeader("ContextId")
?: throw GlobalException(ErrorCode.MISSING_CONTEXTID)

val context =
headerAccessor.getFirstNativeHeader("Context")
?: throw GlobalException(ErrorCode.MISSING_CONTEXT)

val type =
ChatType.valueOf(context)

val userId =
authClient.getTokenInfo(token).data?.userId
?: throw GlobalException(ErrorCode.INVALID_TOKEN)

private fun verifyAccessByType(
type: ChatType,
token: String,
contextId: String,
) {
when (type) {
ChatType.ROOM -> {
val userId =
authClient.getTokenInfo(token).data?.userId
?: throw GlobalException(ErrorCode.INVALID_TOKEN)
accessVerifier.verifyChatRoomAccess(contextId, userId)
}
ChatType.SERVER -> {
Expand All @@ -119,7 +114,22 @@ class WebSocketConfig(
}
else -> throw GlobalException(ErrorCode.INVALID_CONTEXT)
}
return message
}

private fun getTokenFromHeader(headerAccessor: SimpMessageHeaderAccessor): String {
return headerAccessor.getFirstNativeHeader("Authorization")
?.removePrefix("Bearer ")
?: throw GlobalException(ErrorCode.MISSING_TOKEN)
}

private fun getContextIdFromHeader(headerAccessor: SimpMessageHeaderAccessor): String {
return headerAccessor.getFirstNativeHeader("ContextId")
?: throw GlobalException(ErrorCode.MISSING_CONTEXTID)
}

private fun getContext(headerAccessor: SimpMessageHeaderAccessor): String {
return headerAccessor.getFirstNativeHeader("Context")
?: throw GlobalException(ErrorCode.MISSING_CONTEXT)
}

override fun configureClientInboundChannel(registration: ChannelRegistration) {
Expand Down

0 comments on commit f913714

Please sign in to comment.