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:37 UTC

[syncope] branch master 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 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 dea9c22  [SYNCOPE-1512] Escaping single quote when using JSON operators
dea9c22 is described below

commit dea9c22f4c88a7d8cc1f1abf87be40dd0383b647
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  |  2 +-
 .../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  | 46 ++++++++++++++++++++++
 .../core/persistence/jpa/outer/GroupTest.java      | 28 +++++++++++++
 .../src/test/resources/domains/MasterContent.xml   |  3 ++
 9 files changed, 85 insertions(+), 5 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 a5c2d93..6e1486b 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,7 @@ public class MyJPAJSONAnyDAO extends AbstractJPAJSONAnyDAO {
             } else {
                 ((JSONPlainAttr) container).add(attrValue);
             }
-            return "JSON_CONTAINS(plainAttrs, '" + POJOHelper.serialize(List.of(container)) + "')";
+            return "JSON_CONTAINS(plainAttrs, '" + POJOHelper.serialize(List.of(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 404b292..b8d6a98 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
@@ -168,7 +168,7 @@ public class MyJPAJSONAnySearchDAO extends AbstractJPAJSONAnySearchDAO {
                 }
 
                 query.append("JSON_CONTAINS(plainAttrs, '").
-                        append(POJOHelper.serialize(List.of(container))).
+                        append(POJOHelper.serialize(List.of(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 a9673c0..a844be6 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(List.of(container)) + "'::jsonb";
+            return "plainAttrs @> '" + POJOHelper.serialize(List.of(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 cbcf252..b6d5b26 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
@@ -137,7 +137,7 @@ public class PGJPAJSONAnySearchDAO extends AbstractJPAJSONAnySearchDAO {
                 }
 
                 query.append("plainAttrs @> '").
-                        append(POJOHelper.serialize(List.of(container))).
+                        append(POJOHelper.serialize(List.of(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 5c321dc..cf38a3d 100644
--- a/core/persistence-jpa-json/src/test/resources/domains/MasterContent.xml
+++ b/core/persistence-jpa-json/src/test/resources/domains/MasterContent.xml
@@ -152,6 +152,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 9bf8c74..9059e59 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(26, schemas.size());
+        assertEquals(27, 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 5fe5092..a659697 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
@@ -139,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 9f38789..c857676 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 9043a95..e9ba453 100644
--- a/core/persistence-jpa/src/test/resources/domains/MasterContent.xml
+++ b/core/persistence-jpa/src/test/resources/domains/MasterContent.xml
@@ -357,6 +357,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"