[Practice] 사용자 API 만들기 (11)
2021. 4. 14. 13:15ㆍSpring/Practice
1. 문제
- 사용자 비밀번호 초기화 요청 (아이디 입력 후 전화번호로 문자 전송)의 API
- 아이디에 대한 정보 조회
- 비밀번호를 초기화 후 이를 문자 전송 로직 호출
- 초기화 비밀번호는 문자열 10자로 설정
2. 풀이
- ApiUserController.java
package com.example.jpa.sample.user.controller;
import com.example.jpa.sample.notice.entity.Notice;
import com.example.jpa.sample.notice.model.NoticeResponse;
import com.example.jpa.sample.notice.model.ResponseError;
import com.example.jpa.sample.notice.repository.NoticeRepository;
import com.example.jpa.sample.user.entity.User;
import com.example.jpa.sample.user.exception.ExistsEmailException;
import com.example.jpa.sample.user.exception.PasswordNotMatchException;
import com.example.jpa.sample.user.exception.UserNotFoundException;
import com.example.jpa.sample.user.model.*;
import com.example.jpa.sample.user.repository.UserRepository;
import lombok.RequiredArgsConstructor;
import org.springframework.dao.DataIntegrityViolationException;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.validation.Errors;
import org.springframework.validation.FieldError;
import org.springframework.web.bind.annotation.*;
import javax.validation.Valid;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;
@RequiredArgsConstructor
@RestController
public class ApiUserController {
private final UserRepository userRepository;
private final NoticeRepository noticeRepository;
/*
// 문제 1
@PostMapping("/api/user")
public ResponseEntity<?> addUser(@RequestBody @Valid UserInput userInput, Errors errors) {
List<ResponseError> responseErrorList = new ArrayList<>();
if(errors.hasErrors()) {
errors.getAllErrors().forEach(e -> {
responseErrorList.add(ResponseError.of((FieldError)e));
});
return new ResponseEntity<>(responseErrorList, HttpStatus.BAD_REQUEST);
}
// return ResponseEntity.ok().build();
return new ResponseEntity<>(HttpStatus.OK);
}
*/
/*
// 문제 2
@PostMapping("/api/user")
public ResponseEntity<?> addUser(@RequestBody @Valid UserInput userInput, Errors errors) {
List<ResponseError> responseErrorList = new ArrayList<>();
if(errors.hasErrors()) {
errors.getAllErrors().forEach(e -> {
responseErrorList.add(ResponseError.of((FieldError)e));
});
return new ResponseEntity<>(responseErrorList, HttpStatus.BAD_REQUEST);
}
userRepository.save(User.builder()
.email(userInput.getEmail())
.name(userInput.getName())
.password(userInput.getPassword())
.phone(userInput.getPhone())
.regDate(LocalDateTime.now())
.build()
);
return new ResponseEntity<>(HttpStatus.OK);
}
*/
@ExceptionHandler(UserNotFoundException.class)
public ResponseEntity<?> handlerUserNotFoundException(UserNotFoundException exception) {
return new ResponseEntity<>(exception.getMessage(), HttpStatus.BAD_REQUEST);
}
// 문제 3
@PutMapping("/api/user/{id}")
public ResponseEntity<?> updateUser(@PathVariable Long id, @RequestBody @Valid UserUpdate userUpdate, Errors errors) {
List<ResponseError> responseErrorList = new ArrayList<>();
if(errors.hasErrors()) {
errors.getAllErrors().forEach(e -> {
responseErrorList.add(ResponseError.of((FieldError)e));
});
return new ResponseEntity<>(responseErrorList, HttpStatus.BAD_REQUEST);
}
User user = userRepository.findById(id).orElseThrow(() -> new UserNotFoundException("사용자 정보가 없습니다."));
user.setPhone(userUpdate.getPhone());
user.setUpdateDate(LocalDateTime.now());
userRepository.save(user);
return ResponseEntity.ok().build();
}
// 문제 4
@GetMapping("/api/user/{id}")
public UserResponse getUser(@PathVariable Long id) {
User user = userRepository.findById(id).orElseThrow(() -> new UserNotFoundException("사용자 정보가 없습니다."));
// UserResponse userResponse = new UserResponse(user);
UserResponse userResponse = UserResponse.of(user);
return userResponse;
}
// 문제 5
@GetMapping("/api/user/{id}/notice")
public List<NoticeResponse> userNotice(@PathVariable Long id) {
User user = userRepository.findById(id).orElseThrow(() -> new UserNotFoundException("사용자 정보가 없습니다."));
List<Notice> noticeList = noticeRepository.findByUser(user);
List<NoticeResponse> noticeResponsesList = new ArrayList<>();
noticeList.stream().forEach(e -> {
noticeResponsesList.add(NoticeResponse.of(e));
});
return noticeResponsesList;
}
@ExceptionHandler(value = {ExistsEmailException.class, PasswordNotMatchException.class})
public ResponseEntity<?> handlerExistsEmailException(RuntimeException exception) {
return new ResponseEntity<>(exception.getMessage(), HttpStatus.BAD_REQUEST);
}
/*
// 문제 6
@PostMapping("/api/user")
public ResponseEntity<?> addUser(@RequestBody @Valid UserInput userInput, Errors errors) {
List<ResponseError> responseErrorList = new ArrayList<>();
if(errors.hasErrors()) {
errors.getAllErrors().forEach(e -> {
responseErrorList.add(ResponseError.of((FieldError)e));
});
return new ResponseEntity<>(responseErrorList, HttpStatus.BAD_REQUEST);
}
if(userRepository.countByEmail(userInput.getEmail()) > 0) {
throw new ExistsEmailException("이미 가입된 이메일이 존재합니다.");
}
userRepository.save(User.builder()
.email(userInput.getEmail())
.name(userInput.getName())
.password(userInput.getPassword())
.phone(userInput.getPhone())
.regDate(LocalDateTime.now())
.build()
);
return new ResponseEntity<>(HttpStatus.OK);
}
*/
// 문제 7
@PatchMapping("/api/user/{id}/password")
public ResponseEntity<?> updateUserPassword(@PathVariable Long id, @RequestBody @Valid UserInputPassword userInputPassword, Errors errors) {
List<ResponseError> responseErrorList = new ArrayList<>();
if(errors.hasErrors()) {
errors.getAllErrors().forEach(e -> {
responseErrorList.add(ResponseError.of((FieldError)e));
});
return new ResponseEntity<>(responseErrorList, HttpStatus.BAD_REQUEST);
}
User user = userRepository.findByIdAndPassword(id, userInputPassword.getPassword()).orElseThrow(() -> new PasswordNotMatchException("비밀번호가 일치하지 않습니다."));
user.setPassword(userInputPassword.getNewPassword());
userRepository.save(user);
return ResponseEntity.ok().build();
}
private String getEncyrptPassword(String password) {
BCryptPasswordEncoder bCryptPasswordEncoder = new BCryptPasswordEncoder();
String encryptedPassword = bCryptPasswordEncoder.encode(password);
return encryptedPassword;
}
// 문제 8
@PostMapping("/api/user")
public ResponseEntity<?> addUser(@RequestBody @Valid UserInput userInput, Errors errors) {
List<ResponseError> responseErrorList = new ArrayList<>();
if(errors.hasErrors()) {
errors.getAllErrors().forEach(e -> {
responseErrorList.add(ResponseError.of((FieldError)e));
});
return new ResponseEntity<>(responseErrorList, HttpStatus.BAD_REQUEST);
}
if(userRepository.countByEmail(userInput.getEmail()) > 0) {
throw new ExistsEmailException("이미 가입된 이메일이 존재합니다.");
}
userRepository.save(User.builder()
.email(userInput.getEmail())
.name(userInput.getName())
.password(getEncyrptPassword(userInput.getPassword()))
.phone(userInput.getPhone())
.regDate(LocalDateTime.now())
.build()
);
return new ResponseEntity<>(HttpStatus.OK);
}
// 문제 9
@DeleteMapping("/api/user/{id}")
public ResponseEntity<?> deleteUser(@PathVariable Long id) {
User user = userRepository.findById(id).orElseThrow(() -> new UserNotFoundException("사용자 정보가 없습니다."));
try {
userRepository.delete(user);
} catch (DataIntegrityViolationException e) {
String message = "제약조건에 문제가 발생했습니다.";
return new ResponseEntity<>(message, HttpStatus.BAD_REQUEST);
} catch (Exception e) {
String message = "회원탈퇴 중 문제가 발생했습니다.";
return new ResponseEntity<>(message, HttpStatus.BAD_REQUEST);
}
return ResponseEntity.ok().build();
}
// 문제 10
@GetMapping("/api/user")
public ResponseEntity<?> findUser(@RequestBody UserInputFind userInputFind) {
User user = userRepository.findByNameAndPhone(userInputFind.getName(), userInputFind.getPhone())
.orElseThrow(() -> new UserNotFoundException("사용자 정보가 없습니다."));
UserResponse userResponse = UserResponse.of(user);
return ResponseEntity.ok().body(userResponse);
}
private String getResetpassword() {
return UUID.randomUUID().toString().replaceAll("-", "").substring(0, 10);
}
private void sendSMS(String message) {
System.out.println("[문자메시지전송]\n" + message);
}
// 문제 11
@GetMapping("/api/user/{id}/password/reset")
public ResponseEntity<?> resetUserPassword(@PathVariable Long id) {
User user = userRepository.findById(id).orElseThrow(() -> new UserNotFoundException("사용자 정보가 없습니다."));
String resetPassword = getResetpassword();
String resetEncryptPassword = getEncyrptPassword(resetPassword);
user.setPassword(resetEncryptPassword);
userRepository.save(user);
// 문자 전송
String message = String.format("[%s]님의 임시 비밀번호가 [%s]로 초기화 되었습니다.", user.getName(), resetPassword);
sendSMS(message);
return ResponseEntity.ok().build();
}
}
728x90
'Spring > Practice' 카테고리의 다른 글
[Practice] 사용자 API 만들기 (13) (0) | 2021.04.14 |
---|---|
[Practice] 사용자 API 만들기 (12) (0) | 2021.04.14 |
[Practice] 사용자 API 만들기 (10) (0) | 2021.04.14 |
[Practice] 사용자 API 만들기 (9) (0) | 2021.04.14 |