diff --git a/src/main/java/com/gbcm/server/impl/service/AuthServiceImpl.java b/src/main/java/com/gbcm/server/impl/service/AuthServiceImpl.java new file mode 100644 index 0000000..6f29adb --- /dev/null +++ b/src/main/java/com/gbcm/server/impl/service/AuthServiceImpl.java @@ -0,0 +1,213 @@ +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 { + logger.info("SIMULATION - Tentative de connexion pour: {}", loginRequest.getEmail()); + + // Validation basique + if (loginRequest == null || loginRequest.getEmail() == null || loginRequest.getPassword() == null) { + throw new AuthenticationException("Email et mot de passe requis", "AUTH_INVALID_REQUEST"); + } + + // 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"); + } +} diff --git a/src/main/java/com/gbcm/server/impl/service/UserServiceImpl.java b/src/main/java/com/gbcm/server/impl/service/UserServiceImpl.java new file mode 100644 index 0000000..09dd389 --- /dev/null +++ b/src/main/java/com/gbcm/server/impl/service/UserServiceImpl.java @@ -0,0 +1,283 @@ +package com.gbcm.server.impl.service; + +import com.gbcm.server.api.dto.common.PagedResultDTO; +import com.gbcm.server.api.dto.common.SuccessResponseDTO; +import com.gbcm.server.api.dto.user.CreateUserDTO; +import com.gbcm.server.api.dto.user.UpdateUserDTO; +import com.gbcm.server.api.dto.user.UserDTO; +import com.gbcm.server.api.enums.UserRole; +import com.gbcm.server.api.exceptions.AuthorizationException; +import com.gbcm.server.api.exceptions.GBCMException; +import com.gbcm.server.api.exceptions.ResourceNotFoundException; +import com.gbcm.server.api.exceptions.ValidationException; +import com.gbcm.server.api.interfaces.UserService; +import com.gbcm.server.impl.entity.User; +import com.gbcm.server.impl.service.security.PasswordService; + +import jakarta.enterprise.context.ApplicationScoped; +import jakarta.inject.Inject; +import jakarta.transaction.Transactional; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.util.ArrayList; +import java.util.List; + +/** + * Implémentation simplifiée du service de gestion des utilisateurs 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 UserServiceImpl implements UserService { + + private static final Logger logger = LoggerFactory.getLogger(UserServiceImpl.class); + + @Inject + PasswordService passwordService; + + /** + * {@inheritDoc} + */ + @Override + public PagedResultDTO getUsers(int page, int size, String sort, UserRole role, Boolean active, String search) + throws AuthorizationException { + + logger.info("SIMULATION - Récupération des utilisateurs - page: {}, size: {}", page, size); + + // Simulation - retourner une liste d'utilisateurs fictifs + List users = new ArrayList<>(); + + UserDTO admin = new UserDTO(); + admin.setId(1L); + admin.setFirstName("Admin"); + admin.setLastName("GBCM"); + admin.setEmail("admin@gbcm.com"); + admin.setRole(UserRole.ADMIN); + admin.setActive(true); + users.add(admin); + + UserDTO coach = new UserDTO(); + coach.setId(2L); + coach.setFirstName("Coach"); + coach.setLastName("Test"); + coach.setEmail("coach@gbcm.com"); + coach.setRole(UserRole.COACH); + coach.setActive(true); + users.add(coach); + + return new PagedResultDTO<>(users, page, size, 2L); + } + + /** + * {@inheritDoc} + */ + @Override + public UserDTO getUserById(Long id) throws AuthorizationException, ResourceNotFoundException { + logger.info("SIMULATION - Récupération de l'utilisateur avec ID: {}", id); + + if (id == null) { + throw new IllegalArgumentException("L'ID utilisateur ne peut pas être null"); + } + + // Simulation - retourner un utilisateur fictif + UserDTO userDTO = new UserDTO(); + userDTO.setId(id); + userDTO.setFirstName("Utilisateur"); + userDTO.setLastName("Test"); + userDTO.setEmail("user" + id + "@gbcm.com"); + userDTO.setRole(UserRole.CLIENT); + userDTO.setActive(true); + + return userDTO; + } + + /** + * {@inheritDoc} + */ + @Override + @Transactional + public UserDTO createUser(CreateUserDTO createUserDTO) throws ValidationException, GBCMException, AuthorizationException { + logger.info("SIMULATION - Création d'un nouvel utilisateur: {}", createUserDTO.getEmail()); + + // Validation basique + if (createUserDTO == null) { + throw new ValidationException("Données de création requises", "USER_CREATE_DATA_REQUIRED"); + } + + if (createUserDTO.getEmail() == null || createUserDTO.getEmail().trim().isEmpty()) { + throw new ValidationException("Email requis", "USER_EMAIL_REQUIRED"); + } + + // Simulation - créer un utilisateur fictif + UserDTO userDTO = new UserDTO(); + userDTO.setId(System.currentTimeMillis()); // ID simulé + userDTO.setFirstName(createUserDTO.getFirstName()); + userDTO.setLastName(createUserDTO.getLastName()); + userDTO.setEmail(createUserDTO.getEmail()); + userDTO.setRole(createUserDTO.getRole()); + userDTO.setActive(true); + + logger.info("Utilisateur créé avec succès (simulation): {}", userDTO.getEmail()); + return userDTO; + } + + /** + * {@inheritDoc} + */ + @Override + @Transactional + public UserDTO updateUser(Long id, UpdateUserDTO updateUserDTO) + throws ResourceNotFoundException, ValidationException, GBCMException, AuthorizationException { + + logger.info("SIMULATION - Mise à jour de l'utilisateur avec ID: {}", id); + + if (id == null) { + throw new IllegalArgumentException("L'ID utilisateur ne peut pas être null"); + } + + if (updateUserDTO == null) { + throw new ValidationException("Données de mise à jour requises", "USER_UPDATE_DATA_REQUIRED"); + } + + // Simulation - retourner un utilisateur mis à jour + UserDTO userDTO = new UserDTO(); + userDTO.setId(id); + userDTO.setFirstName(updateUserDTO.getFirstName() != null ? updateUserDTO.getFirstName() : "Prénom"); + userDTO.setLastName(updateUserDTO.getLastName() != null ? updateUserDTO.getLastName() : "Nom"); + userDTO.setEmail("user" + id + "@gbcm.com"); + userDTO.setPhone(updateUserDTO.getPhone()); + userDTO.setRole(updateUserDTO.getRole() != null ? updateUserDTO.getRole() : UserRole.CLIENT); + userDTO.setActive(updateUserDTO.getActive() != null ? updateUserDTO.getActive() : true); + + logger.info("Utilisateur mis à jour avec succès (simulation): {}", userDTO.getEmail()); + return userDTO; + } + + /** + * {@inheritDoc} + */ + @Override + @Transactional + public SuccessResponseDTO deleteUser(Long id) throws ResourceNotFoundException, AuthorizationException { + logger.info("SIMULATION - Suppression de l'utilisateur avec ID: {}", id); + + if (id == null) { + throw new IllegalArgumentException("L'ID utilisateur ne peut pas être null"); + } + + // Simulation - suppression réussie + logger.info("Utilisateur supprimé avec succès (simulation): {}", id); + + return new SuccessResponseDTO<>("Utilisateur supprimé avec succès", null); + } + + /** + * {@inheritDoc} + */ + @Override + @Transactional + public UserDTO changeUserStatus(Long id, boolean active) throws ResourceNotFoundException, AuthorizationException { + logger.info("SIMULATION - Changement de statut pour l'utilisateur ID: {} -> actif: {}", id, active); + + if (id == null) { + throw new IllegalArgumentException("L'ID utilisateur ne peut pas être null"); + } + + // Simulation - retourner un utilisateur avec le nouveau statut + UserDTO userDTO = new UserDTO(); + userDTO.setId(id); + userDTO.setFirstName("Utilisateur"); + userDTO.setLastName("Test"); + userDTO.setEmail("user" + id + "@gbcm.com"); + userDTO.setRole(UserRole.CLIENT); + userDTO.setActive(active); + + logger.info("Statut utilisateur changé avec succès (simulation): {} -> {}", id, active); + return userDTO; + } + + /** + * {@inheritDoc} + */ + @Override + public UserDTO getCurrentUserProfile(String authToken) throws AuthorizationException { + logger.info("SIMULATION - Récupération du profil utilisateur courant"); + + if (authToken == null || authToken.trim().isEmpty()) { + throw new AuthorizationException("Token d'authentification requis", "AUTH_TOKEN_REQUIRED"); + } + + // Simulation - retourner le profil de l'utilisateur courant + UserDTO userDTO = new UserDTO(); + userDTO.setId(1L); + userDTO.setFirstName("Utilisateur"); + userDTO.setLastName("Courant"); + userDTO.setEmail("current@gbcm.com"); + userDTO.setRole(UserRole.CLIENT); + userDTO.setActive(true); + + return userDTO; + } + + /** + * {@inheritDoc} + */ + @Override + @Transactional + public UserDTO updateCurrentUserProfile(String authToken, UpdateUserDTO updateUserDTO) + throws ValidationException, GBCMException, AuthorizationException { + + logger.info("SIMULATION - Mise à jour du profil utilisateur courant"); + + if (authToken == null || authToken.trim().isEmpty()) { + throw new AuthorizationException("Token d'authentification requis", "AUTH_TOKEN_REQUIRED"); + } + + if (updateUserDTO == null) { + throw new ValidationException("Données de mise à jour requises", "USER_UPDATE_DATA_REQUIRED"); + } + + // Simulation - retourner le profil mis à jour + UserDTO userDTO = new UserDTO(); + userDTO.setId(1L); + userDTO.setFirstName(updateUserDTO.getFirstName() != null ? updateUserDTO.getFirstName() : "Prénom"); + userDTO.setLastName(updateUserDTO.getLastName() != null ? updateUserDTO.getLastName() : "Nom"); + userDTO.setEmail("current@gbcm.com"); + userDTO.setPhone(updateUserDTO.getPhone()); + userDTO.setRole(UserRole.CLIENT); + userDTO.setActive(true); + + logger.info("Profil utilisateur mis à jour avec succès (simulation)"); + return userDTO; + } + + /** + * {@inheritDoc} + */ + @Override + public PagedResultDTO searchUsers(String query, int page, int size) throws AuthorizationException { + logger.info("SIMULATION - Recherche d'utilisateurs avec query: {}", query); + + if (query == null || query.trim().isEmpty()) { + throw new IllegalArgumentException("Terme de recherche requis"); + } + + // Simulation - retourner des résultats de recherche fictifs + List users = new ArrayList<>(); + + UserDTO result = new UserDTO(); + result.setId(1L); + result.setFirstName("Résultat"); + result.setLastName("Recherche"); + result.setEmail("search@gbcm.com"); + result.setRole(UserRole.CLIENT); + result.setActive(true); + users.add(result); + + return new PagedResultDTO<>(users, page, size, 1L); + } +}