draft: dev-web - forgotten password token

This commit is contained in:
kmitresse
2024-03-22 10:53:13 +01:00
parent 1e02ad373c
commit 0e7066808b
9 changed files with 375 additions and 3 deletions
@@ -8,6 +8,7 @@ package uppa.project.dao;
import uppa.project.pojo.Game;
import uppa.project.pojo.Player;
import uppa.project.pojo.RecoveryPasswordToken;
import uppa.project.pojo.User;
/**
@@ -21,6 +22,7 @@ public abstract class GameDAOFactory {
protected DAO<User> daoUser = null;
protected DAO<Game> daoGame = null;
protected DAO<Player> daoPlayer = null;
protected DAO<RecoveryPasswordToken> daoRecoveryPasswordToken = null;
/**
* @return le DAO pour la classe/table User
@@ -43,4 +45,6 @@ public abstract class GameDAOFactory {
*/
public abstract DAO<Player> getDAOPlayer() throws DAOException;
public abstract DAO<RecoveryPasswordToken> getDAORecoveryPasswordToken() throws DAOException;
}
@@ -0,0 +1,78 @@
/*
* DAO_JPA_RecoveryPasswordToken.java, 20/03/2024
* UPPA M1 TI 2023-2024
* Pas de copyright, aucun droits
*/
package uppa.project.dao.jpa;
import jakarta.persistence.EntityManager;
import jakarta.persistence.TypedQuery;
import java.math.BigDecimal;
import java.util.List;
import uppa.project.dao.DAO;
import uppa.project.dao.DAOException;
import uppa.project.pojo.RecoveryPasswordToken;
import uppa.project.provider.EntityManagerProvider;
/**
* DAO pour les utilisateurs
*
* @author Kévin Mitresse
* @author Lucàs Vabre
* @see RecoveryPasswordToken
* @see DAO
*/
public class DAO_JPA_RecoveryPasswordToken extends DAO<RecoveryPasswordToken> {
/**
* Gestionnaire d'entités
*/
private final EntityManager entityManager;
public DAO_JPA_RecoveryPasswordToken() throws DAOException {
this.entityManager = EntityManagerProvider.getInstance();
}
@Override
public RecoveryPasswordToken findById(int id) throws DAOException {
RecoveryPasswordToken result = entityManager.find(RecoveryPasswordToken.class, new BigDecimal(id));
entityManager.flush();
return result;
}
public RecoveryPasswordToken[] findByField(String field, String value) throws DAOException {
String sqlQuery = String.format("SELECT r FROM RecoveryPasswordToken r WHERE r.%s = (:val)", field);
TypedQuery<RecoveryPasswordToken> query = entityManager.createQuery(sqlQuery, RecoveryPasswordToken.class);
query.setParameter("val", value);
List<RecoveryPasswordToken> results = query.getResultList();
return results.toArray(new RecoveryPasswordToken[0]);
}
@Override
public RecoveryPasswordToken[] findAll() throws DAOException {
TypedQuery<RecoveryPasswordToken> query = entityManager.createQuery("SELECT r FROM RecoveryPasswordToken r", RecoveryPasswordToken.class);
List<RecoveryPasswordToken> results = query.getResultList();
return results.toArray(new RecoveryPasswordToken[0]);
}
@Override
public void create(RecoveryPasswordToken data) throws DAOException {
update(data);
}
@Override
public void update(RecoveryPasswordToken data) throws DAOException {
entityManager.getTransaction().begin();
entityManager.merge(data);
entityManager.getTransaction().commit();
}
@Override
public void delete(RecoveryPasswordToken data) throws DAOException {
entityManager.getTransaction().begin();
entityManager.remove(data);
entityManager.getTransaction().commit();
}
}
@@ -36,4 +36,10 @@ public class Game_JPA_DAO_Factory extends GameDAOFactory {
if (daoPlayer == null) daoPlayer = new DAO_JPA_Player();
return daoPlayer;
}
@Override
public DAO<RecoveryPasswordToken> getDAORecoveryPasswordToken() throws DAOException {
if (daoRecoveryPasswordToken == null) daoRecoveryPasswordToken= new DAO_JPA_RecoveryPasswordToken();
return daoRecoveryPasswordToken;
}
}
@@ -0,0 +1,123 @@
package uppa.project.pojo;
import jakarta.persistence.Column;
import jakarta.persistence.Entity;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.GenerationType;
import jakarta.persistence.Id;
import jakarta.persistence.Table;
import jakarta.persistence.Temporal;
import jakarta.persistence.TemporalType;
import java.util.Date;
/**
* Représentation d'un token de réinitialisation de mot de passe
*
* @author Kevin Mitressé
* @author Lucàs Vabre
*/
@Entity
@Table(name = "recovery_password_token")
public class RecoveryPasswordToken {
@Id
@Column(name = "id")
@GeneratedValue(strategy = GenerationType.IDENTITY)
private int id;
@Column(name = "token")
private String token;
@Column(name = "email")
private String email;
@Temporal(TemporalType.TIMESTAMP)
@Column(name = "expires_at")
private Date expiresAt;
public RecoveryPasswordToken() {
}
/**
* Constructeur
* @param token
* @param email
*/
public RecoveryPasswordToken(String token, String email) {
this.token = token;
this.email = email;
}
/**
* Constructeur depuis la base de données
* @param id
* @param token
* @param email
*/
public RecoveryPasswordToken(int id, String token, String email) {
this.id = id;
this.token = token;
this.email = email;
}
/**
* Récupère l'id de l'instance
*
* @return l'id
*/
public int getId() {
return id;
}
/**
* Récupère le token
*
* @return le token
*/
public String getToken() {
return token;
}
/**
* Définit le token
*
* @param token
*/
public void setToken(String token) {
this.token = token;
}
/**
* Récupère l'email associé au token
*
* @return l'email associé au token
*/
public String getEmail() {
return email;
}
/**
* Définit l'email associé au token
*
* @param email
*/
public void setEmail(String email) {
this.email = email;
}
/**
* Récupère la date d'expiration du token
*
* @return la date d'expiration du token
*/
public Date getExpiresAt() {
return expiresAt;
}
/**
* Définit la date d'expiration du token
*
* @param expiresAt
*/
public void setExpiresAt(Date expiresAt) {
this.expiresAt = expiresAt;
}
}
@@ -12,6 +12,17 @@ import jakarta.servlet.http.HttpServlet;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.UUID;
import javax.mail.Message;
import uppa.project.dao.DAO;
import uppa.project.dao.DAOException;
import uppa.project.dao.jpa.DAO_JPA_User;
import uppa.project.dao.jpa.Game_JPA_DAO_Factory;
import uppa.project.pojo.RecoveryPasswordToken;
import uppa.project.pojo.User;
import java.util.Properties;
import javax.mail.*;
import javax.mail.internet.*;
@WebServlet(name = "forgottenPasswordServlet", value = "/forgotten-password")
public class ForgottenPasswordServlet extends HttpServlet {
@@ -28,6 +39,98 @@ public class ForgottenPasswordServlet extends HttpServlet {
request.getRequestDispatcher("/WEB-INF/views/forgotten-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 {
String email = request.getParameter("email");
User user = getUserByEmail(email);
if (user == null) {
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);
}
sendRecoveryEmail(email, token);
response.sendRedirect(request.getContextPath() + "/forgotten-password?success=200");
}
}
/**
* Envoi d'un e-mail de réinitialisation de mot de passe
*
* @param email
* @param token
*/
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");
Properties props = new Properties();
props.put("mail.smtp.auth", "true");
props.put("mail.smtp.starttls.enable", "true");
props.put("mail.smtp.host", host);
props.put("mail.smtp.port", port);
Session session = Session.getInstance(props, new Authenticator() {
@Override
protected PasswordAuthentication getPasswordAuthentication() {
return new PasswordAuthentication(username, password);
}
});
try {
// Création du message
Message message = new MimeMessage(session);
message.setFrom(new InternetAddress(username));
message.setRecipients(Message.RecipientType.TO, InternetAddress.parse(email));
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" +
"Cordialement,\n" +
"L'équipe CardRush");
// Envoi du message
Transport.send(message);
System.out.println("E-mail envoyé avec succès à : " + email);
} catch (MessagingException e) {
throw new RuntimeException("Erreur lors de l'envoi de l'e-mail", e);
}
}
public static User getUserByEmail(String email){
try {
DAO_JPA_User daoJpaUser = new DAO_JPA_User();
User[] users = daoJpaUser.findByField("email", email);
if (users.length == 0) {
return null;
}
return users[0];
} catch (DAOException e) {
throw new RuntimeException(e);
}
}
public void destroy() {
}
}
}