You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@syncope.apache.org by il...@apache.org on 2019/11/23 14:57:43 UTC

[syncope] branch 2_1_X updated: [SYNCOPE-1512] Escaping single quote when using JSON operators

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

ilgrosso pushed a commit to branch 2_1_X
in repository https://gitbox.apache.org/repos/asf/syncope.git


The following commit(s) were added to refs/heads/2_1_X by this push:
     new 7d5505e  [SYNCOPE-1512] Escaping single quote when using JSON operators
7d5505e is described below

commit 7d5505e2ce8cd49c9dc80a652974d41d7f39cd65
Author: Francesco Chicchiriccò <il...@apache.org>
AuthorDate: Sat Nov 23 15:27:38 2019 +0100

    [SYNCOPE-1512] Escaping single quote when using JSON operators
---
 .../core/persistence/jpa/dao/MyJPAJSONAnyDAO.java  |  4 +-
 .../persistence/jpa/dao/MyJPAJSONAnySearchDAO.java |  2 +-
 .../core/persistence/jpa/dao/PGJPAJSONAnyDAO.java  |  2 +-
 .../persistence/jpa/dao/PGJPAJSONAnySearchDAO.java |  2 +-
 .../src/test/resources/domains/MasterContent.xml   |  3 ++
 .../persistence/jpa/inner/PlainSchemaTest.java     |  2 +-
 .../core/persistence/jpa/outer/AnySearchTest.java  | 50 ++++++++++++++++++++--
 .../core/persistence/jpa/outer/GroupTest.java      | 28 ++++++++++++
 .../src/test/resources/domains/MasterContent.xml   |  3 ++
 9 files changed, 88 insertions(+), 8 deletions(-)

diff --git a/core/persistence-jpa-json/src/main/java/org/apache/syncope/core/persistence/jpa/dao/MyJPAJSONAnyDAO.java b/core/persistence-jpa-json/src/main/java/org/apache/syncope/core/persistence/jpa/dao/MyJPAJSONAnyDAO.java
index 0fa4608..9e22865 100644
--- a/core/persistence-jpa-json/src/main/java/org/apache/syncope/core/persistence/jpa/dao/MyJPAJSONAnyDAO.java
+++ b/core/persistence-jpa-json/src/main/java/org/apache/syncope/core/persistence/jpa/dao/MyJPAJSONAnyDAO.java
@@ -70,7 +70,9 @@ public class MyJPAJSONAnyDAO extends AbstractJPAJSONAnyDAO {
             } else {
                 ((JSONPlainAttr) container).add(attrValue);
             }
-            return "JSON_CONTAINS(plainAttrs, '" + POJOHelper.serialize(Arrays.asList(container)) + "')";
+            return "JSON_CONTAINS(plainAttrs, '"
+                    + POJOHelper.serialize(Arrays.asList(container)).replace("'", "''")
+                    + "')";
         }
     }
 }
diff --git a/core/persistence-jpa-json/src/main/java/org/apache/syncope/core/persistence/jpa/dao/MyJPAJSONAnySearchDAO.java b/core/persistence-jpa-json/src/main/java/org/apache/syncope/core/persistence/jpa/dao/MyJPAJSONAnySearchDAO.java
index 8ccba90..3a2b7d7 100644
--- a/core/persistence-jpa-json/src/main/java/org/apache/syncope/core/persistence/jpa/dao/MyJPAJSONAnySearchDAO.java
+++ b/core/persistence-jpa-json/src/main/java/org/apache/syncope/core/persistence/jpa/dao/MyJPAJSONAnySearchDAO.java
@@ -169,7 +169,7 @@ public class MyJPAJSONAnySearchDAO extends AbstractJPAJSONAnySearchDAO {
                 }
 
                 query.append("JSON_CONTAINS(plainAttrs, '").
-                        append(POJOHelper.serialize(Arrays.asList(container))).
+                        append(POJOHelper.serialize(Arrays.asList(container)).replace("'", "''")).
                         append("')");
             } else {
                 String key = key(schema.getType());
diff --git a/core/persistence-jpa-json/src/main/java/org/apache/syncope/core/persistence/jpa/dao/PGJPAJSONAnyDAO.java b/core/persistence-jpa-json/src/main/java/org/apache/syncope/core/persistence/jpa/dao/PGJPAJSONAnyDAO.java
index 43b389a..4889146 100644
--- a/core/persistence-jpa-json/src/main/java/org/apache/syncope/core/persistence/jpa/dao/PGJPAJSONAnyDAO.java
+++ b/core/persistence-jpa-json/src/main/java/org/apache/syncope/core/persistence/jpa/dao/PGJPAJSONAnyDAO.java
@@ -64,7 +64,7 @@ public class PGJPAJSONAnyDAO extends AbstractJPAJSONAnyDAO {
             } else {
                 ((JSONPlainAttr) container).add(attrValue);
             }
-            return "plainAttrs @> '" + POJOHelper.serialize(Arrays.asList(container)) + "'::jsonb";
+            return "plainAttrs @> '" + POJOHelper.serialize(Arrays.asList(container)).replace("'", "''") + "'::jsonb";
         }
     }
 }
diff --git a/core/persistence-jpa-json/src/main/java/org/apache/syncope/core/persistence/jpa/dao/PGJPAJSONAnySearchDAO.java b/core/persistence-jpa-json/src/main/java/org/apache/syncope/core/persistence/jpa/dao/PGJPAJSONAnySearchDAO.java
index bb774ec..19f5d6e 100644
--- a/core/persistence-jpa-json/src/main/java/org/apache/syncope/core/persistence/jpa/dao/PGJPAJSONAnySearchDAO.java
+++ b/core/persistence-jpa-json/src/main/java/org/apache/syncope/core/persistence/jpa/dao/PGJPAJSONAnySearchDAO.java
@@ -138,7 +138,7 @@ public class PGJPAJSONAnySearchDAO extends AbstractJPAJSONAnySearchDAO {
                 }
 
                 query.append("plainAttrs @> '").
-                        append(POJOHelper.serialize(Arrays.asList(container))).
+                        append(POJOHelper.serialize(Arrays.asList(container)).replace("'", "''")).
                         append("'::jsonb");
             } else {
                 String key = key(schema.getType());
diff --git a/core/persistence-jpa-json/src/test/resources/domains/MasterContent.xml b/core/persistence-jpa-json/src/test/resources/domains/MasterContent.xml
index 377841b..1515899 100644
--- a/core/persistence-jpa-json/src/test/resources/domains/MasterContent.xml
+++ b/core/persistence-jpa-json/src/test/resources/domains/MasterContent.xml
@@ -221,6 +221,9 @@ under the License.
   <SyncopeSchema id="title"/>
   <PlainSchema id="title" type="String" anyTypeClass_id="minimal group"
                mandatoryCondition="false" multivalue="1" uniqueConstraint="0" readonly="0"/>
+  <SyncopeSchema id="originalName"/>
+  <PlainSchema id="originalName" type="String" anyTypeClass_id="minimal group"
+               mandatoryCondition="false" multivalue="0" uniqueConstraint="1" readonly="0"/>
 
   <SyncopeSchema id="rderiveddata"/>
   <DerSchema id="rderiveddata" expression="rderived_sx + '-' + rderived_dx"
diff --git a/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/inner/PlainSchemaTest.java b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/inner/PlainSchemaTest.java
index d499652..af2f90f 100644
--- a/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/inner/PlainSchemaTest.java
+++ b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/inner/PlainSchemaTest.java
@@ -54,7 +54,7 @@ public class PlainSchemaTest extends AbstractTest {
     @Test
     public void findAll() {
         List<PlainSchema> schemas = plainSchemaDAO.findAll();
-        assertEquals(41, schemas.size());
+        assertEquals(42, schemas.size());
     }
 
     @Test
diff --git a/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/outer/AnySearchTest.java b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/outer/AnySearchTest.java
index 6d91b57..e68b5ef 100644
--- a/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/outer/AnySearchTest.java
+++ b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/outer/AnySearchTest.java
@@ -33,6 +33,7 @@ import org.apache.syncope.core.persistence.api.dao.GroupDAO;
 import org.apache.syncope.core.persistence.api.dao.RealmDAO;
 import org.apache.syncope.core.persistence.api.dao.RoleDAO;
 import org.apache.syncope.core.persistence.api.dao.AnySearchDAO;
+import org.apache.syncope.core.persistence.api.dao.PlainSchemaDAO;
 import org.apache.syncope.core.persistence.api.dao.search.AnyCond;
 import org.apache.syncope.core.persistence.api.dao.search.AttributeCond;
 import org.apache.syncope.core.persistence.api.dao.search.OrderByClause;
@@ -40,6 +41,8 @@ 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.user.DynRoleMembership;
 import org.apache.syncope.core.persistence.api.entity.Role;
+import org.apache.syncope.core.persistence.api.entity.group.GPlainAttr;
+import org.apache.syncope.core.persistence.api.entity.group.Group;
 import org.apache.syncope.core.persistence.api.entity.user.User;
 import org.apache.syncope.core.persistence.jpa.AbstractTest;
 import org.junit.jupiter.api.Test;
@@ -61,6 +64,9 @@ public class AnySearchTest extends AbstractTest {
     @Autowired
     private RoleDAO roleDAO;
 
+    @Autowired
+    private PlainSchemaDAO plainSchemaDAO;
+
     @Test
     public void searchByDynMembership() {
         // 1. create role with dynamic membership
@@ -94,9 +100,7 @@ public class AnySearchTest extends AbstractTest {
 
     @Test
     public void issueSYNCOPE95() {
-        groupDAO.findAll(1, 100).forEach(group -> {
-            groupDAO.delete(group.getKey());
-        });
+        groupDAO.findAll(1, 100).forEach(group -> groupDAO.delete(group.getKey()));
         entityManager().flush();
 
         AttributeCond coolLeafCond = new AttributeCond(AttributeCond.Type.EQ);
@@ -141,4 +145,44 @@ public class AnySearchTest extends AbstractTest {
             assertEquals(ClientExceptionType.InvalidSearchExpression, e.getType());
         }
     }
+
+    @Test
+    public void issueSYNCOPE1512() {
+        Group group = groupDAO.findByName("root");
+        assertNotNull(group);
+
+        // non unique
+        GPlainAttr title = entityFactory.newEntity(GPlainAttr.class);
+        title.setOwner(group);
+        title.setSchema(plainSchemaDAO.find("title"));
+        title.add("syncope's group", anyUtilsFactory.getInstance(AnyTypeKind.GROUP));
+        group.add(title);
+
+        // unique
+        GPlainAttr originalName = entityFactory.newEntity(GPlainAttr.class);
+        originalName.setOwner(group);
+        originalName.setSchema(plainSchemaDAO.find("originalName"));
+        originalName.add("syncope's group", anyUtilsFactory.getInstance(AnyTypeKind.GROUP));
+        group.add(originalName);
+
+        groupDAO.save(group);
+
+        entityManager().flush();
+
+        AttributeCond titleCond = new AttributeCond(AttributeCond.Type.EQ);
+        titleCond.setSchema("title");
+        titleCond.setExpression("syncope's group");
+
+        List<Group> matching = searchDAO.search(SearchCond.getLeafCond(titleCond), AnyTypeKind.GROUP);
+        assertEquals(1, matching.size());
+        assertEquals(group.getKey(), matching.get(0).getKey());
+
+        AttributeCond originalNameCond = new AttributeCond(AttributeCond.Type.EQ);
+        originalNameCond.setSchema("originalName");
+        originalNameCond.setExpression("syncope's group");
+
+        matching = searchDAO.search(SearchCond.getLeafCond(originalNameCond), AnyTypeKind.GROUP);
+        assertEquals(1, matching.size());
+        assertEquals(group.getKey(), matching.get(0).getKey());
+    }
 }
diff --git a/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/outer/GroupTest.java b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/outer/GroupTest.java
index c25aead..bd4bdd6 100644
--- a/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/outer/GroupTest.java
+++ b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/outer/GroupTest.java
@@ -371,4 +371,32 @@ public class GroupTest extends AbstractTest {
         dynGroupMemberships = findDynGroups(anyObject);
         assertTrue(dynGroupMemberships.isEmpty());
     }
+
+    @Test
+    public void issueSYNCOPE1512() {
+        Group group = groupDAO.findByName("root");
+        assertNotNull(group);
+
+        // non unique
+        GPlainAttr title = entityFactory.newEntity(GPlainAttr.class);
+        title.setOwner(group);
+        title.setSchema(plainSchemaDAO.find("title"));
+        title.add("syncope's group", anyUtilsFactory.getInstance(AnyTypeKind.GROUP));
+        group.add(title);
+
+        // unique
+        GPlainAttr originalName = entityFactory.newEntity(GPlainAttr.class);
+        originalName.setOwner(group);
+        originalName.setSchema(plainSchemaDAO.find("originalName"));
+        originalName.add("syncope's group", anyUtilsFactory.getInstance(AnyTypeKind.GROUP));
+        group.add(originalName);
+
+        groupDAO.save(group);
+
+        entityManager().flush();
+
+        group = groupDAO.find(group.getKey());
+        assertEquals("syncope's group", group.getPlainAttr("title").get().getValuesAsStrings().get(0));
+        assertEquals("syncope's group", group.getPlainAttr("originalName").get().getValuesAsStrings().get(0));
+    }
 }
diff --git a/core/persistence-jpa/src/test/resources/domains/MasterContent.xml b/core/persistence-jpa/src/test/resources/domains/MasterContent.xml
index 4e50b33..05326aa 100644
--- a/core/persistence-jpa/src/test/resources/domains/MasterContent.xml
+++ b/core/persistence-jpa/src/test/resources/domains/MasterContent.xml
@@ -491,6 +491,9 @@ under the License.
   <SyncopeSchema id="title"/>
   <PlainSchema id="title" type="String" anyTypeClass_id="minimal group"
                mandatoryCondition="false" multivalue="1" uniqueConstraint="0" readonly="0"/>
+  <SyncopeSchema id="originalName"/>
+  <PlainSchema id="originalName" type="String" anyTypeClass_id="minimal group"
+               mandatoryCondition="false" multivalue="0" uniqueConstraint="1" readonly="0"/>
 
   <SyncopeSchema id="rderiveddata"/>
   <DerSchema id="rderiveddata" expression="rderived_sx + '-' + rderived_dx"