Refactoring

This commit is contained in:
dahoud
2026-01-31 16:54:46 +00:00
parent ce89face73
commit 9dc9ca591c
85 changed files with 2643 additions and 381 deletions

View File

@@ -2,6 +2,7 @@ package com.lions.dev.resource;
import com.lions.dev.dto.PasswordResetRequest;
import com.lions.dev.dto.request.users.AssignRoleRequestDTO;
import com.lions.dev.dto.request.users.SetUserActiveRequestDTO;
import com.lions.dev.dto.request.users.UserAuthenticateRequestDTO;
import com.lions.dev.dto.request.users.UserCreateRequestDTO;
import com.lions.dev.dto.response.users.UserAuthenticateResponseDTO;
@@ -9,6 +10,7 @@ import com.lions.dev.dto.response.users.UserCreateResponseDTO;
import com.lions.dev.dto.response.users.UserDeleteResponseDto;
import com.lions.dev.entity.users.Users;
import com.lions.dev.exception.UserNotFoundException;
import com.lions.dev.service.PasswordResetService;
import com.lions.dev.service.UsersService;
import jakarta.inject.Inject;
import jakarta.transaction.Transactional;
@@ -42,6 +44,9 @@ public class UsersResource {
@Inject
UsersService userService;
@Inject
PasswordResetService passwordResetService;
@ConfigProperty(name = "afterwork.super-admin.api-key", defaultValue = "")
Optional<String> superAdminApiKey;
@@ -300,18 +305,8 @@ public class UsersResource {
LOG.info("Demande de reinitialisation de mot de passe pour l'email : " + request.getEmail());
try {
// Rechercher l'utilisateur par email
Users user = userService.findByEmail(request.getEmail());
if (user != null) {
// En standby : pas encore de service d'envoi de mail. Quand disponible :
// - generer un token de reset (table dédiée ou champ user avec expiration)
// - appeler emailService.sendPasswordResetEmail(user.getEmail(), resetToken)
// Pour l'instant, on retourne success pour ne pas reveler si l'email existe.
LOG.info("Utilisateur trouve, email de reinitialisation (en standby - pas de mail service) : " + request.getEmail());
} else {
LOG.info("Aucun utilisateur trouve avec cet email (ne pas reveler) : " + request.getEmail());
}
// Le service gère tout : création du token et envoi de l'email
passwordResetService.initiatePasswordReset(request.getEmail());
// Toujours retourner 200 pour ne pas reveler si l'email existe
return Response.ok()
@@ -326,6 +321,50 @@ public class UsersResource {
}
}
/**
* Endpoint pour réinitialiser le mot de passe avec un token valide.
*
* @param token Le token de réinitialisation reçu par email.
* @param newPassword Le nouveau mot de passe.
* @return Une réponse HTTP indiquant si la réinitialisation a réussi.
*/
@POST
@Path("/reset-password")
@Operation(summary = "Réinitialiser le mot de passe avec un token",
description = "Réinitialise le mot de passe en utilisant le token reçu par email")
@APIResponse(responseCode = "200", description = "Mot de passe réinitialisé avec succès")
@APIResponse(responseCode = "400", description = "Token invalide ou expiré")
public Response resetPasswordWithToken(
@QueryParam("token") String token,
@QueryParam("newPassword") String newPassword) {
if (token == null || token.isBlank()) {
return Response.status(Response.Status.BAD_REQUEST)
.entity(Map.of("message", "Le token est requis"))
.build();
}
if (newPassword == null || newPassword.length() < 8) {
return Response.status(Response.Status.BAD_REQUEST)
.entity(Map.of("message", "Le mot de passe doit contenir au moins 8 caractères"))
.build();
}
boolean success = passwordResetService.resetPassword(token, newPassword);
if (success) {
LOG.info("Mot de passe réinitialisé avec succès via token");
return Response.ok()
.entity(Map.of("message", "Votre mot de passe a été réinitialisé avec succès"))
.build();
} else {
LOG.warn("Échec de réinitialisation : token invalide ou expiré");
return Response.status(Response.Status.BAD_REQUEST)
.entity(Map.of("message", "Le lien de réinitialisation est invalide ou a expiré"))
.build();
}
}
/**
* Attribue un rôle à un utilisateur (réservé au super administrateur).
* Requiert le header X-Super-Admin-Key correspondant à afterwork.super-admin.api-key.
@@ -420,4 +459,51 @@ public class UsersResource {
}
}
/**
* Force l'activation ou la suspension d'un utilisateur (réservé au super administrateur).
* Utilisé pour les managers : active = false = suspendu.
*
* @param id L'ID de l'utilisateur.
* @param request Le DTO contenant active (true = forcer l'activation, false = suspendre).
* @param apiKeyHeader Valeur du header X-Super-Admin-Key.
* @return L'utilisateur mis à jour.
*/
@PATCH
@Path("/{id}/active")
@Transactional
@Operation(summary = "Forcer activation ou suspendre un utilisateur (super admin)",
description = "Modifie le statut actif (isActive) d'un utilisateur. Réservé au super administrateur (header X-Super-Admin-Key).")
@APIResponse(responseCode = "200", description = "Statut actif mis à jour")
@APIResponse(responseCode = "403", description = "Clé super admin invalide ou absente")
@APIResponse(responseCode = "404", description = "Utilisateur non trouvé")
public Response setUserActive(
@PathParam("id") UUID id,
@Valid SetUserActiveRequestDTO request,
@HeaderParam(SUPER_ADMIN_KEY_HEADER) String apiKeyHeader) {
String key = superAdminApiKey.orElse("");
if (key.isBlank()) {
LOG.warn("Opération setUserActive refusée : afterwork.super-admin.api-key non configurée");
return Response.status(Response.Status.FORBIDDEN)
.entity("{\"message\": \"Opération non autorisée : clé super admin non configurée.\"}")
.build();
}
if (apiKeyHeader == null || !apiKeyHeader.equals(key)) {
LOG.warn("Opération setUserActive refusée : clé super admin invalide ou absente");
return Response.status(Response.Status.FORBIDDEN)
.entity("{\"message\": \"Clé super administrateur invalide ou absente.\"}")
.build();
}
try {
Users user = userService.setUserActive(id, request.getActive());
UserCreateResponseDTO responseDTO = new UserCreateResponseDTO(user);
return Response.ok(responseDTO).build();
} catch (UserNotFoundException e) {
return Response.status(Response.Status.NOT_FOUND)
.entity("{\"message\": \"" + e.getMessage() + "\"}")
.build();
}
}
}