Skip to content

Commit

Permalink
Filter audit logs by event type in the backend
Browse files Browse the repository at this point in the history
Co-authored-by: mindmonk <[email protected]>
  • Loading branch information
SailReal and mindmonk committed Feb 10, 2025
1 parent fdfa1a0 commit c4ec06a
Show file tree
Hide file tree
Showing 4 changed files with 21 additions and 7 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -54,11 +54,12 @@ public class AuditLogResource {
@Parameter(name = "paginationId", description = "The smallest (asc ordering) or highest (desc ordering) audit entry id, not included in results. Used for pagination. ", in = ParameterIn.QUERY)
@Parameter(name = "order", description = "The order of the queried table. Determines if most recent (desc) or oldest entries (asc) are considered first. Allowed Values are 'desc' (default) or 'asc'. Used for pagination.", in = ParameterIn.QUERY)
@Parameter(name = "pageSize", description = "the maximum number of entries to return. Must be between 1 and 100.", in = ParameterIn.QUERY)
@Parameter(name = "type", description = "the list of type of events to return. Empty list is all events.", in = ParameterIn.QUERY)
@APIResponse(responseCode = "200", description = "Body contains list of events in the specified time interval")
@APIResponse(responseCode = "400", description = "startDate or endDate not specified, startDate > endDate, order specified and not in ['asc','desc'] or pageSize not in [1 .. 100]")
@APIResponse(responseCode = "402", description = "Community license used or license expired")
@APIResponse(responseCode = "403", description = "requesting user does not have admin role")
public List<AuditEventDto> getAllEvents(@QueryParam("startDate") Instant startDate, @QueryParam("endDate") Instant endDate, @QueryParam("paginationId") Long paginationId, @QueryParam("order") @DefaultValue("desc") String order, @QueryParam("pageSize") @DefaultValue("20") int pageSize) {
public List<AuditEventDto> getAllEvents(@QueryParam("startDate") Instant startDate, @QueryParam("endDate") Instant endDate, @QueryParam("type") List<String> type, @QueryParam("paginationId") Long paginationId, @QueryParam("order") @DefaultValue("desc") String order, @QueryParam("pageSize") @DefaultValue("20") int pageSize) {
if (!license.isSet() || license.isExpired()) {
throw new PaymentRequiredException("Community license used or license expired");
}
Expand All @@ -71,11 +72,13 @@ public List<AuditEventDto> getAllEvents(@QueryParam("startDate") Instant startDa
throw new BadRequestException("order must be either 'asc' or 'desc'");
} else if (pageSize < 1 || pageSize > 100) {
throw new BadRequestException("pageSize must be between 1 and 100");
} else if (type == null) {
throw new BadRequestException("type must be specified");
} else if (paginationId == null) {
throw new BadRequestException("paginationId must be specified");
}

return auditEventRepo.findAllInPeriod(startDate, endDate, paginationId, order.equals("asc"), pageSize).map(AuditEventDto::fromEntity).toList();
return auditEventRepo.findAllInPeriod(startDate, endDate, type, paginationId, order.equals("asc"), pageSize).map(AuditEventDto::fromEntity).toList();
}

@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, include = JsonTypeInfo.As.PROPERTY, property = "type")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
import jakarta.persistence.Table;

import java.time.Instant;
import java.util.List;
import java.util.Objects;
import java.util.stream.Stream;

Expand All @@ -31,6 +32,7 @@
WHERE ae.timestamp >= :startDate
AND ae.timestamp < :endDate
AND ae.id < :paginationId
AND (:allTypes = true OR ae.type IN :types)
ORDER BY ae.id DESC
""")
@NamedQuery(name = "AuditEvent.listAllInPeriodAfterId",
Expand All @@ -40,6 +42,7 @@
WHERE ae.timestamp >= :startDate
AND ae.timestamp < :endDate
AND ae.id > :paginationId
AND (:allTypes = true OR ae.type IN :types)
ORDER BY ae.id ASC
""")
@SequenceGenerator(name = "audit_event_id_seq", sequenceName = "audit_event_id_seq", allocationSize = 1)
Expand Down Expand Up @@ -106,8 +109,14 @@ public int hashCode() {
@ApplicationScoped
public static class Repository implements PanacheRepository<AuditEvent> {

public Stream<AuditEvent> findAllInPeriod(Instant startDate, Instant endDate, long paginationId, boolean ascending, int pageSize) {
var parameters = Parameters.with("startDate", startDate).and("endDate", endDate).and("paginationId", paginationId);
public Stream<AuditEvent> findAllInPeriod(Instant startDate, Instant endDate, List<String> type, long paginationId, boolean ascending, int pageSize) {
var allTypes = type.isEmpty();

var parameters = Parameters.with("startDate", startDate)
.and("endDate", endDate)
.and("paginationId", paginationId)
.and("types", type)
.and("allTypes", allTypes);

final PanacheQuery<AuditEvent> query;
if (ascending) {
Expand Down
5 changes: 3 additions & 2 deletions frontend/src/common/auditlog.ts
Original file line number Diff line number Diff line change
Expand Up @@ -162,8 +162,9 @@ export class AuditLogEntityCache {
/* Service */

class AuditLogService {
public async getAllEvents(startDate: Date, endDate: Date, paginationId: number, order: string, pageSize: number): Promise<AuditEventDto[]> {
return axiosAuth.get<AuditEventDto[]>(`/auditlog?startDate=${startDate.toISOString()}&endDate=${endDate.toISOString()}&paginationId=${paginationId}&order=${order}&pageSize=${pageSize}`)
public async getAllEvents(startDate: Date, endDate: Date, type: string[], paginationId: number, order: string, pageSize: number): Promise<AuditEventDto[]> {
const typeQuery = (type.length > 0 ? `&type=${type.join('&type=')}` : '');
return axiosAuth.get<AuditEventDto[]>(`/auditlog?startDate=${startDate.toISOString()}&endDate=${endDate.toISOString()}&paginationId=${paginationId}${typeQuery}&order=${order}&pageSize=${pageSize}`)
.then(response => response.data.map(dto => {
dto.timestamp = new Date(dto.timestamp);
return dto;
Expand Down
3 changes: 2 additions & 1 deletion frontend/src/components/AuditLog.vue
Original file line number Diff line number Diff line change
Expand Up @@ -290,7 +290,8 @@ async function fetchData(page: number = 0) {
onFetchError.value = null;
try {
// Fetch one more event than the page size to determine if there is a next page
const events = await auditlog.service.getAllEvents(startDate.value, endDate.value, lastIdOfPreviousPage[page], selectedOrder.value, pageSize.value + 1);
// TODO pass here as [] the filter types to the backend
const events = await auditlog.service.getAllEvents(startDate.value, endDate.value, [], lastIdOfPreviousPage[page], selectedOrder.value, pageSize.value + 1);
// If the lastIdOfPreviousPage for the first page has not been set yet, set it to an id "before"/"after" the first event
if (page == 0 && lastIdOfPreviousPage[0] == 0 && events.length > 0) {
lastIdOfPreviousPage[0] = events[0].id + orderOptions[selectedOrder.value].sign;
Expand Down

0 comments on commit c4ec06a

Please sign in to comment.