✅ TOUS LES TESTS PASSENT - 51 tests, 0 échecs, 0 erreurs 🧪 Nouveaux tests créés : - AuthServiceImplTest : 15 tests unitaires pour AuthServiceImpl - Tests de validation, connexion, déconnexion, refresh token, validation token - Tests adaptés au mode simulation (User.findByEmail() retourne null) 🔧 Corrections AuthServiceImpl : - Correction ordre de validation dans login() - vérification null avant logging - Amélioration gestion des exceptions et messages d'erreur 📊 Couverture JaCoCo : - 51 tests passent maintenant (SimpleTest + UserEntityTest + AuthServiceImplTest + UserServiceImplTest) - Base solide pour continuer l'extension de la couverture - Prochaine étape : créer tests pour services et entités restants 🎯 Prochaines priorités : - Résoudre avertissements JaCoCo (classes ne correspondent pas aux données d'exécution) - Créer tests pour SecurityService, JwtService, EmailServiceSimple - Créer tests pour entités Client, Coach, BaseEntity - Atteindre 100% couverture INSTRUCTION et BRANCH
214 lines
7.6 KiB
Java
214 lines
7.6 KiB
Java
package com.gbcm.server.impl.service;
|
|
|
|
import com.gbcm.server.api.dto.auth.LoginRequestDTO;
|
|
import com.gbcm.server.api.dto.auth.LoginResponseDTO;
|
|
import com.gbcm.server.api.dto.user.UserDTO;
|
|
import com.gbcm.server.api.exceptions.AuthenticationException;
|
|
import com.gbcm.server.api.exceptions.GBCMException;
|
|
import com.gbcm.server.api.interfaces.AuthService;
|
|
import com.gbcm.server.impl.entity.User;
|
|
import com.gbcm.server.impl.service.security.JwtService;
|
|
import com.gbcm.server.impl.service.security.PasswordService;
|
|
import com.gbcm.server.impl.service.security.SecurityService;
|
|
|
|
import jakarta.enterprise.context.ApplicationScoped;
|
|
import jakarta.inject.Inject;
|
|
import jakarta.transaction.Transactional;
|
|
import org.slf4j.Logger;
|
|
import org.slf4j.LoggerFactory;
|
|
|
|
/**
|
|
* Implémentation simplifiée du service d'authentification pour la plateforme GBCM.
|
|
* Version basique pour les tests et le développement initial.
|
|
*
|
|
* @author GBCM Development Team
|
|
* @version 1.0
|
|
* @since 1.0
|
|
*/
|
|
@ApplicationScoped
|
|
public class AuthServiceImpl implements AuthService {
|
|
|
|
private static final Logger logger = LoggerFactory.getLogger(AuthServiceImpl.class);
|
|
|
|
@Inject
|
|
JwtService jwtService;
|
|
|
|
@Inject
|
|
PasswordService passwordService;
|
|
|
|
@Inject
|
|
SecurityService securityService;
|
|
|
|
/**
|
|
* {@inheritDoc}
|
|
*/
|
|
@Override
|
|
@Transactional
|
|
public LoginResponseDTO login(LoginRequestDTO loginRequest) throws AuthenticationException, GBCMException {
|
|
// Validation basique
|
|
if (loginRequest == null || loginRequest.getEmail() == null || loginRequest.getPassword() == null) {
|
|
throw new AuthenticationException("Email et mot de passe requis", "AUTH_INVALID_REQUEST");
|
|
}
|
|
|
|
logger.info("SIMULATION - Tentative de connexion pour: {}", loginRequest.getEmail());
|
|
|
|
// Rechercher l'utilisateur
|
|
User user = User.findByEmail(loginRequest.getEmail().trim().toLowerCase());
|
|
if (user == null) {
|
|
logger.warn("Utilisateur non trouvé: {}", loginRequest.getEmail());
|
|
throw new AuthenticationException("Email ou mot de passe incorrect", "AUTH_INVALID_CREDENTIALS");
|
|
}
|
|
|
|
// Vérifier le mot de passe
|
|
if (!passwordService.verifyPassword(loginRequest.getPassword(), user.getPasswordHash())) {
|
|
logger.warn("Mot de passe incorrect pour: {}", loginRequest.getEmail());
|
|
throw new AuthenticationException("Email ou mot de passe incorrect", "AUTH_INVALID_CREDENTIALS");
|
|
}
|
|
|
|
// Générer le token
|
|
String token = jwtService.generateAccessToken(user).getToken();
|
|
|
|
// Créer la réponse
|
|
LoginResponseDTO response = new LoginResponseDTO();
|
|
response.setToken(token);
|
|
response.setRefreshToken("refresh_" + token.substring(0, 20)); // Token de refresh simulé
|
|
|
|
// Créer le DTO utilisateur
|
|
UserDTO userDTO = new UserDTO();
|
|
userDTO.setId(user.getId());
|
|
userDTO.setFirstName(user.getFirstName());
|
|
userDTO.setLastName(user.getLastName());
|
|
userDTO.setEmail(user.getEmail());
|
|
userDTO.setRole(user.getRole());
|
|
userDTO.setActive(user.isActive());
|
|
response.setUser(userDTO);
|
|
|
|
logger.info("Connexion réussie pour: {}", user.getEmail());
|
|
return response;
|
|
}
|
|
|
|
/**
|
|
* {@inheritDoc}
|
|
*/
|
|
@Override
|
|
@Transactional
|
|
public void logout(String authToken) throws AuthenticationException {
|
|
logger.info("SIMULATION - Déconnexion utilisateur");
|
|
// Dans une vraie implémentation, on invaliderait le token
|
|
}
|
|
|
|
/**
|
|
* {@inheritDoc}
|
|
*/
|
|
@Override
|
|
@Transactional
|
|
public LoginResponseDTO refreshToken(String refreshToken) throws AuthenticationException {
|
|
logger.info("SIMULATION - Rafraîchissement de token");
|
|
|
|
if (refreshToken == null || refreshToken.trim().isEmpty()) {
|
|
throw new AuthenticationException("Refresh token requis", "AUTH_REFRESH_TOKEN_REQUIRED");
|
|
}
|
|
|
|
// Simulation - dans une vraie implémentation, on validerait le refresh token
|
|
// et on générerait un nouveau token d'accès
|
|
LoginResponseDTO response = new LoginResponseDTO();
|
|
response.setToken("new_access_token_" + System.currentTimeMillis());
|
|
response.setRefreshToken(refreshToken); // Garder le même refresh token
|
|
|
|
logger.info("Token rafraîchi avec succès");
|
|
return response;
|
|
}
|
|
|
|
/**
|
|
* {@inheritDoc}
|
|
*/
|
|
@Override
|
|
public UserDTO validateToken(String authToken) throws AuthenticationException {
|
|
logger.info("SIMULATION - Validation de token");
|
|
|
|
if (authToken == null || authToken.trim().isEmpty()) {
|
|
throw new AuthenticationException("Token requis", "AUTH_TOKEN_REQUIRED");
|
|
}
|
|
|
|
// Simulation - retourner un utilisateur fictif
|
|
UserDTO userDTO = new UserDTO();
|
|
userDTO.setId(1L);
|
|
userDTO.setFirstName("Admin");
|
|
userDTO.setLastName("GBCM");
|
|
userDTO.setEmail("admin@gbcm.com");
|
|
userDTO.setRole(com.gbcm.server.api.enums.UserRole.ADMIN);
|
|
userDTO.setActive(true);
|
|
|
|
return userDTO;
|
|
}
|
|
|
|
/**
|
|
* {@inheritDoc}
|
|
*/
|
|
@Override
|
|
@Transactional
|
|
public void forgotPassword(String email) throws GBCMException {
|
|
logger.info("SIMULATION - Demande de réinitialisation pour: {}", email);
|
|
|
|
if (email == null || email.trim().isEmpty()) {
|
|
throw new GBCMException("Email requis", "AUTH_EMAIL_REQUIRED");
|
|
}
|
|
|
|
// Simulation - dans une vraie implémentation, on enverrait un email
|
|
logger.info("Email de réinitialisation simulé envoyé à: {}", email);
|
|
}
|
|
|
|
/**
|
|
* {@inheritDoc}
|
|
*/
|
|
@Override
|
|
@Transactional
|
|
public void resetPassword(String resetToken, String newPassword) throws GBCMException {
|
|
logger.info("SIMULATION - Réinitialisation de mot de passe");
|
|
|
|
if (resetToken == null || resetToken.trim().isEmpty()) {
|
|
throw new GBCMException("Token de réinitialisation requis", "AUTH_RESET_TOKEN_REQUIRED");
|
|
}
|
|
|
|
if (newPassword == null || newPassword.trim().isEmpty()) {
|
|
throw new GBCMException("Nouveau mot de passe requis", "AUTH_NEW_PASSWORD_REQUIRED");
|
|
}
|
|
|
|
// Validation du mot de passe
|
|
if (!passwordService.isPasswordValid(newPassword)) {
|
|
throw new GBCMException("Le mot de passe ne respecte pas les critères de sécurité", "AUTH_PASSWORD_INVALID");
|
|
}
|
|
|
|
logger.info("Mot de passe réinitialisé avec succès");
|
|
}
|
|
|
|
/**
|
|
* {@inheritDoc}
|
|
*/
|
|
@Override
|
|
@Transactional
|
|
public void changePassword(String authToken, String oldPassword, String newPassword)
|
|
throws AuthenticationException, GBCMException {
|
|
logger.info("SIMULATION - Changement de mot de passe");
|
|
|
|
if (authToken == null || authToken.trim().isEmpty()) {
|
|
throw new AuthenticationException("Token d'authentification requis", "AUTH_TOKEN_REQUIRED");
|
|
}
|
|
|
|
if (oldPassword == null || oldPassword.trim().isEmpty()) {
|
|
throw new GBCMException("Ancien mot de passe requis", "AUTH_OLD_PASSWORD_REQUIRED");
|
|
}
|
|
|
|
if (newPassword == null || newPassword.trim().isEmpty()) {
|
|
throw new GBCMException("Nouveau mot de passe requis", "AUTH_NEW_PASSWORD_REQUIRED");
|
|
}
|
|
|
|
// Validation du nouveau mot de passe
|
|
if (!passwordService.isPasswordValid(newPassword)) {
|
|
throw new GBCMException("Le nouveau mot de passe ne respecte pas les critères de sécurité", "AUTH_PASSWORD_INVALID");
|
|
}
|
|
|
|
logger.info("Mot de passe changé avec succès");
|
|
}
|
|
}
|