Author: angela
Date: Fri Nov 13 13:58:36 2015
New Revision: 1714207

URL: http://svn.apache.org/viewvc?rev=1714207&view=rev
Log:
OAK-3624 : TypeEditor doesn't validate the required property type

Modified:
    
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/nodetype/TypeEditor.java
    
jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/nodetype/TypeEditorTest.java

Modified: 
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/nodetype/TypeEditor.java
URL: 
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/nodetype/TypeEditor.java?rev=1714207&r1=1714206&r2=1714207&view=diff
==============================================================================
--- 
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/nodetype/TypeEditor.java
 (original)
+++ 
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/nodetype/TypeEditor.java
 Fri Nov 13 13:58:36 2015
@@ -185,7 +185,11 @@ class TypeEditor extends DefaultEditor {
                     constraintViolation(12, "Invalid UUID value in the 
jcr:uuid property");
                 }
             } else {
-                checkValueConstraints(definition, after);
+                int requiredType = getRequiredType(definition);
+                if (requiredType != PropertyType.UNDEFINED) {
+                    checkRequiredType(after, requiredType);
+                    checkValueConstraints(definition, after, requiredType);
+                }
             }
         }
     }
@@ -315,56 +319,58 @@ class TypeEditor extends DefaultEditor {
         return effective;
     }
 
-    private void checkValueConstraints(
-            NodeState definition, PropertyState property)
-            throws CommitFailedException {
-        if (property.count() == 0) {
-            return;
-        }
-
-        PropertyState constraints =
-                definition.getProperty(JCR_VALUECONSTRAINTS);
-        if (constraints == null || constraints.count() == 0) {
-            return;
+    private static int getRequiredType(NodeState definition) {
+        int type = PropertyType.UNDEFINED;
+        PropertyState required = definition.getProperty(JCR_REQUIREDTYPE);
+        if (required != null) {
+            String value = required.getValue(STRING);
+            if ("BINARY".equals(value)) {
+                type = PropertyType.BINARY;
+            } else if ("BOOLEAN".equals(value)) {
+                type = PropertyType.BOOLEAN;
+            } else if ("DATE".equals(value)) {
+                type = PropertyType.DATE;
+            } else if ("DECIMAL".equals(value)) {
+                type = PropertyType.DECIMAL;
+            } else if ("DOUBLE".equals(value)) {
+                type = PropertyType.DOUBLE;
+            } else if ("LONG".equals(value)) {
+                type = PropertyType.LONG;
+            } else if ("NAME".equals(value)) {
+                type = PropertyType.NAME;
+            } else if ("PATH".equals(value)) {
+                type = PropertyType.PATH;
+            } else if ("REFERENCE".equals(value)) {
+                type = PropertyType.REFERENCE;
+            } else if ("STRING".equals(value)) {
+                type = PropertyType.STRING;
+            } else if ("URI".equals(value)) {
+                type = PropertyType.URI;
+            } else if ("WEAKREFERENCE".equals(value)) {
+                type = PropertyType.WEAKREFERENCE;
+            }
+        }
+        return type;
+    }
+
+    private void checkRequiredType(PropertyState property, int requiredType) 
throws CommitFailedException {
+        if (requiredType != property.getType().tag()) {
+            constraintViolation(55, "Required property type violation in " + 
property);
         }
+    }
 
-        PropertyState required = definition.getProperty(JCR_REQUIREDTYPE);
-        if (required == null) {
+    private void checkValueConstraints(NodeState definition, PropertyState 
property, int requiredType) throws CommitFailedException {
+        if (property.count() == 0) {
             return;
         }
 
-        int type;
-        String value = required.getValue(STRING);
-        if ("BINARY".equals(value)) {
-            type = PropertyType.BINARY;
-        } else if ("BOOLEAN".equals(value)) {
-            type = PropertyType.BOOLEAN;
-        } else if ("DATE".equals(value)) {
-            type = PropertyType.DATE;
-        } else if ("DECIMAL".equals(value)) {
-            type = PropertyType.DECIMAL;
-        } else if ("DOUBLE".equals(value)) {
-            type = PropertyType.DOUBLE;
-        } else if ("LONG".equals(value)) {
-            type = PropertyType.LONG;
-        } else if ("NAME".equals(value)) {
-            type = PropertyType.NAME;
-        } else if ("PATH".equals(value)) {
-            type = PropertyType.PATH;
-        } else if ("REFERENCE".equals(value)) {
-            type = PropertyType.REFERENCE;
-        } else if ("STRING".equals(value)) {
-            type = PropertyType.STRING;
-        } else if ("URI".equals(value)) {
-            type = PropertyType.URI;
-        } else if ("WEAKREFERENCE".equals(value)) {
-            type = PropertyType.WEAKREFERENCE;
-        } else {
+        PropertyState constraints = 
definition.getProperty(JCR_VALUECONSTRAINTS);
+        if (constraints == null || constraints.count() == 0) {
             return;
         }
 
         for (String constraint : constraints.getValue(STRINGS)) {
-            Predicate<Value> predicate = valueConstraint(type, constraint);
+            Predicate<Value> predicate = valueConstraint(requiredType, 
constraint);
             for (Value v : ValueFactoryImpl.createValues(property, 
NamePathMapper.DEFAULT)) {
                 if (predicate.apply(v)) {
                     return;

Modified: 
jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/nodetype/TypeEditorTest.java
URL: 
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/nodetype/TypeEditorTest.java?rev=1714207&r1=1714206&r2=1714207&view=diff
==============================================================================
--- 
jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/nodetype/TypeEditorTest.java
 (original)
+++ 
jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/nodetype/TypeEditorTest.java
 Fri Nov 13 13:58:36 2015
@@ -16,16 +16,27 @@
  */
 package org.apache.jackrabbit.oak.plugins.nodetype;
 
+import static org.apache.jackrabbit.JcrConstants.JCR_MIXINTYPES;
+import static org.apache.jackrabbit.JcrConstants.JCR_PRIMARYTYPE;
+import static org.apache.jackrabbit.JcrConstants.NT_FOLDER;
 import static 
org.apache.jackrabbit.oak.plugins.memory.EmptyNodeState.EMPTY_NODE;
 import static 
org.apache.jackrabbit.oak.plugins.nodetype.write.InitialContent.INITIAL_CONTENT;
 import static org.easymock.EasyMock.createControl;
 import static org.easymock.EasyMock.expect;
 import static org.easymock.EasyMock.replay;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
 
+import com.google.common.collect.ImmutableList;
 import org.apache.jackrabbit.oak.api.CommitFailedException;
+import org.apache.jackrabbit.oak.api.Type;
 import org.apache.jackrabbit.oak.plugins.memory.PropertyStates;
 import org.apache.jackrabbit.oak.spi.commit.CommitInfo;
 import org.apache.jackrabbit.oak.spi.commit.EditorHook;
+import 
org.apache.jackrabbit.oak.spi.security.authorization.accesscontrol.AccessControlConstants;
+import org.apache.jackrabbit.oak.spi.security.principal.EveryonePrincipal;
+import org.apache.jackrabbit.oak.spi.security.privilege.PrivilegeConstants;
 import org.apache.jackrabbit.oak.spi.state.NodeBuilder;
 import org.apache.jackrabbit.oak.spi.state.NodeState;
 import org.junit.Test;
@@ -102,4 +113,116 @@ public class TypeEditorTest {
         editor.childNodeDeleted("mandatory", EMPTY_NODE);
     }
 
+    @Test
+    public void addNamedPropertyWithBadRequiredType() {
+        EditorHook hook = new EditorHook(new TypeEditorProvider());
+
+        NodeState root = INITIAL_CONTENT;
+        NodeBuilder builder = root.builder();
+
+        NodeState before = builder.getNodeState();
+
+        NodeBuilder testNode = builder.child("testNode");
+        testNode.setProperty(JCR_PRIMARYTYPE, NT_FOLDER, Type.NAME);
+        testNode.setProperty(JCR_MIXINTYPES, ImmutableList.of("mix:title"), 
Type.NAMES);
+        testNode.setProperty("jcr:title", true);
+
+        try {
+            hook.processCommit(before, builder.getNodeState(), 
CommitInfo.EMPTY);
+            fail();
+        } catch (CommitFailedException e) {
+            assertTrue(e.isConstraintViolation());
+        }
+    }
+
+    @Test
+    public void changeNamedPropertyToBadRequiredType() {
+        EditorHook hook = new EditorHook(new TypeEditorProvider());
+
+        NodeState root = INITIAL_CONTENT;
+        NodeBuilder builder = root.builder();
+        NodeBuilder testNode = builder.child("testNode");
+        testNode.setProperty(JCR_PRIMARYTYPE, NT_FOLDER, Type.NAME);
+        testNode.setProperty(JCR_MIXINTYPES, ImmutableList.of("mix:title"), 
Type.NAMES);
+        testNode.setProperty("jcr:title", "title");
+
+        NodeState before = builder.getNodeState();
+
+        testNode.setProperty("jcr:title", true);
+
+        try {
+            hook.processCommit(before, builder.getNodeState(), 
CommitInfo.EMPTY);
+            fail();
+        } catch (CommitFailedException e) {
+            assertTrue(e.isConstraintViolation());
+        }
+    }
+
+    @Test
+    public void addMandatoryPropertyWithBadRequiredType() {
+        EditorHook hook = new EditorHook(new TypeEditorProvider());
+
+        NodeState root = INITIAL_CONTENT;
+        NodeBuilder builder = root.builder();
+
+        NodeState before = builder.getNodeState();
+
+        NodeBuilder acl = builder.child(AccessControlConstants.REP_POLICY);
+        acl.setProperty(JCR_PRIMARYTYPE, AccessControlConstants.NT_REP_ACL, 
Type.NAME);
+        NodeBuilder ace = acl.child("first");
+        ace.setProperty(JCR_PRIMARYTYPE, 
AccessControlConstants.NT_REP_GRANT_ACE, Type.NAME);
+        ace.setProperty(AccessControlConstants.REP_PRINCIPAL_NAME, 
EveryonePrincipal.NAME);
+        ace.setProperty(AccessControlConstants.REP_PRIVILEGES, 
ImmutableList.of(PrivilegeConstants.JCR_READ), Type.STRINGS);
+
+        try {
+            hook.processCommit(before, builder.getNodeState(), 
CommitInfo.EMPTY);
+            fail();
+        } catch (CommitFailedException e) {
+            assertTrue(e.isConstraintViolation());
+            assertEquals(55, e.getCode());
+        }
+    }
+
+    @Test
+    public void changeMandatoryPropertyToBadRequiredType() {
+        EditorHook hook = new EditorHook(new TypeEditorProvider());
+
+        NodeState root = INITIAL_CONTENT;
+        NodeBuilder builder = root.builder();
+        NodeBuilder acl = builder.child(AccessControlConstants.REP_POLICY);
+        acl.setProperty(JCR_PRIMARYTYPE, AccessControlConstants.NT_REP_ACL, 
Type.NAME);
+        NodeBuilder ace = acl.child("first");
+        ace.setProperty(JCR_PRIMARYTYPE, 
AccessControlConstants.NT_REP_GRANT_ACE, Type.NAME);
+        ace.setProperty(AccessControlConstants.REP_PRINCIPAL_NAME, 
EveryonePrincipal.NAME);
+        ace.setProperty(AccessControlConstants.REP_PRIVILEGES, 
ImmutableList.of(PrivilegeConstants.JCR_READ), Type.NAMES);
+
+        NodeState before = builder.getNodeState();
+
+        // change to invalid type
+        ace.setProperty(AccessControlConstants.REP_PRIVILEGES, 
ImmutableList.of(PrivilegeConstants.JCR_READ), Type.STRINGS);
+
+        try {
+            hook.processCommit(before, builder.getNodeState(), 
CommitInfo.EMPTY);
+            fail();
+        } catch (CommitFailedException e) {
+            assertTrue(e.isConstraintViolation());
+        }
+    }
+
+    @Test
+    public void requiredTypeIsUndefined() throws CommitFailedException {
+        EditorHook hook = new EditorHook(new TypeEditorProvider());
+
+        NodeState root = INITIAL_CONTENT;
+        NodeBuilder builder = root.builder();
+
+        NodeState before = builder.getNodeState();
+
+        builder.setProperty("any", "title");
+        NodeState after = builder.getNodeState();
+        hook.processCommit(before, after, CommitInfo.EMPTY);
+
+        builder.setProperty("any", 134.34, Type.DOUBLE);
+        hook.processCommit(after, builder.getNodeState(), CommitInfo.EMPTY);
+    }
 }


Reply via email to