You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ranger.apache.org by ma...@apache.org on 2015/01/31 09:43:15 UTC
[1/4] incubator-ranger git commit: RANGER-230 Hbase plugin
implementation using new pluggable service model.
Repository: incubator-ranger
Updated Branches:
refs/heads/stack 9784f5343 -> 46633a9ed
http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/1d6a2590/hive-agent/.settings/org.eclipse.jdt.core.prefs
----------------------------------------------------------------------
diff --git a/hive-agent/.settings/org.eclipse.jdt.core.prefs b/hive-agent/.settings/org.eclipse.jdt.core.prefs
index 60105c1..0a63fc5 100644
--- a/hive-agent/.settings/org.eclipse.jdt.core.prefs
+++ b/hive-agent/.settings/org.eclipse.jdt.core.prefs
@@ -1,5 +1,10 @@
-eclipse.preferences.version=1
-org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.6
-org.eclipse.jdt.core.compiler.compliance=1.6
+#Wed Jan 21 11:38:50 PST 2015
+encoding/src/test/java=UTF-8
+org.eclipse.jdt.core.compiler.compliance=1.7
+encoding/src/main/resources=UTF-8
org.eclipse.jdt.core.compiler.problem.forbiddenReference=warning
-org.eclipse.jdt.core.compiler.source=1.6
+encoding/src/main/java=UTF-8
+org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.7
+eclipse.preferences.version=1
+encoding/src/test/resources=UTF-8
+org.eclipse.jdt.core.compiler.source=1.7
http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/1d6a2590/knox-agent/.settings/org.eclipse.jdt.core.prefs
----------------------------------------------------------------------
diff --git a/knox-agent/.settings/org.eclipse.jdt.core.prefs b/knox-agent/.settings/org.eclipse.jdt.core.prefs
index 60105c1..ec4300d 100644
--- a/knox-agent/.settings/org.eclipse.jdt.core.prefs
+++ b/knox-agent/.settings/org.eclipse.jdt.core.prefs
@@ -1,5 +1,5 @@
eclipse.preferences.version=1
-org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.6
-org.eclipse.jdt.core.compiler.compliance=1.6
+org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.7
+org.eclipse.jdt.core.compiler.compliance=1.7
org.eclipse.jdt.core.compiler.problem.forbiddenReference=warning
-org.eclipse.jdt.core.compiler.source=1.6
+org.eclipse.jdt.core.compiler.source=1.7
http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/1d6a2590/lookup-client/.settings/org.eclipse.jdt.core.prefs
----------------------------------------------------------------------
diff --git a/lookup-client/.settings/org.eclipse.jdt.core.prefs b/lookup-client/.settings/org.eclipse.jdt.core.prefs
index 69c31cd..443e085 100644
--- a/lookup-client/.settings/org.eclipse.jdt.core.prefs
+++ b/lookup-client/.settings/org.eclipse.jdt.core.prefs
@@ -1,8 +1,8 @@
eclipse.preferences.version=1
org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
-org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.6
-org.eclipse.jdt.core.compiler.compliance=1.6
+org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.7
+org.eclipse.jdt.core.compiler.compliance=1.7
org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
org.eclipse.jdt.core.compiler.problem.forbiddenReference=warning
-org.eclipse.jdt.core.compiler.source=1.6
+org.eclipse.jdt.core.compiler.source=1.7
http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/1d6a2590/lookup-client/.settings/org.eclipse.wst.common.project.facet.core.xml
----------------------------------------------------------------------
diff --git a/lookup-client/.settings/org.eclipse.wst.common.project.facet.core.xml b/lookup-client/.settings/org.eclipse.wst.common.project.facet.core.xml
index c78d932..4f92af5 100644
--- a/lookup-client/.settings/org.eclipse.wst.common.project.facet.core.xml
+++ b/lookup-client/.settings/org.eclipse.wst.common.project.facet.core.xml
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<faceted-project>
- <installed facet="java" version="1.6"/>
<installed facet="jst.utility" version="1.0"/>
+ <installed facet="java" version="1.7"/>
</faceted-project>
http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/1d6a2590/plugin-common/pom.xml
----------------------------------------------------------------------
diff --git a/plugin-common/pom.xml b/plugin-common/pom.xml
index 0aa4583..dc2a914 100644
--- a/plugin-common/pom.xml
+++ b/plugin-common/pom.xml
@@ -66,4 +66,16 @@
<version>${project.version}</version>
</dependency>
</dependencies>
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-surefire-plugin</artifactId>
+ <configuration>
+ <skipTests>true</skipTests>
+ </configuration>
+ </plugin>
+ </plugins>
+ </build>
+
</project>
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/1d6a2590/plugin-common/src/main/java/org/apache/ranger/plugin/policyengine/RangerAccessResult.java
----------------------------------------------------------------------
diff --git a/plugin-common/src/main/java/org/apache/ranger/plugin/policyengine/RangerAccessResult.java b/plugin-common/src/main/java/org/apache/ranger/plugin/policyengine/RangerAccessResult.java
index 20aadf6..2eaec16 100644
--- a/plugin-common/src/main/java/org/apache/ranger/plugin/policyengine/RangerAccessResult.java
+++ b/plugin-common/src/main/java/org/apache/ranger/plugin/policyengine/RangerAccessResult.java
@@ -82,6 +82,13 @@ public class RangerAccessResult {
}
/**
+ * @param reason the reason to set
+ */
+ public void setReason(String reason) {
+ this.reason = reason;
+ }
+
+ /**
* @return the isAudited
*/
public boolean getIsAudited() {
@@ -96,6 +103,13 @@ public class RangerAccessResult {
}
/**
+ * @return the reason
+ */
+ public String getReason() {
+ return reason;
+ }
+
+ /**
* @return the policyId
*/
public long getPolicyId() {
http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/1d6a2590/plugin-common/src/main/java/org/apache/ranger/plugin/policyengine/RangerPolicyEngineImpl.java
----------------------------------------------------------------------
diff --git a/plugin-common/src/main/java/org/apache/ranger/plugin/policyengine/RangerPolicyEngineImpl.java b/plugin-common/src/main/java/org/apache/ranger/plugin/policyengine/RangerPolicyEngineImpl.java
index d2053f5..8f6231b 100644
--- a/plugin-common/src/main/java/org/apache/ranger/plugin/policyengine/RangerPolicyEngineImpl.java
+++ b/plugin-common/src/main/java/org/apache/ranger/plugin/policyengine/RangerPolicyEngineImpl.java
@@ -100,7 +100,7 @@ public class RangerPolicyEngineImpl implements RangerPolicyEngine {
}
if(LOG.isDebugEnabled()) {
- LOG.debug("<== RangerPolicyEngineImpl.setPolicies(" + serviceName + ", " + serviceDef + ", " + policies + ")");
+ LOG.debug("<== RangerPolicyEngineImpl.setPolicies(" + serviceName + ", " + serviceDef + ", policies.count=" + (policies == null ? 0 : policies.size()) + ")");
}
}
http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/1d6a2590/plugin-common/src/main/java/org/apache/ranger/plugin/util/PolicyRefresher.java
----------------------------------------------------------------------
diff --git a/plugin-common/src/main/java/org/apache/ranger/plugin/util/PolicyRefresher.java b/plugin-common/src/main/java/org/apache/ranger/plugin/util/PolicyRefresher.java
index 2437b3e..7112562 100644
--- a/plugin-common/src/main/java/org/apache/ranger/plugin/util/PolicyRefresher.java
+++ b/plugin-common/src/main/java/org/apache/ranger/plugin/util/PolicyRefresher.java
@@ -131,7 +131,7 @@ public class PolicyRefresher extends Thread {
lastKnownPolicies = svcPolicies;
} else {
if(LOG.isDebugEnabled()) {
- LOG.info("PolicyRefresher(serviceName=" + serviceName + ").run(): no update found. lastKnownVersion=" + lastKnownVersion + "; newVersion=" + newVersion);
+ LOG.debug("PolicyRefresher(serviceName=" + serviceName + ").run(): no update found. lastKnownVersion=" + lastKnownVersion + "; newVersion=" + newVersion);
}
}
} catch(Exception excp) {
http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/1d6a2590/pom.xml
----------------------------------------------------------------------
diff --git a/pom.xml b/pom.xml
index 80e3461..d65e5b7 100644
--- a/pom.xml
+++ b/pom.xml
@@ -163,6 +163,7 @@
<tomcat.embed.version>7.0.55</tomcat.embed.version>
<velocity.version>1.7</velocity.version>
<powermock.version>1.5.6</powermock.version>
+ <aspectj.version>1.8.2</aspectj.version>
<distMgmtStagingId>apache.staging.https</distMgmtStagingId>
<distMgmtStagingName>Apache Release Distribution Repository</distMgmtStagingName>
<distMgmtStagingUrl>https://repository.apache.org/service/local/staging/deploy/maven2</distMgmtStagingUrl>
http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/1d6a2590/security-admin/.settings/org.eclipse.jdt.core.prefs
----------------------------------------------------------------------
diff --git a/security-admin/.settings/org.eclipse.jdt.core.prefs b/security-admin/.settings/org.eclipse.jdt.core.prefs
index 69c31cd..443e085 100644
--- a/security-admin/.settings/org.eclipse.jdt.core.prefs
+++ b/security-admin/.settings/org.eclipse.jdt.core.prefs
@@ -1,8 +1,8 @@
eclipse.preferences.version=1
org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
-org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.6
-org.eclipse.jdt.core.compiler.compliance=1.6
+org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.7
+org.eclipse.jdt.core.compiler.compliance=1.7
org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
org.eclipse.jdt.core.compiler.problem.forbiddenReference=warning
-org.eclipse.jdt.core.compiler.source=1.6
+org.eclipse.jdt.core.compiler.source=1.7
http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/1d6a2590/security-admin/.settings/org.eclipse.wst.common.project.facet.core.xml
----------------------------------------------------------------------
diff --git a/security-admin/.settings/org.eclipse.wst.common.project.facet.core.xml b/security-admin/.settings/org.eclipse.wst.common.project.facet.core.xml
index ec4f11f..81ac8e9 100644
--- a/security-admin/.settings/org.eclipse.wst.common.project.facet.core.xml
+++ b/security-admin/.settings/org.eclipse.wst.common.project.facet.core.xml
@@ -1,9 +1,9 @@
<?xml version="1.0" encoding="UTF-8"?>
<faceted-project>
<fixed facet="wst.jsdt.web"/>
- <installed facet="java" version="1.6"/>
<installed facet="jst.web" version="3.0"/>
<installed facet="jst.jaxrs" version="1.1"/>
<installed facet="jpt.jpa" version="2.0"/>
<installed facet="wst.jsdt.web" version="1.0"/>
+ <installed facet="java" version="1.7"/>
</faceted-project>
http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/1d6a2590/storm-agent/.settings/org.eclipse.jdt.core.prefs
----------------------------------------------------------------------
diff --git a/storm-agent/.settings/org.eclipse.jdt.core.prefs b/storm-agent/.settings/org.eclipse.jdt.core.prefs
index 60105c1..ec4300d 100644
--- a/storm-agent/.settings/org.eclipse.jdt.core.prefs
+++ b/storm-agent/.settings/org.eclipse.jdt.core.prefs
@@ -1,5 +1,5 @@
eclipse.preferences.version=1
-org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.6
-org.eclipse.jdt.core.compiler.compliance=1.6
+org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.7
+org.eclipse.jdt.core.compiler.compliance=1.7
org.eclipse.jdt.core.compiler.problem.forbiddenReference=warning
-org.eclipse.jdt.core.compiler.source=1.6
+org.eclipse.jdt.core.compiler.source=1.7
http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/1d6a2590/ugsync/.settings/org.eclipse.jdt.core.prefs
----------------------------------------------------------------------
diff --git a/ugsync/.settings/org.eclipse.jdt.core.prefs b/ugsync/.settings/org.eclipse.jdt.core.prefs
index 60105c1..ec4300d 100644
--- a/ugsync/.settings/org.eclipse.jdt.core.prefs
+++ b/ugsync/.settings/org.eclipse.jdt.core.prefs
@@ -1,5 +1,5 @@
eclipse.preferences.version=1
-org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.6
-org.eclipse.jdt.core.compiler.compliance=1.6
+org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.7
+org.eclipse.jdt.core.compiler.compliance=1.7
org.eclipse.jdt.core.compiler.problem.forbiddenReference=warning
-org.eclipse.jdt.core.compiler.source=1.6
+org.eclipse.jdt.core.compiler.source=1.7
http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/1d6a2590/unixauthclient/.settings/org.eclipse.jdt.core.prefs
----------------------------------------------------------------------
diff --git a/unixauthclient/.settings/org.eclipse.jdt.core.prefs b/unixauthclient/.settings/org.eclipse.jdt.core.prefs
index 69c31cd..443e085 100644
--- a/unixauthclient/.settings/org.eclipse.jdt.core.prefs
+++ b/unixauthclient/.settings/org.eclipse.jdt.core.prefs
@@ -1,8 +1,8 @@
eclipse.preferences.version=1
org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
-org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.6
-org.eclipse.jdt.core.compiler.compliance=1.6
+org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.7
+org.eclipse.jdt.core.compiler.compliance=1.7
org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
org.eclipse.jdt.core.compiler.problem.forbiddenReference=warning
-org.eclipse.jdt.core.compiler.source=1.6
+org.eclipse.jdt.core.compiler.source=1.7
http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/1d6a2590/unixauthclient/.settings/org.eclipse.wst.common.project.facet.core.xml
----------------------------------------------------------------------
diff --git a/unixauthclient/.settings/org.eclipse.wst.common.project.facet.core.xml b/unixauthclient/.settings/org.eclipse.wst.common.project.facet.core.xml
index c78d932..4f92af5 100644
--- a/unixauthclient/.settings/org.eclipse.wst.common.project.facet.core.xml
+++ b/unixauthclient/.settings/org.eclipse.wst.common.project.facet.core.xml
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<faceted-project>
- <installed facet="java" version="1.6"/>
<installed facet="jst.utility" version="1.0"/>
+ <installed facet="java" version="1.7"/>
</faceted-project>
http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/1d6a2590/unixauthservice/.settings/org.eclipse.jdt.core.prefs
----------------------------------------------------------------------
diff --git a/unixauthservice/.settings/org.eclipse.jdt.core.prefs b/unixauthservice/.settings/org.eclipse.jdt.core.prefs
index 60105c1..ec4300d 100644
--- a/unixauthservice/.settings/org.eclipse.jdt.core.prefs
+++ b/unixauthservice/.settings/org.eclipse.jdt.core.prefs
@@ -1,5 +1,5 @@
eclipse.preferences.version=1
-org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.6
-org.eclipse.jdt.core.compiler.compliance=1.6
+org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.7
+org.eclipse.jdt.core.compiler.compliance=1.7
org.eclipse.jdt.core.compiler.problem.forbiddenReference=warning
-org.eclipse.jdt.core.compiler.source=1.6
+org.eclipse.jdt.core.compiler.source=1.7
[2/4] incubator-ranger git commit: RANGER-230 Hbase plugin
implementation using new pluggable service model.
Posted by ma...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/1d6a2590/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 3d14575..68bd7ac 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
@@ -23,9 +23,12 @@ import java.util.ArrayList;
import java.util.Arrays;
import java.util.Calendar;
import java.util.Collection;
+import java.util.Collections;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
@@ -33,17 +36,15 @@ import java.util.NavigableSet;
import java.util.Set;
import java.util.TimeZone;
-import org.apache.commons.lang.StringUtils;
+import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.hbase.Cell;
-import org.apache.hadoop.hbase.CellUtil;
import org.apache.hadoop.hbase.CoprocessorEnvironment;
import org.apache.hadoop.hbase.HColumnDescriptor;
import org.apache.hadoop.hbase.HRegionInfo;
import org.apache.hadoop.hbase.HTableDescriptor;
-import org.apache.hadoop.hbase.KeyValue;
import org.apache.hadoop.hbase.NamespaceDescriptor;
import org.apache.hadoop.hbase.ServerName;
import org.apache.hadoop.hbase.TableName;
@@ -63,9 +64,9 @@ import org.apache.hadoop.hbase.coprocessor.RegionCoprocessorEnvironment;
import org.apache.hadoop.hbase.coprocessor.RegionServerCoprocessorEnvironment;
import org.apache.hadoop.hbase.filter.ByteArrayComparable;
import org.apache.hadoop.hbase.filter.CompareFilter.CompareOp;
+import org.apache.hadoop.hbase.filter.Filter;
import org.apache.hadoop.hbase.filter.FilterList;
import org.apache.hadoop.hbase.ipc.RequestContext;
-import org.apache.hadoop.hbase.master.RegionPlan;
import org.apache.hadoop.hbase.protobuf.ProtobufUtil;
import org.apache.hadoop.hbase.protobuf.ResponseConverter;
import org.apache.hadoop.hbase.protobuf.generated.AccessControlProtos;
@@ -84,21 +85,23 @@ import org.apache.hadoop.hbase.security.AccessDeniedException;
import org.apache.hadoop.hbase.security.User;
import org.apache.hadoop.hbase.security.access.Permission;
import org.apache.hadoop.hbase.security.access.Permission.Action;
+import org.apache.hadoop.hbase.security.access.RangerAccessControlLists;
import org.apache.hadoop.hbase.security.access.TablePermission;
import org.apache.hadoop.hbase.security.access.UserPermission;
-import org.apache.hadoop.hbase.security.access.RangerAccessControlLists;
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.audit.model.EnumRepositoryType;
import org.apache.ranger.audit.model.AuthzAuditEvent;
-import org.apache.ranger.audit.provider.AuditProviderFactory;
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 com.google.common.base.Objects;
import com.google.common.collect.Lists;
import com.google.common.collect.MapMaker;
import com.google.common.collect.Maps;
@@ -109,25 +112,28 @@ 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 RangerModuleName = RangerConfiguration.getInstance().get(RangerHadoopConstants.AUDITLOG_RANGER_MODULE_ACL_NAME_PROP , RangerHadoopConstants.DEFAULT_RANGER_MODULE_ACL_NAME) ;
- private static final short accessGrantedFlag = 1;
- private static final short accessDeniedFlag = 0;
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 final String GROUP_PREFIX = "@";
-
private static final String SUPERUSER_CONFIG_PROP = "hbase.superuser";
private static final String WILDCARD = "*";
- private static final byte[] WILDCARD_MATCH = "*".getBytes();
private static final TimeZone gmtTimeZone = TimeZone.getTimeZone("GMT+0");
private RegionCoprocessorEnvironment regionEnv;
private Map<InternalScanner, String> scannerOwners = new MapMaker().weakKeys().makeMap();
- private HBaseAccessController accessController = HBaseAccessControllerFactory.getInstance();
private List<String> superUserList = null;
+
+ /*
+ * 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();
+
// Utilities Methods
protected byte[] getTableName(RegionCoprocessorEnvironment e) {
HRegion region = e.getRegion();
@@ -140,7 +146,7 @@ public class RangerAuthorizationCoprocessor extends RangerAuthorizationCoprocess
}
return tableName;
}
- protected void isSystemOrSuperUser(Configuration conf) throws IOException {
+ protected void requireSystemOrSuperUser(Configuration conf) throws IOException {
User user = User.getCurrent();
if (user == null) {
throw new IOException("Unable to obtain the current user, authorization checks for internal operations will not work correctly!");
@@ -169,16 +175,16 @@ public class RangerAuthorizationCoprocessor extends RangerAuthorizationCoprocess
protected boolean isSpecialTable(String tableNameStr) {
return tableNameStr.equals("hbase:meta") || tableNameStr.equals("-ROOT-") || tableNameStr.equals(".META.");
}
- @SuppressWarnings("unused")
- private String getUser() {
- User u = getActiveUser();
- if (u == null) {
- return "(user:unknown)";
+ protected boolean isAccessForMetaTables(RegionCoprocessorEnvironment env) {
+ HRegionInfo hri = env.getRegion().getRegionInfo();
+
+ if (hri.isMetaTable() || hri.isMetaRegion()) {
+ return true;
} else {
- String groups = (u.getGroupNames() == null) ? "" : StringUtils.join(u.getGroupNames(), ",");
- return "(user:" + u.getShortName() + ", groups: [" + groups + "])";
+ return false;
}
}
+
private User getActiveUser() {
User user = RequestContext.getRequestUser();
if (!RequestContext.isInRequestContext()) {
@@ -211,148 +217,384 @@ public class RangerAuthorizationCoprocessor extends RangerAuthorizationCoprocess
}
}
}
- // Methods that are delegated to AUTHManager
- public boolean isPermissionGranted(User user, Action action) {
- if (isSuperUser(user)) {
- return true;
- } else {
- return accessController.isAccessAllowed(user, action);
+
+ /**
+ * @param families
+ * @return empty map if families is null, would never have empty or null keys, would never have null values, values could be empty (non-null) set
+ */
+ Map<String, Set<String>> getColumnFamilies(Map<byte[], ? extends Collection<?>> families) {
+ if (families == null) {
+ // null families map passed. Ok, returning empty map.
+ return Collections.<String, Set<String>>emptyMap();
}
- }
- public boolean isPermissionGranted(User user, byte[] tableName, Action action) {
- if (isSuperUser(user)) {
- return true;
- } else {
- return accessController.isAccessAllowed(user, tableName, action);
+ Map<String, Set<String>> result = new HashMap<String, Set<String>>();
+ for (Map.Entry<byte[], ? extends Collection<?>> anEntry : families.entrySet()) {
+ byte[] familyBytes = anEntry.getKey();
+ String family = Bytes.toString(familyBytes);
+ if (family == null || family.isEmpty()) {
+ LOG.error("Unexpected Input: got null or empty column family (key) in families map! Ignoring...");
+ } else {
+ Collection<?> columnCollection = anEntry.getValue();
+ if (CollectionUtils.isEmpty(columnCollection)) {
+ // family points to null map, OK.
+ result.put(family, Collections.<String> emptySet());
+ } else {
+ Iterator<String> columnIterator = new ColumnIterator(columnCollection);
+ Set<String> columns = new HashSet<String>();
+ while (columnIterator.hasNext()) {
+ String column = columnIterator.next();
+ columns.add(column);
+ }
+ result.put(family, columns);
+ }
+ }
}
+ return result;
}
- public boolean isPermissionGranted(User user, byte[] tableName, byte[] colf, Action action) {
- if (isSuperUser(user)) {
- return true;
- } else {
- return accessController.isAccessAllowed(user, tableName, colf, WILDCARD_MATCH, action);
+
+ static class ColumnFamilyAccessResult {
+ final boolean _everythingIsAccessible;
+ final boolean _somethingIsAccessible;
+ final List<AuthzAuditEvent> _accessAllowedEvents;
+ final AuthzAuditEvent _accessDeniedEvent;
+ final Map<String, Set<String>> _allowedColumns;
+ final String _denialReason;
+
+ ColumnFamilyAccessResult(
+ boolean everythingIsAccessible, boolean somethingIsAccessible,
+ List<AuthzAuditEvent> accessAllowedEvents, AuthzAuditEvent accessDeniedEvent,
+ Map<String, Set<String>> allowedColumns, String denialReason) {
+ _everythingIsAccessible = everythingIsAccessible;
+ _somethingIsAccessible = somethingIsAccessible;
+ // WARNING: we are just holding on to reference of the collection. Potentially risky optimization
+ _accessAllowedEvents = accessAllowedEvents;
+ _accessDeniedEvent = accessDeniedEvent;
+ _allowedColumns = allowedColumns;
+ _denialReason = denialReason;
}
- }
- public boolean isPermissionGranted(User user, byte[] tableName, byte[] colf, byte[] col, Action action) {
- if (isSuperUser(user)) {
- return true;
- } else {
- return accessController.isAccessAllowed(user, tableName, colf, col, action);
+
+ @Override
+ public String toString() {
+ return Objects.toStringHelper(getClass())
+ .add("everythingIsAccessible", _everythingIsAccessible)
+ .add("somethingIsAccessible", _somethingIsAccessible)
+ .add("accessAllowedEvents", _accessAllowedEvents)
+ .add("accessDeniedEvent", _accessDeniedEvent)
+ .add("allowedColumns", _allowedColumns)
+ .add("denialReason", _denialReason)
+ .toString();
+
}
}
- // Methods that are internally used by co-processors
- @SuppressWarnings("unchecked")
- public void requirePermission(String request, Action action, RegionCoprocessorEnvironment rEnv, Map<byte[], ? extends Collection<?>> families) throws IOException {
- HRegionInfo hri = rEnv.getRegion().getRegionInfo();
- byte[] tableName = hri.getTable().getName() ;
- String tableNameStr = Bytes.toString(tableName);
- if (hri.isMetaTable() || hri.isMetaRegion()) {
- if (action == TablePermission.Action.READ) {
- return;
+
+ ColumnFamilyAccessResult evaluateAccess(String operation, Action action, final RegionCoprocessorEnvironment env,
+ final Map<byte[], ? extends Collection<?>> familyMap) throws AccessDeniedException {
+
+ String access = _authUtils.getAccess(action);
+
+ if (LOG.isDebugEnabled()) {
+ final String format = "evaluateAccess: entered: Operation[%s], access[%s], families[%s]";
+ Map<String, Set<String>> families = getColumnFamilies(familyMap);
+ String message = String.format(format, operation, access, families);
+ LOG.debug(message);
+ }
+
+ byte[] tableBytes = getTableName(env);
+ if (tableBytes == null || tableBytes.length == 0) {
+ String message = "evaluateAccess: Unexpected: Couldn't get table from RegionCoprocessorEnvironment. Access denied, not audited";
+ LOG.debug(message);
+ throw new AccessDeniedException("Insufficient permissions for operation '" + operation + "',action: " + action);
+ }
+ String table = Bytes.toString(tableBytes);
+
+ final String messageTemplate = "evaluateAccess: exiting: Operation[%s], access[%s], families[%s], verdict[%s]";
+ ColumnFamilyAccessResult result;
+ if (canSkipAccessCheck(operation, access, table) || canSkipAccessCheck(operation, access, env)) {
+ LOG.debug("evaluateAccess: exiting: isKnownAccessPattern returned true: access allowed, not audited");
+ result = new ColumnFamilyAccessResult(true, true, null, null, null, null);
+ if (LOG.isDebugEnabled()) {
+ Map<String, Set<String>> families = getColumnFamilies(familyMap);
+ String message = String.format(messageTemplate, operation, access, families, result.toString());
+ LOG.debug(message);
}
+ return result;
}
+
User user = getActiveUser();
- if (user == null) {
- throw new AccessDeniedException("No user associated with request (" + request + ") for action: " + action + "on table:" + tableName);
+ // 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)
+ .operation(operation)
+ .remoteAddress(getRemoteAddress())
+ .auditHandler(auditHandler)
+ .user(user)
+ .access(access)
+ .table(table);
+ Map<String, Set<String>> families = getColumnFamilies(familyMap);
+ if (families == null || families.isEmpty()) {
+ // table level access is desired
+ session.buildRequest()
+ .authorize();
+ boolean authorized = session.isAuthorized();
+ String reason = "";
+ if (!authorized) {
+ reason = String.format("Insufficient permissions for user ‘%s',action: %s, tableName:%s, no column families found.", user.getName(), operation, table);
+ }
+ AuthzAuditEvent event = auditHandler.discardMostRecentEvent(); // this could be null, of course, depending on audit settings of table.
+
+ // if authorized then pass captured events as access allowed set else as access denied set.
+ result = new ColumnFamilyAccessResult(authorized, authorized,
+ authorized ? Collections.singletonList(event) : null,
+ authorized ? null : event, null, reason);
+ if (LOG.isDebugEnabled()) {
+ String message = String.format(messageTemplate, operation, access, families, result.toString());
+ LOG.debug(message);
+ }
+ return result;
}
- if (isSuperUser(user)) {
- return;
+
+ boolean everythingIsAccessible = true;
+ boolean somethingIsAccessible = false;
+ // we would have to accumulate audits of all successful accesses and any one denial (which in our case ends up being the last denial)
+ List<AuthzAuditEvent> authorizedEvents = new ArrayList<AuthzAuditEvent>();
+ AuthzAuditEvent deniedEvent = null;
+ String denialReason = null;
+ // we need to cache the auths results so that we can create a filter, if needed
+ Map<String, Set<String>> accessResultsCache = new HashMap<String, Set<String>>();
+
+ for (Map.Entry<String, Set<String>> anEntry : families.entrySet()) {
+ String family = anEntry.getKey();
+ session.columnFamily(family);
+
+ Set<String> columns = anEntry.getValue();
+ if (columns == null || columns.isEmpty()) {
+ // family level access is desired.
+ session.column(null) // zap stale column from prior iteration of this loop, if any
+ .buildRequest()
+ .authorize();
+ if (session.isAuthorized()) {
+ // we need to do 3 things: housekeeping, capturing audit events, building the results cache for filter
+ somethingIsAccessible = true;
+ AuthzAuditEvent event = auditHandler.discardMostRecentEvent();
+ if (event != null) {
+ authorizedEvents.add(event);
+ }
+ // presence of key with null value would imply access to all columns in a family.
+ accessResultsCache.put(family, null);
+ } else {
+ everythingIsAccessible = false;
+ deniedEvent = auditHandler.discardMostRecentEvent();
+ denialReason = String.format("Insufficient permissions for user ‘%s',action: %s, tableName:%s, family:%s, no columns found.", user.getName(), operation, table, family);
+ }
+ } else {
+ Set<String> accessibleColumns = new HashSet<String>(); // will be used in to populate our results cache for the filter
+ for (String column : columns) {
+ session.column(column)
+ .buildRequest()
+ .authorize();
+ if (session.isAuthorized()) {
+ // we need to do 3 things: housekeeping, capturing audit events, building the results cache for filter
+ somethingIsAccessible = true;
+ AuthzAuditEvent event = auditHandler.discardMostRecentEvent();
+ if (event != null) {
+ authorizedEvents.add(event);
+ }
+ accessibleColumns.add(column);
+ } else {
+ everythingIsAccessible = false;
+ deniedEvent = auditHandler.discardMostRecentEvent();
+ denialReason = String.format("Insufficient permissions for user ‘%s',action: %s, tableName:%s, family:%s, column: %s", user.getName(), operation, table, family, column);
+ }
+ }
+ if (!accessibleColumns.isEmpty()) {
+ accessResultsCache.put(family, accessibleColumns);
+ }
+ }
}
- if (action == TablePermission.Action.WRITE && (hri.isMetaTable() || hri.isMetaRegion()) && (isPermissionGranted(user, Permission.Action.CREATE) || isPermissionGranted(user, Permission.Action.ADMIN))) {
- return;
+
+ result = new ColumnFamilyAccessResult(everythingIsAccessible, somethingIsAccessible, authorizedEvents, deniedEvent, accessResultsCache, denialReason);
+ if (LOG.isDebugEnabled()) {
+ String message = String.format(messageTemplate, operation, access, families, result.toString());
+ LOG.debug(message);
}
- if (isPermissionGranted(user, tableName, (byte[]) null, action)) {
+ return result;
+ }
+
+ Filter authorizeAccess(String operation, Action action, final RegionCoprocessorEnvironment env, final Map<byte[], NavigableSet<byte[]>> familyMap) throws AccessDeniedException {
+
+ ColumnFamilyAccessResult accessResult = evaluateAccess(operation, action, env, familyMap);
+ RangerDefaultAuditHandler auditHandler = new RangerDefaultAuditHandler();
+ if (accessResult._everythingIsAccessible) {
+ auditHandler.logAuthzAudits(accessResult._accessAllowedEvents);
+ LOG.debug("authorizeAccess: exiting: No filter returned since all access was allowed");
+ return null; // no filter needed since we are good to go.
+ } else if (accessResult._somethingIsAccessible) {
+ auditHandler.logAuthzAudits(accessResult._accessAllowedEvents); // we still need to log those to which we got access.
+ LOG.debug("authorizeAccess: exiting: Filter returned since some access was allowed");
+ return new RangerAuthorizationFilter(accessResult._allowedColumns);
+ } else {
+ // If we are here then it means nothing was accessible! So let's log one denial (in our case, the last denial) and throw an exception
+ auditHandler.logAuthzAudit(accessResult._accessDeniedEvent);
+ LOG.debug("authorizeAccess: exiting: Throwing exception since nothing was accessible");
+ throw new AccessDeniedException(accessResult._denialReason);
+ }
+ }
+
+ Filter combineFilters(Filter filter, Filter existingFilter) {
+ Filter combinedFilter = filter;
+ if (existingFilter != null) {
+ combinedFilter = new FilterList(FilterList.Operator.MUST_PASS_ALL, Lists.newArrayList(filter, existingFilter));
+ }
+ return combinedFilter;
+ }
+
+ void requirePermission(final String operation, final Action action, final RegionCoprocessorEnvironment regionServerEnv, final Map<byte[], ? extends Collection<?>> familyMap)
+ throws AccessDeniedException {
+
+ ColumnFamilyAccessResult accessResult = evaluateAccess(operation, action, regionServerEnv, familyMap);
+ RangerDefaultAuditHandler auditHandler = new RangerDefaultAuditHandler();
+ if (accessResult._everythingIsAccessible) {
+ auditHandler.logAuthzAudits(accessResult._accessAllowedEvents);
+ LOG.debug("requirePermission: exiting: all access was allowed");
return;
+ } else {
+ auditHandler.logAuthzAudit(accessResult._accessDeniedEvent);
+ LOG.debug("requirePermission: exiting: throwing exception as everything wasn't accessible");
+ throw new AccessDeniedException(accessResult._denialReason);
}
- if (families != null && families.size() > 0) {
- // all families must pass
- for (Map.Entry<byte[], ? extends Collection<?>> family : families.entrySet()) {
- // a) check for family level access
- if (isPermissionGranted(user, tableName, family.getKey(), action)) {
- continue; // family-level permission overrides per-qualifier
- }
- // b) qualifier level access can still succeed
- if ((family.getValue() != null) && (family.getValue().size() > 0)) {
- if (family.getValue() instanceof Set) { // Set<byte[]> - Set
- // of Columns
- // for each qualifier of the family
- Set<byte[]> qualifierSet = (Set<byte[]>) family.getValue();
- for (byte[] qualifier : qualifierSet) {
- if (!isPermissionGranted(user, tableName, family.getKey(), qualifier, action)) {
- if (accessController.isAudited(tableName)) {
- auditEvent(request, tableName, family.getKey(), qualifier, null, null, user, accessDeniedFlag);
- }
- throw new AccessDeniedException("Insufficient permissions for user '" + user + "',action: " + action + ", tableName:" + tableNameStr + ", family:" + Bytes.toString(family.getKey()) + ",column: " + Bytes.toString(qualifier));
- }
- }
- } else if (family.getValue() instanceof List) { // List<KeyValue>
- // - List of
- // KeyValue
- // pair
- List<KeyValue> kvList = (List<KeyValue>) family.getValue();
- for (KeyValue kv : kvList) {
- if (!isPermissionGranted(user, tableName, family.getKey(), kv.getQualifier(), action)) {
- if (accessController.isAudited(tableName)) {
- auditEvent(request, tableName, family.getKey(), kv.getQualifier(), null, null, user, accessDeniedFlag);
- }
- throw new AccessDeniedException("Insufficient permissions for user '" + user + "',action: " + action + ", tableName:" + tableNameStr + ", family:" + Bytes.toString(family.getKey()) + ",column: " + Bytes.toString(kv.getQualifier()));
- }
- }
- }
- } else {
- if (accessController.isAudited(tableName)) {
- auditEvent(request, tableName, family.getKey(), null, null, null, user, accessDeniedFlag);
- }
- throw new AccessDeniedException("Insufficient permissions for user '" + user + "',action: " + action + ", tableName:" + tableNameStr + ", family:" + Bytes.toString(family.getKey()) + ", no columns found.");
- }
+ }
+
+ /**
+ * This could run s
+ * @param operation
+ * @param otherInformation
+ * @param access
+ * @param table
+ * @param columnFamily
+ * @param column
+ * @return
+ * @throws AccessDeniedException
+ */
+ void authorizeAccess(String operation, String otherInformation, Action action, String table, String columnFamily, String column) throws AccessDeniedException {
+
+ String access = _authUtils.getAccess(action);
+ if (LOG.isDebugEnabled()) {
+ final String format = "authorizeAccess: %s: Operation[%s], Info[%s], access[%s], table[%s], columnFamily[%s], column[%s]";
+ String message = String.format(format, "Entering", operation, otherInformation, access, table, columnFamily, column);
+ LOG.debug(message);
+ }
+
+ final String format = "authorizeAccess: %s: Operation[%s], Info[%s], access[%s], table[%s], columnFamily[%s], column[%s], allowed[%s], reason[%s]";
+ if (canSkipAccessCheck(operation, access, table)) {
+ if (LOG.isDebugEnabled()) {
+ String message = String.format(format, "Exiting", operation, otherInformation, access, table, columnFamily, column, true, "can skip auth check");
+ LOG.debug(message);
}
return;
}
- if (accessController.isAudited(tableName)) {
- auditEvent(request, tableName, null, null, null, null, user, accessDeniedFlag);
+ User user = getActiveUser();
+
+ HbaseAuditHandler auditHandler = _factory.getAuditHandler();
+ AuthorizationSession session = new AuthorizationSession(_authorizer)
+ .operation(operation)
+ .otherInformation(otherInformation)
+ .remoteAddress(getRemoteAddress())
+ .auditHandler(auditHandler)
+ .user(user)
+ .access(access)
+ .table(table)
+ .columnFamily(columnFamily)
+ .column(column)
+ .buildRequest()
+ .authorize();
+
+ if (LOG.isDebugEnabled()) {
+ boolean allowed = session.isAuthorized();
+ String reason = session.getDenialReason();
+ String message = String.format(format, "Exiting", operation, otherInformation, access, table, columnFamily, column, allowed, reason);
+ LOG.debug(message);
}
- throw new AccessDeniedException("Insufficient permissions for user '" + user + "',action: " + action + ", tableName:" + tableNameStr);
+
+ session.publishResults();
}
- // Check if the user has global permission ...
- protected void requireGlobalPermission(String request, String objName, Permission.Action action) throws AccessDeniedException {
+
+ boolean canSkipAccessCheck(final String operation, String access, final String table)
+ throws AccessDeniedException {
+
User user = getActiveUser();
- if (!isPermissionGranted(user, action)) {
- if (accessController.isAudited(WILDCARD_MATCH)) {
- auditEvent(request, objName, null, null, null, null, user, accessDeniedFlag);
- }
- throw new AccessDeniedException("Insufficient permissions for user '" + getActiveUser() + "' (global, action=" + action + ")");
+ boolean result = false;
+ if (user == null) {
+ String message = "Unexpeceted: User is null: access denied, not audited!";
+ LOG.warn("canSkipAccessCheck: exiting" + message);
+ throw new AccessDeniedException("No user associated with request (" + operation + ") for action: " + access + "on table:" + table);
+ } else if (isSuperUser(user)) {
+ LOG.debug("canSkipAccessCheck: true: superuser access allowed, not audited");
+ result = true;
+ } else if (isAccessForMetadataRead(access, table)) {
+ LOG.debug("canSkipAccessCheck: true: metadata read access always allowed, not audited");
+ result = true;
+ } else {
+ LOG.debug("Can't skip access checks");
}
+
+ return result;
}
- protected void requirePermission(String request, byte[] tableName, Permission.Action action) throws AccessDeniedException {
+
+ boolean canSkipAccessCheck(final String operation, String access, final RegionCoprocessorEnvironment regionServerEnv) throws AccessDeniedException {
+
User user = getActiveUser();
- if (!isPermissionGranted(user, tableName, action)) {
- if (accessController.isAudited(tableName)) {
- auditEvent(request, tableName, null, null, null, null, user, accessDeniedFlag);
+ // read access to metadata tables is always allowed and isn't audited.
+ if (isAccessForMetaTables(regionServerEnv) && _authUtils.isReadAccess(access)) {
+ LOG.debug("isKnownAccessPattern: exiting: Read access for metadata tables allowed, not audited!");
+ return true;
+ }
+ // 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)
+ .operation(operation)
+ .remoteAddress(getRemoteAddress())
+ .user(user)
+ .access(createAccess)
+ .buildRequest()
+ .authorize();
+ if (session.isAuthorized()) {
+ // NOTE: this access isn't logged
+ LOG.debug("isKnownAccessPattern: exiting: User has global create access, allowed!");
+ return true;
}
- throw new AccessDeniedException("Insufficient permissions for user '" + getActiveUser() + "' (global, action=" + action + ")");
}
+ return false;
+ }
+
+ boolean isAccessForMetadataRead(String access, String table) {
+ if (_authUtils.isReadAccess(access) && isSpecialTable(table)) {
+ LOG.debug("isAccessForMetadataRead: Metadata tables read: access allowed!");
+ return true;
+ }
+ return false;
}
- protected void requirePermission(String request, byte[] aTableName, byte[] aColumnFamily, byte[] aQualifier, Permission.Action... actions) throws AccessDeniedException {
- User user = getActiveUser();
- boolean isAllowed = false;
- for (Action action : actions) {
- isAllowed = isPermissionGranted(user, aTableName, aColumnFamily, aQualifier, action);
+ // Check if the user has global permission ...
+ protected void requireGlobalPermission(String request, String objName, Permission.Action action) throws AccessDeniedException {
+ authorizeAccess(request, objName, action, null, null, null);
+ }
- if(isAllowed) {
- break;
- }
- }
-
- if (!isAllowed) {
- if (accessController.isAudited(aTableName)) {
- auditEvent(request, aTableName, aColumnFamily, aQualifier, null, null, user, accessDeniedFlag);
- }
- Permission.Action deniedAction = actions.length > 0 ? actions[0] : null;
+ protected void requirePermission(String request, byte[] tableName, Permission.Action action) throws AccessDeniedException {
+ String table = Bytes.toString(tableName);
- throw new AccessDeniedException("Insufficient permissions for user '" + user + "',action: " + deniedAction + ", tableName:" + Bytes.toString(aTableName) + ", family:" + Bytes.toString(aColumnFamily) + ",column: " + Bytes.toString(aQualifier));
- }
+ authorizeAccess(request, null, action, table, null, null);
+ }
+
+ protected void requirePermission(String request, byte[] aTableName, byte[] aColumnFamily, byte[] aQualifier, Permission.Action action) throws AccessDeniedException {
+
+ String table = Bytes.toString(aTableName);
+ String columnFamily = Bytes.toString(aColumnFamily);
+ String column = Bytes.toString(aQualifier);
+
+ authorizeAccess(request, null, action, table, columnFamily, column);
}
+
protected void requirePermission(String request, Permission.Action perm, RegionCoprocessorEnvironment env, Collection<byte[]> families) throws IOException {
HashMap<byte[], Set<byte[]>> familyMap = new HashMap<byte[], Set<byte[]>>();
@@ -363,44 +605,6 @@ public class RangerAuthorizationCoprocessor extends RangerAuthorizationCoprocess
}
requirePermission(request, perm, env, familyMap);
}
- protected boolean isPermissionGranted(String request, User requestUser, Permission.Action perm, RegionCoprocessorEnvironment env, Map<byte[], NavigableSet<byte[]>> familyMap) {
- boolean ret = true;
- try {
- requirePermission(request, perm, env, familyMap);
- } catch (Throwable t) {
- ret = false;
- }
- return ret;
- }
- protected boolean hasFamilyQualifierPermission(User requestUser, Permission.Action perm, RegionCoprocessorEnvironment env, Map<byte[], NavigableSet<byte[]>> familyMap) {
- User user = requestUser;
- byte[] tableName = getTableName(env);
- if (familyMap != null && familyMap.size() > 0) {
- for (Map.Entry<byte[], NavigableSet<byte[]>> family : familyMap.entrySet()) {
- if (family.getValue() != null && !family.getValue().isEmpty()) {
- for (byte[] qualifier : family.getValue()) {
- boolean isGranted = isPermissionGranted(user, tableName, family.getKey(), qualifier, perm);
- LOG.info(":=> hasFamilyQualifierPermission: T(" + Bytes.toString(tableName) + "), family: (" + Bytes.toString(family.getKey() ) + "), Q(" + Bytes.toString(qualifier) + "), Permission: [" + perm + "] => [" + isGranted + "]") ;
- if (isGranted) {
- return true;
- }
- }
- } else {
- boolean isGranted = isPermissionGranted(user, tableName, family.getKey(), perm);
- LOG.info(":=> hasFamilyPermission: T(" + Bytes.toString(tableName) + "), family: (" + Bytes.toString(family.getKey() ) + ", Permission: [" + perm + "] => [" + isGranted + "]") ;
- if (isGranted) {
- return true;
- }
- }
- }
- } else {
- if (LOG.isDebugEnabled()) {
- LOG.debug("Empty family map passed for permission check");
- }
- }
- return false;
- }
-
public void checkPermissions(Permission[] permissions) throws IOException {
String tableName = regionEnv.getRegion().getTableDesc().getTableName().getNameAsString() ;
@@ -432,120 +636,26 @@ public class RangerAuthorizationCoprocessor extends RangerAuthorizationCoprocess
}
@Override
- public void postAddColumn(ObserverContext<MasterCoprocessorEnvironment> c, TableName tableName, HColumnDescriptor column) throws IOException {
- auditEvent("addColumn", tableName.getName(), column.getName(), null, null, null, getActiveUser(), accessGrantedFlag);
- }
- @Override
- public void postAssign(ObserverContext<MasterCoprocessorEnvironment> c, HRegionInfo regionInfo) throws IOException {
- auditEvent("assign", regionInfo.getTable().getNameAsString(), null, null, null, null, getActiveUser(), accessGrantedFlag);
- }
- @Override
- public void postBalance(ObserverContext<MasterCoprocessorEnvironment> c,List<RegionPlan> aRegPlanList) throws IOException {
- auditEvent("balance", (String) null, null, null, null, null, getActiveUser(), accessGrantedFlag);
- }
- @Override
- public void postBalanceSwitch(ObserverContext<MasterCoprocessorEnvironment> c, boolean oldValue, boolean newValue) throws IOException {
- auditEvent("balanceSwitch", (String) null, null, null, null, null, getActiveUser(), accessGrantedFlag);
- }
- @Override
- public void postCloneSnapshot(ObserverContext<MasterCoprocessorEnvironment> ctx, SnapshotDescription snapshot, HTableDescriptor hTableDescriptor) throws IOException {
- auditEvent("cloneSnapshot", hTableDescriptor.getNameAsString(), null, null, null, null, getActiveUser(), accessGrantedFlag);
- }
- @Override
- public void postCreateTable(ObserverContext<MasterCoprocessorEnvironment> ctx, HTableDescriptor desc, HRegionInfo[] regions) throws IOException {
- auditEvent("createTable", desc.getNameAsString(), null, null, null, null, getActiveUser(), accessGrantedFlag);
- }
- @Override
- public void postDelete(ObserverContext<RegionCoprocessorEnvironment> c, Delete delete, WALEdit edit, Durability durability) throws IOException {
- auditEvent("delete", delete.toString(), null, null, null, null, getActiveUser(), accessGrantedFlag);
- }
- @Override
- public void postDeleteColumn(ObserverContext<MasterCoprocessorEnvironment> c, TableName tableName, byte[] col) throws IOException {
- auditEvent("deleteColumn", tableName.getName(), col, null, null, null, getActiveUser(), accessGrantedFlag);
- }
- @Override
- public void postDeleteSnapshot(ObserverContext<MasterCoprocessorEnvironment> ctx, SnapshotDescription snapshot) throws IOException {
- auditEvent("deleteSnapShot", (String) null, null, null, null, null, getActiveUser(), accessGrantedFlag);
- }
- @Override
- public void postDeleteTable(ObserverContext<MasterCoprocessorEnvironment> c, TableName tableName) throws IOException {
- auditEvent("deleteTable", tableName.getName(), null, null, null, null, getActiveUser(), accessGrantedFlag);
- }
- @Override
- public void postDisableTable(ObserverContext<MasterCoprocessorEnvironment> c, TableName tableName) throws IOException {
- auditEvent("disableTable", tableName.getName(), null, null, null, null, getActiveUser(), accessGrantedFlag);
- }
- @Override
- public void postEnableTable(ObserverContext<MasterCoprocessorEnvironment> c, TableName tableName) throws IOException {
- auditEvent("enableTable", tableName.getName(), null, null, null, null, getActiveUser(), accessGrantedFlag);
- }
- @Override
- public void postModifyColumn(ObserverContext<MasterCoprocessorEnvironment> c, TableName tableName, HColumnDescriptor descriptor) throws IOException {
- auditEvent("modifyColumn", tableName.getName(), descriptor.getName(), null, null, null, getActiveUser(), accessGrantedFlag);
- }
- @Override
- public void postModifyTable(ObserverContext<MasterCoprocessorEnvironment> c, TableName tableName, HTableDescriptor htd) throws IOException {
- auditEvent("modifyTable", tableName.getName(), null, null, null, null, getActiveUser(), accessGrantedFlag);
- }
- @Override
- public void postMove(ObserverContext<MasterCoprocessorEnvironment> c, HRegionInfo region, ServerName srcServer, ServerName destServer) throws IOException {
- auditEvent("move", region.getTable().getName(), null, null, null, null, getActiveUser(), accessGrantedFlag);
- }
- @Override
- public void postOpen(ObserverContext<RegionCoprocessorEnvironment> ctx) {
- auditEvent("open", (String) null, null, null, null, null, getActiveUser(), accessGrantedFlag);
- }
- @Override
- public void postRestoreSnapshot(ObserverContext<MasterCoprocessorEnvironment> ctx, SnapshotDescription snapshot, HTableDescriptor hTableDescriptor) throws IOException {
- auditEvent("restoreSnapshot", (String) null, null, null, null, null, getActiveUser(), accessGrantedFlag);
- }
- @Override
public void postScannerClose(ObserverContext<RegionCoprocessorEnvironment> c, InternalScanner s) throws IOException {
- try {
- scannerOwners.remove(s);
- } finally {
- byte[] tableName = getTableName(c.getEnvironment());
-
- if (!isSpecialTable(tableName)) {
- auditEvent("scannerClose", tableName, null, null, null, null, getActiveUser(), accessGrantedFlag);
- }
- }
+ scannerOwners.remove(s);
}
@Override
public RegionScanner postScannerOpen(ObserverContext<RegionCoprocessorEnvironment> c, Scan scan, RegionScanner s) throws IOException {
- try {
- User user = getActiveUser();
- if (user != null && user.getShortName() != null) {
- scannerOwners.put(s, user.getShortName());
- }
- } finally {
- byte[] tableName = getTableName(c.getEnvironment());
-
- if (!isSpecialTable(tableName)) {
- auditEvent("scannerOpen", tableName, null, null, null, null, getActiveUser(), accessGrantedFlag);
- }
+ User user = getActiveUser();
+ if (user != null && user.getShortName() != null) {
+ scannerOwners.put(s, user.getShortName());
}
return s;
}
@Override
- public void postSnapshot(ObserverContext<MasterCoprocessorEnvironment> ctx, SnapshotDescription snapshot, HTableDescriptor hTableDescriptor) throws IOException {
- auditEvent("snapshot", hTableDescriptor.getNameAsString(), null, null, null, null, getActiveUser(), accessGrantedFlag);
- }
- @Override
public void postStartMaster(ObserverContext<MasterCoprocessorEnvironment> ctx) throws IOException {
if(UpdateRangerPoliciesOnGrantRevoke) {
RangerAccessControlLists.init(ctx.getEnvironment().getMasterServices());
}
-
- auditEvent("startMaster", (String) null, null, null, null, null, getActiveUser(), accessGrantedFlag);
- }
- @Override
- public void postUnassign(ObserverContext<MasterCoprocessorEnvironment> c, HRegionInfo regionInfo, boolean force) throws IOException {
- auditEvent("unassign", regionInfo.getTable().getName(), null, null, null, null, getActiveUser(), accessGrantedFlag);
}
@Override
public void preAddColumn(ObserverContext<MasterCoprocessorEnvironment> c, TableName tableName, HColumnDescriptor column) throws IOException {
- requirePermission("addColumn", tableName.getName(), null, null, Action.ADMIN, Action.CREATE);
+ requirePermission("addColumn", tableName.getName(), null, null, Action.CREATE);
}
@Override
public Result preAppend(ObserverContext<RegionCoprocessorEnvironment> c, Append append) throws IOException {
@@ -597,12 +707,12 @@ public class RangerAuthorizationCoprocessor extends RangerAuthorizationCoprocess
}
@Override
public InternalScanner preCompact(ObserverContext<RegionCoprocessorEnvironment> e, Store store, InternalScanner scanner,ScanType scanType) throws IOException {
- requirePermission("compact", getTableName(e.getEnvironment()), null, null, Action.ADMIN, Action.CREATE);
+ requirePermission("compact", getTableName(e.getEnvironment()), null, null, Action.CREATE);
return scanner;
}
@Override
public void preCompactSelection(ObserverContext<RegionCoprocessorEnvironment> e, Store store, List<StoreFile> candidates) throws IOException {
- requirePermission("compactSelection", getTableName(e.getEnvironment()), null, null, Action.ADMIN, Action.CREATE);
+ requirePermission("compactSelection", getTableName(e.getEnvironment()), null, null, Action.CREATE);
}
@Override
@@ -615,7 +725,7 @@ public class RangerAuthorizationCoprocessor extends RangerAuthorizationCoprocess
}
@Override
public void preDeleteColumn(ObserverContext<MasterCoprocessorEnvironment> c, TableName tableName, byte[] col) throws IOException {
- requirePermission("deleteColumn", tableName.getName(), null, null, Action.ADMIN, Action.CREATE);
+ requirePermission("deleteColumn", tableName.getName(), null, null, Action.CREATE);
}
@Override
public void preDeleteSnapshot(ObserverContext<MasterCoprocessorEnvironment> ctx, SnapshotDescription snapshot) throws IOException {
@@ -623,15 +733,15 @@ public class RangerAuthorizationCoprocessor extends RangerAuthorizationCoprocess
}
@Override
public void preDeleteTable(ObserverContext<MasterCoprocessorEnvironment> c, TableName tableName) throws IOException {
- requirePermission("deleteTable", tableName.getName(), null, null, Action.ADMIN, Action.CREATE);
+ requirePermission("deleteTable", tableName.getName(), null, null, Action.CREATE);
}
@Override
public void preDisableTable(ObserverContext<MasterCoprocessorEnvironment> c, TableName tableName) throws IOException {
- requirePermission("disableTable", tableName.getName(), null, null, Action.ADMIN, Action.CREATE);
+ requirePermission("disableTable", tableName.getName(), null, null, Action.CREATE);
}
@Override
public void preEnableTable(ObserverContext<MasterCoprocessorEnvironment> c, TableName tableName) throws IOException {
- requirePermission("enableTable", tableName.getName(), null, null, Action.ADMIN, Action.CREATE);
+ requirePermission("enableTable", tableName.getName(), null, null, Action.CREATE);
}
@Override
public boolean preExists(ObserverContext<RegionCoprocessorEnvironment> c, Get get, boolean exists) throws IOException {
@@ -640,7 +750,7 @@ public class RangerAuthorizationCoprocessor extends RangerAuthorizationCoprocess
}
@Override
public void preFlush(ObserverContext<RegionCoprocessorEnvironment> e) throws IOException {
- requirePermission("flush", getTableName(e.getEnvironment()), null, null, Action.ADMIN, Action.CREATE);
+ requirePermission("flush", getTableName(e.getEnvironment()), null, null, Action.CREATE);
}
@Override
public void preGetClosestRowBefore(ObserverContext<RegionCoprocessorEnvironment> c, byte[] row, byte[] family, Result result) throws IOException {
@@ -660,11 +770,11 @@ public class RangerAuthorizationCoprocessor extends RangerAuthorizationCoprocess
}
@Override
public void preModifyColumn(ObserverContext<MasterCoprocessorEnvironment> c, TableName tableName, HColumnDescriptor descriptor) throws IOException {
- requirePermission("modifyColumn", tableName.getName(), null, null, Action.ADMIN, Action.CREATE);
+ requirePermission("modifyColumn", tableName.getName(), null, null, Action.CREATE);
}
@Override
public void preModifyTable(ObserverContext<MasterCoprocessorEnvironment> c, TableName tableName, HTableDescriptor htd) throws IOException {
- requirePermission("modifyTable", tableName.getName(), null, null, Action.ADMIN, Action.CREATE);
+ requirePermission("modifyTable", tableName.getName(), null, null, Action.CREATE);
}
@Override
public void preMove(ObserverContext<MasterCoprocessorEnvironment> c, HRegionInfo region, ServerName srcServer, ServerName destServer) throws IOException {
@@ -680,7 +790,7 @@ public class RangerAuthorizationCoprocessor extends RangerAuthorizationCoprocess
} else {
HRegionInfo regionInfo = region.getRegionInfo();
if (isSpecialTable(regionInfo)) {
- isSystemOrSuperUser(regionEnv.getConfiguration());
+ requireSystemOrSuperUser(regionEnv.getConfiguration());
} else {
requirePermission("open", getTableName(e.getEnvironment()), Action.ADMIN);
}
@@ -703,21 +813,21 @@ public class RangerAuthorizationCoprocessor extends RangerAuthorizationCoprocess
@Override
public RegionScanner preScannerOpen(ObserverContext<RegionCoprocessorEnvironment> c, Scan scan, RegionScanner s) throws IOException {
RegionCoprocessorEnvironment e = c.getEnvironment();
- User user = getActiveUser();
- boolean isGranted = isPermissionGranted("scannerOpen", user, TablePermission.Action.READ, e, scan.getFamilyMap());
- if (!isGranted) {
- if (hasFamilyQualifierPermission(user, TablePermission.Action.READ, e, scan.getFamilyMap())) {
- byte[] table = getTableName(e);
- RangerAccessControlFilter filter = new RangerAccessControlFilter(user, table);
- if (scan.hasFilter()) {
- FilterList wrapper = new FilterList(FilterList.Operator.MUST_PASS_ALL, Lists.newArrayList(filter, scan.getFilter()));
- scan.setFilter(wrapper);
- } else {
- scan.setFilter(filter);
- }
- } else {
- throw new AccessDeniedException("Insufficient permissions for user '" + (user != null ? user.getShortName() : "null") + "' for scanner open on table " + Bytes.toString(getTableName(e)));
+
+ Map<byte[], NavigableSet<byte[]>> familyMap = scan.getFamilyMap();
+ String operation = "scannerOpen";
+ Filter filter = authorizeAccess(operation, Action.READ, e, familyMap);
+ if (filter == null) {
+ if (LOG.isDebugEnabled()) {
+ LOG.debug("preGetOp: Access allowed for all families/column.");
}
+ } else {
+ if (LOG.isDebugEnabled()) {
+ LOG.debug("preGetOp: Access allowed for some of the families/column.");
+ }
+ Filter existingFilter = scan.getFilter();
+ Filter combinedFilter = combineFilters(filter, existingFilter);
+ scan.setFilter(combinedFilter);
}
return s;
}
@@ -779,165 +889,58 @@ public class RangerAuthorizationCoprocessor extends RangerAuthorizationCoprocess
}
}
}
+ // create and initialize the plugin class
+ new RangerBasePlugin("hbase") {}.init(_authorizer);
if (LOG.isDebugEnabled()) {
LOG.debug("Start of Coprocessor: [" + coprocessorType + "] with superUserList [" + superUserList + "]");
}
}
@Override
- public void stop(CoprocessorEnvironment env) {
- }
- @Override
public void prePut(ObserverContext<RegionCoprocessorEnvironment> c, Put put, WALEdit edit, Durability durability) throws IOException {
requirePermission("put", TablePermission.Action.WRITE, c.getEnvironment(), put.getFamilyCellMap());
}
@Override
- public void postPut(ObserverContext<RegionCoprocessorEnvironment> c, Put put, WALEdit edit, Durability durability) {
- byte[] tableName = getTableName(c.getEnvironment());
- if (!isSpecialTable(tableName)) {
- if (accessController.isAudited(tableName)) {
- Map<byte[], List<Cell>> colf2KeyValMap = put.getFamilyCellMap() ;
- for (byte[] colf : colf2KeyValMap.keySet()) {
- if (colf != null) {
- List<Cell> kvList = colf2KeyValMap.get(colf);
- for (Cell kv : kvList) {
- auditEvent("Put", tableName, CellUtil.cloneFamily(kv), CellUtil.cloneQualifier(kv) , CellUtil.cloneRow(kv), CellUtil.cloneValue(kv), getActiveUser(), accessGrantedFlag);
- }
- }
- }
-
-
- }
- }
- }
-
- @Override
public void preGetOp(final ObserverContext<RegionCoprocessorEnvironment> rEnv, final Get get, final List<Cell> result) throws IOException {
RegionCoprocessorEnvironment e = rEnv.getEnvironment();
- User requestUser = getActiveUser();
-
-
- if (LOG.isDebugEnabled())
- {
- StringBuilder fields = new StringBuilder() ;
- Map<byte[], NavigableSet<byte[]>> familyMap = get.getFamilyMap() ;
- if (familyMap != null && familyMap.size() > 0) {
- for(byte[] columnfamily : familyMap.keySet() ) {
- if (columnfamily != null && columnfamily.length > 0) {
- NavigableSet<byte[]> columnNameSet = familyMap.get(columnfamily) ;
- if (columnNameSet != null && columnNameSet.size() > 0) {
- for(byte[] columnname : columnNameSet) {
- fields.append("Field[" + Bytes.toString(columnfamily) + ":" + Bytes.toString(columnname) + "],") ;
- }
- }
- else {
- fields.append("Field[" + Bytes.toString(columnfamily) + ":null],") ;
- }
- }
- }
- }
- else {
- if (familyMap == null){
- fields.append("{null}") ;
- }
- else {
- fields.append("{empty}") ;
- }
- }
- LOG.debug("preGet is checking permission for the following fields: {" + fields.toString() + "}");
- }
-
- boolean isPermGranted = isPermissionGranted("get", requestUser, TablePermission.Action.READ, e, get.getFamilyMap());
-
- if (!isPermGranted) {
- isPermGranted = hasFamilyQualifierPermission(requestUser, TablePermission.Action.READ, e, get.getFamilyMap());
- if (isPermGranted) {
- byte[] table = getTableName(e);
- RangerAccessControlFilter filter = new RangerAccessControlFilter(requestUser, table);
- if (get.getFilter() != null) {
- FilterList wrapper = new FilterList(FilterList.Operator.MUST_PASS_ALL, Lists.newArrayList(filter, get.getFilter()));
- get.setFilter(wrapper);
- } else {
- get.setFilter(filter);
- }
- } else {
- throw new AccessDeniedException("Insufficient permissions (table=" + e.getRegion().getTableDesc().getNameAsString() + ", action=READ)");
- }
- }
- }
- @Override
- public void postGetOp(final ObserverContext<RegionCoprocessorEnvironment> env, final Get get, final List<Cell> results) throws IOException {
- HRegionInfo hri = env.getEnvironment().getRegion().getRegionInfo();
-
- byte[] tableName = hri.getTable().getName() ;
-
- if (!isSpecialTable(tableName)) {
- try {
- if (accessController.isAudited(tableName)) {
- for (Cell cell : results) {
- auditEvent("Get", tableName, cell.getFamily(), cell.getQualifier(), cell.getRow(), cell.getValue(), getActiveUser(), accessGrantedFlag);
- }
- }
- } catch (Throwable t) {
+ Map<byte[], NavigableSet<byte[]>> familyMap = get.getFamilyMap() ;
+
+ String operation = "get";
+ Filter filter = authorizeAccess(operation, Action.READ, e, familyMap);
+ if (filter == null) {
+ if (LOG.isDebugEnabled()) {
+ LOG.debug("preGetOp: Access allowed.");
}
+ } else {
+ Filter existingFilter = get.getFilter();
+ Filter combinedFilter = combineFilters(filter, existingFilter);
+ get.setFilter(combinedFilter);
}
+ return;
}
-
@Override
public void preRegionOffline(ObserverContext<MasterCoprocessorEnvironment> c, HRegionInfo regionInfo) throws IOException {
requirePermission("regionOffline", regionInfo.getTable().getName(), null, null, Action.ADMIN);
}
@Override
- public void postRegionOffline(ObserverContext<MasterCoprocessorEnvironment> c, HRegionInfo regionInfo) throws IOException {
- auditEvent("regionOffline", regionInfo.getTable().getName(), null, null, null, null, getActiveUser(), accessGrantedFlag);
- }
- @Override
public void preCreateNamespace(ObserverContext<MasterCoprocessorEnvironment> ctx, NamespaceDescriptor ns) throws IOException {
requireGlobalPermission("createNamespace", ns.getName(), Action.ADMIN);
}
@Override
- public void postCreateNamespace(ObserverContext<MasterCoprocessorEnvironment> ctx, NamespaceDescriptor ns) throws IOException {
- if (accessController.isAudited(WILDCARD_MATCH)) {
- auditEvent("createNamespace", ns.getName(), null, null, null, null, getActiveUser(), accessGrantedFlag);
- }
- }
- @Override
public void preDeleteNamespace(ObserverContext<MasterCoprocessorEnvironment> ctx, String namespace) throws IOException {
requireGlobalPermission("deleteNamespace", namespace, Action.ADMIN);
}
@Override
- public void postDeleteNamespace(ObserverContext<MasterCoprocessorEnvironment> ctx, String namespace) throws IOException {
- if (accessController.isAudited(WILDCARD_MATCH)) {
- auditEvent("deleteNamespace", namespace, null, null, null, null, getActiveUser(), accessGrantedFlag);
- }
- }
- @Override
public void preModifyNamespace(ObserverContext<MasterCoprocessorEnvironment> ctx, NamespaceDescriptor ns) throws IOException {
requireGlobalPermission("modifyNamespace", ns.getName(), Action.ADMIN);
}
@Override
- public void postModifyNamespace(ObserverContext<MasterCoprocessorEnvironment> ctx, NamespaceDescriptor ns) throws IOException {
- if (accessController.isAudited(WILDCARD_MATCH)) {
- auditEvent("modifyNamespace", ns.getName(), null, null, null, null, getActiveUser(), accessGrantedFlag);
- }
- }
- @Override
public void preGetTableDescriptors(ObserverContext<MasterCoprocessorEnvironment> ctx, List<TableName> tableNamesList, List<HTableDescriptor> descriptors) throws IOException {
if (tableNamesList == null || tableNamesList.isEmpty()) { // If the list is empty, this is a request for all table descriptors and requires GLOBAL ADMIN privs.
requireGlobalPermission("getTableDescriptors", WILDCARD, Action.ADMIN);
} else { // Otherwise, if the requestor has ADMIN or CREATE privs for all listed tables, the request can be granted.
for (TableName tableName: tableNamesList) {
- requirePermission("getTableDescriptors", tableName.getName(), null, null, Action.ADMIN, Action.CREATE);
- }
- }
- }
- @Override
- public void postGetTableDescriptors(ObserverContext<MasterCoprocessorEnvironment> ctx, List<HTableDescriptor> descriptors) throws IOException {
- if (descriptors == null || descriptors.isEmpty()) { // If the list is empty, this is a request for all table descriptors and requires GLOBAL ADMIN privs.
- auditEvent("getTableDescriptors", WILDCARD, null, null, null, null, getActiveUser(), accessGrantedFlag);
- } else { // Otherwise, if the requestor has ADMIN or CREATE privs for all listed tables, the request can be granted.
- for (HTableDescriptor descriptor : descriptors) {
- auditEvent("getTableDescriptors", descriptor.getName(), null, null, null, null, getActiveUser(), accessGrantedFlag);
+ requirePermission("getTableDescriptors", tableName.getName(), null, null, Action.CREATE);
}
}
}
@@ -946,11 +949,6 @@ public class RangerAuthorizationCoprocessor extends RangerAuthorizationCoprocess
requirePermission("mergeRegions", regionA.getTableDesc().getTableName().getName(), null, null, Action.ADMIN);
}
- @Override
- public void postMerge(ObserverContext<RegionServerCoprocessorEnvironment> c, HRegion regionA, HRegion regionB, HRegion mergedRegion) throws IOException {
- auditEvent("mergeRegions", regionA.getTableDesc().getTableName().getName(), null, null, null, null, getActiveUser(), accessGrantedFlag);
- }
-
public void prePrepareBulkLoad(ObserverContext<RegionCoprocessorEnvironment> ctx, PrepareBulkLoadRequest request) throws IOException {
List<byte[]> cfs = null;
@@ -963,55 +961,6 @@ public class RangerAuthorizationCoprocessor extends RangerAuthorizationCoprocess
requirePermission("preCleanupBulkLoad", Permission.Action.WRITE, ctx.getEnvironment(), cfs);
}
- private void auditEvent(String eventName, byte[] tableName, byte[] columnFamilyName, byte[] qualifierName, byte[] row, byte[] value, User user, short accessFlag) {
- auditEvent(eventName, Bytes.toString(tableName), Bytes.toString(columnFamilyName), Bytes.toString(qualifierName), row, value, user, accessFlag);
- }
-
- private void auditEvent(String eventName, String tableName, String columnFamilyName, String qualifierName, byte[] row, byte[] value, User user, short accessFlag) {
-
- if (tableName != null && accessController.isAudited(tableName.getBytes())) {
-
- String resourceType = "table";
- String resourceName = tableName;
- if (columnFamilyName != null && columnFamilyName.length() > 0) {
- resourceName += "/" + columnFamilyName;
- resourceType = "columnFamily";
- }
- if (qualifierName != null && qualifierName.length() > 0) {
- resourceName += "/" + qualifierName;
- resourceType = "column";
- }
-
- AuthzAuditEvent auditEvent = new AuthzAuditEvent();
-
- auditEvent.setAclEnforcer(RangerModuleName);
- auditEvent.setResourceType(resourceType);
- auditEvent.setResourcePath(resourceName);
- auditEvent.setAction(eventName);
- auditEvent.setAccessType(eventName);
- auditEvent.setUser(user == null ? RangerHadoopConstants.AUDITLOG_EMPTY_STRING : user.getShortName());
- auditEvent.setAccessResult(accessFlag);
- auditEvent.setClientIP(getRemoteAddress());
- auditEvent.setEventTime(getUTCDate());
- auditEvent.setRepositoryType(EnumRepositoryType.HBASE);
- auditEvent.setRepositoryName(repositoryName);
-
- try {
- if (LOG.isDebugEnabled()) {
- LOG.debug("Writing audit log [" + auditEvent + "] - START.");
- }
- AuditProviderFactory.getAuditProvider().log(auditEvent);
- if (LOG.isDebugEnabled()) {
- LOG.debug("Writing audit log [" + auditEvent + "] - END.");
- }
- }
- catch(Throwable t) {
- LOG.error("ERROR during audit log [" + auditEvent + "]", t);
- }
-
- }
- }
-
public static Date getUTCDate() {
Calendar local=Calendar.getInstance();
int offset = local.getTimeZone().getOffset(local.getTimeInMillis());
@@ -1047,13 +996,14 @@ public class RangerAuthorizationCoprocessor extends RangerAuthorizationCoprocess
} finally {
byte[] tableName = grData == null ? null : StringUtil.getBytes(grData.getTables());
- if(accessController.isAudited(tableName)) {
- byte[] colFamily = grData == null ? null : StringUtil.getBytes(grData.getColumnFamilies());
- byte[] qualifier = grData == null ? null : StringUtil.getBytes(grData.getColumns());
-
- // Note: failed return from REST call will be logged as 'DENIED'
- auditEvent("grant", tableName, colFamily, qualifier, null, null, getActiveUser(), isSuccess ? accessGrantedFlag : accessDeniedFlag);
- }
+ // TODO - Auditing of grant-revoke to be sorted out.
+// if(accessController.isAudited(tableName)) {
+// byte[] colFamily = grData == null ? null : StringUtil.getBytes(grData.getColumnFamilies());
+// byte[] qualifier = grData == null ? null : StringUtil.getBytes(grData.getColumns());
+//
+// // Note: failed return from REST call will be logged as 'DENIED'
+// auditEvent("grant", tableName, colFamily, qualifier, null, null, getActiveUser(), isSuccess ? accessGrantedFlag : accessDeniedFlag);
+// }
}
}
@@ -1088,13 +1038,14 @@ public class RangerAuthorizationCoprocessor extends RangerAuthorizationCoprocess
} finally {
byte[] tableName = grData == null ? null : StringUtil.getBytes(grData.getTables());
- if(accessController.isAudited(tableName)) {
- byte[] colFamily = grData == null ? null : StringUtil.getBytes(grData.getColumnFamilies());
- byte[] qualifier = grData == null ? null : StringUtil.getBytes(grData.getColumns());
-
- // Note: failed return from REST call will be logged as 'DENIED'
- auditEvent("revoke", tableName, colFamily, qualifier, null, null, getActiveUser(), isSuccess ? accessGrantedFlag : accessDeniedFlag);
- }
+ // TODO Audit of grant revoke to be sorted out
+// if(accessController.isAudited(tableName)) {
+// byte[] colFamily = grData == null ? null : StringUtil.getBytes(grData.getColumnFamilies());
+// byte[] qualifier = grData == null ? null : StringUtil.getBytes(grData.getColumns());
+//
+// // Note: failed return from REST call will be logged as 'DENIED'
+// auditEvent("revoke", tableName, colFamily, qualifier, null, null, getActiveUser(), isSuccess ? accessGrantedFlag : accessDeniedFlag);
+// }
}
}
http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/1d6a2590/hbase-agent/src/main/java/org/apache/ranger/authorization/hbase/RangerAuthorizationCoprocessorBase.java
----------------------------------------------------------------------
diff --git a/hbase-agent/src/main/java/org/apache/ranger/authorization/hbase/RangerAuthorizationCoprocessorBase.java b/hbase-agent/src/main/java/org/apache/ranger/authorization/hbase/RangerAuthorizationCoprocessorBase.java
index 2dab171..a752569 100644
--- a/hbase-agent/src/main/java/org/apache/ranger/authorization/hbase/RangerAuthorizationCoprocessorBase.java
+++ b/hbase-agent/src/main/java/org/apache/ranger/authorization/hbase/RangerAuthorizationCoprocessorBase.java
@@ -21,13 +21,19 @@ package org.apache.ranger.authorization.hbase;
import java.io.IOException;
import java.util.List;
+import org.apache.hadoop.hbase.Cell;
+import org.apache.hadoop.hbase.CoprocessorEnvironment;
import org.apache.hadoop.hbase.HColumnDescriptor;
import org.apache.hadoop.hbase.HRegionInfo;
import org.apache.hadoop.hbase.HTableDescriptor;
import org.apache.hadoop.hbase.NamespaceDescriptor;
import org.apache.hadoop.hbase.ServerName;
import org.apache.hadoop.hbase.TableName;
+import org.apache.hadoop.hbase.client.Delete;
+import org.apache.hadoop.hbase.client.Durability;
+import org.apache.hadoop.hbase.client.Get;
import org.apache.hadoop.hbase.client.Mutation;
+import org.apache.hadoop.hbase.client.Put;
import org.apache.hadoop.hbase.coprocessor.BaseRegionObserver;
import org.apache.hadoop.hbase.coprocessor.BulkLoadObserver;
import org.apache.hadoop.hbase.coprocessor.MasterCoprocessorEnvironment;
@@ -38,48 +44,24 @@ import org.apache.hadoop.hbase.coprocessor.RegionServerCoprocessorEnvironment;
import org.apache.hadoop.hbase.coprocessor.RegionServerObserver;
import org.apache.hadoop.hbase.master.RegionPlan;
import org.apache.hadoop.hbase.protobuf.generated.HBaseProtos.SnapshotDescription;
-import org.apache.hadoop.hbase.protobuf.generated.SecureBulkLoadProtos.CleanupBulkLoadRequest;
-import org.apache.hadoop.hbase.protobuf.generated.SecureBulkLoadProtos.PrepareBulkLoadRequest;
import org.apache.hadoop.hbase.regionserver.HRegion;
+import org.apache.hadoop.hbase.regionserver.wal.WALEdit;
import org.apache.hadoop.hbase.replication.ReplicationEndpoint;
-import org.apache.hadoop.hbase.security.access.Permission;
-import org.apache.hadoop.hbase.security.access.Permission.Action;
-public class RangerAuthorizationCoprocessorBase extends BaseRegionObserver
+/**
+ * This class exits only to prevent the clutter of methods that we don't intend to implement in the main co-processor class.
+ * @author alal
+ *
+ */
+public abstract class RangerAuthorizationCoprocessorBase extends BaseRegionObserver
implements MasterObserver, RegionServerObserver, BulkLoadObserver {
@Override
- public void preStopRegionServer(
- ObserverContext<RegionServerCoprocessorEnvironment> env)
- throws IOException {
- // TODO Auto-generated method stub
-
- }
-
- @Override
- public void preMerge(
- ObserverContext<RegionServerCoprocessorEnvironment> ctx,
- HRegion regionA, HRegion regionB) throws IOException {
- // TODO Auto-generated method stub
-
- }
-
- @Override
- public void postMerge(
- ObserverContext<RegionServerCoprocessorEnvironment> c,
- HRegion regionA, HRegion regionB, HRegion mergedRegion)
- throws IOException {
- // TODO Auto-generated method stub
-
- }
-
- @Override
public void preMergeCommit(
ObserverContext<RegionServerCoprocessorEnvironment> ctx,
HRegion regionA, HRegion regionB, List<Mutation> metaEntries)
throws IOException {
- // TODO Auto-generated method stub
-
+ // Not applicable. Expected to be empty
}
@Override
@@ -87,169 +69,77 @@ public class RangerAuthorizationCoprocessorBase extends BaseRegionObserver
ObserverContext<RegionServerCoprocessorEnvironment> ctx,
HRegion regionA, HRegion regionB, HRegion mergedRegion)
throws IOException {
- // TODO Auto-generated method stub
-
+ // Not applicable. Expected to be empty
}
@Override
public void preRollBackMerge(
ObserverContext<RegionServerCoprocessorEnvironment> ctx,
HRegion regionA, HRegion regionB) throws IOException {
- // TODO Auto-generated method stub
-
+ // Not applicable. Expected to be empty
}
@Override
public void postRollBackMerge(
ObserverContext<RegionServerCoprocessorEnvironment> ctx,
HRegion regionA, HRegion regionB) throws IOException {
- // TODO Auto-generated method stub
-
- }
-
- @Override
- public void preCreateTable(
- ObserverContext<MasterCoprocessorEnvironment> ctx,
- HTableDescriptor desc, HRegionInfo[] regions) throws IOException {
- // TODO Auto-generated method stub
-
- }
-
- @Override
- public void postCreateTable(
- ObserverContext<MasterCoprocessorEnvironment> ctx,
- HTableDescriptor desc, HRegionInfo[] regions) throws IOException {
- // TODO Auto-generated method stub
-
+ // Not applicable. Expected to be empty
}
@Override
public void preCreateTableHandler(
ObserverContext<MasterCoprocessorEnvironment> ctx,
HTableDescriptor desc, HRegionInfo[] regions) throws IOException {
- // TODO Auto-generated method stub
-
+ // Not applicable. Expected to be empty
}
@Override
public void postCreateTableHandler(
ObserverContext<MasterCoprocessorEnvironment> ctx,
HTableDescriptor desc, HRegionInfo[] regions) throws IOException {
- // TODO Auto-generated method stub
-
- }
-
- @Override
- public void preDeleteTable(
- ObserverContext<MasterCoprocessorEnvironment> ctx,
- TableName tableName) throws IOException {
- // TODO Auto-generated method stub
-
- }
-
- @Override
- public void postDeleteTable(
- ObserverContext<MasterCoprocessorEnvironment> ctx,
- TableName tableName) throws IOException {
- // TODO Auto-generated method stub
-
+ // Not applicable. Expected to be empty
}
@Override
public void preDeleteTableHandler(
ObserverContext<MasterCoprocessorEnvironment> ctx,
TableName tableName) throws IOException {
- // TODO Auto-generated method stub
-
+ // Not applicable. Expected to be empty
}
@Override
public void postDeleteTableHandler(
ObserverContext<MasterCoprocessorEnvironment> ctx,
TableName tableName) throws IOException {
- // TODO Auto-generated method stub
-
- }
-
- @Override
- public void preModifyTable(
- ObserverContext<MasterCoprocessorEnvironment> ctx,
- TableName tableName, HTableDescriptor htd) throws IOException {
- // TODO Auto-generated method stub
-
- }
-
- @Override
- public void postModifyTable(
- ObserverContext<MasterCoprocessorEnvironment> ctx,
- TableName tableName, HTableDescriptor htd) throws IOException {
- // TODO Auto-generated method stub
-
+ // Not applicable. Expected to be empty
}
@Override
public void preModifyTableHandler(
ObserverContext<MasterCoprocessorEnvironment> ctx,
TableName tableName, HTableDescriptor htd) throws IOException {
- // TODO Auto-generated method stub
-
+ // Not applicable. Expected to be empty
}
@Override
public void postModifyTableHandler(
ObserverContext<MasterCoprocessorEnvironment> ctx,
TableName tableName, HTableDescriptor htd) throws IOException {
- // TODO Auto-generated method stub
-
- }
-
- @Override
- public void preAddColumn(ObserverContext<MasterCoprocessorEnvironment> ctx,
- TableName tableName, HColumnDescriptor column) throws IOException {
- // TODO Auto-generated method stub
-
- }
-
- @Override
- public void postAddColumn(
- ObserverContext<MasterCoprocessorEnvironment> ctx,
- TableName tableName, HColumnDescriptor column) throws IOException {
- // TODO Auto-generated method stub
-
+ // Not applicable. Expected to be empty
}
@Override
public void preAddColumnHandler(
ObserverContext<MasterCoprocessorEnvironment> ctx,
TableName tableName, HColumnDescriptor column) throws IOException {
- // TODO Auto-generated method stub
-
+ // Not applicable. Expected to be empty
}
@Override
public void postAddColumnHandler(
ObserverContext<MasterCoprocessorEnvironment> ctx,
TableName tableName, HColumnDescriptor column) throws IOException {
- // TODO Auto-generated method stub
-
- }
-
- @Override
- public void preModifyColumn(
- ObserverContext<MasterCoprocessorEnvironment> ctx,
- TableName tableName, HColumnDescriptor descriptor)
- throws IOException {
- // TODO Auto-generated method stub
-
- }
-
- @Override
- public void postModifyColumn(
- ObserverContext<MasterCoprocessorEnvironment> ctx,
- TableName tableName, HColumnDescriptor descriptor)
- throws IOException {
- // TODO Auto-generated method stub
-
+ // Not applicable. Expected to be empty
}
@Override
@@ -257,8 +147,7 @@ public class RangerAuthorizationCoprocessorBase extends BaseRegionObserver
ObserverContext<MasterCoprocessorEnvironment> ctx,
TableName tableName, HColumnDescriptor descriptor)
throws IOException {
- // TODO Auto-generated method stub
-
+ // Not applicable. Expected to be empty
}
@Override
@@ -266,406 +155,214 @@ public class RangerAuthorizationCoprocessorBase extends BaseRegionObserver
ObserverContext<MasterCoprocessorEnvironment> ctx,
TableName tableName, HColumnDescriptor descriptor)
throws IOException {
- // TODO Auto-generated method stub
-
- }
-
- @Override
- public void preDeleteColumn(
- ObserverContext<MasterCoprocessorEnvironment> ctx,
- TableName tableName, byte[] c) throws IOException {
- // TODO Auto-generated method stub
-
- }
-
- @Override
- public void postDeleteColumn(
- ObserverContext<MasterCoprocessorEnvironment> ctx,
- TableName tableName, byte[] c) throws IOException {
- // TODO Auto-generated method stub
-
+ // Not applicable. Expected to be empty
}
@Override
public void preDeleteColumnHandler(
ObserverContext<MasterCoprocessorEnvironment> ctx,
TableName tableName, byte[] c) throws IOException {
- // TODO Auto-generated method stub
-
+ // Not applicable. Expected to be empty
}
@Override
public void postDeleteColumnHandler(
ObserverContext<MasterCoprocessorEnvironment> ctx,
TableName tableName, byte[] c) throws IOException {
- // TODO Auto-generated method stub
-
- }
-
- @Override
- public void preEnableTable(
- ObserverContext<MasterCoprocessorEnvironment> ctx,
- TableName tableName) throws IOException {
- // TODO Auto-generated method stub
-
- }
-
- @Override
- public void postEnableTable(
- ObserverContext<MasterCoprocessorEnvironment> ctx,
- TableName tableName) throws IOException {
- // TODO Auto-generated method stub
-
+ // Not applicable. Expected to be empty
}
@Override
public void preEnableTableHandler(
ObserverContext<MasterCoprocessorEnvironment> ctx,
TableName tableName) throws IOException {
- // TODO Auto-generated method stub
-
+ // Not applicable. Expected to be empty
}
@Override
public void postEnableTableHandler(
ObserverContext<MasterCoprocessorEnvironment> ctx,
TableName tableName) throws IOException {
- // TODO Auto-generated method stub
-
- }
-
- @Override
- public void preDisableTable(
- ObserverContext<MasterCoprocessorEnvironment> ctx,
- TableName tableName) throws IOException {
- // TODO Auto-generated method stub
-
- }
-
- @Override
- public void postDisableTable(
- ObserverContext<MasterCoprocessorEnvironment> ctx,
- TableName tableName) throws IOException {
- // TODO Auto-generated method stub
-
+ // Not applicable. Expected to be empty
}
@Override
public void preDisableTableHandler(
ObserverContext<MasterCoprocessorEnvironment> ctx,
TableName tableName) throws IOException {
- // TODO Auto-generated method stub
-
+ // Not applicable. Expected to be empty
}
@Override
public void postDisableTableHandler(
ObserverContext<MasterCoprocessorEnvironment> ctx,
TableName tableName) throws IOException {
- // TODO Auto-generated method stub
-
+ // Not applicable. Expected to be empty
}
@Override
- public void preMove(ObserverContext<MasterCoprocessorEnvironment> ctx,
- HRegionInfo region, ServerName srcServer, ServerName destServer)
+ public void preMasterInitialization(
+ ObserverContext<MasterCoprocessorEnvironment> ctx)
throws IOException {
- // TODO Auto-generated method stub
-
+ // Not applicable. Expected to be empty
}
- @Override
- public void postMove(ObserverContext<MasterCoprocessorEnvironment> ctx,
- HRegionInfo region, ServerName srcServer, ServerName destServer)
- throws IOException {
- // TODO Auto-generated method stub
-
+ public void preRollWALWriterRequest(ObserverContext<RegionServerCoprocessorEnvironment> ctx) throws IOException {
+ // Not applicable. Expected to be empty
}
- @Override
- public void preAssign(ObserverContext<MasterCoprocessorEnvironment> ctx,
- HRegionInfo regionInfo) throws IOException {
- // TODO Auto-generated method stub
-
+ public void postRollWALWriterRequest(ObserverContext<RegionServerCoprocessorEnvironment> ctx) throws IOException {
+ // Not applicable. Expected to be empty
}
-
- @Override
- public void postAssign(ObserverContext<MasterCoprocessorEnvironment> ctx,
- HRegionInfo regionInfo) throws IOException {
- // TODO Auto-generated method stub
-
+
+ public void preTableFlush(final ObserverContext<MasterCoprocessorEnvironment> ctx, final TableName tableName) throws IOException {
+ // Not applicable. Expected to be empty
}
- @Override
- public void preUnassign(ObserverContext<MasterCoprocessorEnvironment> ctx,
- HRegionInfo regionInfo, boolean force) throws IOException {
- // TODO Auto-generated method stub
-
+ public void postTableFlush(ObserverContext<MasterCoprocessorEnvironment> ctx, TableName tableName) throws IOException {
+ // Not applicable. Expected to be empty
}
- @Override
- public void postUnassign(ObserverContext<MasterCoprocessorEnvironment> ctx,
- HRegionInfo regionInfo, boolean force) throws IOException {
- // TODO Auto-generated method stub
-
+ public void preTruncateTableHandler(final ObserverContext<MasterCoprocessorEnvironment> ctx, TableName tableName) throws IOException {
+ // Not applicable. Expected to be empty
}
- @Override
- public void preRegionOffline(
- ObserverContext<MasterCoprocessorEnvironment> ctx,
- HRegionInfo regionInfo) throws IOException {
- // TODO Auto-generated method stub
-
+ public void postTruncateTableHandler(final ObserverContext<MasterCoprocessorEnvironment> ctx, TableName tableName) throws IOException {
+ // Not applicable. Expected to be empty
}
- @Override
- public void postRegionOffline(
- ObserverContext<MasterCoprocessorEnvironment> ctx,
- HRegionInfo regionInfo) throws IOException {
- // TODO Auto-generated method stub
-
+ public void preTruncateTable(final ObserverContext<MasterCoprocessorEnvironment> ctx, TableName tableName) throws IOException {
+ // Not applicable. Expected to be empty
}
- @Override
- public void preBalance(ObserverContext<MasterCoprocessorEnvironment> ctx)
- throws IOException {
- // TODO Auto-generated method stub
-
+ public void postTruncateTable(final ObserverContext<MasterCoprocessorEnvironment> ctx, TableName tableName) throws IOException {
+ // Not applicable. Expected to be empty
}
- @Override
- public void postBalance(ObserverContext<MasterCoprocessorEnvironment> ctx,
- List<RegionPlan> plans) throws IOException {
- // TODO Auto-generated method stub
-
+ public ReplicationEndpoint postCreateReplicationEndPoint(ObserverContext<RegionServerCoprocessorEnvironment> ctx, ReplicationEndpoint endpoint) {
+ return endpoint;
}
@Override
- public boolean preBalanceSwitch(
- ObserverContext<MasterCoprocessorEnvironment> ctx, boolean newValue)
- throws IOException {
- // TODO Auto-generated method stub
- return false;
+ public void stop(CoprocessorEnvironment env) {
+ // Not applicable. Expected to be empty
}
-
@Override
- public void postBalanceSwitch(
- ObserverContext<MasterCoprocessorEnvironment> ctx,
- boolean oldValue, boolean newValue) throws IOException {
- // TODO Auto-generated method stub
-
+ public void postAddColumn(ObserverContext<MasterCoprocessorEnvironment> c, TableName tableName, HColumnDescriptor column) throws IOException {
+ // Not applicable. Expected to be empty
}
-
@Override
- public void preShutdown(ObserverContext<MasterCoprocessorEnvironment> ctx)
- throws IOException {
- // TODO Auto-generated method stub
-
+ public void postAssign(ObserverContext<MasterCoprocessorEnvironment> c, HRegionInfo regionInfo) throws IOException {
+ // Not applicable. Expected to be empty
}
-
@Override
- public void preStopMaster(ObserverContext<MasterCoprocessorEnvironment> ctx)
- throws IOException {
- // TODO Auto-generated method stub
-
+ public void postBalance(ObserverContext<MasterCoprocessorEnvironment> c,List<RegionPlan> aRegPlanList) throws IOException {
+ // Not applicable. Expected to be empty
}
-
@Override
- public void postStartMaster(
- ObserverContext<MasterCoprocessorEnvironment> ctx)
- throws IOException {
- // TODO Auto-generated method stub
-
+ public void postBalanceSwitch(ObserverContext<MasterCoprocessorEnvironment> c, boolean oldValue, boolean newValue) throws IOException {
+ // Not applicable. Expected to be empty
}
-
@Override
- public void preMasterInitialization(
- ObserverContext<MasterCoprocessorEnvironment> ctx)
- throws IOException {
- // TODO Auto-generated method stub
-
+ public void postCloneSnapshot(ObserverContext<MasterCoprocessorEnvironment> ctx, SnapshotDescription snapshot, HTableDescriptor hTableDescriptor) throws IOException {
+ // Not applicable. Expected to be empty
}
-
@Override
- public void preSnapshot(ObserverContext<MasterCoprocessorEnvironment> ctx,
- SnapshotDescription snapshot, HTableDescriptor hTableDescriptor)
- throws IOException {
- // TODO Auto-generated method stub
-
+ public void postCreateTable(ObserverContext<MasterCoprocessorEnvironment> ctx, HTableDescriptor desc, HRegionInfo[] regions) throws IOException {
+ // Not applicable. Expected to be empty
}
-
@Override
- public void postSnapshot(ObserverContext<MasterCoprocessorEnvironment> ctx,
- SnapshotDescription snapshot, HTableDescriptor hTableDescriptor)
- throws IOException {
- // TODO Auto-generated method stub
-
+ public void postDelete(ObserverContext<RegionCoprocessorEnvironment> c, Delete delete, WALEdit edit, Durability durability) throws IOException {
+ // Not applicable. Expected to be empty
}
-
@Override
- public void preCloneSnapshot(
- ObserverContext<MasterCoprocessorEnvironment> ctx,
- SnapshotDescription snapshot, HTableDescriptor hTableDescriptor)
- throws IOException {
- // TODO Auto-generated method stub
-
+ public void postDeleteColumn(ObserverContext<MasterCoprocessorEnvironment> c, TableName tableName, byte[] col) throws IOException {
+ // Not applicable. Expected to be empty
}
-
@Override
- public void postCloneSnapshot(
- ObserverContext<MasterCoprocessorEnvironment> ctx,
- SnapshotDescription snapshot, HTableDescriptor hTableDescriptor)
- throws IOException {
- // TODO Auto-generated method stub
-
+ public void postDeleteSnapshot(ObserverContext<MasterCoprocessorEnvironment> ctx, SnapshotDescription snapshot) throws IOException {
+ // Not applicable. Expected to be empty
}
-
@Override
- public void preRestoreSnapshot(
- ObserverContext<MasterCoprocessorEnvironment> ctx,
- SnapshotDescription snapshot, HTableDescriptor hTableDescriptor)
- throws IOException {
- // TODO Auto-generated method stub
-
+ public void postDeleteTable(ObserverContext<MasterCoprocessorEnvironment> c, TableName tableName) throws IOException {
+ // Not applicable. Expected to be empty
}
-
@Override
- public void postRestoreSnapshot(
- ObserverContext<MasterCoprocessorEnvironment> ctx,
- SnapshotDescription snapshot, HTableDescriptor hTableDescriptor)
- throws IOException {
- // TODO Auto-generated method stub
-
+ public void postDisableTable(ObserverContext<MasterCoprocessorEnvironment> c, TableName tableName) throws IOException {
+ // Not applicable. Expected to be empty
}
-
@Override
- public void preDeleteSnapshot(
- ObserverContext<MasterCoprocessorEnvironment> ctx,
- SnapshotDescription snapshot) throws IOException {
- // TODO Auto-generated method stub
-
+ public void postEnableTable(ObserverContext<MasterCoprocessorEnvironment> c, TableName tableName) throws IOException {
+ // Not applicable. Expected to be empty
}
-
@Override
- public void postDeleteSnapshot(
- ObserverContext<MasterCoprocessorEnvironment> ctx,
- SnapshotDescription snapshot) throws IOException {
- // TODO Auto-generated method stub
-
+ public void postModifyColumn(ObserverContext<MasterCoprocessorEnvironment> c, TableName tableName, HColumnDescriptor descriptor) throws IOException {
+ // Not applicable. Expected to be empty
}
-
@Override
- public void preGetTableDescriptors(
- ObserverContext<MasterCoprocessorEnvironment> ctx,
- List<TableName> tableNamesList, List<HTableDescriptor> descriptors)
- throws IOException {
- // TODO Auto-generated method stub
-
+ public void postModifyTable(ObserverContext<MasterCoprocessorEnvironment> c, TableName tableName, HTableDescriptor htd) throws IOException {
+ // Not applicable. Expected to be empty
}
-
@Override
- public void postGetTableDescriptors(
- ObserverContext<MasterCoprocessorEnvironment> ctx,
- List<HTableDescriptor> descriptors) throws IOException {
- // TODO Auto-generated method stub
-
+ public void postMove(ObserverContext<MasterCoprocessorEnvironment> c, HRegionInfo region, ServerName srcServer, ServerName destServer) throws IOException {
+ // Not applicable. Expected to be empty
}
-
@Override
- public void preCreateNamespace(
- ObserverContext<MasterCoprocessorEnvironment> ctx,
- NamespaceDescriptor ns) throws IOException {
- // TODO Auto-generated method stub
-
+ public void postOpen(ObserverContext<RegionCoprocessorEnvironment> ctx) {
+ // Not applicable. Expected to be empty
}
-
@Override
- public void postCreateNamespace(
- ObserverContext<MasterCoprocessorEnvironment> ctx,
- NamespaceDescriptor ns) throws IOException {
- // TODO Auto-generated method stub
-
+ public void postRestoreSnapshot(ObserverContext<MasterCoprocessorEnvironment> ctx, SnapshotDescription snapshot, HTableDescriptor hTableDescriptor) throws IOException {
+ // Not applicable. Expected to be empty
}
@Override
- public void preDeleteNamespace(
- ObserverContext<MasterCoprocessorEnvironment> ctx, String namespace)
- throws IOException {
- // TODO Auto-generated method stub
-
+ public void postPut(ObserverContext<RegionCoprocessorEnvironment> c, Put put, WALEdit edit, Durability durability) {
+ // Not applicable. Expected to be empty
}
-
+
@Override
- public void postDeleteNamespace(
- ObserverContext<MasterCoprocessorEnvironment> ctx, String namespace)
- throws IOException {
- // TODO Auto-generated method stub
-
+ public void postGetOp(final ObserverContext<RegionCoprocessorEnvironment> env, final Get get, final List<Cell> results) throws IOException {
+ // Not applicable. Expected to be empty
}
@Override
- public void preModifyNamespace(
- ObserverContext<MasterCoprocessorEnvironment> ctx,
- NamespaceDescriptor ns) throws IOException {
- // TODO Auto-generated method stub
-
+ public void postRegionOffline(ObserverContext<MasterCoprocessorEnvironment> c, HRegionInfo regionInfo) throws IOException {
+ // Not applicable. Expected to be empty
}
@Override
- public void postModifyNamespace(
- ObserverContext<MasterCoprocessorEnvironment> ctx,
- NamespaceDescriptor ns) throws IOException {
- // TODO Auto-generated method stub
-
+ public void postCreateNamespace(ObserverContext<MasterCoprocessorEnvironment> ctx, NamespaceDescriptor ns) throws IOException {
+ // Not applicable. Expected to be empty
}
- public void preRollWALWriterRequest(ObserverContext<RegionServerCoprocessorEnvironment> ctx) throws IOException {
- // TODO Auto-generated method stub
-
- }
-
- public void postRollWALWriterRequest(ObserverContext<RegionServerCoprocessorEnvironment> ctx) throws IOException {
- // TODO Auto-generated method stub
-
+ @Override
+ public void postDeleteNamespace(ObserverContext<MasterCoprocessorEnvironment> ctx, String namespace) throws IOException {
+ // Not applicable. Expected to be empty
}
- public void preTableFlush(final ObserverContext<MasterCoprocessorEnvironment> ctx, final TableName tableName) throws IOException {
- // TODO Auto-generated method stub
-
- }
-
- public void postTableFlush(ObserverContext<MasterCoprocessorEnvironment> ctx, TableName tableName) throws IOException {
- // TODO Auto-generated method stub
-
- }
-
- public void preTruncateTableHandler(final ObserverContext<MasterCoprocessorEnvironment> ctx, TableName tableName) throws IOException {
- // TODO Auto-generated method stub
-
- }
-
- public void postTruncateTableHandler(final ObserverContext<MasterCoprocessorEnvironment> ctx, TableName tableName) throws IOException {
- // TODO Auto-generated method stub
-
- }
-
- public void preTruncateTable(final ObserverContext<MasterCoprocessorEnvironment> ctx, TableName tableName) throws IOException {
- // TODO Auto-generated method stub
-
+ @Override
+ public void postModifyNamespace(ObserverContext<MasterCoprocessorEnvironment> ctx, NamespaceDescriptor ns) throws IOException {
+ // Not applicable. Expected to be empty
}
- public void postTruncateTable(final ObserverContext<MasterCoprocessorEnvironment> ctx, TableName tableName) throws IOException {
- // TODO Auto-generated method stub
-
+ @Override
+ public void postGetTableDescriptors(ObserverContext<MasterCoprocessorEnvironment> ctx, List<HTableDescriptor> descriptors) throws IOException {
+ // Not applicable. Expected to be empty
}
- public ReplicationEndpoint postCreateReplicationEndPoint(ObserverContext<RegionServerCoprocessorEnvironment> ctx, ReplicationEndpoint endpoint) {
- return endpoint;
+ @Override
+ public void postMerge(ObserverContext<RegionServerCoprocessorEnvironment> c, HRegion regionA, HRegion regionB, HRegion mergedRegion) throws IOException {
+ // Not applicable. Expected to be empty
}
- public void prePrepareBulkLoad(ObserverContext<RegionCoprocessorEnvironment> ctx, PrepareBulkLoadRequest request) throws IOException {
+ @Override
+ public void postSnapshot(ObserverContext<MasterCoprocessorEnvironment> ctx, SnapshotDescription snapshot, HTableDescriptor hTableDescriptor) throws IOException {
+ // Not applicable. Expected to be empty
}
- public void preCleanupBulkLoad(ObserverContext<RegionCoprocessorEnvironment> ctx, CleanupBulkLoadRequest request) throws IOException {
+ @Override
+ public void postUnassign(ObserverContext<MasterCoprocessorEnvironment> c, HRegionInfo regionInfo, boolean force) throws IOException {
+ // Not applicable. Expected to be empty
}
}
http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/1d6a2590/hdfs-agent/.settings/org.eclipse.jdt.core.prefs
----------------------------------------------------------------------
diff --git a/hdfs-agent/.settings/org.eclipse.jdt.core.prefs b/hdfs-agent/.settings/org.eclipse.jdt.core.prefs
index 107056a..98daa3b 100644
--- a/hdfs-agent/.settings/org.eclipse.jdt.core.prefs
+++ b/hdfs-agent/.settings/org.eclipse.jdt.core.prefs
@@ -1,12 +1,17 @@
-eclipse.preferences.version=1
-org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
-org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.6
-org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve
-org.eclipse.jdt.core.compiler.compliance=1.6
-org.eclipse.jdt.core.compiler.debug.lineNumber=generate
+#Wed Jan 21 11:38:45 PST 2015
+encoding/src/test/java=UTF-8
org.eclipse.jdt.core.compiler.debug.localVariable=generate
+org.eclipse.jdt.core.compiler.compliance=1.7
+org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve
+encoding/src/main/resources=UTF-8
org.eclipse.jdt.core.compiler.debug.sourceFile=generate
-org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
-org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
org.eclipse.jdt.core.compiler.problem.forbiddenReference=warning
-org.eclipse.jdt.core.compiler.source=1.6
+encoding/src/main/java=UTF-8
+org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.7
+org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
+org.eclipse.jdt.core.compiler.debug.lineNumber=generate
+eclipse.preferences.version=1
+encoding/src/test/resources=UTF-8
+org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
+org.eclipse.jdt.core.compiler.source=1.7
+org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
[4/4] incubator-ranger git commit: RANGER-230 Hbase plugin
implementation using new pluggable service model
Posted by ma...@apache.org.
RANGER-230 Hbase plugin implementation using new pluggable service model
Project: http://git-wip-us.apache.org/repos/asf/incubator-ranger/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-ranger/commit/46633a9e
Tree: http://git-wip-us.apache.org/repos/asf/incubator-ranger/tree/46633a9e
Diff: http://git-wip-us.apache.org/repos/asf/incubator-ranger/diff/46633a9e
Branch: refs/heads/stack
Commit: 46633a9ed2ed3499e95ad87409ce5b0460929da7
Parents: 1d6a259
Author: Alok Lal <al...@hortonworks.com>
Authored: Sat Jan 31 00:42:21 2015 -0800
Committer: Madhan Neethiraj <ma...@apache.org>
Committed: Sat Jan 31 00:42:21 2015 -0800
----------------------------------------------------------------------
.../hbase/AuthorizationSession.java | 342 +++++++++++++++++++
.../authorization/hbase/ColumnIterator.java | 94 +++++
.../authorization/hbase/HbaseAuditHandler.java | 48 +++
.../hbase/HbaseAuditHandlerImpl.java | 69 ++++
.../authorization/hbase/HbaseAuthUtils.java | 33 ++
.../authorization/hbase/HbaseAuthUtilsImpl.java | 66 ++++
.../authorization/hbase/HbaseFactory.java | 58 ++++
.../authorization/hbase/HbaseUserUtils.java | 52 +++
.../authorization/hbase/HbaseUserUtilsImpl.java | 91 +++++
.../hbase/RangerAuthorizationFilter.java | 69 ++++
.../hbase/AuthorizationSessionTest.java | 218 ++++++++++++
.../hbase/HbaseAuthUtilsImplTest.java | 33 ++
.../hbase/RangerCoprocessorTest.java | 33 ++
.../authorization/hbase/TestPolicyEngine.java | 178 ++++++++++
hbase-agent/src/test/resources/log4j.properties | 16 +
.../policyengine/test_policyengine_hbase.json | 159 +++++++++
16 files changed, 1559 insertions(+)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/46633a9e/hbase-agent/src/main/java/org/apache/ranger/authorization/hbase/AuthorizationSession.java
----------------------------------------------------------------------
diff --git a/hbase-agent/src/main/java/org/apache/ranger/authorization/hbase/AuthorizationSession.java b/hbase-agent/src/main/java/org/apache/ranger/authorization/hbase/AuthorizationSession.java
new file mode 100644
index 0000000..e6067ce
--- /dev/null
+++ b/hbase-agent/src/main/java/org/apache/ranger/authorization/hbase/AuthorizationSession.java
@@ -0,0 +1,342 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.ranger.authorization.hbase;
+
+
+import java.util.List;
+import java.util.Set;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.hadoop.hbase.security.AccessDeniedException;
+import org.apache.hadoop.hbase.security.User;
+import org.apache.ranger.audit.model.AuthzAuditEvent;
+import org.apache.ranger.plugin.policyengine.RangerAccessRequest;
+import org.apache.ranger.plugin.policyengine.RangerAccessRequestImpl;
+import org.apache.ranger.plugin.policyengine.RangerAccessResult;
+import org.apache.ranger.plugin.policyengine.RangerPolicyEngine;
+import org.apache.ranger.plugin.policyengine.RangerResourceImpl;
+
+import com.google.common.base.Objects;
+import com.google.common.collect.Lists;
+
+public class AuthorizationSession {
+
+ private static final Log LOG = LogFactory.getLog(AuthorizationSession.class.getName());
+ // collaborator objects
+ final HbaseFactory _factory = HbaseFactory.getInstance();
+ final HbaseUserUtils _userUtils = _factory.getUserUtils();
+ final HbaseAuthUtils _authUtils = _factory.getAuthUtils();
+ // immutable state
+ final RangerPolicyEngine _authorizer;
+ // Mutable state: Use supplied state information
+ String _operation;
+ String _otherInformation;
+ String _access;
+ String _table;
+ String _column;
+ String _columnFamily;
+ String _remoteAddress;
+ User _user;
+ Set<String> _groups; // this exits to avoid having to get group for a user repeatedly. It is kept in sync with _user;
+ // Passing a null handler to policy engine would suppress audit logging.
+ HbaseAuditHandler _auditHandler = null;
+
+ // internal state per-authorization
+ RangerAccessRequest _request;
+ RangerAccessResult _result;
+
+ public AuthorizationSession(RangerPolicyEngine authorizer) {
+ _authorizer = authorizer;
+ }
+
+ AuthorizationSession operation(String anOperation) {
+ _operation = anOperation;
+ return this;
+ }
+
+ AuthorizationSession otherInformation(String information) {
+ _otherInformation = information;
+ return this;
+ }
+
+ AuthorizationSession remoteAddress(String ipAddress) {
+ _remoteAddress = ipAddress;
+ return this;
+ }
+
+ AuthorizationSession access(String anAccess) {
+ _access = anAccess;
+ return this;
+ }
+
+ AuthorizationSession user(User aUser) {
+ _user = aUser;
+ if (_user == null) {
+ LOG.debug("AuthorizationSession.user: user is null!");
+ _groups = null;
+ } else {
+ _groups = _userUtils.getUserGroups(_user);
+ }
+ return this;
+ }
+ AuthorizationSession table(String aTable) {
+ _table = aTable;
+ return this;
+ }
+
+ AuthorizationSession columnFamily(String aColumnFamily) {
+ _columnFamily = aColumnFamily;
+ return this;
+ }
+
+ AuthorizationSession column(String aColumn) {
+ _column = aColumn;
+ return this;
+ }
+
+ void verifyBuildable() {
+
+ String template = "Internal error: Incomplete/inconsisten state: [%s]. Can't build auth request!";
+ if (_factory == null) {
+ String message = String.format(template, "factory is null");
+ LOG.error(message);
+ throw new IllegalStateException(message);
+ }
+ if (_access == null || _access.isEmpty()) {
+ String message = String.format(template, "access is null");
+ LOG.error(message);
+ throw new IllegalStateException(message);
+ }
+ if (_user == null) {
+ String message = String.format(template, "user is null");
+ LOG.error(message);
+ throw new IllegalStateException(message);
+ }
+ if (isProvided(_columnFamily) && !isProvided(_table)) {
+ String message = String.format(template, "Table must be provided if column-family is provided");
+ LOG.error(message);
+ throw new IllegalStateException(message);
+ }
+ if (isProvided(_column) && !isProvided(_columnFamily)) {
+ String message = String.format(template, "Column family must be provided if column is provided");
+ LOG.error(message);
+ throw new IllegalStateException(message);
+ }
+ }
+
+ void zapAuthorizationState() {
+ _request = null;
+ _result = null;
+ }
+
+ boolean isProvided(String aString) {
+ return aString != null && !aString.isEmpty();
+ }
+
+ AuthorizationSession buildRequest() {
+
+ verifyBuildable();
+ // session can be reused so reset its state
+ zapAuthorizationState();
+ // TODO get this via a factory instead
+ RangerResourceImpl resource = new RangerResourceImpl();
+ // policy engine should deal sensibly with null/empty values, if any
+ resource.setValue("table", _table);
+ resource.setValue("column-family", _columnFamily);
+ resource.setValue("column", _column);
+
+ String user = _userUtils.getUserAsString(_user);
+ LOG.debug("AuthorizationSession buildRequest: user[" + user + "], groups[" + _groups + "]");
+
+ RangerAccessRequestImpl request = new RangerAccessRequestImpl(resource, _access, user, _groups);
+ request.setAction(_operation);
+ request.setRequestData(_otherInformation);
+ request.setClientIPAddress(_remoteAddress);
+
+ _request = request;
+ return this;
+ }
+
+ AuthorizationSession authorize() {
+ if (LOG.isDebugEnabled()) {
+ String message = "authorize: " + getRequestMessage();
+ LOG.debug(message);
+ }
+ if (_request == null) {
+ String message = String.format("Invalid state transition: buildRequest() must be called before authorize(). This request would ultimately get denied.!");
+ throw new IllegalStateException(message);
+ } else {
+ // ok to pass potentially null handler to policy engine. Null handler effectively suppresses the audit.
+ _result = _authorizer.isAccessAllowed(_request, _auditHandler);
+ }
+ if (LOG.isDebugEnabled()) {
+ boolean allowed = isAuthorized();
+ String reason = getDenialReason();
+ String message = "AuthorizationSession.authorize: " + getLogMessage(allowed, reason);
+ LOG.debug(message);
+ }
+ return this;
+ }
+
+ void publishResults() throws AccessDeniedException {
+
+ boolean authorized = isAuthorized();
+ if (_auditHandler != null) {
+ List<AuthzAuditEvent> events = null;
+ /*
+ * What we log to audit depends on authorization status. For success we log all accumulated events. In case of failure
+ * we log just the last set of audit messages as we only need to record the cause of overall denial.
+ */
+ if (authorized) {
+ List<AuthzAuditEvent> theseEvents = _auditHandler.getCapturedEvents();
+ if (theseEvents != null && !theseEvents.isEmpty()) {
+ events = theseEvents;
+ }
+ } else {
+ AuthzAuditEvent event = _auditHandler.discardMostRecentEvent();
+ if (event != null) {
+ events = Lists.newArrayList(event);
+ }
+ }
+ if (LOG.isDebugEnabled()) {
+ int size = events == null ? 0 : events.size();
+ String auditMessage = events == null ? "" : events.toString();
+ String message = String.format("Writing %d messages to audit: [%s]", size, auditMessage);
+ LOG.debug(message);
+ }
+ _auditHandler.logAuthzAudits(events);
+ }
+ if (!authorized) {
+ // and throw and exception... callers expect this behavior
+ String reason = getDenialReason();
+ String message = getLogMessage(false, reason);
+ if (LOG.isDebugEnabled()) {
+ LOG.debug("AuthorizationSession.publishResults: throwing exception: " + message);
+ }
+ throw new AccessDeniedException("Insufficient permissions for user '" + _user.getName() + "' (action=" + _access + ")");
+ }
+ }
+
+ boolean isAudited() {
+
+ boolean audited = false;
+ if (_result == null) {
+ String message = String.format("Internal error: _result was null! Assuming no audit. Request[%s]", _request.toString());
+ LOG.error(message);
+ } else {
+ audited = _result.getIsAudited();
+ }
+ return audited;
+ }
+
+ boolean isAuthorized() {
+ boolean allowed = false;
+ if (_result == null) {
+ String message = String.format("Internal error: _result was null! Returning false.");
+ LOG.error(message);
+ } else {
+ allowed = _result.getIsAllowed();
+ }
+ return allowed;
+ }
+
+ String getDenialReason() {
+ String reason = "";
+ if (_result == null) {
+ String message = String.format("Internal error: _result was null! Returning empty reason.");
+ LOG.error(message);
+ } else {
+ boolean allowed = _result.getIsAllowed();
+ if (!allowed) {
+ reason = _result.getReason();
+ }
+ }
+ return reason;
+ }
+
+ String requestToString() {
+ return Objects.toStringHelper(_request.getClass())
+ .add("operation", _operation)
+ .add("otherInformation", _otherInformation)
+ .add("access", _access)
+ .add("user", _user == null ? null : _user.getName())
+ .add("groups", _groups)
+ .add("auditHandler", _auditHandler == null ? null : _auditHandler.getClass().getSimpleName())
+ .add("table", _table)
+ .add("column", _column)
+ .add("column-family", _columnFamily)
+ .toString();
+ }
+
+ String getPrintableValue(String value) {
+ if (isProvided(value)) {
+ return value;
+ } else {
+ return "";
+ }
+ }
+
+ String getRequestMessage() {
+ String format = "Access[%s] by user[%s] belonging to groups[%s] to table[%s] for column-family[%s], column[%s] triggered by operation[%s], otherInformation[%s]";
+ String user = _userUtils.getUserAsString();
+ String message = String.format(format, getPrintableValue(_access), getPrintableValue(user), _groups, getPrintableValue(_table),
+ getPrintableValue(_columnFamily), getPrintableValue(_column), getPrintableValue(_operation), getPrintableValue(_otherInformation));
+ return message;
+ }
+
+ String getLogMessage(boolean allowed, String reason) {
+ String format = " %s: status[%s], reason[%s]";
+ String message = String.format(format, getRequestMessage(), allowed ? "allowed" : "denied", reason);
+ return message;
+ }
+
+ /**
+ * Hand creates a result object and set it on the request for cases where we need not go to policy manager.
+ * @return
+ */
+ AuthorizationSession knownPatternAllowedNotAudited(String reason) {
+ _result = buildResult(true, false, reason);
+ return this;
+ }
+
+ AuthorizationSession knownPatternDisallowedNotAudited(String reason) {
+ _result = buildResult(false, false, reason);
+
+ return this;
+ }
+
+ /**
+ * This method could potentially null out an earlier audit handler -- which effectively would suppress audits.
+ * @param anAuditHandler
+ * @return
+ */
+ AuthorizationSession auditHandler(HbaseAuditHandler anAuditHandler) {
+ _auditHandler = anAuditHandler;
+ return this;
+ }
+
+ RangerAccessResult buildResult(boolean allowed, boolean audited, String reason) {
+ RangerAccessResult result = _authorizer.createAccessResult(_request);
+ result.setIsAllowed(allowed);
+ result.setReason(reason);
+ result.setIsAudited(audited);
+ return result;
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/46633a9e/hbase-agent/src/main/java/org/apache/ranger/authorization/hbase/ColumnIterator.java
----------------------------------------------------------------------
diff --git a/hbase-agent/src/main/java/org/apache/ranger/authorization/hbase/ColumnIterator.java b/hbase-agent/src/main/java/org/apache/ranger/authorization/hbase/ColumnIterator.java
new file mode 100644
index 0000000..2c6f805
--- /dev/null
+++ b/hbase-agent/src/main/java/org/apache/ranger/authorization/hbase/ColumnIterator.java
@@ -0,0 +1,94 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.ranger.authorization.hbase;
+
+import java.util.Collection;
+import java.util.Iterator;
+import java.util.List;
+import java.util.NoSuchElementException;
+import java.util.Set;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.hadoop.hbase.KeyValue;
+import org.apache.hadoop.hbase.util.Bytes;
+
+public class ColumnIterator implements Iterator<String> {
+ // TODO write tests for this class
+
+ private static final Log LOG = LogFactory.getLog(ColumnIterator.class.getName());
+ Iterator<byte[]> _setIterator;
+ Iterator<KeyValue> _listIterator;
+
+ @SuppressWarnings("unchecked")
+ public ColumnIterator(Collection<?> columnCollection) {
+ if (columnCollection != null) {
+ if (columnCollection instanceof Set) {
+ _setIterator = ((Set<byte[]>)columnCollection).iterator();
+ } else if (columnCollection instanceof List) {
+ _listIterator = ((List<KeyValue>)columnCollection).iterator();
+ } else { // unexpected
+ // TODO make message better
+ LOG.error("Unexpected type " + columnCollection.getClass().getName() + " passed as value in column family collection");
+ }
+ }
+ }
+
+ @Override
+ public boolean hasNext() {
+ if (_setIterator != null) {
+ return _setIterator.hasNext();
+ }
+ if (_listIterator != null) {
+ _listIterator.hasNext();
+ }
+ return false;
+ }
+
+ /**
+ * Never returns a null value. Will return empty string in case of null value.
+ */
+ @Override
+ public String next() {
+ String value = "";
+ if (_setIterator != null) {
+ byte[] valueBytes = _setIterator.next();
+ if (valueBytes != null) {
+ value = Bytes.toString(valueBytes);
+ }
+ } else if (_listIterator != null) {
+ KeyValue kv = _listIterator.next();
+ byte[] v = kv.getQualifier();
+ if (v != null) {
+ value = Bytes.toString(v);
+ }
+ } else {
+ // TODO make the error message better
+ throw new NoSuchElementException("Empty values passed in!");
+ }
+ return value;
+ }
+
+ @Override
+ public void remove() {
+ // TODO make the error message better
+ throw new UnsupportedOperationException("Remove not supported from iterator!");
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/46633a9e/hbase-agent/src/main/java/org/apache/ranger/authorization/hbase/HbaseAuditHandler.java
----------------------------------------------------------------------
diff --git a/hbase-agent/src/main/java/org/apache/ranger/authorization/hbase/HbaseAuditHandler.java b/hbase-agent/src/main/java/org/apache/ranger/authorization/hbase/HbaseAuditHandler.java
new file mode 100644
index 0000000..28d41aa
--- /dev/null
+++ b/hbase-agent/src/main/java/org/apache/ranger/authorization/hbase/HbaseAuditHandler.java
@@ -0,0 +1,48 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.ranger.authorization.hbase;
+
+import java.util.Collection;
+import java.util.List;
+
+import org.apache.ranger.audit.model.AuthzAuditEvent;
+import org.apache.ranger.plugin.audit.RangerAuditHandler;
+
+public interface HbaseAuditHandler extends RangerAuditHandler {
+
+ List<AuthzAuditEvent> getCapturedEvents();
+
+ void logAuthzAudits(Collection<AuthzAuditEvent> auditEvents);
+
+ /**
+ * Discards and returns the last audit events captured by the audit handler. Last audit event should be the ones generated during the most recent authorization request.
+ * However, it won't be all of the audit events called during an authorize call since implementation class may not override the method which takes a list of responses -- in
+ * which case there would be several audit messages generated by one call but this only allows you to get last of those messages created during single auth request.
+ * After this call the last set of audit events won't be returned by <code>getCapturedEvents</code>.
+ * @return
+ */
+ AuthzAuditEvent discardMostRecentEvent();
+
+ /**
+ * This is a complement to <code>discardMostRecentEvent</code> to set the most recent events. Often useful to un-pop audit messages that were take out.
+ * @param capturedEvents
+ */
+ void setMostRecentEvent(AuthzAuditEvent capturedEvents);
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/46633a9e/hbase-agent/src/main/java/org/apache/ranger/authorization/hbase/HbaseAuditHandlerImpl.java
----------------------------------------------------------------------
diff --git a/hbase-agent/src/main/java/org/apache/ranger/authorization/hbase/HbaseAuditHandlerImpl.java b/hbase-agent/src/main/java/org/apache/ranger/authorization/hbase/HbaseAuditHandlerImpl.java
new file mode 100644
index 0000000..a5d3f16
--- /dev/null
+++ b/hbase-agent/src/main/java/org/apache/ranger/authorization/hbase/HbaseAuditHandlerImpl.java
@@ -0,0 +1,69 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.ranger.authorization.hbase;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.ranger.audit.model.AuthzAuditEvent;
+import org.apache.ranger.plugin.audit.RangerDefaultAuditHandler;
+import org.apache.ranger.plugin.policyengine.RangerAccessResult;
+
+public class HbaseAuditHandlerImpl extends RangerDefaultAuditHandler implements HbaseAuditHandler {
+
+ static final List<AuthzAuditEvent> _EmptyList = new ArrayList<AuthzAuditEvent>();
+ final List<AuthzAuditEvent> _allEvents = new ArrayList<AuthzAuditEvent>();
+ // we replace its contents anytime new audit events are generated.
+ AuthzAuditEvent _mostRecentEvent = null;
+
+ @Override
+ public AuthzAuditEvent getAuthzEvents(RangerAccessResult result) {
+
+ AuthzAuditEvent event = super.getAuthzEvents(result);
+ // first accumulate last set of events and then capture these as the most recent ones
+ if (_mostRecentEvent != null) {
+ _allEvents.add(_mostRecentEvent);
+ }
+ _mostRecentEvent = event;
+ return event;
+ }
+
+ @Override
+ public List<AuthzAuditEvent> getCapturedEvents() {
+ // construct a new collection since we don't want to lose track of which were the most recent events;
+ List<AuthzAuditEvent> result = new ArrayList<AuthzAuditEvent>(_allEvents);
+ if (_mostRecentEvent != null) {
+ result.add(_mostRecentEvent);
+ }
+
+ return result;
+ }
+
+ @Override
+ public AuthzAuditEvent discardMostRecentEvent() {
+ AuthzAuditEvent result = _mostRecentEvent;
+ _mostRecentEvent = null;
+ return result;
+ }
+
+ @Override
+ public void setMostRecentEvent(AuthzAuditEvent event) {
+ _mostRecentEvent = event;
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/46633a9e/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
new file mode 100644
index 0000000..45d4cb4
--- /dev/null
+++ b/hbase-agent/src/main/java/org/apache/ranger/authorization/hbase/HbaseAuthUtils.java
@@ -0,0 +1,33 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.ranger.authorization.hbase;
+
+import org.apache.hadoop.hbase.coprocessor.RegionCoprocessorEnvironment;
+import org.apache.hadoop.hbase.security.access.Permission.Action;
+
+public interface HbaseAuthUtils {
+
+ String getAccess(Action action);
+
+ boolean isReadAccess(String access);
+
+ boolean isWriteAccess(String access);
+
+ String getTable(RegionCoprocessorEnvironment regionServerEnv);
+}
http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/46633a9e/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
new file mode 100644
index 0000000..955a85c
--- /dev/null
+++ b/hbase-agent/src/main/java/org/apache/ranger/authorization/hbase/HbaseAuthUtilsImpl.java
@@ -0,0 +1,66 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.ranger.authorization.hbase;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.hadoop.hbase.HRegionInfo;
+import org.apache.hadoop.hbase.NamespaceDescriptor;
+import org.apache.hadoop.hbase.coprocessor.RegionCoprocessorEnvironment;
+import org.apache.hadoop.hbase.security.access.Permission.Action;
+import org.apache.hadoop.hbase.util.Bytes;
+
+public class HbaseAuthUtilsImpl implements HbaseAuthUtils {
+
+ private static final Log LOG = LogFactory.getLog(HbaseAuthUtilsImpl.class.getName());
+
+ public String getNameSpace(NamespaceDescriptor ns) {
+ if (ns == null) {
+ // TODO log an error and Throw an error so the operation is denied?
+ }
+ return ns.getName();
+ }
+
+ @Override
+ public String getAccess(Action action) {
+ return action.toString().toLowerCase();
+ }
+
+ @Override
+ public boolean isReadAccess(String access) {
+ return getAccess(Action.READ).equals(access);
+ }
+
+ @Override
+ public boolean isWriteAccess(String access) {
+ return getAccess(Action.WRITE).equals(access);
+ }
+
+ @Override
+ public String getTable(RegionCoprocessorEnvironment regionServerEnv) {
+ HRegionInfo hri = regionServerEnv.getRegion().getRegionInfo();
+ byte[] tableName = hri.getTable().getName() ;
+ String tableNameStr = Bytes.toString(tableName);
+ if (LOG.isDebugEnabled()) {
+ String message = String.format("getTable: Returning tablename[%s]", tableNameStr);
+ LOG.debug(message);
+ }
+ return tableNameStr;
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/46633a9e/hbase-agent/src/main/java/org/apache/ranger/authorization/hbase/HbaseFactory.java
----------------------------------------------------------------------
diff --git a/hbase-agent/src/main/java/org/apache/ranger/authorization/hbase/HbaseFactory.java b/hbase-agent/src/main/java/org/apache/ranger/authorization/hbase/HbaseFactory.java
new file mode 100644
index 0000000..97e70ec
--- /dev/null
+++ b/hbase-agent/src/main/java/org/apache/ranger/authorization/hbase/HbaseFactory.java
@@ -0,0 +1,58 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.ranger.authorization.hbase;
+
+import org.apache.ranger.plugin.policyengine.RangerPolicyEngine;
+import org.apache.ranger.plugin.policyengine.RangerPolicyEngineImpl;
+
+
+// TODO remove this in favor of Guice DI
+public class HbaseFactory {
+
+ static final HbaseUserUtils _UserUtils = new HbaseUserUtilsImpl();
+ static final HbaseAuthUtils _AuthUtils = new HbaseAuthUtilsImpl();
+ static final RangerPolicyEngine _PolicyEngine = new RangerPolicyEngineImpl();
+ static final HbaseFactory _Factory = new HbaseFactory();
+ /**
+ * This is a singleton
+ */
+ private HbaseFactory() {
+ // TODO remove this clutch to enforce singleton by moving to a DI framework
+ }
+
+ static HbaseFactory getInstance() {
+ return _Factory;
+ }
+
+ HbaseAuthUtils getAuthUtils() {
+ return _AuthUtils;
+ }
+
+ HbaseUserUtils getUserUtils() {
+ return _UserUtils;
+ }
+
+ RangerPolicyEngine getPolicyEngine() {
+ return _PolicyEngine;
+ }
+
+ HbaseAuditHandler getAuditHandler() {
+ return new HbaseAuditHandlerImpl();
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/46633a9e/hbase-agent/src/main/java/org/apache/ranger/authorization/hbase/HbaseUserUtils.java
----------------------------------------------------------------------
diff --git a/hbase-agent/src/main/java/org/apache/ranger/authorization/hbase/HbaseUserUtils.java b/hbase-agent/src/main/java/org/apache/ranger/authorization/hbase/HbaseUserUtils.java
new file mode 100644
index 0000000..aa85994
--- /dev/null
+++ b/hbase-agent/src/main/java/org/apache/ranger/authorization/hbase/HbaseUserUtils.java
@@ -0,0 +1,52 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.ranger.authorization.hbase;
+
+import java.util.Set;
+
+import org.apache.hadoop.hbase.security.User;
+
+public interface HbaseUserUtils {
+ /**
+ * Returns user's short name or empty string if null is passed in.
+ * @param user
+ * @return
+ */
+ String getUserAsString(User user);
+
+ /**
+ * Returns the groups to which user belongs to as known to User object. For null values it returns an empty set.
+ * @param user
+ * @return
+ */
+ Set<String> getUserGroups(User user);
+
+ /**
+ * May return null in case of an error
+ * @return
+ */
+ User getUser();
+
+ /**
+ * Returns the user short name. Returns an empty string if Hbase User of context can't be found.
+ * @param request
+ * @return
+ */
+ String getUserAsString();
+}
http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/46633a9e/hbase-agent/src/main/java/org/apache/ranger/authorization/hbase/HbaseUserUtilsImpl.java
----------------------------------------------------------------------
diff --git a/hbase-agent/src/main/java/org/apache/ranger/authorization/hbase/HbaseUserUtilsImpl.java b/hbase-agent/src/main/java/org/apache/ranger/authorization/hbase/HbaseUserUtilsImpl.java
new file mode 100644
index 0000000..6b32e54
--- /dev/null
+++ b/hbase-agent/src/main/java/org/apache/ranger/authorization/hbase/HbaseUserUtilsImpl.java
@@ -0,0 +1,91 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.ranger.authorization.hbase;
+
+import java.io.IOException;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.Set;
+import java.util.concurrent.atomic.AtomicBoolean;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.hadoop.hbase.ipc.RequestContext;
+import org.apache.hadoop.hbase.security.User;
+
+public class HbaseUserUtilsImpl implements HbaseUserUtils {
+
+ private static final Log LOG = LogFactory.getLog(HbaseUserUtilsImpl.class.getName());
+
+ static Set<String> _SuperUsers = Collections.synchronizedSet(new HashSet<String>());
+ static AtomicBoolean initialized = new AtomicBoolean(false);
+
+ @Override
+ public String getUserAsString(User user) {
+ if (user == null) {
+ throw new IllegalArgumentException("User is null!");
+ }
+ else {
+ return user.getShortName();
+ }
+ }
+
+ @Override
+ public Set<String> getUserGroups(User user) {
+ if (user == null) {
+ throw new IllegalArgumentException("User is null!");
+ }
+ else {
+ String[] groupsArray = user.getGroupNames();
+ return new HashSet<String>(Arrays.asList(groupsArray));
+ }
+ }
+
+ @Override
+ public User getUser() {
+ // current implementation does not use the request object!
+ User user;
+ if (RequestContext.isInRequestContext()) {
+ // this is the more common case
+ user = RequestContext.getRequestUser();
+ }
+ else {
+ try {
+ user = User.getCurrent();
+ } catch (IOException e) {
+ LOG.error("Unable to get current user: User.getCurrent() threw IOException");
+ user = null;
+ }
+ }
+ return user;
+ }
+
+
+ @Override
+ public String getUserAsString() {
+ User user = getUser();
+ if (user == null) {
+ return "";
+ }
+ else {
+ return getUserAsString(user);
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/46633a9e/hbase-agent/src/main/java/org/apache/ranger/authorization/hbase/RangerAuthorizationFilter.java
----------------------------------------------------------------------
diff --git a/hbase-agent/src/main/java/org/apache/ranger/authorization/hbase/RangerAuthorizationFilter.java b/hbase-agent/src/main/java/org/apache/ranger/authorization/hbase/RangerAuthorizationFilter.java
new file mode 100644
index 0000000..5a66eb2
--- /dev/null
+++ b/hbase-agent/src/main/java/org/apache/ranger/authorization/hbase/RangerAuthorizationFilter.java
@@ -0,0 +1,69 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.ranger.authorization.hbase;
+
+import java.io.IOException;
+import java.util.Map;
+import java.util.Set;
+
+import org.apache.hadoop.hbase.Cell;
+import org.apache.hadoop.hbase.filter.FilterBase;
+import org.apache.hadoop.hbase.util.Bytes;
+
+public class RangerAuthorizationFilter extends FilterBase {
+
+ final Map<String, Set<String>> _cache;
+
+ public RangerAuthorizationFilter(Map<String, Set<String>> cache) {
+ _cache = cache;
+ }
+
+ @SuppressWarnings("deprecation")
+ @Override
+ public ReturnCode filterKeyValue(Cell kv) throws IOException {
+ // if our cache is null or empty then there is no hope for any access
+ if (_cache == null || _cache.isEmpty()) {
+ return ReturnCode.NEXT_COL;
+ }
+ // null/empty families are denied
+ byte[] familyBytes = kv.getFamily();
+ if (familyBytes == null || familyBytes.length == 0) {
+ return ReturnCode.NEXT_COL;
+ }
+ String family = Bytes.toString(familyBytes);
+ // null/empty columns are also denied
+ byte[] columnBytes = kv.getQualifier();
+ if (columnBytes == null || columnBytes.length == 0) {
+ return ReturnCode.NEXT_COL;
+ }
+ String column = Bytes.toString(columnBytes);
+ // allow if cache contains the family/column in it
+ Set<String> columns = _cache.get(family);
+ if (columns == null || columns.isEmpty()) {
+ // column family with a null/empty set of columns means all columns within that family are allowed
+ return ReturnCode.INCLUDE;
+ }
+ else if (columns.contains(column)) {
+ return ReturnCode.INCLUDE;
+ } else {
+ return ReturnCode.NEXT_COL;
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/46633a9e/hbase-agent/src/test/java/org/apache/ranger/authorization/hbase/AuthorizationSessionTest.java
----------------------------------------------------------------------
diff --git a/hbase-agent/src/test/java/org/apache/ranger/authorization/hbase/AuthorizationSessionTest.java b/hbase-agent/src/test/java/org/apache/ranger/authorization/hbase/AuthorizationSessionTest.java
new file mode 100644
index 0000000..1cd0d92
--- /dev/null
+++ b/hbase-agent/src/test/java/org/apache/ranger/authorization/hbase/AuthorizationSessionTest.java
@@ -0,0 +1,218 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.ranger.authorization.hbase;
+
+
+
+import static org.junit.Assert.*;
+import static org.mockito.Mockito.*;
+
+import org.apache.hadoop.hbase.security.User;
+import org.apache.ranger.plugin.policyengine.RangerPolicyEngine;
+import org.apache.ranger.plugin.policyengine.RangerPolicyEngineImpl;
+import org.junit.Assert;
+import org.junit.Test;
+
+public class AuthorizationSessionTest {
+
+ @Test
+ public void testAuthorizationSession() {
+// fail("Not yet implemented");
+ }
+
+ @Test
+ public void testOperation() {
+// fail("Not yet implemented");
+ }
+
+ @Test
+ public void testOtherInformation() {
+// fail("Not yet implemented");
+ }
+
+ @Test
+ public void testAccess() {
+// fail("Not yet implemented");
+ }
+
+ @Test
+ public void testUser() {
+// fail("Not yet implemented");
+ }
+
+ @Test
+ public void testTable() {
+// fail("Not yet implemented");
+ }
+
+ @Test
+ public void testColumnFamily() {
+// fail("Not yet implemented");
+ }
+
+ @Test
+ public void testColumn() {
+// fail("Not yet implemented");
+ }
+
+ @Test
+ public void testIsBuildable() {
+ RangerPolicyEngine engine = new RangerPolicyEngineImpl();
+ AuthorizationSession session = new AuthorizationSession(engine);
+ try {
+ session.verifyBuildable();
+ Assert.fail("Should have thrown exception");
+ } catch (IllegalStateException e) { }
+ // user and access are the only required ones.
+ User user = mock(User.class);
+ when(user.getGroupNames()).thenReturn(new String[] { "groups", "group2" });
+ session.access(" ");
+ session.user(user);
+ try {
+ session.verifyBuildable();
+ } catch (IllegalStateException e) {
+ fail("Shouldn't have thrown an exception!");
+ }
+ // setting column-family without table is a problem
+ session.columnFamily("family");
+ try {
+ session.verifyBuildable();
+ fail("Should have thrown an exception");
+ } catch (IllegalStateException e) { }
+
+ session.table("table");
+ try {
+ session.verifyBuildable();
+ } catch (IllegalStateException e) {
+ fail("Shouldn't have thrown an exception!");
+ }
+ // setting column without column-family is a problem
+ session.columnFamily(null);
+ session.column("col");
+ try {
+ session.verifyBuildable();
+ fail("Should have thrown an exception");
+ } catch (IllegalStateException e) { }
+ session.columnFamily("family");
+ try {
+ session.verifyBuildable();
+ } catch (IllegalStateException e) {
+ fail("Should have thrown an exception");
+ }
+ }
+
+ @Test
+ public void testZapAuthorizationState() {
+// fail("Not yet implemented");
+ }
+
+ @Test
+ public void testIsProvided() {
+ AuthorizationSession session = new AuthorizationSession(null);
+ assertFalse(session.isProvided(null));
+ assertFalse(session.isProvided(""));
+ assertTrue(session.isProvided(" "));
+ assertTrue(session.isProvided("xtq"));
+ }
+
+ @Test
+ public void testBuildRequest() {
+// fail("Not yet implemented");
+ }
+
+ @Test
+ public void testAuthorize() {
+ RangerPolicyEngine engine = new RangerPolicyEngineImpl();
+
+ User user = mock(User.class);
+ when(user.getShortName()).thenReturn("user1");
+ when(user.getGroupNames()).thenReturn(new String[] { "users" } );
+ AuthorizationSession session = new AuthorizationSession(engine);
+ session.access("read")
+ .user(user)
+ .table(":meta:")
+ .buildRequest()
+ .authorize();
+ }
+
+ @Test
+ public void testPublishResults() {
+// fail("Not yet implemented");
+ }
+
+ @Test
+ public void testIsAuthorized() {
+// fail("Not yet implemented");
+ }
+
+ @Test
+ public void testGetDenialReason() {
+// fail("Not yet implemented");
+ }
+
+ @Test
+ public void testGetResourceType() {
+// fail("Not yet implemented");
+ }
+
+ @Test
+ public void testRequestToString() {
+// fail("Not yet implemented");
+ }
+
+ @Test
+ public void testAudit() {
+// fail("Not yet implemented");
+ }
+
+ @Test
+ public void testGetPrintableValue() {
+// fail("Not yet implemented");
+ }
+
+ @Test
+ public void testBuildAccessDeniedMessage() {
+// fail("Not yet implemented");
+ }
+
+ @Test
+ public void testBuildAccessDeniedMessageString() {
+// fail("Not yet implemented");
+ }
+
+ @Test
+ public void testKnownPatternAllowedNotAudited() {
+// fail("Not yet implemented");
+ }
+
+ @Test
+ public void testKnownPatternDisallowedNotAudited() {
+// fail("Not yet implemented");
+ }
+
+ @Test
+ public void testAuditHandler() {
+// fail("Not yet implemented");
+ }
+
+ @Test
+ public void testBuildResult() {
+// fail("Not yet implemented");
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/46633a9e/hbase-agent/src/test/java/org/apache/ranger/authorization/hbase/HbaseAuthUtilsImplTest.java
----------------------------------------------------------------------
diff --git a/hbase-agent/src/test/java/org/apache/ranger/authorization/hbase/HbaseAuthUtilsImplTest.java b/hbase-agent/src/test/java/org/apache/ranger/authorization/hbase/HbaseAuthUtilsImplTest.java
new file mode 100644
index 0000000..e40f31a
--- /dev/null
+++ b/hbase-agent/src/test/java/org/apache/ranger/authorization/hbase/HbaseAuthUtilsImplTest.java
@@ -0,0 +1,33 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.ranger.authorization.hbase;
+
+import static org.junit.Assert.assertTrue;
+
+import org.junit.Test;
+
+public class HbaseAuthUtilsImplTest {
+
+ @Test
+ public void testIsReadAccess() {
+ HbaseAuthUtilsImpl authUtils = new HbaseAuthUtilsImpl();
+ assertTrue(authUtils.isReadAccess("read"));
+ assertTrue(authUtils.isWriteAccess("write"));
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/46633a9e/hbase-agent/src/test/java/org/apache/ranger/authorization/hbase/RangerCoprocessorTest.java
----------------------------------------------------------------------
diff --git a/hbase-agent/src/test/java/org/apache/ranger/authorization/hbase/RangerCoprocessorTest.java b/hbase-agent/src/test/java/org/apache/ranger/authorization/hbase/RangerCoprocessorTest.java
new file mode 100644
index 0000000..15d4f93
--- /dev/null
+++ b/hbase-agent/src/test/java/org/apache/ranger/authorization/hbase/RangerCoprocessorTest.java
@@ -0,0 +1,33 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.ranger.authorization.hbase;
+
+import static org.junit.Assert.assertNotNull;
+
+import org.junit.Test;
+
+public class RangerCoprocessorTest {
+
+ @Test
+ public void test_canBeNewed() {
+ RangerAuthorizationCoprocessor _coprocessor = new RangerAuthorizationCoprocessor();
+ assertNotNull(_coprocessor);
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/46633a9e/hbase-agent/src/test/java/org/apache/ranger/authorization/hbase/TestPolicyEngine.java
----------------------------------------------------------------------
diff --git a/hbase-agent/src/test/java/org/apache/ranger/authorization/hbase/TestPolicyEngine.java b/hbase-agent/src/test/java/org/apache/ranger/authorization/hbase/TestPolicyEngine.java
new file mode 100644
index 0000000..ed6bcf0
--- /dev/null
+++ b/hbase-agent/src/test/java/org/apache/ranger/authorization/hbase/TestPolicyEngine.java
@@ -0,0 +1,178 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.ranger.authorization.hbase;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.lang.reflect.Type;
+import java.util.List;
+
+import org.apache.hadoop.hbase.security.AccessDeniedException;
+import org.apache.hadoop.hbase.security.User;
+import org.apache.ranger.authorization.hbase.TestPolicyEngine.PolicyEngineTestCase.TestData;
+import org.apache.ranger.plugin.model.RangerPolicy;
+import org.apache.ranger.plugin.model.RangerServiceDef;
+import org.apache.ranger.plugin.policyengine.RangerAccessRequest;
+import org.apache.ranger.plugin.policyengine.RangerAccessRequestImpl;
+import org.apache.ranger.plugin.policyengine.RangerAccessResult;
+import org.apache.ranger.plugin.policyengine.RangerPolicyEngineImpl;
+import org.apache.ranger.plugin.policyengine.RangerResource;
+import org.apache.ranger.plugin.policyengine.RangerResourceImpl;
+import org.junit.AfterClass;
+import org.junit.BeforeClass;
+import org.junit.Test;
+
+import com.google.gson.Gson;
+import com.google.gson.GsonBuilder;
+import com.google.gson.JsonDeserializationContext;
+import com.google.gson.JsonDeserializer;
+import com.google.gson.JsonElement;
+import com.google.gson.JsonParseException;
+
+
+public class TestPolicyEngine {
+ static RangerPolicyEngineImpl policyEngine = null;
+ static Gson gsonBuilder = null;
+
+
+ @BeforeClass
+ public static void setUpBeforeClass() throws Exception {
+ policyEngine = new RangerPolicyEngineImpl();
+ gsonBuilder = new GsonBuilder().setDateFormat("yyyyMMdd-HH:mm:ss.SSS-Z")
+ .setPrettyPrinting()
+ .registerTypeAdapter(RangerAccessRequest.class, new RangerAccessRequestDeserializer())
+ .registerTypeAdapter(RangerResource.class, new RangerResourceDeserializer())
+ .create();
+ }
+
+ @AfterClass
+ public static void tearDownAfterClass() throws Exception {
+ }
+
+ @Test
+ public void testPolicyEngine_hbase() {
+ String[] hbaseTestResourceFiles = { "/policyengine/test_policyengine_hbase.json" };
+
+ runTestsFromResourceFiles(hbaseTestResourceFiles);
+
+ // lets use that policy engine now
+ AuthorizationSession session = new AuthorizationSession(policyEngine);
+ User user = mock(User.class);
+ when(user.getShortName()).thenReturn("user1");
+ when(user.getGroupNames()).thenReturn(new String[] { "users" });
+ session.access("read")
+ .user(user)
+ .table("finance")
+ .buildRequest()
+ .authorize();
+ assertTrue(session.isAuthorized());
+ try {
+ session.publishResults();
+ } catch (AccessDeniedException e) {
+ e.printStackTrace();
+ fail(e.getMessage());
+ }
+
+ when(user.getShortName()).thenReturn("user1");
+ when(user.getGroupNames()).thenReturn(new String[] { "users" });
+ session.access("write")
+ .buildRequest()
+ .authorize();
+ assertFalse(session.isAuthorized());
+ try {
+ session.publishResults();
+ fail("Should have throw exception on denied request!");
+ } catch (AccessDeniedException e) {
+ }
+
+ }
+
+ private void runTestsFromResourceFiles(String[] resourceNames) {
+ for(String resourceName : resourceNames) {
+ InputStream inStream = this.getClass().getResourceAsStream(resourceName);
+ InputStreamReader reader = new InputStreamReader(inStream);
+
+ runTests(reader, resourceName);
+ }
+ }
+
+ private void runTests(InputStreamReader reader, String testName) {
+ try {
+ PolicyEngineTestCase testCase = gsonBuilder.fromJson(reader, PolicyEngineTestCase.class);
+
+ assertTrue("invalid input: " + testName, testCase != null && testCase.serviceDef != null && testCase.policies != null && testCase.tests != null);
+
+ policyEngine.setPolicies(testCase.serviceName, testCase.serviceDef, testCase.policies);
+ boolean justBuildingPolicyEngine = true;
+ if (justBuildingPolicyEngine) {
+ return;
+ } else {
+ for(TestData test : testCase.tests) {
+ RangerAccessResult expected = test.result;
+ RangerAccessResult result = policyEngine.isAccessAllowed(test.request, null);
+
+ assertNotNull(test.name, result);
+ assertEquals(test.name, expected.getIsAllowed(), result.getIsAllowed());
+ }
+ }
+ } catch(Throwable excp) {
+ excp.printStackTrace();
+ }
+
+ }
+
+ static class PolicyEngineTestCase {
+ public String serviceName;
+ public RangerServiceDef serviceDef;
+ public List<RangerPolicy> policies;
+ public List<TestData> tests;
+
+ class TestData {
+ public String name;
+ public RangerAccessRequest request;
+ public RangerAccessResult result;
+ }
+ }
+
+ static class RangerAccessRequestDeserializer implements JsonDeserializer<RangerAccessRequest> {
+ @Override
+ public RangerAccessRequest deserialize(JsonElement jsonObj, Type type,
+ JsonDeserializationContext context) throws JsonParseException {
+ return gsonBuilder.fromJson(jsonObj, RangerAccessRequestImpl.class);
+ }
+ }
+
+ static class RangerResourceDeserializer implements JsonDeserializer<RangerResource> {
+ @Override
+ public RangerResource deserialize(JsonElement jsonObj, Type type,
+ JsonDeserializationContext context) throws JsonParseException {
+ return gsonBuilder.fromJson(jsonObj, RangerResourceImpl.class);
+ }
+ }
+}
+
http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/46633a9e/hbase-agent/src/test/resources/log4j.properties
----------------------------------------------------------------------
diff --git a/hbase-agent/src/test/resources/log4j.properties b/hbase-agent/src/test/resources/log4j.properties
new file mode 100644
index 0000000..71a8957
--- /dev/null
+++ b/hbase-agent/src/test/resources/log4j.properties
@@ -0,0 +1,16 @@
+# Define some default values that can be overridden by system properties
+ranger.root.logger=DEBUG,console
+# Define the root logger to the system property "hbase.root.logger".
+log4j.rootLogger=${ranger.root.logger}
+
+# Logging Threshold
+log4j.threshold=ALL
+
+#
+# console
+# Add "console" to rootlogger above if you want to use this
+#
+log4j.appender.console=org.apache.log4j.ConsoleAppender
+log4j.appender.console.target=System.err
+log4j.appender.console.layout=org.apache.log4j.PatternLayout
+log4j.appender.console.layout.ConversionPattern=%d{ISO8601} %-5p [%t] %c{2}: %m%n
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/46633a9e/hbase-agent/src/test/resources/policyengine/test_policyengine_hbase.json
----------------------------------------------------------------------
diff --git a/hbase-agent/src/test/resources/policyengine/test_policyengine_hbase.json b/hbase-agent/src/test/resources/policyengine/test_policyengine_hbase.json
new file mode 100644
index 0000000..f563c28
--- /dev/null
+++ b/hbase-agent/src/test/resources/policyengine/test_policyengine_hbase.json
@@ -0,0 +1,159 @@
+{
+ "serviceName":"hbasedev",
+
+ "serviceDef":{
+ "name":"hbase",
+ "id":2,
+ "resources":[
+ {"name":"table","level":1,"parent":"","mandatory":true,"lookupSupported":true,"matcher":"org.apache.ranger.plugin.resourcematcher.RangerDefaultResourceMatcher","matcherOptions":"wildCard=true;ignoreCase=true","label":"HBase Table","description":"HBase Table"},
+ {"name":"column-family","level":2,"table":"database","mandatory":true,"lookupSupported":true,"matcher":"org.apache.ranger.plugin.resourcematcher.RangerDefaultResourceMatcher","matcherOptions":"wildCard=true;ignoreCase=true","label":"HBase Column-Family","description":"HBase Column-Family"},
+ {"name":"column","level":3,"parent":"column-family","mandatory":true,"lookupSupported":true,"matcher":"org.apache.ranger.plugin.resourcematcher.RangerDefaultResourceMatcher","matcherOptions":"wildCard=true;ignoreCase=true","label":"HBase Column","description":"HBase Column"}
+ ],
+ "accessTypes":[
+ {"name":"read","label":"Read"},
+ {"name":"write","label":"Write"},
+ {"name":"create","label":"Create"},
+ {"name":"admin","label":"Admin","impliedGrants":["read","write","create"]}
+ ]
+ },
+
+ "policies":[
+ {"id":1,"name":"table=finance; column-family=restricted*: audit-all-access","isEnabled":true,"isAuditEnabled":true,
+ "resources":{"table":{"values":["finance"]},"column-family":{"values":["restricted*"]}},
+ "policyItems":[
+ {"accesses":[],"users":[],"groups":["public"],"delegateAdmin":false}
+ ]
+ }
+ ,
+ {"id":2,"name":"table=finance; column-family=restricted*","isEnabled":true,"isAuditEnabled":true,
+ "resources":{"table":{"values":["finance"]},"column-family":{"values":["restricted*"]}},
+ "policyItems":[
+ {"accesses":[{"type":"read","isAllowed":true},{"type":"write","isAllowed":true}],"users":[],"groups":["finance"],"delegateAdmin":false}
+ ,
+ {"accesses":[{"type":"admin","isAllowed":true}],"users":[],"groups":["finance-admin"],"delegateAdmin":true}
+ ]
+ }
+ ,
+ {"id":3,"name":"table=*; column-family=<excluding>restricted*","isEnabled":true,"isAuditEnabled":false,
+ "resources":{"table":{"values":["*"]},"column-family":{"values":["restricted*"],"isExcludes":true}},
+ "policyItems":[
+ {"accesses":[{"type":"read","isAllowed":true}],"users":[],"groups":["public"],"delegateAdmin":false}
+ ]
+ }
+ ],
+
+ "tests":[
+ {"name":"ALLOW 'scan finance restricted-cf;' for finance",
+ "request":{
+ "resource":{"elements":{"table":"finance","column-family":"restricted-cf"}},
+ "accessTypes":["read"],"user":"user1","userGroups":["users","finance"],"requestData":"scan finance restricted-cf"
+ },
+ "result":{"accessTypeResults":{"read":{"isAllowed":true,"isAudited":true,"policyId":2}}}
+ }
+ ,
+ {"name":"ALLOW 'put finance restricted-cf;' for finance",
+ "request":{
+ "resource":{"elements":{"table":"finance","column-family":"restricted-cf"}},
+ "accessTypes":["write"],"user":"user1","userGroups":["users","finance"],"requestData":"put finance restricted-cf"
+ },
+ "result":{"accessTypeResults":{"write":{"isAllowed":true,"isAudited":true,"policyId":2}}}
+ }
+ ,
+ {"name":"DENY 'create finance restricted-cf;' for finance",
+ "request":{
+ "resource":{"elements":{"table":"finance","column-family":"restricted-cf"}},
+ "accessTypes":["create"],"user":"user1","userGroups":["users","finance"],"requestData":"create finance restricted-cf"
+ },
+ "result":{"accessTypeResults":{"create":{"isAllowed":false,"isAudited":true,"policyId":-1}}}
+ }
+ ,
+ {"name":"DENY 'grant finance restricted-cf;' for finance",
+ "request":{
+ "resource":{"elements":{"table":"finance","column-family":"restricted-cf"}},
+ "accessTypes":["admin"],"user":"user1","userGroups":["users","finance"],"requestData":"grant finance restricted-cf"
+ },
+ "result":{"accessTypeResults":{"admin":{"isAllowed":false,"isAudited":true,"policyId":-1}}}
+ }
+ ,
+ {"name":"DENY 'scan finance restricted-cf;' for user1",
+ "request":{
+ "resource":{"elements":{"table":"finance","column-family":"restricted-cf"}},
+ "accessTypes":["read"],"user":"user1","userGroups":["users"],"requestData":"scan finance restricted-cf"
+ },
+ "result":{"accessTypeResults":{"read":{"isAllowed":false,"isAudited":true,"policyId":-1}}}
+ }
+ ,
+ {"name":"DENY 'put finance restricted-cf;' for user1",
+ "request":{
+ "resource":{"elements":{"table":"finance","column-family":"restricted-cf"}},
+ "accessTypes":["write"],"user":"user1","userGroups":["users"],"requestData":"put finance restricted-cf"
+ },
+ "result":{"accessTypeResults":{"write":{"isAllowed":false,"isAudited":true,"policyId":-1}}}
+ }
+ ,
+ {"name":"DENY 'create finance restricted-cf;' for user1",
+ "request":{
+ "resource":{"elements":{"table":"finance","column-family":"restricted-cf"}},
+ "accessTypes":["create"],"user":"user1","userGroups":["users"],"requestData":"create finance restricted-cf"
+ },
+ "result":{"accessTypeResults":{"create":{"isAllowed":false,"isAudited":true,"policyId":-1}}}
+ }
+ ,
+ {"name":"DENY 'grant finance restricted-cf;' for user1",
+ "request":{
+ "resource":{"elements":{"table":"finance","column-family":"restricted-cf"}},
+ "accessTypes":["admin"],"user":"user1","userGroups":["users"],"requestData":"grant finance restricted-cf"
+ },
+ "result":{"accessTypeResults":{"admin":{"isAllowed":false,"isAudited":true,"policyId":-1}}}
+ }
+ ,
+ {"name":"ALLOW 'scan finance restricted-cf;' for finance-admin",
+ "request":{
+ "resource":{"elements":{"table":"finance","column-family":"restricted-cf"}},
+ "accessTypes":["read"],"user":"user1","userGroups":["users","finance-admin"],"requestData":"scan finance restricted-cf"
+ },
+ "result":{"accessTypeResults":{"read":{"isAllowed":true,"isAudited":true,"policyId":2}}}
+ }
+ ,
+ {"name":"ALLOW 'put finance restricted-cf;' for finance-admin",
+ "request":{
+ "resource":{"elements":{"table":"finance","column-family":"restricted-cf"}},
+ "accessTypes":["write"],"user":"user1","userGroups":["users","finance-admin"],"requestData":"put finance restricted-cf"
+ },
+ "result":{"accessTypeResults":{"write":{"isAllowed":true,"isAudited":true,"policyId":2}}}
+ }
+ ,
+ {"name":"ALLOW 'create finance restricted-cf;' for finance-admin",
+ "request":{
+ "resource":{"elements":{"table":"finance","column-family":"restricted-cf"}},
+ "accessTypes":["create"],"user":"user1","userGroups":["users","finance-admin"],"requestData":"create finance restricted-cf"
+ },
+ "result":{"accessTypeResults":{"create":{"isAllowed":true,"isAudited":true,"policyId":2}}}
+ }
+ ,
+ {"name":"ALLOW 'grant finance restricted-cf;' for finance-admin",
+ "request":{
+ "resource":{"elements":{"table":"finance","column-family":"restricted-cf"}},
+ "accessTypes":["admin"],"user":"user1","userGroups":["users","finance-admin"],"requestData":"grant finance restricted-cf"
+ },
+ "result":{"accessTypeResults":{"admin":{"isAllowed":true,"isAudited":true,"policyId":2}}}
+ }
+ ,
+ {"name":"ALLOW 'scan finance regular-cf;' for user1",
+ "request":{
+ "resource":{"elements":{"table":"finance","column-family":"regular-cf"}},
+ "accessTypes":["read"],"user":"user1","userGroups":["users"],"requestData":"scan finance regular-cf"
+ },
+ "result":{"accessTypeResults":{"read":{"isAllowed":true,"isAudited":false,"policyId":3}}}
+ }
+ ,
+ {"name":"DENY 'put finance regular-cf;' for user1",
+ "request":{
+ "resource":{"elements":{"table":"finance","column-family":"regular-cf"}},
+ "accessTypes":["write"],"user":"user1","userGroups":["users"],"requestData":"put finance regular-cf"
+ },
+ "result":{"accessTypeResults":{"write":{"isAllowed":false,"isAudited":false,"policyId":-1}}}
+ }
+ ]
+}
+
[3/4] incubator-ranger git commit: RANGER-230 Hbase plugin
implementation using new pluggable service model.
Posted by ma...@apache.org.
RANGER-230 Hbase plugin implementation using new pluggable service model.
Project: http://git-wip-us.apache.org/repos/asf/incubator-ranger/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-ranger/commit/1d6a2590
Tree: http://git-wip-us.apache.org/repos/asf/incubator-ranger/tree/1d6a2590
Diff: http://git-wip-us.apache.org/repos/asf/incubator-ranger/diff/1d6a2590
Branch: refs/heads/stack
Commit: 1d6a2590f850248d20065e2b3a58ed8bc86b9e95
Parents: 9784f53
Author: Alok Lal <al...@hortonworks.com>
Authored: Sat Jan 31 00:37:29 2015 -0800
Committer: Madhan Neethiraj <ma...@apache.org>
Committed: Sat Jan 31 00:37:29 2015 -0800
----------------------------------------------------------------------
.../.settings/org.eclipse.jdt.core.prefs | 23 +-
...rg.eclipse.wst.common.project.facet.core.xml | 2 +-
.../.settings/org.eclipse.jdt.core.prefs | 13 +-
.../hadoop/constants/RangerHadoopConstants.java | 3 -
.../.settings/org.eclipse.jdt.core.prefs | 15 +-
.../.settings/org.eclipse.jdt.core.prefs | 6 +-
.../apache/ranger/pdp/hbase/HBaseAuthDB.java | 488 ----------
.../apache/ranger/pdp/hbase/HBaseAuthRules.java | 134 ---
.../ranger/pdp/hbase/RangerAuthorizer.java | 107 ---
.../apache/ranger/pdp/hbase/URLBasedAuthDB.java | 233 -----
.../.settings/org.eclipse.jdt.core.prefs | 6 +-
.../.settings/org.eclipse.jdt.core.prefs | 6 +-
.../.settings/org.eclipse.jdt.core.prefs | 6 +-
.../.settings/org.eclipse.core.resources.prefs | 1 +
.../.settings/org.eclipse.jdt.core.prefs | 6 +-
.../conf/xasecure-hbase-security-changes.cfg | 1 -
hbase-agent/conf/xasecure-hbase-security.xml | 10 -
hbase-agent/pom.xml | 18 +
.../hbase/HBaseAccessController.java | 40 -
.../hbase/HBaseAccessControllerFactory.java | 61 --
.../hbase/RangerAccessControlFilter.java | 51 -
.../hbase/RangerAuthorizationCoprocessor.java | 919 +++++++++----------
.../RangerAuthorizationCoprocessorBase.java | 539 +++--------
hdfs-agent/.settings/org.eclipse.jdt.core.prefs | 23 +-
hive-agent/.settings/org.eclipse.jdt.core.prefs | 13 +-
knox-agent/.settings/org.eclipse.jdt.core.prefs | 6 +-
.../.settings/org.eclipse.jdt.core.prefs | 6 +-
...rg.eclipse.wst.common.project.facet.core.xml | 2 +-
plugin-common/pom.xml | 12 +
.../plugin/policyengine/RangerAccessResult.java | 14 +
.../policyengine/RangerPolicyEngineImpl.java | 2 +-
.../ranger/plugin/util/PolicyRefresher.java | 2 +-
pom.xml | 1 +
.../.settings/org.eclipse.jdt.core.prefs | 6 +-
...rg.eclipse.wst.common.project.facet.core.xml | 2 +-
.../.settings/org.eclipse.jdt.core.prefs | 6 +-
ugsync/.settings/org.eclipse.jdt.core.prefs | 6 +-
.../.settings/org.eclipse.jdt.core.prefs | 6 +-
...rg.eclipse.wst.common.project.facet.core.xml | 2 +-
.../.settings/org.eclipse.jdt.core.prefs | 6 +-
40 files changed, 697 insertions(+), 2106 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/1d6a2590/agents-audit/.settings/org.eclipse.jdt.core.prefs
----------------------------------------------------------------------
diff --git a/agents-audit/.settings/org.eclipse.jdt.core.prefs b/agents-audit/.settings/org.eclipse.jdt.core.prefs
index 107056a..facfa83 100644
--- a/agents-audit/.settings/org.eclipse.jdt.core.prefs
+++ b/agents-audit/.settings/org.eclipse.jdt.core.prefs
@@ -1,12 +1,17 @@
-eclipse.preferences.version=1
-org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
-org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.6
-org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve
-org.eclipse.jdt.core.compiler.compliance=1.6
-org.eclipse.jdt.core.compiler.debug.lineNumber=generate
+#Wed Jan 21 11:38:44 PST 2015
+encoding/src/test/java=UTF-8
org.eclipse.jdt.core.compiler.debug.localVariable=generate
+org.eclipse.jdt.core.compiler.compliance=1.7
+org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve
+encoding/src/main/resources=UTF-8
org.eclipse.jdt.core.compiler.debug.sourceFile=generate
-org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
-org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
org.eclipse.jdt.core.compiler.problem.forbiddenReference=warning
-org.eclipse.jdt.core.compiler.source=1.6
+encoding/src/main/java=UTF-8
+org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.7
+org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
+org.eclipse.jdt.core.compiler.debug.lineNumber=generate
+eclipse.preferences.version=1
+encoding/src/test/resources=UTF-8
+org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
+org.eclipse.jdt.core.compiler.source=1.7
+org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/1d6a2590/agents-audit/.settings/org.eclipse.wst.common.project.facet.core.xml
----------------------------------------------------------------------
diff --git a/agents-audit/.settings/org.eclipse.wst.common.project.facet.core.xml b/agents-audit/.settings/org.eclipse.wst.common.project.facet.core.xml
index 08e864b..0bcc5bd 100644
--- a/agents-audit/.settings/org.eclipse.wst.common.project.facet.core.xml
+++ b/agents-audit/.settings/org.eclipse.wst.common.project.facet.core.xml
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<faceted-project>
- <installed facet="java" version="1.6"/>
<installed facet="jpt.jpa" version="2.0"/>
<installed facet="jst.utility" version="1.0"/>
+ <installed facet="java" version="1.7"/>
</faceted-project>
http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/1d6a2590/agents-common/.settings/org.eclipse.jdt.core.prefs
----------------------------------------------------------------------
diff --git a/agents-common/.settings/org.eclipse.jdt.core.prefs b/agents-common/.settings/org.eclipse.jdt.core.prefs
index 60105c1..51f2cb3 100644
--- a/agents-common/.settings/org.eclipse.jdt.core.prefs
+++ b/agents-common/.settings/org.eclipse.jdt.core.prefs
@@ -1,5 +1,10 @@
-eclipse.preferences.version=1
-org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.6
-org.eclipse.jdt.core.compiler.compliance=1.6
+#Wed Jan 21 11:38:44 PST 2015
+encoding/src/test/java=UTF-8
+org.eclipse.jdt.core.compiler.compliance=1.7
+encoding/src/main/resources=UTF-8
org.eclipse.jdt.core.compiler.problem.forbiddenReference=warning
-org.eclipse.jdt.core.compiler.source=1.6
+encoding/src/main/java=UTF-8
+org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.7
+eclipse.preferences.version=1
+encoding/src/test/resources=UTF-8
+org.eclipse.jdt.core.compiler.source=1.7
http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/1d6a2590/agents-common/src/main/java/org/apache/ranger/authorization/hadoop/constants/RangerHadoopConstants.java
----------------------------------------------------------------------
diff --git a/agents-common/src/main/java/org/apache/ranger/authorization/hadoop/constants/RangerHadoopConstants.java b/agents-common/src/main/java/org/apache/ranger/authorization/hadoop/constants/RangerHadoopConstants.java
index d87057d..906e941 100644
--- a/agents-common/src/main/java/org/apache/ranger/authorization/hadoop/constants/RangerHadoopConstants.java
+++ b/agents-common/src/main/java/org/apache/ranger/authorization/hadoop/constants/RangerHadoopConstants.java
@@ -52,9 +52,6 @@ public class RangerHadoopConstants {
public static final String KNOX_ACCESS_VERIFIER_CLASS_NAME_PROP = "knox.authorization.verifier.classname" ;
public static final String KNOX_ACCESS_VERIFIER_CLASS_NAME_DEFAULT_VALUE = "org.apache.ranger.pdp.knox.RangerAuthorizer" ;
- public static final String HBASE_ACCESS_VERIFIER_CLASS_NAME_PROP = "hbase.authorization.verifier.classname" ;
- public static final String HBASE_ACCESS_VERIFIER_CLASS_NAME_DEFAULT_VALUE = "org.apache.ranger.pdp.hbase.RangerAuthorizer" ;
-
public static final String STORM_ACCESS_VERIFIER_CLASS_NAME_PROP = "storm.authorization.verifier.classname" ;
public static final String STORM_ACCESS_VERIFIER_CLASS_NAME_DEFAULT_VALUE = "org.apache.ranger.pdp.storm.RangerAuthorizer" ;
http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/1d6a2590/agents-cred/.settings/org.eclipse.jdt.core.prefs
----------------------------------------------------------------------
diff --git a/agents-cred/.settings/org.eclipse.jdt.core.prefs b/agents-cred/.settings/org.eclipse.jdt.core.prefs
index 69c31cd..93353a7 100644
--- a/agents-cred/.settings/org.eclipse.jdt.core.prefs
+++ b/agents-cred/.settings/org.eclipse.jdt.core.prefs
@@ -1,8 +1,13 @@
+#Wed Jan 21 11:38:44 PST 2015
+encoding/src/test/java=UTF-8
+org.eclipse.jdt.core.compiler.compliance=1.7
+encoding/src/main/resources=UTF-8
+org.eclipse.jdt.core.compiler.problem.forbiddenReference=warning
+encoding/src/main/java=UTF-8
+org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.7
+org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
eclipse.preferences.version=1
+encoding/src/test/resources=UTF-8
org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
-org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.6
-org.eclipse.jdt.core.compiler.compliance=1.6
+org.eclipse.jdt.core.compiler.source=1.7
org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
-org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
-org.eclipse.jdt.core.compiler.problem.forbiddenReference=warning
-org.eclipse.jdt.core.compiler.source=1.6
http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/1d6a2590/agents-impl/.settings/org.eclipse.jdt.core.prefs
----------------------------------------------------------------------
diff --git a/agents-impl/.settings/org.eclipse.jdt.core.prefs b/agents-impl/.settings/org.eclipse.jdt.core.prefs
index 60105c1..ec4300d 100644
--- a/agents-impl/.settings/org.eclipse.jdt.core.prefs
+++ b/agents-impl/.settings/org.eclipse.jdt.core.prefs
@@ -1,5 +1,5 @@
eclipse.preferences.version=1
-org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.6
-org.eclipse.jdt.core.compiler.compliance=1.6
+org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.7
+org.eclipse.jdt.core.compiler.compliance=1.7
org.eclipse.jdt.core.compiler.problem.forbiddenReference=warning
-org.eclipse.jdt.core.compiler.source=1.6
+org.eclipse.jdt.core.compiler.source=1.7
http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/1d6a2590/agents-impl/src/main/java/org/apache/ranger/pdp/hbase/HBaseAuthDB.java
----------------------------------------------------------------------
diff --git a/agents-impl/src/main/java/org/apache/ranger/pdp/hbase/HBaseAuthDB.java b/agents-impl/src/main/java/org/apache/ranger/pdp/hbase/HBaseAuthDB.java
deleted file mode 100644
index 9f9affd..0000000
--- a/agents-impl/src/main/java/org/apache/ranger/pdp/hbase/HBaseAuthDB.java
+++ /dev/null
@@ -1,488 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-package org.apache.ranger.pdp.hbase;
-
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.List;
-
-import org.apache.commons.io.FilenameUtils;
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-import org.apache.hadoop.hbase.security.User;
-import org.apache.hadoop.hbase.security.access.Permission.Action;
-import org.apache.hadoop.hbase.security.access.UserPermission;
-import org.apache.hadoop.hbase.util.Bytes;
-import org.apache.hadoop.util.StringUtils;
-import org.apache.ranger.authorization.hbase.HBaseAccessController;
-import org.apache.ranger.pdp.constants.RangerConstants;
-
-public class HBaseAuthDB implements HBaseAccessController {
-
- private static final long MAX_CACHE_AUDIT_ENTRIES = 1000L ;
- private static final long MAX_CACHE_ENCRYPT_ENTRIES = 1000L ;
-
- private static final Log LOG = LogFactory.getLog(HBaseAuthDB.class) ;
-
- private ArrayList<HBaseAuthRules> ruleList = null;
- private ArrayList<HBaseAuthRules> globalList = null;
- private ArrayList<HBaseAuthRules> tableList = null;
-
- private ArrayList<String> auditList = null ;
- private HashMap<byte[],Boolean> cachedAuditTable = new HashMap<byte[],Boolean>() ;
-
- private ArrayList<String> encryptList = null ;
-
- private HashSet<String> encryptTableList = null ;
- private HashMap<byte[],Boolean> cachedEncryptedTable = new HashMap<byte[],Boolean>() ;
-
-
- public HBaseAuthDB(ArrayList<HBaseAuthRules> ruleList, ArrayList<String> auditList, ArrayList<String> encryptList) {
-
- if (LOG.isDebugEnabled()) {
- LOG.debug("+Creating HBaseAuthDB is creating with ruleList [" + (ruleList == null ? 0 : ruleList.size()) + "]" );
- }
-
- this.auditList = auditList;
- this.encryptList = encryptList;
-
-
- this.ruleList = new ArrayList<HBaseAuthRules>() ;
- this.globalList = new ArrayList<HBaseAuthRules>() ;
- this.tableList = new ArrayList<HBaseAuthRules>() ;
-
- for(HBaseAuthRules rule : ruleList ) {
- if (rule.isGlobalRule()) {
- this.globalList.add(rule) ;
- if (LOG.isDebugEnabled()) {
- LOG.debug("RULE:[" + rule + "] is being added as GLOBAL Policy");
- }
- }
- else if (rule.isTableRule()) {
- this.tableList.add(rule) ;
- if (LOG.isDebugEnabled()) {
- LOG.debug("RULE:[" + rule + "] is being added as Table Policy");
- }
- }
- else {
- this.ruleList.add(rule) ;
- if (LOG.isDebugEnabled()) {
- LOG.debug("RULE:[" + rule + "] is being added as non-global, non-table Policy");
- }
- }
- }
-
- this.encryptTableList = new HashSet<String>() ;
-
- if (encryptList != null && encryptList.size() > 0) {
- for(String encryptKey : encryptList) {
- String[] objKeys = encryptKey.split("/") ;
- String tableName = objKeys[0] ;
- if (! encryptTableList.contains(tableName)) {
- encryptTableList.add(tableName) ;
- if (LOG.isDebugEnabled()) {
- LOG.debug("EncryptionList:[" + tableName + "] is being added encrypted table.");
- }
- }
- }
- }
-
-
- }
-
-
- public boolean isAccessAllowed(User user, Action accessAction) {
-
-
- String access = accessAction.toString().toLowerCase() ;
-
- if (user == null) {
- if (LOG.isDebugEnabled()) {
- LOG.debug("rulecheck(GLOBAL," + access + ") => [FALSE] as user passed for check was null.");
- }
- return false ;
- }
-
-
- String username = user.getShortName() ;
-
- String[] groups = user.getGroupNames() ;
-
- if (LOG.isDebugEnabled()) {
- LOG.debug("Init of Global access Verification - [" + access + "] for user [" + username + "], groups: [" + Arrays.toString(groups) + "]");
- }
-
- for (HBaseAuthRules rule : globalList) {
-
- if (rule.getAccessType().equals(access)) {
-
- String authorizedUser = rule.getUser() ;
- String authorizedGroup = rule.getGroup();
-
- if (authorizedGroup != null) {
- if (RangerConstants.PUBLIC_ACCESS_ROLE.equals(authorizedGroup)) {
- if (LOG.isDebugEnabled()) {
- LOG.debug("rulecheck(GLOBAL," + access + "," + username + "," + StringUtils.arrayToString(groups) + ") => [TRUE] as matched for rule: " + rule);
- }
- return true ;
- }
-
- for (String group : groups) {
- if (group.equals(authorizedGroup)) {
- if (LOG.isDebugEnabled()) {
- LOG.debug("rulecheck(GLOBAL," + access + "," + username + "," + StringUtils.arrayToString(groups) + ") => [TRUE] as matched for rule: " + rule);
- }
- return true;
- }
- }
- }
-
- if (authorizedUser != null) {
- if (username.equals(authorizedUser)) {
- if (LOG.isDebugEnabled()) {
- LOG.debug("rulecheck(GLOBAL," + access + "," + username + "," + StringUtils.arrayToString(groups) + ") => [TRUE] as matched for rule: " + rule);
- }
- return true;
- }
- }
- }
- }
-
- if (LOG.isDebugEnabled()) {
- LOG.debug("rulecheck(GLOBAL," + access + "," + username + "," + StringUtils.arrayToString(groups) + ") => [FALSE] as it did not match any rules.");
- }
-
- return false;
- }
-
- public boolean isAccessAllowed(User user, byte[] tableName, Action accessAction) {
-
-
- if ( isAccessAllowed(user,accessAction)) { // Check Global Action
- return true ;
- }
-
- String tableNameStr = Bytes.toString(tableName) ;
-
- String access = accessAction.toString().toLowerCase() ;
-
- if (user == null) {
- if (LOG.isDebugEnabled()) {
- LOG.debug("rulecheck(" + tableNameStr + "," + access + ") => [FALSE] as user passed for check was null.");
- }
- return false ;
- }
-
- String username = user.getShortName() ;
-
- String[] groups = user.getGroupNames() ;
-
- if (LOG.isDebugEnabled()) {
- LOG.debug("Init of Table access Verification - [" + access + "] for user [" + username + "], groups: [" + Arrays.toString(groups) + "], tableName: [" + tableNameStr + "]");
- }
-
- for (HBaseAuthRules rule : tableList) {
-
- if (rule.isTableNameMatched(tableNameStr)) {
- if (rule.getAccessType().equals(access)) {
-
- String authorizedUser = rule.getUser() ;
-
- String authorizedGroup = rule.getGroup();
-
- if (authorizedGroup != null) {
- if (RangerConstants.PUBLIC_ACCESS_ROLE.equals(authorizedGroup)) {
- if (LOG.isDebugEnabled()) {
- LOG.debug("rulecheck(" + tableNameStr + "," + access + "," + username + "," + StringUtils.arrayToString(groups) + ") => [TRUE] as matched for rule: " + rule);
- }
- return true ;
- }
-
- for (String group : groups) {
- if (group.equals(authorizedGroup)) {
- if (LOG.isDebugEnabled()) {
- LOG.debug("rulecheck(" + tableNameStr + "," + access + "," + username + "," + StringUtils.arrayToString(groups) + ") => [TRUE] as matched for rule: " + rule);
- }
- return true;
- }
- }
- }
- if (authorizedUser != null && username.equals(authorizedUser)) {
- if (LOG.isDebugEnabled()) {
- LOG.debug("rulecheck(" + tableNameStr + "," + access + "," + username + "," + StringUtils.arrayToString(groups) + ") => [TRUE] as matched for rule: " + rule);
- }
- return true;
- }
- }
- }
- }
-
- if (LOG.isDebugEnabled()) {
- LOG.debug("rulecheck(" + tableNameStr + "," + access + "," + username + "," + StringUtils.arrayToString(groups) + ") => [FALSE] as it did not match any rules.");
- }
-
- return false;
- }
-
-
-
-
-
-
- public boolean isAccessAllowed(User user, byte[] tableName, byte[] columnFamily, byte[] qualifier, Action accessAction) {
-
- String FQColName = getFullyQualifiedColumnName(tableName, columnFamily, qualifier) ;
-
- String access = accessAction.toString().toLowerCase() ;
-
- if (LOG.isDebugEnabled()) {
- LOG.debug("isAccessAllowed on HBaseAuthDB: for FQColName [" + FQColName + "]");
- }
-
-
- if (user == null) {
- if (LOG.isDebugEnabled()) {
- LOG.debug("rulecheck(" + FQColName + "," + access + ") => [FALSE] as as user passed for check was null.");
- }
- return false ;
- }
-
-
- if (isAccessAllowed(user, accessAction)) { // Check Global Action
- return true ;
- }
-
- if (isAccessAllowed(user,tableName, accessAction)) { // Check Table Action
- return true;
- }
-
-
- String username = user.getShortName() ;
-
- String[] groups = user.getGroupNames() ;
-
- if (LOG.isDebugEnabled()) {
- LOG.debug("Init of Table access Verification - [" + access + "] for user [" + username + "], groups: [" + Arrays.toString(groups) + "], FQColumnFamily: [" + FQColName + "]");
- }
-
- for (HBaseAuthRules rule : ruleList) {
-
- if (rule.isMatched(FQColName)) {
- if (LOG.isDebugEnabled()) {
- LOG.debug("Rule [" + rule + "] matched [" + FQColName + "]");
- }
- if (rule.getAccessType().equals(access)) {
- if (LOG.isDebugEnabled()) {
- LOG.debug("Access [" + rule.getAccessType() + "] matched [" + access + "]");
- }
- String authorizedUser = rule.getUser() ;
-
- String authorizedGroup = rule.getGroup();
-
- if (authorizedGroup != null) {
- if (RangerConstants.PUBLIC_ACCESS_ROLE.equals(authorizedGroup)) {
- if (LOG.isDebugEnabled()) {
- LOG.debug("rulecheck(" + FQColName + "," + access + "," + username + "," + StringUtils.arrayToString(groups) + ") => [TRUE] as matched for rule: " + rule);
- }
- return true ;
- }
- for (String group : groups) {
- if (group.equals(authorizedGroup)) {
- if (LOG.isDebugEnabled()) {
- LOG.debug("rulecheck(" + FQColName + "," + access + "," + username + "," + StringUtils.arrayToString(groups) + ") => [TRUE] as matched for rule: " + rule);
- }
- return true;
- }
- }
- }
-
- if (authorizedUser != null) {
- if (username.equals(authorizedUser)) {
- if (LOG.isDebugEnabled()) {
- LOG.debug("rulecheck(" + FQColName + "," + access + "," + username + "," + StringUtils.arrayToString(groups) + ") => [TRUE] as matched for rule: " + rule);
- }
- return true;
- }
- }
- }
- else {
- if (LOG.isDebugEnabled()) {
- LOG.debug("Access [" + rule.getAccessType() + "] DID NOT match [" + access + "]");
- }
- }
- }
- else {
- if (LOG.isDebugEnabled()) {
- LOG.debug("Rule [" + rule + "] not matched [" + FQColName + "]");
- }
- }
- }
-
- if (LOG.isDebugEnabled()) {
- LOG.debug("rulecheck(" + FQColName + "," + access + "," + username + "," + StringUtils.arrayToString(groups) + ") => [FALSE] as it did not match any rules.");
- }
-
- return false;
-
- }
-
- public boolean isEncrypted(byte[] tableName, byte[] columnFamily, byte[] qualifier) {
- String colName = getFullyQualifiedColumnName(tableName, columnFamily, qualifier) ;
- for(String encryptable : encryptList) {
- if (FilenameUtils.wildcardMatch(colName,encryptable)) {
- return true ;
- }
- }
- return false;
- }
-
- public boolean isAudited(byte[] tableName) {
- Boolean ret = cachedAuditTable.get(tableName) ;
- if (ret == null) {
- ret = isAuditedFromTableList(tableName) ;
- synchronized(cachedAuditTable) {
- if (cachedAuditTable.size() > MAX_CACHE_AUDIT_ENTRIES) {
- cachedAuditTable.clear();
- }
- cachedAuditTable.put(tableName,ret) ;
- }
- }
- return ret.booleanValue();
- }
-
- private boolean isAuditedFromTableList(byte[] tableName) {
- boolean ret = false ;
- String tableNameStr = Bytes.toString(tableName) ;
- for(String auditable : auditList) {
- if (FilenameUtils.wildcardMatch(tableNameStr,auditable)) {
- ret = true ;
- break ;
- }
- }
-
- if (LOG.isDebugEnabled()) {
- LOG.debug("isAudited(" + tableNameStr + "):" + ret) ;
- }
-
- return ret;
- }
-
-
- public boolean isTableHasEncryptedColumn(byte[] tableName) {
- Boolean ret = cachedEncryptedTable.get(tableName) ;
- if (ret == null) {
- ret = isTableHasEncryptedColumnFromTableList(tableName) ;
- synchronized(cachedEncryptedTable) {
- if (cachedEncryptedTable.size() > MAX_CACHE_ENCRYPT_ENTRIES) {
- cachedEncryptedTable.clear();
- }
- cachedEncryptedTable.put(tableName, ret) ;
- }
- }
- return ret.booleanValue() ;
- }
-
-
- private boolean isTableHasEncryptedColumnFromTableList(byte[] tableName)
- {
- boolean ret = false ;
-
- String tableNameStr = Bytes.toString(tableName) ;
-
- for(String encryptTable : encryptTableList) {
- ret = FilenameUtils.wildcardMatch(tableNameStr, encryptTable) ;
- if (ret) {
- break ;
- }
- }
-
- if (LOG.isDebugEnabled()) {
- LOG.debug("isTableHasEncryptedColumn(" + tableNameStr + "):" + ret);
- }
-
- return ret ;
- }
-
-
-
- public static String getFullyQualifiedColumnName(byte[] tableName, byte[] columnFamily, byte[] qualifier) {
- StringBuilder sb = new StringBuilder() ;
-
- sb.append(((tableName != null && tableName.length > 0) ? Bytes.toString(tableName) : "*"))
- .append("/")
- .append(((columnFamily != null && columnFamily.length > 0) ? Bytes.toString(columnFamily) : "*"))
- .append("/")
- .append(((qualifier != null && qualifier.length > 0) ? Bytes.toString(qualifier) : "*")) ;
-
- return sb.toString() ;
- }
-
- public List<UserPermission> getUserPermissions(User user) {
- List<UserPermission> ret = new ArrayList<UserPermission>() ;
-
- if (user != null) {
- ArrayList<ArrayList<HBaseAuthRules>> allList = new ArrayList<ArrayList<HBaseAuthRules>>();
- allList.add(globalList) ;
- allList.add(tableList) ;
- allList.add(ruleList) ;
- for(ArrayList<HBaseAuthRules> rList : allList) {
- for(HBaseAuthRules rule : rList) {
- UserPermission perm = rule.getUserPermission(user) ;
- if (perm != null) {
- ret.add(perm) ;
- }
- }
- }
- }
-
- return ret ;
- }
-
- public List<UserPermission> getUserPermissions(User user, byte[] tableName) {
-
- String tableNameStr = Bytes.toString(tableName) ;
-
- List<UserPermission> ret = new ArrayList<UserPermission>() ;
-
- if (user != null) {
- ArrayList<ArrayList<HBaseAuthRules>> allList = new ArrayList<ArrayList<HBaseAuthRules>>();
- allList.add(globalList) ;
- allList.add(tableList) ;
- allList.add(ruleList) ;
- for(ArrayList<HBaseAuthRules> rList : allList) {
- for(HBaseAuthRules rule : rList) {
- if (rule.isTableNameMatched(tableNameStr)) {
- UserPermission perm = rule.getUserPermission(user) ;
- if (perm != null) {
- ret.add(perm) ;
- }
- }
- }
- }
- }
-
- return ret ;
- }
-
-
-
-}
http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/1d6a2590/agents-impl/src/main/java/org/apache/ranger/pdp/hbase/HBaseAuthRules.java
----------------------------------------------------------------------
diff --git a/agents-impl/src/main/java/org/apache/ranger/pdp/hbase/HBaseAuthRules.java b/agents-impl/src/main/java/org/apache/ranger/pdp/hbase/HBaseAuthRules.java
deleted file mode 100644
index ae3980d..0000000
--- a/agents-impl/src/main/java/org/apache/ranger/pdp/hbase/HBaseAuthRules.java
+++ /dev/null
@@ -1,134 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-package org.apache.ranger.pdp.hbase;
-
-import org.apache.commons.io.FilenameUtils;
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-import org.apache.hadoop.hbase.TableName;
-import org.apache.hadoop.hbase.security.User;
-import org.apache.hadoop.hbase.security.access.Permission;
-import org.apache.hadoop.hbase.security.access.UserPermission;
-import org.apache.ranger.pdp.constants.RangerConstants;
-
-public class HBaseAuthRules {
- private String tableName ;
- private String columnGroupName;
- private String columnName ;
- private String accessType ;
- private String group ;
- private String user ;
- private String fullyQualifiedColumnName ;
-
- private static final Log LOG = LogFactory.getLog(HBaseAuthRules.class) ;
-
- public HBaseAuthRules(String tableName, String columnGroupName, String columnName, String accessType, String user, String group) {
- this.tableName = tableName;
- this.columnGroupName = columnGroupName;
- this.columnName = columnName;
- if (accessType != null) {
- this.accessType = accessType.toLowerCase() ;
- }
- this.user = user ;
- this.group = group;
- this.fullyQualifiedColumnName = tableName + "/" + columnGroupName + "/" + columnName ;
- }
-
- public String getTableName() {
- return tableName;
- }
- public String getColumnGroupName() {
- return columnGroupName;
- }
- public String getColumnName() {
- return columnName;
- }
- public String getAccessType() {
- return accessType;
- }
- public String getGroup() {
- return group;
- }
-
- public String getUser() {
- return user;
- }
-
- @Override
- public String toString() {
- return "table: " + tableName + ", columnGroup:" + columnGroupName + ", columnName: " + columnName + ", accessType: " + accessType + ", user:" + user + ", group: " + group ;
- }
-
- public boolean isMatched(String FQColName) {
- return FQColName.equals(fullyQualifiedColumnName) || FilenameUtils.wildcardMatch(FQColName,fullyQualifiedColumnName) ;
- }
-
- public boolean isGlobalRule() {
- return ("*".equals(tableName) && "*".equals(columnGroupName) && "*".equals(columnName)) ;
- }
-
- public boolean isTableRule() {
- return ( ("*".equals(columnGroupName) && "*".equals(columnName)) || ("admin".equals(accessType) || "control".equals(accessType)) ) ;
- }
-
- public boolean isTableNameMatched(String tableNameStr) {
- boolean ret = (tableNameStr == null) || (tableNameStr.equals(tableName)) || FilenameUtils.wildcardMatch(tableNameStr,tableName) ;
- if (LOG.isDebugEnabled()) {
- LOG.debug("TableMatched returns (" + tableNameStr + ", rule:" + tableName + ") returns: " + ret );
- }
- return ret ;
- }
-
- public UserPermission getUserPermission(User aUser) {
-
- if (user == null) {
- return null ;
- }
-
- Permission.Action action = null ;
-
- try {
- action = Permission.Action.valueOf(accessType.toUpperCase()) ;
- } catch (Throwable e) {
- return null ;
- }
-
- if (RangerConstants.PUBLIC_ACCESS_ROLE.equals(group)) {
- return new UserPermission("public".getBytes(), TableName.valueOf ( tableName ) , columnGroupName.getBytes(), columnName.getBytes(), action) ;
- }
-
- if (user != null) {
- if (aUser.getShortName().equals(user)) {
- return new UserPermission(("user:(" + aUser.getShortName() + ")").getBytes(), TableName.valueOf( tableName ) , columnGroupName.getBytes(), columnName.getBytes(), action) ;
- }
- }
-
- if (group != null) {
- for (String ugroups : aUser.getGroupNames()) {
- if (ugroups.equals(group)) {
- return new UserPermission(("group:(" + ugroups + ")").getBytes(), TableName.valueOf( tableName ) , columnGroupName.getBytes(), columnName.getBytes(), action) ;
- }
- }
- }
-
- return null;
- }
-
-}
http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/1d6a2590/agents-impl/src/main/java/org/apache/ranger/pdp/hbase/RangerAuthorizer.java
----------------------------------------------------------------------
diff --git a/agents-impl/src/main/java/org/apache/ranger/pdp/hbase/RangerAuthorizer.java b/agents-impl/src/main/java/org/apache/ranger/pdp/hbase/RangerAuthorizer.java
deleted file mode 100644
index f832cfd..0000000
--- a/agents-impl/src/main/java/org/apache/ranger/pdp/hbase/RangerAuthorizer.java
+++ /dev/null
@@ -1,107 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-package org.apache.ranger.pdp.hbase;
-
-import java.util.List;
-
-import org.apache.hadoop.hbase.security.User;
-import org.apache.hadoop.hbase.security.access.Permission.Action;
-import org.apache.hadoop.hbase.security.access.UserPermission;
-import org.apache.ranger.authorization.hbase.HBaseAccessController;
-
-public class RangerAuthorizer implements HBaseAccessController {
-
- private HBaseAccessController authDB = URLBasedAuthDB.getInstance();
-
- @Override
- public boolean isAccessAllowed(User user, Action accessAction) {
- if (authDB != null) {
- return authDB.isAccessAllowed(user, accessAction);
- } else {
- return false;
- }
- }
-
- @Override
- public boolean isAccessAllowed(User user, byte[] tableName, Action accessAction) {
- if (authDB != null) {
- return authDB.isAccessAllowed(user, tableName, accessAction);
- } else {
- return false;
- }
- }
-
-
- @Override
- public boolean isAccessAllowed(User user, byte[] tableName, byte[] columnFamily, byte[] qualifier, Action accessAction) {
- if (authDB != null) {
- return authDB.isAccessAllowed(user, tableName, columnFamily, qualifier, accessAction);
- } else {
- return false;
- }
- }
-
- @Override
- public boolean isEncrypted(byte[] tableName, byte[] columnFamily, byte[] qualifier) {
- if (authDB != null) {
- return authDB.isEncrypted(tableName, columnFamily, qualifier);
- } else {
- return false;
- }
- }
-
- @Override
- public boolean isTableHasEncryptedColumn(byte[] tableName) {
- if (authDB != null) {
- return authDB.isTableHasEncryptedColumn(tableName);
- } else {
- return false;
- }
- }
-
-
- @Override
- public boolean isAudited(byte[] tableName) {
- if (authDB != null) {
- return authDB.isAudited(tableName);
- } else {
- return false;
- }
- }
-
- @Override
- public List<UserPermission> getUserPermissions(User aUser) {
- if (authDB != null) {
- return authDB.getUserPermissions(aUser) ;
- } else {
- return null;
- }
- }
-
- @Override
- public List<UserPermission> getUserPermissions(User aUser, byte[] aTableName) {
- if (authDB != null) {
- return authDB.getUserPermissions(aUser, aTableName) ;
- } else {
- return null;
- }
- }
-
-}
http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/1d6a2590/agents-impl/src/main/java/org/apache/ranger/pdp/hbase/URLBasedAuthDB.java
----------------------------------------------------------------------
diff --git a/agents-impl/src/main/java/org/apache/ranger/pdp/hbase/URLBasedAuthDB.java b/agents-impl/src/main/java/org/apache/ranger/pdp/hbase/URLBasedAuthDB.java
deleted file mode 100644
index b0e543a..0000000
--- a/agents-impl/src/main/java/org/apache/ranger/pdp/hbase/URLBasedAuthDB.java
+++ /dev/null
@@ -1,233 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-package org.apache.ranger.pdp.hbase;
-
-import java.util.ArrayList;
-import java.util.List;
-
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-import org.apache.hadoop.hbase.security.User;
-import org.apache.hadoop.hbase.security.access.Permission.Action;
-import org.apache.hadoop.hbase.security.access.UserPermission;
-import org.apache.ranger.authorization.hadoop.config.RangerConfiguration;
-import org.apache.ranger.authorization.hbase.HBaseAccessController;
-import org.apache.ranger.pdp.config.PolicyChangeListener;
-import org.apache.ranger.pdp.config.PolicyRefresher;
-import org.apache.ranger.pdp.constants.RangerConstants;
-import org.apache.ranger.pdp.model.Policy;
-import org.apache.ranger.pdp.model.PolicyContainer;
-import org.apache.ranger.pdp.model.RolePermission;
-
-public class URLBasedAuthDB implements HBaseAccessController, PolicyChangeListener {
-
- private static final Log LOG = LogFactory.getLog(URLBasedAuthDB.class);
-
- private HBaseAuthDB authDB = null;
-
- private static URLBasedAuthDB me = null ;
-
- private PolicyRefresher refresher = null ;
-
- public static URLBasedAuthDB getInstance() {
- if (me == null) {
- synchronized(URLBasedAuthDB.class) {
- URLBasedAuthDB temp = me ;
- if (temp == null) {
- me = new URLBasedAuthDB() ;
- me.init() ;
- }
- }
- }
- return me ;
- }
-
-
- private URLBasedAuthDB() {
- String url = RangerConfiguration.getInstance().get(RangerConstants.RANGER_HBASE_POLICYMGR_URL_PROP);
- long refreshInMilli = RangerConfiguration.getInstance().getLong(
- RangerConstants.RANGER_HBASE_POLICYMGR_URL_RELOAD_INTERVAL_IN_MILLIS_PROP,
- RangerConstants.RANGER_HBASE_POLICYMGR_URL_RELOAD_INTERVAL_IN_MILLIS_DEFAULT);
-
- String lastStoredFileName = RangerConfiguration.getInstance().get(RangerConstants.RANGER_HBASE_LAST_SAVED_POLICY_FILE_PROP) ;
-
- String sslConfigFileName = RangerConfiguration.getInstance().get(RangerConstants.RANGER_HBASE_POLICYMGR_SSL_CONFIG_FILE_PROP) ;
- refresher = new PolicyRefresher(url, refreshInMilli,sslConfigFileName,lastStoredFileName) ;
-
- String saveAsFileName = RangerConfiguration.getInstance().get(RangerConstants.RANGER_HBASE_POLICYMGR_URL_SAVE_FILE_PROP) ;
- if (saveAsFileName != null) {
- refresher.setSaveAsFileName(saveAsFileName) ;
- }
-
- if (lastStoredFileName != null) {
- refresher.setLastStoredFileName(lastStoredFileName);
- }
- }
-
- private void init() {
- refresher.setPolicyChangeListener(this);
- }
-
- public boolean isAccessAllowed(User user, Action accessAction) {
- if (authDB != null) {
- return authDB.isAccessAllowed(user, accessAction);
- } else {
- return false;
- }
- }
-
- public boolean isAccessAllowed(User user, byte[] tableName, Action accessAction) {
- if (authDB != null) {
- return authDB.isAccessAllowed(user, tableName, accessAction);
- } else {
- return false;
- }
- }
-
-
- public boolean isAccessAllowed(User user, byte[] tableName, byte[] columnFamily, byte[] qualifier, Action accessAction) {
- if (authDB != null) {
- return authDB.isAccessAllowed(user, tableName, columnFamily, qualifier, accessAction);
- } else {
- return false;
- }
- }
-
- public boolean isEncrypted(byte[] tableName, byte[] columnFamily, byte[] qualifier) {
- if (authDB != null) {
- return authDB.isEncrypted(tableName, columnFamily, qualifier);
- } else {
- return false;
- }
- }
-
- public boolean isTableHasEncryptedColumn(byte[] tableName) {
- if (authDB != null) {
- return authDB.isTableHasEncryptedColumn(tableName);
- } else {
- return false;
- }
- }
-
-
- public boolean isAudited(byte[] tableName) {
- if (authDB != null) {
- return authDB.isAudited(tableName);
- } else {
- return false;
- }
- }
-
- public List<UserPermission> getUserPermissions(User aUser) {
- if (authDB != null) {
- return authDB.getUserPermissions(aUser) ;
- } else {
- return null;
- }
- }
-
- public List<UserPermission> getUserPermissions(User aUser, byte[] aTableName) {
- if (authDB != null) {
- return authDB.getUserPermissions(aUser, aTableName) ;
- } else {
- return null;
- }
- }
-
- @Override
- public void OnPolicyChange(PolicyContainer aPolicyContainer) {
-
- if (aPolicyContainer == null) {
- return ;
- }
-
- ArrayList<HBaseAuthRules> ruleListTemp = new ArrayList<HBaseAuthRules>();
-
- HBaseAuthRules globalRule = new HBaseAuthRules(".META.", "*", "*", "read", null, RangerConstants.PUBLIC_ACCESS_ROLE) ;
- ruleListTemp.add(globalRule) ;
- globalRule = new HBaseAuthRules("-ROOT-", "*", "*", "read", null, RangerConstants.PUBLIC_ACCESS_ROLE) ;
- ruleListTemp.add(globalRule) ;
-
- ArrayList<String> auditListTemp = new ArrayList<String>();
-
- ArrayList<String> encryptList = new ArrayList<String>();
-
- for(Policy acl : aPolicyContainer.getAcl()) {
-
- if (! acl.isEnabled()) {
- LOG.debug("Diabled acl found [" + acl + "]. Skipping this acl ...") ;
- continue ;
- }
-
- for(String table : acl.getTableList()) {
- for(String colfamily : acl.getColumnFamilyList()) {
- for(String col : acl.getColumnList()) {
- if (table == null || table.isEmpty()) {
- table = "*" ;
- }
- if (colfamily == null || colfamily.isEmpty()) {
- colfamily = "*" ;
- }
- if (col == null || col.isEmpty()) {
- col = "*" ;
- }
-
- if (acl.getAuditInd() == 1) {
- if (!auditListTemp.contains(table)) {
- LOG.debug("Adding [" + table + "] to audit list");
- auditListTemp.add(table);
- }
- }
-
- if (acl.getEncryptInd() == 1) {
- String fqn = table + "/" + colfamily + "/" + col ;
- if (!encryptList.contains(fqn)) {
- LOG.debug("Adding [" + fqn + "] to encrypt list");
- encryptList.add(fqn);
- }
- }
-
- for(RolePermission rp : acl.getPermissions()) {
- for (String accessLevel : rp.getAccess() ) {
- if (rp.getGroups() != null && rp.getGroups().size() > 0) {
- for (String group : rp.getGroups()) {
- HBaseAuthRules rule = new HBaseAuthRules(table, colfamily, col, accessLevel, null, group);
- LOG.debug("Adding (group) rule: [" + rule + "]") ;
- ruleListTemp.add(rule);
- }
- }
- if (rp.getUsers() != null && rp.getUsers().size() > 0) {
- for (String user : rp.getUsers()) {
- HBaseAuthRules rule = new HBaseAuthRules(table, colfamily, col, accessLevel, user, null);
- LOG.debug("Adding (user) rule: [" + rule + "]") ;
- ruleListTemp.add(rule);
- }
- }
- }
- }
- }
- }
- }
- }
- HBaseAuthDB authDBTemp = new HBaseAuthDB(ruleListTemp, auditListTemp, encryptList);
- authDB = authDBTemp;
- }
-
-}
http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/1d6a2590/agents-installer/.settings/org.eclipse.jdt.core.prefs
----------------------------------------------------------------------
diff --git a/agents-installer/.settings/org.eclipse.jdt.core.prefs b/agents-installer/.settings/org.eclipse.jdt.core.prefs
index 60105c1..ec4300d 100644
--- a/agents-installer/.settings/org.eclipse.jdt.core.prefs
+++ b/agents-installer/.settings/org.eclipse.jdt.core.prefs
@@ -1,5 +1,5 @@
eclipse.preferences.version=1
-org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.6
-org.eclipse.jdt.core.compiler.compliance=1.6
+org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.7
+org.eclipse.jdt.core.compiler.compliance=1.7
org.eclipse.jdt.core.compiler.problem.forbiddenReference=warning
-org.eclipse.jdt.core.compiler.source=1.6
+org.eclipse.jdt.core.compiler.source=1.7
http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/1d6a2590/credentialbuilder/.settings/org.eclipse.jdt.core.prefs
----------------------------------------------------------------------
diff --git a/credentialbuilder/.settings/org.eclipse.jdt.core.prefs b/credentialbuilder/.settings/org.eclipse.jdt.core.prefs
index 60105c1..ec4300d 100644
--- a/credentialbuilder/.settings/org.eclipse.jdt.core.prefs
+++ b/credentialbuilder/.settings/org.eclipse.jdt.core.prefs
@@ -1,5 +1,5 @@
eclipse.preferences.version=1
-org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.6
-org.eclipse.jdt.core.compiler.compliance=1.6
+org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.7
+org.eclipse.jdt.core.compiler.compliance=1.7
org.eclipse.jdt.core.compiler.problem.forbiddenReference=warning
-org.eclipse.jdt.core.compiler.source=1.6
+org.eclipse.jdt.core.compiler.source=1.7
http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/1d6a2590/embededwebserver/.settings/org.eclipse.jdt.core.prefs
----------------------------------------------------------------------
diff --git a/embededwebserver/.settings/org.eclipse.jdt.core.prefs b/embededwebserver/.settings/org.eclipse.jdt.core.prefs
index 60105c1..ec4300d 100644
--- a/embededwebserver/.settings/org.eclipse.jdt.core.prefs
+++ b/embededwebserver/.settings/org.eclipse.jdt.core.prefs
@@ -1,5 +1,5 @@
eclipse.preferences.version=1
-org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.6
-org.eclipse.jdt.core.compiler.compliance=1.6
+org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.7
+org.eclipse.jdt.core.compiler.compliance=1.7
org.eclipse.jdt.core.compiler.problem.forbiddenReference=warning
-org.eclipse.jdt.core.compiler.source=1.6
+org.eclipse.jdt.core.compiler.source=1.7
http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/1d6a2590/hbase-agent/.settings/org.eclipse.core.resources.prefs
----------------------------------------------------------------------
diff --git a/hbase-agent/.settings/org.eclipse.core.resources.prefs b/hbase-agent/.settings/org.eclipse.core.resources.prefs
index f9fe345..cdfe4f1 100644
--- a/hbase-agent/.settings/org.eclipse.core.resources.prefs
+++ b/hbase-agent/.settings/org.eclipse.core.resources.prefs
@@ -1,4 +1,5 @@
eclipse.preferences.version=1
encoding//src/main/java=UTF-8
encoding//src/test/java=UTF-8
+encoding//src/test/resources=UTF-8
encoding/<project>=UTF-8
http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/1d6a2590/hbase-agent/.settings/org.eclipse.jdt.core.prefs
----------------------------------------------------------------------
diff --git a/hbase-agent/.settings/org.eclipse.jdt.core.prefs b/hbase-agent/.settings/org.eclipse.jdt.core.prefs
index 60105c1..ec4300d 100644
--- a/hbase-agent/.settings/org.eclipse.jdt.core.prefs
+++ b/hbase-agent/.settings/org.eclipse.jdt.core.prefs
@@ -1,5 +1,5 @@
eclipse.preferences.version=1
-org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.6
-org.eclipse.jdt.core.compiler.compliance=1.6
+org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.7
+org.eclipse.jdt.core.compiler.compliance=1.7
org.eclipse.jdt.core.compiler.problem.forbiddenReference=warning
-org.eclipse.jdt.core.compiler.source=1.6
+org.eclipse.jdt.core.compiler.source=1.7
http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/1d6a2590/hbase-agent/conf/xasecure-hbase-security-changes.cfg
----------------------------------------------------------------------
diff --git a/hbase-agent/conf/xasecure-hbase-security-changes.cfg b/hbase-agent/conf/xasecure-hbase-security-changes.cfg
index dc3ec1a..86354ff 100644
--- a/hbase-agent/conf/xasecure-hbase-security-changes.cfg
+++ b/hbase-agent/conf/xasecure-hbase-security-changes.cfg
@@ -16,7 +16,6 @@
# Change the original policy parameter to work with policy manager based.
#
#
-hbase.authorization.verifier.classname org.apache.ranger.pdp.hbase.RangerAuthorizer mod create-if-not-exists
xasecure.hbase.policymgr.url %POLICY_MGR_URL%/service/assets/policyList/%REPOSITORY_NAME% mod create-if-not-exists
xasecure.hbase.policymgr.url.saveAsFile /tmp/hbase_%REPOSITORY_NAME%_json mod create-if-not-exists
xasecure.hbase.policymgr.url.laststoredfile %POLICY_CACHE_FILE_PATH%/hbase_%REPOSITORY_NAME%_json mod create-if-not-exists
http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/1d6a2590/hbase-agent/conf/xasecure-hbase-security.xml
----------------------------------------------------------------------
diff --git a/hbase-agent/conf/xasecure-hbase-security.xml b/hbase-agent/conf/xasecure-hbase-security.xml
index 01e17a3..8ea2665 100644
--- a/hbase-agent/conf/xasecure-hbase-security.xml
+++ b/hbase-agent/conf/xasecure-hbase-security.xml
@@ -18,16 +18,6 @@
<?xml-stylesheet type="text/xsl" href="configuration.xsl"?>
<configuration xmlns:xi="http://www.w3.org/2001/XInclude">
- <!-- The following property is used to select appropriate XASecure
- Authorizer Module (file-based, policy-manager based) -->
- <property>
- <name>hbase.authorization.verifier.classname</name>
- <value>org.apache.ranger.pdp.hbase.RangerAuthorizer</value>
- <description>
- Class Name of the authorization Module
- </description>
- </property>
-
<!-- The following properties are used only when PolicyManager is used as
main storage for all policy -->
<property>
http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/1d6a2590/hbase-agent/pom.xml
----------------------------------------------------------------------
diff --git a/hbase-agent/pom.xml b/hbase-agent/pom.xml
index b309222..2749ca4 100644
--- a/hbase-agent/pom.xml
+++ b/hbase-agent/pom.xml
@@ -52,5 +52,23 @@
<artifactId>ranger-plugins-audit</artifactId>
<version>${project.version}</version>
</dependency>
+ <dependency>
+ <groupId>org.apache.ranger</groupId>
+ <artifactId>plugin-common</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>com.google.code.gson</groupId>
+ <artifactId>gson</artifactId>
+ <version>${gson.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.mockito</groupId>
+ <artifactId>mockito-core</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.hamcrest</groupId>
+ <artifactId>hamcrest-integration</artifactId>
+ </dependency>
</dependencies>
</project>
http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/1d6a2590/hbase-agent/src/main/java/org/apache/ranger/authorization/hbase/HBaseAccessController.java
----------------------------------------------------------------------
diff --git a/hbase-agent/src/main/java/org/apache/ranger/authorization/hbase/HBaseAccessController.java b/hbase-agent/src/main/java/org/apache/ranger/authorization/hbase/HBaseAccessController.java
deleted file mode 100644
index ab69712..0000000
--- a/hbase-agent/src/main/java/org/apache/ranger/authorization/hbase/HBaseAccessController.java
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-package org.apache.ranger.authorization.hbase;
-
-import java.util.List;
-
-import org.apache.hadoop.hbase.security.User;
-import org.apache.hadoop.hbase.security.access.Permission.Action;
-import org.apache.hadoop.hbase.security.access.UserPermission;
-
-public interface HBaseAccessController {
- public boolean isAccessAllowed(User user, Action accessAction) ;
- public boolean isAccessAllowed(User user, byte[] tableName, Action accessAction) ;
- public boolean isAccessAllowed(User user, byte[] tableName, byte[] columnFamily, byte[] qualifier, Action accessAction) ;
- public boolean isEncrypted(byte[] tableName, byte[] columnFamily, byte[] qualifier) ;
- public boolean isAudited(byte[] tableName) ;
- public boolean isTableHasEncryptedColumn(byte[] tableName) ;
- public List<UserPermission> getUserPermissions(User user) ;
- public List<UserPermission> getUserPermissions(User user, byte[] tableName) ;
-
-
-
-}
http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/1d6a2590/hbase-agent/src/main/java/org/apache/ranger/authorization/hbase/HBaseAccessControllerFactory.java
----------------------------------------------------------------------
diff --git a/hbase-agent/src/main/java/org/apache/ranger/authorization/hbase/HBaseAccessControllerFactory.java b/hbase-agent/src/main/java/org/apache/ranger/authorization/hbase/HBaseAccessControllerFactory.java
deleted file mode 100644
index 6f4301e..0000000
--- a/hbase-agent/src/main/java/org/apache/ranger/authorization/hbase/HBaseAccessControllerFactory.java
+++ /dev/null
@@ -1,61 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-package org.apache.ranger.authorization.hbase;
-
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-import org.apache.ranger.authorization.hadoop.config.RangerConfiguration;
-import org.apache.ranger.authorization.hadoop.constants.RangerHadoopConstants;
-
-public class HBaseAccessControllerFactory {
-
- private static final Log LOG = LogFactory.getLog(HBaseAccessControllerFactory.class) ;
-
- private static HBaseAccessController hBaseAccessController = null ;
-
- public static HBaseAccessController getInstance() {
- if (hBaseAccessController == null) {
- synchronized(HBaseAccessControllerFactory.class) {
- HBaseAccessController temp = hBaseAccessController ;
- if (temp == null) {
-
- String hBaseAccessControllerClassName = RangerConfiguration.getInstance().get(RangerHadoopConstants.HBASE_ACCESS_VERIFIER_CLASS_NAME_PROP, RangerHadoopConstants.HBASE_ACCESS_VERIFIER_CLASS_NAME_DEFAULT_VALUE) ;
- if (hBaseAccessControllerClassName != null) {
- try {
- hBaseAccessControllerClassName = hBaseAccessControllerClassName.trim();
- hBaseAccessController = (HBaseAccessController) (Class.forName(hBaseAccessControllerClassName).newInstance()) ;
- LOG.info("Created a new instance of class: [" + hBaseAccessControllerClassName + "] for HBase Access verification.");
- } catch (InstantiationException e) {
- LOG.error("Unable to create HBaseAccessController : [" + hBaseAccessControllerClassName + "]", e);
- } catch (IllegalAccessException e) {
- LOG.error("Unable to create HBaseAccessController : [" + hBaseAccessControllerClassName + "]", e);
- } catch (ClassNotFoundException e) {
- LOG.error("Unable to create HBaseAccessController : [" + hBaseAccessControllerClassName + "]", e);
- }
- }
- }
- }
- }
- return hBaseAccessController ;
-
- }
-
-
-}
http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/1d6a2590/hbase-agent/src/main/java/org/apache/ranger/authorization/hbase/RangerAccessControlFilter.java
----------------------------------------------------------------------
diff --git a/hbase-agent/src/main/java/org/apache/ranger/authorization/hbase/RangerAccessControlFilter.java b/hbase-agent/src/main/java/org/apache/ranger/authorization/hbase/RangerAccessControlFilter.java
deleted file mode 100644
index 9ba5331..0000000
--- a/hbase-agent/src/main/java/org/apache/ranger/authorization/hbase/RangerAccessControlFilter.java
+++ /dev/null
@@ -1,51 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-package org.apache.ranger.authorization.hbase;
-
-import java.io.IOException;
-
-import org.apache.hadoop.hbase.Cell;
-import org.apache.hadoop.hbase.filter.FilterBase;
-import org.apache.hadoop.hbase.security.User;
-import org.apache.hadoop.hbase.security.access.TablePermission;
-
-public class RangerAccessControlFilter extends FilterBase {
-
- private byte[] table = null;
- private User user = null;
-
- public RangerAccessControlFilter(User ugi, byte[] tableName) {
- table = tableName;
- user = ugi;
- }
-
-
- @SuppressWarnings("deprecation")
- @Override
- public ReturnCode filterKeyValue(Cell kv) throws IOException {
- HBaseAccessController accessController = HBaseAccessControllerFactory.getInstance();
- if (accessController.isAccessAllowed(user, table, kv.getFamily(), kv.getQualifier(), TablePermission.Action.READ)) {
- return ReturnCode.INCLUDE;
- } else {
- return ReturnCode.NEXT_COL;
- }
- }
-
-}