Repository: incubator-ranger
Updated Branches:
  refs/heads/stack c4d066b6b -> dc0b2c8eb


RANGER-203: 1) Grant/Revoke implementation in HBase.
2) Fixes in grant/revoke REST API on policy update logic.
3) Updated PolicyRefresher to use thread-interrupt to stop the refresher thread 
(instead of shutdown flag).
4) Fix in HBase Ranger co-processor to ensure a single instance of plugin 
object, and there by a single instance of PolicyRefresher and PolicyEngine 
objects
5) Updated singleton plugin instantiation in HDFS/HBase/Hive to use volatile, 
instead of relying on double-checked locking


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

Branch: refs/heads/stack
Commit: b8ebee5b0924368dc131a1f0b78d1fd684e8cbda
Parents: a6f8050
Author: Madhan Neethiraj <[email protected]>
Authored: Tue Feb 10 17:07:50 2015 -0800
Committer: Madhan Neethiraj <[email protected]>
Committed: Tue Feb 10 17:07:50 2015 -0800

----------------------------------------------------------------------
 .../admin/client/RangerAdminRESTClient.java     |  25 +-
 .../admin/client/datatype/RESTResponse.java     |  11 +
 .../RangerAbstractResourceMatcher.java          |   4 +
 .../ranger/plugin/service/RangerBasePlugin.java |  47 +--
 .../ranger/plugin/util/PolicyRefresher.java     |  19 +-
 .../authorization/hbase/HbaseAuthUtils.java     |   4 +
 .../authorization/hbase/HbaseAuthUtilsImpl.java |  13 +-
 .../hbase/RangerAuthorizationCoprocessor.java   | 179 +++++---
 .../namenode/RangerFSPermissionChecker.java     |  19 +-
 .../hive/authorizer/RangerHiveAuthorizer.java   |  19 +-
 .../org/apache/ranger/common/package-info.java  |   6 +-
 .../org/apache/ranger/rest/ServiceREST.java     | 403 +++++++++++--------
 12 files changed, 470 insertions(+), 279 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/b8ebee5b/agents-common/src/main/java/org/apache/ranger/admin/client/RangerAdminRESTClient.java
----------------------------------------------------------------------
diff --git 
a/agents-common/src/main/java/org/apache/ranger/admin/client/RangerAdminRESTClient.java
 
b/agents-common/src/main/java/org/apache/ranger/admin/client/RangerAdminRESTClient.java
index 8101250..f6bbebc 100644
--- 
a/agents-common/src/main/java/org/apache/ranger/admin/client/RangerAdminRESTClient.java
+++ 
b/agents-common/src/main/java/org/apache/ranger/admin/client/RangerAdminRESTClient.java
@@ -24,6 +24,7 @@ import com.sun.jersey.api.client.WebResource;
 
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
+import org.apache.hadoop.security.AccessControlException;
 import org.apache.ranger.admin.client.datatype.RESTResponse;
 import org.apache.ranger.authorization.hadoop.config.RangerConfiguration;
 import org.apache.ranger.plugin.util.GrantRevokeRequest;
@@ -91,10 +92,16 @@ public class RangerAdminRESTClient implements 
RangerAdminClient {
                WebResource    webResource = 
createWebResource(REST_URL_SERVICE_GRANT_ACCESS + serviceName);
                ClientResponse response    = 
webResource.accept(REST_EXPECTED_MIME_TYPE).type(REST_EXPECTED_MIME_TYPE).post(ClientResponse.class,
 restClient.toJson(request));
 
-               if(response == null || response.getStatus() != 200) {
-                       RESTResponse resp = 
RESTResponse.fromClientResponse(response);
+               if(response != null && response.getStatus() != 200) {
+                       LOG.error("grantAccess() failed: HTTP status=" + 
response.getStatus());
 
-                       throw new Exception(resp.getMessage());
+                       if(response.getStatus() == 401) {
+                               throw new AccessControlException();
+                       }
+
+                       throw new Exception("HTTP " + response.getStatus());
+               } else if(response == null) {
+                       throw new Exception("unknown error");
                }
 
                if(LOG.isDebugEnabled()) {
@@ -111,10 +118,16 @@ public class RangerAdminRESTClient implements 
RangerAdminClient {
                WebResource    webResource = 
createWebResource(REST_URL_SERVICE_REVOKE_ACCESS + serviceName);
                ClientResponse response    = 
webResource.accept(REST_EXPECTED_MIME_TYPE).type(REST_EXPECTED_MIME_TYPE).post(ClientResponse.class,
 restClient.toJson(request));
 
-               if(response == null || response.getStatus() != 200) {
-                       RESTResponse resp = 
RESTResponse.fromClientResponse(response);
+               if(response != null && response.getStatus() != 200) {
+                       LOG.error("revokeAccess() failed: HTTP status=" + 
response.getStatus());
 
-                       throw new Exception(resp.getMessage());
+                       if(response.getStatus() == 401) {
+                               throw new AccessControlException();
+                       }
+
+                       throw new Exception("HTTP " + response.getStatus());
+               } else if(response == null) {
+                       throw new Exception("unknown error");
                }
 
                if(LOG.isDebugEnabled()) {

http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/b8ebee5b/agents-common/src/main/java/org/apache/ranger/admin/client/datatype/RESTResponse.java
----------------------------------------------------------------------
diff --git 
a/agents-common/src/main/java/org/apache/ranger/admin/client/datatype/RESTResponse.java
 
b/agents-common/src/main/java/org/apache/ranger/admin/client/datatype/RESTResponse.java
index 6f0547f..d5b4524 100644
--- 
a/agents-common/src/main/java/org/apache/ranger/admin/client/datatype/RESTResponse.java
+++ 
b/agents-common/src/main/java/org/apache/ranger/admin/client/datatype/RESTResponse.java
@@ -37,6 +37,17 @@ import com.sun.jersey.api.client.ClientResponse;
 public class RESTResponse {
        private static Logger LOG = Logger.getLogger(RESTResponse.class);
 
+       /**
+        * values for statusCode
+        */
+       public static final int STATUS_SUCCESS         = 0;
+       public static final int STATUS_ERROR           = 1;
+       public static final int STATUS_VALIDATION      = 2;
+       public static final int STATUS_WARN            = 3;
+       public static final int STATUS_INFO            = 4;
+       public static final int STATUS_PARTIAL_SUCCESS = 5;
+       public static final int ResponseStatus_MAX     = 5;
+
        private int           httpStatusCode;
        private int           statusCode;
        private String        msgDesc;

http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/b8ebee5b/agents-common/src/main/java/org/apache/ranger/plugin/resourcematcher/RangerAbstractResourceMatcher.java
----------------------------------------------------------------------
diff --git 
a/agents-common/src/main/java/org/apache/ranger/plugin/resourcematcher/RangerAbstractResourceMatcher.java
 
b/agents-common/src/main/java/org/apache/ranger/plugin/resourcematcher/RangerAbstractResourceMatcher.java
index 81f2412..79a878f 100644
--- 
a/agents-common/src/main/java/org/apache/ranger/plugin/resourcematcher/RangerAbstractResourceMatcher.java
+++ 
b/agents-common/src/main/java/org/apache/ranger/plugin/resourcematcher/RangerAbstractResourceMatcher.java
@@ -155,6 +155,10 @@ public abstract class RangerAbstractResourceMatcher 
implements RangerResourceMat
                        } else {
                                ret = optIgnoreCase ? 
StringUtils.equalsIgnoreCase(resource, policyValue) : 
StringUtils.equals(resource, policyValue);
                        }
+
+                       if(policyIsExcludes) {
+                               ret = !ret;
+                       }
                }
 
                if(LOG.isDebugEnabled()) {

http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/b8ebee5b/agents-common/src/main/java/org/apache/ranger/plugin/service/RangerBasePlugin.java
----------------------------------------------------------------------
diff --git 
a/agents-common/src/main/java/org/apache/ranger/plugin/service/RangerBasePlugin.java
 
b/agents-common/src/main/java/org/apache/ranger/plugin/service/RangerBasePlugin.java
index 3dbbe81..d4f4c7f 100644
--- 
a/agents-common/src/main/java/org/apache/ranger/plugin/service/RangerBasePlugin.java
+++ 
b/agents-common/src/main/java/org/apache/ranger/plugin/service/RangerBasePlugin.java
@@ -89,7 +89,7 @@ public class RangerBasePlugin {
 
                serviceName = 
RangerConfiguration.getInstance().get(propertyPrefix + ".service.name");
 
-               RangerAdminClient admin = getAdminClient(propertyPrefix);
+               RangerAdminClient admin = createAdminClient(propertyPrefix);
 
                refresher = new PolicyRefresher(policyEngine, serviceType, 
serviceName, admin, pollingIntervalMs, cacheDir);
                refresher.startRefresher();
@@ -170,47 +170,30 @@ public class RangerBasePlugin {
                return null;
        }
 
-       public boolean grantAccess(GrantRevokeRequest request, 
RangerAuditHandler auditHandler) {
-               boolean ret = false;
+       public void grantAccess(GrantRevokeRequest request, RangerAuditHandler 
auditHandler) throws Exception {
+               PolicyRefresher   refresher = this.refresher;
+               RangerAdminClient admin     = refresher == null ? null : 
refresher.getRangerAdminClient();
 
-               PolicyRefresher refresher = this.refresher;
-
-               if(refresher != null) {
-                       RangerAdminClient admin = 
refresher.getRangerAdminClient();
-                       
-                       if(admin != null) {
-                               try {
-                                       admin.grantAccess(serviceName, request);
-                               } catch(Exception excp) {
-                                       LOG.error("grantAccess() failed", excp);
-                               }
-                       }
+               if(admin == null) {
+                       throw new Exception("ranger-admin client is null");
                }
 
-               return ret;
+               admin.grantAccess(serviceName, request);
        }
 
-       public boolean revokeAccess(GrantRevokeRequest request, 
RangerAuditHandler auditHandler) {
-               boolean ret = false;
+       public void revokeAccess(GrantRevokeRequest request, RangerAuditHandler 
auditHandler) throws Exception {
+               PolicyRefresher   refresher = this.refresher;
+               RangerAdminClient admin     = refresher == null ? null : 
refresher.getRangerAdminClient();
 
-               PolicyRefresher refresher = this.refresher;
-
-               if(refresher != null) {
-                       RangerAdminClient admin = 
refresher.getRangerAdminClient();
-                       
-                       if(admin != null) {
-                               try {
-                                       admin.revokeAccess(serviceName, 
request);
-                               } catch(Exception excp) {
-                                       LOG.error("revokeAccess() failed", 
excp);
-                               }
-                       }
+               if(admin == null) {
+                       throw new Exception("ranger-admin client is null");
                }
 
-               return ret;
+               admin.revokeAccess(serviceName, request);
        }
 
-       private RangerAdminClient getAdminClient(String propertyPrefix) {
+
+       private RangerAdminClient createAdminClient(String propertyPrefix) {
                RangerAdminClient ret = null;
 
                String policySourceImpl = 
RangerConfiguration.getInstance().get(propertyPrefix + ".source.impl");

http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/b8ebee5b/agents-common/src/main/java/org/apache/ranger/plugin/util/PolicyRefresher.java
----------------------------------------------------------------------
diff --git 
a/agents-common/src/main/java/org/apache/ranger/plugin/util/PolicyRefresher.java
 
b/agents-common/src/main/java/org/apache/ranger/plugin/util/PolicyRefresher.java
index 4974a10..eaccf7a 100644
--- 
a/agents-common/src/main/java/org/apache/ranger/plugin/util/PolicyRefresher.java
+++ 
b/agents-common/src/main/java/org/apache/ranger/plugin/util/PolicyRefresher.java
@@ -45,7 +45,6 @@ public class PolicyRefresher extends Thread {
        private long               pollingIntervalMs = 30 * 1000;
        private String             cacheFile         = null;
 
-       private boolean shutdownFlag     = false;
        private long    lastKnownVersion = -1;
        private Gson    gson             = null;
 
@@ -120,13 +119,17 @@ public class PolicyRefresher extends Thread {
        public void startRefresher() {
                loadFromCache();
 
-               shutdownFlag = false;
-
                super.start();
        }
 
        public void stopRefresher() {
-               shutdownFlag = true;
+               super.interrupt();
+
+           try {
+               super.join();
+             } catch (InterruptedException excp) {
+               LOG.warn("PolicyRefresher(serviceName=" + serviceName + "): 
error while waiting for thread to exit", excp);
+             }
        }
 
        public void run() {
@@ -134,7 +137,7 @@ public class PolicyRefresher extends Thread {
                        LOG.debug("==> PolicyRefresher(serviceName=" + 
serviceName + ").run()");
                }
 
-               while(! shutdownFlag) {
+               while(true) {
                        try {
                                ServicePolicies svcPolicies = 
rangerAdmin.getServicePoliciesIfUpdated(serviceName, lastKnownVersion);
 
@@ -167,10 +170,10 @@ public class PolicyRefresher extends Thread {
 
                        try {
                                Thread.sleep(pollingIntervalMs);
-                       } catch(Exception excp) {
-                               LOG.error("PolicyRefresher(serviceName=" + 
serviceName + ").run(): error while sleep. exiting thread", excp);
+                       } catch(InterruptedException excp) {
+                               LOG.info("PolicyRefresher(serviceName=" + 
serviceName + ").run(): interrupted! Exiting thread", excp);
 
-                               throw new RuntimeException(excp);
+                               break;
                        }
                }
 

http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/b8ebee5b/hbase-agent/src/main/java/org/apache/ranger/authorization/hbase/HbaseAuthUtils.java
----------------------------------------------------------------------
diff --git 
a/hbase-agent/src/main/java/org/apache/ranger/authorization/hbase/HbaseAuthUtils.java
 
b/hbase-agent/src/main/java/org/apache/ranger/authorization/hbase/HbaseAuthUtils.java
index 45d4cb4..1d487e5 100644
--- 
a/hbase-agent/src/main/java/org/apache/ranger/authorization/hbase/HbaseAuthUtils.java
+++ 
b/hbase-agent/src/main/java/org/apache/ranger/authorization/hbase/HbaseAuthUtils.java
@@ -22,6 +22,10 @@ import 
org.apache.hadoop.hbase.coprocessor.RegionCoprocessorEnvironment;
 import org.apache.hadoop.hbase.security.access.Permission.Action;
 
 public interface HbaseAuthUtils {
+       public static final String ACCESS_TYPE_READ   = "read";
+       public static final String ACCESS_TYPE_WRITE  = "write";
+       public static final String ACCESS_TYPE_CREATE = "create";
+       public static final String ACCESS_TYPE_ADMIN  = "admin";
 
        String getAccess(Action action);
 

http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/b8ebee5b/hbase-agent/src/main/java/org/apache/ranger/authorization/hbase/HbaseAuthUtilsImpl.java
----------------------------------------------------------------------
diff --git 
a/hbase-agent/src/main/java/org/apache/ranger/authorization/hbase/HbaseAuthUtilsImpl.java
 
b/hbase-agent/src/main/java/org/apache/ranger/authorization/hbase/HbaseAuthUtilsImpl.java
index 955a85c..e42d096 100644
--- 
a/hbase-agent/src/main/java/org/apache/ranger/authorization/hbase/HbaseAuthUtilsImpl.java
+++ 
b/hbase-agent/src/main/java/org/apache/ranger/authorization/hbase/HbaseAuthUtilsImpl.java
@@ -39,7 +39,18 @@ public class HbaseAuthUtilsImpl implements HbaseAuthUtils {
 
        @Override
        public String getAccess(Action action) {
-               return action.toString().toLowerCase();
+               switch(action) {
+                       case READ:
+                               return ACCESS_TYPE_READ;
+                       case WRITE:
+                               return ACCESS_TYPE_WRITE;
+                       case CREATE:
+                               return ACCESS_TYPE_CREATE;
+                       case ADMIN:
+                               return ACCESS_TYPE_ADMIN;
+                       default:
+                               return action.name().toLowerCase();
+               }
        }
 
        @Override

http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/b8ebee5b/hbase-agent/src/main/java/org/apache/ranger/authorization/hbase/RangerAuthorizationCoprocessor.java
----------------------------------------------------------------------
diff --git 
a/hbase-agent/src/main/java/org/apache/ranger/authorization/hbase/RangerAuthorizationCoprocessor.java
 
b/hbase-agent/src/main/java/org/apache/ranger/authorization/hbase/RangerAuthorizationCoprocessor.java
index 828ab7a..1dabb90 100644
--- 
a/hbase-agent/src/main/java/org/apache/ranger/authorization/hbase/RangerAuthorizationCoprocessor.java
+++ 
b/hbase-agent/src/main/java/org/apache/ranger/authorization/hbase/RangerAuthorizationCoprocessor.java
@@ -90,16 +90,15 @@ import 
org.apache.hadoop.hbase.security.access.TablePermission;
 import org.apache.hadoop.hbase.security.access.UserPermission;
 import org.apache.hadoop.hbase.util.Bytes;
 import org.apache.hadoop.hbase.util.Pair;
-import org.apache.ranger.admin.client.RangerAdminRESTClient;
-import org.apache.ranger.admin.client.datatype.GrantRevokeData;
-import org.apache.ranger.admin.client.datatype.GrantRevokeData.PermMap;
+import org.apache.ranger.admin.client.RangerAdminClient;
 import org.apache.ranger.audit.model.AuthzAuditEvent;
 import org.apache.ranger.authorization.hadoop.config.RangerConfiguration;
 import org.apache.ranger.authorization.hadoop.constants.RangerHadoopConstants;
 import org.apache.ranger.authorization.utils.StringUtil;
 import org.apache.ranger.plugin.audit.RangerDefaultAuditHandler;
-import org.apache.ranger.plugin.policyengine.RangerPolicyEngine;
 import org.apache.ranger.plugin.service.RangerBasePlugin;
+import org.apache.ranger.plugin.util.GrantRevokeRequest;
+import org.apache.ranger.plugin.util.PolicyRefresher;
 
 import com.google.common.base.Objects;
 import com.google.common.collect.Lists;
@@ -112,8 +111,7 @@ import com.google.protobuf.Service;
 
 public class RangerAuthorizationCoprocessor extends 
RangerAuthorizationCoprocessorBase implements AccessControlService.Interface, 
CoprocessorService {
        private static final Log LOG = 
LogFactory.getLog(RangerAuthorizationCoprocessor.class.getName());
-       private static final String repositoryName          = 
RangerConfiguration.getInstance().get(RangerHadoopConstants.AUDITLOG_REPOSITORY_NAME_PROP);
-       private static final boolean UpdateRangerPoliciesOnGrantRevoke = 
RangerConfiguration.getInstance().getBoolean(RangerHadoopConstants.HBASE_UPDATE_RANGER_POLICIES_ON_GRANT_REVOKE_PROP,
 
RangerHadoopConstants.HBASE_UPDATE_RANGER_POLICIES_ON_GRANT_REVOKE_DEFAULT_VALUE);
+       private static boolean UpdateRangerPoliciesOnGrantRevoke = 
RangerHadoopConstants.HBASE_UPDATE_RANGER_POLICIES_ON_GRANT_REVOKE_DEFAULT_VALUE;
        private static final String GROUP_PREFIX = "@";
                
        private static final String SUPERUSER_CONFIG_PROP = "hbase.superuser";
@@ -130,9 +128,9 @@ public class RangerAuthorizationCoprocessor extends 
RangerAuthorizationCoprocess
         * These are package level only for testability and aren't meant to be 
exposed outside via getters/setters or made available to derived classes.
         */
        final HbaseFactory _factory = HbaseFactory.getInstance();
-       final RangerPolicyEngine _authorizer = _factory.getPolicyEngine();
        final HbaseUserUtils _userUtils = _factory.getUserUtils();
        final HbaseAuthUtils _authUtils = _factory.getAuthUtils();
+       private static volatile RangerHBasePlugin hbasePlugin = null;
        
        // Utilities Methods 
        protected byte[] getTableName(RegionCoprocessorEnvironment e) {
@@ -323,7 +321,7 @@ public class RangerAuthorizationCoprocessor extends 
RangerAuthorizationCoprocess
                User user = getActiveUser();
                // let's create a session that would be reused.  Set things on 
it that won't change.
                HbaseAuditHandler auditHandler = _factory.getAuditHandler(); 
-               AuthorizationSession session = new 
AuthorizationSession(_authorizer)
+               AuthorizationSession session = new 
AuthorizationSession(hbasePlugin.getPolicyEngine())
                                .operation(operation)
                                .remoteAddress(getRemoteAddress())
                                .auditHandler(auditHandler)
@@ -506,7 +504,7 @@ public class RangerAuthorizationCoprocessor extends 
RangerAuthorizationCoprocess
                User user = getActiveUser();
                
                HbaseAuditHandler auditHandler = _factory.getAuditHandler(); 
-               AuthorizationSession session = new 
AuthorizationSession(_authorizer)
+               AuthorizationSession session = new 
AuthorizationSession(hbasePlugin.getPolicyEngine())
                        .operation(operation)
                        .otherInformation(otherInformation)
                        .remoteAddress(getRemoteAddress())
@@ -562,7 +560,7 @@ public class RangerAuthorizationCoprocessor extends 
RangerAuthorizationCoprocess
                // if write access is desired to metatables then global create 
access is sufficient
                if (_authUtils.isWriteAccess(access) && 
isAccessForMetaTables(regionServerEnv)) {
                        String createAccess = 
_authUtils.getAccess(Action.CREATE);
-                       AuthorizationSession session = new 
AuthorizationSession(_authorizer)
+                       AuthorizationSession session = new 
AuthorizationSession(hbasePlugin.getPolicyEngine())
                                .operation(operation)
                                .remoteAddress(getRemoteAddress())
                                .user(user)
@@ -870,6 +868,7 @@ public class RangerAuthorizationCoprocessor extends 
RangerAuthorizationCoprocess
        private static final String MASTER_COPROCESSOR_TYPE = "master";
        private static final String REGIONAL_COPROCESSOR_TYPE = "regional";
        private static final String REGIONAL_SERVER_COPROCESSOR_TYPE = 
"regionalServer";
+
        @Override
        public void start(CoprocessorEnvironment env) throws IOException {
                String appType = "unknown";
@@ -898,9 +897,26 @@ public class RangerAuthorizationCoprocessor extends 
RangerAuthorizationCoprocess
                                }
                        }
                }
+
                // create and initialize the plugin class
-               new RangerBasePlugin("hbase", appType) {}
-                       .init(_authorizer);
+               RangerHBasePlugin plugin = hbasePlugin;
+
+               if(plugin == null) {
+                       synchronized(RangerAuthorizationCoprocessor.class) {
+                               plugin = hbasePlugin;
+                               
+                               if(plugin == null) {
+                                       plugin = new RangerHBasePlugin(appType);
+
+                                       plugin.init();
+
+                                       UpdateRangerPoliciesOnGrantRevoke = 
RangerConfiguration.getInstance().getBoolean(RangerHadoopConstants.HBASE_UPDATE_RANGER_POLICIES_ON_GRANT_REVOKE_PROP,
 
RangerHadoopConstants.HBASE_UPDATE_RANGER_POLICIES_ON_GRANT_REVOKE_DEFAULT_VALUE);
+
+                                       hbasePlugin = plugin;
+                               }
+                       }
+               }
+               
                if (LOG.isDebugEnabled()) {
                        LOG.debug("Start of Coprocessor: [" + coprocessorType + 
"] with superUserList [" + superUserList + "]");
                }
@@ -985,16 +1001,20 @@ public class RangerAuthorizationCoprocessor extends 
RangerAuthorizationCoprocess
                boolean isSuccess = false;
 
                if(UpdateRangerPoliciesOnGrantRevoke) {
-                       GrantRevokeData grData = null;
+                       GrantRevokeRequest grData = null;
        
                        try {
                                grData = createGrantData(request);
-       
-                               RangerAdminRESTClient xaAdmin = new 
RangerAdminRESTClient();
-       
-                           // TODO: xaAdmin.grantPrivilege(grData);
-       
-                           isSuccess = true;
+
+                               RangerHBasePlugin plugin    = hbasePlugin;
+                               PolicyRefresher   refresher = plugin == null ? 
null : plugin.getPolicyRefresher();
+                               RangerAdminClient admin     = refresher == null 
? null : refresher.getRangerAdminClient();
+
+                               if(admin != null) {
+                                       
admin.grantAccess(plugin.getServiceName(), grData);
+
+                                       isSuccess = true;
+                               }
                        } catch(IOException excp) {
                                LOG.warn("grant() failed", excp);
        
@@ -1004,7 +1024,7 @@ public class RangerAuthorizationCoprocessor extends 
RangerAuthorizationCoprocess
        
                                
ResponseConverter.setControllerException(controller, new 
CoprocessorException(excp.getMessage()));
                        } finally {
-                               byte[] tableName = grData == null ? null : 
StringUtil.getBytes(grData.getTables());
+//                             byte[] tableName = grData == null ? null : 
StringUtil.getBytes(grData.getTables());
        
                                // TODO - Auditing of grant-revoke to be sorted 
out.
 //                             if(accessController.isAudited(tableName)) {
@@ -1027,16 +1047,20 @@ public class RangerAuthorizationCoprocessor extends 
RangerAuthorizationCoprocess
                boolean isSuccess = false;
 
                if(UpdateRangerPoliciesOnGrantRevoke) {
-                       GrantRevokeData grData = null;
+                       GrantRevokeRequest grData = null;
        
                        try {
                                grData = createRevokeData(request);
        
-                               RangerAdminRESTClient xaAdmin = new 
RangerAdminRESTClient();
-       
-                           // TODO: xaAdmin.revokePrivilege(grData);
-       
-                           isSuccess = true;
+                               RangerHBasePlugin plugin    = hbasePlugin;
+                               PolicyRefresher   refresher = plugin == null ? 
null : plugin.getPolicyRefresher();
+                               RangerAdminClient admin     = refresher == null 
? null : refresher.getRangerAdminClient();
+
+                               if(admin != null) {
+                                       
admin.revokeAccess(plugin.getServiceName(), grData);
+
+                                       isSuccess = true;
+                               }
                        } catch(IOException excp) {
                                LOG.warn("revoke() failed", excp);
        
@@ -1046,7 +1070,7 @@ public class RangerAuthorizationCoprocessor extends 
RangerAuthorizationCoprocess
        
                                
ResponseConverter.setControllerException(controller, new 
CoprocessorException(excp.getMessage()));
                        } finally {
-                               byte[] tableName = grData == null ? null : 
StringUtil.getBytes(grData.getTables());
+//                             byte[] tableName = grData == null ? null : 
StringUtil.getBytes(grData.getTables());
        
                                // TODO Audit of grant revoke to be sorted out
 //                             if(accessController.isAudited(tableName)) {
@@ -1079,7 +1103,7 @@ public class RangerAuthorizationCoprocessor extends 
RangerAuthorizationCoprocess
            return 
AccessControlProtos.AccessControlService.newReflectiveService(this);
        }
 
-       private GrantRevokeData 
createGrantData(AccessControlProtos.GrantRequest request) throws Exception {
+       private GrantRevokeRequest 
createGrantData(AccessControlProtos.GrantRequest request) throws Exception {
                
org.apache.hadoop.hbase.protobuf.generated.AccessControlProtos.UserPermission 
up   = request.getUserPermission();
                
org.apache.hadoop.hbase.protobuf.generated.AccessControlProtos.Permission     
perm = up == null ? null : up.getPermission();
 
@@ -1104,7 +1128,7 @@ public class RangerAuthorizationCoprocessor extends 
RangerAuthorizationCoprocess
 
                switch(perm.getType()) {
                        case Global:
-                               tableName = colFamily = qualifier = "*";
+                               tableName = colFamily = qualifier = WILDCARD;
                        break;
 
                        case Table:
@@ -1123,21 +1147,49 @@ public class RangerAuthorizationCoprocessor extends 
RangerAuthorizationCoprocess
                        throw new Exception("grant(): 
table/columnFamily/columnQualifier not specified");
                }
 
-               PermMap permMap = new PermMap();
+               tableName = StringUtil.isEmpty(tableName) ? WILDCARD : 
tableName;
+               colFamily = StringUtil.isEmpty(colFamily) ? WILDCARD : 
colFamily;
+               qualifier = StringUtil.isEmpty(qualifier) ? WILDCARD : 
qualifier;
+
+               User   activeUser = getActiveUser();
+               String grantor    = activeUser != null ? 
activeUser.getShortName() : null;
+
+               Map<String, String> mapResource = new HashMap<String, String>();
+               mapResource.put("table", tableName);
+               mapResource.put("column-family", colFamily);
+               mapResource.put("column", qualifier);
+
+               GrantRevokeRequest ret = new GrantRevokeRequest();
+
+               ret.setGrantor(grantor);
+               ret.setDelegateAdmin(Boolean.FALSE);
+               ret.setEnableAudit(Boolean.TRUE);
+               ret.setReplaceExistingPermissions(Boolean.TRUE);
+               ret.setResource(mapResource);
 
                if(userName.startsWith(GROUP_PREFIX)) {
-                       
permMap.addGroup(userName.substring(GROUP_PREFIX.length()));
+                       
ret.getGroups().add(userName.substring(GROUP_PREFIX.length()));
                } else {
-                       permMap.addUser(userName);
+                       ret.getUsers().add(userName);
                }
 
                for (int i = 0; i < actions.length; i++) {
                        switch(actions[i].code()) {
                                case 'R':
+                                       
ret.getAccessTypes().add(HbaseAuthUtils.ACCESS_TYPE_READ);
+                               break;
+
                                case 'W':
+                                       
ret.getAccessTypes().add(HbaseAuthUtils.ACCESS_TYPE_WRITE);
+                               break;
+
                                case 'C':
+                                       
ret.getAccessTypes().add(HbaseAuthUtils.ACCESS_TYPE_CREATE);
+                               break;
+
                                case 'A':
-                                       permMap.addPerm(actions[i].name());
+                                       
ret.getAccessTypes().add(HbaseAuthUtils.ACCESS_TYPE_ADMIN);
+                                       ret.setDelegateAdmin(Boolean.TRUE);
                                break;
 
                                default:
@@ -1145,17 +1197,10 @@ public class RangerAuthorizationCoprocessor extends 
RangerAuthorizationCoprocess
                        }
                }
 
-               User   activeUser = getActiveUser();
-               String grantor    = activeUser != null ? 
activeUser.getShortName() : null;
-
-               GrantRevokeData grData = new GrantRevokeData();
-
-               grData.setHBaseData(grantor, repositoryName,  tableName,  
qualifier, colFamily, permMap);
-
-               return grData;
+               return ret;
        }
 
-       private GrantRevokeData 
createRevokeData(AccessControlProtos.RevokeRequest request) throws Exception {
+       private GrantRevokeRequest 
createRevokeData(AccessControlProtos.RevokeRequest request) throws Exception {
                
org.apache.hadoop.hbase.protobuf.generated.AccessControlProtos.UserPermission 
up   = request.getUserPermission();
                
org.apache.hadoop.hbase.protobuf.generated.AccessControlProtos.Permission     
perm = up == null ? null : up.getPermission();
 
@@ -1175,7 +1220,7 @@ public class RangerAuthorizationCoprocessor extends 
RangerAuthorizationCoprocess
 
                switch(perm.getType()) {
                        case Global :
-                               tableName = colFamily = qualifier = "*";
+                               tableName = colFamily = qualifier = WILDCARD;
                        break;
 
                        case Table :
@@ -1194,27 +1239,51 @@ public class RangerAuthorizationCoprocessor extends 
RangerAuthorizationCoprocess
                        throw new Exception("revoke(): 
table/columnFamily/columnQualifier not specified");
                }
 
-               PermMap permMap = new PermMap();
+               tableName = StringUtil.isEmpty(tableName) ? WILDCARD : 
tableName;
+               colFamily = StringUtil.isEmpty(colFamily) ? WILDCARD : 
colFamily;
+               qualifier = StringUtil.isEmpty(qualifier) ? WILDCARD : 
qualifier;
+
+               User   activeUser = getActiveUser();
+               String grantor    = activeUser != null ? 
activeUser.getShortName() : null;
+
+               Map<String, String> mapResource = new HashMap<String, String>();
+               mapResource.put("table", tableName);
+               mapResource.put("column-family", colFamily);
+               mapResource.put("column", qualifier);
+
+               GrantRevokeRequest ret = new GrantRevokeRequest();
+
+               ret.setGrantor(grantor);
+               ret.setDelegateAdmin(Boolean.FALSE);
+               ret.setEnableAudit(Boolean.TRUE);
+               ret.setReplaceExistingPermissions(Boolean.TRUE);
+               ret.setResource(mapResource);
 
                if(userName.startsWith(GROUP_PREFIX)) {
-                       
permMap.addGroup(userName.substring(GROUP_PREFIX.length()));
+                       
ret.getGroups().add(userName.substring(GROUP_PREFIX.length()));
                } else {
-                       permMap.addUser(userName);
+                       ret.getUsers().add(userName);
                }
 
                // revoke removes all permissions
-               permMap.addPerm(Permission.Action.READ.name());
-               permMap.addPerm(Permission.Action.WRITE.name());
-               permMap.addPerm(Permission.Action.CREATE.name());
-               permMap.addPerm(Permission.Action.ADMIN.name());
+               ret.getAccessTypes().add(HbaseAuthUtils.ACCESS_TYPE_READ);
+               ret.getAccessTypes().add(HbaseAuthUtils.ACCESS_TYPE_WRITE);
+               ret.getAccessTypes().add(HbaseAuthUtils.ACCESS_TYPE_CREATE);
+               ret.getAccessTypes().add(HbaseAuthUtils.ACCESS_TYPE_ADMIN);
 
-               User   activeUser = getActiveUser();
-               String grantor    = activeUser != null ? 
activeUser.getShortName() : null;
+               return ret;
+       }
+}
 
-               GrantRevokeData grData = new GrantRevokeData();
 
-               grData.setHBaseData(grantor, repositoryName,  tableName,  
qualifier, colFamily, permMap);
+class RangerHBasePlugin extends RangerBasePlugin {
+       public RangerHBasePlugin(String appType) {
+               super("hbase", appType);
+       }
 
-               return grData;
+       public void init() {
+               super.init();
        }
 }
+
+

http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/b8ebee5b/hdfs-agent/src/main/java/org/apache/hadoop/hdfs/server/namenode/RangerFSPermissionChecker.java
----------------------------------------------------------------------
diff --git 
a/hdfs-agent/src/main/java/org/apache/hadoop/hdfs/server/namenode/RangerFSPermissionChecker.java
 
b/hdfs-agent/src/main/java/org/apache/hadoop/hdfs/server/namenode/RangerFSPermissionChecker.java
index 58c1102..151360f 100644
--- 
a/hdfs-agent/src/main/java/org/apache/hadoop/hdfs/server/namenode/RangerFSPermissionChecker.java
+++ 
b/hdfs-agent/src/main/java/org/apache/hadoop/hdfs/server/namenode/RangerFSPermissionChecker.java
@@ -66,7 +66,7 @@ public class RangerFSPermissionChecker {
                access2ActionListMapper.put(FsAction.EXECUTE,       
Sets.newHashSet(EXECUTE_ACCCESS_TYPE));
        }
 
-       private static RangerHdfsPlugin                    rangerPlugin        
= null;
+       private static volatile RangerHdfsPlugin           rangerPlugin        
= null;
        private static ThreadLocal<RangerHdfsAuditHandler> currentAuditHandler 
= new ThreadLocal<RangerHdfsAuditHandler>();
 
 
@@ -98,15 +98,18 @@ public class RangerFSPermissionChecker {
                                aPathName = 
RangerHadoopConstants.HDFS_ROOT_FOLDER_PATH;
                        }
 
-                       if (rangerPlugin == null) {
+                       RangerHdfsPlugin plugin = rangerPlugin;
+
+                       if (plugin == null) {
                                synchronized(RangerFSPermissionChecker.class) {
-                                       RangerHdfsPlugin temp = rangerPlugin ;
-                                       if (temp == null) {
+                                       plugin = rangerPlugin ;
+
+                                       if (plugin == null) {
                                                try {
-                                                       temp = new 
RangerHdfsPlugin();
-                                                       temp.init();
+                                                       plugin = new 
RangerHdfsPlugin();
+                                                       plugin.init();
 
-                                                       rangerPlugin = temp;
+                                                       rangerPlugin = plugin;
                                                }
                                                catch(Throwable t) {
                                                        LOG.error("Unable to 
create Authorizer", t);
@@ -172,7 +175,7 @@ public class RangerFSPermissionChecker {
 }
 
 class RangerHdfsPlugin extends RangerBasePlugin {
-       private static boolean hadoopAuthEnabled = false;
+       private static boolean hadoopAuthEnabled = 
RangerHadoopConstants.RANGER_ADD_HDFS_PERMISSION_DEFAULT;
 
        public RangerHdfsPlugin() {
                super("hdfs", "hdfs");

http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/b8ebee5b/hive-agent/src/main/java/org/apache/ranger/authorization/hive/authorizer/RangerHiveAuthorizer.java
----------------------------------------------------------------------
diff --git 
a/hive-agent/src/main/java/org/apache/ranger/authorization/hive/authorizer/RangerHiveAuthorizer.java
 
b/hive-agent/src/main/java/org/apache/ranger/authorization/hive/authorizer/RangerHiveAuthorizer.java
index e862943..d7d7a34 100644
--- 
a/hive-agent/src/main/java/org/apache/ranger/authorization/hive/authorizer/RangerHiveAuthorizer.java
+++ 
b/hive-agent/src/main/java/org/apache/ranger/authorization/hive/authorizer/RangerHiveAuthorizer.java
@@ -26,7 +26,6 @@ import java.util.List;
 import java.util.Map;
 import java.util.Set;
 
-import org.apache.commons.collections.CollectionUtils;
 import org.apache.commons.lang.StringUtils;
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
@@ -64,7 +63,7 @@ public class RangerHiveAuthorizer extends 
RangerHiveAuthorizerBase {
 
        private static final char COLUMN_SEP = ',';
 
-       private static RangerHivePlugin hivePlugin = null ;
+       private static volatile RangerHivePlugin hivePlugin = null ;
 
 
        public RangerHiveAuthorizer(HiveMetastoreClientFactory 
metastoreClientFactory,
@@ -75,9 +74,13 @@ public class RangerHiveAuthorizer extends 
RangerHiveAuthorizerBase {
 
                LOG.debug("RangerHiveAuthorizer.RangerHiveAuthorizer()");
 
-               if(hivePlugin == null) {
+               RangerHivePlugin plugin = hivePlugin;
+               
+               if(plugin == null) {
                        synchronized(RangerHiveAuthorizer.class) {
-                               if(hivePlugin == null) {
+                               plugin = hivePlugin;
+
+                               if(plugin == null) {
                                        String appType = "unknown";
 
                                        if(sessionContext != null) {
@@ -92,10 +95,10 @@ public class RangerHiveAuthorizer extends 
RangerHiveAuthorizerBase {
                                                }
                                        }
 
-                                       RangerHivePlugin temp = new 
RangerHivePlugin(appType);
-                                       temp.init();
+                                       plugin = new RangerHivePlugin(appType);
+                                       plugin.init();
 
-                                       hivePlugin = temp;
+                                       hivePlugin = plugin;
                                }
                        }
                }
@@ -535,7 +538,7 @@ public class RangerHiveAuthorizer extends 
RangerHiveAuthorizerBase {
 
                                case GRANT_PRIVILEGE:
                                case REVOKE_PRIVILEGE:
-                                       accessType = HiveAccessType.ADMIN;
+                                       accessType = HiveAccessType.NONE; // 
access check will be performed at the ranger-admin side
                                break;
 
                                case ADD:

http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/b8ebee5b/ranger-util/src/gen/org/apache/ranger/common/package-info.java
----------------------------------------------------------------------
diff --git a/ranger-util/src/gen/org/apache/ranger/common/package-info.java 
b/ranger-util/src/gen/org/apache/ranger/common/package-info.java
index 5e8bd27..233f419 100644
--- a/ranger-util/src/gen/org/apache/ranger/common/package-info.java
+++ b/ranger-util/src/gen/org/apache/ranger/common/package-info.java
@@ -20,7 +20,7 @@
  * Generated by saveVersion.sh
  */
 @RangerVersionAnnotation(version="0.4.0", 
shortVersion="${ranger.version.shortname}",
-                         revision="25517f0b1ff57e2da4a0844f4559390508ecb57e", 
branch="BUG-210",
-                         user="gautam", date="Mon Feb 2 11:40:14 IST 2015", 
url="git://Gautams-MacBook-Pro.local/Users/gautam/Code/javaWorkspace/XASecure/Repos/incubator-ranger-patch",
-                         srcChecksum="b46cebc9c7edc45bd3bcc6193ff245ca")
+                         revision="a6f8050b54206dfa61d87a756d7434ec70131d88", 
branch="stack",
+                         user="mneethiraj", date="Tue Feb 10 17:06:21 PST 
2015", 
url="git://HW10963.local/Users/mneethiraj/Apache/git-commit2/incubator-ranger",
+                         srcChecksum="c0d896b805fcb51d32f80227c393ce33")
 package org.apache.ranger.common;

http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/b8ebee5b/security-admin/src/main/java/org/apache/ranger/rest/ServiceREST.java
----------------------------------------------------------------------
diff --git 
a/security-admin/src/main/java/org/apache/ranger/rest/ServiceREST.java 
b/security-admin/src/main/java/org/apache/ranger/rest/ServiceREST.java
index 922d174..971f6ac 100644
--- a/security-admin/src/main/java/org/apache/ranger/rest/ServiceREST.java
+++ b/security-admin/src/main/java/org/apache/ranger/rest/ServiceREST.java
@@ -20,9 +20,8 @@
 package org.apache.ranger.rest;
 
 import java.util.ArrayList;
-import java.util.Collection;
+import java.util.Collections;
 import java.util.HashMap;
-import java.util.HashSet;
 import java.util.List;
 import java.util.Map;
 import java.util.Set;
@@ -36,12 +35,12 @@ import javax.ws.rs.PUT;
 import javax.ws.rs.Path;
 import javax.ws.rs.PathParam;
 import javax.ws.rs.Produces;
+import javax.ws.rs.WebApplicationException;
 import javax.ws.rs.core.Context;
 
 import org.apache.commons.collections.CollectionUtils;
 import org.apache.commons.collections.MapUtils;
 import org.apache.commons.lang3.ArrayUtils;
-import org.apache.commons.lang3.ObjectUtils;
 import org.apache.commons.lang3.StringUtils;
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
@@ -51,6 +50,7 @@ import 
org.apache.ranger.plugin.model.RangerPolicy.RangerPolicyItemAccess;
 import org.apache.ranger.plugin.model.RangerPolicy.RangerPolicyResource;
 import org.apache.ranger.plugin.model.RangerService;
 import org.apache.ranger.plugin.model.RangerServiceDef;
+import org.apache.ranger.plugin.policyengine.RangerPolicyEngine;
 import org.apache.ranger.plugin.policyengine.RangerResource;
 import org.apache.ranger.plugin.policyengine.RangerResourceImpl;
 import org.apache.ranger.plugin.policyevaluator.RangerDefaultPolicyEvaluator;
@@ -66,6 +66,7 @@ import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.context.annotation.Scope;
 import org.springframework.security.access.prepost.PreAuthorize;
 import org.springframework.stereotype.Component;
+import org.apache.ranger.admin.client.datatype.RESTResponse;
 import org.apache.ranger.biz.AssetMgr;
 import org.apache.ranger.biz.ServiceMgr;
 import org.apache.ranger.common.RESTErrorUtil;
@@ -465,16 +466,19 @@ public class ServiceREST {
        @POST
        @Path("/services/grant/{serviceName}")
        @Produces({ "application/json", "application/xml" })
-       public void grantAccess(@PathParam("serviceName") String serviceName, 
GrantRevokeRequest grantRequest, @Context HttpServletRequest request) throws 
Exception {
+       public RESTResponse grantAccess(@PathParam("serviceName") String 
serviceName, GrantRevokeRequest grantRequest, @Context HttpServletRequest 
request) throws Exception {
                if(LOG.isDebugEnabled()) {
                        LOG.debug("==> ServiceREST.grantAccess(" + serviceName 
+ ", " + grantRequest + ")");
                }
 
+               RESTResponse ret = new RESTResponse();
+
                try {
-                       String         userName = grantRequest.getGrantor();
-                       RangerResource resource = new 
RangerResourceImpl(grantRequest.getResource());
+                       String         userName   = grantRequest.getGrantor();
+                       Set<String>    userGroups = 
Collections.<String>emptySet(); // TODO: get groups for the grantor from Ranger 
database
+                       RangerResource resource   = new 
RangerResourceImpl(grantRequest.getResource());
 
-                       boolean isAdmin = isAdminForResource(userName, 
serviceName, resource);
+                       boolean isAdmin = isAdminForResource(userName, 
userGroups, serviceName, resource);
 
                        if(!isAdmin) {
                                throw 
restErrorUtil.createRESTException(HttpServletResponse.SC_UNAUTHORIZED, "", 
true);
@@ -483,79 +487,98 @@ public class ServiceREST {
                        RangerPolicy policy = 
getExactMatchPolicyForResource(serviceName, resource);
        
                        if(policy != null) {
+                               boolean policyUpdated = false;
+
                                // replace all existing privileges for users 
and groups
                                
if(grantRequest.getReplaceExistingPermissions()) {
-                                       int numOfItems = 
CollectionUtils.isEmpty(policy.getPolicyItems()) ? 0 : 
policy.getPolicyItems().size();
+                                       List<RangerPolicyItem> policyItems = 
policy.getPolicyItems();
+
+                                       int numOfItems = policyItems.size();
        
                                        for(int i = 0; i < numOfItems; i++) {
-                                               RangerPolicyItem policyItem = 
policy.getPolicyItems().get(i);
+                                               RangerPolicyItem policyItem = 
policyItems.get(i);
        
-                                               
CollectionUtils.removeAll(policyItem.getUsers(),  grantRequest.getUsers());
-                                               
CollectionUtils.removeAll(policyItem.getGroups(),  grantRequest.getGroups());
+                                               
if(CollectionUtils.containsAny(policyItem.getUsers(), grantRequest.getUsers())) 
{
+                                                       
policyItem.getUsers().removeAll(grantRequest.getUsers());
+
+                                                       policyUpdated = true;
+                                               }
+
+                                               
if(CollectionUtils.containsAny(policyItem.getGroups(), 
grantRequest.getGroups())) {
+                                                       
policyItem.getGroups().removeAll(grantRequest.getGroups());
+
+                                                       policyUpdated = true;
+                                               }
 
                                                
if(CollectionUtils.isEmpty(policyItem.getUsers()) && 
CollectionUtils.isEmpty(policyItem.getGroups())) {
-                                                       
policy.getPolicyItems().remove(i);
+                                                       policyItems.remove(i);
                                                        numOfItems--;
                                                        i--;
+
+                                                       policyUpdated = true;
                                                }
                                        }
+
+                                       if(compactPolicy(policy)) {
+                                               policyUpdated = true;
+                                       }
                                }
-       
-                               // update policy with granted accesses for 
users and groups
-                               int numOfItems = 
CollectionUtils.isEmpty(policy.getPolicyItems()) ? 0 : 
policy.getPolicyItems().size();
-       
-                               boolean policyUpdated = false;
-                               for(int i = 0; i < numOfItems; i++) {
-                                       RangerPolicyItem policyItem = 
policy.getPolicyItems().get(i);
-       
-                                       // if policyItem matches the users and 
groups in the request, update the policyItem
-                                       if(isMatchForUsersGroups(policyItem, 
grantRequest.getUsers(), grantRequest.getGroups())) {
-                                               for(String accessType : 
grantRequest.getAccessTypes()) {
-                                                       boolean foundAccessType 
= false;
-       
-                                                       
for(RangerPolicyItemAccess policyItemAccess : policyItem.getAccesses()) {
-                                                               
if(StringUtils.equals(policyItemAccess.getType(), accessType)) {
-                                                                       
policyItemAccess.setIsAllowed(Boolean.TRUE);
-                                                                       
foundAccessType = true;
-                                                                       break;
-                                                               }
-                                                       }
-                                                       
-                                                       if(! foundAccessType) {
-                                                               
policyItem.getAccesses().add(new RangerPolicyItemAccess(accessType, 
Boolean.TRUE));
-                                                       }
+
+                               for(String user : grantRequest.getUsers()) {
+                                       RangerPolicyItem policyItem = 
getPolicyItemForUser(policy, user);
+                                       
+                                       if(policyItem != null) {
+                                               if(addAccesses(policyItem, 
grantRequest.getAccessTypes())) {
+                                                       policyUpdated = true;
                                                }
-                                               
policyItem.setDelegateAdmin(grantRequest.getDelegateAdmin());
-       
+                                       } else {
+                                               policyItem = new 
RangerPolicyItem();
+                                               
+                                               policyItem.getUsers().add(user);
+                                               addAccesses(policyItem, 
grantRequest.getAccessTypes());
+                                               
policy.getPolicyItems().add(policyItem);
+
                                                policyUpdated = true;
-                                       } else 
if(ObjectUtils.equals(policyItem.getDelegateAdmin(), 
grantRequest.getDelegateAdmin()) &&
-                                                       
isMatchForAccessTypes(policyItem, grantRequest.getAccessTypes())) { // if 
policyItem matches the accessTypes in the request
-                                               
policyItem.getUsers().addAll(grantRequest.getUsers());
-                                               
policyItem.getGroups().addAll(grantRequest.getGroups());
+                                       }
+
+                                       if(grantRequest.getDelegateAdmin()) {
+                                               
if(!policyItem.getDelegateAdmin()) {
+                                                       
policyItem.setDelegateAdmin(Boolean.TRUE);
        
-                                               policyUpdated = true;
+                                                       policyUpdated = true;
+                                               }
                                        }
+                               }
+
+                               for(String group : grantRequest.getGroups()) {
+                                       RangerPolicyItem policyItem = 
getPolicyItemForGroup(policy, group);
                                        
-                                       if(policyUpdated) {
-                                               break;
+                                       if(policyItem != null) {
+                                               if(addAccesses(policyItem, 
grantRequest.getAccessTypes())) {
+                                                       policyUpdated = true;
+                                               }
+                                       } else {
+                                               policyItem = new 
RangerPolicyItem();
+                                               
+                                               
policyItem.getGroups().add(group);
+                                               addAccesses(policyItem, 
grantRequest.getAccessTypes());
+                                               
policy.getPolicyItems().add(policyItem);
+
+                                               policyUpdated = true;
                                        }
-                               }
+
+                                       if(grantRequest.getDelegateAdmin()) {
+                                               
if(!policyItem.getDelegateAdmin()) {
+                                                       
policyItem.setDelegateAdmin(Boolean.TRUE);
        
-                               if(!policyUpdated) {
-                                       RangerPolicyItem policyItem = new 
RangerPolicyItem();
-               
-                                       
policyItem.getUsers().addAll(grantRequest.getUsers());
-                                       
policyItem.getGroups().addAll(grantRequest.getGroups());
-                                       for(String accessType : 
grantRequest.getAccessTypes()) {
-                                               RangerPolicyItemAccess access = 
new RangerPolicyItemAccess(accessType, Boolean.TRUE);
-               
-                                               
policyItem.getAccesses().add(access);
+                                                       policyUpdated = true;
+                                               }
                                        }
-                                       
policyItem.setDelegateAdmin(grantRequest.getDelegateAdmin());
-                                       policy.getPolicyItems().add(policyItem);
                                }
-       
-                               updatePolicy(policy);
+
+                               if(policyUpdated) {
+                                       updatePolicy(policy);
+                               }
                        } else {
                                policy = new RangerPolicy();
                                policy.setService(serviceName);
@@ -574,101 +597,132 @@ public class ServiceREST {
                                }
                                policy.setResources(policyResources);
        
-                               RangerPolicyItem policyItem = new 
RangerPolicyItem();
-       
-                               
policyItem.getUsers().addAll(grantRequest.getUsers());
-                               
policyItem.getGroups().addAll(grantRequest.getGroups());
-                               for(String accessType : 
grantRequest.getAccessTypes()) {
-                                       policyItem.getAccesses().add(new 
RangerPolicyItemAccess(accessType, Boolean.TRUE));
+                               for(String user : grantRequest.getUsers()) {
+                                       RangerPolicyItem policyItem = new 
RangerPolicyItem();
+               
+                                       policyItem.getUsers().add(user);
+                                       for(String accessType : 
grantRequest.getAccessTypes()) {
+                                               
policyItem.getAccesses().add(new RangerPolicyItemAccess(accessType, 
Boolean.TRUE));
+                                       }
+                                       
policyItem.setDelegateAdmin(grantRequest.getDelegateAdmin());
+                                       policy.getPolicyItems().add(policyItem);
+                               }
+                               
+                               for(String group : grantRequest.getGroups()) {
+                                       RangerPolicyItem policyItem = new 
RangerPolicyItem();
+               
+                                       policyItem.getGroups().add(group);
+                                       for(String accessType : 
grantRequest.getAccessTypes()) {
+                                               
policyItem.getAccesses().add(new RangerPolicyItemAccess(accessType, 
Boolean.TRUE));
+                                       }
+                                       
policyItem.setDelegateAdmin(grantRequest.getDelegateAdmin());
+                                       policy.getPolicyItems().add(policyItem);
                                }
-                               
policyItem.setDelegateAdmin(grantRequest.getDelegateAdmin());
-                               policy.getPolicyItems().add(policyItem);
        
                                createPolicy(policy);
                        }
+               } catch(WebApplicationException excp) {
+                       throw excp;
                } catch(Exception excp) {
+                       LOG.error("grantAccess() failed", excp);
+
                        throw 
restErrorUtil.createRESTException(HttpServletResponse.SC_BAD_REQUEST, 
excp.getMessage(), true);
                }
 
+               ret.setStatusCode(RESTResponse.STATUS_SUCCESS);
+
                if(LOG.isDebugEnabled()) {
-                       LOG.debug("<== ServiceREST.grantAccess(" + serviceName 
+ ", " + grantRequest + ")");
+                       LOG.debug("<== ServiceREST.grantAccess(" + serviceName 
+ ", " + grantRequest + "): " + ret);
                }
+
+               return ret;
        }
 
        @POST
        @Path("/services/revoke/{serviceName}")
        @Produces({ "application/json", "application/xml" })
-       public void revokeAccess(@PathParam("serviceName") String serviceName, 
GrantRevokeRequest revokeRequest, @Context HttpServletRequest request) throws 
Exception {
+       public RESTResponse revokeAccess(@PathParam("serviceName") String 
serviceName, GrantRevokeRequest revokeRequest, @Context HttpServletRequest 
request) throws Exception {
                if(LOG.isDebugEnabled()) {
                        LOG.debug("==> ServiceREST.revokeAccess(" + serviceName 
+ ", " + revokeRequest + ")");
                }
 
+               RESTResponse ret = new RESTResponse();
+
                try {
-                       String         userName = revokeRequest.getGrantor();
-                       RangerResource resource = new 
RangerResourceImpl(revokeRequest.getResource());
+                       String         userName   = revokeRequest.getGrantor();
+                       Set<String>    userGroups = 
Collections.<String>emptySet(); // TODO: get groups for the grantor from Ranger 
databas
+                       RangerResource resource   = new 
RangerResourceImpl(revokeRequest.getResource());
 
-                       boolean isAdmin = isAdminForResource(userName, 
serviceName, resource);
+                       boolean isAdmin = isAdminForResource(userName, 
userGroups, serviceName, resource);
                        
                        if(!isAdmin) {
-                               throw new Exception("Access denied");
+                               throw 
restErrorUtil.createRESTException(HttpServletResponse.SC_UNAUTHORIZED, "", 
true);
                        }
 
                        RangerPolicy policy = 
getExactMatchPolicyForResource(serviceName, resource);
-
-                       if(policy != null && 
!CollectionUtils.isEmpty(policy.getPolicyItems())) {
+                       
+                       if(policy != null) {
                                boolean policyUpdated = false;
 
-                               for(int i = 0; i < 
policy.getPolicyItems().size(); i++) {
-                                       RangerPolicyItem policyItem = 
policy.getPolicyItems().get(i);
+                               for(String user : revokeRequest.getUsers()) {
+                                       RangerPolicyItem policyItem = 
getPolicyItemForUser(policy, user);
+                                       
+                                       if(policyItem != null) {
+                                               if(removeAccesses(policyItem, 
revokeRequest.getAccessTypes())) {
+                                                       policyUpdated = true;
+                                               }
+                                       }
 
-                                       // if users and groups of policyItem 
are a subset of request, update the policyItem
-                                       if(isSubsetOfUsersGroups(policyItem, 
revokeRequest.getUsers(), revokeRequest.getGroups())) {
-                                               for(String accessType : 
revokeRequest.getAccessTypes()) {
-                                                       for(int j = 0; j < 
policyItem.getAccesses().size(); j++) {
-                                                               
RangerPolicyItemAccess policyItemAccess = policyItem.getAccesses().get(j);
+                                       if(revokeRequest.getDelegateAdmin()) { 
// remove delegate?
+                                               
if(policyItem.getDelegateAdmin()) {
+                                                       
policyItem.setDelegateAdmin(Boolean.FALSE);
+                                                       policyUpdated = true;
+                                               }
+                                       }
+                               }
 
-                                                               
if(StringUtils.equals(policyItemAccess.getType(), accessType)) {
-                                                                       
policyItem.getAccesses().remove(j);
-                                                                       j--;
+                               for(String group : revokeRequest.getGroups()) {
+                                       RangerPolicyItem policyItem = 
getPolicyItemForGroup(policy, group);
+                                       
+                                       if(policyItem != null) {
+                                               if(removeAccesses(policyItem, 
revokeRequest.getAccessTypes())) {
+                                                       policyUpdated = true;
+                                               }
 
-                                                                       
policyUpdated = true;
-                                                               }
+                                               
if(revokeRequest.getDelegateAdmin()) { // remove delegate?
+                                                       
if(policyItem.getDelegateAdmin()) {
+                                                               
policyItem.setDelegateAdmin(Boolean.FALSE);
+                                                               policyUpdated = 
true;
                                                        }
                                                }
-                                       } else 
if(ObjectUtils.equals(policyItem.getDelegateAdmin(), 
revokeRequest.getDelegateAdmin()) &&
-                                                         
isSubsetOfAccessTypes(policyItem, revokeRequest.getAccessTypes())) { // if 
policyItem matches the accessTypes in the request
-                                               
policyItem.getUsers().removeAll(revokeRequest.getUsers());
-                                               
policyItem.getGroups().removeAll(revokeRequest.getGroups());
-
-                                               policyUpdated = true;
                                        }
+                               }
 
-                                       
if(CollectionUtils.isEmpty(policyItem.getAccesses()) ||
-                                          
(CollectionUtils.isEmpty(policyItem.getUsers()) && 
CollectionUtils.isEmpty(policyItem.getGroups()))) {
-                                               
policy.getPolicyItems().remove(i);
-                                               i--;
-
-                                               policyUpdated = true;
-                                       }
+                               if(compactPolicy(policy)) {
+                                       policyUpdated = true;
                                }
 
                                if(policyUpdated) {
-                                       
if(CollectionUtils.isEmpty(policy.getPolicyItems())) {
-                                               deletePolicy(policy.getId());
-                                       } else {
-                                               updatePolicy(policy);
-                                       }
+                                       updatePolicy(policy);
                                }
                        } else {
                                // nothing to revoke!
                        }
+               } catch(WebApplicationException excp) {
+                       throw excp;
                } catch(Exception excp) {
+                       LOG.error("revokeAccess() failed", excp);
+
                        throw 
restErrorUtil.createRESTException(HttpServletResponse.SC_BAD_REQUEST, 
excp.getMessage(), true);
                }
 
+               ret.setStatusCode(RESTResponse.STATUS_SUCCESS);
+
                if(LOG.isDebugEnabled()) {
-                       LOG.debug("<== ServiceREST.revokeAccess(" + serviceName 
+ ", " + revokeRequest + ")");
+                       LOG.debug("<== ServiceREST.revokeAccess(" + serviceName 
+ ", " + revokeRequest + "): " + ret);
                }
+
+               return ret;
        }
 
 
@@ -968,7 +1022,7 @@ public class ServiceREST {
                }
        }
 
-       private boolean isAdminForResource(String userName, String serviceName, 
RangerResource resource) throws Exception {
+       private boolean isAdminForResource(String userName, Set<String> 
userGroups, String serviceName, RangerResource resource) throws Exception {
                if(LOG.isDebugEnabled()) {
                        LOG.debug("==> ServiceREST.isAdminForResource(" + 
userName + ", " + serviceName + ", " + resource + ")");
                }
@@ -992,12 +1046,12 @@ public class ServiceREST {
                                                continue;
                                        }
 
-                                       if(! 
policyItem.getUsers().contains(userName)) { // TODO: check group membership as 
well
-                                               continue;
+                                       
if(policyItem.getUsers().contains(userName) ||
+                                          
policyItem.getGroups().contains(RangerPolicyEngine.GROUP_PUBLIC) ||
+                                          
CollectionUtils.containsAny(policyItem.getGroups(), userGroups)) {
+                                               ret = true;
+                                               break;
                                        }
-                                       
-                                       ret = true;
-                                       break;
                                }
 
                                if(ret) {
@@ -1089,77 +1143,110 @@ public class ServiceREST {
                return ret;
        }
 
-       private boolean isEqualCollection(Collection<?> col1, Collection<?> 
col2) {
-               if(col1 == null) {
-                       return CollectionUtils.isEmpty(col2);
-               } else if(col2 != null) {
-                       return CollectionUtils.isEqualCollection(col1, col2);
-               } else {
-                       return false;
-               }
-       }
+       private boolean compactPolicy(RangerPolicy policy) {
+               boolean ret = false;
 
-       private boolean isSubCollection(Collection<?> col1, Collection<?> col2) 
{
-               if(col1 == null) {
-                       return CollectionUtils.isEmpty(col2);
-               } else if(col2 != null) {
-                       return CollectionUtils.isSubCollection(col1, col2);
-               } else {
-                       return false;
+               List<RangerPolicyItem> policyItems = policy.getPolicyItems();
+
+               int numOfItems = policyItems.size();
+               
+               for(int i = 0; i < numOfItems; i++) {
+                       RangerPolicyItem policyItem = policyItems.get(i);
+                       
+                       // remove the policy item if 1) there are no users and 
groups OR 2) if there are no accessTypes and not a delegate-admin
+                       if((CollectionUtils.isEmpty(policyItem.getUsers()) && 
CollectionUtils.isEmpty(policyItem.getGroups())) ||
+                          (CollectionUtils.isEmpty(policyItem.getAccesses()) 
&& !policyItem.getDelegateAdmin())) {
+                               policyItems.remove(i);
+                               numOfItems--;
+                               i--;
+
+                               ret = true;
+                       }
                }
+
+               return ret;
        }
 
-       private boolean isMatchForUsersGroups(RangerPolicyItem policyItem, 
Set<String> users, Set<String> groups) {
-               if(policyItem == null) {
-                       return false;
+       private RangerPolicyItem getPolicyItemForUser(RangerPolicy policy, 
String userName) {
+               RangerPolicyItem ret = null;
+
+               for(RangerPolicyItem policyItem : policy.getPolicyItems()) {
+                       if(policyItem.getUsers().size() != 1) {
+                               continue;
+                       }
+
+                       if(policyItem.getUsers().contains(userName)) {
+                               ret = policyItem;
+                               break;
+                       }
                }
 
-               return isEqualCollection(policyItem.getUsers(), users) &&
-                          isEqualCollection(policyItem.getGroups(), groups);
+               return ret;
        }
 
-       private boolean isSubsetOfUsersGroups(RangerPolicyItem policyItem, 
Set<String> users, Set<String> groups) {
-               if(policyItem == null) {
-                       return false;
+       private RangerPolicyItem getPolicyItemForGroup(RangerPolicy policy, 
String groupName) {
+               RangerPolicyItem ret = null;
+
+               for(RangerPolicyItem policyItem : policy.getPolicyItems()) {
+                       if(policyItem.getGroups().size() != 1) {
+                               continue;
+                       }
+
+                       if(policyItem.getGroups().contains(groupName)) {
+                               ret = policyItem;
+                               break;
+                       }
                }
 
-               return isSubCollection(policyItem.getUsers(), users) &&
-                          isSubCollection(policyItem.getGroups(), groups);
+               return ret;
        }
 
-       private boolean isMatchForAccessTypes(RangerPolicyItem policyItem, 
Set<String> accessTypes) {
-               if(policyItem == null) {
-                       return false;
-               }
+       private boolean addAccesses(RangerPolicyItem policyItem, Set<String> 
accessTypes) {
+               boolean ret = false;
 
-               Set<String> policyAccessTypes = new HashSet<String>();
+               for(String accessType : accessTypes) {
+                       RangerPolicyItemAccess policyItemAccess = null;
+
+                       for(RangerPolicyItemAccess itemAccess : 
policyItem.getAccesses()) {
+                               if(StringUtils.equals(itemAccess.getType(), 
accessType)) {
+                                       policyItemAccess = itemAccess;
+                                       break;
+                               }
+                       }
 
-               if(!CollectionUtils.isEmpty(policyItem.getAccesses())) {
-                       for(RangerPolicyItemAccess policyItemAccess : 
policyItem.getAccesses()) {
-                               if(policyItemAccess.getIsAllowed()) {
-                                       
policyAccessTypes.add(policyItemAccess.getType());
+                       if(policyItemAccess != null) {
+                               if(!policyItemAccess.getIsAllowed()) {
+                                       
policyItemAccess.setIsAllowed(Boolean.TRUE);
+                                       ret = true;
                                }
+                       } else {
+                               policyItem.getAccesses().add(new 
RangerPolicyItemAccess(accessType, Boolean.TRUE));
+                               ret = true;
                        }
                }
 
-               return isEqualCollection(policyAccessTypes, accessTypes);
+               return ret;
        }
 
-       private boolean isSubsetOfAccessTypes(RangerPolicyItem policyItem, 
Set<String> accessTypes) {
-               if(policyItem == null) {
-                       return false;
-               }
+       private boolean removeAccesses(RangerPolicyItem policyItem, Set<String> 
accessTypes) {
+               boolean ret = false;
+
+               for(String accessType : accessTypes) {
+                       int numOfItems = policyItem.getAccesses().size();
 
-               Set<String> policyAccessTypes = new HashSet<String>();
+                       for(int i = 0; i < numOfItems; i++) {
+                               RangerPolicyItemAccess itemAccess = 
policyItem.getAccesses().get(i);
+                               
+                               if(StringUtils.equals(itemAccess.getType(), 
accessType)) {
+                                       policyItem.getAccesses().remove(i);
+                                       numOfItems--;
+                                       i--;
 
-               if(!CollectionUtils.isEmpty(policyItem.getAccesses())) {
-                       for(RangerPolicyItemAccess policyItemAccess : 
policyItem.getAccesses()) {
-                               if(policyItemAccess.getIsAllowed()) {
-                                       
policyAccessTypes.add(policyItemAccess.getType());
+                                       ret = true;
                                }
                        }
                }
 
-               return isSubCollection(policyAccessTypes, accessTypes);
+               return ret;
        }
 }

Reply via email to