feat!(DevWeb): Add BulmaCSS, refacto, handle error on login pages, use bean, filters and tags

This commit is contained in:
Lucàs
2024-04-17 13:59:16 +02:00
parent 109ffd334e
commit 469b037232
81 changed files with 1315 additions and 691 deletions
@@ -0,0 +1,31 @@
package uppa.project.web.filter;
import jakarta.servlet.Filter;
import jakarta.servlet.FilterChain;
import jakarta.servlet.ServletException;
import jakarta.servlet.ServletRequest;
import jakarta.servlet.ServletResponse;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import jakarta.servlet.http.HttpSession;
import java.io.IOException;
public class AlreadyLoggedFilter implements Filter {
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
HttpServletRequest httpRequest = (HttpServletRequest) request;
HttpServletResponse httpResponse = (HttpServletResponse) response;
HttpSession session = httpRequest.getSession(false);
// Vérifier si l'utilisateur est connecté en vérifiant la présence d'une session
boolean isLoggedIn = (session != null && session.getAttribute("user") != null);
// Si l'utilisateur n'est pas connecté, laisser passer la requête
if (!isLoggedIn) {
chain.doFilter(request, response);
} else {
// Sinon, rediriger vers la page du menu principal
httpResponse.sendRedirect(httpRequest.getContextPath() + "/main-menu");
}
}
}
@@ -0,0 +1,32 @@
package uppa.project.web.filter;
import jakarta.servlet.Filter;
import jakarta.servlet.FilterChain;
import jakarta.servlet.ServletException;
import jakarta.servlet.ServletRequest;
import jakarta.servlet.ServletResponse;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import jakarta.servlet.http.HttpSession;
import java.io.IOException;
public class AuthenticationFilter implements Filter {
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
HttpServletRequest httpRequest = (HttpServletRequest) request;
HttpServletResponse httpResponse = (HttpServletResponse) response;
HttpSession session = httpRequest.getSession(false);
// Vérifier si l'utilisateur est connecté en vérifiant la présence d'une session
boolean isLoggedIn = (session != null && session.getAttribute("user") != null);
// Si l'utilisateur est connecté, laisser passer la requête
if (isLoggedIn) {
chain.doFilter(request, response);
} else {
// Sinon, rediriger vers la page de connexion
httpResponse.sendRedirect(httpRequest.getContextPath() + "/login");
}
}
}
@@ -0,0 +1,135 @@
/*
* ForgottenPasswordServlet.java, 20/03/2024
* UPPA M1 TI 2023-2024
* Pas de copyright, aucun droits
*/
package uppa.project.web.servlet;
import jakarta.persistence.EntityManager;
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 java.util.UUID;
import javax.mail.Message;
import uppa.project.Global;
import uppa.project.database.dao.DAO;
import uppa.project.database.dao.DAOException;
import uppa.project.database.dao.jpa.DAO_JPA_User;
import uppa.project.database.dao.jpa.Game_JPA_DAO_Factory;
import uppa.project.database.pojo.RecoveryPasswordToken;
import uppa.project.database.pojo.User;
import java.util.Properties;
import javax.mail.*;
import javax.mail.internet.*;
import uppa.project.database.dao.EntityManagerProvider;
@WebServlet(name = "forgottenPasswordServlet", value = "/forgotten-password")
public class ForgottenPasswordServlet extends HttpServlet {
final static EntityManager em = EntityManagerProvider.getInstance();
public void init() {
}
public void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException {
request.setAttribute("current", "forgotten-password");
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();
RecoveryPasswordToken recoveryPasswordToken = new RecoveryPasswordToken(token, user);
CreateToken(recoveryPasswordToken);
sendRecoveryEmail(email, token, request);
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, HttpServletRequest request){
String host = Global.MAIL_HOST;
String port = Global.MAIL_PORT;
String username = Global.MAIL_USERNAME;
String password = Global.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 :"+ request.getContextPath() +"/project_war_exploded/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 static void CreateToken(RecoveryPasswordToken token){
Game_JPA_DAO_Factory jpaDaoFactory = new Game_JPA_DAO_Factory();
em.getTransaction().begin();
try {
DAO<RecoveryPasswordToken> daoJpaRecoveryPasswordToken = jpaDaoFactory.getDAORecoveryPasswordToken();
daoJpaRecoveryPasswordToken.create(token);
em.getTransaction().commit();
} catch (DAOException e) {
em.getTransaction().rollback();
throw new RuntimeException(e);
}
}
public void destroy() {
}
}
@@ -0,0 +1,29 @@
/*
* LoginServlet.java, 20/03/2024
* UPPA M1 TI 2023-2024
* Pas de copyright, aucun droits
*/
package uppa.project.web.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;
@WebServlet(name = "indexServlet", value = "/index")
public class IndexServlet extends HttpServlet {
public void init() {
}
public void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException {
request.setAttribute("current", "index");
request.getRequestDispatcher("/WEB-INF/pages/index.jsp").forward(request, response);
}
public void destroy() {
}
}
@@ -0,0 +1,59 @@
/*
* LoginServlet.java, 20/03/2024
* UPPA M1 TI 2023-2024
* Pas de copyright, aucun droits
*/
package uppa.project.web.servlet;
import com.google.gson.Gson;
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 java.io.PrintWriter;
import uppa.project.bean.LoginBean;
import uppa.project.json.HttpResponse;
import uppa.project.json.HttpResponseCode;
@WebServlet(name = "loginServlet", value = "/login")
public class LoginServlet extends HttpServlet {
public void init() {
}
public void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException {
request.setAttribute("current", "login");
request.getRequestDispatcher("/WEB-INF/pages/login.jsp").forward(request, response);
}
public void doPost(HttpServletRequest request, HttpServletResponse response) throws IOException {
response.setContentType("application/json");
response.setCharacterEncoding("UTF-8");
PrintWriter out = response.getWriter();
LoginBean loginBean = new LoginBean()
.setUsername(request.getParameter("username"))
.setPassword(request.getParameter("password"))
;
Gson gson = new Gson();
HttpResponse httpResponse;
if (loginBean.validate()) {
request.getSession().setAttribute("user", loginBean.getUser());
httpResponse = new HttpResponse(HttpResponseCode.OK, "Login success");
} else {
httpResponse = new HttpResponse(HttpResponseCode.UNAUTHORIZED, "<strong>Erreur de connexion:</strong> Le nom d'utilisateur ou le " +
"mot de passe est incorrect.");
}
out.println(gson.toJson(httpResponse));
out.flush();
}
public void destroy() {
}
}
@@ -0,0 +1,33 @@
/*
* LogoutServlet.java, 20/03/2024
* UPPA M1 TI 2023-2024
* Pas de copyright, aucun droits
*/
package uppa.project.web.servlet;
import com.google.gson.Gson;
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.listener.SessionServletContextListener;
@WebServlet(name = "logoutServlet", value = "/logout")
public class LogoutServlet extends HttpServlet {
private final Gson gson = new Gson();
public void init() {
}
public void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException {
SessionServletContextListener.removeSession(request.getSession());
request.getSession().removeAttribute("user");
response.sendRedirect(request.getContextPath() + "/login");
}
public void destroy() {
}
}
@@ -0,0 +1,72 @@
/*
* MainMenuServlet.java, 20/03/2024
* UPPA M1 TI 2023-2024
* Pas de copyright, aucun droits
*/
package uppa.project.web.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 jakarta.servlet.http.HttpSession;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
import uppa.project.database.pojo.Game;
import uppa.project.database.pojo.Player;
import uppa.project.database.pojo.User;
@WebServlet(name = "mainMenuServlet", value = "/main-menu")
public class MainMenuServlet extends HttpServlet {
public void init() {
}
public void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException {
User user = (User) request.getSession().getAttribute("user");
// if (user == null) {
// response.sendRedirect(request.getContextPath() + "/login");
// return;
// }
request.setAttribute("current", "main-menu");
manageNewGame(request, response, user);
manageStatistics(request, response, user);
request.getRequestDispatcher("/WEB-INF/pages/main-menu.jsp").forward(request, response);
}
public void destroy() {
}
private void manageNewGame(HttpServletRequest request, HttpServletResponse response, User sessionUser) throws IOException, ServletException {
List<User> connectedUsers = new ArrayList<>();
Set<HttpSession> loginsSessions = (Set<HttpSession>) request.getServletContext().getAttribute("loginSession");
if (loginsSessions == null) {
throw new RuntimeException("No login sessions found");
}
for(HttpSession session : loginsSessions) {
User connectedUser = (User) session.getAttribute("user");
if(session.getServletContext().getContextPath().equals(request.getServletContext().getContextPath()) && connectedUser != null && !connectedUser.equals(sessionUser)) {
connectedUsers.add(connectedUser);
}
}
connectedUsers.remove(sessionUser);
request.setAttribute("connectedUsers", connectedUsers);
}
private void manageStatistics(HttpServletRequest request, HttpServletResponse response, User sessionUser) throws IOException, ServletException {
List<Game> games = new ArrayList<>();
if (sessionUser != null && sessionUser.getPlayedGames() != null) {
for (Player player : sessionUser.getPlayedGames()) {
Game game = player.getGame();
game.sortPlayersByScore();
games.add(game);
}
}
request.setAttribute("games", games);
}
}
@@ -0,0 +1,63 @@
/*
* RegisterServlet.java, 20/03/2024
* UPPA M1 TI 2023-2024
* Pas de copyright, aucun droits
*/
package uppa.project.web.servlet;
import com.google.gson.Gson;
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 java.io.PrintWriter;
import uppa.project.bean.LoginBean;
import uppa.project.bean.RegisterBean;
import uppa.project.json.HttpResponse;
import uppa.project.json.HttpResponseCode;
@WebServlet(name = "registerServlet", value = "/register")
public class RegisterServlet extends HttpServlet {
public void init() {
}
public void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException {
request.setAttribute("current", "register");
request.getRequestDispatcher("/WEB-INF/pages/register.jsp").forward(request, response);
}
public void doPost(HttpServletRequest request, HttpServletResponse response) throws IOException {
response.setContentType("application/json");
response.setCharacterEncoding("UTF-8");
PrintWriter out = response.getWriter();
RegisterBean registerBean = new RegisterBean()
.setUsername(request.getParameter("username"))
.setEmail(request.getParameter("email"))
.setPassword(request.getParameter("password"))
.setBirth(request.getParameter("birth"))
.setGender(request.getParameter("gender"))
;
Gson gson = new Gson();
HttpResponse httpResponse;
if (registerBean.validate()) {
httpResponse = new HttpResponse(
HttpResponseCode.OK,
"Register success"
);
} else {
httpResponse = new HttpResponse(HttpResponseCode.UNAUTHORIZED, registerBean.getErrorMessage());
}
out.println(gson.toJson(httpResponse));
out.flush();
}
public void destroy() {
}
}
@@ -0,0 +1,78 @@
package uppa.project.web.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.database.dao.DAOException;
import uppa.project.database.dao.jpa.DAO_JPA_RecoveryPasswordToken;
import uppa.project.database.dao.jpa.DAO_JPA_User;
import uppa.project.database.pojo.RecoveryPasswordToken;
import uppa.project.database.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 token = findRecoveryToken(request.getParameter("token"));
if (token == null) {
response.sendRedirect(request.getContextPath() + "/forgotten-password?error=invalid-token");
return;
}
if (token.getExpirationDate().compareTo(new java.util.Date()) < 0){
response.sendRedirect(request.getContextPath() + "/forgotten-password?error=expired-token");
return;
}
request.setAttribute("current", "reset-password");
request.getRequestDispatcher("/WEB-INF/pages/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=matching-password&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-reseted");
} catch (DAOException e) {
response.sendRedirect(request.getContextPath() + "/reset-password?error=1");
}
}
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);
}
}
}
@@ -0,0 +1,65 @@
package uppa.project.web.websocket;
import com.google.gson.Gson;
import jakarta.websocket.OnClose;
import jakarta.websocket.OnError;
import jakarta.websocket.OnMessage;
import jakarta.websocket.OnOpen;
import jakarta.websocket.RemoteEndpoint;
import jakarta.websocket.Session;
import jakarta.websocket.server.ServerEndpoint;
import java.io.IOException;
import java.util.HashMap;
import uppa.project.database.pojo.User;
import uppa.project.json.websocket.Message;
@ServerEndpoint(value = "/ws/connected-users")
public class ConnectedUsersWS {
private static final HashMap<Session, User> connections = new HashMap<>();
@OnOpen
public void onOpen(Session session) {}
private void broadcastConnectedUsers() {
Gson gson = new Gson();
User[] connectedUsers = connections.values().toArray(new User[0]);
Message websocketObject = new Message("userList", gson.toJson(connectedUsers));
String message = gson.toJson(websocketObject);
for (Session session : connections.keySet()) {
RemoteEndpoint.Basic remote = session.getBasicRemote();
try {
remote.sendText(message);
} catch (IOException e) {
e.printStackTrace();
}
}
}
@OnClose
public void onClose(Session session) {
connections.remove(session);
// Update connected users list
broadcastConnectedUsers();
}
@OnError
public void onError(Throwable throwable) {
throwable.printStackTrace();
}
@OnMessage
public void onMessage(String message, Session session) {
Gson gson = new Gson();
Message websocketMessage = gson.fromJson(message, Message.class);
if (websocketMessage.getType().equals("linkUserSession")) {
User user = gson.fromJson(websocketMessage.getData(), User.class);
connections.put(session, user);
broadcastConnectedUsers();
}
}
}