package dev.lions.user.manager.mapper; import dev.lions.user.manager.dto.user.UserDTO; import dev.lions.user.manager.enums.user.StatutUser; import org.keycloak.representations.idm.UserRepresentation; import java.time.Instant; import java.time.LocalDateTime; import java.time.ZoneId; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.stream.Collectors; /** * Mapper pour convertir UserRepresentation (Keycloak) -> UserDTO * Utilisé pour transformer les objets de l'API Keycloak vers nos DTOs */ public class UserMapper { private UserMapper() { // Classe utilitaire } /** * Convertit UserRepresentation vers UserDTO * @param userRep UserRepresentation de Keycloak * @param realmName nom du realm * @return UserDTO */ public static UserDTO toDTO(UserRepresentation userRep, String realmName) { if (userRep == null) { return null; } return UserDTO.builder() .id(userRep.getId()) .username(userRep.getUsername()) .email(userRep.getEmail()) .emailVerified(userRep.isEmailVerified()) .prenom(userRep.getFirstName()) .nom(userRep.getLastName()) .statut(StatutUser.fromEnabled(userRep.isEnabled())) .enabled(userRep.isEnabled()) .realmName(realmName) .attributes(userRep.getAttributes()) .requiredActions(userRep.getRequiredActions()) .dateCreation(convertTimestamp(userRep.getCreatedTimestamp())) .telephone(getAttributeValue(userRep, "phone_number")) .organisation(getAttributeValue(userRep, "organization")) .departement(getAttributeValue(userRep, "department")) .fonction(getAttributeValue(userRep, "job_title")) .pays(getAttributeValue(userRep, "country")) .ville(getAttributeValue(userRep, "city")) .langue(getAttributeValue(userRep, "locale")) .timezone(getAttributeValue(userRep, "timezone")) .build(); } /** * Convertit UserDTO vers UserRepresentation * @param userDTO UserDTO * @return UserRepresentation */ public static UserRepresentation toRepresentation(UserDTO userDTO) { if (userDTO == null) { return null; } UserRepresentation userRep = new UserRepresentation(); userRep.setId(userDTO.getId()); userRep.setUsername(userDTO.getUsername()); userRep.setEmail(userDTO.getEmail()); userRep.setEmailVerified(userDTO.getEmailVerified()); userRep.setFirstName(userDTO.getPrenom()); userRep.setLastName(userDTO.getNom()); userRep.setEnabled(userDTO.getEnabled() != null ? userDTO.getEnabled() : true); // Attributs personnalisés Map> attributes = new HashMap<>(); if (userDTO.getTelephone() != null) { attributes.put("phone_number", List.of(userDTO.getTelephone())); } if (userDTO.getOrganisation() != null) { attributes.put("organization", List.of(userDTO.getOrganisation())); } if (userDTO.getDepartement() != null) { attributes.put("department", List.of(userDTO.getDepartement())); } if (userDTO.getFonction() != null) { attributes.put("job_title", List.of(userDTO.getFonction())); } if (userDTO.getPays() != null) { attributes.put("country", List.of(userDTO.getPays())); } if (userDTO.getVille() != null) { attributes.put("city", List.of(userDTO.getVille())); } if (userDTO.getLangue() != null) { attributes.put("locale", List.of(userDTO.getLangue())); } if (userDTO.getTimezone() != null) { attributes.put("timezone", List.of(userDTO.getTimezone())); } // Ajouter les attributs existants du DTO if (userDTO.getAttributes() != null) { attributes.putAll(userDTO.getAttributes()); } userRep.setAttributes(attributes); // Actions requises if (userDTO.getRequiredActions() != null) { userRep.setRequiredActions(userDTO.getRequiredActions()); } return userRep; } /** * Convertit une liste de UserRepresentation vers UserDTO * @param userReps liste de UserRepresentation * @param realmName nom du realm * @return liste de UserDTO */ public static List toDTOList(List userReps, String realmName) { if (userReps == null) { return new ArrayList<>(); } return userReps.stream() .map(userRep -> toDTO(userRep, realmName)) .collect(Collectors.toList()); } /** * Récupère la valeur d'un attribut Keycloak * @param userRep UserRepresentation * @param attributeName nom de l'attribut * @return valeur de l'attribut ou null */ private static String getAttributeValue(UserRepresentation userRep, String attributeName) { if (userRep.getAttributes() == null) { return null; } List values = userRep.getAttributes().get(attributeName); if (values == null || values.isEmpty()) { return null; } return values.get(0); } /** * Convertit un timestamp (millisecondes) vers LocalDateTime * @param timestamp timestamp en millisecondes * @return LocalDateTime ou null */ private static LocalDateTime convertTimestamp(Long timestamp) { if (timestamp == null) { return null; } return LocalDateTime.ofInstant( Instant.ofEpochMilli(timestamp), ZoneId.systemDefault() ); } }