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);
+ }
}