feat: dev-web - forgotten password management

This commit is contained in:
kmitresse
2024-03-22 15:29:23 +01:00
parent 0e7066808b
commit 8e9bfebffe
11 changed files with 251 additions and 43 deletions
@@ -45,6 +45,11 @@ public abstract class GameDAOFactory {
*/
public abstract DAO<Player> getDAOPlayer() throws DAOException;
/**
* @return le DAO pour la classe/table RecoveryPasswordToken
* @throws DAOException en cas de problème
* @see RecoveryPasswordToken
*/
public abstract DAO<RecoveryPasswordToken> getDAORecoveryPasswordToken() throws DAOException;
}
@@ -16,7 +16,7 @@ import uppa.project.pojo.RecoveryPasswordToken;
import uppa.project.provider.EntityManagerProvider;
/**
* DAO pour les utilisateurs
* DAO pour les tokens de récupération de mot de passe
*
* @author Kévin Mitresse
* @author Lucàs Vabre
@@ -5,6 +5,8 @@ import jakarta.persistence.Entity;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.GenerationType;
import jakarta.persistence.Id;
import jakarta.persistence.JoinColumn;
import jakarta.persistence.ManyToOne;
import jakarta.persistence.Table;
import jakarta.persistence.Temporal;
import jakarta.persistence.TemporalType;
@@ -24,10 +26,13 @@ public class RecoveryPasswordToken {
@Column(name = "id")
@GeneratedValue(strategy = GenerationType.IDENTITY)
private int id;
@Column(name = "token")
private String token;
@Column(name = "email")
private String email;
@ManyToOne
@JoinColumn(name = "user_id", nullable = false)
private User user;
@Temporal(TemporalType.TIMESTAMP)
@Column(name = "expires_at")
@@ -38,24 +43,27 @@ public class RecoveryPasswordToken {
/**
* Constructeur
*
* @param token
* @param email
* @param user
*/
public RecoveryPasswordToken(String token, String email) {
public RecoveryPasswordToken(String token, User user) {
this.token = token;
this.email = email;
this.user = user;
}
/**
* Constructeur depuis la base de données
*
* @param id
* @param token
* @param email
* @param user
*/
public RecoveryPasswordToken(int id, String token, String email) {
public RecoveryPasswordToken(int id, String token, User user, Date expiresAt) {
this.id = id;
this.token = token;
this.email = email;
this.user = user;
this.expiresAt = expiresAt;
}
/**
@@ -86,21 +94,21 @@ public class RecoveryPasswordToken {
}
/**
* Récupère l'email associé au token
* Récupère l'utilisateur associé au token
*
* @return l'email associé au token
* @return l'utilisateur associé au token
*/
public String getEmail() {
return email;
public User getUser() {
return user;
}
/**
* Définit l'email associé au token
* Définit l'utilisateur associé au token
*
* @param email
* @param user
*/
public void setEmail(String email) {
this.email = email;
public void setUser(User user) {
this.user = user;
}
/**
@@ -120,4 +128,23 @@ public class RecoveryPasswordToken {
public void setExpiresAt(Date expiresAt) {
this.expiresAt = expiresAt;
}
@Override
public String toString() {
return "RecoveryPasswordToken{" +
"id=" + id +
", token='" + token + '\'' +
", user=" + user +
", expiresAt=" + expiresAt +
'}';
}
/**
* Récupère la date d'expiration du token
*
* @return la date d'expiration du token
*/
public Date getExpirationDate() {
return expiresAt;
}
}
@@ -6,7 +6,6 @@
package uppa.project.pojo;
import com.google.gson.Gson;
import jakarta.persistence.CascadeType;
import jakarta.persistence.Column;
import jakarta.persistence.Entity;
@@ -42,21 +41,30 @@ public class User implements Serializable {
@Column(name = "id")
@GeneratedValue(strategy = GenerationType.IDENTITY)
private BigDecimal id;
@Column(name = "username")
private String username;
@Column(name = "email")
private String email;
@Column(name = "password")
private String password;
@Temporal(TemporalType.DATE)
@Column(name = "birth")
private Date birth;
@Column(name = "gender")
@Enumerated(EnumType.STRING)
private Gender gender;
@OneToMany(mappedBy = "user", cascade = CascadeType.ALL, fetch = FetchType.LAZY)
private Set<Player> playedGame;
@OneToMany(mappedBy = "user", cascade = CascadeType.ALL, fetch = FetchType.LAZY)
private Set<RecoveryPasswordToken> recoveryPasswordTokens;
/**
* Constructeur par défaut
*/
@@ -31,11 +31,6 @@ public class ForgottenPasswordServlet extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException {
if (request.getSession().getAttribute("user") != null) {
response.sendRedirect(request.getContextPath() + "/main-menu");
return;
}
request.getRequestDispatcher("/WEB-INF/views/forgotten-password.jsp").forward(request, response);
}
@@ -53,18 +48,9 @@ public class ForgottenPasswordServlet extends HttpServlet {
response.sendRedirect(request.getContextPath() + "/forgotten-password?error=1");
} else {
String token = UUID.randomUUID().toString();
System.out.println("Token : " + token);
System.out.println("1");
RecoveryPasswordToken recoveryPasswordToken = new RecoveryPasswordToken(token, user.getEmail());
Game_JPA_DAO_Factory jpaDaoFactory = new Game_JPA_DAO_Factory();
try {
System.out.println("2");
DAO<RecoveryPasswordToken> daoJpaRecoveryPasswordToken = jpaDaoFactory.getDAORecoveryPasswordToken();
System.out.println("3");
daoJpaRecoveryPasswordToken.create(recoveryPasswordToken);
} catch (DAOException e) {
throw new RuntimeException(e);
}
RecoveryPasswordToken recoveryPasswordToken = new RecoveryPasswordToken(token, user);
CreateToken(recoveryPasswordToken);
sendRecoveryEmail(email, token);
response.sendRedirect(request.getContextPath() + "/forgotten-password?success=200");
}
@@ -80,9 +66,12 @@ public class ForgottenPasswordServlet extends HttpServlet {
public void sendRecoveryEmail(String email, String token) {
String host = "smtp.gmail.com";
String port = "587";
String username = System.getenv("MAIL_USERNAME");
String password = System.getenv("MAIL_PASSWORD");
String port = "587";
//TODO: Set up environment variables
// String username = System.getenv("MAIL_USERNAME");
// String password = System.getenv("MAIL_PASSWORD");
String username = "kmitresse@gmail.com";
String password = "xwos ujwf cesq ocyt";
Properties props = new Properties();
props.put("mail.smtp.auth", "true");
@@ -105,7 +94,7 @@ public class ForgottenPasswordServlet extends HttpServlet {
message.setSubject("Réinitialisation de votre mot de passe");
message.setText("Bonjour,\n\n" +
"Vous avez demandé la réinitialisation de votre mot de passe.\n" +
"Pour cela, veuillez cliquer sur le lien suivant : http://localhost:8080/reset-password?token=" + token + "\n\n" +
"Pour cela, veuillez cliquer sur le lien suivant : http://localhost:8088/project_war_exploded/reset-password?token=" + token + "\n\n" +
"Cordialement,\n" +
"L'équipe CardRush");
// Envoi du message
@@ -128,8 +117,16 @@ public class ForgottenPasswordServlet extends HttpServlet {
} catch (DAOException e) {
throw new RuntimeException(e);
}
}
public static void CreateToken(RecoveryPasswordToken token){
Game_JPA_DAO_Factory jpaDaoFactory = new Game_JPA_DAO_Factory();
try {
DAO<RecoveryPasswordToken> daoJpaRecoveryPasswordToken = jpaDaoFactory.getDAORecoveryPasswordToken();
daoJpaRecoveryPasswordToken.create(token);
} catch (DAOException e) {
throw new RuntimeException(e);
}
}
public void destroy() {
}
@@ -0,0 +1,73 @@
package uppa.project.servlet;
import jakarta.servlet.ServletException;
import jakarta.servlet.annotation.WebServlet;
import jakarta.servlet.http.HttpServlet;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import java.io.IOException;
import uppa.project.dao.DAOException;
import uppa.project.dao.jpa.DAO_JPA_RecoveryPasswordToken;
import uppa.project.dao.jpa.DAO_JPA_User;
import uppa.project.pojo.RecoveryPasswordToken;
import uppa.project.pojo.User;
@WebServlet(name = "resetPasswordServlet", value = "/reset-password")
public class ResetPasswordServlet extends HttpServlet {
public void init() {
}
public void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException {
RecoveryPasswordToken recoveryPasswordToken = findRecoveryToken(request.getParameter("token"));
if (recoveryPasswordToken == null) {
response.sendRedirect(request.getContextPath() + "/error?code=404");
return;
}
request.getRequestDispatcher("/WEB-INF/views/reset-password.jsp").forward(request, response);
}
/**
* Gestion de la réinitialisation de mot de passe
*
* @param request
* @param response
* @throws IOException
*/
public void doPost(HttpServletRequest request, HttpServletResponse response) throws IOException {
RecoveryPasswordToken recoveryPasswordToken = findRecoveryToken(request.getParameter("token"));
User user = recoveryPasswordToken.getUser();
String newPassword = request.getParameter("newPassword");
String confirmPassword = request.getParameter("confirmPassword");
System.out.println("newPassword: " + newPassword);
System.out.println("confirmPassword: " + confirmPassword);
System.out.println(!newPassword.equals(confirmPassword));
if (!newPassword.equals(confirmPassword)) {
System.out.println("ici");
response.sendRedirect(request.getContextPath() + "/reset-password?error=1&token=" + recoveryPasswordToken.getToken());
return;
}
user.setPassword(newPassword);
DAO_JPA_User daoJpaUser = null;
try {
daoJpaUser = new DAO_JPA_User();
daoJpaUser.update(user);
response.sendRedirect(request.getContextPath() + "/login?success=password-modified");
} catch (DAOException e) {
response.sendRedirect(request.getContextPath() + "/reset-password?error=2");
}
}
public static RecoveryPasswordToken findRecoveryToken(String token) {
try {
DAO_JPA_RecoveryPasswordToken daoJpaRecoveryPasswordToken = new DAO_JPA_RecoveryPasswordToken();
RecoveryPasswordToken[] recoveryPasswordTokens = daoJpaRecoveryPasswordToken.findByField("token",token);
if (recoveryPasswordTokens.length == 0) {
return null;
}
return recoveryPasswordTokens[0];
} catch (DAOException e) {
throw new RuntimeException(e);
}
}
}