This is an automated email from the ASF dual-hosted git repository. boglesby pushed a commit to branch feature/GEODE-5404 in repository https://gitbox.apache.org/repos/asf/geode.git
commit c02027d5bb1d85be8b9ccfaa3359df3171e501fe Author: Barry Oglesby <[email protected]> AuthorDate: Mon Jul 9 16:38:06 2018 -0700 GEODE-5405: Created static default whitelist and modified to call length instead of size --- .../RestrictedMethodInvocationAuthorizer.java | 13 ++++- .../cache/tier/sockets/BaseCommandQuery.java | 6 +- .../RestrictedMethodInvocationAuthorizerTest.java | 14 +++++ .../query/QuerySecurityDistinctQueryDUnitTest.java | 65 ++++++++++++++++++++++ .../apache/geode/security/query/data/PdxTrade.java | 59 ++++++++++++++++++++ 5 files changed, 152 insertions(+), 5 deletions(-) diff --git a/geode-core/src/main/java/org/apache/geode/cache/query/internal/RestrictedMethodInvocationAuthorizer.java b/geode-core/src/main/java/org/apache/geode/cache/query/internal/RestrictedMethodInvocationAuthorizer.java index 254c817..20111a4 100644 --- a/geode-core/src/main/java/org/apache/geode/cache/query/internal/RestrictedMethodInvocationAuthorizer.java +++ b/geode-core/src/main/java/org/apache/geode/cache/query/internal/RestrictedMethodInvocationAuthorizer.java @@ -31,6 +31,11 @@ public class RestrictedMethodInvocationAuthorizer implements MethodInvocationAut public static final String UNAUTHORIZED_STRING = "Unauthorized access to method: "; + protected static final HashMap<String, Set> DEFAULT_WHITELIST; + static { + DEFAULT_WHITELIST = createWhiteList(); + } + private SecurityService securityService; // List of methods that can be invoked by @@ -39,10 +44,10 @@ public class RestrictedMethodInvocationAuthorizer implements MethodInvocationAut public RestrictedMethodInvocationAuthorizer(SecurityService securityService) { this.securityService = securityService; - whiteListedMethodsToClass = createWhiteList(); + whiteListedMethodsToClass = DEFAULT_WHITELIST; } - private HashMap<String, Set> createWhiteList() { + private static HashMap<String, Set> createWhiteList() { HashMap<String, Set> whiteListMap = new HashMap(); Set<Class> objectCallers = new HashSet(); objectCallers.add(Object.class); @@ -122,6 +127,10 @@ public class RestrictedMethodInvocationAuthorizer implements MethodInvocationAut return whiteListMap; } + protected HashMap<String, Set> getWhiteList() { + return whiteListedMethodsToClass; + } + boolean isWhitelisted(Method method) { String methodName = method.getName(); diff --git a/geode-core/src/main/java/org/apache/geode/internal/cache/tier/sockets/BaseCommandQuery.java b/geode-core/src/main/java/org/apache/geode/internal/cache/tier/sockets/BaseCommandQuery.java index a162e75..7dcffb5 100644 --- a/geode-core/src/main/java/org/apache/geode/internal/cache/tier/sockets/BaseCommandQuery.java +++ b/geode-core/src/main/java/org/apache/geode/internal/cache/tier/sockets/BaseCommandQuery.java @@ -364,7 +364,7 @@ public abstract class BaseCommandQuery extends BaseCommand { } Object[] results = new Object[MAXIMUM_CHUNK_SIZE]; for (int i = 0; i < MAXIMUM_CHUNK_SIZE; i++) { - if ((resultIndex) == selectResults.size()) { + if ((resultIndex) == objs.length) { incompleteArray = true; break; } @@ -425,7 +425,7 @@ public abstract class BaseCommandQuery extends BaseCommand { } if (sendResults) { - writeQueryResponseChunk(results, collectionType, (resultIndex == selectResults.size()), + writeQueryResponseChunk(results, collectionType, (resultIndex == objs.length), servConn); if (logger.isDebugEnabled()) { @@ -435,7 +435,7 @@ public abstract class BaseCommandQuery extends BaseCommand { } // If we have reached the last element of SelectResults then we should // break out of loop here only. - if (resultIndex == selectResults.size()) { + if (resultIndex == objs.length) { break; } } diff --git a/geode-core/src/test/java/org/apache/geode/cache/query/internal/RestrictedMethodInvocationAuthorizerTest.java b/geode-core/src/test/java/org/apache/geode/cache/query/internal/RestrictedMethodInvocationAuthorizerTest.java index 0f5e589..e72cebe 100644 --- a/geode-core/src/test/java/org/apache/geode/cache/query/internal/RestrictedMethodInvocationAuthorizerTest.java +++ b/geode-core/src/test/java/org/apache/geode/cache/query/internal/RestrictedMethodInvocationAuthorizerTest.java @@ -15,6 +15,7 @@ package org.apache.geode.cache.query.internal; +import static org.assertj.core.api.Assertions.assertThat; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; @@ -483,6 +484,19 @@ public class RestrictedMethodInvocationAuthorizerTest { testNumberMethods(AtomicLong.class); } + @Test + public void verifyAuthorizersUseDefaultWhiteList() { + RestrictedMethodInvocationAuthorizer authorizer1 = + new RestrictedMethodInvocationAuthorizer(null); + RestrictedMethodInvocationAuthorizer authorizer2 = + new RestrictedMethodInvocationAuthorizer(null); + assertThat(authorizer1.getWhiteList()).isSameAs(authorizer2.getWhiteList()); + assertThat(authorizer1.getWhiteList()) + .isSameAs(RestrictedMethodInvocationAuthorizer.DEFAULT_WHITELIST); + assertThat(authorizer2.getWhiteList()) + .isSameAs(RestrictedMethodInvocationAuthorizer.DEFAULT_WHITELIST); + } + private void testNumberMethods(Class<?> clazz) throws NoSuchMethodException { Method byteValue = clazz.getMethod("byteValue"); Method doubleValue = clazz.getMethod("doubleValue"); diff --git a/geode-core/src/test/java/org/apache/geode/security/query/QuerySecurityDistinctQueryDUnitTest.java b/geode-core/src/test/java/org/apache/geode/security/query/QuerySecurityDistinctQueryDUnitTest.java new file mode 100644 index 0000000..dadca76 --- /dev/null +++ b/geode-core/src/test/java/org/apache/geode/security/query/QuerySecurityDistinctQueryDUnitTest.java @@ -0,0 +1,65 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more contributor license + * agreements. See the NOTICE file distributed with this work for additional information 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 + * + * 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 specific language governing permissions and limitations under + * the License. + */ +package org.apache.geode.security.query; + +import static org.assertj.core.api.Assertions.assertThat; + +import org.junit.Test; +import org.junit.experimental.categories.Category; + +import org.apache.geode.cache.RegionShortcut; +import org.apache.geode.cache.query.QueryService; +import org.apache.geode.cache.query.SelectResults; +import org.apache.geode.security.query.data.PdxTrade; +import org.apache.geode.test.junit.categories.DistributedTest; +import org.apache.geode.test.junit.categories.SecurityTest; + +/** + * This test verifies client/server distinct order-by queries with integrated security + */ +@Category({DistributedTest.class, SecurityTest.class}) +public class QuerySecurityDistinctQueryDUnitTest extends QuerySecurityBase { + + public RegionShortcut getRegionType() { + return RegionShortcut.PARTITION; + } + + @Test + public void executingDistinctOrderByQuery() { + // Do puts from the client + int numObjects = 1000; + keys = new Object[numObjects]; + values = new Object[numObjects]; + for (int i = 0; i < numObjects; i++) { + String key = String.valueOf(i); + Object value = new PdxTrade(key, "PVTL", 100, 30); + keys[i] = key; + values[i] = value; + } + putIntoRegion(superUserClient, keys, values, regionName); + + // Execute query from the client and validate the size of the results + superUserClient.invoke(() -> { + int limit = 500; + String query = "<trace> select distinct * from /" + regionName + + " where cusip = 'PVTL' order by id asc limit " + limit; + QueryService queryService = getClientCache().getQueryService(); + Object results = queryService.newQuery(query).execute(); + assertThat(results).isInstanceOf(SelectResults.class); + assertThat(((SelectResults) results).size()).isEqualTo(limit); + }); + + } +} diff --git a/geode-core/src/test/java/org/apache/geode/security/query/data/PdxTrade.java b/geode-core/src/test/java/org/apache/geode/security/query/data/PdxTrade.java new file mode 100644 index 0000000..0001d20 --- /dev/null +++ b/geode-core/src/test/java/org/apache/geode/security/query/data/PdxTrade.java @@ -0,0 +1,59 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more contributor license + * agreements. See the NOTICE file distributed with this work for additional information 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 + * + * 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 specific language governing permissions and limitations under + * the License. + */ +package org.apache.geode.security.query.data; + +import java.io.Serializable; + +import org.apache.geode.pdx.PdxReader; +import org.apache.geode.pdx.PdxSerializable; +import org.apache.geode.pdx.PdxWriter; + +public class PdxTrade implements PdxSerializable, Serializable { + + private String id; + + private String cusip; + + private int shares; + + private int price; + + public PdxTrade() { + + } + + public PdxTrade(String id, String cusip, int shares, int price) { + this.id = id; + this.cusip = cusip; + this.shares = shares; + this.price = price; + } + + @Override + public void toData(PdxWriter writer) { + writer.writeString("id", id); + writer.writeString("cusip", cusip); + writer.writeInt("shares", shares); + writer.writeInt("price", price); + } + + @Override + public void fromData(PdxReader reader) { + id = reader.readString("id"); + cusip = reader.readString("cusip"); + shares = reader.readInt("shares"); + price = reader.readInt("price"); + } +}
