Recuperacion de contrasena

parent b2a47f91
...@@ -68,6 +68,10 @@ ...@@ -68,6 +68,10 @@
<groupId>org.springframework.boot</groupId> <groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId> <artifactId>spring-boot-starter-security</artifactId>
</dependency> </dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-mail</artifactId>
</dependency>
<!-- <dependency>--> <!-- <dependency>-->
<!-- <groupId>org.projectlombok</groupId>--> <!-- <groupId>org.projectlombok</groupId>-->
<!-- <artifactId>lombok</artifactId>--> <!-- <artifactId>lombok</artifactId>-->
......
...@@ -2,14 +2,35 @@ package com.roshka.controller; ...@@ -2,14 +2,35 @@ package com.roshka.controller;
import com.roshka.modelo.RRHHUser; import com.roshka.modelo.RRHHUser;
import com.roshka.repositorio.RRHHUserRepository; import com.roshka.repositorio.RRHHUserRepository;
import com.roshka.service.EmailAsyncService;
import com.roshka.service.RRHHUserService;
import net.bytebuddy.utility.RandomString;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.repository.query.Param;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.mail.javamail.JavaMailSender;
import org.springframework.mail.javamail.MimeMessageHelper;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.stereotype.Controller; import org.springframework.stereotype.Controller;
import org.springframework.ui.Model; import org.springframework.ui.Model;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.ResponseStatus;
import org.springframework.web.servlet.mvc.support.RedirectAttributes;
import org.springframework.web.servlet.view.RedirectView;
import javax.mail.MessagingException;
import javax.mail.internet.MimeMessage;
import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
@Controller @Controller
public class RRHHUserController { public class RRHHUserController {
...@@ -54,4 +75,100 @@ public class RRHHUserController { ...@@ -54,4 +75,100 @@ public class RRHHUserController {
return "register_success"; return "register_success";
} }
@Autowired
private RRHHUserService userService;
@Autowired
private EmailAsyncService emailAsyncService;
@GetMapping("/forgot-password")
public String showForgotPasswordForm(HttpServletRequest request, Model model) {
model.addAttribute("error", request.getParameter("error"));
// if(request.getParameter("error")!=null){
//
// }
return "forgot_password_form";
}
@PostMapping("/forgot-password")
public String processForgotPassword(HttpServletRequest request, Model model) {
String email = request.getParameter("email");
String token = RandomString.make(30);
try {
userService.updateResetPasswordToken(token, email);
}catch (UsernameNotFoundException e){
model.addAttribute("error", "Error al enviar el mail. Checkee sus credenciales " +
"y intentelo de nuevo.");
return "forgot_password_form";
}
String resetPasswordLink = Utility.getSiteURL(request) + "/reset-password?token=" + token;
ExecutorService emailExecutor = Executors.newSingleThreadExecutor();
emailExecutor.execute(new Runnable() {
@Override
public void run() {
try {
emailAsyncService.sendEmail(email, resetPasswordLink);
} catch (IOException | MessagingException e) {
e.printStackTrace();
}
}
});
emailExecutor.shutdown();
return "forgot_password_form";
}
@GetMapping("/reset-password")
public String showResetPasswordForm(@Param(value = "token") String token, Model model) {
RRHHUser user = userService.getByResetPasswordToken(token);
model.addAttribute("token", token);
if (user == null) {
model.addAttribute("error", "Invalid Token");
return "error";
}
return "reset_password_form";
}
@PostMapping("/reset-password")
public String processResetPassword(HttpServletRequest request, Model model) {
String token = request.getParameter("token");
String password = request.getParameter("password");
RRHHUser user = userService.getByResetPasswordToken(token);
model.addAttribute("title", "Reset your password");
if (user == null) {
model.addAttribute("error", "Invalid Token");
return "message";
} else {
userService.updatePassword(user, password);
model.addAttribute("success", "You have successfully changed your password.");
}
return "redirect:/";
}
@ResponseStatus(HttpStatus.PERMANENT_REDIRECT)
@ExceptionHandler({UsernameNotFoundException.class})
public RedirectView handleValidationExceptions(
RedirectAttributes redir, UsernameNotFoundException ex) {
RedirectView redirectView = new RedirectView("/forgot-password", true);
redir.addAttribute("error", "Error al enviar el mail. Checkee sus credenciales" +
" y intentelo de nuevo");
return redirectView;
}
} }
class Utility {
public static String getSiteURL(HttpServletRequest request) {
String siteURL = request.getRequestURL().toString();
return siteURL.replace(request.getServletPath(), "");
}
}
\ No newline at end of file
...@@ -21,6 +21,17 @@ public class RRHHUser { ...@@ -21,6 +21,17 @@ public class RRHHUser {
@Column(name = "last_name", nullable = false, length = 20) @Column(name = "last_name", nullable = false, length = 20)
private String lastName; private String lastName;
@Column(name = "reset_password_token")
private String resetPasswordToken;
public String getResetPasswordToken() {
return resetPasswordToken;
}
public void setResetPasswordToken(String resetPasswordToken) {
this.resetPasswordToken = resetPasswordToken;
}
public Long getId() { public Long getId() {
return id; return id;
} }
......
...@@ -5,4 +5,6 @@ import org.springframework.data.jpa.repository.JpaRepository; ...@@ -5,4 +5,6 @@ import org.springframework.data.jpa.repository.JpaRepository;
public interface RRHHUserRepository extends JpaRepository<RRHHUser, Long> { public interface RRHHUserRepository extends JpaRepository<RRHHUser, Long> {
RRHHUser findByEmail(String username); RRHHUser findByEmail(String username);
RRHHUser findByResetPasswordToken(String resetPasswordToken);
} }
package com.roshka.service;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.mail.javamail.JavaMailSender;
import org.springframework.mail.javamail.MimeMessageHelper;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import javax.mail.MessagingException;
import javax.mail.internet.MimeMessage;
import java.io.UnsupportedEncodingException;
@Service
public class EmailAsyncService {
@Autowired
private JavaMailSender mailSender;
@Async
public void sendEmail(String recipientEmail, String link)
throws MessagingException, UnsupportedEncodingException {
MimeMessage message = mailSender.createMimeMessage();
MimeMessageHelper helper = new MimeMessageHelper(message);
helper.setFrom("test@test.com", "Sistema de Postulacion");
helper.setTo(recipientEmail);
String subject = "Aqui tienes el link para volver a definir tu password";
String content = "<p>Hola!,</p>"
+ "<p>Has solicitado una re-definicion de password.</p>"
+ "<p>Haz click en el link de abajo para re-definir tu password:</p>"
+ "<p><a href=\"" + link + "\">Cambiar password</a></p>"
+ "<br>"
+ "<p>Ignora y no compartas este mail si no has solicitado un cambio de password.";
helper.setSubject(subject);
helper.setText(content, true);
mailSender.send(message);
}
}
\ No newline at end of file
package com.roshka.service;
import com.roshka.modelo.RRHHUser;
import com.roshka.repositorio.RRHHUserRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.stereotype.Service;
import javax.transaction.Transactional;
@Service
@Transactional
public class RRHHUserService {
@Autowired
private RRHHUserRepository userRepo;
public void updateResetPasswordToken(String token, String email) throws UsernameNotFoundException {
RRHHUser customer = userRepo.findByEmail(email);
if (customer != null) {
customer.setResetPasswordToken(token);
userRepo.save(customer);
} else {
throw new UsernameNotFoundException("Could not find any customer with the email " + email);
}
}
public RRHHUser getByResetPasswordToken(String token) {
return userRepo.findByResetPasswordToken(token);
}
public void updatePassword(RRHHUser user, String newPassword) {
BCryptPasswordEncoder passwordEncoder = new BCryptPasswordEncoder();
String encodedPassword = passwordEncoder.encode(newPassword);
user.setPassword(encodedPassword);
user.setResetPasswordToken(null);
userRepo.save(user);
}
}
\ No newline at end of file
...@@ -16,3 +16,11 @@ spring.jpa.properties.hibernate.jdbc.lob.non_contextual_creation=true ...@@ -16,3 +16,11 @@ spring.jpa.properties.hibernate.jdbc.lob.non_contextual_creation=true
#server.port=8888 #server.port=8888
spring.mvc.view.prefix=/jsp/ spring.mvc.view.prefix=/jsp/
spring.mvc.view.suffix=.jsp spring.mvc.view.suffix=.jsp
spring.mail.host=smtp.gmail.com
spring.mail.username=fpunascrumkanban@gmail.com
spring.mail.password=fpunascrumkanban123
spring.mail.port=587
spring.mail.properties.mail.smtp.auth=true
spring.mail.properties.mail.smtp.starttls.enable=true
<%@ taglib prefix="form" uri="http://www.springframework.org/tags/form" %>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<meta name="description" content="">
<meta name="author" content="">
<title>Forgot Password</title>
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-1BmE4kWBq78iYhFldvKuhfTAU6auU8tT94WrHftjDbrCEXSU1oBoqyl2QvZ6jIW3" crossorigin="anonymous">
<link href="https://getbootstrap.com/docs/4.0/examples/signin/signin.css" rel="stylesheet" crossorigin="anonymous">
</head>
<body>
<jsp:include page="alerts.jsp"/>
<div>
<h2>Forgot Password</h2>
</div>
<form:form action="/forgot-password" method="post" style="max-width: 420px; margin: 0 auto;">
<div class="border border-secondary rounded p-3">
<div>
<p>We will be sending a reset password link to your email.</p>
</div>
<div>
<p>
<input type="email" name="email" class="form-control" placeholder="Enter your e-mail" required autofocus/>
</p>
<p class="text-center">
<input type="submit" value="Send" class="btn btn-primary" />
</p>
</div>
</div>
</form:form>
</body>
</html>
\ No newline at end of file
...@@ -38,7 +38,9 @@ ...@@ -38,7 +38,9 @@
</form:form> </form:form>
<hr class="my-4"> <hr class="my-4">
<div class="row">
<a href="/forgot-password">Olvidaste tu contrasena?</a>
</div>
</div> </div>
</div> </div>
</div> </div>
......
<%@ taglib prefix="form" uri="http://www.springframework.org/tags/form" %>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<meta name="description" content="">
<meta name="author" content="">
<title>Forgot Password</title>
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-1BmE4kWBq78iYhFldvKuhfTAU6auU8tT94WrHftjDbrCEXSU1oBoqyl2QvZ6jIW3" crossorigin="anonymous">
<link href="https://getbootstrap.com/docs/4.0/examples/signin/signin.css" rel="stylesheet" crossorigin="anonymous">
</head>
<body>
<jsp:include page="alerts.jsp"/>
<div>
<h2>Reset Your Password</h2>
</div>
<form:form action="/reset-password" method="post" style="max-width: 350px; margin: 0 auto;">
<input type="hidden" name="token" value="${token}" />
<div class="border border-secondary rounded p-3">
<div>
<p>
<input type="password" name="password" id="password" class="form-control"
placeholder="Enter your new password" required autofocus />
</p>
<p class="text-center">
<input type="submit" value="Change Password" class="btn btn-primary" />
</p>
</div>
</div>
</form:form>
</body>
</html>
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment