From fe060d9f934d9a841cbda5366b47280ee066211b Mon Sep 17 00:00:00 2001 From: alberto bogi Date: Fri, 9 Oct 2026 17:29:58 +0200 Subject: [PATCH 1/2] [SYNCOPE-2000] Add AnyAbout filtering by Realm, uManager, and gManager --- .../common/dao/AbstractAnyMatchDAO.java | 29 +++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/core/persistence-common/src/main/java/org/apache/syncope/core/persistence/common/dao/AbstractAnyMatchDAO.java b/core/persistence-common/src/main/java/org/apache/syncope/core/persistence/common/dao/AbstractAnyMatchDAO.java index 7b19f5e6c4d..07139f255a9 100644 --- a/core/persistence-common/src/main/java/org/apache/syncope/core/persistence/common/dao/AbstractAnyMatchDAO.java +++ b/core/persistence-common/src/main/java/org/apache/syncope/core/persistence/common/dao/AbstractAnyMatchDAO.java @@ -23,6 +23,8 @@ import jakarta.validation.constraints.Min; import java.beans.PropertyDescriptor; import java.lang.annotation.Annotation; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; import java.time.OffsetDateTime; import java.util.ArrayList; import java.util.List; @@ -31,6 +33,7 @@ import java.util.regex.Pattern; import java.util.stream.Collectors; import org.apache.commons.lang3.BooleanUtils; +import org.apache.commons.lang3.ClassUtils; import org.apache.syncope.common.lib.SyncopeConstants; import org.apache.syncope.common.lib.types.AnyTypeKind; import org.apache.syncope.common.lib.types.AttrSchemaType; @@ -59,6 +62,7 @@ import org.apache.syncope.core.persistence.api.entity.PlainAttr; import org.apache.syncope.core.persistence.api.entity.PlainAttrValue; import org.apache.syncope.core.persistence.api.entity.PlainSchema; +import org.apache.syncope.core.persistence.api.entity.Realm; import org.apache.syncope.core.persistence.api.entity.Relatable; import org.apache.syncope.core.persistence.api.entity.anyobject.AnyObject; import org.apache.syncope.core.persistence.api.entity.group.Group; @@ -439,6 +443,31 @@ protected boolean matches(final Any any, final AnyCond cond, final boolean not) // Deal with any fields representing relationships to other entities relationshipFieldMatches(pd, cond, schema); + if (!(anyAttrValue instanceof String)) { + + try { + Method relMethod = null; + if (!SyncopeConstants.UUID_PATTERN.matcher(cond.getExpression()).matches()) { + Class type = pd.getPropertyType(); + + if (type == Realm.class) { + relMethod = ClassUtils.getPublicMethod(pd.getPropertyType(), "getFullPath"); + } else if (type == User.class) { + relMethod = ClassUtils.getPublicMethod(pd.getPropertyType(), "getUsername"); + } else if (type == Group.class) { + relMethod = ClassUtils.getPublicMethod(pd.getPropertyType(), "getName"); + } + } else { + relMethod = ClassUtils.getPublicMethod(pd.getPropertyType(), "getKey", new Class[0]); + } + + if (relMethod != null && String.class.isAssignableFrom(relMethod.getReturnType())) { + anyAttrValue = relMethod.invoke(anyAttrValue); + } + } catch (NoSuchMethodException | InvocationTargetException | IllegalAccessException e) { + throw new RuntimeException(e); + } + } PlainAttrValue attrValue = new PlainAttrValue(); if (cond.getType() != AttrCond.Type.LIKE From 28bdde0c0f2934d27aa9eb5cf086230c0d916ef6 Mon Sep 17 00:00:00 2001 From: alberto bogi Date: Mon, 12 Oct 2026 09:20:33 +0200 Subject: [PATCH 2/2] [SYNCOPE-2000] PR review comments --- .../persistence/common/dao/AbstractAnyMatchDAO.java | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/core/persistence-common/src/main/java/org/apache/syncope/core/persistence/common/dao/AbstractAnyMatchDAO.java b/core/persistence-common/src/main/java/org/apache/syncope/core/persistence/common/dao/AbstractAnyMatchDAO.java index 07139f255a9..aaa235f3714 100644 --- a/core/persistence-common/src/main/java/org/apache/syncope/core/persistence/common/dao/AbstractAnyMatchDAO.java +++ b/core/persistence-common/src/main/java/org/apache/syncope/core/persistence/common/dao/AbstractAnyMatchDAO.java @@ -450,22 +450,23 @@ protected boolean matches(final Any any, final AnyCond cond, final boolean not) if (!SyncopeConstants.UUID_PATTERN.matcher(cond.getExpression()).matches()) { Class type = pd.getPropertyType(); - if (type == Realm.class) { + if (Realm.class.isAssignableFrom(type)) { relMethod = ClassUtils.getPublicMethod(pd.getPropertyType(), "getFullPath"); - } else if (type == User.class) { + } else if (User.class.isAssignableFrom(type)) { relMethod = ClassUtils.getPublicMethod(pd.getPropertyType(), "getUsername"); - } else if (type == Group.class) { + } else if (Group.class.isAssignableFrom(type)) { relMethod = ClassUtils.getPublicMethod(pd.getPropertyType(), "getName"); } } else { - relMethod = ClassUtils.getPublicMethod(pd.getPropertyType(), "getKey", new Class[0]); + relMethod = ClassUtils.getPublicMethod(pd.getPropertyType(), "getKey"); } if (relMethod != null && String.class.isAssignableFrom(relMethod.getReturnType())) { anyAttrValue = relMethod.invoke(anyAttrValue); } } catch (NoSuchMethodException | InvocationTargetException | IllegalAccessException e) { - throw new RuntimeException(e); + LOG.error("Could not find getter method for relationshipField of type [{}]", + pd.getPropertyType().getSimpleName(), e); } }