Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,11 @@
package org.apache.syncope.common.rest.api.beans;

import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.media.ArraySchema;
import io.swagger.v3.oas.annotations.media.Schema;
import jakarta.ws.rs.QueryParam;
import java.util.HashSet;
import java.util.Set;
import org.apache.syncope.common.lib.types.OpEvent;
import org.apache.syncope.common.rest.api.service.JAXRSService;

Expand All @@ -40,6 +43,11 @@ public Builder entityKey(final String entityKey) {
return this;
}

public Builder who(final String who) {
getInstance().getWho().add(who);
return this;
}

public Builder type(final OpEvent.CategoryType type) {
getInstance().setType(type);
return this;
Expand Down Expand Up @@ -68,6 +76,8 @@ public Builder outcome(final OpEvent.Outcome outcome) {

private String entityKey;

private Set<String> who = new HashSet<>();

private OpEvent.CategoryType type;

private String category;
Expand All @@ -89,6 +99,18 @@ public void setEntityKey(final String entityKey) {
this.entityKey = entityKey;
}

@Parameter(name = "who", description = "audit event author(s) (username) to match; "
+ "may be repeated to match any of the given values", array =
@ArraySchema(schema = @Schema(implementation = String.class)))
public Set<String> getWho() {
return who;
}

@QueryParam("who")
public void setWho(final Set<String> who) {
this.who = who;
}

@Parameter(name = "type", description = "audit type to match", schema =
@Schema(implementation = OpEvent.CategoryType.class))
public OpEvent.CategoryType getType() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -275,6 +275,7 @@ public List<OpEvent> events() {
@Transactional(readOnly = true)
public Page<AuditEventTO> search(
final String entityKey,
final Set<String> who,
final OpEvent.CategoryType type,
final String category,
final String subcategory,
Expand All @@ -284,10 +285,10 @@ public Page<AuditEventTO> search(
final OffsetDateTime after,
final Pageable pageable) {

long count = auditEventDAO.count(entityKey, type, category, subcategory, op, result, before, after);
long count = auditEventDAO.count(entityKey, who, type, category, subcategory, op, result, before, after);

List<AuditEventTO> matching = auditEventDAO.search(
entityKey, type, category, subcategory, op, result, before, after, pageable);
entityKey, who, type, category, subcategory, op, result, before, after, pageable);

return new SyncopePage<>(matching, pageable, count);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,7 @@ public List<OpEvent> events() {
public PagedResult<AuditEventTO> search(final AuditQuery auditQuery) {
Page<AuditEventTO> result = logic.search(
auditQuery.getEntityKey(),
auditQuery.getWho(),
auditQuery.getType(),
auditQuery.getCategory(),
auditQuery.getSubcategory(),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@

import java.time.OffsetDateTime;
import java.util.List;
import java.util.Set;
import org.apache.syncope.common.lib.to.AuditEventTO;
import org.apache.syncope.common.lib.types.OpEvent;
import org.apache.syncope.core.persistence.api.entity.AuditEvent;
Expand All @@ -31,6 +32,7 @@ public interface AuditEventDAO {

long count(
String entityKey,
Set<String> who,
OpEvent.CategoryType type,
String category,
String subcategory,
Expand All @@ -54,6 +56,7 @@ default AuditEventTO toAuditEventTO(final AuditEvent auditEvent) {

List<AuditEventTO> search(
String entityKey,
Set<String> who,
OpEvent.CategoryType type,
String category,
String subcategory,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.Set;
import java.util.stream.Collectors;
import org.apache.syncope.common.lib.to.AuditEventTO;
import org.apache.syncope.common.lib.types.OpEvent;
Expand All @@ -32,6 +33,7 @@
import org.apache.syncope.core.persistence.jpa.entity.JPAAuditEvent;
import org.springframework.data.domain.Pageable;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

public class JPAAuditEventDAO implements AuditEventDAO {

Expand Down Expand Up @@ -59,6 +61,17 @@ protected AuditEventCriteriaBuilder entityKey(final String entityKey) {
return this;
}

public AuditEventCriteriaBuilder who(final Set<String> who, final List<Object> parameters) {
if (!CollectionUtils.isEmpty(who)) {
query.append(andIfNeeded()).append("who IN (").
append(who.stream().
map(value -> "?" + setParameter(parameters, value)).
collect(Collectors.joining(", "))).
append(")");
}
return this;
}

public AuditEventCriteriaBuilder opEvent(
final OpEvent.CategoryType type,
final String category,
Expand Down Expand Up @@ -125,6 +138,7 @@ protected void fillWithParameters(final Query query, final List<Object> paramete
@Override
public long count(
final String entityKey,
final Set<String> who,
final OpEvent.CategoryType type,
final String category,
final String subcategory,
Expand All @@ -137,6 +151,7 @@ public long count(
String queryString = "SELECT COUNT(0)"
+ " FROM " + JPAAuditEvent.TABLE
+ " WHERE" + criteriaBuilder(entityKey).
who(who, parameters).
opEvent(type, category, subcategory, op, outcome).
before(before, parameters).
after(after, parameters).
Expand All @@ -151,6 +166,7 @@ public long count(
@Override
public List<AuditEventTO> search(
final String entityKey,
final Set<String> who,
final OpEvent.CategoryType type,
final String category,
final String subcategory,
Expand All @@ -164,6 +180,7 @@ public List<AuditEventTO> search(
String queryString = "SELECT id"
+ " FROM " + JPAAuditEvent.TABLE
+ " WHERE" + criteriaBuilder(entityKey).
who(who, parameters).
opEvent(type, category, subcategory, op, outcome).
before(before, parameters).
after(after, parameters).
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.Set;
import java.util.stream.Collectors;
import org.apache.syncope.common.lib.to.AuditEventTO;
import org.apache.syncope.common.lib.types.OpEvent;
Expand All @@ -36,6 +37,7 @@
import org.springframework.data.neo4j.core.Neo4jClient;
import org.springframework.data.neo4j.core.Neo4jTemplate;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

public class Neo4jAuditEventDAO implements AuditEventDAO {

Expand All @@ -60,6 +62,14 @@ protected AuditEventCriteriaBuilder entityKey(final String entityKey) {
return this;
}

public AuditEventCriteriaBuilder who(final Set<String> who, final Map<String, Object> parameters) {
if (!CollectionUtils.isEmpty(who)) {
parameters.put("who", List.copyOf(who));
query.append(andIfNeeded()).append("n.who IN $who");
}
return this;
}

public AuditEventCriteriaBuilder opEvent(
final OpEvent.CategoryType type,
final String category,
Expand Down Expand Up @@ -127,6 +137,7 @@ protected AuditEventCriteriaBuilder criteriaBuilder(final String entityKey) {
@Override
public long count(
final String entityKey,
final Set<String> who,
final OpEvent.CategoryType type,
final String category,
final String subcategory,
Expand All @@ -138,6 +149,7 @@ public long count(
Map<String, Object> parameters = new HashMap<>();
String query = "MATCH (n:" + Neo4jAuditEvent.NODE + ") "
+ " WHERE " + criteriaBuilder(entityKey).
who(who, parameters).
opEvent(type, category, subcategory, op, outcome).
before(before, parameters).
after(after, parameters).
Expand All @@ -150,6 +162,7 @@ public long count(
@Override
public List<AuditEventTO> search(
final String entityKey,
final Set<String> who,
final OpEvent.CategoryType type,
final String category,
final String subcategory,
Expand All @@ -163,6 +176,7 @@ public List<AuditEventTO> search(

StringBuilder query = new StringBuilder("MATCH (n:" + Neo4jAuditEvent.NODE + ") "
+ "WHERE " + criteriaBuilder(entityKey).
who(who, parameters).
opEvent(type, category, subcategory, op, outcome).
before(before, parameters).
after(after, parameters).
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@
import java.time.OffsetDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
import java.util.stream.Stream;
import org.apache.syncope.common.lib.to.AuditEventTO;
import org.apache.syncope.common.lib.types.OpEvent;
Expand Down Expand Up @@ -81,6 +82,7 @@ public AuditEvent save(final AuditEvent auditEvent) {

protected Query getQuery(
final String entityKey,
final Set<String> who,
final OpEvent.CategoryType type,
final String category,
final String subcategory,
Expand All @@ -99,6 +101,14 @@ protected Query getQuery(
query("\"key\":\"" + entityKey + "\"").build()).build());
}

if (!CollectionUtils.isEmpty(who)) {
List<Query> whoQueries = who.stream().map(value -> new Query.Builder().
term(QueryBuilders.term().field("who").value(value).build()).build()).
toList();
queries.add(new Query.Builder().
bool(QueryBuilders.bool().should(whoQueries).minimumShouldMatch("1").build()).build());
}

queries.add(new Query.Builder().regexp(QueryBuilders.regexp().
field("opEvent").
value(OpEvent.toString(type, category, subcategory, op, outcome).
Expand Down Expand Up @@ -127,6 +137,7 @@ protected Query getQuery(
@Override
public long count(
final String entityKey,
final Set<String> who,
final OpEvent.CategoryType type,
final String category,
final String subcategory,
Expand All @@ -137,7 +148,7 @@ public long count(

CountRequest request = new CountRequest.Builder().
index(ElasticsearchUtils.getAuditIndex(AuthContextUtils.getDomain())).
query(getQuery(entityKey, type, category, subcategory, op, outcome, before, after)).
query(getQuery(entityKey, who, type, category, subcategory, op, outcome, before, after)).
build();
LOG.debug("Count request: {}", request);

Expand All @@ -161,6 +172,7 @@ protected List<SortOptions> sortBuilders(final Stream<Sort.Order> orderBy) {
@Override
public List<AuditEventTO> search(
final String entityKey,
final Set<String> who,
final OpEvent.CategoryType type,
final String category,
final String subcategory,
Expand All @@ -173,7 +185,7 @@ public List<AuditEventTO> search(
SearchRequest request = new SearchRequest.Builder().
index(ElasticsearchUtils.getAuditIndex(AuthContextUtils.getDomain())).
searchType(SearchType.QueryThenFetch).
query(getQuery(entityKey, type, category, subcategory, op, outcome, before, after)).
query(getQuery(entityKey, who, type, category, subcategory, op, outcome, before, after)).
from(pageable.isUnpaged() ? 0 : pageable.getPageSize() * pageable.getPageNumber()).
size(pageable.isUnpaged() ? indexMaxResultWindow : pageable.getPageSize()).
sort(sortBuilders(pageable.getSort().get())).
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
import java.time.OffsetDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
import java.util.stream.Stream;
import org.apache.syncope.common.lib.to.AuditEventTO;
import org.apache.syncope.common.lib.types.OpEvent;
Expand Down Expand Up @@ -80,6 +81,7 @@ public AuditEvent save(final AuditEvent auditEvent) {

protected Query getQuery(
final String entityKey,
final Set<String> who,
final OpEvent.CategoryType type,
final String category,
final String subcategory,
Expand All @@ -98,6 +100,14 @@ protected Query getQuery(
query("\"key\":\"" + entityKey + "\"").build()).build());
}

if (!CollectionUtils.isEmpty(who)) {
List<Query> whoQueries = who.stream().map(value -> new Query.Builder().
term(QueryBuilders.term().field("who").value(v -> v.stringValue(value)).build()).build()).
toList();
queries.add(new Query.Builder().
bool(QueryBuilders.bool().should(whoQueries).minimumShouldMatch("1").build()).build());
}

queries.add(new Query.Builder().regexp(QueryBuilders.regexp().
field("opEvent").
value(OpEvent.toString(type, category, subcategory, op, outcome).
Expand Down Expand Up @@ -126,6 +136,7 @@ protected Query getQuery(
@Override
public long count(
final String entityKey,
final Set<String> who,
final OpEvent.CategoryType type,
final String category,
final String subcategory,
Expand All @@ -136,7 +147,7 @@ public long count(

CountRequest request = new CountRequest.Builder().
index(OpenSearchUtils.getAuditIndex(AuthContextUtils.getDomain())).
query(getQuery(entityKey, type, category, subcategory, op, outcome, before, after)).
query(getQuery(entityKey, who, type, category, subcategory, op, outcome, before, after)).
build();
LOG.debug("Count request: {}", request);

Expand All @@ -160,6 +171,7 @@ protected List<SortOptions> sortBuilders(final Stream<Sort.Order> orderBy) {
@Override
public List<AuditEventTO> search(
final String entityKey,
final Set<String> who,
final OpEvent.CategoryType type,
final String category,
final String subcategory,
Expand All @@ -172,7 +184,7 @@ public List<AuditEventTO> search(
SearchRequest request = new SearchRequest.Builder().
index(OpenSearchUtils.getAuditIndex(AuthContextUtils.getDomain())).
searchType(SearchType.QueryThenFetch).
query(getQuery(entityKey, type, category, subcategory, op, outcome, before, after)).
query(getQuery(entityKey, who, type, category, subcategory, op, outcome, before, after)).
from(pageable.isUnpaged() ? 0 : pageable.getPageSize() * pageable.getPageNumber()).
size(pageable.isUnpaged() ? indexMaxResultWindow : pageable.getPageSize()).
sort(sortBuilders(pageable.getSort().get())).
Expand Down
Loading