Files
as-talange/as-talange-web/src/main/java/com/astalange/web/controller/PublicInscriptionController.java
T
ucef 851fb36c2a
AS Talange CI/CD Pipeline / Build & Run Unit Tests (push) Successful in 4m59s
AS Talange CI/CD Pipeline / Deploy to Test Environment (push) Successful in 6m25s
fix: passer le temps d'expiration du token de pre-inscription a 30 minutes
2026-08-10 23:06:14 +02:00

229 lines
10 KiB
Java
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
package com.astalange.web.controller;
import com.astalange.core.entity.PreInscription;
import com.astalange.core.entity.TokenPreInscription;
import com.astalange.core.entity.Saison;
import com.astalange.core.repository.PreInscriptionRepository;
import com.astalange.core.repository.TokenPreInscriptionRepository;
import com.astalange.core.repository.SaisonRepository;
import com.astalange.core.repository.CategorieRepository;
import com.astalange.core.repository.EquipementRepository;
import com.astalange.core.entity.Categorie;
import com.astalange.core.entity.Equipement;
import com.astalange.core.service.CaptchaValidationService;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.servlet.mvc.support.RedirectAttributes;
import org.springframework.beans.factory.annotation.Value;
import java.time.LocalDateTime;
import java.time.LocalDate;
import java.util.UUID;
import java.util.List;
import java.math.BigDecimal;
import java.util.Set;
import java.util.TreeSet;
@Controller
@RequestMapping("/inscription-public")
public class PublicInscriptionController {
private final CaptchaValidationService captchaValidationService;
private final TokenPreInscriptionRepository tokenRepository;
private final PreInscriptionRepository preInscriptionRepository;
private final SaisonRepository saisonRepository;
private final CategorieRepository categorieRepository;
private final EquipementRepository equipementRepository;
public PublicInscriptionController(CaptchaValidationService captchaValidationService,
TokenPreInscriptionRepository tokenRepository,
PreInscriptionRepository preInscriptionRepository,
SaisonRepository saisonRepository,
CategorieRepository categorieRepository,
EquipementRepository equipementRepository) {
this.captchaValidationService = captchaValidationService;
this.tokenRepository = tokenRepository;
this.preInscriptionRepository = preInscriptionRepository;
this.saisonRepository = saisonRepository;
this.categorieRepository = categorieRepository;
this.equipementRepository = equipementRepository;
}
@Value("${captcha.sitekey:1x00000000000000000000AA}")
private String captchaSiteKey;
@GetMapping("/demarrer")
public String showDemarrer(Model model) {
model.addAttribute("captchaSiteKey", captchaSiteKey);
Saison activeSaison = saisonRepository.findByEstActiveTrue().orElse(null);
if (activeSaison == null || !activeSaison.getInscriptionsOuvertes()) {
model.addAttribute("inscriptionsFermees", true);
}
return "public/demarrer";
}
@PostMapping("/demarrer")
public String processDemarrer(@RequestParam("cf-turnstile-response") String captchaResponse,
RedirectAttributes redirectAttributes) {
Saison activeSaison = saisonRepository.findByEstActiveTrue().orElse(null);
if (activeSaison == null || !activeSaison.getInscriptionsOuvertes()) {
redirectAttributes.addFlashAttribute("error",
"Les inscriptions ne sont pas ouvertes pour le moment, veuillez contacter un responsable du club.");
return "redirect:/inscription-public/demarrer";
}
// En vrai, captchaResponse dépend du fournisseur. Cloudflare Turnstile =
// cf-turnstile-response
if (!captchaValidationService.validateCaptcha(captchaResponse)) {
redirectAttributes.addFlashAttribute("error", "Validation CAPTCHA échouée. Veuillez réessayer.");
return "redirect:/inscription-public/demarrer";
}
TokenPreInscription token = new TokenPreInscription();
token.setValeurUuid(UUID.randomUUID().toString());
token.setDateExpiration(LocalDateTime.now().plusMinutes(30));
tokenRepository.save(token);
return "redirect:/inscription-public/formulaire?token=" + token.getValeurUuid();
}
@GetMapping("/formulaire")
public String showFormulaire(@RequestParam("token") String tokenUuid, Model model,
RedirectAttributes redirectAttributes) {
Saison activeSaison = saisonRepository.findByEstActiveTrue().orElse(null);
if (activeSaison == null || !activeSaison.getInscriptionsOuvertes()) {
redirectAttributes.addFlashAttribute("error",
"Les inscriptions ne sont pas ouvertes pour le moment, veuillez contacter un responsable du club.");
return "redirect:/inscription-public/demarrer";
}
TokenPreInscription token = tokenRepository.findByValeurUuid(tokenUuid).orElse(null);
if (token == null || !token.isValide()) {
return "public/lien-expire";
}
model.addAttribute("preInscription", new PreInscription());
model.addAttribute("tokenUuid", tokenUuid);
// Fetch tailles and pointures (Standard exhaustive list)
Set<String> tailles = new java.util.LinkedHashSet<>(java.util.Arrays.asList(
"5/6ANS (Taille 116cm)", "7/8ANS (Taille 128cm)", "9/10ANS (Taille 140cm)",
"11/12ANS (Taille 152cm)", "13/14ANS (Taille 164cm)", "XS", "S", "M", "L", "XL", "XXL"
));
Set<String> pointures = new java.util.LinkedHashSet<>(java.util.Arrays.asList(
"27/30 (Taille 0)", "31/34 (Taille 1)", "35/38 (Taille 2)", "39/42 (Taille 3)", "43/46 (Taille 4)"
));
model.addAttribute("taillesDisponibles", tailles);
model.addAttribute("pointuresDisponibles", pointures);
return "public/formulaire";
}
@PostMapping("/formulaire")
public String processFormulaire(@RequestParam("token") String tokenUuid,
@ModelAttribute("preInscription") PreInscription preInscription,
RedirectAttributes redirectAttributes) {
TokenPreInscription token = tokenRepository.findByValeurUuid(tokenUuid).orElse(null);
if (token == null || !token.isValide()) {
return "public/lien-expire";
}
Saison activeSaison = saisonRepository.findByEstActiveTrue().orElse(null);
if (activeSaison == null || !activeSaison.getInscriptionsOuvertes()) {
redirectAttributes.addFlashAttribute("error",
"Les inscriptions ne sont pas ouvertes pour le moment, veuillez contacter un responsable du club.");
return "redirect:/inscription-public/demarrer";
}
// Nettoyage défensif des champs non applicables
if ("RENOUVELLEMENT".equals(preInscription.getTypeDemande())) {
preInscription.setAncienClub(null);
preInscription.setRaisonChangementClub(null);
preInscription.setAncienneCategorie(null);
preInscription.setCommentConnuClub(null);
}
if (preInscription.getDateNaissance() != null) {
int age = java.time.Period.between(preInscription.getDateNaissance(), java.time.LocalDate.now()).getYears();
if (age >= 18) {
preInscription.setRepresentantLegal(null);
}
}
// Sauvegarde de la pré-inscription
preInscription.setSaison(activeSaison);
preInscription.setStatutTraite(false);
preInscriptionRepository.save(preInscription);
// Invalidation du token
token.setEstUtilise(true);
tokenRepository.save(token);
if ("NOUVELLE".equals(preInscription.getTypeDemande())) {
String tarifStr = "210 €"; // Default
if (preInscription.getDateNaissance() != null) {
int annee = preInscription.getDateNaissance().getYear();
List<Categorie> categories = categorieRepository.findBySaisonAndAnnee(activeSaison, annee);
if (!categories.isEmpty()) {
Categorie cat = categories.get(0);
if (cat.getTarifBase() != null) {
BigDecimal prixMaillot = cat.getEquipementPrixByNom("Maillot");
if (prixMaillot == null) {
prixMaillot = BigDecimal.ZERO;
}
BigDecimal tarifTotal = cat.getTarifBase().add(prixMaillot);
tarifStr = tarifTotal.intValue() + " €";
}
}
}
redirectAttributes.addFlashAttribute("prenom", preInscription.getPrenom());
redirectAttributes.addFlashAttribute("tarif", tarifStr);
redirectAttributes.addFlashAttribute("documents", java.util.Arrays.asList(
"Photo didentité",
"Carte didentité ou passeport de l'adhérent",
"Livret de famille (si pas de pièce didentité)",
"Adresse e-mail de l'adhérent (représentant légal en cas de mineur)",
"Pour les adhérents nés à l'étranger : Passeport + justificatif de domicile (du représentant légal en cas de mineur)"
));
redirectAttributes.addFlashAttribute("isNouvelle", true);
}
return "redirect:/inscription-public/succes";
}
@GetMapping("/api/tarif")
@ResponseBody
public String getTarif(@RequestParam(value = "dateNaissance", required = false) String dateNaissanceStr) {
if (dateNaissanceStr == null || dateNaissanceStr.isEmpty()) {
return "210 €";
}
try {
LocalDate dateNaissance = LocalDate.parse(dateNaissanceStr);
int annee = dateNaissance.getYear();
Saison activeSaison = saisonRepository.findByEstActiveTrue().orElse(null);
if (activeSaison == null) return "210 €";
List<Categorie> categories = categorieRepository.findBySaisonAndAnnee(activeSaison, annee);
if (categories.isEmpty()) return "210 €";
Categorie cat = categories.get(0);
if (cat.getTarifBase() != null) {
BigDecimal prixMaillot = cat.getEquipementPrixByNom("Maillot");
if (prixMaillot == null) {
prixMaillot = BigDecimal.ZERO;
}
BigDecimal tarifTotal = cat.getTarifBase().add(prixMaillot);
return tarifTotal.intValue() + " €";
}
} catch (Exception e) {
// Return default on error
}
return "210 €";
}
@GetMapping("/succes")
public String showSucces() {
return "public/succes";
}
}