From 4f1a8e9c5e80aaccfceacda88e77841c5f988ea3 Mon Sep 17 00:00:00 2001 From: Sebastien Date: Wed, 6 Jun 2018 19:30:19 +0200 Subject: [PATCH] Create all internal methods for reset password, missing API routes --- .../DB/Entity/PendingPwdResetEntity.java | 58 +++++++++++++++++ .../Repository/PendingPwdResetRepository.java | 11 ++++ .../RestApi/UserManagerAPIController.java | 16 +++-- .../Tools/UserManager/PasswordResetUtils.java | 64 +++++++++++++++++++ .../Broken/Tools/UserManager/UserUtils.java | 2 +- 5 files changed, 146 insertions(+), 5 deletions(-) create mode 100644 src/main/java/net/Broken/DB/Entity/PendingPwdResetEntity.java create mode 100644 src/main/java/net/Broken/DB/Repository/PendingPwdResetRepository.java create mode 100644 src/main/java/net/Broken/Tools/UserManager/PasswordResetUtils.java diff --git a/src/main/java/net/Broken/DB/Entity/PendingPwdResetEntity.java b/src/main/java/net/Broken/DB/Entity/PendingPwdResetEntity.java new file mode 100644 index 0000000..6bd2cfa --- /dev/null +++ b/src/main/java/net/Broken/DB/Entity/PendingPwdResetEntity.java @@ -0,0 +1,58 @@ +package net.Broken.DB.Entity; + +import javax.persistence.Entity; +import javax.persistence.GeneratedValue; +import javax.persistence.GenerationType; +import javax.persistence.Id; +import java.util.Calendar; +import java.util.Date; + + +@Entity +public class PendingPwdResetEntity { + @Id + @GeneratedValue(strategy= GenerationType.AUTO) + private Integer id; + + private UserEntity userEntity; + private String securityToken; + private Date expirationDate; + + + public PendingPwdResetEntity(UserEntity userEntity,String token) { + this.userEntity = userEntity; + this.securityToken = token; + Calendar cal = Calendar.getInstance(); + cal.setTime(new Date()); + cal.add(Calendar.HOUR, 24); + expirationDate = cal.getTime(); + + } + + public PendingPwdResetEntity() {} + + + public UserEntity getUserEntity() { + return userEntity; + } + + public void setUserEntity(UserEntity userEntity) { + this.userEntity = userEntity; + } + + public String getSecurityToken() { + return securityToken; + } + + public void setSecurityToken(String securityToken) { + this.securityToken = securityToken; + } + + public Date getExpirationDate() { + return expirationDate; + } + + public void setExpirationDate(Date expirationDate) { + this.expirationDate = expirationDate; + } +} diff --git a/src/main/java/net/Broken/DB/Repository/PendingPwdResetRepository.java b/src/main/java/net/Broken/DB/Repository/PendingPwdResetRepository.java new file mode 100644 index 0000000..fee4b68 --- /dev/null +++ b/src/main/java/net/Broken/DB/Repository/PendingPwdResetRepository.java @@ -0,0 +1,11 @@ +package net.Broken.DB.Repository; + +import net.Broken.DB.Entity.PendingPwdResetEntity; +import net.Broken.DB.Entity.UserEntity; +import org.springframework.data.repository.CrudRepository; + +import java.util.List; + +public interface PendingPwdResetRepository extends CrudRepository{ + List findByUserEntity(UserEntity userEntity); +} diff --git a/src/main/java/net/Broken/RestApi/UserManagerAPIController.java b/src/main/java/net/Broken/RestApi/UserManagerAPIController.java index 2d16375..dae025c 100644 --- a/src/main/java/net/Broken/RestApi/UserManagerAPIController.java +++ b/src/main/java/net/Broken/RestApi/UserManagerAPIController.java @@ -29,17 +29,23 @@ import java.util.List; @RequestMapping("/api/userManagement") public class UserManagerAPIController { Logger logger = LogManager.getLogger(); - @Autowired + final PendingUserRepository pendingUserRepository; - @Autowired + final UserRepository userRepository; - @Autowired - private PasswordEncoder passwordEncoder; + private final PasswordEncoder passwordEncoder; UserUtils userUtils = UserUtils.getInstance(); + @Autowired + public UserManagerAPIController(PendingUserRepository pendingUserRepository, UserRepository userRepository, PasswordEncoder passwordEncoder) { + this.pendingUserRepository = pendingUserRepository; + this.userRepository = userRepository; + this.passwordEncoder = passwordEncoder; + } + @RequestMapping(value = "/preRegister", method = RequestMethod.POST) public ResponseEntity command(@RequestBody UserInfoData data){ @@ -114,4 +120,6 @@ public class UserManagerAPIController { } + + } diff --git a/src/main/java/net/Broken/Tools/UserManager/PasswordResetUtils.java b/src/main/java/net/Broken/Tools/UserManager/PasswordResetUtils.java new file mode 100644 index 0000000..e5a5a57 --- /dev/null +++ b/src/main/java/net/Broken/Tools/UserManager/PasswordResetUtils.java @@ -0,0 +1,64 @@ +package net.Broken.Tools.UserManager; + +import net.Broken.DB.Entity.PendingPwdResetEntity; +import net.Broken.DB.Entity.UserEntity; +import net.Broken.DB.Repository.PendingPwdResetRepository; +import net.Broken.DB.Repository.UserRepository; +import net.Broken.SpringContext; +import net.Broken.Tools.UserManager.Exceptions.TokenNotMatch; +import net.Broken.Tools.UserManager.Exceptions.UserNotFoundException; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; +import org.springframework.context.ApplicationContext; +import org.springframework.security.crypto.password.PasswordEncoder; + +import java.util.List; + +public class PasswordResetUtils { + private Logger logger = LogManager.getLogger(); + private PasswordEncoder passwordEncoder; + private PendingPwdResetRepository pendingPwdResetRepository; + private UserRepository userRepository; + + private static PasswordResetUtils INSTANCE = new PasswordResetUtils(); + + /** + * Private default constructor + */ + private PasswordResetUtils(){ + ApplicationContext context = SpringContext.getAppContext(); + passwordEncoder = (PasswordEncoder) context.getBean("passwordEncoder"); + pendingPwdResetRepository = (PendingPwdResetRepository) context.getBean("pendingPwdResetRepository"); + userRepository = (UserRepository) context.getBean("userRepository"); + } + + + /** + * Singleton + * @return Unique PasswordResetUtils instance + */ + public static PasswordResetUtils getInstance(){ + return INSTANCE; + } + + public String resetRequest(UserEntity userEntity){ + String token = UserUtils.getInstance().generateCheckToken(); + String encodedToken = passwordEncoder.encode(token); + PendingPwdResetEntity entity = new PendingPwdResetEntity(userEntity, encodedToken); + pendingPwdResetRepository.save(entity); + return encodedToken; + } + + public void changePass(UserEntity userEntity, String token, String newPassword) throws UserNotFoundException, TokenNotMatch { + List dbResults = pendingPwdResetRepository.findByUserEntity(userEntity); + if(dbResults.size() == 0) + throw new UserNotFoundException(); + PendingPwdResetEntity pendingPwdReset = dbResults.get(0); + if(!passwordEncoder.matches(token, pendingPwdReset.getSecurityToken())) + throw new TokenNotMatch(); + + userEntity.setPassword(passwordEncoder.encode(newPassword)); + userRepository.save(userEntity); + } + +} diff --git a/src/main/java/net/Broken/Tools/UserManager/UserUtils.java b/src/main/java/net/Broken/Tools/UserManager/UserUtils.java index c5107d6..657d64c 100644 --- a/src/main/java/net/Broken/Tools/UserManager/UserUtils.java +++ b/src/main/java/net/Broken/Tools/UserManager/UserUtils.java @@ -201,7 +201,7 @@ public class UserUtils { * Generate short check token * @return check token as string */ - private String generateCheckToken(){ + public String generateCheckToken(){ SecureRandom random = new SecureRandom(); long longToken = Math.abs( random.nextLong() ); String randomStr = Long.toString( longToken, 16 );