Merge branch 'Johan'

This commit is contained in:
Parpaillax
2024-04-25 12:49:37 +02:00
5 changed files with 99 additions and 16 deletions

View File

@@ -27,6 +27,10 @@ dependencies {
//Securité //Securité
implementation 'org.springframework.boot:spring-boot-starter-security' implementation 'org.springframework.boot:spring-boot-starter-security'
implementation 'org.thymeleaf.extras:thymeleaf-extras-springsecurity6' implementation 'org.thymeleaf.extras:thymeleaf-extras-springsecurity6'
//Vérification de formulaire
implementation 'commons-validator:commons-validator:1.7'
implementation 'com.googlecode.libphonenumber:libphonenumber:5.5'
//test
testImplementation 'org.springframework.security:spring-security-test' testImplementation 'org.springframework.security:spring-security-test'
testImplementation 'org.springframework.boot:spring-boot-starter-test' testImplementation 'org.springframework.boot:spring-boot-starter-test'
} }

View File

@@ -160,4 +160,5 @@ public class UserProfil {
public void setNewPassword(String newPassword) { public void setNewPassword(String newPassword) {
this.newPassword = newPassword; this.newPassword = newPassword;
} }
} }

View File

@@ -1,5 +1,7 @@
package fr.eni.enchere.config; package fr.eni.enchere.config;
import com.google.i18n.phonenumbers.PhoneNumberUtil;
import org.apache.commons.validator.routines.EmailValidator;
import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.LocaleResolver; import org.springframework.web.servlet.LocaleResolver;
@@ -28,4 +30,15 @@ public class WebConfig {
source.setUseCodeAsDefaultMessage(true); source.setUseCodeAsDefaultMessage(true);
return source; return source;
} }
@Bean
public EmailValidator emailValidator() {
return EmailValidator.getInstance();
}
@Bean
public PhoneNumberUtil phoneValidator() {
return PhoneNumberUtil.getInstance();
}
} }

View File

@@ -1,8 +1,14 @@
package fr.eni.enchere.controllers; package fr.eni.enchere.controllers;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.google.i18n.phonenumbers.NumberParseException;
import com.google.i18n.phonenumbers.PhoneNumberUtil;
import com.google.i18n.phonenumbers.Phonenumber;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.Authentication; import org.apache.commons.validator.routines.EmailValidator;
import org.springframework.security.core.context.SecurityContextHolder; import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.security.crypto.password.PasswordEncoder; import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.validation.BindingResult; import org.springframework.validation.BindingResult;
import fr.eni.enchere.bll.UserService; import fr.eni.enchere.bll.UserService;
@@ -10,30 +16,41 @@ import fr.eni.enchere.bo.UserProfil;
import org.springframework.stereotype.Controller; import org.springframework.stereotype.Controller;
import org.springframework.ui.Model; import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.*; import org.springframework.web.bind.annotation.*;
import org.springframework.web.client.RestTemplate;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List; import java.util.List;
import java.util.regex.Pattern;
@Controller @Controller
@RequestMapping("/inscription") @RequestMapping("/inscription")
public class InscriptionController { public class InscriptionController {
private final String API_URL = "https://apicarto.ign.fr/api/codes-postaux/communes/";
@Autowired @Autowired
private final UserService userService; private final UserService userService;
private PasswordEncoder passwordEncoder; private PasswordEncoder passwordEncoder;
private EmailValidator emailValidator;
private PhoneNumberUtil phoneValidator;
public InscriptionController(UserService userService, PasswordEncoder passwordEncoder) { public InscriptionController(UserService userService, PasswordEncoder passwordEncoder, EmailValidator emailValidator, PhoneNumberUtil phoneValidator) {
this.userService = userService; this.userService = userService;
this.passwordEncoder = passwordEncoder; this.passwordEncoder = passwordEncoder;
this.emailValidator = emailValidator;
this.phoneValidator = phoneValidator;
} }
@GetMapping @GetMapping
public String viewInscription(Model model) { public String viewInscription(Model model) {
model.addAttribute("user", new UserProfil()); model.addAttribute("userProfile", new UserProfil());
return "inscription"; return "inscription";
} }
@PostMapping("/newUser") @PostMapping("/newUser")
public String setUser(@ModelAttribute("userProfile") UserProfil userProfile, BindingResult result) { public String setUser(@ModelAttribute("userProfile") UserProfil userProfile, @RequestParam("confirmPassword") String confirmPassword, BindingResult result) {
// Vérifier si le pseudo existe déjà // Vérifier si le pseudo existe déjà
List<String> allUsernames = userService.listPseudo(); List<String> allUsernames = userService.listPseudo();
if (allUsernames.contains(userProfile.getPseudo())) { if (allUsernames.contains(userProfile.getPseudo())) {
@@ -44,12 +61,60 @@ public class InscriptionController {
if (allEmails.contains(userProfile.getEmail())) { if (allEmails.contains(userProfile.getEmail())) {
result.rejectValue("email", "error.userProfile", "Cet e-mail est déjà utilisé."); result.rejectValue("email", "error.userProfile", "Cet e-mail est déjà utilisé.");
} }
// vérifier si l'e-mail est valide
if (!emailValidator.isValid(userProfile.getEmail())) {
result.rejectValue("email", "error.userProfile", "L'adresse e-mail n'est pas valide.");
}
// vérifier si le numéro de téléphone est valide
PhoneNumberUtil phoneNumberUtil = PhoneNumberUtil.getInstance();
try {
Phonenumber.PhoneNumber number = phoneNumberUtil.parse(userProfile.getTelephone(), "FR"); // Indiquez le code pays, ici FR pour la France
phoneNumberUtil.isValidNumber(number);
} catch (NumberParseException e) {
result.rejectValue("telephone", "error.userProfile", "Le numéro de téléphone n'est pas valide.");
}
// vérification retrait
//Vérification rue
if (!Pattern.matches("^[a-zA-Z0-9 ]+$", userProfile.getRue())){
result.rejectValue("rue", "error.userProfile", "Le rue n'est pas valide.");
}
//Vérifier code postal et ville
if(Pattern.matches("^\\d{5}$", userProfile.getCode_postal())){
//Récupérer les villes en fonction du code postal
RestTemplate restTemplate = new RestTemplate();
List<String> villeCodePostal = new ArrayList<>(); // Initialisez la liste pour éviter les NullPointerException
String apiUrl = API_URL + userProfile.getCode_postal();
ResponseEntity<JsonNode> response = restTemplate.getForEntity(apiUrl, JsonNode.class); // Désérialiser en JsonNode
if (response.getStatusCode().is2xxSuccessful()) {
JsonNode responseBody = response.getBody();
if (responseBody.isArray()) { // Vérifiez si le corps de la réponse est un tableau JSON
for (JsonNode node : responseBody) {
String cityName = node.get("nomCommune").asText();
villeCodePostal.add(cityName);
}
} else {
result.rejectValue("ville", "error.userProfile", "La réponse de l'API n'est pas un tableau JSON.");
}
if (!villeCodePostal.contains(userProfile.getVille())) {
String showCity = String.join(", ", villeCodePostal);
result.rejectValue("ville", "error.userProfile", "Essayer : " + showCity);
}
} else {
result.rejectValue("ville", "error.userProfile", "La ville n'est pas valide.");
}
} else {
result.rejectValue("code_postal", "error.userProfile", "Le code postal n'est pas valide.");
}
// vérifier si les mot de passes sont identique
if (!confirmPassword.equals(userProfile.getPassword())) {
result.rejectValue("password", "error.userProfile", "Les mots de passe ne correspond pas.");
}
// Si des erreurs de validation sont détectées, retourner à la page de création de compte // Si des erreurs de validation sont détectées, retourner à la page de création de compte
if (result.hasErrors()) { if (result.hasErrors()) {
return "inscription"; return "inscription";
} }
// Sinon, enregistrer l'utilisateur et rediriger vers la page de connexion // Sinon, enregistrer l'utilisateur et rediriger vers la page de connexion
userService.setUtilisateur(userProfile); //userService.setUtilisateur(userProfile);
return "redirect:/login"; return "redirect:/login";
} }
} }

View File

@@ -6,7 +6,7 @@
<body> <body>
<!-- Ajouter la page de nav bar --> <!-- Ajouter la page de nav bar -->
<div id="container-main"> <div id="container-main">
<form th:action="@{/inscription/newUser}" method="post" th:object="${user}"> <form th:action="@{/inscription/newUser}" method="post" th:object="${userProfile}">
<!--<div class="erreur-saisie" th:if="${#fields.hasErrors('*')}" > <!--<div class="erreur-saisie" th:if="${#fields.hasErrors('*')}" >
<p th:text="#{index.erreurs}">Message d'erreur</p> <p th:text="#{index.erreurs}">Message d'erreur</p>
</div>--> </div>-->
@@ -14,7 +14,7 @@
<div class="champ-saisie"> <div class="champ-saisie">
<label for="pseudo">Pseudo: </label> <label for="pseudo">Pseudo: </label>
<div> <div>
<input type="text" th:field="*{pseudo}" id="pseudo"/> <input type="text" th:field="*{pseudo}" id="pseudo" required/>
</div> </div>
<span style="color: red;" th:if="${#fields.hasErrors('pseudo')}"> <span style="color: red;" th:if="${#fields.hasErrors('pseudo')}">
<ul> <ul>
@@ -26,7 +26,7 @@
<div class="champ-saisie"> <div class="champ-saisie">
<label for="prenom">Prénom: </label> <label for="prenom">Prénom: </label>
<div> <div>
<input type="text" th:field="*{prenom}" id="prenom" /> <input type="text" th:field="*{prenom}" id="prenom" required/>
</div> </div>
<span style="color: red;" th:if="${#fields.hasErrors('prenom')}"> <span style="color: red;" th:if="${#fields.hasErrors('prenom')}">
<ul> <ul>
@@ -38,7 +38,7 @@
<div class="champ-saisie"> <div class="champ-saisie">
<label for="nom">Nom: </label> <label for="nom">Nom: </label>
<div> <div>
<input type="text" th:field="*{nom}" id="nom" /> <input type="text" th:field="*{nom}" id="nom" required/>
</div> </div>
<span style="color: red;" th:if="${#fields.hasErrors('nom')}"> <span style="color: red;" th:if="${#fields.hasErrors('nom')}">
<ul> <ul>
@@ -50,7 +50,7 @@
<div class="champ-saisie"> <div class="champ-saisie">
<label for="email">Email: </label> <label for="email">Email: </label>
<div> <div>
<input type="email" th:field="*{email}" id="email" /> <input type="email" th:field="*{email}" id="email" required/>
</div> </div>
<span style="color: red;" th:if="${#fields.hasErrors('email')}"> <span style="color: red;" th:if="${#fields.hasErrors('email')}">
<ul> <ul>
@@ -74,7 +74,7 @@
<div class="champ-saisie"> <div class="champ-saisie">
<label for="rue">Rue: </label> <label for="rue">Rue: </label>
<div> <div>
<input type="text" th:field="*{rue}" id="rue" /> <input type="text" th:field="*{rue}" id="rue" required/>
</div> </div>
<span style="color: red;" th:if="${#fields.hasErrors('rue')}"> <span style="color: red;" th:if="${#fields.hasErrors('rue')}">
<ul> <ul>
@@ -86,7 +86,7 @@
<div class="champ-saisie"> <div class="champ-saisie">
<label for="code_postal">Code postal: </label> <label for="code_postal">Code postal: </label>
<div> <div>
<input type="text" th:field="*{code_postal}" id="code_postal" /> <input type="text" th:field="*{code_postal}" id="code_postal" required/>
</div> </div>
<span style="color: red;" th:if="${#fields.hasErrors('code_postal')}"> <span style="color: red;" th:if="${#fields.hasErrors('code_postal')}">
<ul> <ul>
@@ -98,7 +98,7 @@
<div class="champ-saisie"> <div class="champ-saisie">
<label for="code_postal">Ville: </label> <label for="code_postal">Ville: </label>
<div> <div>
<input type="text" th:field="*{ville}" id="ville" /> <input type="text" th:field="*{ville}" id="ville" required/>
</div> </div>
<span style="color: red;" th:if="${#fields.hasErrors('ville')}"> <span style="color: red;" th:if="${#fields.hasErrors('ville')}">
<ul> <ul>
@@ -109,7 +109,7 @@
<div class="champ-saisie"> <div class="champ-saisie">
<label for="password">Mot de passe: </label> <label for="password">Mot de passe: </label>
<div> <div>
<input type="password" th:field="*{password}" id="password" /> <input type="password" th:field="*{password}" id="password" required/>
</div> </div>
<span style="color: red;" th:if="${#fields.hasErrors('password')}"> <span style="color: red;" th:if="${#fields.hasErrors('password')}">
<ul> <ul>
@@ -120,7 +120,7 @@
<div class="champ-saisie"> <div class="champ-saisie">
<label for="confirmPassword">Confirmation du mot de passe: </label> <label for="confirmPassword">Confirmation du mot de passe: </label>
<div> <div>
<input type="password" id="confirmPassword" /> <input type="password" name="confirmPassword" id="confirmPassword" required/>
</div> </div>
</div> </div>
<input type="submit" value="Créer" /> <input type="submit" value="Créer" />