Skip to content

Commit

Permalink
Merge pull request #59 from mju-likelion/feature/user-update-#58
Browse files Browse the repository at this point in the history
Feature/#58 회원 정보 수정 및 탈퇴 기능
  • Loading branch information
rnqhstmd authored Jul 28, 2024
2 parents c087ab5 + 0fe7d63 commit af7fecd
Show file tree
Hide file tree
Showing 5 changed files with 98 additions and 3 deletions.
Original file line number Diff line number Diff line change
@@ -1,16 +1,17 @@
package com.example.mutsideout_mju.controller;

import com.example.mutsideout_mju.authentication.AuthenticatedUser;
import com.example.mutsideout_mju.dto.request.user.DeleteUserDto;
import com.example.mutsideout_mju.dto.request.user.UpdateUserDto;
import com.example.mutsideout_mju.dto.response.ResponseDto;
import com.example.mutsideout_mju.dto.response.user.UserGradeResponseDto;
import com.example.mutsideout_mju.entity.User;
import com.example.mutsideout_mju.service.UserService;
import jakarta.validation.Valid;
import lombok.RequiredArgsConstructor;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.bind.annotation.*;

@RestController
@RequiredArgsConstructor
Expand All @@ -23,4 +24,18 @@ public ResponseEntity<ResponseDto<UserGradeResponseDto>> getUserGrade(@Authentic
UserGradeResponseDto userGradeResponseDto = userService.getUserGrade(user);
return new ResponseEntity<>(ResponseDto.res(HttpStatus.OK, "유저 등급 조회 완료", userGradeResponseDto), HttpStatus.OK);
}

@PatchMapping
public ResponseEntity<ResponseDto<UserGradeResponseDto>> updateUser(@AuthenticatedUser User user,
@RequestBody @Valid UpdateUserDto updateUserDto) {
userService.updateUser(user, updateUserDto);
return new ResponseEntity<>(ResponseDto.res(HttpStatus.OK, "유저 정보 수정 완료"), HttpStatus.OK);
}

@DeleteMapping
public ResponseEntity<ResponseDto<UserGradeResponseDto>> deleteUser(@AuthenticatedUser User user,
@RequestBody @Valid DeleteUserDto deleteUserDto) {
userService.deleteUser(user, deleteUserDto);
return new ResponseEntity<>(ResponseDto.res(HttpStatus.OK, "회원 탈퇴 성공"), HttpStatus.OK);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package com.example.mutsideout_mju.dto.request.user;

import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.Pattern;
import jakarta.validation.constraints.Size;
import lombok.Getter;

@Getter
public class DeleteUserDto {
@NotBlank(message = "비밀번호를 입력해주세요.")
@Pattern(regexp = "^(?=.*[A-Za-z])(?=.*\\d)(?=.*[!@#$%^&*()])[A-Za-z\\d!@#$%^&*()]{8,20}$", message = "비밀번호는 영문과 숫자,특수기호를 조합하여 8~20글자 미만으로 입력해주세요.")
@Size(min = 8, max = 20, message = "비밀번호는 최소 8자에서 최대 20자까지 입력 가능합니다.")
private String password;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package com.example.mutsideout_mju.dto.request.user;

import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.Pattern;
import jakarta.validation.constraints.Size;
import lombok.Getter;

@Getter
public class UpdateUserDto {
@Size(min = 1, max = 10, message = "이름은 최소 1자에서 최대 10자까지 입력 가능합니다.")
private String newName;

@NotBlank(message = "기존 비밀번호를 입력해주세요.")
@Pattern(regexp = "^(?=.*[A-Za-z])(?=.*\\d)(?=.*[!@#$%^&*()])[A-Za-z\\d!@#$%^&*()]{8,20}$", message = "비밀번호는 영문과 숫자,특수기호를 조합하여 8~20글자 미만으로 입력해주세요.")
@Size(min = 8, max = 20, message = "비밀번호는 최소 8자에서 최대 20자까지 입력 가능합니다.")
private String originPassword;

@Pattern(regexp = "^(?=.*[A-Za-z])(?=.*\\d)(?=.*[!@#$%^&*()])[A-Za-z\\d!@#$%^&*()]{8,20}$", message = "비밀번호는 영문과 숫자,특수기호를 조합하여 8~20글자 미만으로 입력해주세요.")
@Size(min = 8, max = 20, message = "비밀번호는 최소 8자에서 최대 20자까지 입력 가능합니다.")
private String newPassword;
}
8 changes: 8 additions & 0 deletions src/main/java/com/example/mutsideout_mju/entity/User.java
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,14 @@ public void setUserGrade(Grade userGrade) {
this.userGrade = userGrade;
}

public void setName(String name) {
this.name = name;
}

public void setPassword(String password) {
this.password = password;
}

public Grade determineGrade(long count) {
if (count >= 4) {
return Grade.TOMATO;
Expand Down
37 changes: 37 additions & 0 deletions src/main/java/com/example/mutsideout_mju/service/UserService.java
Original file line number Diff line number Diff line change
@@ -1,10 +1,16 @@
package com.example.mutsideout_mju.service;

import com.example.mutsideout_mju.authentication.PasswordHashEncryption;
import com.example.mutsideout_mju.dto.request.user.DeleteUserDto;
import com.example.mutsideout_mju.dto.request.user.UpdateUserDto;
import com.example.mutsideout_mju.dto.response.user.UserGradeResponseDto;
import com.example.mutsideout_mju.entity.Grade;
import com.example.mutsideout_mju.entity.SurveyOption;
import com.example.mutsideout_mju.entity.User;
import com.example.mutsideout_mju.entity.UserSurvey;
import com.example.mutsideout_mju.exception.ConflictException;
import com.example.mutsideout_mju.exception.ForbiddenException;
import com.example.mutsideout_mju.exception.errorCode.ErrorCode;
import com.example.mutsideout_mju.repository.UserRepository;
import com.example.mutsideout_mju.repository.UserSurveyRepository;
import lombok.RequiredArgsConstructor;
Expand All @@ -18,6 +24,7 @@
public class UserService {
private final UserRepository userRepository;
private final UserSurveyRepository userSurveyRepository;
private final PasswordHashEncryption passwordHashEncryption;

@Transactional
public UserGradeResponseDto calculateUserGrade(User user) {
Expand Down Expand Up @@ -45,4 +52,34 @@ public static boolean isValidSurveyOption(UserSurvey userSurvey) {
return (questionNumber >= 1 && questionNumber <= 3 && (option == SurveyOption.NORMAL || option == SurveyOption.YES))
|| (questionNumber >= 4 && questionNumber <= 6 && option == SurveyOption.YES);
}

//회원 탈퇴
public void deleteUser(User user, DeleteUserDto deleteUserDto) {
validatePassword(deleteUserDto.getPassword(), user.getPassword());
userRepository.delete(user);
}

//회원 정보 수정
@Transactional
public void updateUser(User user, UpdateUserDto updateUserDto) {
validatePassword(updateUserDto.getOriginPassword(), user.getPassword());
if (updateUserDto.getNewName() != null && !updateUserDto.getNewName().isEmpty()) {
//중복된 이름이 있을 경우
if (userRepository.findByName(updateUserDto.getNewName()).isPresent()) {
throw new ConflictException(ErrorCode.DUPLICATED_NAME);
}
user.setName(updateUserDto.getNewName());
}
if (updateUserDto.getNewPassword() != null && !updateUserDto.getNewPassword().isEmpty()) {
user.setPassword(passwordHashEncryption.encrypt(updateUserDto.getNewPassword()));
}
userRepository.save(user);
}

//비밀번호 일치 여부 확인
public void validatePassword(String plainPassword, String hashedPassword) {
if (!passwordHashEncryption.matches(plainPassword, hashedPassword)) {
throw new ForbiddenException(ErrorCode.NO_ACCESS, "비밀번호 정보가 일치하지 않습니다.");
}
}
}

0 comments on commit af7fecd

Please sign in to comment.