AuditController.java
package com.edtech.controller;
import com.edtech.dto.AuditLogDto;
import com.edtech.model.AuditLog;
import com.edtech.model.User;
import com.edtech.repository.AuditLogRepository;
import com.edtech.repository.UserRepository;
import java.time.format.DateTimeFormatter;
import java.util.List;
import java.util.stream.Collectors;
import org.springframework.http.ResponseEntity;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
/** Controller para buscar logs de auditoria. */
@RestController
@RequestMapping("/api/audit-logs")
public class AuditController {
private final AuditLogRepository auditLogRepository;
private final UserRepository userRepository;
/**
* Construtor.
*
* @param auditLogRepository repo
* @param userRepository repo
*/
public AuditController(AuditLogRepository auditLogRepository, UserRepository userRepository) {
this.auditLogRepository = auditLogRepository;
this.userRepository = userRepository;
}
/**
* Busca logs de auditoria com filtro.
*
* @param search texto de busca
* @param action acao filtrada
* @return lista de logs
*/
@GetMapping
@PreAuthorize("hasRole('AUDITOR')")
public ResponseEntity<List<AuditLogDto>> getAuditLogs(
@RequestParam(required = false) String search,
@RequestParam(required = false) String action) {
List<AuditLog> logs = auditLogRepository.findAllByOrderByCreatedAtDesc();
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss.SSS");
List<AuditLogDto> dtos =
logs.stream()
.map(
log -> {
AuditLogDto dto = new AuditLogDto();
dto.setId(log.getId().toString());
dto.setTimestamp(log.getCreatedAt().format(formatter));
dto.setAction(log.getAction().name());
User user = userRepository.findById(log.getUserId()).orElse(null);
dto.setUserName(user != null ? user.getName() : "Unknown");
dto.setIp(log.getIpAddress());
dto.setDetails(log.getDetails());
// Determine Action Class and Severity based on Action
switch (log.getAction()) {
case LOGIN_SUCCESS:
case DOCUMENT_APPROVED:
dto.setActionClass("green");
dto.setSeverity("INFO");
break;
case LOGIN_FAILED:
case DOCUMENT_REJECTED:
case MEMBER_JOINED:
dto.setActionClass("orange");
dto.setSeverity("WARNING");
break;
case DELETE_DOCUMENT:
dto.setActionClass("red");
dto.setSeverity("CRITICAL");
break;
default:
dto.setActionClass("blue");
dto.setSeverity("INFO");
}
return dto;
})
.collect(Collectors.toList());
if (search != null && !search.isEmpty()) {
String s = search.toLowerCase();
dtos =
dtos.stream()
.filter(
dto ->
dto.getAction().toLowerCase().contains(s)
|| (dto.getDetails() != null
&& dto.getDetails().toLowerCase().contains(s))
|| dto.getUserName().toLowerCase().contains(s)
|| dto.getIp().contains(s))
.collect(Collectors.toList());
}
if (action != null && !action.isEmpty() && !action.equals("Todas as Ações")) {
dtos =
dtos.stream().filter(dto -> dto.getAction().equals(action)).collect(Collectors.toList());
}
return ResponseEntity.ok(dtos);
}
/**
* Exporta logs de auditoria para CSV.
*
* @param search texto de busca
* @param action acao filtrada
* @return Arquivo CSV
*/
@GetMapping("/export")
@PreAuthorize("hasRole('AUDITOR')")
public ResponseEntity<String> exportAuditLogs(
@RequestParam(required = false) String search,
@RequestParam(required = false) String action) {
ResponseEntity<List<AuditLogDto>> response = getAuditLogs(search, action);
List<AuditLogDto> dtos = response.getBody();
StringBuilder csv = new StringBuilder();
csv.append("ID,Timestamp,Action,User,IP,Details,Severity\n");
if (dtos != null) {
for (AuditLogDto dto : dtos) {
csv.append(escapeCsv(dto.getId()))
.append(",")
.append(escapeCsv(dto.getTimestamp()))
.append(",")
.append(escapeCsv(dto.getAction()))
.append(",")
.append(escapeCsv(dto.getUserName()))
.append(",")
.append(escapeCsv(dto.getIp()))
.append(",")
.append(escapeCsv(dto.getDetails()))
.append(",")
.append(escapeCsv(dto.getSeverity()))
.append("\n");
}
}
org.springframework.http.HttpHeaders headers = new org.springframework.http.HttpHeaders();
headers.add("Content-Disposition", "attachment; filename=\"audit_logs.csv\"");
headers.add("Content-Type", "text/csv; charset=UTF-8");
return ResponseEntity.ok().headers(headers).body(csv.toString());
}
private String escapeCsv(String value) {
if (value == null) {
return "";
}
String escaped = value.replace("\"", "\"\"");
if (escaped.contains(",") || escaped.contains("\"") || escaped.contains("\n")) {
return "\"" + escaped + "\"";
}
return escaped;
}
}