Merge branch 'Johan'

This commit is contained in:
jleroy
2024-04-29 13:46:29 +02:00
18 changed files with 505 additions and 3 deletions

View File

@@ -0,0 +1,12 @@
package fr.eni.enchere.bll;
import fr.eni.enchere.bo.ForgotPassword;
import java.util.List;
public interface ForgotPasswordService {
ForgotPassword getForgotPassword(String link);
void setForgotPassword(String email);
}

View File

@@ -0,0 +1,27 @@
package fr.eni.enchere.bll;
import fr.eni.enchere.bo.ForgotPassword;
import fr.eni.enchere.dal.ForgotPasswordRepository;
import org.springframework.stereotype.Service;
import java.util.List;
@Service("ForgotPasswordService")
public class ForgotPasswordServiceImpl implements ForgotPasswordService {
private ForgotPasswordRepository forgotPasswordRepository;
public ForgotPasswordServiceImpl(ForgotPasswordRepository forgotPasswordRepository) {
this.forgotPasswordRepository = forgotPasswordRepository;
}
@Override
public ForgotPassword getForgotPassword(String link) {
return forgotPasswordRepository.getForgotPasswordByLink(link);
}
@Override
public void setForgotPassword(String email) {
forgotPasswordRepository.setForgotPasswords(email);
}
}

View File

@@ -1,6 +1,7 @@
package fr.eni.enchere.bll;
import fr.eni.enchere.bo.UserProfil;
import org.apache.catalina.User;
import java.util.List;
@@ -8,8 +9,10 @@ public interface UserService {
List<UserProfil> listeUtilisateurs();
UserProfil utilisateurById(int id);
UserProfil utilisateurByName(String username);
UserProfil utilisateurByEmail(String email);
List<String> listPseudo();
List<String> listEmail();
String getUserByMail(String mail);
void setUtilisateur(UserProfil utilisateur);
void setCredit(float credit, int id);
void deleteUtilisateur(int id);

View File

@@ -30,6 +30,11 @@ public class UserServiceImpl implements UserService {
return userRepository.findByUsername(username);
}
@Override
public UserProfil utilisateurByEmail(String email) {
return userRepository.findUserByEmail(email);
}
@Override
public List<String> listPseudo() {
return userRepository.findAllUsernames();
@@ -40,6 +45,11 @@ public class UserServiceImpl implements UserService {
return userRepository.findAllEmail();
}
@Override
public String getUserByMail(String mail) {
return userRepository.findByEmail(mail);
}
@Override
public void setUtilisateur(UserProfil utilisateur) {
userRepository.save(utilisateur);

View File

@@ -0,0 +1,64 @@
package fr.eni.enchere.bo;
import java.time.LocalDate;
import java.util.Calendar;
public class ForgotPassword {
private int id;
private String email;
private String link;
private Calendar dateCreate;
private Calendar dateExpire;
public ForgotPassword() {}
public ForgotPassword(int id, String email, String link, Calendar dateCreate, Calendar dateExpire) {
setId(id);
setEmail(email);
setLink(link);
setDateCreate(dateCreate);
setDateExpire(dateExpire);
}
public String getLink() {
return link;
}
public void setLink(String link) {
this.link = link;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public Calendar getDateCreate() {
return dateCreate;
}
public void setDateCreate(Calendar dateCreate) {
this.dateCreate = dateCreate;
}
public Calendar getDateExpire() {
return dateExpire;
}
public void setDateExpire(Calendar dateExpire) {
this.dateExpire = dateExpire;
}
}

View File

@@ -4,6 +4,10 @@ import com.google.i18n.phonenumbers.PhoneNumberUtil;
import org.apache.commons.validator.routines.EmailValidator;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.mail.MailException;
import org.springframework.mail.SimpleMailMessage;
import org.springframework.mail.javamail.JavaMailSender;
import org.springframework.mail.javamail.JavaMailSenderImpl;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
@@ -15,7 +19,9 @@ import org.springframework.context.annotation.Bean;
import org.springframework.context.support.ResourceBundleMessageSource;
import org.springframework.web.servlet.i18n.SessionLocaleResolver;
import java.io.InputStream;
import java.util.Locale;
import java.util.Properties;
@Configuration
public class WebConfig {

View File

@@ -0,0 +1,153 @@
package fr.eni.enchere.controllers;
import fr.eni.enchere.bll.ForgotPasswordService;
import fr.eni.enchere.bll.UserService;
import fr.eni.enchere.bo.ForgotPassword;
import fr.eni.enchere.bo.UserProfil;
import org.apache.commons.validator.routines.EmailValidator;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import java.util.Calendar;
import java.util.regex.Pattern;
@Controller()
@RequestMapping("/forgotPassword")
public class ForgotPasswordController {
@Autowired
private final UserService userService;
private EmailValidator emailValidator;
private ForgotPasswordService forgotPasswordService;
public ForgotPasswordController(EmailValidator emailValidator, ForgotPasswordService forgotPasswordService, UserService userService) {
this.userService = userService;
this.emailValidator = emailValidator;
this.forgotPasswordService = forgotPasswordService;
}
@GetMapping
public String forgotPassword(Model model, @RequestParam(value = "link", required = false) String link) {
// Vérifier si l'utilisateur est déjà authentifié
Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
if (!authentication.getName().equals("anonymousUser")){
return "redirect:/accueil";
}
if (link != null) {
ForgotPassword forgotPassword = forgotPasswordService.getForgotPassword(link);
if (forgotPassword != null) {
Calendar dateNow = Calendar.getInstance();
if (dateNow.before(forgotPassword.getDateExpire())){
return "redirect:/forgotPassword/changePassword?link=" + forgotPassword.getLink();
}else{
return "redirect:/forgotPassword/changePasswordExpired?link=" + forgotPassword.getLink();
}
}else{
return "redirect:/security/forgotPassword";
}
}else{
return "security/forgotPassword";
}
}
@PostMapping
public String createLinkForgotPassword(@RequestParam("email") String email) {
if (email.isEmpty()){
return "redirect:/forgotPassword?error";
}else{
if (!emailValidator.isValid(email)) {
return "redirect:/forgotPassword?error";
}
}
//Vérification de l'email dans la base de donnée
if (userService.getUserByMail(email) == null){
return "redirect:/forgotPassword?error";
}
forgotPasswordService.setForgotPassword(email);
return "redirect:/forgotPassword?mailSend";
}
@GetMapping("/changePassword")
public String forgotPasswordChangePassword(Model model, @RequestParam(value = "link", required = true) String link) {
// Vérifier si l'utilisateur est déjà authentifié
Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
if (!authentication.getName().equals("anonymousUser")){
return "redirect:/accueil";
}
ForgotPassword forgotPassword = forgotPasswordService.getForgotPassword(link);
if (forgotPassword != null) {
Calendar dateNow = Calendar.getInstance();
if (dateNow.before(forgotPassword.getDateExpire())){
return "security/changePassword";
}else{
return "redirect:/forgotPassword/changePasswordExpired?link=" + forgotPassword.getLink();
}
}else{
return "security/forgotPassword";
}
}
@PostMapping("/changePassword/check")
public String changePassword(@RequestParam("email") String email,
@RequestParam("password") String password,
@RequestParam("confirmPassword") String confirmPassword,
@RequestParam("link") String link) {
ForgotPassword forgotPassword = forgotPasswordService.getForgotPassword(link);
if (forgotPassword != null) {
Calendar dateNow = Calendar.getInstance();
if (dateNow.before(forgotPassword.getDateExpire())){
if (email.equalsIgnoreCase(forgotPassword.getEmail())){
if (password.equals(confirmPassword)){
String passwordRegex = "^(?=.*[0-9])(?=.*[a-z])(?=.*[A-Z])(?=.*[@?*#$%^&+=_!\\-])(?=\\S+$).{8,}$";
Pattern pattern = Pattern.compile(passwordRegex);
// Vérifier si le mot de passe correspond à l'expression régulière
if (pattern.matcher(password).matches()){
UserProfil userForgotPassword = userService.utilisateurByEmail(email);
userForgotPassword.setNewPassword(password);
userService.setUtilisateur(userForgotPassword);
return "redirect:/login";
}else{
return "redirect:/forgotPassword/changePassword?link=" + forgotPassword.getLink() + "&passwordSecurity";
}
}else{
return "redirect:/forgotPassword/changePassword?link=" + forgotPassword.getLink() + "&passwordNotIdentique";
}
}else{
return "redirect:/forgotPassword/changePassword?link=" + forgotPassword.getLink() + "&emailError";
}
}else{
return "redirect:/forgotPassword/changePasswordExpired?link=" + forgotPassword.getLink();
}
}else{
return "security/forgotPassword";
}
}
@GetMapping("/changePasswordExpired")
public String forgotPasswordLinkExpired(Model model, @RequestParam(value = "link", required = true) String link) {
// Vérifier si l'utilisateur est déjà authentifié
Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
if (!authentication.getName().equals("anonymousUser")){
return "redirect:/accueil";
}
ForgotPassword forgotPassword = forgotPasswordService.getForgotPassword(link);
if (forgotPassword != null) {
Calendar dateNow = Calendar.getInstance();
if (dateNow.before(forgotPassword.getDateExpire())){
return "redirect:/forgotPassword/changePassword?link=" + forgotPassword.getLink();
}else{
return "security/changePasswordExpired";
}
}else{
return "security/forgotPassword";
}
}
}

View File

@@ -0,0 +1,12 @@
package fr.eni.enchere.dal;
import fr.eni.enchere.bo.ForgotPassword;
import java.util.List;
public interface ForgotPasswordRepository {
ForgotPassword getForgotPasswordByLink(String link);
void setForgotPasswords(String email);
}

View File

@@ -0,0 +1,93 @@
package fr.eni.enchere.dal;
import fr.eni.enchere.bo.ForgotPassword;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Primary;
import org.springframework.dao.EmptyResultDataAccessException;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.RowMapper;
import org.springframework.jdbc.core.namedparam.MapSqlParameterSource;
import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate;
import org.springframework.mail.SimpleMailMessage;
import org.springframework.mail.javamail.JavaMailSender;
import org.springframework.stereotype.Repository;
import java.security.SecureRandom;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.Calendar;
@Repository
@Primary
public class ForgotPasswordRepositoryImpl implements ForgotPasswordRepository {
static final String keychain = "0123456789azertyuiopqsdfghjklmwxcvbnAZERTYUIOPQSDFGHJKLMWXCVBN" ;
static SecureRandom randomValue = new SecureRandom();
@Autowired
private JavaMailSender javaMailSender;
private final JdbcTemplate jdbcTemplate;
private NamedParameterJdbcTemplate namedParameterJdbcTemplate;
public ForgotPasswordRepositoryImpl(JavaMailSender javaMailSender, JdbcTemplate jdbcTemplate, NamedParameterJdbcTemplate namedParameterJdbcTemplate) {
this.javaMailSender = javaMailSender;
this.jdbcTemplate = jdbcTemplate;
this.namedParameterJdbcTemplate = namedParameterJdbcTemplate;
}
public class ForgotPasswordRowMapper implements RowMapper<ForgotPassword> {
@Override
public ForgotPassword mapRow(ResultSet rs, int rowNum) throws SQLException {
ForgotPassword forgotPassword = new ForgotPassword();
forgotPassword.setId(rs.getInt("id"));
forgotPassword.setEmail(rs.getString("email"));
forgotPassword.setLink(rs.getString("lien"));
Calendar dateCreated = Calendar.getInstance();
Calendar dateExpired = Calendar.getInstance();
dateCreated.setTime(rs.getDate("dateCreate"));
dateExpired.setTime(rs.getDate("dateExpire"));
forgotPassword.setDateCreate(dateCreated);
forgotPassword.setDateExpire(dateExpired);
return forgotPassword;
}
}
@Override
public ForgotPassword getForgotPasswordByLink(String link) {
String sql = "SELECT * FROM FORGOT WHERE lien = ?";
try {
return jdbcTemplate.queryForObject(sql, new ForgotPasswordRepositoryImpl.ForgotPasswordRowMapper(), link);
} catch (EmptyResultDataAccessException e) {
// Aucun résultat trouvé, retourne null
return null;
}
}
@Override
public void setForgotPasswords(String email) {
//Générer un code
StringBuilder linkCreate = new StringBuilder(50);
for (int i = 0; i < 50; i ++){
linkCreate.append(keychain.charAt(randomValue.nextInt(keychain.length())));
}
//Récupérer la date actuelle plus 10 minutes en plus
Calendar dateNow = Calendar.getInstance();
Calendar dateAgo = Calendar.getInstance();
dateAgo.add(Calendar.MINUTE, 10);
//Ajouter en base de donnée
String sql = "INSERT INTO FORGOT (email, lien, dateCreate, dateExpire) VALUES (:email, :lien, :dateCreate, :dateExpire)";
MapSqlParameterSource parameters = new MapSqlParameterSource();
parameters.addValue("email", email);
parameters.addValue("lien", linkCreate.toString());
parameters.addValue("dateCreate", dateNow.getTime());
parameters.addValue("dateExpire", dateAgo.getTime());
namedParameterJdbcTemplate.update(sql, parameters);
//Envoyer un email
String link = "http://eni.enchere.horya.fr/forgotPassword?link=" + linkCreate.toString();
SimpleMailMessage message = new SimpleMailMessage();
message.setTo(email);
message.setSubject("ENI Enchere - Demmande de changement de mot de passe");
message.setText("Bonjour,\n\nVous avez demandé une réinitialisation de votre mot de passe. Veuillez utiliser le lien suivant pour procéder à la réinitialisation : " + link);
javaMailSender.send(message);
}
}

View File

@@ -8,8 +8,10 @@ public interface UserRepository {
List<UserProfil> findAll();
UserProfil findById(int id);
UserProfil findByUsername(String username);
UserProfil findUserByEmail(String email);
List<String> findAllUsernames();
List<String> findAllEmail();
String findByEmail(String email);
void save(UserProfil utilisateur);
void updateCredit(float credit, int id);
void delete(int id);

View File

@@ -3,6 +3,7 @@ package fr.eni.enchere.dal;
import fr.eni.enchere.bo.UserProfil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Primary;
import org.springframework.dao.EmptyResultDataAccessException;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.RowMapper;
import org.springframework.jdbc.core.namedparam.MapSqlParameterSource;
@@ -60,6 +61,13 @@ public class UserRepositoryImpl implements UserRepository {
return user;
}
@Override
public UserProfil findUserByEmail(String email) {
String sql = "SELECT * FROM UTILISATEURS WHERE email = ? AND isDelete = 0";
UserProfil user = jdbcTemplate.queryForObject(sql, new UserRowMapper(), email);
return user;
}
@Override
public List<String> findAllUsernames() {
String sql = "SELECT pseudo FROM UTILISATEURS WHERE isDelete = 0";
@@ -74,6 +82,18 @@ public class UserRepositoryImpl implements UserRepository {
return email;
}
@Override
public String findByEmail(String email) {
//Vérifie si un email existe dans la base et est valide
String sql = "SELECT email FROM UTILISATEURS WHERE isDisabled = 0 AND email = ?";
try {
return jdbcTemplate.queryForObject(sql, new Object[]{email}, String.class);
} catch (EmptyResultDataAccessException e) {
// Aucun résultat trouvé, retourne null
return null;
}
}
@Override
public List<UserProfil> findAll() {
String sql = "SELECT * FROM UTILISATEURS WHERE isDelete = 0";

View File

@@ -19,7 +19,7 @@ public class WebSecurityConfig{
@Bean
public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
http.authorizeHttpRequests((requests) -> requests
.requestMatchers("/","/accueil", "/login", "/inscription/**", "/searchArticle", "/article/show", "/change-language").permitAll()
.requestMatchers("/","/accueil", "/login", "/forgotPassword/**", "/inscription/**", "/searchArticle", "/article/show", "/change-language").permitAll()
.requestMatchers("/css/**", "/images/**", "/assets/**", "/img/**", "/js/**", "/assets/**", "/i18n/**").permitAll()
.requestMatchers("/profil/**", "/article/new/**", "/article/update", "/article/delete").authenticated()
.requestMatchers("/admin").hasRole("ADMIN")