Merge branch 'master' of https://git.eactive.synology.me:8090/elink/simulator-v2
This commit is contained in:
@@ -0,0 +1,108 @@
|
||||
package com.eactive.testmaster.login.controller;
|
||||
|
||||
import com.eactive.testmaster.common.exception.UserNotFoundException;
|
||||
import com.eactive.testmaster.login.dto.PasswordResetDTO;
|
||||
import com.eactive.testmaster.login.entity.Token;
|
||||
import com.eactive.testmaster.login.service.TokenService;
|
||||
import com.eactive.testmaster.user.service.UserService;
|
||||
import java.time.LocalDateTime;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
|
||||
import org.springframework.stereotype.Controller;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
import org.springframework.ui.Model;
|
||||
import org.springframework.validation.BindingResult;
|
||||
import org.springframework.validation.Validator;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.ModelAttribute;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.RequestParam;
|
||||
|
||||
/**
|
||||
* Created by Sungpil Hyun
|
||||
*/
|
||||
@Controller
|
||||
@ConditionalOnProperty(name = "password.reset.enabled", havingValue = "true")
|
||||
public class PasswordResetController {
|
||||
|
||||
public static final String RESET_PASSWORD = "page/resetPassword";
|
||||
public static final String FORGOT_PASSWORD = "page/forgotPassword";
|
||||
@Autowired
|
||||
private UserService userService;
|
||||
|
||||
@Autowired
|
||||
private TokenService tokenService;
|
||||
|
||||
@Autowired
|
||||
private Validator validator;
|
||||
|
||||
|
||||
@GetMapping(value = "/forgot_password.do")
|
||||
public String forgotPasswordView() {
|
||||
return FORGOT_PASSWORD;
|
||||
}
|
||||
|
||||
/**
|
||||
* 비밀번호 초기화 링크를 생성한다.
|
||||
*
|
||||
* @param email
|
||||
* @param model
|
||||
* @return
|
||||
*/
|
||||
@PostMapping(value = "/forgot_password.do")
|
||||
public String requestPasswordReset(@RequestParam(value = "email", defaultValue = "0") String email,
|
||||
Model model) {
|
||||
try {
|
||||
userService.requestPasswordReset(email);
|
||||
} catch (UserNotFoundException e) {
|
||||
model.addAttribute("error", "존재하지 않는 이메일입니다.");
|
||||
return FORGOT_PASSWORD;
|
||||
} catch (Exception e) {
|
||||
model.addAttribute("error", "비밀번호 초기화 요청에 실패하였습니다.");
|
||||
return FORGOT_PASSWORD;
|
||||
}
|
||||
|
||||
return "redirect:/forgot_password.do?success";
|
||||
}
|
||||
|
||||
@GetMapping("/reset_password.do")
|
||||
public String resetPasswordView(@RequestParam(value = "token", defaultValue = "0") String tokenValue,
|
||||
Model model) {
|
||||
Token token = tokenService.findByToken(tokenValue);
|
||||
|
||||
if (token == null || token.getExpiresAt().isBefore(LocalDateTime.now())) {
|
||||
return "redirect:/forgot_password.do?expired";
|
||||
}
|
||||
|
||||
model.addAttribute("tokenValue", tokenValue);
|
||||
model.addAttribute("passwordReset", new PasswordResetDTO());
|
||||
return RESET_PASSWORD;
|
||||
}
|
||||
|
||||
@PostMapping("/reset_password.do")
|
||||
@Transactional
|
||||
public String resetPassword(@ModelAttribute("passwordResetRequest") PasswordResetDTO passwordReset,
|
||||
BindingResult bindingResult,
|
||||
Model model) {
|
||||
|
||||
Token token = tokenService.findByToken(passwordReset.getToken());
|
||||
|
||||
if (token == null || token.getExpiresAt().isBefore(LocalDateTime.now())) {
|
||||
return "redirect:/forgot_password.do?expired";
|
||||
}
|
||||
|
||||
validator.validate(passwordReset, bindingResult);
|
||||
|
||||
if (bindingResult.hasErrors()) {
|
||||
model.addAttribute("tokenValue", passwordReset.getToken());
|
||||
model.addAttribute("passwordReset", passwordReset);
|
||||
return RESET_PASSWORD;
|
||||
}
|
||||
|
||||
userService.resetPassword(token.getEmail(), passwordReset.getPassword());
|
||||
|
||||
tokenService.deleteToken(token);
|
||||
|
||||
return "redirect:/login";
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
package com.eactive.testmaster.login.dto;
|
||||
|
||||
import com.eactive.testmaster.common.validator.PasswordMatch;
|
||||
import java.io.Serializable;
|
||||
|
||||
@PasswordMatch(input = "password", confirm = "password2")
|
||||
public class PasswordResetDTO implements Serializable {
|
||||
|
||||
private String token;
|
||||
private String password;
|
||||
private String password2;
|
||||
|
||||
public String getToken() {
|
||||
return token;
|
||||
}
|
||||
|
||||
public void setToken(String token) {
|
||||
this.token = token;
|
||||
}
|
||||
|
||||
public String getPassword() {
|
||||
return password;
|
||||
}
|
||||
|
||||
public void setPassword(String password) {
|
||||
this.password = password;
|
||||
}
|
||||
|
||||
public String getPassword2() {
|
||||
return password2;
|
||||
}
|
||||
|
||||
public void setPassword2(String password2) {
|
||||
this.password2 = password2;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,54 @@
|
||||
package com.eactive.testmaster.login.entity;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.time.LocalDateTime;
|
||||
import javax.persistence.Column;
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.Id;
|
||||
import javax.persistence.Table;
|
||||
|
||||
@Entity
|
||||
@Table(name = "PT_TOKEN")
|
||||
public class Token implements Serializable {
|
||||
|
||||
public Token(String tokenValue, String email, LocalDateTime expiresAt) {
|
||||
this.tokenValue = tokenValue;
|
||||
this.email = email;
|
||||
this.expiresAt = expiresAt;
|
||||
}
|
||||
|
||||
public Token() {
|
||||
}
|
||||
|
||||
@Id
|
||||
@Column(name = "TOKEN")
|
||||
private String tokenValue;
|
||||
|
||||
private String email;
|
||||
|
||||
private LocalDateTime expiresAt;
|
||||
|
||||
public String getTokenValue() {
|
||||
return tokenValue;
|
||||
}
|
||||
|
||||
public void setTokenValue(String tokenValue) {
|
||||
this.tokenValue = tokenValue;
|
||||
}
|
||||
|
||||
public String getEmail() {
|
||||
return email;
|
||||
}
|
||||
|
||||
public void setEmail(String email) {
|
||||
this.email = email;
|
||||
}
|
||||
|
||||
public LocalDateTime getExpiresAt() {
|
||||
return expiresAt;
|
||||
}
|
||||
|
||||
public void setExpiresAt(LocalDateTime expiresAt) {
|
||||
this.expiresAt = expiresAt;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
package com.eactive.testmaster.login.repository;
|
||||
|
||||
import com.eactive.testmaster.login.entity.Token;
|
||||
import org.springframework.data.jpa.repository.JpaRepository;
|
||||
|
||||
public interface TokenRepository extends JpaRepository<Token, String> {
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
package com.eactive.testmaster.login.service;
|
||||
|
||||
import com.eactive.testmaster.login.entity.Token;
|
||||
import com.eactive.testmaster.login.repository.TokenRepository;
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.UUID;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
@Service
|
||||
@Transactional
|
||||
public class TokenService {
|
||||
|
||||
@Autowired
|
||||
private TokenRepository tokenRepository;
|
||||
|
||||
public Token createToken(String email) {
|
||||
String token = UUID.randomUUID().toString();
|
||||
LocalDateTime expiresAt = LocalDateTime.now().plusHours(24);
|
||||
Token tokenObj = new Token(token, email, expiresAt);
|
||||
return tokenRepository.save(tokenObj);
|
||||
}
|
||||
|
||||
public Token findByToken(String token) {
|
||||
return tokenRepository.findById(token).orElse(null);
|
||||
}
|
||||
|
||||
public void deleteToken(Token token) {
|
||||
tokenRepository.delete(token);
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,7 @@
|
||||
package com.eactive.testmaster.user.controller;
|
||||
|
||||
import com.eactive.testmaster.common.util.SecurityUtil;
|
||||
import com.eactive.testmaster.user.dto.StaffPasswordChangeRequestDTO;
|
||||
import com.eactive.testmaster.user.dto.UserRegisterDTO;
|
||||
import com.eactive.testmaster.user.dto.UserSearch;
|
||||
import com.eactive.testmaster.user.dto.UserUpdateDTO;
|
||||
@@ -25,8 +26,9 @@ import org.springframework.web.bind.annotation.RequestParam;
|
||||
@RequestMapping("/mgmt/users")
|
||||
public class UserMgmtController {
|
||||
|
||||
public static final String STAFF_USER_EDIT = "page/users/staffUserEdit";
|
||||
public static final String USERS_LIST_VIEW = "redirect:/mgmt/users/list_view.do";
|
||||
private static final String STAFF_USER_EDIT = "page/users/staffUserEdit";
|
||||
private static final String USERS_LIST_VIEW = "redirect:/mgmt/users/list_view.do";
|
||||
private static final String STAFF_PASSWORD_RESET_VIEW = "page/users/staffPasswordReset";
|
||||
|
||||
private final StaffUserService staffUserService;
|
||||
|
||||
@@ -129,4 +131,23 @@ public class UserMgmtController {
|
||||
return USERS_LIST_VIEW;
|
||||
}
|
||||
|
||||
@PostMapping("/staff_password_reset_view.do")
|
||||
public String staffPasswordReset(@ModelAttribute("passwordChangeRequest") StaffPasswordChangeRequestDTO passwordChangeRequestDTO) {
|
||||
StaffUser found = staffUserService.findById(passwordChangeRequestDTO.getId());
|
||||
passwordChangeRequestDTO.setUsername(found.getUsername());
|
||||
return STAFF_PASSWORD_RESET_VIEW;
|
||||
}
|
||||
|
||||
@PostMapping("/update_staff_password.do")
|
||||
public String updateStaffPassword(@ModelAttribute("passwordChangeRequest") StaffPasswordChangeRequestDTO passwordChangeRequestDTO,
|
||||
BindingResult bindingResult) {
|
||||
|
||||
validator.validate(passwordChangeRequestDTO, bindingResult);
|
||||
if (bindingResult.hasErrors()) {
|
||||
return STAFF_PASSWORD_RESET_VIEW;
|
||||
}
|
||||
staffUserService.updatePassword(passwordChangeRequestDTO.getId(), passwordChangeRequestDTO.getNewPassword());
|
||||
return USERS_LIST_VIEW;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,51 @@
|
||||
package com.eactive.testmaster.user.dto;
|
||||
|
||||
import com.eactive.testmaster.common.validator.PasswordMatch;
|
||||
import javax.validation.constraints.NotEmpty;
|
||||
|
||||
@PasswordMatch(input = "newPassword", confirm = "newPassword2")
|
||||
public class StaffPasswordChangeRequestDTO {
|
||||
|
||||
@NotEmpty(message = "{field.required}")
|
||||
private String id;
|
||||
|
||||
private String username;
|
||||
|
||||
@NotEmpty(message = "{field.required}")
|
||||
private String newPassword;
|
||||
|
||||
@NotEmpty(message = "{field.required}")
|
||||
private String newPassword2;
|
||||
|
||||
public String getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(String id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public String getUsername() {
|
||||
return username;
|
||||
}
|
||||
|
||||
public void setUsername(String username) {
|
||||
this.username = username;
|
||||
}
|
||||
|
||||
public String getNewPassword() {
|
||||
return newPassword;
|
||||
}
|
||||
|
||||
public void setNewPassword(String newPassword) {
|
||||
this.newPassword = newPassword;
|
||||
}
|
||||
|
||||
public String getNewPassword2() {
|
||||
return newPassword2;
|
||||
}
|
||||
|
||||
public void setNewPassword2(String newPassword2) {
|
||||
this.newPassword2 = newPassword2;
|
||||
}
|
||||
}
|
||||
@@ -62,7 +62,15 @@ public class StaffUserService {
|
||||
|
||||
staffUserRepository.save(user);
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
public void updatePassword(String id, String newPassword) {
|
||||
StaffUser user = staffUserRepository.findById(id).orElseThrow(() -> new UserNotFoundException(USER_NOT_FOUND_MESSAGE));
|
||||
user.setUserSecurity(newPassword);
|
||||
user.setLockAt(EnabledStatus.N);
|
||||
user.setLockCnt(0);
|
||||
user.setLastLockDate(null);
|
||||
staffUserRepository.save(user);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -3,10 +3,17 @@ package com.eactive.testmaster.user.service;
|
||||
import com.eactive.testmaster.common.entity.EnabledStatus;
|
||||
import com.eactive.testmaster.common.exception.UserNotFoundException;
|
||||
import com.eactive.testmaster.common.util.EncryptionUtil;
|
||||
import com.eactive.testmaster.login.entity.Token;
|
||||
import com.eactive.testmaster.login.service.TokenService;
|
||||
import com.eactive.testmaster.user.entity.StaffUser;
|
||||
import com.eactive.testmaster.user.entity.User;
|
||||
import com.eactive.testmaster.user.repository.StaffUserRepository;
|
||||
import java.time.LocalDateTime;
|
||||
import java.time.format.DateTimeFormatter;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.security.core.userdetails.UserDetails;
|
||||
import org.springframework.security.core.userdetails.UserDetailsService;
|
||||
@@ -17,14 +24,23 @@ import org.springframework.stereotype.Service;
|
||||
//@Transactional(propagation = Propagation.NESTED)
|
||||
public class UserService implements UserDetailsService {
|
||||
|
||||
private static final Logger logger = LoggerFactory.getLogger(UserService.class);
|
||||
|
||||
|
||||
public static final String USER_NOT_FOUND_MESSAGE = "사용자 정보가 존재하지 않습니다.";
|
||||
|
||||
@Autowired
|
||||
StaffUserRepository staffUserRepository;
|
||||
private final StaffUserRepository staffUserRepository;
|
||||
|
||||
@Autowired
|
||||
private EncryptionUtil encryptionUtil;
|
||||
|
||||
private final TokenService tokenService;
|
||||
|
||||
public UserService(StaffUserRepository staffUserRepository, EncryptionUtil encryptionUtil, TokenService tokenService) {
|
||||
this.staffUserRepository = staffUserRepository;
|
||||
this.encryptionUtil = encryptionUtil;
|
||||
this.tokenService = tokenService;
|
||||
}
|
||||
|
||||
@Override
|
||||
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
|
||||
try {
|
||||
@@ -65,6 +81,25 @@ public class UserService implements UserDetailsService {
|
||||
staffUserRepository.save((StaffUser) user);
|
||||
}
|
||||
|
||||
public void requestPasswordReset(String email) {
|
||||
|
||||
Token token = tokenService.createToken(email);
|
||||
Map<String, Object> params = new HashMap<>();
|
||||
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
|
||||
String formattedDateTime = token.getExpiresAt().format(formatter);
|
||||
|
||||
params.put("userId", email);
|
||||
params.put("token", token.getTokenValue());
|
||||
params.put("expiresAt", formattedDateTime);
|
||||
|
||||
logger.info("requestPasswordReset::params= {}", params);
|
||||
}
|
||||
|
||||
public void resetPassword(String email, String newPassword) {
|
||||
User user = findByUserId(email);
|
||||
updatePassword(user, newPassword);
|
||||
}
|
||||
|
||||
public void updateUser(User user) {
|
||||
staffUserRepository.save((StaffUser) user);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user