Skip to content
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 @@ -63,12 +63,15 @@ public enum ErrorCode implements ResponseCode {
*/
INVALID_SEARCH_TYPE(HttpStatus.BAD_REQUEST, 900000,"알맞은 검색어 타입을 찾을 수 없습니다."),


/**
* 100000 : room error
*/
ROOM_NOT_FOUND(HttpStatus.NOT_FOUND, 100000, "존재하지 않는 ROOM 입니다."),
INVALID_ROOM_CREATE(HttpStatus.BAD_REQUEST, 100001, "유효하지 않은 ROOM 생성 요청 입니다."),

ROOM_PASSWORD_MISMATCH(HttpStatus.BAD_REQUEST, 100002, "비밀번호가 일치하지 않습니다."),
ROOM_PASSWORD_NOT_REQUIRED(HttpStatus.BAD_REQUEST, 100003, "공개방은 비밀번호가 필요하지 않습니다."),
ROOM_RECRUITMENT_PERIOD_EXPIRED(HttpStatus.BAD_REQUEST, 100004, "모집기간이 만료된 방입니다."),
/**
* 110000 : vote error
*/
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,24 @@
package konkuk.thip.room.adapter.in.web;

import jakarta.validation.Valid;
import konkuk.thip.common.dto.BaseResponse;
import konkuk.thip.room.adapter.in.web.request.RoomVerifyPasswordRequest;
import konkuk.thip.room.application.port.in.RoomVerifyPasswordUseCase;
import lombok.RequiredArgsConstructor;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.bind.annotation.*;

@RestController
@RequiredArgsConstructor
public class RoomQueryController {

private final RoomVerifyPasswordUseCase roomVerifyPasswordUseCase;

//비공개 방 비밀번호 입력 검증
@PostMapping("/rooms/{roomId}/password")
public BaseResponse<Void> verifyRoomPassword(@PathVariable("roomId") final Long roomId,
@Valid @RequestBody final RoomVerifyPasswordRequest roomVerifyPasswordRequest
) {
return BaseResponse.ok(roomVerifyPasswordUseCase.verifyRoomPassword(roomVerifyPasswordRequest.toQuery(roomId)));
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package konkuk.thip.room.adapter.in.web.request;

import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.Pattern;
import konkuk.thip.room.application.port.in.dto.RoomVerifyPasswordQuery;

public record RoomVerifyPasswordRequest(

@NotBlank(message = "비밀번호는 필수입니다.")
@Pattern(regexp = "\\d{4}", message = "비밀번호는 숫자 4자리여야 합니다.")
String password
) {
public RoomVerifyPasswordQuery toQuery(Long roomId) {
return new RoomVerifyPasswordQuery(
roomId,
password);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,6 @@ public class RoomJpaEntity extends BaseJpaEntity {
@Column(name = "is_public", nullable = false)
private boolean isPublic;

@Column(length = 4)
private String password;

@Builder.Default
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package konkuk.thip.room.application.port.in;

import konkuk.thip.room.application.port.in.dto.RoomVerifyPasswordQuery;

public interface RoomVerifyPasswordUseCase {
Void verifyRoomPassword(RoomVerifyPasswordQuery query);
}

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package konkuk.thip.room.application.port.in.dto;

public record RoomVerifyPasswordQuery(
Long roomId,
String password
) {
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
package konkuk.thip.room.application.service;

import konkuk.thip.room.application.port.in.RoomVerifyPasswordUseCase;
import konkuk.thip.room.application.port.in.dto.RoomVerifyPasswordQuery;
import konkuk.thip.room.application.port.out.RoomCommandPort;
import konkuk.thip.room.domain.Room;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

@Service
@RequiredArgsConstructor
@Transactional(readOnly = true)
public class RoomVerifyPasswordService implements RoomVerifyPasswordUseCase {

private final RoomCommandPort roomCommandPort;

@Override
public Void verifyRoomPassword(RoomVerifyPasswordQuery query) {

//방 검증
Room room = roomCommandPort.findById(query.roomId());

//도메인에서 비밀번호 검증 로직 수행
room.verifyPassword(query.password());
return null;
}
}
33 changes: 32 additions & 1 deletion src/main/java/konkuk/thip/room/domain/Room.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,16 @@
import konkuk.thip.common.entity.BaseDomainEntity;
import konkuk.thip.common.exception.InvalidStateException;
import konkuk.thip.common.entity.StatusType;
import konkuk.thip.common.exception.BusinessException;
import konkuk.thip.common.exception.code.ErrorCode;
import lombok.Getter;
import lombok.experimental.SuperBuilder;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;

import java.time.LocalDate;

import static konkuk.thip.common.exception.code.ErrorCode.INVALID_ROOM_CREATE;
import static konkuk.thip.common.exception.code.ErrorCode.*;

@Getter
@SuperBuilder
Expand Down Expand Up @@ -111,4 +113,33 @@ public boolean matchesPassword(String rawPassword) {
}
return PASSWORD_ENCODER.matches(rawPassword, this.hashedPassword);
}

public void verifyPassword(String rawPassword) {

// 모집기간 만료 체크
LocalDate deadline = this.startDate.minusDays(1);
if (isRecruitmentPeriodExpired()) {
String message = String.format("모집기간(%s까지)이 만료된 방에는 참여할 수 없습니다.", deadline);
throw new BusinessException(
ErrorCode.ROOM_RECRUITMENT_PERIOD_EXPIRED, new IllegalArgumentException(message)
);
}

// 공개방일 경우 비밀번호 입력 요청 예외 처리
if (this.isPublic()) {
throw new BusinessException(ROOM_PASSWORD_NOT_REQUIRED);
}

//비밀번호 검증
if (!matchesPassword(rawPassword)) {
throw new BusinessException(ROOM_PASSWORD_MISMATCH);
}
}

public boolean isRecruitmentPeriodExpired() {
LocalDate today = LocalDate.now();
// 모집 마감일: startDate.minusDays(1)
return today.isAfter(this.startDate.minusDays(1));
}

}
Loading