Skip to content
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

Ignore: ✨ Ban Chat Member API #217

Merged
merged 7 commits into from
Jan 11, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -73,4 +73,16 @@ ResponseEntity<?> joinChatRoom(
)
@ApiResponse(responseCode = "200", description = "채팅방 멤버 탈퇴 성공")
ResponseEntity<?> leaveChatRoom(@PathVariable("chatRoomId") Long chatRoomId, @PathVariable("chatMemberId") Long chatMemberId);

@Operation(summary = "채팅방 멤버 추방", method = "DELETE", description = "채팅방 멤버를 추방한다. 채팅방장만이 채팅방 멤버를 추방할 수 있다.")
@Parameters({
@Parameter(name = "chatRoomId", description = "채팅방 ID", required = true, in = ParameterIn.PATH),
@Parameter(name = "chatMemberId", description = "추방할 채팅방 멤버 ID (user id가 아님)", required = true, in = ParameterIn.PATH)
})
@ApiResponseExplanations(errors = {
@ApiExceptionExplanation(value = ChatMemberErrorCode.class, constant = "NOT_FOUND", summary = "채팅방 멤버를 찾을 수 없음", description = "채팅방 멤버를 찾을 수 없어 채팅방 멤버 추방에 실패했습니다."),
@ApiExceptionExplanation(value = ChatMemberErrorCode.class, constant = "NOT_ADMIN", summary = "권한 없음", description = "권한이 없어 채팅방 멤버 추방에 실패했습니다.")
})
@ApiResponse(responseCode = "200", description = "채팅방 멤버 추방 성공")
ResponseEntity<?> banChatMember(@PathVariable("chatRoomId") Long chatRoomId, @PathVariable("chatMemberId") Long chatMemberId, @AuthenticationPrincipal SecurityUserDetails user);
}
Original file line number Diff line number Diff line change
Expand Up @@ -61,4 +61,13 @@ public ResponseEntity<?> leaveChatRoom(@PathVariable("chatRoomId") Long chatRoom

return ResponseEntity.ok(SuccessResponse.noContent());
}

@Override
@DeleteMapping("/{chatMemberId}/ban")
@PreAuthorize("isAuthenticated() and @chatRoomManager.hasPermission(principal.userId, #chatRoomId)")
public ResponseEntity<?> banChatMember(@PathVariable("chatRoomId") Long chatRoomId, @PathVariable("chatMemberId") Long chatMemberId, @AuthenticationPrincipal SecurityUserDetails user) {
chatMemberUseCase.banChatMember(user.getUserId(), chatMemberId, chatRoomId);

return ResponseEntity.ok(SuccessResponse.noContent());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@
import kr.co.pennyway.api.apis.chat.service.ChatMemberJoinService;
import kr.co.pennyway.api.apis.chat.service.ChatMemberSearchService;
import kr.co.pennyway.common.annotation.UseCase;
import kr.co.pennyway.domain.context.chat.dto.ChatMemberBanCommand;
import kr.co.pennyway.domain.context.chat.service.ChatMemberBanService;
import kr.co.pennyway.domain.context.chat.service.ChatRoomLeaveService;
import kr.co.pennyway.domain.domains.chatroom.domain.ChatRoom;
import kr.co.pennyway.domain.domains.member.dto.ChatMemberResult;
Expand All @@ -24,6 +26,7 @@ public class ChatMemberUseCase {
private final ChatMemberJoinService chatMemberJoinService;
private final ChatMemberSearchService chatMemberSearchService;
private final ChatRoomLeaveService chatRoomLeaveService;
private final ChatMemberBanService chatMemberBanService;

public ChatRoomRes.Detail joinChatRoom(Long userId, Long chatRoomId, Integer password) {
Triple<ChatRoom, Integer, Long> chatRoom = chatMemberJoinService.execute(userId, chatRoomId, password);
Expand All @@ -40,4 +43,8 @@ public List<ChatMemberRes.MemberDetail> readChatMembers(Long chatRoomId, Set<Lon
public void leaveChatRoom(Long chatMemberId) {
chatRoomLeaveService.execute(chatMemberId);
}

public void banChatMember(Long userId, Long targetMemberId, Long chatRoomId) {
chatMemberBanService.execute(ChatMemberBanCommand.of(userId, targetMemberId, chatRoomId));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
public enum ChatMemberErrorCode implements BaseErrorCode {
/* 403 FORBIDDEN */
BANNED(StatusCode.FORBIDDEN, ReasonCode.ACCESS_TO_THE_REQUESTED_RESOURCE_IS_FORBIDDEN, "차단된 회원입니다."),
NOT_ADMIN(StatusCode.FORBIDDEN, ReasonCode.ACCESS_TO_RESOURCE_NOT_ALLOWED_FOR_USER_ROLE, "관리자가 아닙니다."),

/* 404 NOT FOUND */
NOT_FOUND(StatusCode.NOT_FOUND, ReasonCode.REQUESTED_RESOURCE_NOT_FOUND, "회원을 찾을 수 없습니다."),
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
package kr.co.pennyway.domain.context.chat.dto;

public record ChatMemberBanCommand(
Long userId,
Long targetMemberId,
Long chatRoomId
) {
public ChatMemberBanCommand {
if (userId == null) {
throw new IllegalArgumentException("userId must not be null");
}
if (targetMemberId == null) {
throw new IllegalArgumentException("targetMemberId must not be null");
}
if (chatRoomId == null) {
throw new IllegalArgumentException("chatRoomId must not be null");
}
}

public static ChatMemberBanCommand of(Long adminId, Long targetMemberId, Long chatRoomId) {
return new ChatMemberBanCommand(adminId, targetMemberId, chatRoomId);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
package kr.co.pennyway.domain.context.chat.service;

import kr.co.pennyway.common.annotation.DomainService;
import kr.co.pennyway.domain.context.chat.dto.ChatMemberBanCommand;
import kr.co.pennyway.domain.domains.member.domain.ChatMember;
import kr.co.pennyway.domain.domains.member.exception.ChatMemberErrorCode;
import kr.co.pennyway.domain.domains.member.exception.ChatMemberErrorException;
import kr.co.pennyway.domain.domains.member.service.ChatMemberRdbService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.transaction.annotation.Transactional;

@Slf4j
@DomainService
@RequiredArgsConstructor
public class ChatMemberBanService {

private final ChatMemberRdbService chatMemberRdbService;

@Transactional
public void execute(ChatMemberBanCommand command) {
ChatMember admin = chatMemberRdbService.readChatMember(command.userId(), command.chatRoomId())
.orElseThrow(() -> new ChatMemberErrorException(ChatMemberErrorCode.NOT_FOUND));

if (!admin.isAdmin()) {
throw new ChatMemberErrorException(ChatMemberErrorCode.NOT_ADMIN);
}

ChatMember targetMember = chatMemberRdbService.readChatMemberByChatMemberId(command.targetMemberId())
.orElseThrow(() -> new ChatMemberErrorException(ChatMemberErrorCode.NOT_FOUND));

targetMember.ban();

chatMemberRdbService.update(targetMember);
}
}
Loading