From ea9533e34deaba695dd9b6935da4b0de0aa8ee32 Mon Sep 17 00:00:00 2001 From: wrathlion Date: Mon, 2 Sep 2024 17:50:39 +0900 Subject: [PATCH] =?UTF-8?q?=E2=9C=A8=20/api/auth/member=20API=20=EA=B8=B0?= =?UTF-8?q?=EB=8A=A5=20=EC=B6=94=EA=B0=80=20(#4)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Feat: Member DB 수정 - 한글이름, 영어이름, 기수, 과정 추가 - 과정 표현하는 Enumerate 추가 - 수정에 따른 오류 수정 - getNickname -> getKoreaName of getEnglishName Related to: #2 * Rename: Member DB Field 이름 변경 Related to: #2 * Feat: /api/auth/member 관련 DTO 작성 Related to: #2 * Feat: /api/auth/member API 관련 DTO 내용 추가 Related to: #2 * Feat: /api/auth/member 관련 MemberService 추가 Related to: #2 * Feat: /api/auth/member 관련 MemberContoller 추가 Related to: #2 * Feat: CORS Error 수정 Related to: #2 * Fix: RefreshToken 매번 생성 오류 수정 Related to: #2 * Refactor: 코드 리뷰 내용 반영 - 불필요 코드 삭제 - 반환값 오류 수정 Related to: #2 --- .../kaboo_auth/config/SecurityConfig.java | 15 ++++ .../controller/MainControllerAdvice.java | 26 ++++++ .../controller/MemberController.java | 86 +++++++++++++++++++ .../java/kaboo/kaboo_auth/domain/Course.java | 13 +++ .../kaboo_auth/domain/CustomUserDetails.java | 2 +- .../dto/request/MemberInfoUpdateRequest.java | 13 +++ .../dto/response/MemberInfoResponse.java | 20 +++++ .../dto/response/MemberListResponse.java | 21 +++++ .../domain/dto/response/ResponseDTO.java | 18 ++++ .../kaboo_auth/domain/entity/Member.java | 34 +++++++- .../domain/jwt/filter/JwtFilter.java | 2 + .../repository/MemberRepository.java | 5 ++ .../service/CustomOAuth2Service.java | 2 +- .../kaboo_auth/service/MemberService.java | 47 ++++++++++ .../repository/MemberRepositoryTest.java | 4 +- 15 files changed, 300 insertions(+), 8 deletions(-) create mode 100644 src/main/java/kaboo/kaboo_auth/controller/MainControllerAdvice.java create mode 100644 src/main/java/kaboo/kaboo_auth/controller/MemberController.java create mode 100644 src/main/java/kaboo/kaboo_auth/domain/Course.java create mode 100644 src/main/java/kaboo/kaboo_auth/domain/dto/request/MemberInfoUpdateRequest.java create mode 100644 src/main/java/kaboo/kaboo_auth/domain/dto/response/MemberInfoResponse.java create mode 100644 src/main/java/kaboo/kaboo_auth/domain/dto/response/MemberListResponse.java create mode 100644 src/main/java/kaboo/kaboo_auth/domain/dto/response/ResponseDTO.java diff --git a/src/main/java/kaboo/kaboo_auth/config/SecurityConfig.java b/src/main/java/kaboo/kaboo_auth/config/SecurityConfig.java index 7cc7cfd..6202af5 100644 --- a/src/main/java/kaboo/kaboo_auth/config/SecurityConfig.java +++ b/src/main/java/kaboo/kaboo_auth/config/SecurityConfig.java @@ -9,6 +9,9 @@ import org.springframework.security.config.http.SessionCreationPolicy; import org.springframework.security.web.SecurityFilterChain; import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter; +import org.springframework.web.cors.CorsConfiguration; +import org.springframework.web.cors.UrlBasedCorsConfigurationSource; +import org.springframework.web.filter.CorsFilter; import kaboo.kaboo_auth.domain.handler.LoginSuccessHandler; import kaboo.kaboo_auth.domain.jwt.filter.JwtFilter; @@ -45,4 +48,16 @@ public SecurityFilterChain filterChain(HttpSecurity http) throws Exception { return http.build(); } + + @Bean + public CorsFilter corsFilter() { + UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource(); + CorsConfiguration config = new CorsConfiguration(); + config.setAllowCredentials(true); + config.addAllowedOriginPattern("*"); // 모든 도메인 허용. 필요에 따라 변경 + config.addAllowedHeader("*"); + config.addAllowedMethod("*"); + source.registerCorsConfiguration("/**", config); + return new CorsFilter(source); + } } diff --git a/src/main/java/kaboo/kaboo_auth/controller/MainControllerAdvice.java b/src/main/java/kaboo/kaboo_auth/controller/MainControllerAdvice.java new file mode 100644 index 0000000..0d62ae9 --- /dev/null +++ b/src/main/java/kaboo/kaboo_auth/controller/MainControllerAdvice.java @@ -0,0 +1,26 @@ +package kaboo.kaboo_auth.controller; + +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.security.core.userdetails.UsernameNotFoundException; +import org.springframework.web.bind.annotation.ExceptionHandler; +import org.springframework.web.bind.annotation.RestControllerAdvice; + +import kaboo.kaboo_auth.domain.dto.response.ResponseDTO; +import lombok.extern.slf4j.Slf4j; + +@Slf4j +@RestControllerAdvice +public class MainControllerAdvice { + + @ExceptionHandler({IllegalStateException.class, UsernameNotFoundException.class}) + public ResponseEntity> exceptionHandler(Exception e) { + log.error("[Kaboo-Auth]: 예외가 발생하였습니다. {}", e.getMessage()); + return ResponseEntity.status(HttpStatus.OK) + .body(new ResponseDTO<>( + true, + e.getMessage(), + null + )); + } +} diff --git a/src/main/java/kaboo/kaboo_auth/controller/MemberController.java b/src/main/java/kaboo/kaboo_auth/controller/MemberController.java new file mode 100644 index 0000000..4affd6e --- /dev/null +++ b/src/main/java/kaboo/kaboo_auth/controller/MemberController.java @@ -0,0 +1,86 @@ +package kaboo.kaboo_auth.controller; + +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.RestController; + +import kaboo.kaboo_auth.domain.dto.request.MemberInfoUpdateRequest; +import kaboo.kaboo_auth.domain.dto.response.MemberInfoResponse; +import kaboo.kaboo_auth.domain.dto.response.MemberListResponse; +import kaboo.kaboo_auth.domain.dto.response.ResponseDTO; +import kaboo.kaboo_auth.service.MemberService; +import lombok.RequiredArgsConstructor; + +@RestController +@RequiredArgsConstructor +@RequestMapping("/api/auth/member") +public class MemberController { + + private final MemberService memberService; + + @GetMapping("/all") + public ResponseEntity> getAllMembers() { + return ResponseEntity.status(HttpStatus.OK) + .body(new ResponseDTO<>( + memberService.getAllMembers() + )); + } + + @GetMapping("/class/{class}") + public ResponseEntity> getClassMembers( + @PathVariable(name = "class") int classNum) { + + return ResponseEntity.status(HttpStatus.OK) + .body(new ResponseDTO<>( + memberService.getMembersByClassNum(classNum) + )); + } + + @GetMapping + public ResponseEntity> getMemberInfo( + @RequestParam(name = "name", defaultValue = "") String koreaName) { + + return ResponseEntity.status(HttpStatus.OK) + .body(new ResponseDTO<>( + memberService.getMemberInfoByKoreaName(koreaName) + )); + } + + @PostMapping + public ResponseEntity> updateMemberInfo( + @RequestParam(name = "name", defaultValue = "") String koreaName, + @RequestBody MemberInfoUpdateRequest request) { + + return ResponseEntity.status(HttpStatus.OK) + .body(new ResponseDTO<>( + memberService.updateMemberInfoByKoreaName(koreaName, request) + )); + } + + @GetMapping("/introduce") + public ResponseEntity> getMemberIntroduce( + @RequestParam(name = "name", defaultValue = "") String koreaName) { + + return ResponseEntity.status(HttpStatus.OK) + .body(new ResponseDTO<>( + memberService.getMemberIntroduceByKoreaName(koreaName) + )); + } + + @PostMapping("/introduce") + public ResponseEntity> updateMemberIntrouce( + @RequestParam(name = "name", defaultValue = "") String koreaName, + @RequestBody String request) { + + return ResponseEntity.status(HttpStatus.OK) + .body(new ResponseDTO<>( + memberService.updateMemberIntroduceByKoreaName(koreaName, request) + )); + } +} diff --git a/src/main/java/kaboo/kaboo_auth/domain/Course.java b/src/main/java/kaboo/kaboo_auth/domain/Course.java new file mode 100644 index 0000000..c5a3a06 --- /dev/null +++ b/src/main/java/kaboo/kaboo_auth/domain/Course.java @@ -0,0 +1,13 @@ +package kaboo.kaboo_auth.domain; + +public enum Course { + AI("GenAI"), + FULLSTACK("Fullstack"), + CLOUD("Cloud"); + + private final String course; + + Course(String course) { + this.course = course; + } +} diff --git a/src/main/java/kaboo/kaboo_auth/domain/CustomUserDetails.java b/src/main/java/kaboo/kaboo_auth/domain/CustomUserDetails.java index ce539d0..7554366 100644 --- a/src/main/java/kaboo/kaboo_auth/domain/CustomUserDetails.java +++ b/src/main/java/kaboo/kaboo_auth/domain/CustomUserDetails.java @@ -22,7 +22,7 @@ public String getUsername() { @Override public String getName() { - return member.getNickname(); + return member.getKoreaName(); } @Override diff --git a/src/main/java/kaboo/kaboo_auth/domain/dto/request/MemberInfoUpdateRequest.java b/src/main/java/kaboo/kaboo_auth/domain/dto/request/MemberInfoUpdateRequest.java new file mode 100644 index 0000000..53ab147 --- /dev/null +++ b/src/main/java/kaboo/kaboo_auth/domain/dto/request/MemberInfoUpdateRequest.java @@ -0,0 +1,13 @@ +package kaboo.kaboo_auth.domain.dto.request; + +import kaboo.kaboo_auth.domain.Course; +import lombok.Getter; + +@Getter +public class MemberInfoUpdateRequest { + private String koreaName; + private String englishName; + private int classNum; + private Course course; + +} diff --git a/src/main/java/kaboo/kaboo_auth/domain/dto/response/MemberInfoResponse.java b/src/main/java/kaboo/kaboo_auth/domain/dto/response/MemberInfoResponse.java new file mode 100644 index 0000000..853943c --- /dev/null +++ b/src/main/java/kaboo/kaboo_auth/domain/dto/response/MemberInfoResponse.java @@ -0,0 +1,20 @@ +package kaboo.kaboo_auth.domain.dto.response; + +import kaboo.kaboo_auth.domain.Course; +import kaboo.kaboo_auth.domain.entity.Member; +import lombok.Getter; + +@Getter +public class MemberInfoResponse { + private final String koreaName; + private final String englishName; + private final int classNum; + private final Course course; + + public MemberInfoResponse(Member member) { + this.koreaName = member.getKoreaName(); + this.englishName = member.getEnglishName(); + this.classNum = member.getClassNum(); + this.course = member.getCourse(); + } +} diff --git a/src/main/java/kaboo/kaboo_auth/domain/dto/response/MemberListResponse.java b/src/main/java/kaboo/kaboo_auth/domain/dto/response/MemberListResponse.java new file mode 100644 index 0000000..2f46aff --- /dev/null +++ b/src/main/java/kaboo/kaboo_auth/domain/dto/response/MemberListResponse.java @@ -0,0 +1,21 @@ +package kaboo.kaboo_auth.domain.dto.response; + +import java.util.List; + +import kaboo.kaboo_auth.domain.entity.Member; +import lombok.Getter; + +@Getter +public class MemberListResponse { + private final int classNum; + private final int memberNum; + private final List memberList; + + public MemberListResponse(List members, int classNum) { + this.classNum = classNum; + this.memberNum = members.size(); + this.memberList = members.stream() + .map(MemberInfoResponse::new) + .toList(); + } +} diff --git a/src/main/java/kaboo/kaboo_auth/domain/dto/response/ResponseDTO.java b/src/main/java/kaboo/kaboo_auth/domain/dto/response/ResponseDTO.java new file mode 100644 index 0000000..a292021 --- /dev/null +++ b/src/main/java/kaboo/kaboo_auth/domain/dto/response/ResponseDTO.java @@ -0,0 +1,18 @@ +package kaboo.kaboo_auth.domain.dto.response; + +import lombok.AllArgsConstructor; +import lombok.Getter; + +@Getter +@AllArgsConstructor +public class ResponseDTO { + private boolean success; + private String message; + private T data; + + public ResponseDTO(T data) { + success = true; + message = "요청이 성공적으로 처리되었습니다."; + this.data = data; + } +} diff --git a/src/main/java/kaboo/kaboo_auth/domain/entity/Member.java b/src/main/java/kaboo/kaboo_auth/domain/entity/Member.java index 4d5fa53..bbd68c9 100644 --- a/src/main/java/kaboo/kaboo_auth/domain/entity/Member.java +++ b/src/main/java/kaboo/kaboo_auth/domain/entity/Member.java @@ -7,6 +7,7 @@ import jakarta.persistence.GeneratedValue; import jakarta.persistence.GenerationType; import jakarta.persistence.Id; +import kaboo.kaboo_auth.domain.Course; import kaboo.kaboo_auth.domain.UserRole; import lombok.Builder; import lombok.Getter; @@ -23,19 +24,44 @@ public class Member { private String username; private String email; - private String nickname; + private String koreaName; + private String englishName; private String password; - private String info; + + @Column(columnDefinition = "TEXT") + private String introduce; + + private int classNum; + + @Enumerated(EnumType.STRING) + private Course course; @Enumerated(EnumType.STRING) private UserRole role; @Builder - public Member(String username, String email, String nickname, String password, UserRole role) { + public Member(String username, String email, String koreaName, String englishName, String password, + String introduce, + int classNum, Course course, UserRole role) { this.username = username; this.email = email; - this.nickname = nickname; + this.koreaName = koreaName; + this.englishName = englishName; this.password = password; + this.introduce = introduce; + this.classNum = classNum; + this.course = course; this.role = role; } + + public void updateInfo(String koreaName, String englishName, int classNum, Course course) { + this.koreaName = koreaName; + this.englishName = englishName; + this.classNum = classNum; + this.course = course; + } + + public void updateIntroduce(String introduce) { + this.introduce = introduce; + } } diff --git a/src/main/java/kaboo/kaboo_auth/domain/jwt/filter/JwtFilter.java b/src/main/java/kaboo/kaboo_auth/domain/jwt/filter/JwtFilter.java index ea332ca..c62d302 100644 --- a/src/main/java/kaboo/kaboo_auth/domain/jwt/filter/JwtFilter.java +++ b/src/main/java/kaboo/kaboo_auth/domain/jwt/filter/JwtFilter.java @@ -82,6 +82,8 @@ protected void doFilterInternal(HttpServletRequest request, HttpServletResponse SecurityContextHolder.getContext().setAuthentication(authentication); chain.doFilter(request, response); + + return; } } diff --git a/src/main/java/kaboo/kaboo_auth/repository/MemberRepository.java b/src/main/java/kaboo/kaboo_auth/repository/MemberRepository.java index 4893242..22b742d 100644 --- a/src/main/java/kaboo/kaboo_auth/repository/MemberRepository.java +++ b/src/main/java/kaboo/kaboo_auth/repository/MemberRepository.java @@ -1,5 +1,6 @@ package kaboo.kaboo_auth.repository; +import java.util.List; import java.util.Optional; import org.springframework.data.jpa.repository.JpaRepository; @@ -8,4 +9,8 @@ public interface MemberRepository extends JpaRepository { Optional findByUsername(String username); + + List findByClassNum(int classNum); + + Optional findByKoreaName(String koreaName); } diff --git a/src/main/java/kaboo/kaboo_auth/service/CustomOAuth2Service.java b/src/main/java/kaboo/kaboo_auth/service/CustomOAuth2Service.java index 8ca515c..87eb4b4 100644 --- a/src/main/java/kaboo/kaboo_auth/service/CustomOAuth2Service.java +++ b/src/main/java/kaboo/kaboo_auth/service/CustomOAuth2Service.java @@ -51,7 +51,7 @@ public OAuth2User loadUser(OAuth2UserRequest userRequest) throws OAuth2Authentic String rawPassword = username + passwordPostfix; member = Member.builder() .username(username) - .nickname(nickname) + .koreaName(nickname) .email(email) .password(passwordEncoder.encode(rawPassword)) .role(UserRole.ROLE_USER) diff --git a/src/main/java/kaboo/kaboo_auth/service/MemberService.java b/src/main/java/kaboo/kaboo_auth/service/MemberService.java index af06403..ac0b6b6 100644 --- a/src/main/java/kaboo/kaboo_auth/service/MemberService.java +++ b/src/main/java/kaboo/kaboo_auth/service/MemberService.java @@ -1,7 +1,13 @@ package kaboo.kaboo_auth.service; +import java.util.List; + import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; +import kaboo.kaboo_auth.domain.dto.request.MemberInfoUpdateRequest; +import kaboo.kaboo_auth.domain.dto.response.MemberInfoResponse; +import kaboo.kaboo_auth.domain.dto.response.MemberListResponse; import kaboo.kaboo_auth.domain.entity.Member; import kaboo.kaboo_auth.repository.MemberRepository; import lombok.RequiredArgsConstructor; @@ -16,4 +22,45 @@ public Member getMemberByUsername(String username) { new IllegalStateException("존재하지 않는 ID 입니다.") ); } + + public MemberListResponse getAllMembers() { + List members = memberRepository.findAll(); + return new MemberListResponse(members, 0); + } + + public MemberListResponse getMembersByClassNum(int classNum) { + List members = memberRepository.findByClassNum(classNum); + return new MemberListResponse(members, classNum); + } + + public MemberInfoResponse getMemberInfoByKoreaName(String koreaName) { + return new MemberInfoResponse( + getMember(koreaName)); + } + + @Transactional + public MemberInfoResponse updateMemberInfoByKoreaName(String koreaName, MemberInfoUpdateRequest request) { + Member member = getMember(koreaName); + + member.updateInfo(request.getKoreaName(), request.getEnglishName(), request.getClassNum(), request.getCourse()); + + return new MemberInfoResponse(member); + } + + public String getMemberIntroduceByKoreaName(String koreaName) { + return getMember(koreaName).getIntroduce(); + } + + @Transactional + public String updateMemberIntroduceByKoreaName(String koreaName, String request) { + Member member = getMember(koreaName); + member.updateIntroduce(request); + + return member.getIntroduce(); + } + + private Member getMember(String koreaName) { + return memberRepository.findByKoreaName(koreaName) + .orElseThrow(() -> new IllegalStateException(koreaName + "을 찾을 수 없습니다. 다시 한번 확인해주세요.")); + } } diff --git a/src/test/java/kaboo/kaboo_auth/repository/MemberRepositoryTest.java b/src/test/java/kaboo/kaboo_auth/repository/MemberRepositoryTest.java index a7d9ad0..b1c8d0f 100644 --- a/src/test/java/kaboo/kaboo_auth/repository/MemberRepositoryTest.java +++ b/src/test/java/kaboo/kaboo_auth/repository/MemberRepositoryTest.java @@ -23,7 +23,7 @@ class MemberRepositoryTest { @DisplayName("DB 저장 Test") void saveMemberTest() { // Given - Member member = Member.builder().username("Alice").nickname("Alice").password("1234").build(); + Member member = Member.builder().username("Alice").englishName("Alice").password("1234").build(); memberRepository.save(member); // When @@ -37,7 +37,7 @@ void saveMemberTest() { @DisplayName("Username으로 찾기 성공 Test") void findByUsername_Success() { // Given - Member member1 = Member.builder().username("Alice").nickname("Alice").password("1234").build(); + Member member1 = Member.builder().username("Alice").englishName("Alice").password("1234").build(); memberRepository.save(member1); // When