Repository: incubator-geode
Updated Branches:
  refs/heads/develop 5f8405495 -> 774044eeb


Geode-1569: require principal to be Serializable so that post process can 
happen in a remote server


Project: http://git-wip-us.apache.org/repos/asf/incubator-geode/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-geode/commit/774044ee
Tree: http://git-wip-us.apache.org/repos/asf/incubator-geode/tree/774044ee
Diff: http://git-wip-us.apache.org/repos/asf/incubator-geode/diff/774044ee

Branch: refs/heads/develop
Commit: 774044eeb6a5f1ce4456afda19f1b6b12c9e0cc4
Parents: 5f84054
Author: Jinmei Liao <jil...@pivotal.io>
Authored: Thu Aug 4 16:15:33 2016 -0700
Committer: Jinmei Liao <jil...@pivotal.io>
Committed: Mon Aug 8 08:26:14 2016 -0700

----------------------------------------------------------------------
 .../internal/security/GeodeSecurityUtil.java    |  24 ++--
 .../security/IntegratedSecurityService.java     |   6 +-
 .../internal/security/SecurityService.java      |   6 +-
 .../security/shiro/CustomAuthRealm.java         |   6 +-
 .../internal/cli/commands/DataCommands.java     |   8 +-
 .../internal/cli/domain/DataCommandRequest.java |  10 ++
 .../cli/functions/DataCommandFunction.java      |  20 ++-
 .../apache/geode/security/PostProcessor.java    |   7 +-
 .../apache/geode/security/SecurityManager.java  |   8 +-
 .../security/templates/SamplePostProcessor.java |  12 +-
 .../templates/SampleSecurityManager.java        |  12 +-
 .../security/AbstractSecureServerDUnitTest.java |  16 +--
 .../security/NoShowValue1PostProcessor.java     |   4 +-
 .../PDXGfshPostProcessorOnRemoteServerTest.java | 142 +++++++++++++++++++
 .../gemfire/security/PDXPostProcessor.java      |   6 +-
 .../gemfire/security/SpySecurityManager.java    |   4 +-
 16 files changed, 237 insertions(+), 54 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/774044ee/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 a9c2162..f73790b 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
@@ -19,19 +19,19 @@ package com.gemstone.gemfire.internal.security;
 import static com.gemstone.gemfire.distributed.ConfigurationProperties.*;
 
 import java.io.IOException;
+import java.io.Serializable;
 import java.lang.reflect.Method;
 import java.security.AccessController;
-import java.security.Principal;
 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.PostProcessor;
 import org.apache.geode.security.ResourcePermission;
 import org.apache.geode.security.ResourcePermission.Operation;
 import org.apache.geode.security.ResourcePermission.Resource;
-import org.apache.geode.security.PostProcessor;
 import org.apache.geode.security.SecurityManager;
 import org.apache.logging.log4j.Logger;
 import org.apache.shiro.SecurityUtils;
@@ -366,14 +366,20 @@ public class GeodeSecurityUtil {
   }
 
   public static Object postProcess(String regionPath, Object key, Object 
value, boolean valueIsSerialized){
-    if(!needPostProcess())
-      return value;
-
-    Subject subject = getSubject();
+    return postProcess(null, regionPath, key, value, valueIsSerialized);
+  }
 
-    if(subject == null)
+  public static Object postProcess(Serializable principal, String regionPath, 
Object key, Object value, boolean valueIsSerialized) {
+    if (!needPostProcess())
       return value;
 
+    if (principal == null) {
+      Subject subject = getSubject();
+      if (subject == null)
+        return value;
+      principal = (Serializable) subject.getPrincipal();
+    }
+
     String regionName = StringUtils.stripStart(regionPath, "/");
     Object newValue = null;
 
@@ -382,14 +388,14 @@ public class GeodeSecurityUtil {
     if (valueIsSerialized && value instanceof byte[]) {
       try {
         Object oldObj = EntryEventImpl.deserialize((byte[]) value);
-        Object newObj = 
postProcessor.processRegionValue((Principal)subject.getPrincipal(), regionName, 
key,  oldObj);
+        Object newObj = postProcessor.processRegionValue(principal, 
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);
+      newValue = postProcessor.processRegionValue(principal, regionName, key, 
value);
     }
 
     return newValue;

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/774044ee/geode-core/src/main/java/com/gemstone/gemfire/internal/security/IntegratedSecurityService.java
----------------------------------------------------------------------
diff --git 
a/geode-core/src/main/java/com/gemstone/gemfire/internal/security/IntegratedSecurityService.java
 
b/geode-core/src/main/java/com/gemstone/gemfire/internal/security/IntegratedSecurityService.java
index 84a0c32..30da9bf 100644
--- 
a/geode-core/src/main/java/com/gemstone/gemfire/internal/security/IntegratedSecurityService.java
+++ 
b/geode-core/src/main/java/com/gemstone/gemfire/internal/security/IntegratedSecurityService.java
@@ -19,7 +19,6 @@ package com.gemstone.gemfire.internal.security;
 import java.io.InvalidObjectException;
 import java.io.ObjectInputStream;
 import java.io.Serializable;
-import java.util.List;
 import java.util.Properties;
 import java.util.concurrent.Callable;
 
@@ -171,6 +170,11 @@ public class IntegratedSecurityService implements 
SecurityService, Serializable
   }
 
   @Override
+  public Object postProcess(final Serializable principal, final String 
regionPath, final Object key, final Object value, final boolean 
valueIsSerialized) {
+    return GeodeSecurityUtil.postProcess(principal, regionPath, key, value, 
valueIsSerialized);
+  }
+
+  @Override
   public boolean isClientSecurityRequired() {
     return GeodeSecurityUtil.isClientSecurityRequired();
   }

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/774044ee/geode-core/src/main/java/com/gemstone/gemfire/internal/security/SecurityService.java
----------------------------------------------------------------------
diff --git 
a/geode-core/src/main/java/com/gemstone/gemfire/internal/security/SecurityService.java
 
b/geode-core/src/main/java/com/gemstone/gemfire/internal/security/SecurityService.java
index 9629ba3..b562892 100644
--- 
a/geode-core/src/main/java/com/gemstone/gemfire/internal/security/SecurityService.java
+++ 
b/geode-core/src/main/java/com/gemstone/gemfire/internal/security/SecurityService.java
@@ -16,16 +16,17 @@
  */
 package com.gemstone.gemfire.internal.security;
 
+import java.io.Serializable;
 import java.util.Properties;
 import java.util.concurrent.Callable;
 
-import com.gemstone.gemfire.management.internal.security.ResourceOperation;
-
 import org.apache.geode.security.ResourcePermission;
 import org.apache.geode.security.SecurityManager;
 import org.apache.shiro.subject.Subject;
 import org.apache.shiro.util.ThreadState;
 
+import com.gemstone.gemfire.management.internal.security.ResourceOperation;
+
 public interface SecurityService {
 
   ThreadState bindSubject(Subject subject);
@@ -52,6 +53,7 @@ public interface SecurityService {
   void close();
   boolean needPostProcess();
   Object postProcess(String regionPath, Object key, Object value, boolean 
valueIsSerialized);
+  Object postProcess(Serializable principal, String regionPath, Object key, 
Object value, boolean valueIsSerialized);
   boolean isClientSecurityRequired();
   boolean isPeerSecurityRequired();
   boolean isIntegratedSecurity();

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/774044ee/geode-core/src/main/java/com/gemstone/gemfire/internal/security/shiro/CustomAuthRealm.java
----------------------------------------------------------------------
diff --git 
a/geode-core/src/main/java/com/gemstone/gemfire/internal/security/shiro/CustomAuthRealm.java
 
b/geode-core/src/main/java/com/gemstone/gemfire/internal/security/shiro/CustomAuthRealm.java
index edb0790..b9dd8c0 100644
--- 
a/geode-core/src/main/java/com/gemstone/gemfire/internal/security/shiro/CustomAuthRealm.java
+++ 
b/geode-core/src/main/java/com/gemstone/gemfire/internal/security/shiro/CustomAuthRealm.java
@@ -16,7 +16,7 @@
  */
 package com.gemstone.gemfire.internal.security.shiro;
 
-import java.security.Principal;
+import java.io.Serializable;
 import java.util.Properties;
 
 import org.apache.geode.security.ResourcePermission;
@@ -71,7 +71,7 @@ public class CustomAuthRealm extends AuthorizingRealm {
     credentialProps.put(ResourceConstants.USER_NAME, username);
     credentialProps.put(ResourceConstants.PASSWORD, password);
 
-    Principal principal  = securityManager.authenticate(credentialProps);
+    Serializable principal  = securityManager.authenticate(credentialProps);
 
     try {
       return new SimpleAuthenticationInfo(principal, authToken.getPassword(), 
REALM_NAME);
@@ -89,7 +89,7 @@ public class CustomAuthRealm extends AuthorizingRealm {
   @Override
   public boolean isPermitted(PrincipalCollection principals, Permission 
permission) {
     ResourcePermission context = (ResourcePermission) permission;
-    Principal principal = (Principal) principals.getPrimaryPrincipal();
+    Serializable principal = (Serializable)principals.getPrimaryPrincipal();
     return securityManager.authorize(principal, context);
   }
 

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/774044ee/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 ae87b72..d6ff853 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
@@ -16,6 +16,7 @@
  */
 package com.gemstone.gemfire.management.internal.cli.commands;
 
+import java.io.Serializable;
 import java.util.ArrayList;
 import java.util.HashSet;
 import java.util.Iterator;
@@ -32,6 +33,7 @@ import java.util.concurrent.TimeoutException;
 
 import org.apache.geode.security.ResourcePermission.Operation;
 import org.apache.geode.security.ResourcePermission.Resource;
+import org.apache.shiro.subject.Subject;
 import org.springframework.shell.core.CommandMarker;
 import org.springframework.shell.core.annotation.CliAvailabilityIndicator;
 import org.springframework.shell.core.annotation.CliCommand;
@@ -1060,6 +1062,10 @@ public class DataCommands implements CommandMarker {
         request.setRegionName(regionPath);
         request.setValueClass(valueClass);
         request.setLoadOnCacheMiss(loadOnCacheMiss);
+        Subject subject = this.securityService.getSubject();
+        if(subject!=null){
+          request.setPrincipal((Serializable)subject.getPrincipal());
+        }
         dataResult = callFunctionForRegion(request, getfn, memberList);
       } else
         dataResult = DataCommandResult.createGetInfoResult(key, null, null,
@@ -1067,7 +1073,7 @@ public class DataCommands implements CommandMarker {
                 CliStrings.GET__MSG__REGION_NOT_FOUND_ON_ALL_MEMBERS,
                 regionPath), false);
     } else {
-      dataResult = getfn.get(key, keyClass, valueClass, regionPath, 
loadOnCacheMiss);
+      dataResult = getfn.get(null, key, keyClass, valueClass, regionPath, 
loadOnCacheMiss);
     }
     dataResult.setKeyClass(keyClass);
     if (valueClass != null)

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/774044ee/geode-core/src/main/java/com/gemstone/gemfire/management/internal/cli/domain/DataCommandRequest.java
----------------------------------------------------------------------
diff --git 
a/geode-core/src/main/java/com/gemstone/gemfire/management/internal/cli/domain/DataCommandRequest.java
 
b/geode-core/src/main/java/com/gemstone/gemfire/management/internal/cli/domain/DataCommandRequest.java
index 92d4579..76582c3 100644
--- 
a/geode-core/src/main/java/com/gemstone/gemfire/management/internal/cli/domain/DataCommandRequest.java
+++ 
b/geode-core/src/main/java/com/gemstone/gemfire/management/internal/cli/domain/DataCommandRequest.java
@@ -46,6 +46,7 @@ public class DataCommandRequest implements /*Data*/ 
Serializable{
   private String removeAllKeys;
   private String value;
   private String valueClass;
+  private Serializable principal;
 
   public static final String NEW_LINE = System.getProperty("line.separator");
 
@@ -135,6 +136,9 @@ public class DataCommandRequest implements /*Data*/ 
Serializable{
   public boolean isLoadOnCacheMiss() {
     return loadOnCacheMiss;
   }
+  public Serializable getPrincipal() {
+    return principal;
+  }
 
   public void setKey(String key) {
     this.key = key;
@@ -180,6 +184,10 @@ public class DataCommandRequest implements /*Data*/ 
Serializable{
     this.loadOnCacheMiss = loadOnCacheMiss;
   }
 
+  public void setPrincipal(Serializable principal){
+    this.principal = principal;
+  }
+
   //@Override
   public void toData(DataOutput out) throws IOException {
     DataSerializer.writeString(command,out);
@@ -192,6 +200,7 @@ public class DataCommandRequest implements /*Data*/ 
Serializable{
     DataSerializer.writeString(removeAllKeys,out);
     DataSerializer.writeBoolean(recursive,out);    
     DataSerializer.writeBoolean(loadOnCacheMiss,out);
+    DataSerializer.writeObject(principal, out);
   }
 
   //@Override
@@ -206,6 +215,7 @@ public class DataCommandRequest implements /*Data*/ 
Serializable{
     removeAllKeys = DataSerializer.readString(in);
     recursive = DataSerializer.readBoolean(in);
     loadOnCacheMiss = DataSerializer.readBoolean(in);
+    principal = DataSerializer.readObject(in);
   }  
   
   

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/774044ee/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 e6482c1..2708242 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
@@ -17,6 +17,7 @@
 package com.gemstone.gemfire.management.internal.cli.functions;
 
 import java.io.IOException;
+import java.io.Serializable;
 import java.util.ArrayList;
 import java.util.Collections;
 import java.util.HashSet;
@@ -28,6 +29,7 @@ import java.util.concurrent.atomic.AtomicInteger;
 
 import org.apache.commons.lang.StringUtils;
 import org.apache.logging.log4j.Logger;
+import org.apache.shiro.subject.Subject;
 import org.json.JSONArray;
 
 import com.gemstone.gemfire.cache.Cache;
@@ -98,7 +100,7 @@ public class DataCommandFunction extends FunctionAdapter 
implements  InternalEnt
   private static final int NESTED_JSON_LENGTH = 20;
 
   private SecurityService securityService = 
IntegratedSecurityService.getSecurityService();
-  
+
   @Override
   public String getId() {
     return DataCommandFunction.class.getName();
@@ -177,7 +179,7 @@ public class DataCommandFunction extends FunctionAdapter 
implements  InternalEnt
     String valueClass = request.getValueClass();
     String regionName = request.getRegionName();
     Boolean loadOnCacheMiss = request.isLoadOnCacheMiss();
-    return get(key, keyClass, valueClass, regionName, loadOnCacheMiss);
+    return get(request.getPrincipal(), key, keyClass, valueClass, regionName, 
loadOnCacheMiss);
   }
   
   public DataCommandResult locateEntry(DataCommandRequest request) {
@@ -202,7 +204,7 @@ public class DataCommandFunction extends FunctionAdapter 
implements  InternalEnt
   
   public DataCommandResult select(DataCommandRequest request) {
     String query = request.getQuery();    
-    return select(query);
+    return select(request.getPrincipal(), query);
   }
   
   /**
@@ -221,7 +223,7 @@ public class DataCommandFunction extends FunctionAdapter 
implements  InternalEnt
   }
   
   @SuppressWarnings("rawtypes")
-  private DataCommandResult select(String queryString) {
+  private DataCommandResult select(Serializable principal, String queryString) 
{
 
     Cache cache = CacheFactory.getAnyInstance();
     AtomicInteger nestedObjectCount = new AtomicInteger(0);
@@ -253,7 +255,7 @@ public class DataCommandFunction extends FunctionAdapter 
implements  InternalEnt
           for (Iterator iter = selectResults.iterator(); iter.hasNext();) {
             Object object = iter.next();
             // Post processing
-            object = this.securityService.postProcess(null, null, object, 
false);
+            object = this.securityService.postProcess(principal, null, null, 
object, false);
 
             if (object instanceof Struct) {
               StructImpl impl = (StructImpl) object;
@@ -421,7 +423,7 @@ public class DataCommandFunction extends FunctionAdapter 
implements  InternalEnt
   }
   
   @SuppressWarnings({ "rawtypes" })
-  public DataCommandResult get(String key, String keyClass, String valueClass, 
String regionName, Boolean loadOnCacheMiss) {
+  public DataCommandResult get(Serializable principal, String key, String 
keyClass, String valueClass, String regionName, Boolean loadOnCacheMiss) {
     
     Cache cache = CacheFactory.getAnyInstance();
     
@@ -458,7 +460,7 @@ public class DataCommandFunction extends FunctionAdapter 
implements  InternalEnt
 
         // 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 = this.securityService.postProcess(regionName, keyObject, value, 
false);
+        value = this.securityService.postProcess(principal, regionName, 
keyObject, value, false);
 
         if (logger.isDebugEnabled()) 
           logger.debug("Get for key {} value {}", key, value);
@@ -943,6 +945,10 @@ public class DataCommandFunction extends FunctionAdapter 
implements  InternalEnt
             DataCommandRequest request = new DataCommandRequest();
             request.setCommand(CliStrings.QUERY);
             request.setQuery(query);
+            Subject subject = this.securityService.getSubject();
+            if(subject!=null){
+              request.setPrincipal((Serializable)subject.getPrincipal());
+            }
             dataResult = DataCommands.callFunctionForRegion(request, function, 
members);
             dataResult.setInputQuery(query);
             return (dataResult);

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/774044ee/geode-core/src/main/java/org/apache/geode/security/PostProcessor.java
----------------------------------------------------------------------
diff --git 
a/geode-core/src/main/java/org/apache/geode/security/PostProcessor.java 
b/geode-core/src/main/java/org/apache/geode/security/PostProcessor.java
index 1a0e5de..3c50ecc 100644
--- a/geode-core/src/main/java/org/apache/geode/security/PostProcessor.java
+++ b/geode-core/src/main/java/org/apache/geode/security/PostProcessor.java
@@ -17,7 +17,7 @@
 
 package org.apache.geode.security;
 
-import java.security.Principal;
+import java.io.Serializable;
 import java.util.Properties;
 
 /**
@@ -38,7 +38,8 @@ public interface PostProcessor {
    * Process the value before sending it to the requester
    *
    * @param principal
-   *        The principal that's accessing the value
+   *        The principal that's accessing the value. The type of the 
principal will depend on how you implemented
+   *        your SecurityManager
    * @param regionName
    *        The region that's been accessed. This could be null.
    * @param key
@@ -48,7 +49,7 @@ public interface PostProcessor {
    * @return
    *        the value that will be returned to the requester
    */
-  Object processRegionValue(Principal principal, String regionName, Object 
key,  Object value);
+  Object processRegionValue(Serializable principal, String regionName, Object 
key, Object value);
 
   /**
    * Give the implementation a chance to close the resources used.

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/774044ee/geode-core/src/main/java/org/apache/geode/security/SecurityManager.java
----------------------------------------------------------------------
diff --git 
a/geode-core/src/main/java/org/apache/geode/security/SecurityManager.java 
b/geode-core/src/main/java/org/apache/geode/security/SecurityManager.java
index 273f2f1..9db4734 100644
--- a/geode-core/src/main/java/org/apache/geode/security/SecurityManager.java
+++ b/geode-core/src/main/java/org/apache/geode/security/SecurityManager.java
@@ -16,7 +16,7 @@
  */
 package org.apache.geode.security;
 
-import java.security.Principal;
+import java.io.Serializable;
 import java.util.Properties;
 
 import com.gemstone.gemfire.distributed.DistributedSystem;
@@ -46,10 +46,10 @@ public interface SecurityManager {
    * @param credentials
    *        it contains the security-username and security-password as keys of 
the properties
    * @return
-   *        the authenticated Principal object
+   *        a serializable principal object
    * @throws AuthenticationFailedException
    */
-  Principal authenticate(Properties credentials) throws 
AuthenticationFailedException;
+  Serializable authenticate(Properties credentials) throws 
AuthenticationFailedException;
 
   /**
    * Authorize the ResourcePermission for a given Principal
@@ -60,7 +60,7 @@ public interface SecurityManager {
    * @return
    *        true if authorized, false if not
    */
-  default boolean authorize(Principal principal, ResourcePermission 
permission) {
+  default boolean authorize(Serializable principal, ResourcePermission 
permission) {
     return true;
   }
 

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/774044ee/geode-core/src/main/java/org/apache/geode/security/templates/SamplePostProcessor.java
----------------------------------------------------------------------
diff --git 
a/geode-core/src/main/java/org/apache/geode/security/templates/SamplePostProcessor.java
 
b/geode-core/src/main/java/org/apache/geode/security/templates/SamplePostProcessor.java
index ce87bf8..bcf40cf 100644
--- 
a/geode-core/src/main/java/org/apache/geode/security/templates/SamplePostProcessor.java
+++ 
b/geode-core/src/main/java/org/apache/geode/security/templates/SamplePostProcessor.java
@@ -16,6 +16,7 @@
  */
 package org.apache.geode.security.templates;
 
+import java.io.Serializable;
 import java.security.Principal;
 import java.util.Properties;
 
@@ -44,10 +45,17 @@ public class SamplePostProcessor implements PostProcessor{
    * @return the processed value
    */
   @Override
-  public Object processRegionValue(Principal principal,
+  public Object processRegionValue(Serializable principal,
                                    String regionName,
                                    Object key,
                                    Object value) {
-    return principal.getName()+"/"+regionName+"/"+key+"/"+value;
+    String name = null;
+    if(principal instanceof Principal){
+      name = ((Principal) principal).getName();
+    }
+    else{
+      name = principal.toString();
+    }
+    return name+"/"+regionName+"/"+key+"/"+value;
   }
 }

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/774044ee/geode-core/src/main/java/org/apache/geode/security/templates/SampleSecurityManager.java
----------------------------------------------------------------------
diff --git 
a/geode-core/src/main/java/org/apache/geode/security/templates/SampleSecurityManager.java
 
b/geode-core/src/main/java/org/apache/geode/security/templates/SampleSecurityManager.java
index 83ac50e..6845647 100644
--- 
a/geode-core/src/main/java/org/apache/geode/security/templates/SampleSecurityManager.java
+++ 
b/geode-core/src/main/java/org/apache/geode/security/templates/SampleSecurityManager.java
@@ -20,8 +20,8 @@ import java.io.File;
 import java.io.FileInputStream;
 import java.io.IOException;
 import java.io.InputStream;
+import java.io.Serializable;
 import java.io.StringWriter;
-import java.security.Principal;
 import java.util.ArrayList;
 import java.util.Collections;
 import java.util.HashMap;
@@ -33,8 +33,6 @@ import java.util.Set;
 import java.util.stream.Collectors;
 import java.util.stream.StreamSupport;
 
-import javax.management.remote.JMXPrincipal;
-
 import com.fasterxml.jackson.databind.JsonNode;
 import com.fasterxml.jackson.databind.ObjectMapper;
 import org.apache.commons.io.IOUtils;
@@ -106,10 +104,10 @@ public class SampleSecurityManager implements 
SecurityManager {
   private Map<String, User> userNameToUser;
 
   @Override
-  public boolean authorize(final Principal principal, final ResourcePermission 
context) {
+  public boolean authorize(final Serializable principal, final 
ResourcePermission context) {
     if (principal == null) return false;
 
-    User user = this.userNameToUser.get(principal.getName());
+    User user = this.userNameToUser.get(principal.toString());
     if (user == null) return false; // this user is not authorized to do 
anything
 
     // check if the user has this permission defined in the context
@@ -150,7 +148,7 @@ public class SampleSecurityManager implements 
SecurityManager {
   }
 
   @Override
-  public Principal authenticate(final Properties credentials) throws 
AuthenticationFailedException {
+  public Serializable authenticate(final Properties credentials) throws 
AuthenticationFailedException {
     String user = credentials.getProperty(ResourceConstants.USER_NAME);
     String password = credentials.getProperty(ResourceConstants.PASSWORD);
 
@@ -163,7 +161,7 @@ public class SampleSecurityManager implements 
SecurityManager {
       throw new AuthenticationFailedException("SampleSecurityManager: wrong 
username/password");
     }
 
-    return new JMXPrincipal(user);
+    return user;
   }
 
   boolean initializeFromJson(final String json) {//throws IOException {

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/774044ee/geode-core/src/test/java/com/gemstone/gemfire/security/AbstractSecureServerDUnitTest.java
----------------------------------------------------------------------
diff --git 
a/geode-core/src/test/java/com/gemstone/gemfire/security/AbstractSecureServerDUnitTest.java
 
b/geode-core/src/test/java/com/gemstone/gemfire/security/AbstractSecureServerDUnitTest.java
index 4f0e260..e054206 100644
--- 
a/geode-core/src/test/java/com/gemstone/gemfire/security/AbstractSecureServerDUnitTest.java
+++ 
b/geode-core/src/test/java/com/gemstone/gemfire/security/AbstractSecureServerDUnitTest.java
@@ -75,6 +75,7 @@ public class AbstractSecureServerDUnitTest extends 
JUnit4CacheTestCase {
     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(SECURITY_SHIRO_INIT, "shiro.ini");
     props.setProperty(LOCATORS, "");
     props.setProperty(MCAST_PORT, "0");
     if (postProcessor!=null) {
@@ -97,19 +98,18 @@ public class AbstractSecureServerDUnitTest extends 
JUnit4CacheTestCase {
 
     getSystem(props);
 
-    CacheFactory cf = null;
-    cf = new CacheFactory();
+    CacheFactory cf = new CacheFactory();
     cf.setPdxPersistent(pdxPersistent);
     cf.setPdxReadSerialized(pdxPersistent);
     Cache cache = getCache(cf);
 
     Region region = 
cache.createRegionFactory(RegionShortcut.REPLICATE).create(REGION_NAME);
 
-    CacheServer server1 = cache.addCacheServer();
-    server1.setPort(0);
-    server1.start();
+    CacheServer server = cache.addCacheServer();
+    server.setPort(0);
+    server.start();
 
-    this.serverPort = server1.getPort();
+    this.serverPort = server.getPort();
 
     for(Entry entry:values.entrySet()){
       region.put(entry.getKey(), entry.getValue());
@@ -126,7 +126,7 @@ public class AbstractSecureServerDUnitTest extends 
JUnit4CacheTestCase {
     assertThatThrownBy(shouldRaiseThrowable).hasMessageContaining(permString);
   }
 
-  protected Properties createClientProperties(String userName, String 
password) {
+  public static Properties createClientProperties(String userName, String 
password) {
     Properties props = new Properties();
     props.setProperty(UserPasswordAuthInit.USER_NAME, userName);
     props.setProperty(UserPasswordAuthInit.PASSWORD, password);
@@ -137,7 +137,7 @@ public class AbstractSecureServerDUnitTest extends 
JUnit4CacheTestCase {
     return props;
   }
 
-  protected ClientCache createClientCache(String username, String password, 
int serverPort){
+  public static ClientCache createClientCache(String username, String 
password, int serverPort){
     ClientCache cache = new 
ClientCacheFactory(createClientProperties(username, password))
       .setPoolSubscriptionEnabled(true)
       .addPoolServer("localhost", serverPort)

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/774044ee/geode-core/src/test/java/com/gemstone/gemfire/security/NoShowValue1PostProcessor.java
----------------------------------------------------------------------
diff --git 
a/geode-core/src/test/java/com/gemstone/gemfire/security/NoShowValue1PostProcessor.java
 
b/geode-core/src/test/java/com/gemstone/gemfire/security/NoShowValue1PostProcessor.java
index b428144..d456516 100644
--- 
a/geode-core/src/test/java/com/gemstone/gemfire/security/NoShowValue1PostProcessor.java
+++ 
b/geode-core/src/test/java/com/gemstone/gemfire/security/NoShowValue1PostProcessor.java
@@ -16,14 +16,14 @@
  */
 package com.gemstone.gemfire.security;
 
-import java.security.Principal;
+import java.io.Serializable;
 
 import org.apache.geode.security.PostProcessor;
 
 public class NoShowValue1PostProcessor implements PostProcessor {
 
   @Override
-  public Object processRegionValue(final Principal principal,
+  public Object processRegionValue(final Serializable principal,
                                    final String regionName,
                                    final Object key,
                                    final Object value) {

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/774044ee/geode-core/src/test/java/com/gemstone/gemfire/security/PDXGfshPostProcessorOnRemoteServerTest.java
----------------------------------------------------------------------
diff --git 
a/geode-core/src/test/java/com/gemstone/gemfire/security/PDXGfshPostProcessorOnRemoteServerTest.java
 
b/geode-core/src/test/java/com/gemstone/gemfire/security/PDXGfshPostProcessorOnRemoteServerTest.java
new file mode 100644
index 0000000..5b4f3ac
--- /dev/null
+++ 
b/geode-core/src/test/java/com/gemstone/gemfire/security/PDXGfshPostProcessorOnRemoteServerTest.java
@@ -0,0 +1,142 @@
+package com.gemstone.gemfire.security;
+
+import static com.gemstone.gemfire.distributed.ConfigurationProperties.*;
+import static org.junit.Assert.*;
+
+import java.io.File;
+import java.util.Properties;
+import java.util.concurrent.TimeUnit;
+
+import com.jayway.awaitility.Awaitility;
+import org.apache.geode.security.templates.SampleSecurityManager;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.experimental.categories.Category;
+
+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.server.CacheServer;
+import com.gemstone.gemfire.distributed.Locator;
+import com.gemstone.gemfire.distributed.internal.InternalDistributedSystem;
+import com.gemstone.gemfire.internal.AvailablePortHelper;
+import com.gemstone.gemfire.internal.security.GeodeSecurityUtil;
+import com.gemstone.gemfire.management.ManagementService;
+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.security.templates.UserPasswordAuthInit;
+import com.gemstone.gemfire.test.dunit.Host;
+import com.gemstone.gemfire.test.dunit.VM;
+import com.gemstone.gemfire.test.dunit.internal.JUnit4DistributedTestCase;
+import com.gemstone.gemfire.test.junit.categories.DistributedTest;
+import com.gemstone.gemfire.test.junit.categories.SecurityTest;
+
+@Category({ DistributedTest.class, SecurityTest.class })
+public class PDXGfshPostProcessorOnRemoteServerTest extends 
JUnit4DistributedTestCase {
+  protected static final String REGION_NAME = "AuthRegion";
+  protected VM locator = null;
+  protected VM server = null;
+
+  @Before
+  public void before() throws Exception {
+    final Host host = Host.getHost(0);
+    this.locator = host.getVM(0);
+    this.server = host.getVM(1);
+  }
+
+  @Test
+  public void testGfshCommand() throws Exception{
+    // set up locator with security
+    int[] ports = AvailablePortHelper.getRandomAvailableTCPPorts(2);
+    int locatorPort = ports[0];
+    int jmxPort = ports[1];
+    locator.invoke(()->{
+      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(MCAST_PORT, "0");
+      props.put(JMX_MANAGER, "true");
+      props.put(JMX_MANAGER_START, "true");
+      props.put(JMX_MANAGER_PORT, jmxPort+"");
+      props.setProperty(SECURITY_POST_PROCESSOR, 
PDXPostProcessor.class.getName());
+      Locator.startLocatorAndDS(locatorPort, new File("locator.log"), props);
+    });
+
+    // set up server with security
+    String locators = "localhost[" + locatorPort + "]";
+    server.invoke(()->{
+      Properties props = new Properties();
+      props.setProperty(MCAST_PORT, "0");
+      props.setProperty(LOCATORS, locators);
+      props.setProperty(SECURITY_MANAGER, 
SampleSecurityManager.class.getName());
+      props.setProperty(SampleSecurityManager.SECURITY_JSON, 
"com/gemstone/gemfire/management/internal/security/clientServer.json");
+      props.setProperty(SECURITY_POST_PROCESSOR, 
PDXPostProcessor.class.getName());
+
+      // the following are needed for peer-to-peer authentication
+      props.setProperty(SECURITY_PEER_AUTH_INIT, 
UserPasswordAuthInit.class.getName());
+      props.setProperty("security-username", "super-user");
+      props.setProperty("security-password", "1234567");
+      InternalDistributedSystem ds = getSystem(props);
+
+      Cache cache = CacheFactory.create(ds);
+      Region region = 
cache.createRegionFactory(RegionShortcut.REPLICATE).create(REGION_NAME);
+
+      CacheServer server = cache.addCacheServer();
+      server.setPort(0);
+      server.start();
+
+      for(int i=0; i<5; i++){
+        SimpleClass obj = new SimpleClass(i, (byte)i);
+        region.put("key"+i, obj);
+      }
+    });
+
+    // wait until the region bean is visible
+    locator.invoke(()->{
+      Awaitility.await().pollInterval(500, TimeUnit.MICROSECONDS).atMost(5, 
TimeUnit.SECONDS).until(()->{
+        Cache cache = CacheFactory.getAnyInstance();
+        Object bean = 
ManagementService.getManagementService(cache).getDistributedRegionMXBean("/"+REGION_NAME);
+        return bean != null;
+      });
+    });
+
+    // run gfsh command in this vm
+    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);
+    
assertTrue(result.getContent().toString().contains(SimpleClass.class.getName()));
+
+    gfsh.executeCommand("query --query=\"select * from /AuthRegion\"");
+    result = (CommandResult)gfsh.getResult();
+
+    CliUtil.isGfshVM = false;
+    server.invoke(()-> {
+      PDXPostProcessor pp = (PDXPostProcessor) 
GeodeSecurityUtil.getPostProcessor();
+      // verify that the post processor is called 6 times. (5 for the query, 1 
for the get)
+      assertEquals(pp.getCount(), 6);
+    });
+  }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/774044ee/geode-core/src/test/java/com/gemstone/gemfire/security/PDXPostProcessor.java
----------------------------------------------------------------------
diff --git 
a/geode-core/src/test/java/com/gemstone/gemfire/security/PDXPostProcessor.java 
b/geode-core/src/test/java/com/gemstone/gemfire/security/PDXPostProcessor.java
index 5609a21..c51c9d8 100644
--- 
a/geode-core/src/test/java/com/gemstone/gemfire/security/PDXPostProcessor.java
+++ 
b/geode-core/src/test/java/com/gemstone/gemfire/security/PDXPostProcessor.java
@@ -16,9 +16,9 @@
  */
 package com.gemstone.gemfire.security;
 
-import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.*;
 
-import java.security.Principal;
+import java.io.Serializable;
 import java.util.Arrays;
 import java.util.Properties;
 
@@ -38,7 +38,7 @@ public class PDXPostProcessor implements PostProcessor{
     count = 0;
   }
   @Override
-  public Object processRegionValue(final Principal principal,
+  public Object processRegionValue(final Serializable principal,
                                    final String regionName,
                                    final Object key,
                                    final Object value) {

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/774044ee/geode-core/src/test/java/com/gemstone/gemfire/security/SpySecurityManager.java
----------------------------------------------------------------------
diff --git 
a/geode-core/src/test/java/com/gemstone/gemfire/security/SpySecurityManager.java
 
b/geode-core/src/test/java/com/gemstone/gemfire/security/SpySecurityManager.java
index 6d04a0d..31ebde5 100644
--- 
a/geode-core/src/test/java/com/gemstone/gemfire/security/SpySecurityManager.java
+++ 
b/geode-core/src/test/java/com/gemstone/gemfire/security/SpySecurityManager.java
@@ -16,7 +16,7 @@
  */
 package com.gemstone.gemfire.security;
 
-import java.security.Principal;
+import java.io.Serializable;
 import java.util.Properties;
 
 import org.apache.geode.security.SecurityManager;
@@ -32,7 +32,7 @@ public class SpySecurityManager implements SecurityManager {
   }
 
   @Override
-  public Principal authenticate(final Properties props) throws 
AuthenticationFailedException {
+  public Serializable authenticate(final Properties props) throws 
AuthenticationFailedException {
     return null;
   }
 


Reply via email to