From 98c1cef6dd3624c3e699b552d6b41ae0dc234f75 Mon Sep 17 00:00:00 2001 From: Ramzi Benmansour Date: Sun, 7 May 2023 10:02:33 +0200 Subject: [PATCH] Initial commit --- nb-configuration.xml | 19 + pom.xml | 97 +++++ src/main/java/g3/Forms/Checkable.java | 14 + src/main/java/g3/Forms/FormChecker.java | 41 ++ src/main/java/g3/Forms/LoginFormChecker.java | 62 +++ src/main/java/g3/Forms/SigninFormChecker.java | 109 ++++++ src/main/java/g3/beans/Identifiable.java | 18 + src/main/java/g3/beans/User.java | 83 ++++ src/main/java/g3/dao/Crudable.java | 34 ++ src/main/java/g3/dao/Dao.java | 86 +++++ src/main/java/g3/dao/DaoFactory.java | 19 + src/main/java/g3/dao/DaoUser.java | 155 ++++++++ src/main/java/g3/filters/ConnectFilter.java | 46 +++ src/main/java/g3/filters/isAdminFilter.java | 50 +++ .../g3/helpers/PasswordAuthentification.java | 139 +++++++ src/main/java/g3/servelets/Home.java | 34 ++ src/main/java/g3/servelets/Login.java | 57 +++ src/main/java/g3/servelets/Logout.java | 55 +++ src/main/java/g3/servelets/Profile.java | 56 +++ src/main/java/g3/servelets/Signin.java | 59 +++ src/main/webapp/META-INF/context.xml | 2 + src/main/webapp/WEB-INF/Admin.jsp | 17 + src/main/webapp/WEB-INF/Home.jsp | 45 +++ src/main/webapp/WEB-INF/Login.jsp | 34 ++ src/main/webapp/WEB-INF/Profile.jsp | 86 +++++ src/main/webapp/WEB-INF/Signin.jsp | 40 ++ src/main/webapp/WEB-INF/Style.css | 56 +++ src/main/webapp/WEB-INF/jspf/Footer.jsp | 29 ++ src/main/webapp/WEB-INF/jspf/Header.jsp | 63 +++ src/main/webapp/WEB-INF/jspf/Style.jsp | 361 ++++++++++++++++++ src/main/webapp/WEB-INF/taglibs.jsp | 1 + src/main/webapp/WEB-INF/web.xml | 22 ++ src/main/webapp/index.html | 10 + 33 files changed, 1999 insertions(+) create mode 100644 nb-configuration.xml create mode 100644 pom.xml create mode 100644 src/main/java/g3/Forms/Checkable.java create mode 100644 src/main/java/g3/Forms/FormChecker.java create mode 100644 src/main/java/g3/Forms/LoginFormChecker.java create mode 100644 src/main/java/g3/Forms/SigninFormChecker.java create mode 100644 src/main/java/g3/beans/Identifiable.java create mode 100644 src/main/java/g3/beans/User.java create mode 100644 src/main/java/g3/dao/Crudable.java create mode 100644 src/main/java/g3/dao/Dao.java create mode 100644 src/main/java/g3/dao/DaoFactory.java create mode 100644 src/main/java/g3/dao/DaoUser.java create mode 100644 src/main/java/g3/filters/ConnectFilter.java create mode 100644 src/main/java/g3/filters/isAdminFilter.java create mode 100644 src/main/java/g3/helpers/PasswordAuthentification.java create mode 100644 src/main/java/g3/servelets/Home.java create mode 100644 src/main/java/g3/servelets/Login.java create mode 100644 src/main/java/g3/servelets/Logout.java create mode 100644 src/main/java/g3/servelets/Profile.java create mode 100644 src/main/java/g3/servelets/Signin.java create mode 100644 src/main/webapp/META-INF/context.xml create mode 100644 src/main/webapp/WEB-INF/Admin.jsp create mode 100644 src/main/webapp/WEB-INF/Home.jsp create mode 100644 src/main/webapp/WEB-INF/Login.jsp create mode 100644 src/main/webapp/WEB-INF/Profile.jsp create mode 100644 src/main/webapp/WEB-INF/Signin.jsp create mode 100644 src/main/webapp/WEB-INF/Style.css create mode 100644 src/main/webapp/WEB-INF/jspf/Footer.jsp create mode 100644 src/main/webapp/WEB-INF/jspf/Header.jsp create mode 100644 src/main/webapp/WEB-INF/jspf/Style.jsp create mode 100644 src/main/webapp/WEB-INF/taglibs.jsp create mode 100644 src/main/webapp/WEB-INF/web.xml create mode 100644 src/main/webapp/index.html diff --git a/nb-configuration.xml b/nb-configuration.xml new file mode 100644 index 0000000..cd0068d --- /dev/null +++ b/nb-configuration.xml @@ -0,0 +1,19 @@ + + + + + + 1.7-web + Tomcat + + diff --git a/pom.xml b/pom.xml new file mode 100644 index 0000000..81eb3c7 --- /dev/null +++ b/pom.xml @@ -0,0 +1,97 @@ + + + 4.0.0 + + G3 + Miamle + 1.0-SNAPSHOT + war + + Miamle + + + ${project.build.directory}/endorsed + UTF-8 + + + + + javax + javaee-web-api + 7.0 + provided + + + javax.servlet + jstl + 1.2 + + + + org.mariadb.jdbc + mariadb-java-client + 3.1.4 + + + javax.mail + mail + 1.4.7 + + + com.googlecode.libphonenumber + libphonenumber + 8.12.32 + + + + + + + org.apache.maven.plugins + maven-compiler-plugin + 3.1 + + 1.7 + 1.7 + + ${endorsed.dir} + + + + + org.apache.maven.plugins + maven-war-plugin + 2.3 + + false + + + + org.apache.maven.plugins + maven-dependency-plugin + 2.6 + + + validate + + copy + + + ${endorsed.dir} + true + + + javax + javaee-endorsed-api + 7.0 + jar + + + + + + + + + + diff --git a/src/main/java/g3/Forms/Checkable.java b/src/main/java/g3/Forms/Checkable.java new file mode 100644 index 0000000..818ea88 --- /dev/null +++ b/src/main/java/g3/Forms/Checkable.java @@ -0,0 +1,14 @@ +/* + * To change this license header, choose License Headers in Project Properties. + * To change this template file, choose Tools | Templates + * and open the template in the editor. + */ +package g3.Forms; + +/** + * + * @author stag + */ +public interface Checkable { + boolean checkForm(); +} diff --git a/src/main/java/g3/Forms/FormChecker.java b/src/main/java/g3/Forms/FormChecker.java new file mode 100644 index 0000000..0b29c1d --- /dev/null +++ b/src/main/java/g3/Forms/FormChecker.java @@ -0,0 +1,41 @@ +/* + * To change this license header, choose License Headers in Project Properties. + * To change this template file, choose Tools | Templates + * and open the template in the editor. + */ +package g3.Forms; + +import java.util.HashMap; +import javax.servlet.http.HttpServletRequest; + +/** + * + * @author stag + */ +public abstract class FormChecker implements Checkable{ + protected final HttpServletRequest request; + protected final HashMap errors; + protected T bean; + + + public FormChecker(HttpServletRequest request) { + this.request = request; + errors = new HashMap<>(); + } + + public HashMap getErrors() { + return errors; + } + + private String getParameter(String field) { + if (request.getParameter(field) == null || request.getParameter(field).trim().length() == 0) { + return null; + } else { + return request.getParameter(field).trim(); + } + } + + public T getBean() { + return bean; + } +} diff --git a/src/main/java/g3/Forms/LoginFormChecker.java b/src/main/java/g3/Forms/LoginFormChecker.java new file mode 100644 index 0000000..5a729b0 --- /dev/null +++ b/src/main/java/g3/Forms/LoginFormChecker.java @@ -0,0 +1,62 @@ +/* + * To change this license header, choose License Headers in Project Properties. + * To change this template file, choose Tools | Templates + * and open the template in the editor. + */ +package g3.Forms; + +/** + * + * @author stag + */ +import g3.beans.User; +import g3.dao.DaoFactory; +import g3.helpers.PasswordAuthentification; +import javax.servlet.http.HttpServletRequest; + +public class LoginFormChecker extends FormChecker { + + private static final String PSEUDO_FIELD = "pseudo"; + private static final String PWD_FIELD = "pwd"; + + public LoginFormChecker(HttpServletRequest request) { + super(request); + } + + @Override + public boolean checkForm() { + String pseudo = request.getParameter(PSEUDO_FIELD); + String pwd = request.getParameter(PWD_FIELD); + + bean = new User(23, null, pseudo, pwd); + + if (pseudo == null || pseudo.trim().length() < 3) { + errors.put(PSEUDO_FIELD, "Doit faire au moins 3 caractères"); + } + + if (pwd.length() < 6) { + errors.put(PWD_FIELD, "Doit faire au moins 6 caractères"); + } + + if (errors.isEmpty()) { + User user = DaoFactory.getUserDao().getByName(pseudo); + // Vérifications de l'existence de l'utilisateur + PasswordAuthentification pa = new PasswordAuthentification(); + try { + // Attention, la méthode authenticate lance des exceptions silencieuses... + if (user == null || !pa.authenticate(pwd.toCharArray(), user.getPassword())) { + errors.put(PSEUDO_FIELD, "Utilisateur ou mot de passe erroné"); + } else { + // L'utilisateur est le bon + bean = user; + } + } catch (IllegalArgumentException ex) { + errors.put(PSEUDO_FIELD, "Utilisateur ou mot de passe erroné"); + + } + } + + return errors.isEmpty(); + + } +} diff --git a/src/main/java/g3/Forms/SigninFormChecker.java b/src/main/java/g3/Forms/SigninFormChecker.java new file mode 100644 index 0000000..a346493 --- /dev/null +++ b/src/main/java/g3/Forms/SigninFormChecker.java @@ -0,0 +1,109 @@ +/* + * To change this license header, choose License Headers in Project Properties. + * To change this template file, choose Tools | Templates + * and open the template in the editor. + */ +package g3.Forms; + +/** + * + * @author stag + */ +import com.google.i18n.phonenumbers.NumberParseException; +import g3.beans.User; +import g3.dao.DaoFactory; +import g3.helpers.PasswordAuthentification; +import javax.servlet.http.HttpServletRequest; +import javax.mail.internet.InternetAddress; +import com.google.i18n.phonenumbers.PhoneNumberUtil; +import com.google.i18n.phonenumbers.Phonenumber.PhoneNumber; + +public class SigninFormChecker extends FormChecker { + + private static final String CONTACT_FIELD = "contact"; + private static final String PWD_FIELD = "password"; + private static final String CONFIRM_PWD_FIELD = "confirmPassword"; + private static final String PSEUDO_FIELD = "pseudo"; + + public SigninFormChecker(HttpServletRequest request) { + super(request); + } + + @Override + public boolean checkForm() { + + String contact = request.getParameter(CONTACT_FIELD); + String password = request.getParameter(PWD_FIELD); + String confirmPassword = request.getParameter(CONFIRM_PWD_FIELD); + String pseudo = request.getParameter(PSEUDO_FIELD); + bean = new User(pseudo, contact, password); + + if (contact == null || contact.trim().isEmpty()) { + errors.put(CONTACT_FIELD, "Le contact est obligatoire."); + } else { + // Vérifiez si le contact est un e-mail + if (contact.contains("@")) { + // Vérifiez si l'adresse e-mail est valide + if (!isValidEmail(contact)) { + errors.put(CONTACT_FIELD, "L'adresse e-mail n'est pas valide. Veuillez entrer une adresse e-mail valide."); + } + } else { + // Vérifiez si le contact est un num de téléphone français + PhoneNumberUtil phoneUtil = PhoneNumberUtil.getInstance(); + try { + PhoneNumber phoneNumber = phoneUtil.parse(contact, "FR"); // "FR" for France + if (!phoneUtil.isValidNumber(phoneNumber)) { + errors.put(CONTACT_FIELD, "Le contact n'est pas un numéro de téléphone valide en France."); + } + } catch (NumberParseException e) { + errors.put(CONTACT_FIELD, "Le contact n'est pas un numéro de téléphone valide."); + } + } + } + + if (password == null || password.length() < 6) { + password = ""; // nécessaire pour simplifier la tentative de hashage + errors.put(PWD_FIELD, "Doit contenir au moins 6 caractères"); + } else { + if (confirmPassword == null || !password.equals(confirmPassword)) { + errors.put(CONFIRM_PWD_FIELD, "Doit être identique au mot de passe"); + } + } + + if (pseudo == null || pseudo.trim().isEmpty()) { + errors.put(PSEUDO_FIELD, "Le pseudo est obligatoire."); + } else if (pseudo.length() < 3) { + errors.put(PSEUDO_FIELD, "Le pseudo doit contenir au moins 3 caractères."); + } else { + // Check if the pseudo already exists in the database + User existingUser = DaoFactory.getUserDao().getByName(pseudo); + if (existingUser != null) { + errors.put(PSEUDO_FIELD, "Ce pseudo est déjà utilisé."); + } + } + + if (errors.isEmpty()) { + PasswordAuthentification pa = new PasswordAuthentification(); + bean.setPassword(pa.hash(password.toCharArray())); + DaoFactory.getUserDao().insert(bean); + if (bean.getId() == null) { + errors.put(PSEUDO_FIELD, "Ce pseudo est déja utilisé !!!"); + } + } + + return errors.isEmpty(); + + } + + public boolean isValidEmail(String email) { + boolean result = true; + try { + InternetAddress emailAddr = new InternetAddress(email); + emailAddr.validate(); + } catch (Exception ex) { + result = false; + } + return result; + } + +} diff --git a/src/main/java/g3/beans/Identifiable.java b/src/main/java/g3/beans/Identifiable.java new file mode 100644 index 0000000..f6c3ed2 --- /dev/null +++ b/src/main/java/g3/beans/Identifiable.java @@ -0,0 +1,18 @@ +/* + * To change this license header, choose License Headers in Project Properties. + * To change this template file, choose Tools | Templates + * and open the template in the editor. + */ +package g3.beans; + +/** + * + * @author stag + */ +public interface Identifiable { + Integer getId(); + void setId(Integer id); +} + + + diff --git a/src/main/java/g3/beans/User.java b/src/main/java/g3/beans/User.java new file mode 100644 index 0000000..1c79fde --- /dev/null +++ b/src/main/java/g3/beans/User.java @@ -0,0 +1,83 @@ +/* + * To change this license header, choose License Headers in Project Properties. + * To change this template file, choose Tools | Templates + * and open the template in the editor. + */ +package g3.beans; + +/** + * + * @author stag + */ +public class User implements Identifiable { + + private Integer id_user; + private String pseudo; + private String contact; + private String password; + + public User() { + } + + public User(Integer id, String pseudo, String contact, String password) { + this.id_user = id; + this.pseudo = pseudo; + this.contact = contact; + this.password = password; + } + + public User(String pseudo, String contact, String password) { + this.pseudo = pseudo; + this.contact = contact; + this.password = password; + } + + public User(String pseudo, String password) { + this.pseudo = pseudo; + this.password = password; + } + + // getters and setters + public String getContact() { + return contact; + } + + public String getPseudo() { + return pseudo; + } + + public void setPseudo(String pseudo) { + this.pseudo = pseudo; + } + + public String getPassword() { + return password; + } + + public void setPassword(String password) { + this.password = password; + } + + public void setContact(String contact) { + this.contact = contact; + } + + public Integer getId_user() { + return id_user; + } + + public void setId_user(Integer id_user) { + this.id_user = id_user; + } + + @Override + public Integer getId() { + return id_user; + } + + @Override + public void setId(Integer id_user) { + this.id_user = id_user; + } + +} diff --git a/src/main/java/g3/dao/Crudable.java b/src/main/java/g3/dao/Crudable.java new file mode 100644 index 0000000..53b7353 --- /dev/null +++ b/src/main/java/g3/dao/Crudable.java @@ -0,0 +1,34 @@ +/* + * To change this license header, choose License Headers in Project Properties. + * To change this template file, choose Tools | Templates + * and open the template in the editor. + */ +package g3.dao; + +import java.util.*; + + +/** + * + * @author stag + */ +public interface Crudable { + + Collection getAll(); + + int count(); + + T getById(int id); + + void insert(T obj); + + void update(T obj); + + void delete(T obj); + + void delete(int id); +} + + + + diff --git a/src/main/java/g3/dao/Dao.java b/src/main/java/g3/dao/Dao.java new file mode 100644 index 0000000..66d9f4f --- /dev/null +++ b/src/main/java/g3/dao/Dao.java @@ -0,0 +1,86 @@ +/* + * To change this license header, choose License Headers in Project Properties. + * To change this template file, choose Tools | Templates + * and open the template in the editor. + */ +package g3.dao; + +import g3.beans.Identifiable; +import java.sql.Connection; +import java.sql.DriverManager; +import java.sql.PreparedStatement; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.util.logging.Level; +import java.util.logging.Logger; +import javax.swing.JOptionPane; + +/** + * + * @author stag + */ +public abstract class Dao implements Crudable { + + protected Connection connection; + private String url; + private final String user = "miamle"; + private final String pwd = "miamle"; + private final String DBType = "mariadb"; + private final String DBip = "localhost"; + private final int DBPort = 3306; + private final String DBName = "Miamle"; + protected String tableName; + + public Dao(String tableName) { + this.tableName = tableName; + try { + Class.forName("org.mariadb.jdbc.Driver"); + url = "jdbc:" + DBType + "://" + DBip + ":" + DBPort + "/" + DBName; + connection = DriverManager.getConnection(url, user, pwd); + } catch (ClassNotFoundException | SQLException ex) { + JOptionPane.showMessageDialog(null, "Connexion à la DB impossible", "Erreur", JOptionPane.ERROR_MESSAGE); + System.exit(1); + } + } + + @Override + public int count() { + String req = "SELECT COUNT(*) AS total FROM " + tableName; + int count = 0; + try { + PreparedStatement pstmt = connection.prepareStatement(req); + ResultSet rs = pstmt.executeQuery(); + if (rs.first()) { + count = rs.getInt("total"); + } + } catch (SQLException ex) { + Logger.getLogger(Dao.class.getName()).log(Level.SEVERE, null, ex); + } + return count; + } + + @Override + public void delete(T obj) { + String req = "DELETE FROM " + tableName + " WHERE id_" + tableName + "=?"; + try { + PreparedStatement pstmt = connection.prepareStatement(req); + pstmt.setInt(1, obj.getId()); + int nbLignesImpactees = pstmt.executeUpdate(); + } catch (SQLException ex) { + Logger.getLogger(Dao.class.getName()).log(Level.SEVERE, null, ex); + } + } + + @Override + public void delete(int id) { + String req = "DELETE FROM " + tableName + " WHERE id_" + tableName + "=?"; + try { + PreparedStatement pstmt = connection.prepareStatement(req); + pstmt.setInt(1, id); + int nbLignesImpactees = pstmt.executeUpdate(); + } catch (SQLException ex) { + Logger.getLogger(Dao.class.getName()).log(Level.SEVERE, null, ex); + } + } + +} diff --git a/src/main/java/g3/dao/DaoFactory.java b/src/main/java/g3/dao/DaoFactory.java new file mode 100644 index 0000000..4c8a0f1 --- /dev/null +++ b/src/main/java/g3/dao/DaoFactory.java @@ -0,0 +1,19 @@ +/* + * To change this license header, choose License Headers in Project Properties. + * To change this template file, choose Tools | Templates + * and open the template in the editor. + */ +package g3.dao; + +/** + * + * @author stag + */ +public class DaoFactory { + + public static DaoUser getUserDao() { + return new DaoUser(); + } + + +} diff --git a/src/main/java/g3/dao/DaoUser.java b/src/main/java/g3/dao/DaoUser.java new file mode 100644 index 0000000..0290651 --- /dev/null +++ b/src/main/java/g3/dao/DaoUser.java @@ -0,0 +1,155 @@ +/* + * To change this license header, choose License Headers in Project Properties. + * To change this template file, choose Tools | Templates + * and open the template in the editor. + */ +package g3.dao; + +import g3.beans.User; +import java.sql.PreparedStatement; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.util.ArrayList; +import java.util.Collection; +import java.util.logging.Level; +import java.util.logging.Logger; + +/** + * + * @author stag + */ +public class DaoUser extends Dao { + + public DaoUser() { + super("user"); + } + + @Override + public Collection getAll() { + ArrayList objects = new ArrayList<>(); + String req = "SELECT * FROM " + tableName; + try { + PreparedStatement pstmt = connection.prepareStatement(req); + ResultSet rs = pstmt.executeQuery(); + while (rs.next()) { + objects.add( + new User( + rs.getInt("id_" + tableName), + rs.getString("pseudo"), + rs.getString("contact"), + rs.getString("password") + ) + ); + } + } catch (SQLException ex) { + Logger.getLogger(DaoUser.class.getName()).log(Level.SEVERE, null, ex); + } + + return objects; + } + + @Override + public User getById(int id) { + User obj = null; + String req = "SELECT * FROM " + tableName + " WHERE id_" + tableName + "=?"; + try { + PreparedStatement pstmt = connection.prepareStatement(req); + pstmt.setInt(1, id); + ResultSet rs = pstmt.executeQuery(); + if (rs.first()) { + obj = new User( + rs.getInt("id_" + tableName), + rs.getString("pseudo"), + rs.getString("contact"), + rs.getString("password") + ); + } + } catch (SQLException ex) { + Logger.getLogger(DaoUser.class.getName()).log(Level.SEVERE, null, ex); + } + return obj; + } + + @Override + public void insert(User obj) { + String req = "INSERT INTO " + tableName + " (pseudo, contact, password) VALUES (?, ?, ?)"; + try { + PreparedStatement pstmt = connection.prepareStatement(req, PreparedStatement.RETURN_GENERATED_KEYS); + pstmt.setString(1, obj.getPseudo()); + pstmt.setString(2, obj.getContact()); + pstmt.setString(3, obj.getPassword()); + int nbLignesImpactees = pstmt.executeUpdate(); + ResultSet generatedKeys = pstmt.getGeneratedKeys(); + if (generatedKeys.first()) { + obj.setId(generatedKeys.getInt(1)); + } + } catch (SQLException ex) { + Logger.getLogger(DaoUser.class.getName()).log(Level.SEVERE, null, ex); + } + } + + @Override + public void update(User obj) { + String req = "UPDATE " + tableName + " SET pseudo=?, contact=?, password=? WHERE id_" + tableName + "=?"; + try { + PreparedStatement pstmt = connection.prepareStatement(req); + pstmt.setString(1, obj.getPseudo()); + pstmt.setString(2, obj.getContact()); + pstmt.setString(3, obj.getPassword()); + pstmt.setInt(4, obj.getId()); + int nbLignesImpactees = pstmt.executeUpdate(); + } catch (SQLException ex) { + Logger.getLogger(DaoUser.class.getName()).log(Level.SEVERE, null, ex); + } + } + + /** + * + * methode de recherche + * + * + */ + public User getByName(String pseudo) { + User obj = null; + String req = "SELECT * FROM " + tableName + " WHERE pseudo=?"; + try { + PreparedStatement pstmt = connection.prepareStatement(req); + pstmt.setString(1, pseudo); + ResultSet rs = pstmt.executeQuery(); + if (rs.first()) { + obj = new User( + rs.getInt("id_" + tableName), + rs.getString("pseudo"), + rs.getString("contact"), + rs.getString("password") + ); + } + } catch (SQLException ex) { + Logger.getLogger(DaoUser.class.getName()).log(Level.SEVERE, null, ex); + } + return obj; + } + + //par Pseudo + public User getByName(User user) { + User obj = null; + String req = "SELECT * FROM " + tableName + " WHERE pseudo=?"; + try { + PreparedStatement pstmt = connection.prepareStatement(req); + pstmt.setString(1, user.getPseudo()); + ResultSet rs = pstmt.executeQuery(); + if (rs.first()) { + obj = new User( + rs.getInt("id_" + tableName), + rs.getString("pseudo"), + rs.getString("contact"), + rs.getString("password") + ); + } + } catch (SQLException ex) { + Logger.getLogger(DaoUser.class.getName()).log(Level.SEVERE, null, ex); + } + return obj; + } + +} diff --git a/src/main/java/g3/filters/ConnectFilter.java b/src/main/java/g3/filters/ConnectFilter.java new file mode 100644 index 0000000..7a99b1a --- /dev/null +++ b/src/main/java/g3/filters/ConnectFilter.java @@ -0,0 +1,46 @@ +/* + * To change this license header, choose License Headers in Project Properties. + * To change this template file, choose Tools | Templates + * and open the template in the editor. + */ +package g3.filters; + +import g3.beans.User; +import java.io.IOException; +import javax.servlet.Filter; +import javax.servlet.FilterChain; +import javax.servlet.FilterConfig; +import javax.servlet.ServletException; +import javax.servlet.ServletRequest; +import javax.servlet.ServletResponse; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpSession; + +/** + * + * @author stag + */ +public class ConnectFilter implements Filter { + + @Override + public void init(FilterConfig filterConfig) throws ServletException { + } + + @Override + public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { + HttpSession session = ((HttpServletRequest) request).getSession(); + // Travail avant l'appel à la servlet + if (session.getAttribute("user") != null && ((User) session.getAttribute("user")).getId() == 1) { + session.setAttribute("isAdmin", true); + } + // Appel à la servlet + chain.doFilter(request, response); + // Travail après la servlet mais avant la réponse + + } + + @Override + public void destroy() { + } + +} diff --git a/src/main/java/g3/filters/isAdminFilter.java b/src/main/java/g3/filters/isAdminFilter.java new file mode 100644 index 0000000..3ff4cbb --- /dev/null +++ b/src/main/java/g3/filters/isAdminFilter.java @@ -0,0 +1,50 @@ +/* + * To change this license header, choose License Headers in Project Properties. + * To change this template file, choose Tools | Templates + * and open the template in the editor. + */ +package g3.filters; + +import g3.beans.User; +import java.io.IOException; +import javax.servlet.Filter; +import javax.servlet.FilterChain; +import javax.servlet.FilterConfig; +import javax.servlet.ServletException; +import javax.servlet.ServletRequest; +import javax.servlet.ServletResponse; +import javax.servlet.annotation.WebFilter; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpSession; + +/** + * + * @author stag + */ +@WebFilter(urlPatterns = "/*") +public class isAdminFilter implements Filter { + + @Override + public void init(FilterConfig filterConfig) throws ServletException { + } + + @Override + public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { + // À l'aller : je travaille sur la requête + HttpSession session = ((HttpServletRequest) request).getSession(); + + User user = (User) session.getAttribute("user"); + if (user != null && user.getId() == 1) { + session.setAttribute("isAdmin", true); + } else { + session.removeAttribute("isAdmin"); + } + + chain.doFilter(request, response); + } + + @Override + public void destroy() { + } + +} diff --git a/src/main/java/g3/helpers/PasswordAuthentification.java b/src/main/java/g3/helpers/PasswordAuthentification.java new file mode 100644 index 0000000..ee31c24 --- /dev/null +++ b/src/main/java/g3/helpers/PasswordAuthentification.java @@ -0,0 +1,139 @@ +/* + * To change this license header, choose License Headers in Project Properties. + * To change this template file, choose Tools | Templates + * and open the template in the editor. + */ +package g3.helpers; + +import java.security.NoSuchAlgorithmException; +import java.security.SecureRandom; +import java.security.spec.InvalidKeySpecException; +import java.security.spec.KeySpec; +import java.util.Arrays; +import java.util.Base64; +import java.util.regex.Matcher; +import java.util.regex.Pattern; +import javax.crypto.SecretKeyFactory; +import javax.crypto.spec.PBEKeySpec; + +/** + * + * @author stag + */ +public final class PasswordAuthentification { + + private static final String INIT_ID = "51"; + + /** + * Each token produced by this class uses this identifier as a prefix. + */ + public static final String ID = "$" + INIT_ID + "$"; + + /** + * The minimum recommended cost, used by default + */ + public static final int DEFAULT_COST = 16; + private static final String ALGORITHM = "PBKDF2WithHmacSHA512"; + private static final int SIZE = 128; + private static final Pattern LAYOUT = Pattern.compile("\\$" + INIT_ID + "\\$(\\d\\d?)\\$(.{43})"); + private final SecureRandom random; + private final int cost; + + /** + * Create a password manager with a default cost + */ + public PasswordAuthentification() { + this(DEFAULT_COST); + } + + /** + * Create a password manager with a specified cost + * + * @param cost the exponential computational cost of hashing a password, 0 + * to 30 + */ + public PasswordAuthentification(int cost) { + iterations(cost); + /* Validate cost */ + this.cost = cost; + this.random = new SecureRandom(); + } + + private static int iterations(int cost) { + if ((cost < 0) || (cost > 30)) { + throw new IllegalArgumentException("cost: " + cost); + } + return 1 << cost; // Décalage du bit à gauche : 0001 << 3 revient à 1000 + } + + /** + * Hash a password for storage. + * + * @param password The password to hash + * @return a secure authentication token to be stored for later + * authentication + */ + public String hash(char[] password) { + byte[] salt = new byte[SIZE / 8]; + random.nextBytes(salt); + byte[] dk = pbkdf2(password, salt, 1 << cost); + byte[] hash = new byte[salt.length + dk.length]; + System.arraycopy(salt, 0, hash, 0, salt.length); + System.arraycopy(dk, 0, hash, salt.length, dk.length); + Base64.Encoder enc = Base64.getUrlEncoder().withoutPadding(); + return ID + cost + '$' + enc.encodeToString(hash); + } + + /** + * Authenticate with a password and a stored password token. + * + * @param password The password to compare + * @param token The token to compare the password to + * @return true if the password and token match + */ + public boolean authenticate(char[] password, String token) { + Matcher m = LAYOUT.matcher(token); + if (!m.matches()) { + throw new IllegalArgumentException("Invalid token format"); + } + int iterations = iterations(Integer.parseInt(m.group(1))); + byte[] hash = Base64.getUrlDecoder().decode(m.group(2)); + byte[] salt = Arrays.copyOfRange(hash, 0, SIZE / 8); + byte[] check = pbkdf2(password, salt, iterations); + int zero = 0; + for (int idx = 0; idx < check.length; ++idx) { + zero |= hash[salt.length + idx] ^ check[idx]; + } + return zero == 0; + } + + private static byte[] pbkdf2(char[] password, byte[] salt, int iterations) { + KeySpec spec = new PBEKeySpec(password, salt, iterations, SIZE); + try { + SecretKeyFactory f = SecretKeyFactory.getInstance(ALGORITHM); + return f.generateSecret(spec).getEncoded(); + } catch (NoSuchAlgorithmException ex) { + throw new IllegalStateException("Missing algorithm: " + ALGORITHM, ex); + } catch (InvalidKeySpecException ex) { + throw new IllegalStateException("Invalid SecretKeyFactory", ex); + } + } + + /** + * Hash a password in an immutable {@code String}. + * + *

+ * Passwords should be stored in a {@code char[]} so that it can be filled + * with zeros after use instead of lingering on the heap and elsewhere. + * + * @param password The password to hash + * @return a secure authentication token to be stored for later + * authentication + * @deprecated Use {@link #hash(char[])} instead + */ + @Deprecated + public String hash(String password) { + return hash(password.toCharArray()); + } + +} diff --git a/src/main/java/g3/servelets/Home.java b/src/main/java/g3/servelets/Home.java new file mode 100644 index 0000000..a202bc8 --- /dev/null +++ b/src/main/java/g3/servelets/Home.java @@ -0,0 +1,34 @@ +package g3.servelets; + +import g3.dao.DaoFactory; +import java.io.IOException; +import javax.servlet.ServletException; +import javax.servlet.annotation.WebServlet; +import javax.servlet.http.HttpServlet; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +@WebServlet(name = "home", urlPatterns = {"/home"}) +public class Home extends HttpServlet { + + private static final String VIEW = "/WEB-INF/Home.jsp"; + + @Override + protected void doGet(HttpServletRequest request, HttpServletResponse response) + throws ServletException, IOException { + + // On récupère les infos depuis la DB + + + // On appelle la vue + request.getServletContext() + .getRequestDispatcher("/WEB-INF/Home.jsp") + .forward(request, response); + + } + + @Override + public String getServletInfo() { + return "Short description"; + } +} diff --git a/src/main/java/g3/servelets/Login.java b/src/main/java/g3/servelets/Login.java new file mode 100644 index 0000000..91a1873 --- /dev/null +++ b/src/main/java/g3/servelets/Login.java @@ -0,0 +1,57 @@ +package g3.servelets; + +import g3.Forms.LoginFormChecker; +import g3.beans.User; +import java.io.*; +import javax.servlet.*; +import javax.servlet.annotation.*; +import javax.servlet.http.*; + +@WebServlet(name = "login", urlPatterns = {"/login"}) +public class Login extends HttpServlet { + + private static final String VIEW = "/WEB-INF/Login.jsp"; + private static final String VIEW_ADMIN = "/WEB-INF/Admin.jsp"; + + @Override + protected void doGet(HttpServletRequest request, HttpServletResponse response) + throws ServletException, IOException { + if (request.getSession().getAttribute("user") == null) { + RequestDispatcher dispatcher = request.getServletContext().getRequestDispatcher(VIEW); + dispatcher.forward(request, response); + } else { + User myUser = (User) request.getSession().getAttribute("user"); + if (myUser.getId_user() == 1) { + request.getServletContext().getRequestDispatcher(VIEW_ADMIN).forward(request, response); + } else { + response.sendRedirect(request.getContextPath() + "/home"); + } + } + } + + @Override + protected void doPost(HttpServletRequest request, HttpServletResponse response) + throws ServletException, IOException { + LoginFormChecker checker = new LoginFormChecker(request); + if (!checker.checkForm()) { + //Assurer que l'utilisateur n'est plus en session + request.getSession().invalidate(); + + request.setAttribute("errors", checker.getErrors()); + request.setAttribute("userData", checker.getBean()); + + request.getServletContext() + .getRequestDispatcher(VIEW) + .forward(request, response); + + } else { + + //je met l'utilisateur en session + request.getSession().setAttribute("user", checker.getBean()); + + response.sendRedirect(request.getContextPath() + "/home"); + + } + } + +} diff --git a/src/main/java/g3/servelets/Logout.java b/src/main/java/g3/servelets/Logout.java new file mode 100644 index 0000000..09a3ba5 --- /dev/null +++ b/src/main/java/g3/servelets/Logout.java @@ -0,0 +1,55 @@ +/* + * To change this license header, choose License Headers in Project Properties. + * To change this template file, choose Tools | Templates + * and open the template in the editor. + */ +package g3.servelets; + +import java.io.IOException; +import java.io.PrintWriter; +import javax.servlet.RequestDispatcher; +import javax.servlet.ServletException; +import javax.servlet.annotation.WebServlet; +import javax.servlet.http.HttpServlet; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +/** + * + * @author stag + */ +@WebServlet(name = "Logout", urlPatterns = {"/logout"}) +public class Logout extends HttpServlet { + + + private static final String VIEW = "/WEB-INF/Home.jsp"; + + + + // + /** + * Handles the HTTP GET method. + * + * @param request servlet request + * @param response servlet response + * @throws ServletException if a servlet-specific error occurs + * @throws IOException if an I/O error occurs + */ + @Override + protected void doGet(HttpServletRequest request, HttpServletResponse response) + throws ServletException, IOException { + if (request.getSession().getAttribute("user") == null) { + RequestDispatcher dispatcher = request.getServletContext().getRequestDispatcher(VIEW); + dispatcher.forward(request, response); + } else { + //invalidation + request.getSession().invalidate(); + //redirection vers accueil + response.sendRedirect(request.getContextPath() + "/home"); + + } + + + } + +} diff --git a/src/main/java/g3/servelets/Profile.java b/src/main/java/g3/servelets/Profile.java new file mode 100644 index 0000000..89d30bd --- /dev/null +++ b/src/main/java/g3/servelets/Profile.java @@ -0,0 +1,56 @@ +/* + * To change this license header, choose License Headers in Project Properties. + * To change this template file, choose Tools | Templates + * and open the template in the editor. + */ +package g3.servelets; + +import java.io.IOException; +import java.io.PrintWriter; +import javax.servlet.ServletException; +import javax.servlet.annotation.WebServlet; +import javax.servlet.http.HttpServlet; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +/** + * + * @author stag + */ +@WebServlet(name = "Profile", urlPatterns = {"/profile"}) +public class Profile extends HttpServlet { + + + private static final String VIEW = "/WEB-INF/Profile.jsp"; + + + + + @Override + protected void doGet(HttpServletRequest request, HttpServletResponse response) + throws ServletException, IOException { + //verifier que user est connecté + if (request.getSession().getAttribute("user") != null) { + request.getRequestDispatcher(VIEW) + .forward(request, response); + } else { + response.sendRedirect(request.getContextPath() + "/login"); + } + + } + + /** + * Handles the HTTP POST method. + * + * @param request servlet request + * @param response servlet response + * @throws ServletException if a servlet-specific error occurs + * @throws IOException if an I/O error occurs + */ + @Override + protected void doPost(HttpServletRequest request, HttpServletResponse response) + throws ServletException, IOException { + + } + +} diff --git a/src/main/java/g3/servelets/Signin.java b/src/main/java/g3/servelets/Signin.java new file mode 100644 index 0000000..1a7650f --- /dev/null +++ b/src/main/java/g3/servelets/Signin.java @@ -0,0 +1,59 @@ +package g3.servelets; + +import g3.Forms.SigninFormChecker; +import g3.beans.User; +import java.io.IOException; +import javax.servlet.RequestDispatcher; +import javax.servlet.ServletException; +import javax.servlet.annotation.WebServlet; +import javax.servlet.http.HttpServlet; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +@WebServlet(name = "sign-in", urlPatterns = {"/sign-in"}) +public class Signin extends HttpServlet { + + private static final String VIEW = "/WEB-INF/Signin.jsp"; + private static final String VIEW_ADMIN = "/WEB-INF/Admin.jsp"; + + @Override + protected void doGet(HttpServletRequest request, HttpServletResponse response) + throws ServletException, IOException { + if (request.getSession().getAttribute("user") == null) { + RequestDispatcher dispatcher = request.getServletContext().getRequestDispatcher(VIEW); + dispatcher.forward(request, response); + } else { + User myUser = (User) request.getSession().getAttribute("user"); + if (myUser.getId_user() == 1) { + request.getServletContext().getRequestDispatcher(VIEW_ADMIN).forward(request, response); + } else { + response.sendRedirect(request.getContextPath() + "/home"); + } + } + } + + @Override + protected void doPost(HttpServletRequest request, HttpServletResponse response) + throws ServletException, IOException { + SigninFormChecker checker = new SigninFormChecker(request); + if (!checker.checkForm()) { + //Assurer que l'utilisateur n'est plus en session + request.getSession().invalidate(); + + request.setAttribute("errors", checker.getErrors()); + //request.setAttribute("userD", checker.getBean()); + + request.getServletContext() + .getRequestDispatcher(VIEW) + .forward(request, response); + + } else { + + //je met l'utilisateur en session + request.getSession().setAttribute("user", checker.getBean()); + + response.sendRedirect(request.getContextPath() + "/home"); + + } + } +} diff --git a/src/main/webapp/META-INF/context.xml b/src/main/webapp/META-INF/context.xml new file mode 100644 index 0000000..2b2fa52 --- /dev/null +++ b/src/main/webapp/META-INF/context.xml @@ -0,0 +1,2 @@ + + diff --git a/src/main/webapp/WEB-INF/Admin.jsp b/src/main/webapp/WEB-INF/Admin.jsp new file mode 100644 index 0000000..a9def0c --- /dev/null +++ b/src/main/webapp/WEB-INF/Admin.jsp @@ -0,0 +1,17 @@ +<%-- + Document : Admin + Created on : 5 mai 2023, 13:03:36 + Author : stag +--%> + +<%@page contentType="text/html" pageEncoding="UTF-8"%> + + + + + Admin Page + + +

Hello World!

+ + diff --git a/src/main/webapp/WEB-INF/Home.jsp b/src/main/webapp/WEB-INF/Home.jsp new file mode 100644 index 0000000..2c81d72 --- /dev/null +++ b/src/main/webapp/WEB-INF/Home.jsp @@ -0,0 +1,45 @@ +<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> + + + + <%@page contentType="text/html" pageEncoding="UTF-8"%> + <%@include file="/WEB-INF/jspf/Style.jsp" %> + Blog + + + + <%@include file="/WEB-INF/jspf/Header.jsp" %> + +

La liste des évenements

+ + //tableau des évenements + + + <%@include file="./jspf/Footer.jsp" %> + + + + + diff --git a/src/main/webapp/WEB-INF/Login.jsp b/src/main/webapp/WEB-INF/Login.jsp new file mode 100644 index 0000000..e94ac3d --- /dev/null +++ b/src/main/webapp/WEB-INF/Login.jsp @@ -0,0 +1,34 @@ +<%@include file="taglibs.jsp" %> +<%@page contentType="text/html" pageEncoding="UTF-8"%> + + + + + <%@include file="/WEB-INF/jspf/Style.jsp" %> + + Connexion + + + <%@include file="/WEB-INF/jspf/Header.jsp" %> +

Page de connexion

+ + +

${errorMessage}

+
+ +
+ + " required>
+ ${errors.pseudo} + + +
+ + ${errors.pwd} + + + +
+ <%@include file="./jspf/Footer.jsp" %> + + diff --git a/src/main/webapp/WEB-INF/Profile.jsp b/src/main/webapp/WEB-INF/Profile.jsp new file mode 100644 index 0000000..55c4e47 --- /dev/null +++ b/src/main/webapp/WEB-INF/Profile.jsp @@ -0,0 +1,86 @@ +<%-- + Document : Profile + Created on : 5 mai 2023, 03:35:35 + Author : stag +--%> + +<%@page contentType="text/html" pageEncoding="UTF-8"%> + + + + + JSP Page + <%@include file="/WEB-INF/jspf/Style.jsp" %> + + + + <%@include file="/WEB-INF/jspf/Header.jsp" %> +

Vos informations personnelles

+ + + + + + + + + + + + + + + + + +
Votre id : ${sessionScope.user.id}
Votre Pseudo : ${sessionScope.user.pseudo}
Votre Contact : ${sessionScope.user.contact}
Votre mot de passe : ${sessionScope.user.password}
+ + + <%@include file="./jspf/Footer.jsp" %> + + + + diff --git a/src/main/webapp/WEB-INF/Signin.jsp b/src/main/webapp/WEB-INF/Signin.jsp new file mode 100644 index 0000000..bae04e2 --- /dev/null +++ b/src/main/webapp/WEB-INF/Signin.jsp @@ -0,0 +1,40 @@ +<%@include file="taglibs.jsp" %> + +<%@page contentType="text/html" pageEncoding="UTF-8"%> + + + + + + <%@include file="/WEB-INF/jspf/Style.jsp" %> + + Inscription + + + <%@include file="/WEB-INF/jspf/Header.jsp" %> +

Page d'inscription

+ +
+ +
+ ${requestScope.errors.contact} + + +
+ ${requestScope.errors.password} + + +
+ ${requestScope.errors.confirmPassword} + + +
+ ${requestScope.errors.pseudo} + + + +
+ <%@include file="./jspf/Footer.jsp" %> + + + diff --git a/src/main/webapp/WEB-INF/Style.css b/src/main/webapp/WEB-INF/Style.css new file mode 100644 index 0000000..2a1a1b7 --- /dev/null +++ b/src/main/webapp/WEB-INF/Style.css @@ -0,0 +1,56 @@ +form { + display: flex; + flex-direction: column; + align-items: center; + justify-content: center; + margin: 0 auto; + width: 40%; + padding: 30px; + border-radius: 10px; + background: #2B3A42; + box-shadow: 0px 5px 20px rgba(0, 0, 0, 0.5); +} + +h1 { + color: #F7DC6F; + text-align: center; + font-size: 2.5rem; +} + +label { + color: #F7DC6F; + font-size: 1.5rem; + font-weight: bold; + margin-bottom: 10px; +} + +input[type=text], input[type=password] { + padding: 15px; + border: none; + border-radius: 10px; + margin-bottom: 20px; + width: 100%; + background-color: #F7DC6F; + color: #2B3A42; + font-size: 1.2rem; +} + +input[type=submit] { + background-color: #F7DC6F; + color: #2B3A42; + padding: 15px 30px; + border: none; + border-radius: 10px; + font-size: 1.2rem; + cursor: pointer; +} + +input[type=submit]:hover { + background-color: #34495E; + color: #F7DC6F; +} + +.error-message { + color: red; + font-weight: bold; +} diff --git a/src/main/webapp/WEB-INF/jspf/Footer.jsp b/src/main/webapp/WEB-INF/jspf/Footer.jsp new file mode 100644 index 0000000..ab31941 --- /dev/null +++ b/src/main/webapp/WEB-INF/jspf/Footer.jsp @@ -0,0 +1,29 @@ +<%-- + Document : Footer + Created on : 27 avr. 2023, 12:59:37 + Author : stag +--%> + +<%@page contentType="text/html" pageEncoding="UTF-8"%> +
+ + Vous etes connecté avec le id: ${sessionScope.user.id} pseudo: + ${sessionScope.user.pseudo} et Vos contact : ${sessionScope.user.contact} + + vous n'êtes pas connecté. + + + et vous êtes administrateur +
diff --git a/src/main/webapp/WEB-INF/jspf/Header.jsp b/src/main/webapp/WEB-INF/jspf/Header.jsp new file mode 100644 index 0000000..b442664 --- /dev/null +++ b/src/main/webapp/WEB-INF/jspf/Header.jsp @@ -0,0 +1,63 @@ +<%-- + Document : Header + Created on : 27 avr. 2023, 11:07:46 + Author : stag +--%> + +<%@page contentType="text/html" pageEncoding="UTF-8"%> + + diff --git a/src/main/webapp/WEB-INF/jspf/Style.jsp b/src/main/webapp/WEB-INF/jspf/Style.jsp new file mode 100644 index 0000000..f810700 --- /dev/null +++ b/src/main/webapp/WEB-INF/jspf/Style.jsp @@ -0,0 +1,361 @@ +<%-- + Document : newjsp + Created on : 5 mai 2023, 14:01:13 + Author : stag +--%> + + + + "/> + + + diff --git a/src/main/webapp/WEB-INF/taglibs.jsp b/src/main/webapp/WEB-INF/taglibs.jsp new file mode 100644 index 0000000..b402b33 --- /dev/null +++ b/src/main/webapp/WEB-INF/taglibs.jsp @@ -0,0 +1 @@ +<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> diff --git a/src/main/webapp/WEB-INF/web.xml b/src/main/webapp/WEB-INF/web.xml new file mode 100644 index 0000000..8e105b3 --- /dev/null +++ b/src/main/webapp/WEB-INF/web.xml @@ -0,0 +1,22 @@ + + + + + 30 + + + + home + + + + + *.jsp + /WEB-INF/taglibs.jsp + + + + + + + diff --git a/src/main/webapp/index.html b/src/main/webapp/index.html new file mode 100644 index 0000000..3368e9c --- /dev/null +++ b/src/main/webapp/index.html @@ -0,0 +1,10 @@ + + + + Start Page + + + +

Hello World!

+ + -- GitLab