This is an automated email from the ASF dual-hosted git repository. echobravo pushed a commit to branch release/1.12.0 in repository https://gitbox.apache.org/repos/asf/geode.git
The following commit(s) were added to refs/heads/release/1.12.0 by this push: new 9ca8043 GEODE-7756: Do not use authorization cache for CQs (#4677) 9ca8043 is described below commit 9ca80438c392db7ab2cd8523662bcb4c76c0ad29 Author: Juan José Ramos <jujora...@users.noreply.github.com> AuthorDate: Thu Feb 13 11:33:25 2020 +0000 GEODE-7756: Do not use authorization cache for CQs (#4677) CQs are executed on individual entries whenever an event is triggered for them and the execution context is always cleared before the actual evaluation, thus using an internal cache to keep already authorized methods is useless (will always be a cache miss and the computation required just adds overhead). - Fixed the CQ creation to always set the 'cqQueryContext' flag. - Modified the query engine to avoid using the internal cache for already authorized methods when the context belongs to a CQ. - Avoid the creation and concatenation of unnecessary Strings, using the Method class directly instead. (cherry picked from commit 5dd7a8420bbe43657abc82e5b8d073eb01b51d8d) --- .../cache/query/internal/AttributeDescriptor.java | 40 ++++---- .../geode/cache/query/internal/MethodDispatch.java | 40 ++++---- .../query/internal/QueryExecutionContext.java | 10 +- .../query/internal/AttributeDescriptorTest.java | 93 +++++++++++++++++-- .../cache/query/internal/MethodDispatchTest.java | 103 ++++++++++++++++++++- ...tyExecutionContextTamperingDistributedTest.java | 8 +- .../geode/cache/query/cq/internal/CqQueryImpl.java | 2 +- 7 files changed, 248 insertions(+), 48 deletions(-) diff --git a/geode-core/src/main/java/org/apache/geode/cache/query/internal/AttributeDescriptor.java b/geode-core/src/main/java/org/apache/geode/cache/query/internal/AttributeDescriptor.java index 2c3fd51..ef8e36d 100644 --- a/geode-core/src/main/java/org/apache/geode/cache/query/internal/AttributeDescriptor.java +++ b/geode-core/src/main/java/org/apache/geode/cache/query/internal/AttributeDescriptor.java @@ -34,6 +34,7 @@ import org.apache.geode.cache.EntryDestroyedException; import org.apache.geode.cache.query.NameNotFoundException; import org.apache.geode.cache.query.QueryInvocationTargetException; import org.apache.geode.cache.query.QueryService; +import org.apache.geode.cache.query.security.MethodInvocationAuthorizer; import org.apache.geode.internal.cache.Token; import org.apache.geode.internal.lang.JavaWorkarounds; import org.apache.geode.pdx.JSONFormatter; @@ -98,23 +99,30 @@ public class AttributeDescriptor { if (m instanceof Method) { try { Method method = (Method) m; - // Try to use previous result so authorizer gets invoked only once per query. - boolean authorizationResult; - String cacheKey = target.getClass().getCanonicalName() + "." + method.getName(); - Boolean cachedResult = (Boolean) executionContext.cacheGet(cacheKey); - - if (cachedResult == null) { - // First time, evaluate and cache result. - authorizationResult = - executionContext.getMethodInvocationAuthorizer().authorize(method, target); - executionContext.cachePut(cacheKey, authorizationResult); - } else { - // Use cached result. - authorizationResult = cachedResult; - } + MethodInvocationAuthorizer authorizer = executionContext.getMethodInvocationAuthorizer(); - if (!authorizationResult) { - throw new NotAuthorizedException(UNAUTHORIZED_STRING + method.getName()); + // CQs are generally executed on individual events, so caching is just an overhead. + if (executionContext.isCqQueryContext()) { + if (!authorizer.authorize(method, target)) { + throw new NotAuthorizedException(UNAUTHORIZED_STRING + method.getName()); + } + } else { + // Try to use previous result so authorizer gets invoked only once per query. + boolean authorizationResult; + Boolean cachedResult = (Boolean) executionContext.cacheGet(method); + + if (cachedResult == null) { + // First time, evaluate and cache result. + authorizationResult = authorizer.authorize(method, target); + executionContext.cachePut(method, authorizationResult); + } else { + // Use cached result. + authorizationResult = cachedResult; + } + + if (!authorizationResult) { + throw new NotAuthorizedException(UNAUTHORIZED_STRING + method.getName()); + } } return method.invoke(target, (Object[]) null); diff --git a/geode-core/src/main/java/org/apache/geode/cache/query/internal/MethodDispatch.java b/geode-core/src/main/java/org/apache/geode/cache/query/internal/MethodDispatch.java index 06044aa..98a1d27 100644 --- a/geode-core/src/main/java/org/apache/geode/cache/query/internal/MethodDispatch.java +++ b/geode-core/src/main/java/org/apache/geode/cache/query/internal/MethodDispatch.java @@ -29,6 +29,7 @@ import org.apache.geode.cache.query.NameNotFoundException; import org.apache.geode.cache.query.NameResolutionException; import org.apache.geode.cache.query.QueryInvocationTargetException; import org.apache.geode.cache.query.internal.types.TypeUtils; +import org.apache.geode.cache.query.security.MethodInvocationAuthorizer; import org.apache.geode.security.NotAuthorizedException; /** @@ -57,23 +58,30 @@ public class MethodDispatch { Object[] argsArray = args.toArray(); try { - // Try to use cached result so authorizer gets invoked only once per query. - boolean authorizationResult; - String cacheKey = target.getClass().getCanonicalName() + "." + _method.getName(); - Boolean cachedResult = (Boolean) executionContext.cacheGet(cacheKey); - - if (cachedResult != null) { - // Use cached result. - authorizationResult = cachedResult; - } else { - // First time, evaluate and cache result. - authorizationResult = - executionContext.getMethodInvocationAuthorizer().authorize(_method, target); - executionContext.cachePut(cacheKey, authorizationResult); - } + MethodInvocationAuthorizer authorizer = executionContext.getMethodInvocationAuthorizer(); - if (!authorizationResult) { - throw new NotAuthorizedException(UNAUTHORIZED_STRING + _method.getName()); + // CQs are generally executed on individual events, so caching is just an overhead. + if (executionContext.isCqQueryContext()) { + if (!authorizer.authorize(_method, target)) { + throw new NotAuthorizedException(UNAUTHORIZED_STRING + _method.getName()); + } + } else { + // Try to use cached result so authorizer gets invoked only once per query. + boolean authorizationResult; + Boolean cachedResult = (Boolean) executionContext.cacheGet(_method); + + if (cachedResult != null) { + // Use cached result. + authorizationResult = cachedResult; + } else { + // First time, evaluate and cache result. + authorizationResult = authorizer.authorize(_method, target); + executionContext.cachePut(_method, authorizationResult); + } + + if (!authorizationResult) { + throw new NotAuthorizedException(UNAUTHORIZED_STRING + _method.getName()); + } } return _method.invoke(target, argsArray); diff --git a/geode-core/src/main/java/org/apache/geode/cache/query/internal/QueryExecutionContext.java b/geode-core/src/main/java/org/apache/geode/cache/query/internal/QueryExecutionContext.java index 7371fde..790cac8 100644 --- a/geode-core/src/main/java/org/apache/geode/cache/query/internal/QueryExecutionContext.java +++ b/geode-core/src/main/java/org/apache/geode/cache/query/internal/QueryExecutionContext.java @@ -37,7 +37,7 @@ public class QueryExecutionContext extends ExecutionContext { private final Query query; - private boolean cqQueryContext = false; + private final boolean cqQueryContext; private List bucketList; @@ -67,6 +67,14 @@ public class QueryExecutionContext extends ExecutionContext { public QueryExecutionContext(Object[] bindArguments, InternalCache cache) { super(bindArguments, cache); this.query = null; + this.cqQueryContext = false; + } + + public QueryExecutionContext(Object[] bindArguments, InternalCache cache, + boolean cqQueryContext) { + super(bindArguments, cache); + this.query = null; + this.cqQueryContext = cqQueryContext; } public QueryExecutionContext(Object[] bindArguments, InternalCache cache, Query query) { diff --git a/geode-core/src/test/java/org/apache/geode/cache/query/internal/AttributeDescriptorTest.java b/geode-core/src/test/java/org/apache/geode/cache/query/internal/AttributeDescriptorTest.java index f7c2a20..cf6235d 100644 --- a/geode-core/src/test/java/org/apache/geode/cache/query/internal/AttributeDescriptorTest.java +++ b/geode-core/src/test/java/org/apache/geode/cache/query/internal/AttributeDescriptorTest.java @@ -75,7 +75,7 @@ public class AttributeDescriptorTest { when(mockService.getMethodAuthorizer()).thenReturn(methodInvocationAuthorizer); when(mockCache.getService(QueryConfigurationService.class)).thenReturn(mockService); - queryExecutionContext = new QueryExecutionContext(null, mockCache); + queryExecutionContext = spy(new QueryExecutionContext(null, mockCache)); } @Test @@ -241,8 +241,23 @@ public class AttributeDescriptorTest { AttributeDescriptor attributeDescriptor = new AttributeDescriptor(typeRegistry, attributeName); attributeDescriptor.readReflection(testBean, queryExecutionContext); - String cacheKey = TestBean.class.getCanonicalName() + "." + methodName; - assertThat(queryExecutionContext.cacheGet(cacheKey)).isEqualTo(true); + Method method = TestBean.class.getMethod(methodName); + assertThat(queryExecutionContext.cacheGet(method)).isEqualTo(true); + } + + @Test + @Parameters({ + "nonPublicAttributeWithPublicAccessor, nonPublicAttributeWithPublicAccessor", + "nonPublicAttributeWithPublicGetterMethod, getNonPublicAttributeWithPublicGetterMethod"}) + public void readReflectionForImplicitMethodInvocationShouldReturnCorrectlyWhenMethodIsAuthorizedAndDoNotCacheResultForCqs( + String attributeName, String methodName) throws Exception { + when(queryExecutionContext.isCqQueryContext()).thenReturn(true); + doReturn(true).when(methodInvocationAuthorizer).authorize(any(), any()); + AttributeDescriptor attributeDescriptor = new AttributeDescriptor(typeRegistry, attributeName); + attributeDescriptor.readReflection(testBean, queryExecutionContext); + + Method method = TestBean.class.getMethod(methodName); + assertThat(queryExecutionContext.cacheGet(method)).isNull(); } @Test @@ -295,6 +310,31 @@ public class AttributeDescriptorTest { } @Test + public void readReflectionForImplicitMethodInvocationShouldNotUseCachedAuthorizerResultForCqs() { + when(queryExecutionContext.isCqQueryContext()).thenReturn(true); + doReturn(true).when(methodInvocationAuthorizer).authorize(any(), any()); + AttributeDescriptor nonPublicAttributeWithPublicAccessor = + new AttributeDescriptor(typeRegistry, PRIVATE_ACCESSOR_BY_NAME); + AttributeDescriptor nonPublicAttributeWithPublicGetterMethod = + new AttributeDescriptor(typeRegistry, PRIVATE_ACCESSOR_BY_GETTER); + + // Same QueryExecutionContext but CQ -> Do not use cache. + IntStream.range(0, 10).forEach(element -> { + try { + assertThat( + nonPublicAttributeWithPublicAccessor.readReflection(testBean, queryExecutionContext)) + .isInstanceOf(String.class).isEqualTo(PRIVATE_ACCESSOR_BY_NAME); + assertThat(nonPublicAttributeWithPublicGetterMethod.readReflection(testBean, + queryExecutionContext)).isInstanceOf(String.class) + .isEqualTo(PRIVATE_ACCESSOR_BY_GETTER); + } catch (NameNotFoundException | QueryInvocationTargetException exception) { + throw new RuntimeException(exception); + } + }); + verify(methodInvocationAuthorizer, times(20)).authorize(any(), any()); + } + + @Test @Parameters({PRIVATE_ACCESSOR_BY_NAME, PRIVATE_ACCESSOR_BY_GETTER}) public void readReflectionForImplicitMethodInvocationShouldThrowExceptionWhenMethodIsNotAuthorized( String attributeName) { @@ -310,8 +350,26 @@ public class AttributeDescriptorTest { @Parameters({ "nonPublicAttributeWithPublicAccessor, nonPublicAttributeWithPublicAccessor", "nonPublicAttributeWithPublicGetterMethod, getNonPublicAttributeWithPublicGetterMethod"}) - public void readReflectionForImplicitMethodInvocationShouldShouldThrowExceptionWhenMethodIsNotAuthorizedAndCacheResult( - String attributeName, String methodName) { + public void readReflectionForImplicitMethodInvocationShouldThrowExceptionWhenMethodIsNotAuthorizedAndCacheResult( + String attributeName, String methodName) throws NoSuchMethodException { + doReturn(false).when(methodInvocationAuthorizer).authorize(any(), any()); + AttributeDescriptor attributeDescriptor = new AttributeDescriptor(typeRegistry, attributeName); + + assertThatThrownBy(() -> attributeDescriptor.readReflection(testBean, queryExecutionContext)) + .isInstanceOf(NotAuthorizedException.class) + .hasMessageStartingWith(RestrictedMethodAuthorizer.UNAUTHORIZED_STRING); + + Method method = TestBean.class.getMethod(methodName); + assertThat(queryExecutionContext.cacheGet(method)).isEqualTo(false); + } + + @Test + @Parameters({ + "nonPublicAttributeWithPublicAccessor, nonPublicAttributeWithPublicAccessor", + "nonPublicAttributeWithPublicGetterMethod, getNonPublicAttributeWithPublicGetterMethod"}) + public void readReflectionForImplicitMethodInvocationShouldThrowExceptionWhenMethodIsNotAuthorizedAndDoNotCacheResultForCqs( + String attributeName, String methodName) throws NoSuchMethodException { + when(queryExecutionContext.isCqQueryContext()).thenReturn(true); doReturn(false).when(methodInvocationAuthorizer).authorize(any(), any()); AttributeDescriptor attributeDescriptor = new AttributeDescriptor(typeRegistry, attributeName); @@ -319,8 +377,8 @@ public class AttributeDescriptorTest { .isInstanceOf(NotAuthorizedException.class) .hasMessageStartingWith(RestrictedMethodAuthorizer.UNAUTHORIZED_STRING); - String cacheKey = TestBean.class.getCanonicalName() + "." + methodName; - assertThat(queryExecutionContext.cacheGet(cacheKey)).isEqualTo(false); + Method method = TestBean.class.getMethod(methodName); + assertThat(queryExecutionContext.cacheGet(method)).isNull(); } @Test @@ -369,6 +427,27 @@ public class AttributeDescriptorTest { } @Test + public void readReflectionForImplicitMethodInvocationShouldNotUseCachedAuthorizerResultWhenMethodIsForbiddenForCqs() { + when(queryExecutionContext.isCqQueryContext()).thenReturn(true); + doReturn(false).when(methodInvocationAuthorizer).authorize(any(), any()); + AttributeDescriptor nonPublicAttributeWithPublicAccessor = + new AttributeDescriptor(typeRegistry, PRIVATE_ACCESSOR_BY_NAME); + AttributeDescriptor nonPublicAttributeWithPublicGetterMethod = + new AttributeDescriptor(typeRegistry, PRIVATE_ACCESSOR_BY_GETTER); + + // Same QueryExecutionContext but CQ -> Do not use cache. + IntStream.range(0, 10).forEach(element -> { + assertThatThrownBy(() -> nonPublicAttributeWithPublicAccessor.readReflection(testBean, + queryExecutionContext)).isInstanceOf(NotAuthorizedException.class) + .hasMessageStartingWith(RestrictedMethodAuthorizer.UNAUTHORIZED_STRING); + assertThatThrownBy(() -> nonPublicAttributeWithPublicGetterMethod.readReflection(testBean, + queryExecutionContext)).isInstanceOf(NotAuthorizedException.class) + .hasMessageStartingWith(RestrictedMethodAuthorizer.UNAUTHORIZED_STRING); + }); + verify(methodInvocationAuthorizer, times(20)).authorize(any(), any()); + } + + @Test public void readShouldReturnUndefinedForNullOrUndefinedTargetObject() throws NameNotFoundException, QueryInvocationTargetException { AttributeDescriptor attributeDescriptor = new AttributeDescriptor(typeRegistry, "whatever"); diff --git a/geode-core/src/test/java/org/apache/geode/cache/query/internal/MethodDispatchTest.java b/geode-core/src/test/java/org/apache/geode/cache/query/internal/MethodDispatchTest.java index eaae032..8e58223 100644 --- a/geode-core/src/test/java/org/apache/geode/cache/query/internal/MethodDispatchTest.java +++ b/geode-core/src/test/java/org/apache/geode/cache/query/internal/MethodDispatchTest.java @@ -24,6 +24,7 @@ import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; +import java.lang.reflect.Method; import java.util.Collections; import java.util.List; import java.util.stream.IntStream; @@ -47,7 +48,7 @@ public class MethodDispatchTest { private static final String EXTENDED_PUBLIC_METHOD_NAME = "publicMethod"; private static final String EXTENDED_PUBLIC_METHOD_RETURN_VALUE = "extendedPublic"; - private List emptyList; + private List<?> emptyList; private TestBean testBean; private QueryExecutionContext queryExecutionContext; private MethodInvocationAuthorizer methodInvocationAuthorizer; @@ -63,7 +64,7 @@ public class MethodDispatchTest { InternalCache mockCache = mock(InternalCache.class); when(mockCache.getService(QueryConfigurationService.class)).thenReturn(mockService); - queryExecutionContext = new QueryExecutionContext(null, mockCache); + queryExecutionContext = spy(new QueryExecutionContext(null, mockCache)); } @Test @@ -95,8 +96,21 @@ public class MethodDispatchTest { MethodDispatch methodDispatch = new MethodDispatch(Integer.class, "toString", Collections.emptyList()); + Method toStringMethod = Integer.class.getMethod("toString"); methodDispatch.invoke(new Integer("0"), emptyList, queryExecutionContext); - assertThat(queryExecutionContext.cacheGet("java.lang.Integer.toString")).isEqualTo(true); + assertThat(queryExecutionContext.cacheGet(toStringMethod)).isEqualTo(true); + } + + @Test + public void invokeShouldNotCacheResultForAllowedMethodOnCqs() throws Exception { + when(queryExecutionContext.isCqQueryContext()).thenReturn(true); + doReturn(true).when(methodInvocationAuthorizer).authorize(any(), any()); + MethodDispatch methodDispatch = + new MethodDispatch(Integer.class, "toString", Collections.emptyList()); + + Method toStringMethod = Integer.class.getMethod("toString"); + methodDispatch.invoke(new Integer("0"), emptyList, queryExecutionContext); + assertThat(queryExecutionContext.cacheGet(toStringMethod)).isNull(); } @Test @@ -109,7 +123,25 @@ public class MethodDispatchTest { () -> methodDispatch.invoke(new Integer("0"), emptyList, queryExecutionContext)) .isInstanceOf(NotAuthorizedException.class) .hasMessage(RestrictedMethodAuthorizer.UNAUTHORIZED_STRING + "toString"); - assertThat(queryExecutionContext.cacheGet("java.lang.Integer.toString")).isEqualTo(false); + + Method toStringMethod = Integer.class.getMethod("toString"); + assertThat(queryExecutionContext.cacheGet(toStringMethod)).isEqualTo(false); + } + + @Test + public void invokeShouldNotCacheResultForForbiddenMethodOnCqs() throws Exception { + when(queryExecutionContext.isCqQueryContext()).thenReturn(true); + doReturn(false).when(methodInvocationAuthorizer).authorize(any(), any()); + MethodDispatch methodDispatch = + new MethodDispatch(Integer.class, "toString", Collections.emptyList()); + + assertThatThrownBy( + () -> methodDispatch.invoke(new Integer("0"), emptyList, queryExecutionContext)) + .isInstanceOf(NotAuthorizedException.class) + .hasMessage(RestrictedMethodAuthorizer.UNAUTHORIZED_STRING + "toString"); + + Method toStringMethod = Integer.class.getMethod("toString"); + assertThat(queryExecutionContext.cacheGet(toStringMethod)).isNull(); } @Test @@ -174,6 +206,36 @@ public class MethodDispatchTest { } @Test + public void invokeShouldNotUseCachedAuthorizerResultWhenMethodIsAuthorizedAndQueryContextIsTheSameForCqs() + throws NameResolutionException { + when(queryExecutionContext.isCqQueryContext()).thenReturn(true); + doReturn(true).when(methodInvocationAuthorizer).authorize(any(), any()); + MethodDispatch publicMethodDispatch = + new MethodDispatch(TestBean.class, PUBLIC_METHOD_NAME, Collections.emptyList()); + MethodDispatch anotherPublicMethodDispatch = + new MethodDispatch(TestBean.class, ANOTHER_PUBLIC_METHOD_NAME, Collections.emptyList()); + MethodDispatch extendedPublicMethodDispatch = + new MethodDispatch(TestBeanExtension.class, EXTENDED_PUBLIC_METHOD_NAME, + Collections.emptyList()); + + // Same QueryExecutionContext -> Use cache. + IntStream.range(0, 10).forEach(element -> { + try { + assertThat(publicMethodDispatch.invoke(testBean, emptyList, queryExecutionContext)) + .isInstanceOf(String.class).isEqualTo(PUBLIC_METHOD_RETURN_VALUE); + assertThat(anotherPublicMethodDispatch.invoke(testBean, emptyList, queryExecutionContext)) + .isInstanceOf(String.class).isEqualTo(ANOTHER_PUBLIC_METHOD_RETURN_VALUE); + assertThat(extendedPublicMethodDispatch + .invoke(new TestBeanExtension(), emptyList, queryExecutionContext)) + .isInstanceOf(String.class).isEqualTo(EXTENDED_PUBLIC_METHOD_RETURN_VALUE); + } catch (NameNotFoundException | QueryInvocationTargetException exception) { + throw new RuntimeException(exception); + } + }); + verify(methodInvocationAuthorizer, times(30)).authorize(any(), any()); + } + + @Test public void invokeShouldUseCachedAuthorizerResultWhenMethodIsNotAuthorizedAndContextIsTheSame() throws NameResolutionException { doReturn(false).when(methodInvocationAuthorizer).authorize(any(), any()); @@ -237,6 +299,39 @@ public class MethodDispatchTest { verify(methodInvocationAuthorizer, times(30)).authorize(any(), any()); } + @Test + public void invokeShouldNotUseCachedAuthorizerResultWhenMethodIsNotAuthorizedAndContextIsTheSameForCqs() + throws NameResolutionException { + when(queryExecutionContext.isCqQueryContext()).thenReturn(true); + doReturn(false).when(methodInvocationAuthorizer).authorize(any(), any()); + MethodDispatch publicMethodDispatch = + new MethodDispatch(TestBean.class, PUBLIC_METHOD_NAME, Collections.emptyList()); + MethodDispatch anotherPublicMethodDispatch = + new MethodDispatch(TestBean.class, ANOTHER_PUBLIC_METHOD_NAME, Collections.emptyList()); + MethodDispatch extendedPublicMethodDispatch = + new MethodDispatch(TestBeanExtension.class, EXTENDED_PUBLIC_METHOD_NAME, + Collections.emptyList()); + + // Same QueryExecutionContext -> Use cache. + IntStream.range(0, 10).forEach(element -> { + assertThatThrownBy( + () -> publicMethodDispatch.invoke(testBean, emptyList, queryExecutionContext)) + .isInstanceOf(NotAuthorizedException.class) + .hasMessage(RestrictedMethodAuthorizer.UNAUTHORIZED_STRING + PUBLIC_METHOD_NAME); + assertThatThrownBy( + () -> anotherPublicMethodDispatch.invoke(testBean, emptyList, queryExecutionContext)) + .isInstanceOf(NotAuthorizedException.class) + .hasMessage( + RestrictedMethodAuthorizer.UNAUTHORIZED_STRING + ANOTHER_PUBLIC_METHOD_NAME); + assertThatThrownBy(() -> extendedPublicMethodDispatch + .invoke(new TestBeanExtension(), emptyList, queryExecutionContext)) + .isInstanceOf(NotAuthorizedException.class) + .hasMessage( + RestrictedMethodAuthorizer.UNAUTHORIZED_STRING + EXTENDED_PUBLIC_METHOD_NAME); + }); + verify(methodInvocationAuthorizer, times(30)).authorize(any(), any()); + } + @SuppressWarnings("unused") private static class TestBean { public String publicMethod() { diff --git a/geode-cq/src/distributedTest/java/org/apache/geode/cache/query/cq/internal/CqSecurityExecutionContextTamperingDistributedTest.java b/geode-cq/src/distributedTest/java/org/apache/geode/cache/query/cq/internal/CqSecurityExecutionContextTamperingDistributedTest.java index d681739..92eccbf 100644 --- a/geode-cq/src/distributedTest/java/org/apache/geode/cache/query/cq/internal/CqSecurityExecutionContextTamperingDistributedTest.java +++ b/geode-cq/src/distributedTest/java/org/apache/geode/cache/query/cq/internal/CqSecurityExecutionContextTamperingDistributedTest.java @@ -21,6 +21,7 @@ import static org.apache.geode.test.awaitility.GeodeAwaitility.await; import static org.assertj.core.api.Assertions.assertThat; import java.io.Serializable; +import java.lang.reflect.Method; import org.junit.Before; import org.junit.Rule; @@ -49,7 +50,7 @@ import org.apache.geode.test.junit.categories.SecurityTest; import org.apache.geode.test.junit.runners.CategoryWithParameterizedRunnerFactory; /** - * Verifies that users can tamper the {@link ExecutionContext}. + * Verifies that users can not tamper the {@link ExecutionContext}. * It needs to be part of the {@link org.apache.geode.cache.query.cq.internal} package because the * method {@link CqQueryImpl#getQueryExecutionContext()} has package access. */ @@ -121,8 +122,9 @@ public class CqSecurityExecutionContextTamperingDistributedTest implements Seria assertThat(internalCache.getCqService().getAllCqs().size()).isEqualTo(1); CqQueryImpl cqQueryImpl = (CqQueryImpl) internalCache.getCqService().getAllCqs().iterator().next(); - ExecutionContextTamperer.tamperContextCache(cqQueryImpl.getQueryExecutionContext(), - "org.apache.geode.security.query.data.QueryTestObject.getName", true); + Method method = QueryTestObject.class.getMethod("getName"); + ExecutionContextTamperer.tamperContextCache(cqQueryImpl.getQueryExecutionContext(), method, + true); Region<String, QueryTestObject> region = ClusterStartupRule.getCache().getRegion(regionName); region.put("1", new QueryTestObject(1, "Beth")); diff --git a/geode-cq/src/main/java/org/apache/geode/cache/query/cq/internal/CqQueryImpl.java b/geode-cq/src/main/java/org/apache/geode/cache/query/cq/internal/CqQueryImpl.java index 66fc6cf..eed5568 100644 --- a/geode-cq/src/main/java/org/apache/geode/cache/query/cq/internal/CqQueryImpl.java +++ b/geode-cq/src/main/java/org/apache/geode/cache/query/cq/internal/CqQueryImpl.java @@ -210,7 +210,7 @@ public abstract class CqQueryImpl implements InternalCqQuery { // Set Query ExecutionContext, that will be used in later execution. this.setQueryExecutionContext( - new QueryExecutionContext(null, (InternalCache) this.cqService.getCache())); + new QueryExecutionContext(null, (InternalCache) this.cqService.getCache(), true)); } /**