Repository: incubator-geode Updated Branches: refs/heads/develop c7530d06b -> 90e00bf97
GEODE-1569: post process for serialized domain objects * for client/server retreival, post process the value before it was put into the message * for gfsh commands, post process the value before it was put into the command result json Project: http://git-wip-us.apache.org/repos/asf/incubator-geode/repo Commit: http://git-wip-us.apache.org/repos/asf/incubator-geode/commit/90e00bf9 Tree: http://git-wip-us.apache.org/repos/asf/incubator-geode/tree/90e00bf9 Diff: http://git-wip-us.apache.org/repos/asf/incubator-geode/diff/90e00bf9 Branch: refs/heads/develop Commit: 90e00bf97d4287f5462cf73eab2b5810c69c7077 Parents: c7530d0 Author: Jinmei Liao <jil...@pivotal.io> Authored: Thu Jul 28 09:11:56 2016 -0700 Committer: Jinmei Liao <jil...@pivotal.io> Committed: Mon Aug 1 08:15:45 2016 -0700 ---------------------------------------------------------------------- .../cache/tier/sockets/BaseCommandQuery.java | 123 +++---- .../cache/tier/sockets/CacheClientProxy.java | 17 +- .../cache/tier/sockets/command/Get70.java | 2 +- .../cache/tier/sockets/command/GetAll.java | 2 +- .../cache/tier/sockets/command/GetAll651.java | 2 +- .../cache/tier/sockets/command/GetAll70.java | 2 +- .../internal/security/GeodeSecurityUtil.java | 40 ++- .../internal/cli/commands/DataCommands.java | 3 - .../cli/functions/DataCommandFunction.java | 27 +- .../internal/cli/json/GfJsonObject.java | 16 + ...ractIntegratedClientAuthDistributedTest.java | 39 ++- ...ntegratedSecurityPostProcessorDUnitTest.java | 12 +- .../ClientQueryAuthDistributedTest.java | 122 +++++++ ...ntegratedClientQueryAuthDistributedTest.java | 122 ------- .../security/PDXPostProcessorDUnitTest.java | 323 +++++++++++++++++++ .../src/main/java/org/json/JSONObject.java | 7 +- 16 files changed, 600 insertions(+), 259 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/90e00bf9/geode-core/src/main/java/com/gemstone/gemfire/internal/cache/tier/sockets/BaseCommandQuery.java ---------------------------------------------------------------------- diff --git a/geode-core/src/main/java/com/gemstone/gemfire/internal/cache/tier/sockets/BaseCommandQuery.java b/geode-core/src/main/java/com/gemstone/gemfire/internal/cache/tier/sockets/BaseCommandQuery.java index 0e32fb8..f788d02 100644 --- a/geode-core/src/main/java/com/gemstone/gemfire/internal/cache/tier/sockets/BaseCommandQuery.java +++ b/geode-core/src/main/java/com/gemstone/gemfire/internal/cache/tier/sockets/BaseCommandQuery.java @@ -157,39 +157,14 @@ public abstract class BaseCommandQuery extends BaseCommand { if (result instanceof SelectResults) { SelectResults selectResults = (SelectResults)result; - // post process, iterate through the result for post processing - if(GeodeSecurityUtil.needPostProcess()) { - List list = selectResults.asList(); - for (Iterator<Object> valItr = list.iterator(); valItr.hasNext(); ) { - Object value = valItr.next(); - if (value == null) - continue; - - if (value instanceof CqEntry) { - CqEntry cqEntry = (CqEntry) value; - Object cqNewValue = GeodeSecurityUtil.postProcess(null, cqEntry.getKey(), cqEntry.getValue()); - if (!cqEntry.getValue().equals(cqNewValue)) { - selectResults.remove(value); - selectResults.add(new CqEntry(cqEntry.getKey(), cqNewValue)); - } - } else { - Object newValue = GeodeSecurityUtil.postProcess(null, null, value); - if (!value.equals(newValue)) { - selectResults.remove(value); - selectResults.add(newValue); - } - } - } - } - if (logger.isDebugEnabled()) { logger.debug("Query Result size for : {} is {}", query.getQueryString(), selectResults.size()); } - + CollectionType collectionType = null; boolean sendCqResultsWithKey = true; boolean isStructs = false; - + // check if resultset has serialized objects, so that they could be sent // as ObjectPartList boolean hasSerializedObjects = ((DefaultQuery) query) @@ -201,7 +176,7 @@ public abstract class BaseCommandQuery extends BaseCommand { // The results in a StructSet are stored in Object[]s // Get them as Object[]s for the objs[] in order to avoid duplicating // the StructTypes - + // Object[] objs = new Object[selectResults.size()]; // Get the collection type (which includes the element type) // (used to generate the appropriate instance on the client) @@ -215,15 +190,15 @@ public abstract class BaseCommandQuery extends BaseCommand { if (cqQuery != null){ // Check if the key can be sent to the client based on its version. sendCqResultsWithKey = sendCqResultsWithKey(servConn); - + if (sendCqResultsWithKey){ // Update the collection type to include key info. - collectionType = new CollectionTypeImpl(Collection.class, + collectionType = new CollectionTypeImpl(Collection.class, new StructTypeImpl(new String[]{"key", "value"})); - isStructs = collectionType.getElementType().isStructType(); + isStructs = collectionType.getElementType().isStructType(); } } - + int numberOfChunks = (int)Math.ceil(selectResults.size() * 1.0 / maximumChunkSize); @@ -231,7 +206,7 @@ public abstract class BaseCommandQuery extends BaseCommand { logger.trace("{}: Query results size: {}: Entries in chunk: {}: Number of chunks: {}", servConn.getName(), selectResults.size(), maximumChunkSize, numberOfChunks); } - + long oldStart = start; start = DistributionStats.getStatTime(); stats.incProcessQueryTime(start - oldStart); @@ -265,12 +240,12 @@ public abstract class BaseCommandQuery extends BaseCommand { isStructs, collectionType, queryString, cqQuery, sendCqResultsWithKey, sendResults); } } - + if(cqQuery != null){ // Set the CQ query result cache initialized flag. cqQuery.setCqResultsCacheInitialized(); } - + } else if (result instanceof Integer) { if (sendResults) { @@ -319,7 +294,7 @@ public abstract class BaseCommandQuery extends BaseCommand { return false; } finally { // Since the query object is being shared in case of bind queries, - // resetting the flag may cause inconsistency. + // resetting the flag may cause inconsistency. // Also since this flag is only being set in code path executed by // remote query execution, resetting it is not required. @@ -333,7 +308,7 @@ public abstract class BaseCommandQuery extends BaseCommand { stats.incWriteQueryResponseTime(DistributionStats.getStatTime() - start); return true; } - + private static boolean sendCqResultsWithKey(ServerConnection servConn) { Version clientVersion = servConn.getClientVersion(); if (clientVersion.compareTo(Version.GFE_65) >= 0) { @@ -390,9 +365,9 @@ public abstract class BaseCommandQuery extends BaseCommand { logger.debug("CQ Response sent successfully"); } } - + private static void sendResultsAsObjectArray(SelectResults selectResults, - int numberOfChunks, ServerConnection servConn, + int numberOfChunks, ServerConnection servConn, boolean isStructs, CollectionType collectionType, String queryString, ServerCQ cqQuery, boolean sendCqResultsWithKey, boolean sendResults) throws IOException { int resultIndex = 0; @@ -422,7 +397,7 @@ public abstract class BaseCommandQuery extends BaseCommand { // that results[i] is not null. i--; continue; - } + } // Add the key into CQ results cache. // For PR the Result caching is not yet supported. // cqQuery.cqResultsCacheInitialized is added to take care @@ -431,13 +406,13 @@ public abstract class BaseCommandQuery extends BaseCommand { if (!cqQuery.isPR()) { cqQuery.addToCqResultKeys(e.getKey()); } - + // Add to the Results object array. if (sendCqResultsWithKey) { results[i] = e.getKeyValuePair(); } else { results[i] = e.getValue(); - } + } } else { // instance check added to fix bug 40516. if (isStructs && (objs[resultIndex] instanceof Struct)) { @@ -468,7 +443,7 @@ public abstract class BaseCommandQuery extends BaseCommand { if (sendResults) { writeQueryResponseChunk(results, collectionType, (resultIndex == selectResults.size()), servConn); - + if (logger.isDebugEnabled()) { logger.debug("{}: Sent chunk ({} of {}) of query response for query: {}", servConn.getName(), (j + 1), numberOfChunks, queryString); @@ -507,7 +482,8 @@ public abstract class BaseCommandQuery extends BaseCommand { if (e.getValue() == null) { resultIndex++; continue; - } + } + // Add the key into CQ results cache. // For PR the Result caching is not yet supported. // cqQuery.cqResultsCacheInitialized is added to take care @@ -516,13 +492,13 @@ public abstract class BaseCommandQuery extends BaseCommand { if (!cqQuery.isPR()) { cqQuery.addToCqResultKeys(e.getKey()); } - + // Add to the Results object array. if (sendCqResultsWithKey) { result = e.getKeyValuePair(); } else { result = e.getValue(); - } + } } else { result = objs.get(resultIndex); @@ -533,7 +509,7 @@ public abstract class BaseCommandQuery extends BaseCommand { } resultIndex++; } - + if (sendResults) { writeQueryResponseChunk(serializedObjs, collectionType, ((j + 1) == numberOfChunks), servConn); @@ -545,24 +521,17 @@ public abstract class BaseCommandQuery extends BaseCommand { } } } - + private static void addToObjectPartList(ObjectPartList serializedObjs, Object res, CollectionType collectionType, boolean lastChunk, ServerConnection servConn, boolean isStructs) throws IOException { - if (isStructs && (res instanceof Struct)) { Object[] values = ((Struct) res).getFieldValues(); // create another ObjectPartList for the struct ObjectPartList serializedValueObjs = new ObjectPartList(values.length, false); for (Object value : values) { - if (value instanceof CachedDeserializable) { - serializedValueObjs.addPart(null, - ((CachedDeserializable) value).getSerializedValue(), - ObjectPartList.OBJECT, null); - } else { - addDeSerializedObjectToObjectPartList(serializedValueObjs, value); - } + addObjectToPartList(serializedValueObjs, null, value); } serializedObjs.addPart(null, serializedValueObjs, ObjectPartList.OBJECT, null); @@ -571,33 +540,33 @@ public abstract class BaseCommandQuery extends BaseCommand { // create another ObjectPartList for the Object[] ObjectPartList serializedValueObjs = new ObjectPartList(values.length, false); - for (Object value : values) { - if (value instanceof CachedDeserializable) { - serializedValueObjs.addPart(null, - ((CachedDeserializable) value).getSerializedValue(), - ObjectPartList.OBJECT, null); - } else { - addDeSerializedObjectToObjectPartList(serializedValueObjs, value); - } + for(int i=0; i<values.length; i+=2) { + Object key = values[i]; + Object value = values[i+1]; + addObjectToPartList(serializedValueObjs, key, value); } serializedObjs.addPart(null, serializedValueObjs, ObjectPartList.OBJECT, null); - } else if (res instanceof CachedDeserializable) { - serializedObjs.addPart(null, - ((CachedDeserializable) res).getSerializedValue(), - ObjectPartList.OBJECT, null); - } else { // for deserialized objects - addDeSerializedObjectToObjectPartList(serializedObjs, res); + } else { //for deserialized objects + addObjectToPartList(serializedObjs, null, res); } } - - private static void addDeSerializedObjectToObjectPartList( - ObjectPartList objPartList, Object obj) { - if (obj instanceof byte[]) { - objPartList.addPart(null, obj, ObjectPartList.BYTES, null); - } else { - objPartList.addPart(null, obj, ObjectPartList.OBJECT, null); + + private static void addObjectToPartList(ObjectPartList objPartList, Object key, Object value) { + Object object = value; + boolean isObject = true; + if (value instanceof CachedDeserializable) { + object = ((CachedDeserializable)value).getSerializedValue(); + } + else if(value instanceof byte[]){ + isObject = false; + } + + object = GeodeSecurityUtil.postProcess(null, key, object, isObject); + if(key!=null){ + objPartList.addPart(null, key, ObjectPartList.OBJECT, null); } + objPartList.addPart(null, object, isObject?ObjectPartList.OBJECT:ObjectPartList.BYTES, null); } } http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/90e00bf9/geode-core/src/main/java/com/gemstone/gemfire/internal/cache/tier/sockets/CacheClientProxy.java ---------------------------------------------------------------------- diff --git a/geode-core/src/main/java/com/gemstone/gemfire/internal/cache/tier/sockets/CacheClientProxy.java b/geode-core/src/main/java/com/gemstone/gemfire/internal/cache/tier/sockets/CacheClientProxy.java index 46737b7..e798e2e 100644 --- a/geode-core/src/main/java/com/gemstone/gemfire/internal/cache/tier/sockets/CacheClientProxy.java +++ b/geode-core/src/main/java/com/gemstone/gemfire/internal/cache/tier/sockets/CacheClientProxy.java @@ -47,7 +47,6 @@ import org.apache.shiro.util.ThreadState; import com.gemstone.gemfire.CancelException; import com.gemstone.gemfire.DataSerializer; -import com.gemstone.gemfire.GemFireIOException; import com.gemstone.gemfire.StatisticsFactory; import com.gemstone.gemfire.cache.Cache; import com.gemstone.gemfire.cache.CacheClosedException; @@ -84,7 +83,6 @@ import com.gemstone.gemfire.internal.cache.ClientServerObserver; import com.gemstone.gemfire.internal.cache.ClientServerObserverHolder; import com.gemstone.gemfire.internal.cache.Conflatable; import com.gemstone.gemfire.internal.cache.DistributedRegion; -import com.gemstone.gemfire.internal.cache.EntryEventImpl; import com.gemstone.gemfire.internal.cache.EnumListenerEvent; import com.gemstone.gemfire.internal.cache.EventID; import com.gemstone.gemfire.internal.cache.FilterProfile; @@ -109,7 +107,6 @@ import com.gemstone.gemfire.internal.logging.log4j.LocalizedMessage; import com.gemstone.gemfire.internal.logging.log4j.LogMarker; import com.gemstone.gemfire.internal.security.AuthorizeRequestPP; import com.gemstone.gemfire.internal.security.GeodeSecurityUtil; -import com.gemstone.gemfire.internal.util.BlobHelper; import com.gemstone.gemfire.security.AccessControl; /** @@ -1678,18 +1675,8 @@ public class CacheClientProxy implements ClientSession { // post process if(GeodeSecurityUtil.needPostProcess()) { Object oldValue = clientMessage.getValue(); - if (clientMessage.valueIsObject()) { - Object newValue = GeodeSecurityUtil.postProcess(clientMessage.getRegionName(), clientMessage.getKeyOfInterest(), EntryEventImpl - .deserialize((byte[]) oldValue)); - try { - clientMessage.setLatestValue(BlobHelper.serializeToBlob(newValue)); - } catch (IOException e) { - throw new GemFireIOException("Exception serializing entry value", e); - } - } else { - Object newValue = GeodeSecurityUtil.postProcess(clientMessage.getRegionName(), clientMessage.getKeyOfInterest(), oldValue); - clientMessage.setLatestValue(newValue); - } + Object newValue = GeodeSecurityUtil.postProcess(clientMessage.getRegionName(), clientMessage.getKeyOfInterest(), oldValue, clientMessage.valueIsObject()); + clientMessage.setLatestValue(newValue); } if (clientMessage.needsNoAuthorizationCheck() || postDeliverAuthCheckPassed(clientMessage)) { http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/90e00bf9/geode-core/src/main/java/com/gemstone/gemfire/internal/cache/tier/sockets/command/Get70.java ---------------------------------------------------------------------- diff --git a/geode-core/src/main/java/com/gemstone/gemfire/internal/cache/tier/sockets/command/Get70.java b/geode-core/src/main/java/com/gemstone/gemfire/internal/cache/tier/sockets/command/Get70.java index f6e17ae..54227fb 100755 --- a/geode-core/src/main/java/com/gemstone/gemfire/internal/cache/tier/sockets/command/Get70.java +++ b/geode-core/src/main/java/com/gemstone/gemfire/internal/cache/tier/sockets/command/Get70.java @@ -217,7 +217,7 @@ public class Get70 extends BaseCommand { } // post process - data = GeodeSecurityUtil.postProcess(regionName, key, data); + data = GeodeSecurityUtil.postProcess(regionName, key, data, entry.isObject); long oldStart = start; start = DistributionStats.getStatTime(); http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/90e00bf9/geode-core/src/main/java/com/gemstone/gemfire/internal/cache/tier/sockets/command/GetAll.java ---------------------------------------------------------------------- diff --git a/geode-core/src/main/java/com/gemstone/gemfire/internal/cache/tier/sockets/command/GetAll.java b/geode-core/src/main/java/com/gemstone/gemfire/internal/cache/tier/sockets/command/GetAll.java index 5ae5d12..ea860d3 100755 --- a/geode-core/src/main/java/com/gemstone/gemfire/internal/cache/tier/sockets/command/GetAll.java +++ b/geode-core/src/main/java/com/gemstone/gemfire/internal/cache/tier/sockets/command/GetAll.java @@ -242,7 +242,7 @@ public class GetAll extends BaseCommand { } // post process - value = GeodeSecurityUtil.postProcess(regionName, key, value); + value = GeodeSecurityUtil.postProcess(regionName, key, value, isObject); if (logger.isDebugEnabled()) { logger.debug("{}: Returning value for key={}: {}", servConn.getName(), key, value); http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/90e00bf9/geode-core/src/main/java/com/gemstone/gemfire/internal/cache/tier/sockets/command/GetAll651.java ---------------------------------------------------------------------- diff --git a/geode-core/src/main/java/com/gemstone/gemfire/internal/cache/tier/sockets/command/GetAll651.java b/geode-core/src/main/java/com/gemstone/gemfire/internal/cache/tier/sockets/command/GetAll651.java index 5b278e3..d696bf6 100644 --- a/geode-core/src/main/java/com/gemstone/gemfire/internal/cache/tier/sockets/command/GetAll651.java +++ b/geode-core/src/main/java/com/gemstone/gemfire/internal/cache/tier/sockets/command/GetAll651.java @@ -242,7 +242,7 @@ public class GetAll651 extends BaseCommand { } } - value = GeodeSecurityUtil.postProcess(regionName, key, value); + value = GeodeSecurityUtil.postProcess(regionName, key, value, isObject); if (isDebugEnabled) { logger.debug("{}: Returning value for key={}: {}", servConn.getName(), key, value); http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/90e00bf9/geode-core/src/main/java/com/gemstone/gemfire/internal/cache/tier/sockets/command/GetAll70.java ---------------------------------------------------------------------- diff --git a/geode-core/src/main/java/com/gemstone/gemfire/internal/cache/tier/sockets/command/GetAll70.java b/geode-core/src/main/java/com/gemstone/gemfire/internal/cache/tier/sockets/command/GetAll70.java index c1ab7a9..673a061 100644 --- a/geode-core/src/main/java/com/gemstone/gemfire/internal/cache/tier/sockets/command/GetAll70.java +++ b/geode-core/src/main/java/com/gemstone/gemfire/internal/cache/tier/sockets/command/GetAll70.java @@ -272,7 +272,7 @@ public class GetAll70 extends BaseCommand { } } - data = GeodeSecurityUtil.postProcess(regionName, key, data); + data = GeodeSecurityUtil.postProcess(regionName, key, data, entry.isObject); // Add the entry to the list that will be returned to the client if (keyNotPresent) { http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/90e00bf9/geode-core/src/main/java/com/gemstone/gemfire/internal/security/GeodeSecurityUtil.java ---------------------------------------------------------------------- diff --git a/geode-core/src/main/java/com/gemstone/gemfire/internal/security/GeodeSecurityUtil.java b/geode-core/src/main/java/com/gemstone/gemfire/internal/security/GeodeSecurityUtil.java index 3694d2c..958fc7a 100644 --- a/geode-core/src/main/java/com/gemstone/gemfire/internal/security/GeodeSecurityUtil.java +++ b/geode-core/src/main/java/com/gemstone/gemfire/internal/security/GeodeSecurityUtil.java @@ -18,6 +18,7 @@ package com.gemstone.gemfire.internal.security; import static com.gemstone.gemfire.distributed.ConfigurationProperties.*; +import java.io.IOException; import java.lang.reflect.Method; import java.security.AccessController; import java.security.Principal; @@ -25,6 +26,7 @@ import java.util.Properties; import java.util.Set; import java.util.concurrent.Callable; +import org.apache.commons.lang.SerializationException; import org.apache.commons.lang.StringUtils; import org.apache.geode.security.ResourcePermission; import org.apache.geode.security.ResourcePermission.Operation; @@ -44,10 +46,13 @@ import org.apache.shiro.subject.support.SubjectThreadState; import org.apache.shiro.util.ThreadContext; import org.apache.shiro.util.ThreadState; +import com.gemstone.gemfire.GemFireIOException; import com.gemstone.gemfire.internal.ClassLoadUtil; +import com.gemstone.gemfire.internal.cache.EntryEventImpl; import com.gemstone.gemfire.internal.logging.LogService; import com.gemstone.gemfire.internal.security.shiro.CustomAuthRealm; import com.gemstone.gemfire.internal.security.shiro.ShiroPrincipal; +import com.gemstone.gemfire.internal.util.BlobHelper; import com.gemstone.gemfire.management.internal.security.ResourceOperation; import com.gemstone.gemfire.security.AuthenticationFailedException; import com.gemstone.gemfire.security.GemFireSecurityException; @@ -360,17 +365,38 @@ public class GeodeSecurityUtil { return (isIntegratedSecurity && postProcessor != null); } - public static Object postProcess(String regionPath, Object key, Object result){ - if(postProcessor == null) - return result; + public static Object postProcess(String regionPath, Object key, Object value, boolean valueIsSerialized){ + if(!needPostProcess()) + return value; Subject subject = getSubject(); if(subject == null) - return result; + return value; String regionName = StringUtils.stripStart(regionPath, "/"); - return postProcessor.processRegionValue((Principal)subject.getPrincipal(), regionName, key, result); + Object newValue = null; + + // if the data is a byte array, but the data itself is supposed to be an object, we need to desearized it before we pass + // it to the callback. + if (valueIsSerialized && value instanceof byte[]) { + try { + Object oldObj = EntryEventImpl.deserialize((byte[]) value); + Object newObj = postProcessor.processRegionValue((Principal)subject.getPrincipal(), regionName, key, oldObj); + newValue = BlobHelper.serializeToBlob(newObj); + } catch (IOException|SerializationException e) { + throw new GemFireIOException("Exception de/serializing entry value", e); + } + } + else { + newValue = postProcessor.processRegionValue((Principal) subject.getPrincipal(), regionName, key, value); + } + + return newValue; + } + + private static void checkSameClass(Object obj1, Object obj2){ + } /** @@ -441,6 +467,10 @@ public class GeodeSecurityUtil { return securityManager; } + public static PostProcessor getPostProcessor() { + return postProcessor; + } + public static boolean isClientSecurityRequired() { return isClientAuthenticator || isIntegratedSecurity; } http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/90e00bf9/geode-core/src/main/java/com/gemstone/gemfire/management/internal/cli/commands/DataCommands.java ---------------------------------------------------------------------- diff --git a/geode-core/src/main/java/com/gemstone/gemfire/management/internal/cli/commands/DataCommands.java b/geode-core/src/main/java/com/gemstone/gemfire/management/internal/cli/commands/DataCommands.java index bdbaa15..4b39c4a 100644 --- a/geode-core/src/main/java/com/gemstone/gemfire/management/internal/cli/commands/DataCommands.java +++ b/geode-core/src/main/java/com/gemstone/gemfire/management/internal/cli/commands/DataCommands.java @@ -1070,9 +1070,6 @@ public class DataCommands implements CommandMarker { if (valueClass != null) dataResult.setValueClass(valueClass); - Object result = GeodeSecurityUtil.postProcess(regionPath, key, dataResult.getGetResult()); - dataResult.setGetResult(result); - return makePresentationResult(dataResult); } http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/90e00bf9/geode-core/src/main/java/com/gemstone/gemfire/management/internal/cli/functions/DataCommandFunction.java ---------------------------------------------------------------------- diff --git a/geode-core/src/main/java/com/gemstone/gemfire/management/internal/cli/functions/DataCommandFunction.java b/geode-core/src/main/java/com/gemstone/gemfire/management/internal/cli/functions/DataCommandFunction.java index ed119a5..724a1d4 100644 --- a/geode-core/src/main/java/com/gemstone/gemfire/management/internal/cli/functions/DataCommandFunction.java +++ b/geode-core/src/main/java/com/gemstone/gemfire/management/internal/cli/functions/DataCommandFunction.java @@ -251,6 +251,9 @@ public class DataCommandFunction extends FunctionAdapter implements InternalEnt SelectResults selectResults = (SelectResults) results; for (Iterator iter = selectResults.iterator(); iter.hasNext();) { Object object = iter.next(); + // Post processing + object = GeodeSecurityUtil.postProcess(null, null, object, false); + if (object instanceof Struct) { StructImpl impl = (StructImpl) object; GfJsonObject jsonStruct = getJSONForStruct(impl, nestedObjectCount); @@ -451,6 +454,11 @@ public class DataCommandFunction extends FunctionAdapter implements InternalEnt if (doGet || region.containsKey(keyObject)) { Object value= region.get(keyObject); + + // run it through post processor. region.get will return the deserialized object already, so we don't need to + // deserialize it anymore to pass it to the postProcessor + value = GeodeSecurityUtil.postProcess(regionName, keyObject, value, false); + if (logger.isDebugEnabled()) logger.debug("Get for key {} value {}", key, value); //return DataCommandResult.createGetResult(key, value, null, null); @@ -676,8 +684,9 @@ public class DataCommandFunction extends FunctionAdapter implements InternalEnt else{ array[0] = obj.getClass().getCanonicalName(); Class klass = obj.getClass(); - if(JsonUtil.isPrimitiveOrWrapper(klass)) + if(JsonUtil.isPrimitiveOrWrapper(klass)) { array[1] = obj; + } else if (obj instanceof PdxInstance){ String str = pdxToJson((PdxInstance)obj); array[1] = str; @@ -933,22 +942,6 @@ public class DataCommandFunction extends FunctionAdapter implements InternalEnt request.setQuery(query); dataResult = DataCommands.callFunctionForRegion(request, function, members); dataResult.setInputQuery(query); - - // post process, iterate through the result for post processing - if(GeodeSecurityUtil.needPostProcess()) { - List<SelectResultRow> rows = dataResult.getSelectResult(); - for (Iterator<SelectResultRow> itr = rows.iterator(); itr.hasNext(); ) { - SelectResultRow row = itr.next(); - Object newValue = GeodeSecurityUtil.postProcess(null, null, row.getValue()); - // user is not supposed to see this row - if (newValue == null) { - itr.remove(); - } else { - row.setValue(newValue); - } - } - } - return (dataResult); } else { return (dataResult = DataCommandResult.createSelectInfoResult(null, null, -1, null, http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/90e00bf9/geode-core/src/main/java/com/gemstone/gemfire/management/internal/cli/json/GfJsonObject.java ---------------------------------------------------------------------- diff --git a/geode-core/src/main/java/com/gemstone/gemfire/management/internal/cli/json/GfJsonObject.java b/geode-core/src/main/java/com/gemstone/gemfire/management/internal/cli/json/GfJsonObject.java index 1849066..bcde0a7 100644 --- a/geode-core/src/main/java/com/gemstone/gemfire/management/internal/cli/json/GfJsonObject.java +++ b/geode-core/src/main/java/com/gemstone/gemfire/management/internal/cli/json/GfJsonObject.java @@ -51,6 +51,22 @@ public class GfJsonObject { this.jsonObject = (JSONObject) bean; } else { this.jsonObject = new JSONObject(bean); + // If we want to print out the values of the primitive arrays and report back +// Class klass = bean.getClass(); +// if(klass.isArray() && klass.getComponentType().isPrimitive()){ +// String str = ""; +// int length = Array.getLength(bean); +// for (int i = 0; i < length; i++) { +// if(i==0) +// str += (Array.get(bean, i)); +// else +// str +=(","+Array.get(bean, i)); +// } +// try { +// this.jsonObject.put("Value", str); +// } catch (JSONException ignore) { +// } +// } } if (checkCyclicDep) { JSONObject.cyclicDepChkEnabled.set(false); http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/90e00bf9/geode-core/src/test/java/com/gemstone/gemfire/security/AbstractIntegratedClientAuthDistributedTest.java ---------------------------------------------------------------------- diff --git a/geode-core/src/test/java/com/gemstone/gemfire/security/AbstractIntegratedClientAuthDistributedTest.java b/geode-core/src/test/java/com/gemstone/gemfire/security/AbstractIntegratedClientAuthDistributedTest.java index feda4b4..65cc98f 100644 --- a/geode-core/src/test/java/com/gemstone/gemfire/security/AbstractIntegratedClientAuthDistributedTest.java +++ b/geode-core/src/test/java/com/gemstone/gemfire/security/AbstractIntegratedClientAuthDistributedTest.java @@ -18,8 +18,10 @@ package com.gemstone.gemfire.security; import static com.gemstone.gemfire.distributed.ConfigurationProperties.*; import static org.assertj.core.api.Assertions.*; -import static org.junit.Assert.*; +import java.util.HashMap; +import java.util.Map; +import java.util.Map.Entry; import java.util.Properties; import org.apache.geode.security.templates.SampleSecurityManager; @@ -27,6 +29,7 @@ import org.assertj.core.api.ThrowableAssert.ThrowingCallable; import org.junit.Before; import com.gemstone.gemfire.cache.Cache; +import com.gemstone.gemfire.cache.CacheFactory; import com.gemstone.gemfire.cache.Region; import com.gemstone.gemfire.cache.RegionShortcut; import com.gemstone.gemfire.cache.client.ClientCache; @@ -48,9 +51,19 @@ public class AbstractIntegratedClientAuthDistributedTest extends JUnit4CacheTest protected VM client3 = null; protected int serverPort; protected Class postProcessor = null; + protected boolean pdxPersistent = false; + protected int jmxPort = 0; + protected Map<String, Object> values; + + public AbstractIntegratedClientAuthDistributedTest(){ + values = new HashMap(); + for(int i=0; i<5; i++){ + values.put("key"+i, "value"+i); + } + } @Before - public void before() throws Exception{ + public void before() throws Exception { final Host host = Host.getHost(0); this.client1 = host.getVM(1); this.client2 = host.getVM(2); @@ -58,17 +71,28 @@ public class AbstractIntegratedClientAuthDistributedTest extends JUnit4CacheTest Properties props = new Properties(); props.setProperty(SampleSecurityManager.SECURITY_JSON, "com/gemstone/gemfire/management/internal/security/clientServer.json"); + props.setProperty(SECURITY_MANAGER, SampleSecurityManager.class.getName()); props.setProperty(LOCATORS, ""); props.setProperty(MCAST_PORT, "0"); if (postProcessor!=null) { props.setProperty(SECURITY_POST_PROCESSOR, postProcessor.getName()); } props.setProperty(SECURITY_LOG_LEVEL, "finest"); - props.setProperty(SECURITY_MANAGER, SampleSecurityManager.class.getName()); + + props.setProperty("security-pdx", pdxPersistent+""); + if(jmxPort>0){ + props.put(JMX_MANAGER, "true"); + props.put(JMX_MANAGER_START, "true"); + props.put(JMX_MANAGER_PORT, String.valueOf(jmxPort)); + } getSystem(props); - Cache cache = getCache(); + CacheFactory cf = null; + cf = new CacheFactory(); + cf.setPdxPersistent(pdxPersistent); + cf.setPdxReadSerialized(pdxPersistent); + Cache cache = getCache(cf); Region region = cache.createRegionFactory(RegionShortcut.REPLICATE).create(REGION_NAME); @@ -78,12 +102,9 @@ public class AbstractIntegratedClientAuthDistributedTest extends JUnit4CacheTest this.serverPort = server1.getPort(); - for (int i = 0; i < 5; i++) { - String key = "key" + i; - String value = "value" + i; - region.put(key, value); + for(Entry entry:values.entrySet()){ + region.put(entry.getKey(), entry.getValue()); } - assertEquals(5, region.size()); } @Override http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/90e00bf9/geode-core/src/test/java/com/gemstone/gemfire/security/IntegratedSecurityPostProcessorDUnitTest.java ---------------------------------------------------------------------- diff --git a/geode-core/src/test/java/com/gemstone/gemfire/security/IntegratedSecurityPostProcessorDUnitTest.java b/geode-core/src/test/java/com/gemstone/gemfire/security/IntegratedSecurityPostProcessorDUnitTest.java index 0568659..b3fb16e 100644 --- a/geode-core/src/test/java/com/gemstone/gemfire/security/IntegratedSecurityPostProcessorDUnitTest.java +++ b/geode-core/src/test/java/com/gemstone/gemfire/security/IntegratedSecurityPostProcessorDUnitTest.java @@ -22,6 +22,7 @@ import java.util.ArrayList; import java.util.List; import java.util.Map; +import org.apache.geode.security.templates.SamplePostProcessor; import org.junit.Test; import org.junit.experimental.categories.Category; @@ -35,7 +36,6 @@ import com.gemstone.gemfire.cache.client.Pool; import com.gemstone.gemfire.cache.client.PoolManager; import com.gemstone.gemfire.cache.query.SelectResults; import com.gemstone.gemfire.cache.util.CacheListenerAdapter; -import org.apache.geode.security.templates.SamplePostProcessor; import com.gemstone.gemfire.test.junit.categories.DistributedTest; import com.gemstone.gemfire.test.junit.categories.SecurityTest; @@ -47,7 +47,7 @@ public class IntegratedSecurityPostProcessorDUnitTest extends AbstractIntegrated } @Test - public void testPostProcess(){ + public void testPostProcessRegionGet(){ List<String> keys = new ArrayList<>(); keys.add("key1"); keys.add("key2"); @@ -65,6 +65,14 @@ public class IntegratedSecurityPostProcessorDUnitTest extends AbstractIntegrated assertEquals(2, values.size()); assertEquals("super-user/AuthRegion/key1/value1", values.get("key1")); assertEquals("super-user/AuthRegion/key2/value2", values.get("key2")); + }); + } + + @Test + public void testPostProcessQuery(){ + client1.invoke(()->{ + ClientCache cache = createClientCache("super-user", "1234567", serverPort); + Region region = cache.getRegion(REGION_NAME); // post process for query String query = "select * from /AuthRegion"; http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/90e00bf9/geode-cq/src/test/java/com/gemstone/gemfire/security/ClientQueryAuthDistributedTest.java ---------------------------------------------------------------------- diff --git a/geode-cq/src/test/java/com/gemstone/gemfire/security/ClientQueryAuthDistributedTest.java b/geode-cq/src/test/java/com/gemstone/gemfire/security/ClientQueryAuthDistributedTest.java new file mode 100644 index 0000000..2cdef1b --- /dev/null +++ b/geode-cq/src/test/java/com/gemstone/gemfire/security/ClientQueryAuthDistributedTest.java @@ -0,0 +1,122 @@ +/* + * 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 com.gemstone.gemfire.security; + +import org.junit.Test; +import org.junit.experimental.categories.Category; + +import com.gemstone.gemfire.cache.Region; +import com.gemstone.gemfire.cache.client.ClientCache; +import com.gemstone.gemfire.cache.client.Pool; +import com.gemstone.gemfire.cache.client.PoolManager; +import com.gemstone.gemfire.cache.query.CqAttributes; +import com.gemstone.gemfire.cache.query.CqAttributesFactory; +import com.gemstone.gemfire.cache.query.CqEvent; +import com.gemstone.gemfire.cache.query.CqListener; +import com.gemstone.gemfire.cache.query.CqQuery; +import com.gemstone.gemfire.cache.query.QueryService; +import com.gemstone.gemfire.test.junit.categories.DistributedTest; +import com.gemstone.gemfire.test.junit.categories.SecurityTest; + +@Category({ DistributedTest.class, SecurityTest.class }) +public class ClientQueryAuthDistributedTest extends AbstractIntegratedClientAuthDistributedTest { + + @Test + public void testQuery(){ + client1.invoke(()-> { + ClientCache cache = createClientCache("stranger", "1234567", serverPort); + final Region region = cache.getRegion(REGION_NAME); + + String query = "select * from /AuthRegion"; + assertNotAuthorized(()->region.query(query), "DATA:READ:AuthRegion"); + + Pool pool = PoolManager.find(region); + assertNotAuthorized(()->pool.getQueryService().newQuery(query).execute(), "DATA:READ:AuthRegion"); + }); + } + + @Test + public void testCQ(){ + String query = "select * from /AuthRegion"; + client1.invoke(()-> { + ClientCache cache =createClientCache("stranger", "1234567", serverPort); + Region region = cache.getRegion(REGION_NAME); + Pool pool = PoolManager.find(region); + QueryService qs = pool.getQueryService(); + + CqAttributes cqa = new CqAttributesFactory().create(); + + // Create the CqQuery + CqQuery cq = qs.newCq("CQ1", query, cqa); + + assertNotAuthorized(()->cq.executeWithInitialResults(), "DATA:READ:AuthRegion"); + assertNotAuthorized(()->cq.execute(), "DATA:READ:AuthRegion"); + + assertNotAuthorized(()->cq.close(), "DATA:MANAGE"); + }); + + client2.invoke(()-> { + ClientCache cache =createClientCache("authRegionReader", "1234567", serverPort); + Region region = cache.getRegion(REGION_NAME); + Pool pool = PoolManager.find(region); + QueryService qs = pool.getQueryService(); + + CqAttributes cqa = new CqAttributesFactory().create(); + // Create the CqQuery + CqQuery cq = qs.newCq("CQ1", query, cqa); + cq.execute(); + + assertNotAuthorized(()->cq.stop(), "DATA:MANAGE"); + assertNotAuthorized(()->qs.getAllDurableCqsFromServer(), "CLUSTER:READ"); + }); + + client3.invoke(()-> { + ClientCache cache =createClientCache("super-user", "1234567", serverPort); + Region region = cache.getRegion(REGION_NAME); + Pool pool = PoolManager.find(region); + QueryService qs = pool.getQueryService(); + + CqAttributesFactory factory = new CqAttributesFactory(); + factory.addCqListener(new CqListener() { + @Override + public void onEvent(final CqEvent aCqEvent) { + System.out.println(aCqEvent); + } + + @Override + public void onError(final CqEvent aCqEvent) { + + } + + @Override + public void close() { + + } + }); + + + CqAttributes cqa = factory.create(); + + // Create the CqQuery + CqQuery cq = qs.newCq("CQ1", query, cqa); + System.out.println("query result: "+cq.executeWithInitialResults()); + + cq.stop(); + }); + } + +} http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/90e00bf9/geode-cq/src/test/java/com/gemstone/gemfire/security/IntegratedClientQueryAuthDistributedTest.java ---------------------------------------------------------------------- diff --git a/geode-cq/src/test/java/com/gemstone/gemfire/security/IntegratedClientQueryAuthDistributedTest.java b/geode-cq/src/test/java/com/gemstone/gemfire/security/IntegratedClientQueryAuthDistributedTest.java deleted file mode 100644 index d9b69b7..0000000 --- a/geode-cq/src/test/java/com/gemstone/gemfire/security/IntegratedClientQueryAuthDistributedTest.java +++ /dev/null @@ -1,122 +0,0 @@ -/* - * 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 com.gemstone.gemfire.security; - -import org.junit.Test; -import org.junit.experimental.categories.Category; - -import com.gemstone.gemfire.cache.Region; -import com.gemstone.gemfire.cache.client.ClientCache; -import com.gemstone.gemfire.cache.client.Pool; -import com.gemstone.gemfire.cache.client.PoolManager; -import com.gemstone.gemfire.cache.query.CqAttributes; -import com.gemstone.gemfire.cache.query.CqAttributesFactory; -import com.gemstone.gemfire.cache.query.CqEvent; -import com.gemstone.gemfire.cache.query.CqListener; -import com.gemstone.gemfire.cache.query.CqQuery; -import com.gemstone.gemfire.cache.query.QueryService; -import com.gemstone.gemfire.test.junit.categories.DistributedTest; -import com.gemstone.gemfire.test.junit.categories.SecurityTest; - -@Category({ DistributedTest.class, SecurityTest.class }) -public class IntegratedClientQueryAuthDistributedTest extends AbstractIntegratedClientAuthDistributedTest { - - @Test - public void testQuery(){ - client1.invoke(()-> { - ClientCache cache = createClientCache("stranger", "1234567", serverPort); - final Region region = cache.getRegion(REGION_NAME); - - String query = "select * from /AuthRegion"; - assertNotAuthorized(()->region.query(query), "DATA:READ:AuthRegion"); - - Pool pool = PoolManager.find(region); - assertNotAuthorized(()->pool.getQueryService().newQuery(query).execute(), "DATA:READ:AuthRegion"); - }); - } - - @Test - public void testCQ(){ - String query = "select * from /AuthRegion"; - client1.invoke(()-> { - ClientCache cache =createClientCache("stranger", "1234567", serverPort); - Region region = cache.getRegion(REGION_NAME); - Pool pool = PoolManager.find(region); - QueryService qs = pool.getQueryService(); - - CqAttributes cqa = new CqAttributesFactory().create(); - - // Create the CqQuery - CqQuery cq = qs.newCq("CQ1", query, cqa); - - assertNotAuthorized(()->cq.executeWithInitialResults(), "DATA:READ:AuthRegion"); - assertNotAuthorized(()->cq.execute(), "DATA:READ:AuthRegion"); - - assertNotAuthorized(()->cq.close(), "DATA:MANAGE"); - }); - - client2.invoke(()-> { - ClientCache cache =createClientCache("authRegionReader", "1234567", serverPort); - Region region = cache.getRegion(REGION_NAME); - Pool pool = PoolManager.find(region); - QueryService qs = pool.getQueryService(); - - CqAttributes cqa = new CqAttributesFactory().create(); - // Create the CqQuery - CqQuery cq = qs.newCq("CQ1", query, cqa); - cq.execute(); - - assertNotAuthorized(()->cq.stop(), "DATA:MANAGE"); - assertNotAuthorized(()->qs.getAllDurableCqsFromServer(), "CLUSTER:READ"); - }); - - client3.invoke(()-> { - ClientCache cache =createClientCache("super-user", "1234567", serverPort); - Region region = cache.getRegion(REGION_NAME); - Pool pool = PoolManager.find(region); - QueryService qs = pool.getQueryService(); - - CqAttributesFactory factory = new CqAttributesFactory(); - factory.addCqListener(new CqListener() { - @Override - public void onEvent(final CqEvent aCqEvent) { - System.out.println(aCqEvent); - } - - @Override - public void onError(final CqEvent aCqEvent) { - - } - - @Override - public void close() { - - } - }); - - - CqAttributes cqa = factory.create(); - - // Create the CqQuery - CqQuery cq = qs.newCq("CQ1", query, cqa); - System.out.println("query result: "+cq.executeWithInitialResults()); - - cq.stop(); - }); - } - -} http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/90e00bf9/geode-cq/src/test/java/com/gemstone/gemfire/security/PDXPostProcessorDUnitTest.java ---------------------------------------------------------------------- diff --git a/geode-cq/src/test/java/com/gemstone/gemfire/security/PDXPostProcessorDUnitTest.java b/geode-cq/src/test/java/com/gemstone/gemfire/security/PDXPostProcessorDUnitTest.java new file mode 100644 index 0000000..671882e --- /dev/null +++ b/geode-cq/src/test/java/com/gemstone/gemfire/security/PDXPostProcessorDUnitTest.java @@ -0,0 +1,323 @@ +/* + * 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 com.gemstone.gemfire.security; + +import static org.junit.Assert.*; + +import java.security.Principal; +import java.util.Arrays; +import java.util.Collection; +import java.util.HashMap; +import java.util.Iterator; +import java.util.Properties; +import java.util.concurrent.TimeUnit; + +import com.jayway.awaitility.Awaitility; +import org.apache.geode.security.PostProcessor; +import org.junit.Test; +import org.junit.experimental.categories.Category; +import org.junit.runner.RunWith; +import org.junit.runners.Parameterized; + +import com.gemstone.gemfire.cache.EntryEvent; +import com.gemstone.gemfire.cache.Region; +import com.gemstone.gemfire.cache.client.ClientCache; +import com.gemstone.gemfire.cache.client.ClientCacheFactory; +import com.gemstone.gemfire.cache.client.ClientRegionFactory; +import com.gemstone.gemfire.cache.client.ClientRegionShortcut; +import com.gemstone.gemfire.cache.client.Pool; +import com.gemstone.gemfire.cache.client.PoolManager; +import com.gemstone.gemfire.cache.query.CqAttributes; +import com.gemstone.gemfire.cache.query.CqAttributesFactory; +import com.gemstone.gemfire.cache.query.CqEvent; +import com.gemstone.gemfire.cache.query.CqQuery; +import com.gemstone.gemfire.cache.query.CqResults; +import com.gemstone.gemfire.cache.query.QueryService; +import com.gemstone.gemfire.cache.query.SelectResults; +import com.gemstone.gemfire.cache.query.internal.cq.CqListenerImpl; +import com.gemstone.gemfire.cache.util.CacheListenerAdapter; +import com.gemstone.gemfire.internal.AvailablePortHelper; +import com.gemstone.gemfire.internal.cache.EntryEventImpl; +import com.gemstone.gemfire.internal.security.GeodeSecurityUtil; +import com.gemstone.gemfire.management.cli.Result.Status; +import com.gemstone.gemfire.management.internal.cli.CliUtil; +import com.gemstone.gemfire.management.internal.cli.HeadlessGfsh; +import com.gemstone.gemfire.management.internal.cli.i18n.CliStrings; +import com.gemstone.gemfire.management.internal.cli.result.CommandResult; +import com.gemstone.gemfire.management.internal.cli.util.CommandStringBuilder; +import com.gemstone.gemfire.pdx.SimpleClass; +import com.gemstone.gemfire.pdx.internal.PdxInstanceImpl; +import com.gemstone.gemfire.test.junit.categories.DistributedTest; +import com.gemstone.gemfire.test.junit.categories.SecurityTest; +import com.gemstone.gemfire.test.junit.runners.CategoryWithParameterizedRunnerFactory; + +@Category({ DistributedTest.class, SecurityTest.class }) +@RunWith(Parameterized.class) +@Parameterized.UseParametersRunnerFactory(CategoryWithParameterizedRunnerFactory.class) +public class PDXPostProcessorDUnitTest extends AbstractIntegratedClientAuthDistributedTest { + private static byte[] BYTES = {1,0}; + + @Parameterized.Parameters + public static Collection<Object[]> parameters(){ + Object[][] params = {{true}, {false}}; + return Arrays.asList(params); + } + + public PDXPostProcessorDUnitTest(boolean pdxPersistent){ + this.postProcessor = PDXPostProcessor.class; + this.pdxPersistent = pdxPersistent; + this.jmxPort = AvailablePortHelper.getRandomAvailableTCPPort(); + values = new HashMap(); + } + + @Test + public void testRegionGet(){ + client2.invoke(()->{ + ClientCache cache = createClientCache("super-user", "1234567", serverPort); + Region region = cache.getRegion(REGION_NAME); + // put in a value that's a domain object + region.put("key1", new SimpleClass(1, (byte) 1)); + // put in a byte value + region.put("key2", BYTES); + }); + + client1.invoke(()->{ + ClientCache cache = createClientCache("super-user", "1234567", serverPort); + Region region = cache.getRegion(REGION_NAME); + + // post process for get the client domain object + Object value = region.get("key1"); + assertTrue(value instanceof SimpleClass); + + // post process for get the raw byte value + value = region.get("key2"); + assertTrue(Arrays.equals(BYTES, (byte[])value)); + }); + + // this makes sure PostProcessor is getting called + PDXPostProcessor pp = (PDXPostProcessor) GeodeSecurityUtil.getPostProcessor(); + assertEquals(pp.getCount(), 2); + } + + @Test + public void testQuery(){ + client2.invoke(()->{ + ClientCache cache = createClientCache("super-user", "1234567", serverPort); + Region region = cache.getRegion(REGION_NAME); + // put in a value that's a domain object + region.put("key1", new SimpleClass(1, (byte) 1)); + region.put("key2", BYTES); + }); + + client1.invoke(()->{ + ClientCache cache = createClientCache("super-user", "1234567", serverPort); + Region region = cache.getRegion(REGION_NAME); + + // post process for query + String query = "select * from /AuthRegion"; + SelectResults result = region.query(query); + + Iterator itr = result.iterator(); + while (itr.hasNext()) { + Object obj = itr.next(); + if(obj instanceof byte[]){ + assertTrue(Arrays.equals(BYTES, (byte[])obj)); + } + else{ + assertTrue(obj instanceof SimpleClass); + } + } + }); + + // this makes sure PostProcessor is getting called + PDXPostProcessor pp = (PDXPostProcessor) GeodeSecurityUtil.getPostProcessor(); + assertEquals(pp.getCount(), 2); + } + + @Test + public void testRegisterInterest(){ + client1.invoke(()->{ + ClientCache cache = new ClientCacheFactory(createClientProperties("super-user", "1234567")) + .setPoolSubscriptionEnabled(true) + .addPoolServer("localhost", serverPort) + .create(); + + ClientRegionFactory factory = cache.createClientRegionFactory(ClientRegionShortcut.PROXY); + factory.addCacheListener(new CacheListenerAdapter() { + @Override + public void afterUpdate(EntryEvent event) { + Object key = event.getKey(); + Object value = ((EntryEventImpl) event).getDeserializedValue(); + if(key.equals("key1")) { + assertTrue(value instanceof SimpleClass); + } + else if(key.equals("key2")){ + assertTrue(Arrays.equals(BYTES, (byte[])value)); + } + } + }); + + Region region = factory.create(REGION_NAME); + region.put("key1", "value1"); + region.registerInterest("key1"); + region.registerInterest("key2"); + }); + + client2.invoke(()->{ + ClientCache cache = createClientCache("dataUser", "1234567", serverPort); + Region region = cache.getRegion(REGION_NAME); + // put in a value that's a domain object + region.put("key1", new SimpleClass(1, (byte) 1)); + region.put("key2", BYTES); + }); + + // wait for events to fire + Awaitility.await().atMost(1, TimeUnit.SECONDS); + PDXPostProcessor pp = (PDXPostProcessor) GeodeSecurityUtil.getPostProcessor(); + assertEquals(pp.getCount(), 2); + } + + @Test + public void testCQ() { + String query = "select * from /AuthRegion"; + client1.invoke(() -> { + ClientCache cache = createClientCache("super-user", "1234567", serverPort); + Region region = cache.getRegion(REGION_NAME); + + Pool pool = PoolManager.find(region); + QueryService qs = pool.getQueryService(); + + CqAttributesFactory factory = new CqAttributesFactory(); + + factory.addCqListener(new CqListenerImpl() { + @Override + public void onEvent(final CqEvent aCqEvent) { + Object key = aCqEvent.getKey(); + Object value = aCqEvent.getNewValue(); + if(key.equals("key1")) { + assertTrue(value instanceof SimpleClass); + } + else if(key.equals("key2")){ + assertTrue(Arrays.equals(BYTES, (byte[])value)); + } + } + }); + + CqAttributes cqa = factory.create(); + + // Create the CqQuery + CqQuery cq = qs.newCq("CQ1", query, cqa); + CqResults results = cq.executeWithInitialResults(); + }); + + client2.invoke(() -> { + ClientCache cache = createClientCache("authRegionUser", "1234567", serverPort); + Region region = cache.getRegion(REGION_NAME); + region.put("key1", new SimpleClass(1, (byte) 1)); + region.put("key2", BYTES); + }); + + // wait for events to fire + Awaitility.await().atMost(1, TimeUnit.SECONDS); + PDXPostProcessor pp = (PDXPostProcessor) GeodeSecurityUtil.getPostProcessor(); + assertEquals(pp.getCount(), 2); + } + + @Test + public void testGfshCommand(){ + // have client2 input some domain data into the region + client2.invoke(()->{ + ClientCache cache = createClientCache("super-user", "1234567", serverPort); + Region region = cache.getRegion(REGION_NAME); + // put in a value that's a domain object + region.put("key1", new SimpleClass(1, (byte) 1)); + // put in a byte value + region.put("key2", BYTES); + }); + + client1.invoke(()->{ + CliUtil.isGfshVM = true; + String shellId = getClass().getSimpleName(); + HeadlessGfsh gfsh = new HeadlessGfsh(shellId, 30, "gfsh_files"); + + // connect to the jmx server + final CommandStringBuilder connectCommand = new CommandStringBuilder(CliStrings.CONNECT); + connectCommand.addOption(CliStrings.CONNECT__USERNAME, "dataUser"); + connectCommand.addOption(CliStrings.CONNECT__PASSWORD, "1234567"); + + String endpoint = "localhost[" + jmxPort + "]"; + connectCommand.addOption(CliStrings.CONNECT__JMX_MANAGER, endpoint); + + gfsh.executeCommand(connectCommand.toString()); + CommandResult result = (CommandResult) gfsh.getResult(); + + // get command + gfsh.executeCommand("get --key=key1 --region=AuthRegion"); + result = (CommandResult) gfsh.getResult(); + assertEquals(result.getStatus(), Status.OK); + if(pdxPersistent) + assertTrue(result.getContent().toString().contains("com.gemstone.gemfire.pdx.internal.PdxInstanceImpl")); + else + assertTrue(result.getContent().toString().contains("SimpleClass")); + + gfsh.executeCommand("get --key=key2 --region=AuthRegion"); + result = (CommandResult)gfsh.getResult(); + assertEquals(result.getStatus(), Status.OK); + assertTrue(result.getContent().toString().contains("byte[]")); + + gfsh.executeCommand("query --query=\"select * from /AuthRegion\""); + result = (CommandResult)gfsh.getResult(); + System.out.println("gfsh result: " + result); + }); + + PDXPostProcessor pp = (PDXPostProcessor) GeodeSecurityUtil.getPostProcessor(); + assertEquals(pp.getCount(), 4); + } + + public static class PDXPostProcessor implements PostProcessor{ + private boolean pdx = false; + private int count = 0; + + public void init(Properties props){ + pdx = Boolean.parseBoolean(props.getProperty("security-pdx")); + count = 0; + } + @Override + public Object processRegionValue(final Principal principal, + final String regionName, + final Object key, + final Object value) { + count ++; + if(value instanceof byte[]){ + assertTrue(Arrays.equals(BYTES, (byte[])value)); + } + else if(pdx){ + assertTrue(value instanceof PdxInstanceImpl); + } + else { + assertTrue(value instanceof SimpleClass); + } + return value; + } + + public int getCount(){ + return count; + } + } + +} http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/90e00bf9/geode-json/src/main/java/org/json/JSONObject.java ---------------------------------------------------------------------- diff --git a/geode-json/src/main/java/org/json/JSONObject.java b/geode-json/src/main/java/org/json/JSONObject.java index 24f5cc7..a2c67a9 100755 --- a/geode-json/src/main/java/org/json/JSONObject.java +++ b/geode-json/src/main/java/org/json/JSONObject.java @@ -32,7 +32,6 @@ import java.lang.reflect.Method; import java.lang.reflect.Modifier; import java.util.Collection; import java.util.Enumeration; -import java.util.HashSet; import java.util.Iterator; import java.util.LinkedHashMap; import java.util.Locale; @@ -95,7 +94,6 @@ import java.util.Set; * @version 2012-05-29 */ public class JSONObject { - /** * JSONObject.NULL is equivalent to the value that JavaScript calls null, * whilst Java's null is equivalent to the value that JavaScript calls @@ -1481,9 +1479,8 @@ public class JSONObject { return object.toString(); } - if(cyclicDepChkEnabled.get() != null){ - if (cyclicDepChkEnabled.get() - && cyclicDependencySet.get().contains(object)) { + if(cyclicDepChkEnabled.get()!=null && cyclicDependencySet.get()!=null){ + if (cyclicDepChkEnabled.get() && cyclicDependencySet.get().contains(object)) { //break cyclic reference return object.getClass().getCanonicalName(); }else {