RANGER-908: Ranger policy model updated to support row-filtering
Project: http://git-wip-us.apache.org/repos/asf/incubator-ranger/repo Commit: http://git-wip-us.apache.org/repos/asf/incubator-ranger/commit/2c7f617b Tree: http://git-wip-us.apache.org/repos/asf/incubator-ranger/tree/2c7f617b Diff: http://git-wip-us.apache.org/repos/asf/incubator-ranger/diff/2c7f617b Branch: refs/heads/master Commit: 2c7f617be49fb9fc93b1e0e4fab62701602f6c55 Parents: 38b79e7 Author: Madhan Neethiraj <[email protected]> Authored: Sun Apr 3 22:01:17 2016 -0700 Committer: Madhan Neethiraj <[email protected]> Committed: Tue Apr 5 09:20:12 2016 -0700 ---------------------------------------------------------------------- .../ranger/plugin/model/RangerPolicy.java | 219 ++++++++- .../ranger/plugin/model/RangerServiceDef.java | 164 ++++++- .../validation/RangerServiceDefHelper.java | 6 + .../plugin/policyengine/RangerPolicyEngine.java | 2 + .../policyengine/RangerPolicyEngineImpl.java | 37 +- .../policyengine/RangerPolicyRepository.java | 26 +- .../policyengine/RangerRowFilterResult.java | 80 ++++ .../RangerDataMaskPolicyItemEvaluator.java | 10 +- ...angerDefaultDataMaskPolicyItemEvaluator.java | 28 +- .../RangerDefaultPolicyEvaluator.java | 468 ++++++++++++------- ...ngerDefaultRowFilterPolicyItemEvaluator.java | 42 ++ .../policyevaluator/RangerPolicyEvaluator.java | 3 + .../RangerPolicyItemEvaluator.java | 3 +- .../RangerRowFilterPolicyItemEvaluator.java | 28 ++ .../ranger/plugin/service/RangerBasePlugin.java | 12 + .../plugin/store/AbstractPredicateUtil.java | 8 +- .../ranger/plugin/util/ServiceDefUtil.java | 48 ++ .../service-defs/ranger-servicedef-hive.json | 30 +- .../plugin/policyengine/TestPolicyEngine.java | 14 +- .../test_policyengine_hive_mask_filter.json | 243 ++++++++++ .../test_policyengine_hive_masking.json | 156 ------- .../hive/authorizer/RangerHiveAuditHandler.java | 18 +- .../db/mysql/patches/020-datamask-policy.sql | 23 + .../db/postgres/patches/020-datamask-policy.sql | 30 ++ .../ranger/biz/RangerPolicyRetriever.java | 68 ++- .../org/apache/ranger/biz/ServiceDBStore.java | 312 ++++++++----- .../java/org/apache/ranger/biz/XUserMgr.java | 26 +- .../org/apache/ranger/common/AppConstants.java | 6 +- .../apache/ranger/db/RangerDaoManagerBase.java | 10 + .../ranger/db/XXPolicyItemRowFilterInfoDao.java | 71 +++ .../apache/ranger/entity/XXAccessTypeDef.java | 23 +- .../ranger/entity/XXPolicyItemDataMaskInfo.java | 41 +- .../entity/XXPolicyItemRowFilterInfo.java | 176 +++++++ .../org/apache/ranger/entity/XXResourceDef.java | 21 + .../service/RangerServiceDefServiceBase.java | 18 +- .../resources/META-INF/jpa_named_queries.xml | 21 + .../apache/ranger/biz/TestServiceDBStore.java | 17 + 37 files changed, 1952 insertions(+), 556 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/2c7f617b/agents-common/src/main/java/org/apache/ranger/plugin/model/RangerPolicy.java ---------------------------------------------------------------------- diff --git a/agents-common/src/main/java/org/apache/ranger/plugin/model/RangerPolicy.java b/agents-common/src/main/java/org/apache/ranger/plugin/model/RangerPolicy.java index f022707..d8e19b7 100644 --- a/agents-common/src/main/java/org/apache/ranger/plugin/model/RangerPolicy.java +++ b/agents-common/src/main/java/org/apache/ranger/plugin/model/RangerPolicy.java @@ -40,10 +40,15 @@ import org.codehaus.jackson.map.annotate.JsonSerialize; @XmlRootElement @XmlAccessorType(XmlAccessType.FIELD) public class RangerPolicy extends RangerBaseModelObject implements java.io.Serializable { - public static final int POLICY_TYPE_ACCESS = 0; - public static final int POLICY_TYPE_DATAMASK = 1; + public static final int POLICY_TYPE_ACCESS = 0; + public static final int POLICY_TYPE_DATAMASK = 1; + public static final int POLICY_TYPE_ROWFILTER = 2; - public static final int[] POLICY_TYPES = new int[] { POLICY_TYPE_ACCESS, POLICY_TYPE_DATAMASK }; + public static final int[] POLICY_TYPES = new int[] { + POLICY_TYPE_ACCESS, + POLICY_TYPE_DATAMASK, + POLICY_TYPE_ROWFILTER + }; // For future use private static final long serialVersionUID = 1L; @@ -59,7 +64,8 @@ public class RangerPolicy extends RangerBaseModelObject implements java.io.Seria private List<RangerPolicyItem> denyPolicyItems = null; private List<RangerPolicyItem> allowExceptions = null; private List<RangerPolicyItem> denyExceptions = null; - private List<RangerDataMaskPolicyItem> dataMaskPolicyItems = null; + private List<RangerDataMaskPolicyItem> dataMaskPolicyItems = null; + private List<RangerRowFilterPolicyItem> rowFilterPolicyItems = null; /** @@ -93,6 +99,7 @@ public class RangerPolicy extends RangerBaseModelObject implements java.io.Seria setAllowExceptions(null); setDenyExceptions(null); setDataMaskPolicyItems(null); + setRowFilterPolicyItems(null); } /** @@ -113,7 +120,7 @@ public class RangerPolicy extends RangerBaseModelObject implements java.io.Seria setAllowExceptions(other.getAllowExceptions()); setDenyExceptions(other.getDenyExceptions()); setDataMaskPolicyItems(other.getDataMaskPolicyItems()); - + setRowFilterPolicyItems(other.getRowFilterPolicyItems()); } /** @@ -362,6 +369,28 @@ public class RangerPolicy extends RangerBaseModelObject implements java.io.Seria } } + public List<RangerRowFilterPolicyItem> getRowFilterPolicyItems() { + return rowFilterPolicyItems; + } + + public void setRowFilterPolicyItems(List<RangerRowFilterPolicyItem> rowFilterPolicyItems) { + if(this.rowFilterPolicyItems == null) { + this.rowFilterPolicyItems = new ArrayList<RangerRowFilterPolicyItem>(); + } + + if(this.rowFilterPolicyItems == rowFilterPolicyItems) { + return; + } + + this.rowFilterPolicyItems.clear(); + + if(rowFilterPolicyItems != null) { + for(RangerRowFilterPolicyItem rowFilterPolicyItem : rowFilterPolicyItems) { + this.rowFilterPolicyItems.add(rowFilterPolicyItem); + } + } + } + @Override public String toString( ) { StringBuilder sb = new StringBuilder(); @@ -433,6 +462,26 @@ public class RangerPolicy extends RangerBaseModelObject implements java.io.Seria } sb.append("} "); + sb.append("dataMaskPolicyItems={"); + if(dataMaskPolicyItems != null) { + for(RangerDataMaskPolicyItem dataMaskPolicyItem : dataMaskPolicyItems) { + if(dataMaskPolicyItem != null) { + dataMaskPolicyItem.toString(sb); + } + } + } + sb.append("} "); + + sb.append("rowFilterPolicyItems={"); + if(rowFilterPolicyItems != null) { + for(RangerRowFilterPolicyItem rowFilterPolicyItem : rowFilterPolicyItems) { + if(rowFilterPolicyItem != null) { + rowFilterPolicyItem.toString(sb); + } + } + } + sb.append("} "); + sb.append("}"); return sb; @@ -899,7 +948,7 @@ public class RangerPolicy extends RangerBaseModelObject implements java.io.Seria * @param dataMaskInfo the dataMaskInfo to set */ public void setDataMaskInfo(RangerPolicyItemDataMaskInfo dataMaskInfo) { - this.dataMaskInfo = dataMaskInfo; + this.dataMaskInfo = dataMaskInfo == null ? new RangerPolicyItemDataMaskInfo() : dataMaskInfo; } @Override @@ -960,6 +1009,93 @@ public class RangerPolicy extends RangerBaseModelObject implements java.io.Seria @JsonIgnoreProperties(ignoreUnknown=true) @XmlRootElement @XmlAccessorType(XmlAccessType.FIELD) + public static class RangerRowFilterPolicyItem extends RangerPolicyItem implements java.io.Serializable { + private static final long serialVersionUID = 1L; + + private RangerPolicyItemRowFilterInfo rowFilterInfo = null; + + public RangerRowFilterPolicyItem() { + this(null, null, null, null, null, null); + } + + public RangerRowFilterPolicyItem(RangerPolicyItemRowFilterInfo rowFilterInfo, List<RangerPolicyItemAccess> accesses, List<String> users, List<String> groups, List<RangerPolicyItemCondition> conditions, Boolean delegateAdmin) { + super(accesses, users, groups, conditions, delegateAdmin); + + setRowFilterInfo(rowFilterInfo); + } + + /** + * @return the rowFilterInfo + */ + public RangerPolicyItemRowFilterInfo getRowFilterInfo() { + return rowFilterInfo; + } + + /** + * @param rowFilterInfo the rowFilterInfo to set + */ + public void setRowFilterInfo(RangerPolicyItemRowFilterInfo rowFilterInfo) { + this.rowFilterInfo = rowFilterInfo == null ? new RangerPolicyItemRowFilterInfo() : rowFilterInfo; + } + + @Override + public int hashCode() { + final int prime = 31; + int result = super.hashCode(); + result = prime * result + ((rowFilterInfo == null) ? 0 : rowFilterInfo.hashCode()); + return result; + } + + @Override + public boolean equals(Object obj) { + if(! super.equals(obj)) + return false; + if (this == obj) + return true; + if (obj == null) + return false; + if (getClass() != obj.getClass()) + return false; + RangerRowFilterPolicyItem other = (RangerRowFilterPolicyItem) obj; + if (rowFilterInfo == null) { + if (other.rowFilterInfo != null) + return false; + } else if (!rowFilterInfo.equals(other.rowFilterInfo)) + return false; + return true; + } + + @Override + public String toString( ) { + StringBuilder sb = new StringBuilder(); + + toString(sb); + + return sb.toString(); + } + + public StringBuilder toString(StringBuilder sb) { + sb.append("RangerRowFilterPolicyItem={"); + + super.toString(sb); + + sb.append("rowFilterInfo={"); + if(rowFilterInfo != null) { + rowFilterInfo.toString(sb); + } + sb.append("} "); + + sb.append("}"); + + return sb; + } + } + + @JsonAutoDetect(fieldVisibility=Visibility.ANY) + @JsonSerialize(include=JsonSerialize.Inclusion.NON_NULL) + @JsonIgnoreProperties(ignoreUnknown=true) + @XmlRootElement + @XmlAccessorType(XmlAccessType.FIELD) public static class RangerPolicyItemAccess implements java.io.Serializable { private static final long serialVersionUID = 1L; @@ -1283,4 +1419,75 @@ public class RangerPolicy extends RangerBaseModelObject implements java.io.Seria return sb; } } + + @JsonAutoDetect(fieldVisibility=Visibility.ANY) + @JsonSerialize(include=JsonSerialize.Inclusion.NON_NULL) + @JsonIgnoreProperties(ignoreUnknown=true) + @XmlRootElement + @XmlAccessorType(XmlAccessType.FIELD) + public static class RangerPolicyItemRowFilterInfo implements java.io.Serializable { + private static final long serialVersionUID = 1L; + + private String filterExpr = null; + + public RangerPolicyItemRowFilterInfo() { } + + public RangerPolicyItemRowFilterInfo(String filterExpr) { + setFilterExpr(filterExpr); + } + + public String getFilterExpr() { + return filterExpr; + } + + public void setFilterExpr(String filterExpr) { + this.filterExpr = filterExpr; + } + + @Override + public int hashCode() { + final int prime = 31; + int result = super.hashCode(); + result = prime * result + ((filterExpr == null) ? 0 : filterExpr.hashCode()); + return result; + } + + @Override + public boolean equals(Object obj) { + if(! super.equals(obj)) + return false; + if (this == obj) + return true; + if (obj == null) + return false; + if (getClass() != obj.getClass()) + return false; + RangerPolicyItemRowFilterInfo other = (RangerPolicyItemRowFilterInfo) obj; + if (filterExpr == null) { + if (other.filterExpr != null) + return false; + } else if (!filterExpr.equals(other.filterExpr)) + return false; + return true; + } + + @Override + public String toString( ) { + StringBuilder sb = new StringBuilder(); + + toString(sb); + + return sb.toString(); + } + + public StringBuilder toString(StringBuilder sb) { + sb.append("RangerPolicyItemDataMaskInfo={"); + + sb.append("filterExpr={").append(filterExpr).append("} "); + + sb.append("}"); + + return sb; + } + } } http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/2c7f617b/agents-common/src/main/java/org/apache/ranger/plugin/model/RangerServiceDef.java ---------------------------------------------------------------------- diff --git a/agents-common/src/main/java/org/apache/ranger/plugin/model/RangerServiceDef.java b/agents-common/src/main/java/org/apache/ranger/plugin/model/RangerServiceDef.java index 1dac6e8..0f0e5ee 100644 --- a/agents-common/src/main/java/org/apache/ranger/plugin/model/RangerServiceDef.java +++ b/agents-common/src/main/java/org/apache/ranger/plugin/model/RangerServiceDef.java @@ -59,14 +59,15 @@ public class RangerServiceDef extends RangerBaseModelObject implements java.io.S private List<RangerContextEnricherDef> contextEnrichers = null; private List<RangerEnumDef> enums = null; private RangerDataMaskDef dataMaskDef = null; + private RangerRowFilterDef rowFilterDef = null; public RangerServiceDef() { - this(null, null, null, null, null, null, null, null, null, null, null, null); + this(null, null, null, null, null, null, null, null, null, null, null, null, null); } public RangerServiceDef(String name, String implClass, String label, String description, Map<String, String> options, List<RangerServiceConfigDef> configs, List<RangerResourceDef> resources, List<RangerAccessTypeDef> accessTypes, List<RangerPolicyConditionDef> policyConditions, List<RangerContextEnricherDef> contextEnrichers, List<RangerEnumDef> enums) { - this(name, implClass, label, description, options, configs, resources, accessTypes, policyConditions, contextEnrichers, enums, null); + this(name, implClass, label, description, options, configs, resources, accessTypes, policyConditions, contextEnrichers, enums, null, null); } /** @@ -83,7 +84,7 @@ public class RangerServiceDef extends RangerBaseModelObject implements java.io.S * @param dataMaskDef * @param enums */ - public RangerServiceDef(String name, String implClass, String label, String description, Map<String, String> options, List<RangerServiceConfigDef> configs, List<RangerResourceDef> resources, List<RangerAccessTypeDef> accessTypes, List<RangerPolicyConditionDef> policyConditions, List<RangerContextEnricherDef> contextEnrichers, List<RangerEnumDef> enums, RangerDataMaskDef dataMaskDef) { + public RangerServiceDef(String name, String implClass, String label, String description, Map<String, String> options, List<RangerServiceConfigDef> configs, List<RangerResourceDef> resources, List<RangerAccessTypeDef> accessTypes, List<RangerPolicyConditionDef> policyConditions, List<RangerContextEnricherDef> contextEnrichers, List<RangerEnumDef> enums, RangerDataMaskDef dataMaskDef, RangerRowFilterDef rowFilterDef) { super(); setName(name); @@ -98,6 +99,7 @@ public class RangerServiceDef extends RangerBaseModelObject implements java.io.S setContextEnrichers(contextEnrichers); setEnums(enums); setDataMaskDef(dataMaskDef); + setRowFilterDef(rowFilterDef); } /** @@ -116,6 +118,7 @@ public class RangerServiceDef extends RangerBaseModelObject implements java.io.S setPolicyConditions(other.getPolicyConditions()); setEnums(other.getEnums()); setDataMaskDef(other.getDataMaskDef()); + setRowFilterDef(other.getRowFilterDef()); } /** @@ -404,6 +407,14 @@ public class RangerServiceDef extends RangerBaseModelObject implements java.io.S this.dataMaskDef = dataMaskDef == null ? new RangerDataMaskDef() : dataMaskDef; } + public RangerRowFilterDef getRowFilterDef() { + return rowFilterDef; + } + + public void setRowFilterDef(RangerRowFilterDef rowFilterDef) { + this.rowFilterDef = rowFilterDef == null ? new RangerRowFilterDef() : rowFilterDef; + } + @Override public String toString( ) { StringBuilder sb = new StringBuilder(); @@ -499,6 +510,12 @@ public class RangerServiceDef extends RangerBaseModelObject implements java.io.S } sb.append("} "); + sb.append("rowFilterDef={"); + if(rowFilterDef != null) { + rowFilterDef.toString(sb); + } + sb.append("} "); + sb.append("}"); return sb; @@ -2880,4 +2897,145 @@ public class RangerServiceDef extends RangerBaseModelObject implements java.io.S return true; } } + + @JsonAutoDetect(fieldVisibility=Visibility.ANY) + @JsonSerialize(include=JsonSerialize.Inclusion.NON_NULL) + @JsonIgnoreProperties(ignoreUnknown=true) + @XmlRootElement + @XmlAccessorType(XmlAccessType.FIELD) + public static class RangerRowFilterDef implements java.io.Serializable { + private static final long serialVersionUID = 1L; + + private List<RangerAccessTypeDef> accessTypes; + private List<RangerResourceDef> resources; + + + public RangerRowFilterDef() { + setAccessTypes(null); + setResources(null); + } + + public RangerRowFilterDef(List<RangerAccessTypeDef> accessTypes, List<RangerResourceDef> resources) { + setAccessTypes(accessTypes); + setResources(resources); + } + + public RangerRowFilterDef(RangerRowFilterDef other) { + setAccessTypes(other.getAccessTypes()); + setResources(other.getResources()); + } + + public List<RangerAccessTypeDef> getAccessTypes() { + return accessTypes; + } + + public void setAccessTypes(List<RangerAccessTypeDef> accessTypes) { + if(this.accessTypes == null) { + this.accessTypes = new ArrayList<RangerAccessTypeDef>(); + } + + if(this.accessTypes == accessTypes) { + return; + } + + this.accessTypes.clear(); + + if(accessTypes != null) { + for(RangerAccessTypeDef accessType : accessTypes) { + this.accessTypes.add(accessType); + } + } + } + + public List<RangerResourceDef> getResources() { + return resources; + } + + public void setResources(List<RangerResourceDef> resources) { + if(this.resources == null) { + this.resources = new ArrayList<RangerResourceDef>(); + } + + if(this.resources == resources) { + return; + } + + this.resources.clear(); + + if(resources != null) { + for(RangerResourceDef resource : resources) { + this.resources.add(resource); + } + } + } + + @Override + public String toString( ) { + StringBuilder sb = new StringBuilder(); + + toString(sb); + + return sb.toString(); + } + + public StringBuilder toString(StringBuilder sb) { + sb.append("RangerRowFilterDef={"); + + sb.append("accessTypes={"); + if(accessTypes != null) { + for(RangerAccessTypeDef accessType : accessTypes) { + if(accessType != null) { + accessType.toString(sb).append(" "); + } + } + } + sb.append("} "); + + sb.append("resources={"); + if(resources != null) { + for(RangerResourceDef resource : resources) { + if(resource != null) { + resource.toString(sb).append(" "); + } + } + } + sb.append("} "); + + sb.append("}"); + + return sb; + } + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + ((accessTypes == null) ? 0 : accessTypes.hashCode()); + result = prime * result + ((resources == null) ? 0 : resources.hashCode()); + return result; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) + return true; + if (obj == null) + return false; + if (getClass() != obj.getClass()) + return false; + RangerRowFilterDef other = (RangerRowFilterDef) obj; + + if (accessTypes == null) { + if (other.accessTypes != null) + return false; + } else if (!accessTypes.equals(other.accessTypes)) + return false; + if (resources == null) { + if (other.resources != null) + return false; + } else if (!resources.equals(other.resources)) + return false; + return true; + } + } } http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/2c7f617b/agents-common/src/main/java/org/apache/ranger/plugin/model/validation/RangerServiceDefHelper.java ---------------------------------------------------------------------- diff --git a/agents-common/src/main/java/org/apache/ranger/plugin/model/validation/RangerServiceDefHelper.java b/agents-common/src/main/java/org/apache/ranger/plugin/model/validation/RangerServiceDefHelper.java index 101d911..273d61f 100644 --- a/agents-common/src/main/java/org/apache/ranger/plugin/model/validation/RangerServiceDefHelper.java +++ b/agents-common/src/main/java/org/apache/ranger/plugin/model/validation/RangerServiceDefHelper.java @@ -250,6 +250,12 @@ public class RangerServiceDefHelper { } else { resourceDefs = null; } + } else if(policyType == RangerPolicy.POLICY_TYPE_ROWFILTER) { + if(serviceDef.getRowFilterDef() != null) { + resourceDefs = serviceDef.getRowFilterDef().getResources(); + } else { + resourceDefs = null; + } } else { // unknown policyType; use all resources resourceDefs = serviceDef.getResources(); } http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/2c7f617b/agents-common/src/main/java/org/apache/ranger/plugin/policyengine/RangerPolicyEngine.java ---------------------------------------------------------------------- diff --git a/agents-common/src/main/java/org/apache/ranger/plugin/policyengine/RangerPolicyEngine.java b/agents-common/src/main/java/org/apache/ranger/plugin/policyengine/RangerPolicyEngine.java index d19e3d0..e5f1132 100644 --- a/agents-common/src/main/java/org/apache/ranger/plugin/policyengine/RangerPolicyEngine.java +++ b/agents-common/src/main/java/org/apache/ranger/plugin/policyengine/RangerPolicyEngine.java @@ -51,6 +51,8 @@ public interface RangerPolicyEngine { RangerDataMaskResult evalDataMaskPolicies(RangerAccessRequest request, RangerAccessResultProcessor resultProcessor); + RangerRowFilterResult evalRowFilterPolicies(RangerAccessRequest request, RangerAccessResultProcessor resultProcessor); + boolean isAccessAllowed(RangerAccessResource resource, String user, Set<String> userGroups, String accessType); boolean isAccessAllowed(Map<String, RangerPolicyResource> resources, String user, Set<String> userGroups, String accessType); http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/2c7f617b/agents-common/src/main/java/org/apache/ranger/plugin/policyengine/RangerPolicyEngineImpl.java ---------------------------------------------------------------------- diff --git a/agents-common/src/main/java/org/apache/ranger/plugin/policyengine/RangerPolicyEngineImpl.java b/agents-common/src/main/java/org/apache/ranger/plugin/policyengine/RangerPolicyEngineImpl.java index 51cab80..e6e9a3a 100644 --- a/agents-common/src/main/java/org/apache/ranger/plugin/policyengine/RangerPolicyEngineImpl.java +++ b/agents-common/src/main/java/org/apache/ranger/plugin/policyengine/RangerPolicyEngineImpl.java @@ -294,7 +294,7 @@ public class RangerPolicyEngineImpl implements RangerPolicyEngine { } } - // no need to audit if filter/mask is not enabled + // no need to audit if mask is not enabled if(! ret.isMaskEnabled()) { ret.setIsAudited(false); } @@ -311,6 +311,41 @@ public class RangerPolicyEngineImpl implements RangerPolicyEngine { } @Override + public RangerRowFilterResult evalRowFilterPolicies(RangerAccessRequest request, RangerAccessResultProcessor resultProcessor) { + if (LOG.isDebugEnabled()) { + LOG.debug("==> RangerPolicyEngineImpl.evalRowFilterPolicies(" + request + ")"); + } + + RangerRowFilterResult ret = new RangerRowFilterResult(getServiceName(), getServiceDef(), request); + + if(request != null) { + List<RangerPolicyEvaluator> evaluators = policyRepository.getRowFilterPolicyEvaluators(); + for (RangerPolicyEvaluator evaluator : evaluators) { + evaluator.evaluate(request, ret); + + if (ret.getIsAccessDetermined() && ret.getIsAuditedDetermined()) { + break; + } + } + } + + // no need to audit if filter is not enabled + if(! ret.isRowFilterEnabled()) { + ret.setIsAudited(false); + } + + if (resultProcessor != null) { + resultProcessor.processResult(ret); + } + + if (LOG.isDebugEnabled()) { + LOG.debug("<== RangerPolicyEngineImpl.evalRowFilterPolicies(" + request + "): " + ret); + } + + return ret; + } + + @Override public boolean isAccessAllowed(RangerAccessResource resource, String user, Set<String> userGroups, String accessType) { if (LOG.isDebugEnabled()) { LOG.debug("==> RangerPolicyEngineImpl.isAccessAllowed(" + resource + ", " + user + ", " + userGroups + ", " + accessType + ")"); http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/2c7f617b/agents-common/src/main/java/org/apache/ranger/plugin/policyengine/RangerPolicyRepository.java ---------------------------------------------------------------------- diff --git a/agents-common/src/main/java/org/apache/ranger/plugin/policyengine/RangerPolicyRepository.java b/agents-common/src/main/java/org/apache/ranger/plugin/policyengine/RangerPolicyRepository.java index b1463bc..be98f3b 100644 --- a/agents-common/src/main/java/org/apache/ranger/plugin/policyengine/RangerPolicyRepository.java +++ b/agents-common/src/main/java/org/apache/ranger/plugin/policyengine/RangerPolicyRepository.java @@ -50,6 +50,7 @@ public class RangerPolicyRepository { private List<RangerContextEnricher> contextEnrichers; private List<RangerPolicyEvaluator> policyEvaluators; private List<RangerPolicyEvaluator> dataMaskPolicyEvaluators; + private List<RangerPolicyEvaluator> rowFilterPolicyEvaluators; private final Map<String, Boolean> accessAuditCache; private final String componentServiceName; @@ -133,6 +134,10 @@ public class RangerPolicyRepository { return dataMaskPolicyEvaluators; } + public List<RangerPolicyEvaluator> getRowFilterPolicyEvaluators() { + return rowFilterPolicyEvaluators; + } + private RangerServiceDef normalizeAccessTypeDefs(RangerServiceDef serviceDef, final String componentType) { if (serviceDef != null && StringUtils.isNotBlank(componentType)) { @@ -317,7 +322,8 @@ public class RangerPolicyRepository { private void init(RangerPolicyEngineOptions options) { List<RangerPolicyEvaluator> policyEvaluators = new ArrayList<RangerPolicyEvaluator>(); - List<RangerPolicyEvaluator> dataMaskPolicyEvaluators = new ArrayList<RangerPolicyEvaluator>(); + List<RangerPolicyEvaluator> dataMaskPolicyEvaluators = new ArrayList<RangerPolicyEvaluator>(); + List<RangerPolicyEvaluator> rowFilterPolicyEvaluators = new ArrayList<RangerPolicyEvaluator>(); for (RangerPolicy policy : policies) { if (skipBuildingPolicyEvaluator(policy, options)) { @@ -331,6 +337,8 @@ public class RangerPolicyRepository { policyEvaluators.add(evaluator); } else if(policy.getPolicyType() == RangerPolicy.POLICY_TYPE_DATAMASK) { dataMaskPolicyEvaluators.add(evaluator); + } else if(policy.getPolicyType() == RangerPolicy.POLICY_TYPE_ROWFILTER) { + rowFilterPolicyEvaluators.add(evaluator); } else { LOG.warn("RangerPolicyEngine: ignoring policy id=" + policy.getId() + " - invalid policyType '" + policy.getPolicyType() + "'"); } @@ -342,6 +350,9 @@ public class RangerPolicyRepository { Collections.sort(dataMaskPolicyEvaluators); this.dataMaskPolicyEvaluators = Collections.unmodifiableList(dataMaskPolicyEvaluators); + Collections.sort(rowFilterPolicyEvaluators); + this.rowFilterPolicyEvaluators = Collections.unmodifiableList(rowFilterPolicyEvaluators); + List<RangerContextEnricher> contextEnrichers = new ArrayList<RangerContextEnricher>(); if (CollectionUtils.isNotEmpty(this.policyEvaluators)) { if (!options.disableContextEnrichers && !CollectionUtils.isEmpty(serviceDef.getContextEnrichers())) { @@ -370,13 +381,20 @@ public class RangerPolicyRepository { LOG.debug("policy evaluation order: #" + (++order) + " - policy id=" + policy.getId() + "; name=" + policy.getName() + "; evalOrder=" + policyEvaluator.getEvalOrder()); } - LOG.debug("datamasking policy evaluation order: " + this.dataMaskPolicyEvaluators.size() + " policies"); - + LOG.debug("dataMask policy evaluation order: " + this.dataMaskPolicyEvaluators.size() + " policies"); order = 0; for(RangerPolicyEvaluator policyEvaluator : this.dataMaskPolicyEvaluators) { RangerPolicy policy = policyEvaluator.getPolicy(); - LOG.debug("datamasking policy evaluation order: #" + (++order) + " - policy id=" + policy.getId() + "; name=" + policy.getName() + "; evalOrder=" + policyEvaluator.getEvalOrder()); + LOG.debug("dataMask policy evaluation order: #" + (++order) + " - policy id=" + policy.getId() + "; name=" + policy.getName() + "; evalOrder=" + policyEvaluator.getEvalOrder()); + } + + LOG.debug("rowFilter policy evaluation order: " + this.dataMaskPolicyEvaluators.size() + " policies"); + order = 0; + for(RangerPolicyEvaluator policyEvaluator : this.rowFilterPolicyEvaluators) { + RangerPolicy policy = policyEvaluator.getPolicy(); + + LOG.debug("rowFilter policy evaluation order: #" + (++order) + " - policy id=" + policy.getId() + "; name=" + policy.getName() + "; evalOrder=" + policyEvaluator.getEvalOrder()); } } } http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/2c7f617b/agents-common/src/main/java/org/apache/ranger/plugin/policyengine/RangerRowFilterResult.java ---------------------------------------------------------------------- diff --git a/agents-common/src/main/java/org/apache/ranger/plugin/policyengine/RangerRowFilterResult.java b/agents-common/src/main/java/org/apache/ranger/plugin/policyengine/RangerRowFilterResult.java new file mode 100644 index 0000000..ad82471 --- /dev/null +++ b/agents-common/src/main/java/org/apache/ranger/plugin/policyengine/RangerRowFilterResult.java @@ -0,0 +1,80 @@ +/* + * 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.plugin.policyengine; + +import org.apache.commons.lang.StringUtils; +import org.apache.ranger.plugin.model.RangerPolicy; +import org.apache.ranger.plugin.model.RangerServiceDef; + + +public class RangerRowFilterResult extends RangerAccessResult { + private String filterExpr = null; + + + public RangerRowFilterResult(final String serviceName, final RangerServiceDef serviceDef, final RangerAccessRequest request) { + this(serviceName, serviceDef, request, null); + } + + public RangerRowFilterResult(final String serviceName, final RangerServiceDef serviceDef, final RangerAccessRequest request, final RangerPolicy.RangerPolicyItemRowFilterInfo rowFilterInfo) { + super(serviceName, serviceDef, request); + + if(rowFilterInfo != null) { + setFilterExpr(rowFilterInfo.getFilterExpr()); + } + } + + /** + * @return the filterExpr + */ + public String getFilterExpr() { + return filterExpr; + } + + /** + * @param filterExpr the filterExpr to set + */ + public void setFilterExpr(String filterExpr) { + this.filterExpr = filterExpr; + } + + public boolean isRowFilterEnabled() { + return StringUtils.isNotEmpty(filterExpr); + } + + @Override + public String toString( ) { + StringBuilder sb = new StringBuilder(); + + toString(sb); + + return sb.toString(); + } + + public StringBuilder toString(StringBuilder sb) { + sb.append("RangerRowFilterResult={"); + + super.toString(sb); + + sb.append("filterExpr={").append(filterExpr).append("} "); + + sb.append("}"); + + return sb; + } +} http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/2c7f617b/agents-common/src/main/java/org/apache/ranger/plugin/policyevaluator/RangerDataMaskPolicyItemEvaluator.java ---------------------------------------------------------------------- diff --git a/agents-common/src/main/java/org/apache/ranger/plugin/policyevaluator/RangerDataMaskPolicyItemEvaluator.java b/agents-common/src/main/java/org/apache/ranger/plugin/policyevaluator/RangerDataMaskPolicyItemEvaluator.java index 62d624c..fbd7977 100644 --- a/agents-common/src/main/java/org/apache/ranger/plugin/policyevaluator/RangerDataMaskPolicyItemEvaluator.java +++ b/agents-common/src/main/java/org/apache/ranger/plugin/policyevaluator/RangerDataMaskPolicyItemEvaluator.java @@ -18,17 +18,11 @@ */ package org.apache.ranger.plugin.policyevaluator; -import org.apache.ranger.plugin.model.RangerPolicy.RangerDataMaskPolicyItem; +import org.apache.ranger.plugin.model.RangerPolicy.RangerPolicyItemDataMaskInfo; public interface RangerDataMaskPolicyItemEvaluator extends RangerPolicyItemEvaluator { void init(); - RangerDataMaskPolicyItem getPolicyItem(); - - String getMaskType(); - - String getMaskCondition(); - - String getMaskedValue(); + RangerPolicyItemDataMaskInfo getDataMaskInfo(); } http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/2c7f617b/agents-common/src/main/java/org/apache/ranger/plugin/policyevaluator/RangerDefaultDataMaskPolicyItemEvaluator.java ---------------------------------------------------------------------- diff --git a/agents-common/src/main/java/org/apache/ranger/plugin/policyevaluator/RangerDefaultDataMaskPolicyItemEvaluator.java b/agents-common/src/main/java/org/apache/ranger/plugin/policyevaluator/RangerDefaultDataMaskPolicyItemEvaluator.java index 4583de9..45db7b0 100644 --- a/agents-common/src/main/java/org/apache/ranger/plugin/policyevaluator/RangerDefaultDataMaskPolicyItemEvaluator.java +++ b/agents-common/src/main/java/org/apache/ranger/plugin/policyevaluator/RangerDefaultDataMaskPolicyItemEvaluator.java @@ -28,34 +28,16 @@ import org.apache.ranger.plugin.policyengine.RangerPolicyEngineOptions; public class RangerDefaultDataMaskPolicyItemEvaluator extends RangerDefaultPolicyItemEvaluator implements RangerDataMaskPolicyItemEvaluator { + final private RangerDataMaskPolicyItem dataMaskPolicyItem; public RangerDefaultDataMaskPolicyItemEvaluator(RangerServiceDef serviceDef, RangerPolicy policy, RangerDataMaskPolicyItem policyItem, int policyItemIndex, RangerPolicyEngineOptions options) { - super(serviceDef, policy, policyItem, RangerPolicyItemEvaluator.POLICY_ITEM_TYPE_DATA_MASKING, policyItemIndex, options); - } - - @Override - public RangerDataMaskPolicyItem getPolicyItem() { - return (RangerDataMaskPolicyItem)policyItem; - } - - @Override - public String getMaskType() { - RangerPolicyItemDataMaskInfo dataMaskInfo = getPolicyItem().getDataMaskInfo(); + super(serviceDef, policy, policyItem, RangerPolicyItemEvaluator.POLICY_ITEM_TYPE_DATAMASK, policyItemIndex, options); - return dataMaskInfo != null ? dataMaskInfo.getDataMaskType() : null; + dataMaskPolicyItem = policyItem; } @Override - public String getMaskCondition() { - RangerPolicyItemDataMaskInfo dataMaskInfo = getPolicyItem().getDataMaskInfo(); - - return dataMaskInfo != null ? dataMaskInfo.getConditionExpr() : null; - } - - @Override - public String getMaskedValue() { - RangerPolicyItemDataMaskInfo dataMaskInfo = getPolicyItem().getDataMaskInfo(); - - return dataMaskInfo != null ? dataMaskInfo.getValueExpr() : null; + public RangerPolicyItemDataMaskInfo getDataMaskInfo() { + return dataMaskPolicyItem == null ? null : dataMaskPolicyItem.getDataMaskInfo(); } } http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/2c7f617b/agents-common/src/main/java/org/apache/ranger/plugin/policyevaluator/RangerDefaultPolicyEvaluator.java ---------------------------------------------------------------------- diff --git a/agents-common/src/main/java/org/apache/ranger/plugin/policyevaluator/RangerDefaultPolicyEvaluator.java b/agents-common/src/main/java/org/apache/ranger/plugin/policyevaluator/RangerDefaultPolicyEvaluator.java index b87891f..2b26218 100644 --- a/agents-common/src/main/java/org/apache/ranger/plugin/policyevaluator/RangerDefaultPolicyEvaluator.java +++ b/agents-common/src/main/java/org/apache/ranger/plugin/policyevaluator/RangerDefaultPolicyEvaluator.java @@ -36,7 +36,10 @@ import org.apache.ranger.plugin.model.RangerPolicy; import org.apache.ranger.plugin.model.RangerPolicy.RangerDataMaskPolicyItem; import org.apache.ranger.plugin.model.RangerPolicy.RangerPolicyItem; import org.apache.ranger.plugin.model.RangerPolicy.RangerPolicyItemAccess; +import org.apache.ranger.plugin.model.RangerPolicy.RangerPolicyItemDataMaskInfo; +import org.apache.ranger.plugin.model.RangerPolicy.RangerPolicyItemRowFilterInfo; import org.apache.ranger.plugin.model.RangerPolicy.RangerPolicyResource; +import org.apache.ranger.plugin.model.RangerPolicy.RangerRowFilterPolicyItem; import org.apache.ranger.plugin.model.RangerServiceDef; import org.apache.ranger.plugin.model.RangerServiceDef.RangerAccessTypeDef; import org.apache.ranger.plugin.policyengine.RangerAccessRequest; @@ -45,6 +48,7 @@ import org.apache.ranger.plugin.policyengine.RangerAccessResult; import org.apache.ranger.plugin.policyengine.RangerDataMaskResult; import org.apache.ranger.plugin.policyengine.RangerPolicyEngineOptions; import org.apache.ranger.plugin.policyengine.RangerResourceAccessInfo; +import org.apache.ranger.plugin.policyengine.RangerRowFilterResult; import org.apache.ranger.plugin.policyresourcematcher.RangerDefaultPolicyResourceMatcher; import org.apache.ranger.plugin.policyresourcematcher.RangerPolicyResourceMatcher; import org.apache.ranger.plugin.util.RangerPerfTracer; @@ -63,7 +67,8 @@ public class RangerDefaultPolicyEvaluator extends RangerAbstractPolicyEvaluator private List<RangerPolicyItemEvaluator> allowExceptionEvaluators = null; private List<RangerPolicyItemEvaluator> denyExceptionEvaluators = null; private int customConditionsCount = 0; - private List<RangerDataMaskPolicyItemEvaluator> dataMaskEvaluators = null; + private List<RangerDataMaskPolicyItemEvaluator> dataMaskEvaluators = null; + private List<RangerRowFilterPolicyItemEvaluator> rowFilterEvaluators = null; private String perfTag; @Override @@ -105,13 +110,15 @@ public class RangerDefaultPolicyEvaluator extends RangerAbstractPolicyEvaluator denyEvaluators = createPolicyItemEvaluators(policy, serviceDef, options, RangerPolicyItemEvaluator.POLICY_ITEM_TYPE_DENY); allowExceptionEvaluators = createPolicyItemEvaluators(policy, serviceDef, options, RangerPolicyItemEvaluator.POLICY_ITEM_TYPE_ALLOW_EXCEPTIONS); denyExceptionEvaluators = createPolicyItemEvaluators(policy, serviceDef, options, RangerPolicyItemEvaluator.POLICY_ITEM_TYPE_DENY_EXCEPTIONS); - dataMaskEvaluators = createPolicyItemEvaluators(policy, serviceDef, options, policy.getDataMaskPolicyItems()); + dataMaskEvaluators = createDataMaskPolicyItemEvaluators(policy, serviceDef, options, policy.getDataMaskPolicyItems()); + rowFilterEvaluators = createRowFilterPolicyItemEvaluators(policy, serviceDef, options, policy.getRowFilterPolicyItems()); } else { allowEvaluators = Collections.<RangerPolicyItemEvaluator>emptyList(); denyEvaluators = Collections.<RangerPolicyItemEvaluator>emptyList(); allowExceptionEvaluators = Collections.<RangerPolicyItemEvaluator>emptyList(); denyExceptionEvaluators = Collections.<RangerPolicyItemEvaluator>emptyList(); dataMaskEvaluators = Collections.<RangerDataMaskPolicyItemEvaluator>emptyList(); + rowFilterEvaluators = Collections.<RangerRowFilterPolicyItemEvaluator>emptyList(); } Collections.sort(allowEvaluators); @@ -119,8 +126,9 @@ public class RangerDefaultPolicyEvaluator extends RangerAbstractPolicyEvaluator Collections.sort(allowExceptionEvaluators); Collections.sort(denyExceptionEvaluators); - /* dataMask policyItems must be evaulated in the order given in the policy; hence no sort + /* dataMask, rowFilter policyItems must be evaulated in the order given in the policy; hence no sort Collections.sort(dataMaskEvaluators); + Collections.sort(rowFilterEvaluators); */ RangerPerfTracer.log(perf); @@ -206,63 +214,135 @@ public class RangerDefaultPolicyEvaluator extends RangerAbstractPolicyEvaluator } } - protected void evaluatePolicyItems(RangerAccessRequest request, RangerAccessResult result, boolean isResourceMatch) { - if(LOG.isDebugEnabled()) { - LOG.debug("==> RangerDefaultPolicyEvaluator.evaluatePolicyItems(" + request + ", " + result + ", " + isResourceMatch + ")"); - } + @Override + public void evaluate(RangerAccessRequest request, RangerDataMaskResult result) { + if(LOG.isDebugEnabled()) { + LOG.debug("==> RangerDefaultPolicyEvaluator.evaluate(" + request + ", " + result + ")"); + } - RangerPolicyItemEvaluator matchedPolicyItem = getMatchingPolicyItem(request, denyEvaluators, denyExceptionEvaluators); + RangerPerfTracer perf = null; - if(matchedPolicyItem == null && !result.getIsAllowed()) { // if not denied, evaluate allowItems only if not already allowed - matchedPolicyItem = getMatchingPolicyItem(request, allowEvaluators, allowExceptionEvaluators); - } + if(RangerPerfTracer.isPerfTraceEnabled(PERF_POLICY_REQUEST_LOG)) { + perf = RangerPerfTracer.getPerfTracer(PERF_POLICY_REQUEST_LOG, "RangerPolicyEvaluator.evaluate(requestHashCode=" + Integer.toHexString(System.identityHashCode(request)) + "," + perfTag + ")"); + } - if(matchedPolicyItem != null) { - RangerPolicy policy = getPolicy(); + if (request != null && result != null && CollectionUtils.isNotEmpty(dataMaskEvaluators)) { + boolean isResourceMatchAttempted = false; + boolean isResourceMatch = false; + boolean isResourceHeadMatch = false; + boolean isResourceHeadMatchAttempted = false; + final boolean attemptResourceHeadMatch = request.isAccessTypeAny() || request.getResourceMatchingScope() == RangerAccessRequest.ResourceMatchingScope.SELF_OR_DESCENDANTS; - if(matchedPolicyItem.getPolicyItemType() == RangerPolicyItemEvaluator.POLICY_ITEM_TYPE_DENY) { - if(isResourceMatch) { - result.setIsAllowed(false); - result.setPolicyId(policy.getId()); - result.setReason(matchedPolicyItem.getComments()); - } - } else { - if(! result.getIsAllowed()) { // if access is not yet allowed by another policy - result.setIsAllowed(true); - result.setPolicyId(policy.getId()); - result.setReason(matchedPolicyItem.getComments()); - } - } - } + if (!result.getIsAuditedDetermined()) { + if (!isResourceMatchAttempted) { + isResourceMatch = isMatch(request.getResource()); + isResourceMatchAttempted = true; + } - if(LOG.isDebugEnabled()) { - LOG.debug("<== RangerDefaultPolicyEvaluator.evaluatePolicyItems(" + request + ", " + result + ", " + isResourceMatch + ")"); - } - } + if (!isResourceMatch) { + if (attemptResourceHeadMatch && !isResourceHeadMatchAttempted) { + isResourceHeadMatch = matchResourceHead(request.getResource()); + isResourceHeadMatchAttempted = true; + } + } - protected RangerPolicyItemEvaluator getDeterminingPolicyItem(String user, Set<String> userGroups, String accessType) { - if(LOG.isDebugEnabled()) { - LOG.debug("==> RangerDefaultPolicyEvaluator.getDeterminingPolicyItem(" + user + ", " + userGroups + ", " + accessType + ")"); - } + if (isResourceMatch || isResourceHeadMatch) { + if (isAuditEnabled()) { + result.setIsAudited(true); + } + } + } - RangerPolicyItemEvaluator ret = null; + if (!result.getIsAccessDetermined()) { + if (!isResourceMatchAttempted) { + isResourceMatch = isMatch(request.getResource()); + isResourceMatchAttempted = true; + } - /* - * 1. if a deny matches without hitting any deny-exception, return that - * 2. if an allow matches without hitting any allow-exception, return that - */ - ret = getMatchingPolicyItem(user, userGroups, accessType, denyEvaluators, denyExceptionEvaluators); + if (!isResourceMatch) { + if (attemptResourceHeadMatch && !isResourceHeadMatchAttempted) { + isResourceHeadMatch = matchResourceHead(request.getResource()); + isResourceHeadMatchAttempted = true; + } + } - if(ret == null) { - ret = getMatchingPolicyItem(user, userGroups, accessType, allowEvaluators, allowExceptionEvaluators); - } + if (isResourceMatch || isResourceHeadMatch) { + evaluatePolicyItems(request, result); + } + } + } - if(LOG.isDebugEnabled()) { - LOG.debug("<== RangerDefaultPolicyEvaluator.getDeterminingPolicyItem(" + user + ", " + userGroups + ", " + accessType + "): " + ret); - } + RangerPerfTracer.log(perf); - return ret; - } + if(LOG.isDebugEnabled()) { + LOG.debug("<== RangerDefaultPolicyEvaluator.evaluate(" + request + ", " + result + ")"); + } + } + + @Override + public void evaluate(RangerAccessRequest request, RangerRowFilterResult result) { + if(LOG.isDebugEnabled()) { + LOG.debug("==> RangerDefaultPolicyEvaluator.evaluate(" + request + ", " + result + ")"); + } + + RangerPerfTracer perf = null; + + if(RangerPerfTracer.isPerfTraceEnabled(PERF_POLICY_REQUEST_LOG)) { + perf = RangerPerfTracer.getPerfTracer(PERF_POLICY_REQUEST_LOG, "RangerPolicyEvaluator.evaluate(requestHashCode=" + Integer.toHexString(System.identityHashCode(request)) + "," + perfTag + ")"); + } + + if (request != null && result != null && CollectionUtils.isNotEmpty(rowFilterEvaluators)) { + boolean isResourceMatchAttempted = false; + boolean isResourceMatch = false; + boolean isResourceHeadMatch = false; + boolean isResourceHeadMatchAttempted = false; + final boolean attemptResourceHeadMatch = request.isAccessTypeAny() || request.getResourceMatchingScope() == RangerAccessRequest.ResourceMatchingScope.SELF_OR_DESCENDANTS; + + if (!result.getIsAuditedDetermined()) { + if (!isResourceMatchAttempted) { + isResourceMatch = isMatch(request.getResource()); + isResourceMatchAttempted = true; + } + + if (!isResourceMatch) { + if (attemptResourceHeadMatch && !isResourceHeadMatchAttempted) { + isResourceHeadMatch = matchResourceHead(request.getResource()); + isResourceHeadMatchAttempted = true; + } + } + + if (isResourceMatch || isResourceHeadMatch) { + if (isAuditEnabled()) { + result.setIsAudited(true); + } + } + } + + if (!result.getIsAccessDetermined()) { + if (!isResourceMatchAttempted) { + isResourceMatch = isMatch(request.getResource()); + isResourceMatchAttempted = true; + } + + if (!isResourceMatch) { + if (attemptResourceHeadMatch && !isResourceHeadMatchAttempted) { + isResourceHeadMatch = matchResourceHead(request.getResource()); + isResourceHeadMatchAttempted = true; + } + } + + if (isResourceMatch || isResourceHeadMatch) { + evaluatePolicyItems(request, result); + } + } + } + + RangerPerfTracer.log(perf); + + if(LOG.isDebugEnabled()) { + LOG.debug("<== RangerDefaultPolicyEvaluator.evaluate(" + request + ", " + result + ")"); + } + } @Override public boolean isMatch(RangerAccessResource resource) { @@ -419,6 +499,112 @@ public class RangerDefaultPolicyEvaluator extends RangerAbstractPolicyEvaluator } + protected void evaluatePolicyItems(RangerAccessRequest request, RangerAccessResult result, boolean isResourceMatch) { + if(LOG.isDebugEnabled()) { + LOG.debug("==> RangerDefaultPolicyEvaluator.evaluatePolicyItems(" + request + ", " + result + ", " + isResourceMatch + ")"); + } + + RangerPolicyItemEvaluator matchedPolicyItem = getMatchingPolicyItem(request, denyEvaluators, denyExceptionEvaluators); + + if(matchedPolicyItem == null && !result.getIsAllowed()) { // if not denied, evaluate allowItems only if not already allowed + matchedPolicyItem = getMatchingPolicyItem(request, allowEvaluators, allowExceptionEvaluators); + } + + if(matchedPolicyItem != null) { + RangerPolicy policy = getPolicy(); + + if(matchedPolicyItem.getPolicyItemType() == RangerPolicyItemEvaluator.POLICY_ITEM_TYPE_DENY) { + if(isResourceMatch) { + result.setIsAllowed(false); + result.setPolicyId(policy.getId()); + result.setReason(matchedPolicyItem.getComments()); + } + } else { + if(! result.getIsAllowed()) { // if access is not yet allowed by another policy + result.setIsAllowed(true); + result.setPolicyId(policy.getId()); + result.setReason(matchedPolicyItem.getComments()); + } + } + } + + if(LOG.isDebugEnabled()) { + LOG.debug("<== RangerDefaultPolicyEvaluator.evaluatePolicyItems(" + request + ", " + result + ", " + isResourceMatch + ")"); + } + } + + protected void evaluatePolicyItems(RangerAccessRequest request, RangerDataMaskResult result) { + if(LOG.isDebugEnabled()) { + LOG.debug("==> RangerDefaultPolicyEvaluator.evaluatePolicyItems(" + request + ", " + result + ")"); + } + + RangerDataMaskPolicyItemEvaluator matchedPolicyItem = getMatchingPolicyItem(request, dataMaskEvaluators); + RangerPolicyItemDataMaskInfo dataMaskInfo = matchedPolicyItem != null ? matchedPolicyItem.getDataMaskInfo() : null; + + if(dataMaskInfo != null) { + RangerPolicy policy = getPolicy(); + + result.setIsAllowed(true); + result.setIsAccessDetermined(true); + + result.setMaskType(dataMaskInfo.getDataMaskType()); + result.setMaskCondition(dataMaskInfo.getConditionExpr()); + result.setMaskedValue(dataMaskInfo.getValueExpr()); + result.setPolicyId(policy.getId()); + } + + if(LOG.isDebugEnabled()) { + LOG.debug("<== RangerDefaultPolicyEvaluator.evaluatePolicyItems(" + request + ", " + result + ", " + ")"); + } + } + + protected void evaluatePolicyItems(RangerAccessRequest request, RangerRowFilterResult result) { + if(LOG.isDebugEnabled()) { + LOG.debug("==> RangerDefaultPolicyEvaluator.evaluatePolicyItems(" + request + ", " + result + ")"); + } + + RangerRowFilterPolicyItemEvaluator matchedPolicyItem = getMatchingPolicyItem(request, rowFilterEvaluators); + RangerPolicyItemRowFilterInfo rowFilterInfo = matchedPolicyItem != null ? matchedPolicyItem.getRowFilterInfo() : null; + + if(rowFilterInfo != null) { + RangerPolicy policy = getPolicy(); + + result.setIsAllowed(true); + result.setIsAccessDetermined(true); + + result.setFilterExpr(rowFilterInfo.getFilterExpr()); + result.setPolicyId(policy.getId()); + } + + if(LOG.isDebugEnabled()) { + LOG.debug("<== RangerDefaultPolicyEvaluator.evaluatePolicyItems(" + request + ", " + result + ", " + ")"); + } + } + + protected RangerPolicyItemEvaluator getDeterminingPolicyItem(String user, Set<String> userGroups, String accessType) { + if(LOG.isDebugEnabled()) { + LOG.debug("==> RangerDefaultPolicyEvaluator.getDeterminingPolicyItem(" + user + ", " + userGroups + ", " + accessType + ")"); + } + + RangerPolicyItemEvaluator ret = null; + + /* + * 1. if a deny matches without hitting any deny-exception, return that + * 2. if an allow matches without hitting any allow-exception, return that + */ + ret = getMatchingPolicyItem(user, userGroups, accessType, denyEvaluators, denyExceptionEvaluators); + + if(ret == null) { + ret = getMatchingPolicyItem(user, userGroups, accessType, allowEvaluators, allowExceptionEvaluators); + } + + if(LOG.isDebugEnabled()) { + LOG.debug("<== RangerDefaultPolicyEvaluator.getDeterminingPolicyItem(" + user + ", " + userGroups + ", " + accessType + "): " + ret); + } + + return ret; + } + private void getResourceAccessInfo(RangerAccessRequest request, List<? extends RangerPolicyItemEvaluator> policyItems, Set<String> users, Set<String> groups) { if(LOG.isDebugEnabled()) { LOG.debug("==> RangerDefaultPolicyEvaluator.getResourceAccessInfo(" + request + ", " + policyItems + ", " + users + ", " + groups + ")"); @@ -668,6 +854,58 @@ public class RangerDefaultPolicyEvaluator extends RangerAbstractPolicyEvaluator return ret; } + private List<RangerDataMaskPolicyItemEvaluator> createDataMaskPolicyItemEvaluators(RangerPolicy policy, RangerServiceDef serviceDef, RangerPolicyEngineOptions options, List<RangerDataMaskPolicyItem> policyItems) { + List<RangerDataMaskPolicyItemEvaluator> ret = null; + + if(CollectionUtils.isNotEmpty(policyItems)) { + ret = new ArrayList<RangerDataMaskPolicyItemEvaluator>(); + + int policyItemCounter = 1; + + for(RangerDataMaskPolicyItem policyItem : policyItems) { + RangerDataMaskPolicyItemEvaluator itemEvaluator = new RangerDefaultDataMaskPolicyItemEvaluator(serviceDef, policy, policyItem, policyItemCounter++, options); + + itemEvaluator.init(); + + ret.add(itemEvaluator); + + if(CollectionUtils.isNotEmpty(itemEvaluator.getConditionEvaluators())) { + customConditionsCount += itemEvaluator.getConditionEvaluators().size(); + } + } + } else { + ret = Collections.<RangerDataMaskPolicyItemEvaluator>emptyList(); + } + + return ret; + } + + private List<RangerRowFilterPolicyItemEvaluator> createRowFilterPolicyItemEvaluators(RangerPolicy policy, RangerServiceDef serviceDef, RangerPolicyEngineOptions options, List<RangerRowFilterPolicyItem> policyItems) { + List<RangerRowFilterPolicyItemEvaluator> ret = null; + + if(CollectionUtils.isNotEmpty(policyItems)) { + ret = new ArrayList<RangerRowFilterPolicyItemEvaluator>(); + + int policyItemCounter = 1; + + for(RangerRowFilterPolicyItem policyItem : policyItems) { + RangerRowFilterPolicyItemEvaluator itemEvaluator = new RangerDefaultRowFilterPolicyItemEvaluator(serviceDef, policy, policyItem, policyItemCounter++, options); + + itemEvaluator.init(); + + ret.add(itemEvaluator); + + if(CollectionUtils.isNotEmpty(itemEvaluator.getConditionEvaluators())) { + customConditionsCount += itemEvaluator.getConditionEvaluators().size(); + } + } + } else { + ret = Collections.<RangerRowFilterPolicyItemEvaluator>emptyList(); + } + + return ret; + } + private boolean isPolicyItemTypeEnabled(RangerServiceDef serviceDef, int policyItemType) { boolean ret = true; @@ -680,15 +918,21 @@ public class RangerDefaultPolicyEvaluator extends RangerAbstractPolicyEvaluator return ret; } - private RangerPolicyItemEvaluator getMatchingPolicyItem(RangerAccessRequest request, List<? extends RangerPolicyItemEvaluator> evaluators, List<? extends RangerPolicyItemEvaluator> exceptionEvaluators) { + protected <T extends RangerPolicyItemEvaluator> T getMatchingPolicyItem(RangerAccessRequest request, List<T> evaluators) { + T ret = getMatchingPolicyItem(request, evaluators, null); + + return ret; + } + + private <T extends RangerPolicyItemEvaluator> T getMatchingPolicyItem(RangerAccessRequest request, List<T> evaluators, List<T> exceptionEvaluators) { if(LOG.isDebugEnabled()) { LOG.debug("==> RangerDefaultPolicyEvaluator.getMatchingPolicyItem(" + request + ")"); } - RangerPolicyItemEvaluator ret = null; + T ret = null; if(CollectionUtils.isNotEmpty(evaluators)) { - for (RangerPolicyItemEvaluator evaluator : evaluators) { + for (T evaluator : evaluators) { if(evaluator.isMatch(request)) { ret = evaluator; @@ -698,7 +942,7 @@ public class RangerDefaultPolicyEvaluator extends RangerAbstractPolicyEvaluator } if(ret != null && CollectionUtils.isNotEmpty(exceptionEvaluators)) { - for (RangerPolicyItemEvaluator exceptionEvaluator : exceptionEvaluators) { + for (T exceptionEvaluator : exceptionEvaluators) { if(exceptionEvaluator.isMatch(request)) { if(LOG.isDebugEnabled()) { LOG.debug("RangerDefaultPolicyEvaluator.getMatchingPolicyItem(" + request + "): found exception policyItem(" + exceptionEvaluator.getPolicyItem() + "); ignoring the matchedPolicyItem(" + ret.getPolicyItem() + ")"); @@ -718,15 +962,15 @@ public class RangerDefaultPolicyEvaluator extends RangerAbstractPolicyEvaluator return ret; } - private RangerPolicyItemEvaluator getMatchingPolicyItem(String user, Set<String> userGroups, String accessType, List<RangerPolicyItemEvaluator> evaluators, List<RangerPolicyItemEvaluator> exceptionEvaluators) { + private <T extends RangerPolicyItemEvaluator> T getMatchingPolicyItem(String user, Set<String> userGroups, String accessType, List<T> evaluators, List<T> exceptionEvaluators) { if(LOG.isDebugEnabled()) { LOG.debug("==> RangerDefaultPolicyEvaluator.getMatchingPolicyItem(" + user + ", " + userGroups + ", " + accessType + ")"); } - RangerPolicyItemEvaluator ret = null; + T ret = null; if(CollectionUtils.isNotEmpty(evaluators)) { - for (RangerPolicyItemEvaluator evaluator : evaluators) { + for (T evaluator : evaluators) { if(evaluator.matchUserGroup(user, userGroups) && evaluator.matchAccessType(accessType)) { ret = evaluator; @@ -736,7 +980,7 @@ public class RangerDefaultPolicyEvaluator extends RangerAbstractPolicyEvaluator } if(ret != null && CollectionUtils.isNotEmpty(exceptionEvaluators)) { - for (RangerPolicyItemEvaluator exceptionEvaluator : exceptionEvaluators) { + for (T exceptionEvaluator : exceptionEvaluators) { if(exceptionEvaluator.matchUserGroup(user, userGroups) && exceptionEvaluator.matchAccessType(accessType)) { if(LOG.isDebugEnabled()) { LOG.debug("RangerDefaultPolicyEvaluator.getMatchingPolicyItem(" + user + ", " + userGroups + ", " + accessType + "): found exception policyItem(" + exceptionEvaluator.getPolicyItem() + "); ignoring the matchedPolicyItem(" + ret.getPolicyItem() + ")"); @@ -771,114 +1015,4 @@ public class RangerDefaultPolicyEvaluator extends RangerAbstractPolicyEvaluator return ret; } - - @Override - public void evaluate(RangerAccessRequest request, RangerDataMaskResult result) { - if(LOG.isDebugEnabled()) { - LOG.debug("==> RangerDefaultPolicyEvaluator.evaluate(" + request + ", " + result + ")"); - } - - RangerPerfTracer perf = null; - - if(RangerPerfTracer.isPerfTraceEnabled(PERF_POLICY_REQUEST_LOG)) { - perf = RangerPerfTracer.getPerfTracer(PERF_POLICY_REQUEST_LOG, "RangerPolicyEvaluator.evaluate(requestHashCode=" + Integer.toHexString(System.identityHashCode(request)) + "," + perfTag + ")"); - } - - if (request != null && result != null && CollectionUtils.isNotEmpty(dataMaskEvaluators)) { - boolean isResourceMatchAttempted = false; - boolean isResourceMatch = false; - - if (!result.getIsAuditedDetermined()) { - if (!isResourceMatchAttempted) { - isResourceMatch = isMatch(request.getResource()); - isResourceMatchAttempted = true; - } - - if (isResourceMatch) { - if (isAuditEnabled()) { - result.setIsAudited(true); - } - } - } - - if (!result.getIsAccessDetermined()) { - if (!isResourceMatchAttempted) { - isResourceMatch = isMatch(request.getResource()); - isResourceMatchAttempted = true; - } - - if (isResourceMatch) { - evaluatePolicyItems(request, result); - } - } - } - - RangerPerfTracer.log(perf); - - if(LOG.isDebugEnabled()) { - LOG.debug("<== RangerDefaultPolicyEvaluator.evaluate(" + request + ", " + result + ")"); - } - } - - protected void evaluatePolicyItems(RangerAccessRequest request, RangerDataMaskResult result) { - if(LOG.isDebugEnabled()) { - LOG.debug("==> RangerDefaultPolicyEvaluator.evaluatePolicyItems(" + request + ", " + result + ")"); - } - - RangerDataMaskPolicyItemEvaluator matchedPolicyItem = getMatchingPolicyItem(request, dataMaskEvaluators); - - if(matchedPolicyItem != null) { - RangerPolicy policy = getPolicy(); - - result.setIsAllowed(true); - result.setIsAccessDetermined(true); - - result.setMaskType(matchedPolicyItem.getMaskType()); - result.setMaskCondition(matchedPolicyItem.getMaskCondition()); - result.setMaskedValue(matchedPolicyItem.getMaskedValue()); - result.setPolicyId(policy.getId()); - } - - if(LOG.isDebugEnabled()) { - LOG.debug("<== RangerDefaultPolicyEvaluator.evaluatePolicyItems(" + request + ", " + result + ", " + ")"); - } - } - - protected RangerDataMaskPolicyItemEvaluator getMatchingPolicyItem(RangerAccessRequest request, List<RangerDataMaskPolicyItemEvaluator> evaluators) { - RangerDataMaskPolicyItemEvaluator ret = null; - - RangerPolicyItemEvaluator policyItem = getMatchingPolicyItem(request, dataMaskEvaluators, null); - - if(policyItem != null) { - ret = (RangerDataMaskPolicyItemEvaluator)policyItem; - } - - return ret; - } - - private List<RangerDataMaskPolicyItemEvaluator> createPolicyItemEvaluators(RangerPolicy policy, RangerServiceDef serviceDef, RangerPolicyEngineOptions options, List<RangerDataMaskPolicyItem> policyItems) { - List<RangerDataMaskPolicyItemEvaluator> ret = null; - - if(CollectionUtils.isNotEmpty(policyItems)) { - ret = new ArrayList<RangerDataMaskPolicyItemEvaluator>(); - - int policyItemCounter = 1; - - for(RangerDataMaskPolicyItem policyItem : policyItems) { - RangerDataMaskPolicyItemEvaluator itemEvaluator = new RangerDefaultDataMaskPolicyItemEvaluator(serviceDef, policy, policyItem, policyItemCounter++, options); - - itemEvaluator.init(); - - ret.add(itemEvaluator); - - if(CollectionUtils.isNotEmpty(itemEvaluator.getConditionEvaluators())) { - customConditionsCount += itemEvaluator.getConditionEvaluators().size(); - } - } - } else { - ret = Collections.<RangerDataMaskPolicyItemEvaluator>emptyList(); - } - - return ret; - } } http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/2c7f617b/agents-common/src/main/java/org/apache/ranger/plugin/policyevaluator/RangerDefaultRowFilterPolicyItemEvaluator.java ---------------------------------------------------------------------- diff --git a/agents-common/src/main/java/org/apache/ranger/plugin/policyevaluator/RangerDefaultRowFilterPolicyItemEvaluator.java b/agents-common/src/main/java/org/apache/ranger/plugin/policyevaluator/RangerDefaultRowFilterPolicyItemEvaluator.java new file mode 100644 index 0000000..365661b --- /dev/null +++ b/agents-common/src/main/java/org/apache/ranger/plugin/policyevaluator/RangerDefaultRowFilterPolicyItemEvaluator.java @@ -0,0 +1,42 @@ +/* + * 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.plugin.policyevaluator; + + +import org.apache.ranger.plugin.model.RangerPolicy; +import org.apache.ranger.plugin.model.RangerPolicy.RangerPolicyItemRowFilterInfo; +import org.apache.ranger.plugin.model.RangerPolicy.RangerRowFilterPolicyItem; +import org.apache.ranger.plugin.model.RangerServiceDef; +import org.apache.ranger.plugin.policyengine.RangerPolicyEngineOptions; + + +public class RangerDefaultRowFilterPolicyItemEvaluator extends RangerDefaultPolicyItemEvaluator implements RangerRowFilterPolicyItemEvaluator { + final private RangerRowFilterPolicyItem rowFilterPolicyItem; + + public RangerDefaultRowFilterPolicyItemEvaluator(RangerServiceDef serviceDef, RangerPolicy policy, RangerRowFilterPolicyItem policyItem, int policyItemIndex, RangerPolicyEngineOptions options) { + super(serviceDef, policy, policyItem, RangerPolicyItemEvaluator.POLICY_ITEM_TYPE_DATAMASK, policyItemIndex, options); + + rowFilterPolicyItem = policyItem; + } + + @Override + public RangerPolicyItemRowFilterInfo getRowFilterInfo() { + return rowFilterPolicyItem == null ? null : rowFilterPolicyItem.getRowFilterInfo(); + } +} http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/2c7f617b/agents-common/src/main/java/org/apache/ranger/plugin/policyevaluator/RangerPolicyEvaluator.java ---------------------------------------------------------------------- diff --git a/agents-common/src/main/java/org/apache/ranger/plugin/policyevaluator/RangerPolicyEvaluator.java b/agents-common/src/main/java/org/apache/ranger/plugin/policyevaluator/RangerPolicyEvaluator.java index 1010727..be97830 100644 --- a/agents-common/src/main/java/org/apache/ranger/plugin/policyevaluator/RangerPolicyEvaluator.java +++ b/agents-common/src/main/java/org/apache/ranger/plugin/policyevaluator/RangerPolicyEvaluator.java @@ -32,6 +32,7 @@ import org.apache.ranger.plugin.policyengine.RangerAccessResource; import org.apache.ranger.plugin.policyengine.RangerDataMaskResult; import org.apache.ranger.plugin.policyengine.RangerPolicyEngineOptions; import org.apache.ranger.plugin.policyengine.RangerResourceAccessInfo; +import org.apache.ranger.plugin.policyengine.RangerRowFilterResult; public interface RangerPolicyEvaluator extends Comparable<RangerPolicyEvaluator> { @@ -59,6 +60,8 @@ public interface RangerPolicyEvaluator extends Comparable<RangerPolicyEvaluator> void evaluate(RangerAccessRequest request, RangerDataMaskResult result); + void evaluate(RangerAccessRequest request, RangerRowFilterResult result); + boolean isMatch(RangerAccessResource resource); boolean isCompleteMatch(RangerAccessResource resource); http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/2c7f617b/agents-common/src/main/java/org/apache/ranger/plugin/policyevaluator/RangerPolicyItemEvaluator.java ---------------------------------------------------------------------- diff --git a/agents-common/src/main/java/org/apache/ranger/plugin/policyevaluator/RangerPolicyItemEvaluator.java b/agents-common/src/main/java/org/apache/ranger/plugin/policyevaluator/RangerPolicyItemEvaluator.java index 3c4b926..80e46f5 100644 --- a/agents-common/src/main/java/org/apache/ranger/plugin/policyevaluator/RangerPolicyItemEvaluator.java +++ b/agents-common/src/main/java/org/apache/ranger/plugin/policyevaluator/RangerPolicyItemEvaluator.java @@ -30,7 +30,8 @@ public interface RangerPolicyItemEvaluator extends Comparable<RangerPolicyItemEv int POLICY_ITEM_TYPE_DENY = 1; int POLICY_ITEM_TYPE_ALLOW_EXCEPTIONS = 2; int POLICY_ITEM_TYPE_DENY_EXCEPTIONS = 3; - int POLICY_ITEM_TYPE_DATA_MASKING = 4; + int POLICY_ITEM_TYPE_DATAMASK = 4; + int POLICY_ITEM_TYPE_ROWFILTER = 5; void init(); http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/2c7f617b/agents-common/src/main/java/org/apache/ranger/plugin/policyevaluator/RangerRowFilterPolicyItemEvaluator.java ---------------------------------------------------------------------- diff --git a/agents-common/src/main/java/org/apache/ranger/plugin/policyevaluator/RangerRowFilterPolicyItemEvaluator.java b/agents-common/src/main/java/org/apache/ranger/plugin/policyevaluator/RangerRowFilterPolicyItemEvaluator.java new file mode 100644 index 0000000..c108e4f --- /dev/null +++ b/agents-common/src/main/java/org/apache/ranger/plugin/policyevaluator/RangerRowFilterPolicyItemEvaluator.java @@ -0,0 +1,28 @@ +/* + * 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.plugin.policyevaluator; + +import org.apache.ranger.plugin.model.RangerPolicy.RangerPolicyItemRowFilterInfo; + + +public interface RangerRowFilterPolicyItemEvaluator extends RangerPolicyItemEvaluator { + void init(); + + RangerPolicyItemRowFilterInfo getRowFilterInfo(); +} http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/2c7f617b/agents-common/src/main/java/org/apache/ranger/plugin/service/RangerBasePlugin.java ---------------------------------------------------------------------- diff --git a/agents-common/src/main/java/org/apache/ranger/plugin/service/RangerBasePlugin.java b/agents-common/src/main/java/org/apache/ranger/plugin/service/RangerBasePlugin.java index aef7bcb..bf5e95b 100644 --- a/agents-common/src/main/java/org/apache/ranger/plugin/service/RangerBasePlugin.java +++ b/agents-common/src/main/java/org/apache/ranger/plugin/service/RangerBasePlugin.java @@ -194,6 +194,18 @@ public class RangerBasePlugin { return null; } + public RangerRowFilterResult evalRowFilterPolicies(RangerAccessRequest request, RangerAccessResultProcessor resultProcessor) { + RangerPolicyEngine policyEngine = this.policyEngine; + + if(policyEngine != null) { + policyEngine.preProcess(request); + + return policyEngine.evalRowFilterPolicies(request, resultProcessor); + } + + return null; + } + public RangerResourceAccessInfo getResourceAccessInfo(RangerAccessRequest request) { RangerPolicyEngine policyEngine = this.policyEngine; http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/2c7f617b/agents-common/src/main/java/org/apache/ranger/plugin/store/AbstractPredicateUtil.java ---------------------------------------------------------------------- diff --git a/agents-common/src/main/java/org/apache/ranger/plugin/store/AbstractPredicateUtil.java b/agents-common/src/main/java/org/apache/ranger/plugin/store/AbstractPredicateUtil.java index b154115..478ea0c 100644 --- a/agents-common/src/main/java/org/apache/ranger/plugin/store/AbstractPredicateUtil.java +++ b/agents-common/src/main/java/org/apache/ranger/plugin/store/AbstractPredicateUtil.java @@ -451,7 +451,9 @@ public class AbstractPredicateUtil { List<?>[] policyItemsList = new List<?>[] { policy.getPolicyItems(), policy.getDenyPolicyItems(), policy.getAllowExceptions(), - policy.getDenyExceptions() + policy.getDenyExceptions(), + policy.getDataMaskPolicyItems(), + policy.getRowFilterPolicyItems() }; for(List<?> policyItemsObj : policyItemsList) { @@ -501,7 +503,9 @@ public class AbstractPredicateUtil { List<?>[] policyItemsList = new List<?>[] { policy.getPolicyItems(), policy.getDenyPolicyItems(), policy.getAllowExceptions(), - policy.getDenyExceptions() + policy.getDenyExceptions(), + policy.getDataMaskPolicyItems(), + policy.getRowFilterPolicyItems() }; for(List<?> policyItemsObj : policyItemsList) { http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/2c7f617b/agents-common/src/main/java/org/apache/ranger/plugin/util/ServiceDefUtil.java ---------------------------------------------------------------------- diff --git a/agents-common/src/main/java/org/apache/ranger/plugin/util/ServiceDefUtil.java b/agents-common/src/main/java/org/apache/ranger/plugin/util/ServiceDefUtil.java index 34f4cc6..eaf60b7 100644 --- a/agents-common/src/main/java/org/apache/ranger/plugin/util/ServiceDefUtil.java +++ b/agents-common/src/main/java/org/apache/ranger/plugin/util/ServiceDefUtil.java @@ -68,6 +68,7 @@ public class ServiceDefUtil { public static RangerServiceDef normalize(RangerServiceDef serviceDef) { normalizeDataMaskDef(serviceDef); + normalizeRowFilterDef(serviceDef); return serviceDef; } @@ -119,6 +120,53 @@ public class ServiceDefUtil { } } + private static void normalizeRowFilterDef(RangerServiceDef serviceDef) { + if(serviceDef != null && serviceDef.getRowFilterDef() != null) { + List<RangerResourceDef> rowFilterResources = serviceDef.getRowFilterDef().getResources(); + List<RangerAccessTypeDef> rowFilterAccessTypes = serviceDef.getRowFilterDef().getAccessTypes(); + + if(CollectionUtils.isNotEmpty(rowFilterResources)) { + List<RangerResourceDef> resources = serviceDef.getResources(); + List<RangerResourceDef> processedDefs = new ArrayList<RangerResourceDef>(rowFilterResources.size()); + + for(RangerResourceDef rowFilterResource : rowFilterResources) { + RangerResourceDef processedDef = rowFilterResource; + + for(RangerResourceDef resourceDef : resources) { + if(StringUtils.equals(resourceDef.getName(), rowFilterResource.getName())) { + processedDef = ServiceDefUtil.mergeResourceDef(resourceDef, rowFilterResource); + break; + } + } + + processedDefs.add(processedDef); + } + + serviceDef.getRowFilterDef().setResources(processedDefs); + } + + if(CollectionUtils.isNotEmpty(rowFilterAccessTypes)) { + List<RangerAccessTypeDef> accessTypes = serviceDef.getAccessTypes(); + List<RangerAccessTypeDef> processedDefs = new ArrayList<RangerAccessTypeDef>(accessTypes.size()); + + for(RangerAccessTypeDef rowFilterAccessType : rowFilterAccessTypes) { + RangerAccessTypeDef processedDef = rowFilterAccessType; + + for(RangerAccessTypeDef accessType : accessTypes) { + if(StringUtils.equals(accessType.getName(), rowFilterAccessType.getName())) { + processedDef = ServiceDefUtil.mergeAccessTypeDef(accessType, rowFilterAccessType); + break; + } + } + + processedDefs.add(processedDef); + } + + serviceDef.getRowFilterDef().setAccessTypes(processedDefs); + } + } + } + private static RangerResourceDef mergeResourceDef(RangerResourceDef base, RangerResourceDef delta) { RangerResourceDef ret = new RangerResourceDef(base); http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/2c7f617b/agents-common/src/main/resources/service-defs/ranger-servicedef-hive.json ---------------------------------------------------------------------- diff --git a/agents-common/src/main/resources/service-defs/ranger-servicedef-hive.json b/agents-common/src/main/resources/service-defs/ranger-servicedef-hive.json index f3c75d1..8cdf273 100644 --- a/agents-common/src/main/resources/service-defs/ranger-servicedef-hive.json +++ b/agents-common/src/main/resources/service-defs/ranger-servicedef-hive.json @@ -223,7 +223,6 @@ "description": "List of Hive resources" } ], - "dataMaskDef": { "accessTypes": [ { @@ -347,7 +346,7 @@ }, { "itemId": 10, - "name": "MASK_DATE_YEAR", + "name": "MASK_DATE_SHOW_YEAR", "label": "Date: show only year", "description": "Date: show only year", "transformer": "org.apache.ranger.authorization.hive.udf.MaskTransformer", @@ -368,5 +367,32 @@ "description": "No masking" } ] + }, + "rowFilterDef": { + "accessTypes": [ + { + "name": "select" + } + ], + "resources": [ + { + "name": "database", + "matcherOptions": { + "wildCard": "false" + }, + "lookupSupported": true, + "mandatory": true, + "uiHint": "{ \"singleValue\":true }" + }, + { + "name": "table", + "matcherOptions": { + "wildCard": "false" + }, + "lookupSupported": true, + "mandatory": true, + "uiHint": "{ \"singleValue\":true }" + } + ] } } http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/2c7f617b/agents-common/src/test/java/org/apache/ranger/plugin/policyengine/TestPolicyEngine.java ---------------------------------------------------------------------- diff --git a/agents-common/src/test/java/org/apache/ranger/plugin/policyengine/TestPolicyEngine.java b/agents-common/src/test/java/org/apache/ranger/plugin/policyengine/TestPolicyEngine.java index 05cbcde..8ee6bea 100644 --- a/agents-common/src/test/java/org/apache/ranger/plugin/policyengine/TestPolicyEngine.java +++ b/agents-common/src/test/java/org/apache/ranger/plugin/policyengine/TestPolicyEngine.java @@ -203,7 +203,7 @@ public class TestPolicyEngine { @Test public void testPolicyEngine_hiveMasking() { - String[] resourceFiles = { "/policyengine/test_policyengine_hive_masking.json" }; + String[] resourceFiles = {"/policyengine/test_policyengine_hive_mask_filter.json"}; runTestsFromResourceFiles(resourceFiles); } @@ -339,6 +339,15 @@ public class TestPolicyEngine { assertEquals("policyId mismatched! - " + test.name, expected.getPolicyId(), result.getPolicyId()); } + if(test.rowFilterResult != null) { + RangerRowFilterResult expected = test.rowFilterResult; + RangerRowFilterResult result = policyEngine.evalRowFilterPolicies(request, auditHandler); + + assertNotNull("result was null! - " + test.name, result); + assertEquals("filterExpr mismatched! - " + test.name, expected.getFilterExpr(), result.getFilterExpr()); + assertEquals("policyId mismatched! - " + test.name, expected.getPolicyId(), result.getPolicyId()); + } + if(test.resourceAccessInfo != null) { RangerResourceAccessInfo expected = new RangerResourceAccessInfo(test.resourceAccessInfo); RangerResourceAccessInfo result = policyEngine.getResourceAccessInfo(test.request); @@ -363,7 +372,8 @@ public class TestPolicyEngine { public String name; public RangerAccessRequest request; public RangerAccessResult result; - public RangerDataMaskResult dataMaskResult; + public RangerDataMaskResult dataMaskResult; + public RangerRowFilterResult rowFilterResult; public RangerResourceAccessInfo resourceAccessInfo; }
