This is an automated email from the ASF dual-hosted git repository.

andreapatricelli 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 1453817fa8 [SYNCOPE-1922] raise error while searching by encrypted 
plain schema, removed suggestion of such schemas on search in console (#1219)
1453817fa8 is described below

commit 1453817fa8f1d314a4bca5a8d83d2eb11cf70c1e
Author: Andrea Patricelli <[email protected]>
AuthorDate: Wed Oct 29 14:11:46 2025 +0100

    [SYNCOPE-1922] raise error while searching by encrypted plain schema, 
removed suggestion of such schemas on search in console (#1219)
---
 .../panels/search/AnyObjectSearchPanel.java        |  4 ++-
 .../common/dao/AbstractAnySearchDAO.java           |  5 +++
 .../core/persistence/jpa/inner/AnySearchTest.java  | 19 +++++++++++
 .../persistence/neo4j/inner/AnySearchTest.java     | 38 ++++++++++++++++++++++
 .../org/apache/syncope/fit/core/SearchITCase.java  | 19 +++++++++++
 5 files changed, 84 insertions(+), 1 deletion(-)

diff --git 
a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/panels/search/AnyObjectSearchPanel.java
 
b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/panels/search/AnyObjectSearchPanel.java
index 4045b8f03a..3479bd64f7 100644
--- 
a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/panels/search/AnyObjectSearchPanel.java
+++ 
b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/panels/search/AnyObjectSearchPanel.java
@@ -33,6 +33,7 @@ import org.apache.syncope.common.lib.to.GroupTO;
 import org.apache.syncope.common.lib.to.PlainSchemaTO;
 import org.apache.syncope.common.lib.to.SchemaTO;
 import org.apache.syncope.common.lib.types.AnyTypeKind;
+import org.apache.syncope.common.lib.types.AttrSchemaType;
 import org.apache.syncope.common.lib.types.SchemaType;
 import org.apache.wicket.PageReference;
 import org.apache.wicket.extensions.markup.html.repeater.util.SortParam;
@@ -123,7 +124,8 @@ public class AnyObjectSearchPanel extends 
AbstractSearchPanel {
             protected Map<String, PlainSchemaTO> load() {
                 return schemaRestClient.<PlainSchemaTO>getSchemas(
                         SchemaType.PLAIN, null, 
anyTypeRestClient.read(anyType).getClasses().toArray(String[]::new)).
-                        stream().collect(Collectors.toMap(SchemaTO::getKey, 
Function.identity()));
+                        stream().filter(schema -> AttrSchemaType.Encrypted != 
schema.getType()).
+                        collect(Collectors.toMap(SchemaTO::getKey, 
Function.identity()));
             }
         };
     }
diff --git 
a/core/persistence-common/src/main/java/org/apache/syncope/core/persistence/common/dao/AbstractAnySearchDAO.java
 
b/core/persistence-common/src/main/java/org/apache/syncope/core/persistence/common/dao/AbstractAnySearchDAO.java
index 8459e7977e..079d8cf8af 100644
--- 
a/core/persistence-common/src/main/java/org/apache/syncope/core/persistence/common/dao/AbstractAnySearchDAO.java
+++ 
b/core/persistence-common/src/main/java/org/apache/syncope/core/persistence/common/dao/AbstractAnySearchDAO.java
@@ -242,6 +242,11 @@ public abstract class AbstractAnySearchDAO implements 
AnySearchDAO {
                 orElseThrow(() -> new IllegalArgumentException("Invalid schema 
" + cond.getSchema()));
 
         PlainAttrValue attrValue = new PlainAttrValue();
+        
+        if (AttrSchemaType.Encrypted == schema.getType()) {
+            throw new IllegalArgumentException("Cannot search by encrypted 
schema " + cond.getSchema());
+        }
+        
         try {
             if (cond.getType() != AttrCond.Type.LIKE
                     && cond.getType() != AttrCond.Type.ILIKE
diff --git 
a/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/inner/AnySearchTest.java
 
b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/inner/AnySearchTest.java
index b27d83fec6..1a1f45812c 100644
--- 
a/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/inner/AnySearchTest.java
+++ 
b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/inner/AnySearchTest.java
@@ -21,6 +21,7 @@ package org.apache.syncope.core.persistence.jpa.inner;
 import static org.junit.jupiter.api.Assertions.assertEquals;
 import static org.junit.jupiter.api.Assertions.assertFalse;
 import static org.junit.jupiter.api.Assertions.assertNotNull;
+import static org.junit.jupiter.api.Assertions.assertThrows;
 import static org.junit.jupiter.api.Assertions.assertTrue;
 
 import java.text.ParseException;
@@ -1027,6 +1028,24 @@ public class AnySearchTest extends AbstractTest {
         assertEquals("bellini", users.get(0).getUsername());
     }
 
+    @Test
+    public void issueSYNCOPE1922() {
+        User bellini = userDAO.findByUsername("bellini").orElseThrow();
+
+        PlainSchema obscureSchema = 
plainSchemaDAO.findById("obscure").orElseThrow();
+
+        userDAO.save(addPlainAttr(bellini, obscureSchema, "myobscurevalue"));
+
+        entityManager.flush();
+
+        AttrCond obscureCond = new AttrCond(AttrCond.Type.EQ);
+        obscureCond.setSchema("obscure");
+        obscureCond.setExpression("myobscurevalue");
+
+        assertThrows(IllegalArgumentException.class,
+                () -> searchDAO.search(SearchCond.of(obscureCond), 
AnyTypeKind.USER));
+    }
+
     private User addPlainAttr(final User user, final PlainSchema plainSchema, 
final String value) {
         user.getPlainAttr(plainSchema.getKey())
                 .ifPresentOrElse(ctype -> 
ctype.getValues().get(0).setStringValue(value), () -> {
diff --git 
a/core/persistence-neo4j/src/test/java/org/apache/syncope/core/persistence/neo4j/inner/AnySearchTest.java
 
b/core/persistence-neo4j/src/test/java/org/apache/syncope/core/persistence/neo4j/inner/AnySearchTest.java
index 007536901e..5f8060b022 100644
--- 
a/core/persistence-neo4j/src/test/java/org/apache/syncope/core/persistence/neo4j/inner/AnySearchTest.java
+++ 
b/core/persistence-neo4j/src/test/java/org/apache/syncope/core/persistence/neo4j/inner/AnySearchTest.java
@@ -21,6 +21,7 @@ package org.apache.syncope.core.persistence.neo4j.inner;
 import static org.junit.jupiter.api.Assertions.assertEquals;
 import static org.junit.jupiter.api.Assertions.assertFalse;
 import static org.junit.jupiter.api.Assertions.assertNotNull;
+import static org.junit.jupiter.api.Assertions.assertThrows;
 import static org.junit.jupiter.api.Assertions.assertTrue;
 
 import java.text.ParseException;
@@ -36,10 +37,12 @@ import java.util.stream.Stream;
 import org.apache.syncope.common.lib.SyncopeConstants;
 import org.apache.syncope.common.lib.types.AnyTypeKind;
 import org.apache.syncope.common.lib.types.IdRepoEntitlement;
+import 
org.apache.syncope.core.persistence.api.attrvalue.PlainAttrValidationManager;
 import org.apache.syncope.core.persistence.api.dao.AnyObjectDAO;
 import org.apache.syncope.core.persistence.api.dao.AnySearchDAO;
 import org.apache.syncope.core.persistence.api.dao.AnyTypeDAO;
 import org.apache.syncope.core.persistence.api.dao.GroupDAO;
+import org.apache.syncope.core.persistence.api.dao.PlainSchemaDAO;
 import org.apache.syncope.core.persistence.api.dao.RealmDAO;
 import org.apache.syncope.core.persistence.api.dao.RealmSearchDAO;
 import org.apache.syncope.core.persistence.api.dao.RoleDAO;
@@ -56,6 +59,7 @@ import 
org.apache.syncope.core.persistence.api.dao.search.RoleCond;
 import org.apache.syncope.core.persistence.api.dao.search.SearchCond;
 import org.apache.syncope.core.persistence.api.entity.AnyType;
 import org.apache.syncope.core.persistence.api.entity.PlainAttr;
+import org.apache.syncope.core.persistence.api.entity.PlainSchema;
 import org.apache.syncope.core.persistence.api.entity.anyobject.AMembership;
 import org.apache.syncope.core.persistence.api.entity.anyobject.AnyObject;
 import org.apache.syncope.core.persistence.api.entity.group.Group;
@@ -105,6 +109,12 @@ public class AnySearchTest extends AbstractTest {
     @Autowired
     private RoleDAO roleDAO;
 
+    @Autowired
+    private PlainSchemaDAO plainSchemaDAO;
+
+    @Autowired
+    private PlainAttrValidationManager validator;
+
     @BeforeEach
     public void adjustLoginDateForLocalSystem() throws ParseException {
         User rossini = userDAO.findByUsername("rossini").orElseThrow();
@@ -974,4 +984,32 @@ public class AnySearchTest extends AbstractTest {
         assertNotNull(users);
         assertEquals(4, users.size());
     }
+
+    @Test
+    public void issueSYNCOPE1922() {
+        User bellini = userDAO.findByUsername("bellini").orElseThrow();
+
+        PlainSchema obscureSchema = 
plainSchemaDAO.findById("obscure").orElseThrow();
+
+        userDAO.save(addPlainAttr(bellini, obscureSchema, "myobscurevalue"));
+
+        AttrCond obscureCond = new AttrCond(AttrCond.Type.EQ);
+        obscureCond.setSchema("obscure");
+        obscureCond.setExpression("myobscurevalue");
+
+        assertThrows(IllegalArgumentException.class,
+                () -> searchDAO.search(SearchCond.of(obscureCond), 
AnyTypeKind.USER));
+    }
+
+    protected User addPlainAttr(final User user, final PlainSchema 
plainSchema, final String value) {
+        user.getPlainAttr(plainSchema.getKey())
+                .ifPresentOrElse(ctype -> 
ctype.getValues().get(0).setStringValue(value), () -> {
+                    PlainAttr attr = new PlainAttr();
+                    attr.setPlainSchema(plainSchema);
+                    attr.add(validator, value);
+
+                    user.add(attr);
+                });
+        return user;
+    }
 }
diff --git 
a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/SearchITCase.java
 
b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/SearchITCase.java
index d24ff178dc..7b4a0891bd 100644
--- 
a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/SearchITCase.java
+++ 
b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/SearchITCase.java
@@ -1163,4 +1163,23 @@ public class SearchITCase extends AbstractITCase {
             deleteUser("user test 182");
         }
     }
+
+    @Test
+    public void issueSYNCOPE1922() {
+        // 1. set encrypted value
+        updateUser(new 
UserUR.Builder(USER_SERVICE.read("bellini").getKey()).plainAttr(
+                attrAddReplacePatch("obscure", "myobscurevalue")).build());
+        // 2. search by encrypted value
+        try {
+            USER_SERVICE.search(new 
AnyQuery.Builder().fiql(SyncopeClient.getUserSearchConditionBuilder()
+                    
.and(List.of(SyncopeClient.getUserSearchConditionBuilder().is("obscure").equalTo("myobscurevalue"),
+                            
SyncopeClient.getUserSearchConditionBuilder().is("surname").equalTo("bellini")))
+                    .query()).page(1).size(1).build());
+            fail("Search should have been blocked, since on encrypted schema");
+        } catch (SyncopeClientException sce) {
+            assertEquals(ClientExceptionType.InvalidSearchParameters, 
sce.getType());
+            assertTrue(
+                    sce.getMessage().contains("IllegalArgumentException: 
Cannot search by encrypted schema obscure"));
+        }
+    }
 }

Reply via email to