This is an automated email from the ASF dual-hosted git repository.
ilgrosso pushed a commit to branch 4_0_X
in repository https://gitbox.apache.org/repos/asf/syncope.git
The following commit(s) were added to refs/heads/4_0_X by this push:
new 0020ef75d4 Restricting orderby clauses for Audit Events search (#1437)
0020ef75d4 is described below
commit 0020ef75d43cc18ba142e02c27b39ee157496d6f
Author: Francesco Chicchiriccò <[email protected]>
AuthorDate: Wed Jun 24 14:31:17 2026 +0200
Restricting orderby clauses for Audit Events search (#1437)
---
.../common/dao/AbstractAuditEventDAO.java | 37 ++++++++++++++++++++++
.../core/persistence/jpa/dao/JPAAuditEventDAO.java | 10 ++++--
.../persistence/neo4j/dao/Neo4jAuditEventDAO.java | 13 ++++----
.../core/persistence/neo4j/dao/Neo4jTaskDAO.java | 4 +--
4 files changed, 52 insertions(+), 12 deletions(-)
diff --git
a/core/persistence-common/src/main/java/org/apache/syncope/core/persistence/common/dao/AbstractAuditEventDAO.java
b/core/persistence-common/src/main/java/org/apache/syncope/core/persistence/common/dao/AbstractAuditEventDAO.java
new file mode 100644
index 0000000000..a84dd746fc
--- /dev/null
+++
b/core/persistence-common/src/main/java/org/apache/syncope/core/persistence/common/dao/AbstractAuditEventDAO.java
@@ -0,0 +1,37 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.syncope.core.persistence.common.dao;
+
+import java.util.List;
+import java.util.stream.Stream;
+import org.apache.syncope.core.persistence.api.entity.AuditEvent;
+import org.springframework.data.domain.Sort;
+import org.springframework.util.ReflectionUtils;
+
+public abstract class AbstractAuditEventDAO {
+
+ protected List<Sort.Order> filterOrderBy(
+ final Stream<Sort.Order> orderByClauses,
+ final Class<? extends AuditEvent> clazz) {
+
+ return orderByClauses.
+ filter(clause -> ReflectionUtils.findField(clazz,
clause.getProperty().trim()) != null).
+ toList();
+ }
+}
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 180338ea1b..4d9baa3cb7 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
@@ -29,11 +29,13 @@ import org.apache.syncope.common.lib.to.AuditEventTO;
import org.apache.syncope.common.lib.types.OpEvent;
import org.apache.syncope.core.persistence.api.dao.AuditEventDAO;
import org.apache.syncope.core.persistence.api.entity.AuditEvent;
+import org.apache.syncope.core.persistence.common.dao.AbstractAuditEventDAO;
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;
-public class JPAAuditEventDAO implements AuditEventDAO {
+public class JPAAuditEventDAO extends AbstractAuditEventDAO implements
AuditEventDAO {
protected static class AuditEventCriteriaBuilder {
@@ -168,8 +170,10 @@ public class JPAAuditEventDAO implements AuditEventDAO {
before(before, parameters).
after(after, parameters).
build();
- if (!pageable.getSort().isEmpty()) {
- queryString += " ORDER BY " + pageable.getSort().stream().
+
+ List<Sort.Order> orderBy = filterOrderBy(pageable.getSort().stream(),
JPAAuditEvent.class);
+ if (!orderBy.isEmpty()) {
+ queryString += " ORDER BY " + orderBy.stream().
map(clause -> ("when".equals(clause.getProperty()) ?
"event_date" : clause.getProperty())
+ ' ' + clause.getDirection().name()).
collect(Collectors.joining(","));
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 8c8d9f2b4f..6cc3d0903c 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
@@ -28,18 +28,16 @@ import org.apache.syncope.common.lib.to.AuditEventTO;
import org.apache.syncope.common.lib.types.OpEvent;
import org.apache.syncope.core.persistence.api.dao.AuditEventDAO;
import org.apache.syncope.core.persistence.api.entity.AuditEvent;
+import org.apache.syncope.core.persistence.common.dao.AbstractAuditEventDAO;
import org.apache.syncope.core.persistence.neo4j.entity.Neo4jAuditEvent;
import org.apache.syncope.core.persistence.neo4j.spring.NodeValidator;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
import org.springframework.data.domain.Pageable;
+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;
-public class Neo4jAuditEventDAO implements AuditEventDAO {
-
- protected static final Logger LOG =
LoggerFactory.getLogger(AuditEventDAO.class);
+public class Neo4jAuditEventDAO extends AbstractAuditEventDAO implements
AuditEventDAO {
protected static class AuditEventCriteriaBuilder {
@@ -169,8 +167,9 @@ public class Neo4jAuditEventDAO implements AuditEventDAO {
build()
+ " RETURN n.id");
- if (!pageable.getSort().isEmpty()) {
- query.append(" ORDER BY ").append(pageable.getSort().stream().
+ List<Sort.Order> orderBy = filterOrderBy(pageable.getSort().stream(),
Neo4jAuditEvent.class);
+ if (!orderBy.isEmpty()) {
+ query.append(" ORDER BY ").append(orderBy.stream().
map(clause -> "n." + clause.getProperty() + ' ' +
clause.getDirection().name()).
collect(Collectors.joining(",")));
}
diff --git
a/core/persistence-neo4j/src/main/java/org/apache/syncope/core/persistence/neo4j/dao/Neo4jTaskDAO.java
b/core/persistence-neo4j/src/main/java/org/apache/syncope/core/persistence/neo4j/dao/Neo4jTaskDAO.java
index 75576dd5c5..28470fdbfa 100644
---
a/core/persistence-neo4j/src/main/java/org/apache/syncope/core/persistence/neo4j/dao/Neo4jTaskDAO.java
+++
b/core/persistence-neo4j/src/main/java/org/apache/syncope/core/persistence/neo4j/dao/Neo4jTaskDAO.java
@@ -291,7 +291,7 @@ public class Neo4jTaskDAO extends AbstractDAO implements
TaskDAO {
query.append("(n)-[:").append(execRelationship(type)).append("]-()
");
}
- query.append("RETURN n.id
").append(toOrderByStatement(pageable.getSort().get()));
+ query.append("RETURN n.id
").append(toOrderByStatement(pageable.getSort().stream()));
if (pageable.isPaged()) {
query.append(" SKIP ").append(pageable.getPageSize() *
pageable.getPageNumber()).
@@ -463,7 +463,7 @@ public class Neo4jTaskDAO extends AbstractDAO implements
TaskDAO {
query.append(" WITH n ");
- query.append(toOrderByStatement(pageable.getSort().get()));
+ query.append(toOrderByStatement(pageable.getSort().stream()));
if (pageable.isPaged()) {
query.append(" SKIP ").append(pageable.getPageSize() *
pageable.getPageNumber()).