package dev.lions.user.manager.resource; import dev.lions.user.manager.api.AuditResourceApi; import dev.lions.user.manager.dto.audit.AuditLogDTO; import dev.lions.user.manager.dto.common.CountDTO; import dev.lions.user.manager.enums.audit.TypeActionAudit; import dev.lions.user.manager.service.AuditService; import jakarta.annotation.security.RolesAllowed; import jakarta.inject.Inject; import jakarta.ws.rs.core.Response; import org.eclipse.microprofile.config.inject.ConfigProperty; import lombok.extern.slf4j.Slf4j; import java.time.LocalDateTime; import java.util.List; import java.util.Map; import java.util.stream.Collectors; /** * REST Resource pour l'audit et la consultation des logs * Implémente l'interface API commune. */ @Slf4j @jakarta.enterprise.context.ApplicationScoped @jakarta.ws.rs.Path("/api/audit") public class AuditResource implements AuditResourceApi { private static final String DEFAULT_REALM_VALUE = "master"; @Inject AuditService auditService; @ConfigProperty(name = "lions.keycloak.admin-realm", defaultValue = DEFAULT_REALM_VALUE) String defaultRealm; @Override @RolesAllowed({ "admin", "auditor" }) public List searchLogs( String acteurUsername, String dateDebutStr, String dateFinStr, TypeActionAudit typeAction, String ressourceType, Boolean succes, int page, int pageSize) { log.info("POST /api/audit/search - Recherche de logs"); LocalDateTime dateDebut = dateDebutStr != null ? LocalDateTime.parse(dateDebutStr) : null; LocalDateTime dateFin = dateFinStr != null ? LocalDateTime.parse(dateFinStr) : null; // Utiliser findByActeur si acteurUsername est fourni, sinon findByRealm List logs; if (acteurUsername != null && !acteurUsername.isBlank()) { logs = auditService.findByActeur(acteurUsername, dateDebut, dateFin, page, pageSize); } else { // Pour une recherche générale, utiliser findByRealm (on utilise defaultRealm par // défaut) logs = auditService.findByRealm(defaultRealm, dateDebut, dateFin, page, pageSize); } // Filtrer par typeAction, ressourceType et succes si fournis if (typeAction != null || ressourceType != null || succes != null) { logs = logs.stream() .filter(log -> typeAction == null || typeAction.equals(log.getTypeAction())) .filter(log -> ressourceType == null || ressourceType.equals(log.getRessourceType())) .filter(log -> succes == null || succes == log.isSuccessful()) .collect(Collectors.toList()); } return logs; } @Override @RolesAllowed({ "admin", "auditor" }) public List getLogsByActor(String acteurUsername, int limit) { log.info("GET /api/audit/actor/{} - Limite: {}", acteurUsername, limit); return auditService.findByActeur(acteurUsername, null, null, 0, limit); } @Override @RolesAllowed({ "admin", "auditor" }) public List getLogsByResource(String ressourceType, String ressourceId, int limit) { log.info("GET /api/audit/resource/{}/{} - Limite: {}", ressourceType, ressourceId, limit); return auditService.findByRessource(ressourceType, ressourceId, null, null, 0, limit); } @Override @RolesAllowed({ "admin", "auditor" }) public List getLogsByAction(TypeActionAudit typeAction, String dateDebutStr, String dateFinStr, int limit) { log.info("GET /api/audit/action/{} - Limite: {}", typeAction, limit); LocalDateTime dateDebut = dateDebutStr != null ? LocalDateTime.parse(dateDebutStr) : null; LocalDateTime dateFin = dateFinStr != null ? LocalDateTime.parse(dateFinStr) : null; return auditService.findByTypeAction(typeAction, defaultRealm, dateDebut, dateFin, 0, limit); } @Override @RolesAllowed({ "admin", "auditor" }) public Map getActionStatistics(String dateDebutStr, String dateFinStr) { log.info("GET /api/audit/stats/actions - Période: {} à {}", dateDebutStr, dateFinStr); LocalDateTime dateDebut = dateDebutStr != null ? LocalDateTime.parse(dateDebutStr) : null; LocalDateTime dateFin = dateFinStr != null ? LocalDateTime.parse(dateFinStr) : null; return auditService.countByActionType(defaultRealm, dateDebut, dateFin); } @Override @RolesAllowed({ "admin", "auditor" }) public Map getUserActivityStatistics(String dateDebutStr, String dateFinStr) { log.info("GET /api/audit/stats/users - Période: {} à {}", dateDebutStr, dateFinStr); LocalDateTime dateDebut = dateDebutStr != null ? LocalDateTime.parse(dateDebutStr) : null; LocalDateTime dateFin = dateFinStr != null ? LocalDateTime.parse(dateFinStr) : null; return auditService.countByActeur(defaultRealm, dateDebut, dateFin); } @Override @RolesAllowed({ "admin", "auditor" }) public CountDTO getFailureCount(String dateDebutStr, String dateFinStr) { log.info("GET /api/audit/stats/failures - Période: {} à {}", dateDebutStr, dateFinStr); LocalDateTime dateDebut = dateDebutStr != null ? LocalDateTime.parse(dateDebutStr) : null; LocalDateTime dateFin = dateFinStr != null ? LocalDateTime.parse(dateFinStr) : null; Map successVsFailure = auditService.countSuccessVsFailure(defaultRealm, dateDebut, dateFin); long count = successVsFailure.getOrDefault("failure", 0L); return new CountDTO(count); } @Override @RolesAllowed({ "admin", "auditor" }) public CountDTO getSuccessCount(String dateDebutStr, String dateFinStr) { log.info("GET /api/audit/stats/success - Période: {} à {}", dateDebutStr, dateFinStr); LocalDateTime dateDebut = dateDebutStr != null ? LocalDateTime.parse(dateDebutStr) : null; LocalDateTime dateFin = dateFinStr != null ? LocalDateTime.parse(dateFinStr) : null; Map successVsFailure = auditService.countSuccessVsFailure(defaultRealm, dateDebut, dateFin); long count = successVsFailure.getOrDefault("success", 0L); return new CountDTO(count); } @Override @RolesAllowed({ "admin", "auditor" }) public Response exportLogsToCSV(String dateDebutStr, String dateFinStr) { log.info("GET /api/audit/export/csv - Période: {} à {}", dateDebutStr, dateFinStr); try { LocalDateTime dateDebut = dateDebutStr != null ? LocalDateTime.parse(dateDebutStr) : null; LocalDateTime dateFin = dateFinStr != null ? LocalDateTime.parse(dateFinStr) : null; String csvContent = auditService.exportToCSV(defaultRealm, dateDebut, dateFin); return Response.ok(csvContent) .header("Content-Disposition", "attachment; filename=\"audit-logs-" + LocalDateTime.now().toString().replace(":", "-") + ".csv\"") .build(); } catch (Exception e) { log.error("Erreur lors de l'export CSV des logs", e); throw new RuntimeException(e); } } @Override @RolesAllowed({ "admin" }) public void purgeOldLogs(int joursAnciennete) { log.info("DELETE /api/audit/purge - Suppression des logs de plus de {} jours", joursAnciennete); LocalDateTime dateLimite = LocalDateTime.now().minusDays(joursAnciennete); auditService.purgeOldLogs(dateLimite); } }