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
@@ -1,5 +1,6 @@
package com.tekcit.festival.domain.user.controller;

import com.tekcit.festival.domain.user.dto.api.AddressApiSpecification;
import com.tekcit.festival.domain.user.dto.request.AddressRequestDTO;
import com.tekcit.festival.domain.user.dto.response.AddressDTO;
import com.tekcit.festival.domain.user.service.AddressService;
Expand All @@ -20,12 +21,10 @@
@RequestMapping("/api/addresses")
@RequiredArgsConstructor
@Tag(name = "주소 API", description = "주소 조회, 추가, 수정, 삭제, 기본 배송지 수정")
public class AddressController {
public class AddressController implements AddressApiSpecification {
private final AddressService addressService;

@PostMapping
@Operation(summary = "회원 주소 정보 추가",
description = "회원 주소 정보 추가, AddressRequestDTO를 포함해야 합니다. ex) POST /api/addresses")
@PreAuthorize("hasRole('USER')")
public ResponseEntity<SuccessResponse<AddressDTO>> addAddress(@Valid @RequestBody AddressRequestDTO addressRequestDTO, @AuthenticationPrincipal String principal){
Long userId = Long.parseLong(principal);
Expand All @@ -34,8 +33,6 @@ public ResponseEntity<SuccessResponse<AddressDTO>> addAddress(@Valid @RequestBod
}

@PatchMapping(value="/updateAddress/{addressId}")
@Operation(summary = "회원 주소 정보 수정",
description = "회원 주소 정보 수정, AddressRequestDTO를 포함해야 합니다. ex) PATCH /api/addresses/updateAddress/{addressId}")
@PreAuthorize("hasRole('USER')")
public ResponseEntity<SuccessResponse<AddressDTO>> updateAddress(@PathVariable Long addressId, @Valid @RequestBody AddressRequestDTO addressRequestDTO, @AuthenticationPrincipal String principal){
Long userId = Long.parseLong(principal);
Expand All @@ -44,8 +41,6 @@ public ResponseEntity<SuccessResponse<AddressDTO>> updateAddress(@PathVariable L
}

@PatchMapping(value="/changeDefault/{addressId}")
@Operation(summary = "회원 주소 기본 배송지 수정",
description = "회원 주소 기본 배송지 수정, ex) PATCH /api/addresses/changeDefault/{addressId}")
@PreAuthorize("hasRole('USER')")
public ResponseEntity<SuccessResponse<AddressDTO>> updateDefault(@PathVariable Long addressId, @AuthenticationPrincipal String principal){
Long userId = Long.parseLong(principal);
Expand All @@ -54,8 +49,6 @@ public ResponseEntity<SuccessResponse<AddressDTO>> updateDefault(@PathVariable L
}

@DeleteMapping(value="/{addressId}")
@Operation(summary = "회원 주소 삭제",
description = "회원 주소 삭제, ex) DELETE /api/addresses/deleteAddress/{addressId}")
@PreAuthorize("hasRole('USER')")
public ResponseEntity<Void> deleteAddress(@PathVariable Long addressId, @AuthenticationPrincipal String principal){
Long userId = Long.parseLong(principal);
Expand All @@ -64,8 +57,6 @@ public ResponseEntity<Void> deleteAddress(@PathVariable Long addressId, @Authent
}

@GetMapping(value="/allAddress")
@Operation(summary = "회원 주소 정보 전체 조회",
description = "회원 주소 정보 전체 조회 ex) GET /api/addresses/allAddress")
@PreAuthorize("hasAnyRole('USER')")
public ResponseEntity<SuccessResponse<List<AddressDTO>>> getAllAddresses(@AuthenticationPrincipal String principal){
Long userId = Long.parseLong(principal);
Expand All @@ -74,8 +65,6 @@ public ResponseEntity<SuccessResponse<List<AddressDTO>>> getAllAddresses(@Authen
}

@GetMapping(value="/defaultAddress")
@Operation(summary = "회원 주소 기본 배송지 조회",
description = "회원 주소 기본 배송지 정보 조회 ex) GET /api/addresses/defaultAddress")
@PreAuthorize("hasAnyRole('USER')")
public ResponseEntity<SuccessResponse<AddressDTO>> getDefaultAddress(@AuthenticationPrincipal String principal){
Long userId = Long.parseLong(principal);
Expand All @@ -84,11 +73,10 @@ public ResponseEntity<SuccessResponse<AddressDTO>> getDefaultAddress(@Authentica
}

@GetMapping(value="/{addressId}")
@Operation(summary = "회원 주소 정보 한 개 조회",
description = "회원 주소 정보 한 개 조회 ex) GET /api/addresses/{addressId}")
@PreAuthorize("hasAnyRole('USER')")
public ResponseEntity<SuccessResponse<AddressDTO>> getAddress(@PathVariable Long addressId){
AddressDTO addressDTO = addressService.getAddress(addressId);
public ResponseEntity<SuccessResponse<AddressDTO>> getAddress(@AuthenticationPrincipal String principal, @PathVariable Long addressId){
Long userId = Long.parseLong(principal);
AddressDTO addressDTO = addressService.getAddress(userId, addressId);
return ApiResponseUtil.success(addressDTO);
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package com.tekcit.festival.domain.user.controller;

import com.tekcit.festival.domain.user.dto.api.AdminApiSpecification;
import com.tekcit.festival.domain.user.dto.response.AddressDTO;
import com.tekcit.festival.domain.user.dto.response.AdminHostListDTO;
import com.tekcit.festival.domain.user.dto.response.AdminUserListDTO;
Expand All @@ -22,13 +23,11 @@
@RequestMapping("/api/admin")
@RequiredArgsConstructor
@Tag(name = "운영 관리자 api", description = "전체 회원 조회, 전체 주최자 조회")
public class AdminController {
public class AdminController implements AdminApiSpecification {

private final AdminService adminService;

@GetMapping(value="/userList")
@Operation(summary = "사용자 전체 목록 조회",
description = "사용자 전체 목록 조회(user), ex) GET /api/admin/userList")
@PreAuthorize("hasRole('ADMIN')")
public ResponseEntity<SuccessResponse<List<AdminUserListDTO>>> getAllUser(@AuthenticationPrincipal String principal){
Long userId = Long.parseLong(principal);
Expand All @@ -37,8 +36,6 @@ public ResponseEntity<SuccessResponse<List<AdminUserListDTO>>> getAllUser(@Authe
}

@GetMapping(value="/hostList")
@Operation(summary = "주최자 전체 목록 조회",
description = "주최자 전체 목록 조회(host), ex) GET /api/admin/hostList")
@PreAuthorize("hasRole('ADMIN')")
public ResponseEntity<SuccessResponse<List<AdminHostListDTO>>> getAllHostList(@AuthenticationPrincipal String principal){
Long userId = Long.parseLong(principal);
Expand All @@ -47,13 +44,6 @@ public ResponseEntity<SuccessResponse<List<AdminHostListDTO>>> getAllHostList(@A
}

@PatchMapping(value="/{userId}/state")
@Operation(summary = "회원 상태 변경 (활성화 / 비활성화)",
description = "운영관리자는 userId를 기준으로 회원의 활성 상태(active)를 true/false로 변경할 수 있습니다. ex) PATCH /api/admin/{userId}/state?active=false")
@ApiResponses(value = {
@ApiResponse(responseCode = "200", description = "회원 상태(active) 조정 완료"),
@ApiResponse(responseCode = "403", description = "회원 상태(active) 조정 실패(운영 관리자는 불가능)"),
@ApiResponse(responseCode = "404", description = "회원 상태(active) 조정 실패(해당 유저를 찾을 수 없거나 운영 관리자만 상태 관리를 할 수 있습니다.)")
})
@PreAuthorize("hasRole('ADMIN')")
public ResponseEntity<SuccessResponse<Void>> changeState(@PathVariable Long userId, @RequestParam boolean active, @AuthenticationPrincipal String principal){
Long adminId = Long.parseLong(principal);
Expand All @@ -62,8 +52,6 @@ public ResponseEntity<SuccessResponse<Void>> changeState(@PathVariable Long user
}

@DeleteMapping(value="/{userId}")
@Operation(summary = "주최자 탈퇴(삭제)",
description = "운영관리자가 주최자 탈퇴(host), ex) DELETE /api/admin/{userId}")
@PreAuthorize("hasRole('ADMIN')")
public ResponseEntity<SuccessResponse<Void>> deleteHost(@AuthenticationPrincipal String principal, @PathVariable Long userId){
Long adminId = Long.parseLong(principal);
Expand All @@ -73,8 +61,6 @@ public ResponseEntity<SuccessResponse<Void>> deleteHost(@AuthenticationPrincipal
}

@GetMapping
@Operation(summary = "전체 회원 주소 정보 조회",
description = "회원 주소 정보 조회 ex) GET /api/admin/addresses")
@PreAuthorize("hasAnyRole('ADMIN')")
public ResponseEntity<SuccessResponse<List<AddressDTO>>> getAllAddresses(@AuthenticationPrincipal String principal){
Long userId = Long.parseLong(principal);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package com.tekcit.festival.domain.user.controller;

import com.tekcit.festival.config.security.token.JwtTokenProvider;
import com.tekcit.festival.domain.user.dto.api.AuthApiSpecification;
import com.tekcit.festival.domain.user.dto.response.AccessTokenInfoDTO;
import com.tekcit.festival.domain.user.dto.request.LoginRequestDTO;
import com.tekcit.festival.domain.user.dto.response.LoginResponseDTO;
Expand All @@ -21,6 +22,7 @@
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import jakarta.validation.Valid;
import lombok.RequiredArgsConstructor;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
Expand All @@ -29,47 +31,29 @@
@RequestMapping("/api/users")
@RequiredArgsConstructor
@Tag(name = "로그인 API", description = "회원 로그인, 로그아웃, 토큰 재발급")
public class AuthController {
public class AuthController implements AuthApiSpecification {
private final JwtTokenProvider jwtTokenProvider;
private final AuthService authService;

@PostMapping("/login")
@Operation(summary = "로그인",
description = "로그인 기능, LoginRequestDTO를 포함해야 합니다. ex) POST /api/users/login")
@ApiResponses(value = {
@ApiResponse(responseCode = "200", description = "로그인 성공",
content = @Content(schema = @Schema(implementation = SuccessResponse.class)))})
public ResponseEntity<SuccessResponse<LoginResponseDTO>> login(@RequestBody LoginRequestDTO request, HttpServletResponse response) {
public ResponseEntity<SuccessResponse<LoginResponseDTO>> login(@Valid @RequestBody LoginRequestDTO request, HttpServletResponse response) {
LoginResponseDTO loginResult = authService.login(request, response);
return ApiResponseUtil.success(loginResult);
}

@PostMapping("/logout")
@Operation(summary = "로그아웃",
description = "로그아웃 기능 ex) POST /api/users/logout")
@ApiResponse(responseCode = "200", description = "로그아웃 성공",
content = @Content(schema = @Schema(implementation = SuccessResponse.class)))
public ResponseEntity<SuccessResponse<Void>> logout(HttpServletRequest request, HttpServletResponse response) {
authService.logout(request, response);
return ApiResponseUtil.success(null, "로그아웃 성공");
}

@PostMapping("/reissue")
@Operation(summary = "accessToken 재발급",
description = "accessToken 재발급 기능 ex) POST /api/users/reissue")
@ApiResponses(value = {
@ApiResponse(responseCode = "200", description = "재발급 성공",
content = @Content(schema = @Schema(implementation = SuccessResponse.class)))})
public ResponseEntity<SuccessResponse<LoginResponseDTO>> reissue(HttpServletRequest request, HttpServletResponse response) {
LoginResponseDTO newToken = authService.reissue(request, response);
return ApiResponseUtil.success(newToken);
}

@GetMapping("/token/parse")
@Operation(
summary = "Access Token 파싱",
description = "Authorization: Bearer {token} 헤더로 전달된 Access Token을 검증하고, 포함된 클레임 정보를 반환합니다."
)
public ResponseEntity<SuccessResponse<AccessTokenInfoDTO>> parseToken(HttpServletRequest request) {

String raw = TokenParseUtil.parseToken(request);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package com.tekcit.festival.domain.user.controller;

import com.tekcit.festival.domain.user.dto.api.EmailApiSpecification;
import com.tekcit.festival.domain.user.dto.request.EmailSendDTO;
import com.tekcit.festival.domain.user.dto.request.EmailVerifyDTO;
import com.tekcit.festival.domain.user.dto.response.EmailResponseDTO;
Expand All @@ -17,21 +18,17 @@
@RequiredArgsConstructor
@RequestMapping("/api/mail")
@Tag(name = "이메일 인증 API", description = "이메일 인증 코드 전송, 검증")
public class EmailController {
public class EmailController implements EmailApiSpecification {

private final EmailService emailService;

@PostMapping("/sendCode")
@Operation(summary = "이메일 인증 코드 전송",
description = "이메일 인증 코드 전송, 인증 코드 5분 이후 만료, emailSendDTO를 포함해야 합니다. ex) POST /api/mail/sendCode")
public ResponseEntity<SuccessResponse<EmailResponseDTO>> sendCode(@Valid @RequestBody EmailSendDTO emailSendDTO) {
EmailResponseDTO sendCode = emailService.sendVerificationCode(emailSendDTO);
return ApiResponseUtil.success(sendCode);
}

@PostMapping("/verifyCode")
@Operation(summary = "이메일 인증 코드 검증",
description = "이메일 인증 코드 검증, emailVerifyDTO를 포함해야 합니다. ex) POST /api/mail/verify")
public ResponseEntity<SuccessResponse<EmailResponseDTO>> verifyCode(@Valid @RequestBody EmailVerifyDTO emailVerifyDTO) {
EmailResponseDTO verifyCode = emailService.verifyCode(emailVerifyDTO);
return ApiResponseUtil.success(verifyCode);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package com.tekcit.festival.domain.user.controller;

import com.tekcit.festival.domain.user.dto.api.KakaoAuthApiSpecification;
import com.tekcit.festival.domain.user.dto.request.KakaoSignupDTO;
import com.tekcit.festival.domain.user.dto.response.UserResponseDTO;
import com.tekcit.festival.domain.user.service.KakaoService;
Expand Down Expand Up @@ -29,7 +30,7 @@
@RequestMapping("/api/auth/kakao")
@RequiredArgsConstructor
@Tag(name = "카카오 회원가입, 로그인 API", description = "카카오 회원가입, 로그인, 로그아웃, 토큰 재발급")
public class KakaoAuthController {
public class KakaoAuthController implements KakaoAuthApiSpecification {
@Value("${kakao.restapi-key}")
private String clientId;

Expand Down Expand Up @@ -88,16 +89,6 @@ public void callback(@RequestParam("code") String code, HttpServletResponse resp
}

@PostMapping(value="/signupUser")
@Operation(summary = "회원 가입(일반 유저), 카카오 회원가입",
description = "일반 유저 회원 가입, SignupUserDTO를 포함해야 합니다. ex) POST /api/auth/kakao/signupUser")
@ApiResponses(value = {
@ApiResponse(responseCode = "200", description = "회원 가입 성공(일반 유저)",
content = @Content(schema = @Schema(implementation = SuccessResponse.class))),
@ApiResponse(responseCode = "400", description = "회원 가입 실패 (잘못된 데이터, 필수 필드 누락)",
content = @Content(schema = @Schema(implementation = ErrorResponse.class))),
@ApiResponse(responseCode = "409", description = "회원 가입 실패 (중복된 ID, Email로 인한 conflict)",
content = @Content(schema = @Schema(implementation = ErrorResponse.class)))
})
public ResponseEntity<SuccessResponse<UserResponseDTO>> signupUser(@Valid @RequestBody KakaoSignupDTO kakaoSignupDTO,
@CookieValue(value = "kakao_signup", required = false) String ticket,
HttpServletResponse res) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,12 +1,9 @@
package com.tekcit.festival.domain.user.controller;

import com.tekcit.festival.config.security.userdetails.CustomUserDetails;
import com.tekcit.festival.domain.user.dto.api.MyPageApiSpecification;
import com.tekcit.festival.domain.user.dto.request.CheckPwDTO;
import com.tekcit.festival.domain.user.dto.request.ResetPwDTO;
import com.tekcit.festival.domain.user.dto.request.UpdateUserRequestDTO;
import com.tekcit.festival.domain.user.dto.response.MyPageCommonDTO;
import com.tekcit.festival.domain.user.dto.response.MyPageHostDTO;
import com.tekcit.festival.domain.user.dto.response.MyPageUserDTO;
import com.tekcit.festival.domain.user.dto.response.UpdateUserResponseDTO;
import com.tekcit.festival.domain.user.service.MyPageService;
import com.tekcit.festival.exception.global.SuccessResponse;
Expand All @@ -27,51 +24,31 @@
@RequestMapping("/api/myPage")
@RequiredArgsConstructor
@Tag(name = "마이 페이지 API", description = "회원 생성, 조회, 탈퇴")
public class MyPageController {
public class MyPageController implements MyPageApiSpecification {
private final MyPageService myPageService;

@GetMapping(value="/userInfo")
@Operation(summary = "마이페이지 회원 정보 조회",
description = "마이페이지 회원 정보 조회, MyPageUserDTO(USER), MyPageHostDTO(HOST), MyPageCommonDTO(ADMIN) Role에 따라 return 값이 달라집니다." +
"ex) GET /api/myPage/userInfo")
@ApiResponse(responseCode = "200", content = @Content(
schema = @Schema(oneOf = { MyPageUserDTO.class, MyPageHostDTO.class, MyPageCommonDTO.class })
))
public ResponseEntity<SuccessResponse<Object>> myPageUserInfo(@AuthenticationPrincipal String principal){
Long userId = Long.parseLong(principal);
Object myPageDto = myPageService.getUserInfo(userId);
return ApiResponseUtil.success(myPageDto);
}

@PatchMapping(value="/updateUser")
@Operation(summary = "마이페이지 회원 정보 수정",
description = "마이페이지 회원 정보 수정, UpdateUserRequestDTO를 포함해야 합니다. ex) PATCH /api/myPage/updateUser")
public ResponseEntity<SuccessResponse<UpdateUserResponseDTO>> updateUser(@Valid @RequestBody UpdateUserRequestDTO updateUserRequestDTO, @AuthenticationPrincipal String principal){
Long userId = Long.parseLong(principal);
UpdateUserResponseDTO updateUserDTO = myPageService.updateUser(updateUserRequestDTO, userId);
return ApiResponseUtil.success(updateUserDTO);
}

@PostMapping(value="/checkPassword")
@Operation(summary = "마이페이지 기존 비밀번호 일치 여부 확인",
description = "마이페이지에서 기존 비밀번호 일치 여부를 확인할 수 있습니다. CheckPwDTO(기존 비밀번호)를 포함해야 합니다. ex) POST /api/myPage/checkPassword")
@ApiResponses(value = {
@ApiResponse(responseCode = "200", description = "비밀번호가 일치합니다.",
content = @Content(schema = @Schema(implementation = SuccessResponse.class))),
})
public ResponseEntity<SuccessResponse<Void>> checkPassword(@AuthenticationPrincipal String principal, @Valid @RequestBody CheckPwDTO checkPwDTO){
Long userId = Long.parseLong(principal);
myPageService.checkPassword(userId, checkPwDTO);
return ApiResponseUtil.success(null, "비밀번호가 일치합니다.");
}

@PatchMapping(value="/resetPassword")
@Operation(summary = "마이페이지 비밀번호 재설정",
description = "마이페이지에서 비밀번호를 변경할 수 있습니다. ResetPwDTO(새로운 비밀번호)를 포함해야 합니다. ex) PATCH /api/myPage/resetPassword")
@ApiResponses(value = {
@ApiResponse(responseCode = "200", description = "새로운 비밀번호 재설정",
content = @Content(schema = @Schema(implementation = SuccessResponse.class))),
})
public ResponseEntity<SuccessResponse<Void>> resetPassword(@AuthenticationPrincipal String principal, @Valid @RequestBody ResetPwDTO resetPwDTO){
Long userId = Long.parseLong(principal);
myPageService.resetPassword(userId, resetPwDTO);
Expand Down
Loading