From f64e119c71eb9d21f1eca1a034b1d16fa6488f2b Mon Sep 17 00:00:00 2001 From: chamcham0707 Date: Tue, 4 Jun 2024 22:31:15 +0900 Subject: [PATCH 1/3] =?UTF-8?q?feat:=20profile=20=EC=A1=B0=ED=9A=8C,=20?= =?UTF-8?q?=EC=88=98=EC=A0=95=20=EA=B8=B0=EB=8A=A5=20=EC=99=84=EB=A3=8C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../oneandzerobest/auth/entity/User.java | 11 ++++ .../profile/controller/ProfileController.java | 26 ++++++++++ .../profile/dto/ProfileRequestDto.java | 12 +++++ .../profile/dto/ProfileResponseDto.java | 19 +++++++ .../exception/GlobalExceptionHandler.java | 23 +++++++++ .../exception/IncorrectPasswordException.java | 6 +++ .../exception/NotFoundUserException.java | 10 ++++ .../exception/PasswordPatternException.java | 6 +++ .../profile/service/ProfileService.java | 51 +++++++++++++++++++ src/main/resources/application.yml | 2 +- 10 files changed, 165 insertions(+), 1 deletion(-) create mode 100644 src/main/java/com/sparta/oneandzerobest/profile/controller/ProfileController.java create mode 100644 src/main/java/com/sparta/oneandzerobest/profile/dto/ProfileRequestDto.java create mode 100644 src/main/java/com/sparta/oneandzerobest/profile/dto/ProfileResponseDto.java create mode 100644 src/main/java/com/sparta/oneandzerobest/profile/exception/GlobalExceptionHandler.java create mode 100644 src/main/java/com/sparta/oneandzerobest/profile/exception/IncorrectPasswordException.java create mode 100644 src/main/java/com/sparta/oneandzerobest/profile/exception/NotFoundUserException.java create mode 100644 src/main/java/com/sparta/oneandzerobest/profile/exception/PasswordPatternException.java create mode 100644 src/main/java/com/sparta/oneandzerobest/profile/service/ProfileService.java diff --git a/src/main/java/com/sparta/oneandzerobest/auth/entity/User.java b/src/main/java/com/sparta/oneandzerobest/auth/entity/User.java index 4759a5c..360270f 100644 --- a/src/main/java/com/sparta/oneandzerobest/auth/entity/User.java +++ b/src/main/java/com/sparta/oneandzerobest/auth/entity/User.java @@ -1,5 +1,6 @@ package com.sparta.oneandzerobest.auth.entity; +import com.sparta.oneandzerobest.profile.dto.ProfileRequestDto; import jakarta.persistence.*; import lombok.Getter; import lombok.NoArgsConstructor; @@ -74,4 +75,14 @@ public boolean isEnabled() { public Collection getAuthorities() { return Collections.emptyList(); // 권한 관련 설정 } + + public void update(ProfileRequestDto requestDto) { + this.name = requestDto.getName(); + this.email = requestDto.getEmail(); + this.introduction = requestDto.getIntroduction(); + } + + public void updatePassword(String password) { + this.password = password; + } } diff --git a/src/main/java/com/sparta/oneandzerobest/profile/controller/ProfileController.java b/src/main/java/com/sparta/oneandzerobest/profile/controller/ProfileController.java new file mode 100644 index 0000000..f0add9c --- /dev/null +++ b/src/main/java/com/sparta/oneandzerobest/profile/controller/ProfileController.java @@ -0,0 +1,26 @@ +package com.sparta.oneandzerobest.profile.controller; + +import com.sparta.oneandzerobest.profile.dto.ProfileRequestDto; +import com.sparta.oneandzerobest.profile.dto.ProfileResponseDto; +import com.sparta.oneandzerobest.profile.service.ProfileService; +import lombok.RequiredArgsConstructor; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.*; + +@RestController +@RequestMapping("/profile") +@RequiredArgsConstructor +public class ProfileController { + + private final ProfileService profileService; + + @GetMapping("/{id}") + public ResponseEntity inquiryProfile(@PathVariable Long id) { + return ResponseEntity.status(200).body(profileService.inquiryProfile(id)); + } + + @PutMapping("/{id}") + public ResponseEntity editProfile(@PathVariable Long id, @RequestBody ProfileRequestDto requestDto) { + return ResponseEntity.status(200).body(profileService.editProfile(id, requestDto)); + } +} diff --git a/src/main/java/com/sparta/oneandzerobest/profile/dto/ProfileRequestDto.java b/src/main/java/com/sparta/oneandzerobest/profile/dto/ProfileRequestDto.java new file mode 100644 index 0000000..a52a5d5 --- /dev/null +++ b/src/main/java/com/sparta/oneandzerobest/profile/dto/ProfileRequestDto.java @@ -0,0 +1,12 @@ +package com.sparta.oneandzerobest.profile.dto; + +import lombok.Getter; + +@Getter +public class ProfileRequestDto { + private String name; + private String email; + private String introduction; + private String password; + private String newPassword; +} diff --git a/src/main/java/com/sparta/oneandzerobest/profile/dto/ProfileResponseDto.java b/src/main/java/com/sparta/oneandzerobest/profile/dto/ProfileResponseDto.java new file mode 100644 index 0000000..5275c7d --- /dev/null +++ b/src/main/java/com/sparta/oneandzerobest/profile/dto/ProfileResponseDto.java @@ -0,0 +1,19 @@ +package com.sparta.oneandzerobest.profile.dto; + +import com.sparta.oneandzerobest.auth.entity.User; +import lombok.Getter; + +@Getter +public class ProfileResponseDto { + private String username; + private String name; + private String introduction; + private String email; + + public ProfileResponseDto(User user) { + this.username = user.getUsername(); + this.name = user.getName(); + this.introduction = user.getIntroduction(); + this.email = user.getEmail(); + } +} diff --git a/src/main/java/com/sparta/oneandzerobest/profile/exception/GlobalExceptionHandler.java b/src/main/java/com/sparta/oneandzerobest/profile/exception/GlobalExceptionHandler.java new file mode 100644 index 0000000..ec969bd --- /dev/null +++ b/src/main/java/com/sparta/oneandzerobest/profile/exception/GlobalExceptionHandler.java @@ -0,0 +1,23 @@ +package com.sparta.oneandzerobest.profile.exception; + +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.ControllerAdvice; +import org.springframework.web.bind.annotation.ExceptionHandler; + +@ControllerAdvice +public class GlobalExceptionHandler { + @ExceptionHandler(NotFoundUserException.class) + public ResponseEntity notFoundUserHandler() { + return ResponseEntity.status(400).body("해당 유저를 찾을 수 없습니다."); + } + + @ExceptionHandler(IncorrectPasswordException.class) + public ResponseEntity incorrectPasswordHandler() { + return ResponseEntity.status(400).body("비밀번호가 맞지 않습니다."); + } + + @ExceptionHandler(PasswordPatternException.class) + public ResponseEntity passwordPatternHandler() { + return ResponseEntity.status(400).body("비밀번호는 최소 10자 이상이며 알파벳 대소문자, 숫자, 특수문자를 포함해야 합니다."); + } +} diff --git a/src/main/java/com/sparta/oneandzerobest/profile/exception/IncorrectPasswordException.java b/src/main/java/com/sparta/oneandzerobest/profile/exception/IncorrectPasswordException.java new file mode 100644 index 0000000..bcadb2e --- /dev/null +++ b/src/main/java/com/sparta/oneandzerobest/profile/exception/IncorrectPasswordException.java @@ -0,0 +1,6 @@ +package com.sparta.oneandzerobest.profile.exception; + +public class IncorrectPasswordException extends RuntimeException { + public IncorrectPasswordException() { + } +} diff --git a/src/main/java/com/sparta/oneandzerobest/profile/exception/NotFoundUserException.java b/src/main/java/com/sparta/oneandzerobest/profile/exception/NotFoundUserException.java new file mode 100644 index 0000000..7fe6c36 --- /dev/null +++ b/src/main/java/com/sparta/oneandzerobest/profile/exception/NotFoundUserException.java @@ -0,0 +1,10 @@ +package com.sparta.oneandzerobest.profile.exception; + +public class NotFoundUserException extends RuntimeException { + public NotFoundUserException() { + } + + public NotFoundUserException(String message) { + super(message); + } +} diff --git a/src/main/java/com/sparta/oneandzerobest/profile/exception/PasswordPatternException.java b/src/main/java/com/sparta/oneandzerobest/profile/exception/PasswordPatternException.java new file mode 100644 index 0000000..3d0f0a9 --- /dev/null +++ b/src/main/java/com/sparta/oneandzerobest/profile/exception/PasswordPatternException.java @@ -0,0 +1,6 @@ +package com.sparta.oneandzerobest.profile.exception; + +public class PasswordPatternException extends RuntimeException { + public PasswordPatternException() { + } +} diff --git a/src/main/java/com/sparta/oneandzerobest/profile/service/ProfileService.java b/src/main/java/com/sparta/oneandzerobest/profile/service/ProfileService.java new file mode 100644 index 0000000..7260550 --- /dev/null +++ b/src/main/java/com/sparta/oneandzerobest/profile/service/ProfileService.java @@ -0,0 +1,51 @@ +package com.sparta.oneandzerobest.profile.service; + +import com.sparta.oneandzerobest.auth.entity.User; +import com.sparta.oneandzerobest.auth.repository.UserRepository; +import com.sparta.oneandzerobest.profile.dto.ProfileRequestDto; +import com.sparta.oneandzerobest.profile.dto.ProfileResponseDto; +import com.sparta.oneandzerobest.profile.exception.IncorrectPasswordException; +import com.sparta.oneandzerobest.profile.exception.NotFoundUserException; +import com.sparta.oneandzerobest.profile.exception.PasswordPatternException; +import lombok.RequiredArgsConstructor; +import org.springframework.security.crypto.password.PasswordEncoder; +import org.springframework.stereotype.Service; + +@Service +@RequiredArgsConstructor +public class ProfileService { + + private final UserRepository userRepository; + private final PasswordEncoder passwordEncoder; + + public ProfileResponseDto inquiryProfile(Long id) { + User user = userRepository.findById(id).orElseThrow( + () -> new NotFoundUserException() + ); + + ProfileResponseDto responseDto = new ProfileResponseDto(user); + return responseDto; + } + + public ProfileResponseDto editProfile(Long id, ProfileRequestDto requestDto) { + User user = userRepository.findById(id).orElseThrow( + () -> new NotFoundUserException() + ); + + if (requestDto.getPassword() != null) { + if (passwordEncoder.matches(requestDto.getPassword(), user.getPassword())) { + if (!requestDto.getNewPassword().matches("^(?=.*[a-zA-Z])(?=.*\\d)(?=.*[!@#$%^&*])[a-zA-Z\\d!@#$%^&*]{10,}$")) { + throw new PasswordPatternException(); + } + user.updatePassword(passwordEncoder.encode(requestDto.getNewPassword())); + } else { + throw new IncorrectPasswordException(); + } + } else { + user.update(requestDto); + } + + ProfileResponseDto responseDto = new ProfileResponseDto(userRepository.save(user)); + return responseDto; + } +} diff --git a/src/main/resources/application.yml b/src/main/resources/application.yml index 0269dc2..e91b4b6 100644 --- a/src/main/resources/application.yml +++ b/src/main/resources/application.yml @@ -5,7 +5,7 @@ spring: url: jdbc:mysql://localhost:3306/siumechu driver-class-name: com.mysql.cj.jdbc.Driver username: root - password: password + password: coals5023! jpa: hibernate: ddl-auto: update From fa87039aab012b981ba905a72c82ecc25f47b903 Mon Sep 17 00:00:00 2001 From: chamcham0707 Date: Wed, 5 Jun 2024 09:59:59 +0900 Subject: [PATCH 2/3] =?UTF-8?q?feat:=20=EA=B0=99=EC=9D=80=20=EB=B9=84?= =?UTF-8?q?=EB=B0=80=EB=B2=88=ED=98=B8=20=EC=98=A4=EB=A5=98=20=EC=B2=98?= =?UTF-8?q?=EB=A6=AC=20=EC=B6=94=EA=B0=80,=20=EC=A3=BC=EC=84=9D=20?= =?UTF-8?q?=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../profile/controller/ProfileController.java | 11 +++++ .../exception/GlobalExceptionHandler.java | 22 +++++++++ .../UnacceptablePasswordException.java | 6 +++ .../profile/service/ProfileService.java | 49 ++++++++++++++----- 4 files changed, 76 insertions(+), 12 deletions(-) create mode 100644 src/main/java/com/sparta/oneandzerobest/profile/exception/UnacceptablePasswordException.java diff --git a/src/main/java/com/sparta/oneandzerobest/profile/controller/ProfileController.java b/src/main/java/com/sparta/oneandzerobest/profile/controller/ProfileController.java index f0add9c..061ab52 100644 --- a/src/main/java/com/sparta/oneandzerobest/profile/controller/ProfileController.java +++ b/src/main/java/com/sparta/oneandzerobest/profile/controller/ProfileController.java @@ -14,11 +14,22 @@ public class ProfileController { private final ProfileService profileService; + /** + * 선택한 프로필을 조회 + * @param id : userId + * @return : body로 유저의 정보 전달 + */ @GetMapping("/{id}") public ResponseEntity inquiryProfile(@PathVariable Long id) { return ResponseEntity.status(200).body(profileService.inquiryProfile(id)); } + /** + * 프로필 수정 + * @param id : userId + * @param requestDto : 수정하고자하는 정보를 body로 받아옴 + * @return : body로 유저의 정보 전달 + */ @PutMapping("/{id}") public ResponseEntity editProfile(@PathVariable Long id, @RequestBody ProfileRequestDto requestDto) { return ResponseEntity.status(200).body(profileService.editProfile(id, requestDto)); diff --git a/src/main/java/com/sparta/oneandzerobest/profile/exception/GlobalExceptionHandler.java b/src/main/java/com/sparta/oneandzerobest/profile/exception/GlobalExceptionHandler.java index ec969bd..8f734df 100644 --- a/src/main/java/com/sparta/oneandzerobest/profile/exception/GlobalExceptionHandler.java +++ b/src/main/java/com/sparta/oneandzerobest/profile/exception/GlobalExceptionHandler.java @@ -6,18 +6,40 @@ @ControllerAdvice public class GlobalExceptionHandler { + + /** + * 해당하는 유저를 찾을 수 없을 때, 클라이언트로 에러 코드와 메시지 반환 + * @return + */ @ExceptionHandler(NotFoundUserException.class) public ResponseEntity notFoundUserHandler() { return ResponseEntity.status(400).body("해당 유저를 찾을 수 없습니다."); } + /** + * 비밀번호가 맞지 않을 때, 클라이언트로 에러 코드와 메시지 반환 + * @return + */ @ExceptionHandler(IncorrectPasswordException.class) public ResponseEntity incorrectPasswordHandler() { return ResponseEntity.status(400).body("비밀번호가 맞지 않습니다."); } + /** + * 비밀번호가 형식이 맞지 않을 때, 클라이언트로 에러 코드와 메시지 반환 + * @return + */ @ExceptionHandler(PasswordPatternException.class) public ResponseEntity passwordPatternHandler() { return ResponseEntity.status(400).body("비밀번호는 최소 10자 이상이며 알파벳 대소문자, 숫자, 특수문자를 포함해야 합니다."); } + + /** + * 비밀번호가 변경이 불가능 할 때, 클라이언트로 에러 코드와 메시지 반환 + * @return + */ + @ExceptionHandler(UnacceptablePasswordException.class) + public ResponseEntity unacceptablePasswordHandler() { + return ResponseEntity.status(400).body("해당 비밀번호로 변경이 불가능합니다. (이전과 동일한 비밀번호로 변경할 수 없습니다.)"); + } } diff --git a/src/main/java/com/sparta/oneandzerobest/profile/exception/UnacceptablePasswordException.java b/src/main/java/com/sparta/oneandzerobest/profile/exception/UnacceptablePasswordException.java new file mode 100644 index 0000000..e587c2a --- /dev/null +++ b/src/main/java/com/sparta/oneandzerobest/profile/exception/UnacceptablePasswordException.java @@ -0,0 +1,6 @@ +package com.sparta.oneandzerobest.profile.exception; + +public class UnacceptablePasswordException extends RuntimeException { + public UnacceptablePasswordException() { + } +} diff --git a/src/main/java/com/sparta/oneandzerobest/profile/service/ProfileService.java b/src/main/java/com/sparta/oneandzerobest/profile/service/ProfileService.java index 7260550..3eadcee 100644 --- a/src/main/java/com/sparta/oneandzerobest/profile/service/ProfileService.java +++ b/src/main/java/com/sparta/oneandzerobest/profile/service/ProfileService.java @@ -7,6 +7,7 @@ import com.sparta.oneandzerobest.profile.exception.IncorrectPasswordException; import com.sparta.oneandzerobest.profile.exception.NotFoundUserException; import com.sparta.oneandzerobest.profile.exception.PasswordPatternException; +import com.sparta.oneandzerobest.profile.exception.UnacceptablePasswordException; import lombok.RequiredArgsConstructor; import org.springframework.security.crypto.password.PasswordEncoder; import org.springframework.stereotype.Service; @@ -18,34 +19,58 @@ public class ProfileService { private final UserRepository userRepository; private final PasswordEncoder passwordEncoder; + /** + * 해당 id를 가진 user의 프로필을 조회해주는 메서드 + * + * @param id : userId + * @return : ProfileResponseDto + */ public ProfileResponseDto inquiryProfile(Long id) { User user = userRepository.findById(id).orElseThrow( () -> new NotFoundUserException() ); - ProfileResponseDto responseDto = new ProfileResponseDto(user); - return responseDto; + return new ProfileResponseDto(user); } + /** + * 프로필을 수정해주는 메서드 + * + * @param id : userId + * @param requestDto : 수정 정보가 담긴 requestDto + * @return : ProfileResponseDto + */ public ProfileResponseDto editProfile(Long id, ProfileRequestDto requestDto) { User user = userRepository.findById(id).orElseThrow( () -> new NotFoundUserException() ); - if (requestDto.getPassword() != null) { - if (passwordEncoder.matches(requestDto.getPassword(), user.getPassword())) { - if (!requestDto.getNewPassword().matches("^(?=.*[a-zA-Z])(?=.*\\d)(?=.*[!@#$%^&*])[a-zA-Z\\d!@#$%^&*]{10,}$")) { - throw new PasswordPatternException(); - } - user.updatePassword(passwordEncoder.encode(requestDto.getNewPassword())); + user.update(requestDto); // 이메일, 이름, 한줄소개 수정 + + if (requestDto.getPassword() != null && !requestDto.getPassword().isEmpty()) { // 비밀번호가 입력되어 있을때만 비밀번호 검사 시작 + if (passwordEncoder.matches(requestDto.getPassword(), user.getPassword())) { // DB에 저장된 비밀번호와 일치하지 않는지 검사 + validationPassword(requestDto, user.getPassword()); // 유효한 비밀번호로 변경하려는지 검사 + user.updatePassword(passwordEncoder.encode(requestDto.getNewPassword())); // 비밀번호 수정 } else { throw new IncorrectPasswordException(); } - } else { - user.update(requestDto); } - ProfileResponseDto responseDto = new ProfileResponseDto(userRepository.save(user)); - return responseDto; + return new ProfileResponseDto(userRepository.save(user)); + } + + /** + * 유효한 비밀번호로 변경하려는지 검사하는 메서드 + * + * @param requestDto : 유저가 입력한 입력한 기존 비밀번호와 새 비밀번호 정보가 담겨있다. + * @param userPassword : 원래 DB에 저장되어 있던 유저의 비밀번호 + */ + private void validationPassword(ProfileRequestDto requestDto, String userPassword) { + if (!requestDto.getNewPassword().matches("^(?=.*[a-zA-Z])(?=.*\\d)(?=.*[!@#$%^&*])[a-zA-Z\\d!@#$%^&*]{10,}$")) { // 비밀번호를 올바른 형식으로 바꾸려는 검사 + if (passwordEncoder.matches(requestDto.getNewPassword(), userPassword)) { // 이전과 같은 비밀번호로 수정하는지 검사 + throw new UnacceptablePasswordException(); + } + throw new PasswordPatternException(); + } } } From a12cf3d249a9db77fda183d463ad3e948d86459f Mon Sep 17 00:00:00 2001 From: chamcham0707 Date: Wed, 5 Jun 2024 10:17:13 +0900 Subject: [PATCH 3/3] =?UTF-8?q?edit:=20DB=20=EB=B9=84=EB=B0=80=EB=B2=88?= =?UTF-8?q?=ED=98=B8=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/resources/application.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/resources/application.yml b/src/main/resources/application.yml index e91b4b6..0269dc2 100644 --- a/src/main/resources/application.yml +++ b/src/main/resources/application.yml @@ -5,7 +5,7 @@ spring: url: jdbc:mysql://localhost:3306/siumechu driver-class-name: com.mysql.cj.jdbc.Driver username: root - password: coals5023! + password: password jpa: hibernate: ddl-auto: update