This is an automated email from the ASF dual-hosted git repository.
ilgrosso pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/syncope.git
The following commit(s) were added to refs/heads/master by this push:
new 00a4a9c464 [SYNCOPE-1981] Search audit events by who (#1438)
00a4a9c464 is described below
commit 00a4a9c464d7547585532d8cb7643ebd53db0968
Author: Oleg Zimakov <[email protected]>
AuthorDate: Fri Jun 26 02:56:47 2026 -0700
[SYNCOPE-1981] Search audit events by who (#1438)
---
.../syncope/common/rest/api/beans/AuditQuery.java | 22 +++++++
.../org/apache/syncope/core/logic/AuditLogic.java | 5 +-
.../core/rest/cxf/service/AuditServiceImpl.java | 1 +
.../core/persistence/api/dao/AuditEventDAO.java | 3 +
.../core/persistence/jpa/dao/JPAAuditEventDAO.java | 17 +++++
.../persistence/neo4j/dao/Neo4jAuditEventDAO.java | 14 +++++
.../dao/ElasticsearchAuditEventDAO.java | 16 ++++-
.../opensearch/dao/OpenSearchAuditEventDAO.java | 16 ++++-
.../org/apache/syncope/fit/core/AuditITCase.java | 72 ++++++++++++++++++++++
9 files changed, 160 insertions(+), 6 deletions(-)
diff --git
a/common/idrepo/rest-api/src/main/java/org/apache/syncope/common/rest/api/beans/AuditQuery.java
b/common/idrepo/rest-api/src/main/java/org/apache/syncope/common/rest/api/beans/AuditQuery.java
index cddcf3b616..9d82c912a0 100644
---
a/common/idrepo/rest-api/src/main/java/org/apache/syncope/common/rest/api/beans/AuditQuery.java
+++
b/common/idrepo/rest-api/src/main/java/org/apache/syncope/common/rest/api/beans/AuditQuery.java
@@ -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;
@@ -40,6 +43,11 @@ public class AuditQuery extends AbstractTimeframeQuery {
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;
@@ -68,6 +76,8 @@ public class AuditQuery extends AbstractTimeframeQuery {
private String entityKey;
+ private Set<String> who = new HashSet<>();
+
private OpEvent.CategoryType type;
private String category;
@@ -89,6 +99,18 @@ public class AuditQuery extends AbstractTimeframeQuery {
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() {
diff --git
a/core/idrepo/logic/src/main/java/org/apache/syncope/core/logic/AuditLogic.java
b/core/idrepo/logic/src/main/java/org/apache/syncope/core/logic/AuditLogic.java
index 89c9718cb7..291c5291e6 100644
---
a/core/idrepo/logic/src/main/java/org/apache/syncope/core/logic/AuditLogic.java
+++
b/core/idrepo/logic/src/main/java/org/apache/syncope/core/logic/AuditLogic.java
@@ -275,6 +275,7 @@ public class AuditLogic extends
AbstractTransactionalLogic<AuditConfTO> {
@Transactional(readOnly = true)
public Page<AuditEventTO> search(
final String entityKey,
+ final Set<String> who,
final OpEvent.CategoryType type,
final String category,
final String subcategory,
@@ -284,10 +285,10 @@ public class AuditLogic extends
AbstractTransactionalLogic<AuditConfTO> {
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);
}
diff --git
a/core/idrepo/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/AuditServiceImpl.java
b/core/idrepo/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/AuditServiceImpl.java
index 4d4578d462..468830cf5e 100644
---
a/core/idrepo/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/AuditServiceImpl.java
+++
b/core/idrepo/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/AuditServiceImpl.java
@@ -70,6 +70,7 @@ public class AuditServiceImpl extends AbstractService
implements AuditService {
public PagedResult<AuditEventTO> search(final AuditQuery auditQuery) {
Page<AuditEventTO> result = logic.search(
auditQuery.getEntityKey(),
+ auditQuery.getWho(),
auditQuery.getType(),
auditQuery.getCategory(),
auditQuery.getSubcategory(),
diff --git
a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/AuditEventDAO.java
b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/AuditEventDAO.java
index 6c5822ae0c..a2f9e2a107 100644
---
a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/AuditEventDAO.java
+++
b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/AuditEventDAO.java
@@ -20,6 +20,7 @@ package org.apache.syncope.core.persistence.api.dao;
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;
@@ -31,6 +32,7 @@ public interface AuditEventDAO {
long count(
String entityKey,
+ Set<String> who,
OpEvent.CategoryType type,
String category,
String subcategory,
@@ -54,6 +56,7 @@ public interface AuditEventDAO {
List<AuditEventTO> search(
String entityKey,
+ Set<String> who,
OpEvent.CategoryType type,
String category,
String subcategory,
diff --git
a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAAuditEventDAO.java
b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAAuditEventDAO.java
index 307dcc22eb..df621d77cd 100644
---
a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAAuditEventDAO.java
+++
b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAAuditEventDAO.java
@@ -24,6 +24,7 @@ import java.time.OffsetDateTime;
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;
@@ -34,6 +35,7 @@ import
org.apache.syncope.core.persistence.jpa.entity.JPAAuditEvent;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.transaction.annotation.Transactional;
+import org.springframework.util.CollectionUtils;
public class JPAAuditEventDAO extends AbstractAuditEventDAO implements
AuditEventDAO {
@@ -61,6 +63,17 @@ public class JPAAuditEventDAO extends AbstractAuditEventDAO
implements AuditEven
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,
@@ -127,6 +140,7 @@ public class JPAAuditEventDAO extends AbstractAuditEventDAO
implements AuditEven
@Override
public long count(
final String entityKey,
+ final Set<String> who,
final OpEvent.CategoryType type,
final String category,
final String subcategory,
@@ -139,6 +153,7 @@ public class JPAAuditEventDAO extends AbstractAuditEventDAO
implements AuditEven
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).
@@ -153,6 +168,7 @@ public class JPAAuditEventDAO extends AbstractAuditEventDAO
implements AuditEven
@Override
public List<AuditEventTO> search(
final String entityKey,
+ final Set<String> who,
final OpEvent.CategoryType type,
final String category,
final String subcategory,
@@ -166,6 +182,7 @@ public class JPAAuditEventDAO extends AbstractAuditEventDAO
implements AuditEven
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).
diff --git
a/core/persistence-neo4j/src/main/java/org/apache/syncope/core/persistence/neo4j/dao/Neo4jAuditEventDAO.java
b/core/persistence-neo4j/src/main/java/org/apache/syncope/core/persistence/neo4j/dao/Neo4jAuditEventDAO.java
index 6cc3d0903c..2c59bdbf0a 100644
---
a/core/persistence-neo4j/src/main/java/org/apache/syncope/core/persistence/neo4j/dao/Neo4jAuditEventDAO.java
+++
b/core/persistence-neo4j/src/main/java/org/apache/syncope/core/persistence/neo4j/dao/Neo4jAuditEventDAO.java
@@ -23,6 +23,7 @@ import java.util.HashMap;
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;
@@ -36,6 +37,7 @@ import org.springframework.data.domain.Sort;
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 extends AbstractAuditEventDAO implements
AuditEventDAO {
@@ -58,6 +60,14 @@ public class Neo4jAuditEventDAO extends
AbstractAuditEventDAO implements AuditEv
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,
@@ -125,6 +135,7 @@ public class Neo4jAuditEventDAO extends
AbstractAuditEventDAO implements AuditEv
@Override
public long count(
final String entityKey,
+ final Set<String> who,
final OpEvent.CategoryType type,
final String category,
final String subcategory,
@@ -136,6 +147,7 @@ public class Neo4jAuditEventDAO extends
AbstractAuditEventDAO implements AuditEv
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).
@@ -148,6 +160,7 @@ public class Neo4jAuditEventDAO extends
AbstractAuditEventDAO implements AuditEv
@Override
public List<AuditEventTO> search(
final String entityKey,
+ final Set<String> who,
final OpEvent.CategoryType type,
final String category,
final String subcategory,
@@ -161,6 +174,7 @@ public class Neo4jAuditEventDAO extends
AbstractAuditEventDAO implements AuditEv
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).
diff --git
a/ext/elasticsearch/persistence/src/main/java/org/apache/syncope/core/persistence/elasticsearch/dao/ElasticsearchAuditEventDAO.java
b/ext/elasticsearch/persistence/src/main/java/org/apache/syncope/core/persistence/elasticsearch/dao/ElasticsearchAuditEventDAO.java
index 4fe92c1fe7..2798489ee5 100644
---
a/ext/elasticsearch/persistence/src/main/java/org/apache/syncope/core/persistence/elasticsearch/dao/ElasticsearchAuditEventDAO.java
+++
b/ext/elasticsearch/persistence/src/main/java/org/apache/syncope/core/persistence/elasticsearch/dao/ElasticsearchAuditEventDAO.java
@@ -35,6 +35,7 @@ import java.io.IOException;
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;
@@ -81,6 +82,7 @@ public class ElasticsearchAuditEventDAO implements
AuditEventDAO {
protected Query getQuery(
final String entityKey,
+ final Set<String> who,
final OpEvent.CategoryType type,
final String category,
final String subcategory,
@@ -99,6 +101,14 @@ public class ElasticsearchAuditEventDAO implements
AuditEventDAO {
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).
@@ -127,6 +137,7 @@ public class ElasticsearchAuditEventDAO implements
AuditEventDAO {
@Override
public long count(
final String entityKey,
+ final Set<String> who,
final OpEvent.CategoryType type,
final String category,
final String subcategory,
@@ -137,7 +148,7 @@ public class ElasticsearchAuditEventDAO implements
AuditEventDAO {
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);
@@ -161,6 +172,7 @@ public class ElasticsearchAuditEventDAO implements
AuditEventDAO {
@Override
public List<AuditEventTO> search(
final String entityKey,
+ final Set<String> who,
final OpEvent.CategoryType type,
final String category,
final String subcategory,
@@ -173,7 +185,7 @@ public class ElasticsearchAuditEventDAO implements
AuditEventDAO {
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())).
diff --git
a/ext/opensearch/persistence/src/main/java/org/apache/syncope/core/persistence/opensearch/dao/OpenSearchAuditEventDAO.java
b/ext/opensearch/persistence/src/main/java/org/apache/syncope/core/persistence/opensearch/dao/OpenSearchAuditEventDAO.java
index 71833f4ce3..02bf3be892 100644
---
a/ext/opensearch/persistence/src/main/java/org/apache/syncope/core/persistence/opensearch/dao/OpenSearchAuditEventDAO.java
+++
b/ext/opensearch/persistence/src/main/java/org/apache/syncope/core/persistence/opensearch/dao/OpenSearchAuditEventDAO.java
@@ -22,6 +22,7 @@ import java.io.IOException;
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;
@@ -80,6 +81,7 @@ public class OpenSearchAuditEventDAO implements AuditEventDAO
{
protected Query getQuery(
final String entityKey,
+ final Set<String> who,
final OpEvent.CategoryType type,
final String category,
final String subcategory,
@@ -98,6 +100,14 @@ public class OpenSearchAuditEventDAO implements
AuditEventDAO {
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).
@@ -126,6 +136,7 @@ public class OpenSearchAuditEventDAO implements
AuditEventDAO {
@Override
public long count(
final String entityKey,
+ final Set<String> who,
final OpEvent.CategoryType type,
final String category,
final String subcategory,
@@ -136,7 +147,7 @@ public class OpenSearchAuditEventDAO implements
AuditEventDAO {
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);
@@ -160,6 +171,7 @@ public class OpenSearchAuditEventDAO implements
AuditEventDAO {
@Override
public List<AuditEventTO> search(
final String entityKey,
+ final Set<String> who,
final OpEvent.CategoryType type,
final String category,
final String subcategory,
@@ -172,7 +184,7 @@ public class OpenSearchAuditEventDAO implements
AuditEventDAO {
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())).
diff --git
a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/AuditITCase.java
b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/AuditITCase.java
index bbaedc394d..7d94db44a6 100644
---
a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/AuditITCase.java
+++
b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/AuditITCase.java
@@ -161,6 +161,78 @@ public class AuditITCase extends AbstractITCase {
USER_SERVICE.delete(userTO.getKey());
}
+ @Test
+ public void findByWho() {
+ UserTO userTO =
createUser(UserITCase.getUniqueSample("[email protected]")).getEntity();
+ assertNotNull(userTO.getKey());
+
+ // exact match on the author of the just-created user's create event
+ AuditQuery exact = new AuditQuery.Builder().
+ entityKey(userTO.getKey()).
+ who(ADMIN_UNAME).
+ type(OpEvent.CategoryType.LOGIC).
+ category(UserLogic.class.getSimpleName()).
+ op("create").
+ outcome(OpEvent.Outcome.SUCCESS).
+ build();
+ assertFalse(query(exact, MAX_WAIT_SECONDS).isEmpty());
+
+ // multiple who values are OR'ed: admin still matches alongside an
unrelated author
+ AuditQuery multiple = new AuditQuery.Builder().
+ entityKey(userTO.getKey()).
+ who(ADMIN_UNAME).
+ who("non-existent-" + UUID.randomUUID()).
+ type(OpEvent.CategoryType.LOGIC).
+ category(UserLogic.class.getSimpleName()).
+ op("create").
+ outcome(OpEvent.Outcome.SUCCESS).
+ build();
+ assertFalse(AUDIT_SERVICE.search(multiple).getResult().isEmpty());
+
+ // the who filter excludes non-matching authors
+ AuditQuery noMatch = new AuditQuery.Builder().
+ entityKey(userTO.getKey()).
+ who("non-existent-" + UUID.randomUUID()).
+ type(OpEvent.CategoryType.LOGIC).
+ category(UserLogic.class.getSimpleName()).
+ op("create").
+ outcome(OpEvent.Outcome.SUCCESS).
+ build();
+ assertTrue(AUDIT_SERVICE.search(noMatch).getResult().isEmpty());
+
+ USER_SERVICE.delete(userTO.getKey());
+ }
+
+ @Test
+ public void findByWhoIsExactMatch() {
+ UserTO userTO =
createUser(UserITCase.getUniqueSample("[email protected]")).getEntity();
+ assertNotNull(userTO.getKey());
+
+ // make sure the create event is there (matched exactly by the admin
author)
+ AuditQuery exact = new AuditQuery.Builder().
+ entityKey(userTO.getKey()).
+ who(ADMIN_UNAME).
+ type(OpEvent.CategoryType.LOGIC).
+ category(UserLogic.class.getSimpleName()).
+ op("create").
+ outcome(OpEvent.Outcome.SUCCESS).
+ build();
+ assertFalse(query(exact, MAX_WAIT_SECONDS).isEmpty());
+
+ // who matches exactly: a '*' is treated literally, not as a wildcard
+ AuditQuery wildcard = new AuditQuery.Builder().
+ entityKey(userTO.getKey()).
+ who(ADMIN_UNAME.substring(0, 3) + '*').
+ type(OpEvent.CategoryType.LOGIC).
+ category(UserLogic.class.getSimpleName()).
+ op("create").
+ outcome(OpEvent.Outcome.SUCCESS).
+ build();
+ assertTrue(AUDIT_SERVICE.search(wildcard).getResult().isEmpty());
+
+ USER_SERVICE.delete(userTO.getKey());
+ }
+
@Test
public void findByGroup() {
GroupTO groupTO =
createGroup(GroupITCase.getBasicSample("AuditGroup")).getEntity();