diff --git a/src/backend/Eyesee/src/main/java/com/fortune/eyesee/config/SecurityConfig.java b/src/backend/Eyesee/src/main/java/com/fortune/eyesee/config/SecurityConfig.java index 5e09e2a..314ba85 100644 --- a/src/backend/Eyesee/src/main/java/com/fortune/eyesee/config/SecurityConfig.java +++ b/src/backend/Eyesee/src/main/java/com/fortune/eyesee/config/SecurityConfig.java @@ -6,6 +6,11 @@ import org.springframework.security.web.SecurityFilterChain; import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; import org.springframework.security.crypto.password.PasswordEncoder; +import org.springframework.web.cors.CorsConfiguration; +import org.springframework.web.cors.CorsConfigurationSource; +import org.springframework.web.cors.UrlBasedCorsConfigurationSource; + +import java.util.List; @Configuration public class SecurityConfig { @@ -13,7 +18,8 @@ public class SecurityConfig { @Bean public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception { http - .csrf(csrf -> csrf.disable()) // CSRF 비활성화 (필요시 활성화 가능) + .cors(cors -> cors.configurationSource(corsConfigurationSource())) // CORS 설정 추가 + .csrf(csrf -> csrf.disable()) // CSRF 비활성화 (필요시 활성화 가능) .authorizeHttpRequests(auth -> auth .requestMatchers("/api/admin/signup", "/api/admin/login").permitAll() // 회원가입, 로그인은 인증 필요 없음 .anyRequest().permitAll() // 나머지 요청도 인증 필요 없음 @@ -23,8 +29,21 @@ public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Excepti return http.build(); } + @Bean + public CorsConfigurationSource corsConfigurationSource() { + CorsConfiguration configuration = new CorsConfiguration(); + configuration.setAllowedOrigins(List.of("http://example.com", "http://localhost:3000")); // 허용할 도메인 설정 + configuration.setAllowedMethods(List.of("GET", "POST", "PUT", "DELETE", "OPTIONS")); // 허용할 HTTP 메서드 + configuration.setAllowedHeaders(List.of("*")); // 모든 헤더 허용 + configuration.setAllowCredentials(true); // 인증 정보 포함 여부 + + UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource(); + source.registerCorsConfiguration("/**", configuration); + return source; + } + @Bean public PasswordEncoder passwordEncoder() { return new BCryptPasswordEncoder(); } -} \ No newline at end of file +} diff --git a/src/backend/Eyesee/src/main/java/com/fortune/eyesee/controller/ExamController.java b/src/backend/Eyesee/src/main/java/com/fortune/eyesee/controller/ExamController.java index 08cb78f..efb1291 100644 --- a/src/backend/Eyesee/src/main/java/com/fortune/eyesee/controller/ExamController.java +++ b/src/backend/Eyesee/src/main/java/com/fortune/eyesee/controller/ExamController.java @@ -24,40 +24,72 @@ public class ExamController { @Autowired private ExamService examService; +// // "before" 상태의 Exam 리스트 조회 +// @GetMapping("/before") +// public ResponseEntity>> getBeforeExams(HttpSession session) { +// return getExamsByStatus("BEFORE", session); +// } +// +// // "in-progress" 상태의 Exam 리스트 조회 +// @GetMapping("/in-progress") +// public ResponseEntity>> getInProgressExams(HttpSession session) { +// return getExamsByStatus("IN_PROGRESS", session); +// } +// +// // "done" 상태의 Exam 리스트 조회 +// @GetMapping("/done") +// public ResponseEntity>> getDoneExams(HttpSession session) { +// return getExamsByStatus("DONE", session); +// } + + // 공통 메서드: 상태별 Exam 조회 +// private ResponseEntity>> getExamsByStatus(String status, HttpSession session) { +// Integer adminId = (Integer) session.getAttribute("adminId"); +// if (adminId == null) { +// throw new BaseException(BaseResponseCode.UNAUTHORIZED); +// } +// +// ExamStatus examStatus = ExamStatus.fromString(status); +// if (examStatus == null) { +// throw new BaseException(BaseResponseCode.INVALID_STATUS); +// } +// +// List examList = examService.getExamsByStatus(adminId, examStatus); +// return ResponseEntity.ok(new BaseResponse<>(examList)); +// } + // "before" 상태의 Exam 리스트 조회 @GetMapping("/before") - public ResponseEntity>> getBeforeExams(HttpSession session) { - return getExamsByStatus("BEFORE", session); + public ResponseEntity>> getBeforeExams() { + return getExamsByStatus("BEFORE"); } // "in-progress" 상태의 Exam 리스트 조회 @GetMapping("/in-progress") - public ResponseEntity>> getInProgressExams(HttpSession session) { - return getExamsByStatus("IN_PROGRESS", session); + public ResponseEntity>> getInProgressExams() { + return getExamsByStatus("IN_PROGRESS"); } // "done" 상태의 Exam 리스트 조회 @GetMapping("/done") - public ResponseEntity>> getDoneExams(HttpSession session) { - return getExamsByStatus("DONE", session); + public ResponseEntity>> getDoneExams() { + return getExamsByStatus("DONE"); } - // 공통 메서드: 상태별 Exam 조회 - private ResponseEntity>> getExamsByStatus(String status, HttpSession session) { - Integer adminId = (Integer) session.getAttribute("adminId"); - if (adminId == null) { - throw new BaseException(BaseResponseCode.UNAUTHORIZED); - } - + // 공통 메서드: 상태별 Exam 조회 (세션 검증 없이) + private ResponseEntity>> getExamsByStatus(String status) { ExamStatus examStatus = ExamStatus.fromString(status); if (examStatus == null) { throw new BaseException(BaseResponseCode.INVALID_STATUS); } - List examList = examService.getExamsByStatus(adminId, examStatus); + // adminId를 사용하지 않는 조회 방식으로 수정 + List examList = examService.getExamsByStatus(null, examStatus); return ResponseEntity.ok(new BaseResponse<>(examList)); } + + // ExamCode로 특정 Exam 조회 (POST 요청) @PostMapping("/{examId}/code") public ResponseEntity> getExamByCode(@PathVariable Integer examId, @RequestBody ExamCodeRequestDTO examCodeRequestDTO, HttpSession session) { diff --git a/src/backend/Eyesee/src/main/java/com/fortune/eyesee/repository/ExamRepository.java b/src/backend/Eyesee/src/main/java/com/fortune/eyesee/repository/ExamRepository.java index 1976718..3889903 100644 --- a/src/backend/Eyesee/src/main/java/com/fortune/eyesee/repository/ExamRepository.java +++ b/src/backend/Eyesee/src/main/java/com/fortune/eyesee/repository/ExamRepository.java @@ -19,4 +19,8 @@ public interface ExamRepository extends JpaRepository { // 랜덤 코드와 adminId로 Exam 조회 Exam findByExamRandomCode(String examRandomCode); + + + // adminId 없이 상태로만 Exam 조회 + List findByExamStatus(ExamStatus examStatus); } \ No newline at end of file diff --git a/src/backend/Eyesee/src/main/java/com/fortune/eyesee/service/ExamService.java b/src/backend/Eyesee/src/main/java/com/fortune/eyesee/service/ExamService.java index 7405f5f..cd80265 100644 --- a/src/backend/Eyesee/src/main/java/com/fortune/eyesee/service/ExamService.java +++ b/src/backend/Eyesee/src/main/java/com/fortune/eyesee/service/ExamService.java @@ -50,25 +50,66 @@ public boolean existsById(Integer examId) { } // Admin ID와 ExamStatus로 시험 목록 조회 +// public List getExamsByStatus(Integer adminId, ExamStatus examStatus) { +// return examRepository.findByAdmin_AdminIdAndExamStatus(adminId, examStatus).stream() +// .map(exam -> new ExamResponseDTO( +// exam.getExamId(), +// exam.getExamName(), +// exam.getExamSemester(), +// exam.getExamStudentNumber(), +// exam.getExamLocation(), +// exam.getExamDate(), +// exam.getExamStartTime(), +// exam.getExamDuration(), +// exam.getExamStatus(), +// exam.getExamNotice(), +// exam.getSession() != null ? exam.getSession().getSessionId() : null, +// exam.getExamRandomCode() +// )) +// .collect(Collectors.toList()); +// } + + // Admin ID 없이 ExamStatus로만 시험 목록 조회 public List getExamsByStatus(Integer adminId, ExamStatus examStatus) { - return examRepository.findByAdmin_AdminIdAndExamStatus(adminId, examStatus).stream() - .map(exam -> new ExamResponseDTO( - exam.getExamId(), - exam.getExamName(), - exam.getExamSemester(), - exam.getExamStudentNumber(), - exam.getExamLocation(), - exam.getExamDate(), - exam.getExamStartTime(), - exam.getExamDuration(), - exam.getExamStatus(), - exam.getExamNotice(), - exam.getSession() != null ? exam.getSession().getSessionId() : null, - exam.getExamRandomCode() - )) - .collect(Collectors.toList()); + if (adminId == null) { + return examRepository.findByExamStatus(examStatus).stream() + .map(exam -> new ExamResponseDTO( + exam.getExamId(), + exam.getExamName(), + exam.getExamSemester(), + exam.getExamStudentNumber(), + exam.getExamLocation(), + exam.getExamDate(), + exam.getExamStartTime(), + exam.getExamDuration(), + exam.getExamStatus(), + exam.getExamNotice(), + exam.getSession() != null ? exam.getSession().getSessionId() : null, + exam.getExamRandomCode() + )) + .collect(Collectors.toList()); + } else { + return examRepository.findByAdmin_AdminIdAndExamStatus(adminId, examStatus).stream() + .map(exam -> new ExamResponseDTO( + exam.getExamId(), + exam.getExamName(), + exam.getExamSemester(), + exam.getExamStudentNumber(), + exam.getExamLocation(), + exam.getExamDate(), + exam.getExamStartTime(), + exam.getExamDuration(), + exam.getExamStatus(), + exam.getExamNotice(), + exam.getSession() != null ? exam.getSession().getSessionId() : null, + exam.getExamRandomCode() + )) + .collect(Collectors.toList()); + } } + + // ExamCode로 시험 조회 public ExamResponseDTO getExamByCode(String examCode) { Exam exam = examRepository.findByExamRandomCode(examCode);