From fbafc3a4fdab5d3cc05e6bb5c0e87c3b0a8eb41f Mon Sep 17 00:00:00 2001 From: Stephan Klevenz Date: Fri, 28 Mar 2014 16:08:33 +0100 Subject: [PATCH] [OLINGO-206] key predicate validation --- .../core/uri/UriResourceWithKeysImpl.java | 22 +++--- .../uri/validator/UriValidationException.java | 9 ++- .../core/uri/validator/UriValidator.java | 67 +++++++++++++++---- .../uri/validator/UriEdmValidatorTest.java | 39 ++++++----- 4 files changed, 95 insertions(+), 42 deletions(-) diff --git a/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/UriResourceWithKeysImpl.java b/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/UriResourceWithKeysImpl.java index f8827faca..aef580017 100644 --- a/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/UriResourceWithKeysImpl.java +++ b/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/UriResourceWithKeysImpl.java @@ -1,18 +1,18 @@ -/* +/* * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file + * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file + * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the + * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ @@ -47,8 +47,10 @@ public abstract class UriResourceWithKeysImpl extends UriResourceImpl implements public List getKeyPredicates() { List retList = new ArrayList(); - for (UriParameterImpl item : keyPredicates) { - retList.add(item); + if (keyPredicates != null) { + for (UriParameterImpl item : keyPredicates) { + retList.add(item); + } } return retList; } diff --git a/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/validator/UriValidationException.java b/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/validator/UriValidationException.java index 3ba323d1b..c9c664d4b 100644 --- a/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/validator/UriValidationException.java +++ b/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/validator/UriValidationException.java @@ -18,12 +18,17 @@ */ package org.apache.olingo.server.core.uri.validator; +import org.apache.olingo.commons.api.edm.EdmPrimitiveTypeException; + public class UriValidationException extends Exception { + private static final long serialVersionUID = -3179078078053564742L; + public UriValidationException(String msg) { super(msg); } - private static final long serialVersionUID = -3179078078053564742L; - + public UriValidationException(EdmPrimitiveTypeException e) { + super(e); + } } diff --git a/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/validator/UriValidator.java b/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/validator/UriValidator.java index a8f1790e9..2530908f0 100644 --- a/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/validator/UriValidator.java +++ b/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/validator/UriValidator.java @@ -18,14 +18,24 @@ */ package org.apache.olingo.server.core.uri.validator; +import java.util.HashMap; +import java.util.List; + import org.apache.olingo.commons.api.ODataRuntimeException; import org.apache.olingo.commons.api.edm.Edm; import org.apache.olingo.commons.api.edm.EdmEntityType; +import org.apache.olingo.commons.api.edm.EdmKeyPropertyRef; +import org.apache.olingo.commons.api.edm.EdmPrimitiveType; +import org.apache.olingo.commons.api.edm.EdmPrimitiveTypeException; import org.apache.olingo.commons.api.edm.EdmReturnType; +import org.apache.olingo.commons.api.edm.EdmType; import org.apache.olingo.server.api.uri.UriInfo; +import org.apache.olingo.server.api.uri.UriParameter; import org.apache.olingo.server.api.uri.UriResource; import org.apache.olingo.server.api.uri.UriResourceAction; +import org.apache.olingo.server.api.uri.UriResourceEntitySet; import org.apache.olingo.server.api.uri.UriResourceFunction; +import org.apache.olingo.server.api.uri.UriResourceKind; import org.apache.olingo.server.api.uri.UriResourceNavigation; import org.apache.olingo.server.api.uri.UriResourcePartTyped; import org.apache.olingo.server.api.uri.queryoption.SystemQueryOption; @@ -439,20 +449,14 @@ public class UriValidator { } private void validateQueryOptions(final UriInfo uriInfo, Edm edm) throws UriValidationException { - try { - RowIndexForUriType row = rowIndexForUriType(uriInfo, edm); + RowIndexForUriType row = rowIndexForUriType(uriInfo, edm); - for (SystemQueryOption option : uriInfo.getSystemQueryOptions()) { - ColumnIndex col = colIndex(option.getKind()); + for (SystemQueryOption option : uriInfo.getSystemQueryOptions()) { + ColumnIndex col = colIndex(option.getKind()); - System.out.print("[" + row + "][" + col + "]"); - - if (!decisionMatrix[row.getIndex()][col.getIndex()]) { - throw new UriValidationException("System query option not allowed: " + option.getName()); - } + if (!decisionMatrix[row.getIndex()][col.getIndex()]) { + throw new UriValidationException("System query option not allowed: " + option.getName()); } - } finally { - System.out.println(); } } @@ -492,6 +496,45 @@ public class UriValidator { return idx; } - private void validateKeyPredicateTypes(final UriInfo uriInfo, final Edm edm) throws UriValidationException {} + private void validateKeyPredicateTypes(final UriInfo uriInfo, final Edm edm) throws UriValidationException { + try { + for (UriResource pathSegment : uriInfo.getUriResourceParts()) { + if (pathSegment.getKind() == UriResourceKind.entitySet) { + UriResourceEntitySet pathEntitySet = (UriResourceEntitySet) pathSegment; + EdmEntityType type = pathEntitySet.getEntityType(); + List keys = type.getKeyPropertyRefs(); + List keyPredicates = pathEntitySet.getKeyPredicates(); + + if (null != keyPredicates) { + + HashMap edmKeys = new HashMap(); + for (EdmKeyPropertyRef key : keys) { + edmKeys.put(key.getKeyPropertyName(), key); + } + + for (UriParameter keyPredicate : keyPredicates) { + String name = keyPredicate.getName(); + String value = keyPredicate.getText(); + EdmKeyPropertyRef edmKey = edmKeys.get(name); + + if (edmKey == null) { + throw new UriValidationException("Unknown key property: " + name); + } + + EdmType edmType = edmKey.getProperty().getType(); + EdmPrimitiveType edmPrimitiveType = (EdmPrimitiveType) edmType; + + String edmLiteral = edmPrimitiveType.fromUriLiteral(value); + edmPrimitiveType.validate(edmLiteral, edmKey.getProperty().isNullable(), edmKey.getProperty() + .getMaxLength(), edmKey.getProperty().getPrecision(), edmKey.getProperty().getScale(), edmKey + .getProperty().isUnicode()); + } + } + } + } + } catch (EdmPrimitiveTypeException e) { + throw new UriValidationException(e); + } + } } diff --git a/lib/server-core/src/test/java/org/apache/olingo/server/core/uri/validator/UriEdmValidatorTest.java b/lib/server-core/src/test/java/org/apache/olingo/server/core/uri/validator/UriEdmValidatorTest.java index a76cee584..4865f8b4e 100644 --- a/lib/server-core/src/test/java/org/apache/olingo/server/core/uri/validator/UriEdmValidatorTest.java +++ b/lib/server-core/src/test/java/org/apache/olingo/server/core/uri/validator/UriEdmValidatorTest.java @@ -73,8 +73,6 @@ public class UriEdmValidatorTest { private static final String QO_LEVELS = "$expand=*($levels=1)"; private static final String QO_TOP = "$top=1"; - private Edm edm = new EdmProviderImpl(new EdmTechProvider()); - private String[][] urisWithValidSystemQueryOptions = { { URI_ALL, QO_FILTER, }, { URI_ALL, QO_FORMAT }, { URI_ALL, QO_EXPAND }, { URI_ALL, QO_COUNT }, /* { URI_ALL, QO_ORDERBY }, *//* { URI_ALL, QO_SEARCH }, */{ URI_ALL, QO_SELECT }, { URI_ALL, QO_SKIP }, @@ -249,28 +247,33 @@ public class UriEdmValidatorTest { { URI_NAV_ENTITY_SET, QO_ID }, }; - + private Parser parser; + private Edm edm; @Before public void before() { parser = new Parser(); + edm = new EdmProviderImpl(new EdmTechProvider()); } -// @Test -// @Ignore -// public -// void bla() throws Exception { -// String[][] m = { -// { "/ESMedia(1)/$value?$filter='1' eq '1'" }, -// }; -// String[] uris = constructUri(m); -// for (String uri : uris) { -// System.out.println(uri); -// -// parseAndValidate(uri); -// } -// } + @Test(expected = UriValidationException.class) + public void validateKeyPredicatesWrongKey() throws Exception { + String uri = "ESTwoKeyNav(xxx=1, yyy='abc')"; + parseAndValidate(uri); + } + + @Test + public void validateKeyPredicates() throws Exception { + String uri = "ESTwoKeyNav(PropertyInt16=1, PropertyString='abc')"; + parseAndValidate(uri); + } + + @Test(expected = UriValidationException.class) + public void validateKeyPredicatesWrongValueType() throws Exception { + String uri = "ESTwoKeyNav(PropertyInt16='abc', PropertyString=1)"; + parseAndValidate(uri); + } @Test public void checkValidSystemQueryOption() throws Exception { @@ -321,7 +324,7 @@ public class UriEdmValidatorTest { UriInfo uriInfo = parser.parseUri(uri.trim(), edm); UriValidator validator = new UriValidator(); - System.out.print("URI: " + uri); validator.validate(uriInfo, edm, "GET"); } + }