This is an automated email from the ASF dual-hosted git repository.
madhan pushed a commit to branch RANGER-3923
in repository https://gitbox.apache.org/repos/asf/ranger.git
The following commit(s) were added to refs/heads/RANGER-3923 by this push:
new 87bec2676 RANGER-4269: gds policy engine implementation of
getResourceACLs() API - #3
87bec2676 is described below
commit 87bec2676f06d0da9d37f710fd23c0b6b7f031f2
Author: Madhan Neethiraj <[email protected]>
AuthorDate: Wed Nov 8 19:22:24 2023 -0800
RANGER-4269: gds policy engine implementation of getResourceACLs() API - #3
---
.../policyengine/RangerPolicyEngineImpl.java | 2 +-
.../plugin/policyengine/RangerResourceACLs.java | 43 +++++++
.../policyengine/gds/GdsDataShareEvaluator.java | 37 ++++++
.../policyengine/gds/GdsDatasetEvaluator.java | 16 +++
.../plugin/policyengine/gds/GdsDipEvaluator.java | 27 ++++
.../plugin/policyengine/gds/GdsDshidEvaluator.java | 28 ++++-
.../plugin/policyengine/gds/GdsPolicyEngine.java | 19 +++
.../policyengine/gds/GdsProjectEvaluator.java | 14 +++
.../gds/GdsSharedResourceEvaluator.java | 21 ++++
.../RangerAbstractPolicyEvaluator.java | 46 +++++--
.../policyevaluator/RangerPolicyEvaluator.java | 2 +-
.../ranger/plugin/service/RangerBasePlugin.java | 42 +++++++
.../policyengine/gds/TestGdsPolicyEngine.java | 13 +-
.../gds/test_gds_policy_engine_hive.json | 139 +++++++++++++++++++--
14 files changed, 427 insertions(+), 22 deletions(-)
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 e268fff38..2d576c580 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
@@ -317,7 +317,7 @@ public class RangerPolicyEngineImpl implements
RangerPolicyEngine {
boolean isTemporalTagPolicy =
policyIdForTemporalTags.contains(evaluator.getPolicyId());
MatchType tagMatchType =
tagMatchTypeMap.get(evaluator.getPolicyId());
- evaluator.getResourceACLs(request, ret,
isTemporalTagPolicy, tagMatchType, policyEngine);
+ evaluator.getResourceACLs(request, ret,
isTemporalTagPolicy, null, tagMatchType, policyEngine);
}
ret.finalizeAcls();
diff --git
a/agents-common/src/main/java/org/apache/ranger/plugin/policyengine/RangerResourceACLs.java
b/agents-common/src/main/java/org/apache/ranger/plugin/policyengine/RangerResourceACLs.java
index f8554d574..694bebdcf 100644
---
a/agents-common/src/main/java/org/apache/ranger/plugin/policyengine/RangerResourceACLs.java
+++
b/agents-common/src/main/java/org/apache/ranger/plugin/policyengine/RangerResourceACLs.java
@@ -31,6 +31,7 @@ import org.codehaus.jackson.map.annotate.JsonSerialize;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.HashMap;
+import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Objects;
@@ -46,6 +47,8 @@ public class RangerResourceACLs {
final private Map<String, Map<String, AccessResult>> roleACLs = new
HashMap<>();
final private List<RowFilterResult> rowFilters = new
ArrayList<>();
final private List<DataMaskResult> dataMasks = new
ArrayList<>();
+ final private Set<String> datasets = new
HashSet<>();
+ final private Set<String> projects = new
HashSet<>();
public RangerResourceACLs() {
}
@@ -64,6 +67,10 @@ public class RangerResourceACLs {
public List<DataMaskResult> getDataMasks() { return dataMasks; }
+ public Set<String> getDatasets() { return datasets; }
+
+ public Set<String> getProjects() { return projects; }
+
public void finalizeAcls() {
Map<String, AccessResult> publicGroupAccessInfo =
groupACLs.get(RangerPolicyEngine.GROUP_PUBLIC);
if (publicGroupAccessInfo != null) {
@@ -162,6 +169,30 @@ public class RangerResourceACLs {
}
}
+ @Override
+ public int hashCode() {
+ return Objects.hash(userACLs, groupACLs, roleACLs, rowFilters,
dataMasks);
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj) {
+ return true;
+ } else if (obj == null || !getClass().equals(obj.getClass())) {
+ return false;
+ } else {
+ RangerResourceACLs other = (RangerResourceACLs) obj;
+
+ return Objects.equals(userACLs, other.userACLs) &&
+ Objects.equals(groupACLs, other.groupACLs) &&
+ Objects.equals(roleACLs, other.roleACLs) &&
+ Objects.equals(rowFilters, other.rowFilters) &&
+ Objects.equals(dataMasks, other.dataMasks) &&
+ Objects.equals(datasets, other.datasets) &&
+ Objects.equals(projects, other.projects);
+ }
+ }
+
@Override
public String toString() {
StringBuilder sb = new StringBuilder();
@@ -220,6 +251,18 @@ public class RangerResourceACLs {
}
sb.append("]");
+ sb.append(", datasets=[");
+ for (String dataset : datasets) {
+ sb.append(dataset).append(" ");
+ }
+ sb.append("]");
+
+ sb.append(", projects=[");
+ for (String project : projects) {
+ sb.append(project).append(" ");
+ }
+ sb.append("]");
+
return sb.toString();
}
diff --git
a/agents-common/src/main/java/org/apache/ranger/plugin/policyengine/gds/GdsDataShareEvaluator.java
b/agents-common/src/main/java/org/apache/ranger/plugin/policyengine/gds/GdsDataShareEvaluator.java
index 83ab59630..4936a86ed 100644
---
a/agents-common/src/main/java/org/apache/ranger/plugin/policyengine/gds/GdsDataShareEvaluator.java
+++
b/agents-common/src/main/java/org/apache/ranger/plugin/policyengine/gds/GdsDataShareEvaluator.java
@@ -24,6 +24,7 @@ import
org.apache.ranger.plugin.conditionevaluator.RangerConditionEvaluator;
import org.apache.ranger.plugin.model.RangerServiceDef.RangerResourceDef;
import org.apache.ranger.plugin.model.validation.RangerServiceDefHelper;
import org.apache.ranger.plugin.policyengine.RangerAccessRequest;
+import org.apache.ranger.plugin.policyengine.RangerResourceACLs;
import org.apache.ranger.plugin.policyengine.RangerResourceTrie;
import org.apache.ranger.plugin.policyevaluator.RangerCustomConditionEvaluator;
import org.apache.ranger.plugin.util.RangerResourceEvaluatorsRetriever;
@@ -140,6 +141,42 @@ public class GdsDataShareEvaluator {
LOG.debug("<== GdsDataShareEvaluator.evaluate({}, {})", request,
result);
}
+ public void getResourceACLs(RangerAccessRequest request,
RangerResourceACLs acls, Map<Long, GdsDatasetEvaluator> datasets, Map<Long,
GdsProjectEvaluator> projects) {
+ LOG.debug("==> GdsDataShareEvaluator.getResourceACLs({}, {})",
request, acls);
+
+ List<GdsSharedResourceEvaluator> evaluators =
getResourceEvaluators(request);
+
+ if (!evaluators.isEmpty()) {
+ boolean isConditional = conditionEvaluator != null;
+
+ for (GdsSharedResourceEvaluator evaluator : evaluators) {
+ evaluator.getResourceACLs(request, acls, isConditional,
dsidEvaluators, datasets, projects);
+ }
+ }
+
+ LOG.debug("<== GdsDataShareEvaluator.getResourceACLs({}, {})",
request, acls);
+ }
+
+ private List<GdsSharedResourceEvaluator>
getResourceEvaluators(RangerAccessRequest request) {
+ final List<GdsSharedResourceEvaluator> ret;
+
+ Collection<GdsSharedResourceEvaluator> evaluators =
RangerResourceEvaluatorsRetriever.getEvaluators(resourceTries,
request.getResource().getAsMap(), request.getResourceElementMatchingScopes());
+
+ if (evaluators == null) {
+ ret = Collections.emptyList();
+ } else if (evaluators.size() > 1) {
+ ret = new ArrayList<>(evaluators);
+
+ ret.sort(GdsSharedResourceEvaluator.EVAL_ORDER_COMPARATOR);
+ } else {
+ ret = Collections.singletonList(evaluators.iterator().next());
+ }
+
+ LOG.debug("GdsDataShareEvaluator.getResourceEvaluators({}): found {}
evaluators", request, ret.size());
+
+ return ret;
+ }
+
public static class GdsDataShareEvalOrderComparator implements
Comparator<GdsDataShareEvaluator> {
@Override
public int compare(GdsDataShareEvaluator me, GdsDataShareEvaluator
other) {
diff --git
a/agents-common/src/main/java/org/apache/ranger/plugin/policyengine/gds/GdsDatasetEvaluator.java
b/agents-common/src/main/java/org/apache/ranger/plugin/policyengine/gds/GdsDatasetEvaluator.java
index 61047134b..aa9fbea7c 100644
---
a/agents-common/src/main/java/org/apache/ranger/plugin/policyengine/gds/GdsDatasetEvaluator.java
+++
b/agents-common/src/main/java/org/apache/ranger/plugin/policyengine/gds/GdsDatasetEvaluator.java
@@ -25,6 +25,7 @@ import org.apache.ranger.plugin.model.RangerServiceDef;
import org.apache.ranger.plugin.policyengine.*;
import org.apache.ranger.plugin.policyevaluator.RangerOptimizedPolicyEvaluator;
import org.apache.ranger.plugin.policyevaluator.RangerPolicyEvaluator;
+import
org.apache.ranger.plugin.policyresourcematcher.RangerPolicyResourceMatcher;
import org.apache.ranger.plugin.util.ServiceGdsInfo.DatasetInfo;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -117,6 +118,21 @@ public class GdsDatasetEvaluator {
LOG.debug("<== GdsDatasetEvaluator.evaluate({}, {})", request, result);
}
+ public void getResourceACLs(RangerAccessRequest request,
RangerResourceACLs acls, boolean isConditional, Set<String> allowedAccessTypes,
Map<Long, GdsProjectEvaluator> projects) {
+ acls.getDatasets().add(getName());
+
+ if (!policyEvaluators.isEmpty()) {
+ GdsDatasetAccessRequest datasetRequest = new
GdsDatasetAccessRequest(getId(), gdsServiceDef, request);
+
+ for (RangerPolicyEvaluator policyEvaluator : policyEvaluators) {
+ policyEvaluator.getResourceACLs(datasetRequest, acls,
isConditional, allowedAccessTypes, RangerPolicyResourceMatcher.MatchType.SELF,
null);
+ }
+ }
+
+ for (GdsDipEvaluator dipEvaluator : dipEvaluators) {
+ dipEvaluator.getResourceACLs(request, acls, isConditional,
allowedAccessTypes, projects);
+ }
+ }
public static class GdsDatasetAccessRequest extends
RangerAccessRequestImpl {
public GdsDatasetAccessRequest(Long datasetId, RangerServiceDef
gdsServiceDef, RangerAccessRequest request) {
diff --git
a/agents-common/src/main/java/org/apache/ranger/plugin/policyengine/gds/GdsDipEvaluator.java
b/agents-common/src/main/java/org/apache/ranger/plugin/policyengine/gds/GdsDipEvaluator.java
index 2198eadf1..a5256ca4c 100644
---
a/agents-common/src/main/java/org/apache/ranger/plugin/policyengine/gds/GdsDipEvaluator.java
+++
b/agents-common/src/main/java/org/apache/ranger/plugin/policyengine/gds/GdsDipEvaluator.java
@@ -21,10 +21,18 @@ package org.apache.ranger.plugin.policyengine.gds;
import org.apache.ranger.plugin.model.RangerGds;
import org.apache.ranger.plugin.policyengine.RangerAccessRequest;
+import org.apache.ranger.plugin.policyengine.RangerResourceACLs;
import
org.apache.ranger.plugin.policyevaluator.RangerValidityScheduleEvaluator;
import org.apache.ranger.plugin.util.ServiceGdsInfo.DatasetInProjectInfo;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.Map;
+import java.util.Set;
public class GdsDipEvaluator {
+ private static final Logger LOG =
LoggerFactory.getLogger(GdsDipEvaluator.class);
+
private final DatasetInProjectInfo dip;
private final RangerValidityScheduleEvaluator scheduleEvaluator;
@@ -57,6 +65,25 @@ public class GdsDipEvaluator {
}
+ public void getResourceACLs(RangerAccessRequest request,
RangerResourceACLs acls, boolean isConditional, Set<String> allowedAccessTypes,
Map<Long, GdsProjectEvaluator> projects) {
+ LOG.debug("==> GdsDipEvaluator.getResourceACLs({}, {})", request,
acls);
+
+ if (dip.getStatus() == RangerGds.GdsShareStatus.ACTIVE) {
+ GdsProjectEvaluator evaluator = projects.get(dip.getProjectId());
+
+ if (evaluator != null) {
+ isConditional = isConditional || scheduleEvaluator != null;
+
+ evaluator.getResourceACLs(request, acls, isConditional,
allowedAccessTypes);
+ } else {
+ LOG.warn("GdsDipEvaluator.getResourceACLs({}): evaluator for
projectId={} not found", request, dip.getProjectId());
+ }
+ }
+
+ LOG.debug("<== GdsDipEvaluator.getResourceACLs({}, {})", request,
acls);
+ }
+
+
private boolean isActive() {
boolean ret = dip.getStatus() == RangerGds.GdsShareStatus.ACTIVE;
diff --git
a/agents-common/src/main/java/org/apache/ranger/plugin/policyengine/gds/GdsDshidEvaluator.java
b/agents-common/src/main/java/org/apache/ranger/plugin/policyengine/gds/GdsDshidEvaluator.java
index 97bb06b2e..c32f22b27 100644
---
a/agents-common/src/main/java/org/apache/ranger/plugin/policyengine/gds/GdsDshidEvaluator.java
+++
b/agents-common/src/main/java/org/apache/ranger/plugin/policyengine/gds/GdsDshidEvaluator.java
@@ -21,11 +21,19 @@ package org.apache.ranger.plugin.policyengine.gds;
import org.apache.ranger.plugin.model.RangerGds;
import org.apache.ranger.plugin.policyengine.RangerAccessRequest;
+import org.apache.ranger.plugin.policyengine.RangerResourceACLs;
import
org.apache.ranger.plugin.policyevaluator.RangerValidityScheduleEvaluator;
import org.apache.ranger.plugin.util.ServiceGdsInfo.DataShareInDatasetInfo;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.Map;
+import java.util.Set;
public class GdsDshidEvaluator {
- private final DataShareInDatasetInfo dshid;
+ private static final Logger LOG =
LoggerFactory.getLogger(GdsDshidEvaluator.class);
+
+ private final DataShareInDatasetInfo dshid;
private final RangerValidityScheduleEvaluator scheduleEvaluator;
public GdsDshidEvaluator(DataShareInDatasetInfo dshid) {
@@ -56,6 +64,24 @@ public class GdsDshidEvaluator {
return ret;
}
+ public void getResourceACLs(RangerAccessRequest request,
RangerResourceACLs acls, boolean isConditional, Map<Long, GdsDatasetEvaluator>
datasets, Map<Long, GdsProjectEvaluator> projects, Set<String>
allowedAccessTypes) {
+ LOG.debug("==> GdsDshidEvaluator.getResourceACLs({}, {})", request,
acls);
+
+ if (dshid.getStatus() == RangerGds.GdsShareStatus.ACTIVE) {
+ GdsDatasetEvaluator datasetEvaluator =
datasets.get(dshid.getDatasetId());
+
+ if (datasetEvaluator != null) {
+ isConditional = isConditional || scheduleEvaluator != null;
+
+ datasetEvaluator.getResourceACLs(request, acls, isConditional,
allowedAccessTypes, projects);
+ } else {
+ LOG.warn("GdsDshidEvaluator.getResourceACLs({}):
datasetEvaluator for datasetId={} not found", request, dshid.getDatasetId());
+ }
+ }
+
+ LOG.debug("<== GdsDshidEvaluator.getResourceACLs({}, {})", request,
acls);
+ }
+
private boolean isActive() {
boolean ret = dshid.getStatus() == RangerGds.GdsShareStatus.ACTIVE;
diff --git
a/agents-common/src/main/java/org/apache/ranger/plugin/policyengine/gds/GdsPolicyEngine.java
b/agents-common/src/main/java/org/apache/ranger/plugin/policyengine/gds/GdsPolicyEngine.java
index 809bbfa96..d9aa81732 100644
---
a/agents-common/src/main/java/org/apache/ranger/plugin/policyengine/gds/GdsPolicyEngine.java
+++
b/agents-common/src/main/java/org/apache/ranger/plugin/policyengine/gds/GdsPolicyEngine.java
@@ -27,6 +27,7 @@ import
org.apache.ranger.plugin.model.validation.RangerServiceDefHelper;
import org.apache.ranger.plugin.policyengine.RangerAccessRequest;
import org.apache.ranger.plugin.policyengine.RangerPluginContext;
import org.apache.ranger.plugin.policyengine.RangerPolicyEngineOptions;
+import org.apache.ranger.plugin.policyengine.RangerResourceACLs;
import org.apache.ranger.plugin.util.RangerAccessRequestUtil;
import org.apache.ranger.plugin.util.ServiceGdsInfo;
import org.apache.ranger.plugin.util.ServiceGdsInfo.DatasetInfo;
@@ -98,6 +99,24 @@ public class GdsPolicyEngine {
return ret;
}
+ public RangerResourceACLs getResourceACLs(RangerAccessRequest request) {
+ RangerResourceACLs ret = new RangerResourceACLs();
+
+ List<GdsDataShareEvaluator> dataShares =
getDataShareEvaluators(request);
+
+ if (!dataShares.isEmpty()) {
+ if (dataShares.size() > 1) {
+ dataShares.sort(GdsDataShareEvaluator.EVAL_ORDER_COMPARATOR);
+ }
+
+ for (GdsDataShareEvaluator dshEvaluator : dataShares) {
+ dshEvaluator.getResourceACLs(request, ret, datasets, projects);
+ }
+ }
+
+ return ret;
+ }
+
private void init(RangerServiceDefHelper serviceDefHelper,
RangerPluginContext pluginContext) {
LOG.debug("==> RangerGdsPolicyEngine.init()");
diff --git
a/agents-common/src/main/java/org/apache/ranger/plugin/policyengine/gds/GdsProjectEvaluator.java
b/agents-common/src/main/java/org/apache/ranger/plugin/policyengine/gds/GdsProjectEvaluator.java
index 446f2a90a..17a86163b 100644
---
a/agents-common/src/main/java/org/apache/ranger/plugin/policyengine/gds/GdsProjectEvaluator.java
+++
b/agents-common/src/main/java/org/apache/ranger/plugin/policyengine/gds/GdsProjectEvaluator.java
@@ -25,6 +25,7 @@ import org.apache.ranger.plugin.model.RangerServiceDef;
import org.apache.ranger.plugin.policyengine.*;
import org.apache.ranger.plugin.policyevaluator.RangerOptimizedPolicyEvaluator;
import org.apache.ranger.plugin.policyevaluator.RangerPolicyEvaluator;
+import
org.apache.ranger.plugin.policyresourcematcher.RangerPolicyResourceMatcher;
import org.apache.ranger.plugin.util.ServiceGdsInfo.ProjectInfo;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -33,6 +34,7 @@ import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
+import java.util.Set;
public class GdsProjectEvaluator {
private static final Logger LOG =
LoggerFactory.getLogger(GdsDatasetEvaluator.class);
@@ -105,6 +107,18 @@ public class GdsProjectEvaluator {
LOG.debug("<== GdsDatasetEvaluator.evaluate({}, {})", request, result);
}
+ public void getResourceACLs(RangerAccessRequest request,
RangerResourceACLs acls, boolean isConditional, Set<String> allowedAccessTypes)
{
+ acls.getProjects().add(getName());
+
+ if (!policyEvaluators.isEmpty()) {
+ GdsProjectAccessRequest projectRequest = new
GdsProjectAccessRequest(getId(), gdsServiceDef, request);
+
+ for (RangerPolicyEvaluator policyEvaluator : policyEvaluators) {
+ policyEvaluator.getResourceACLs(projectRequest, acls,
isConditional, allowedAccessTypes, RangerPolicyResourceMatcher.MatchType.SELF,
null);
+ }
+ }
+ }
+
public static class GdsProjectAccessRequest extends
RangerAccessRequestImpl {
public GdsProjectAccessRequest(Long projectId, RangerServiceDef
gdsServiceDef, RangerAccessRequest request) {
diff --git
a/agents-common/src/main/java/org/apache/ranger/plugin/policyengine/gds/GdsSharedResourceEvaluator.java
b/agents-common/src/main/java/org/apache/ranger/plugin/policyengine/gds/GdsSharedResourceEvaluator.java
index 33a9e44fa..726331271 100644
---
a/agents-common/src/main/java/org/apache/ranger/plugin/policyengine/gds/GdsSharedResourceEvaluator.java
+++
b/agents-common/src/main/java/org/apache/ranger/plugin/policyengine/gds/GdsSharedResourceEvaluator.java
@@ -29,6 +29,7 @@ import
org.apache.ranger.plugin.model.RangerPolicy.RangerPolicyResource;
import org.apache.ranger.plugin.model.RangerServiceDef.RangerResourceDef;
import org.apache.ranger.plugin.model.validation.RangerServiceDefHelper;
import org.apache.ranger.plugin.policyengine.RangerAccessRequest;
+import org.apache.ranger.plugin.policyengine.RangerResourceACLs;
import org.apache.ranger.plugin.policyevaluator.RangerCustomConditionEvaluator;
import
org.apache.ranger.plugin.policyresourcematcher.RangerDefaultPolicyResourceMatcher;
import
org.apache.ranger.plugin.policyresourcematcher.RangerPolicyResourceMatcher;
@@ -106,6 +107,10 @@ public class GdsSharedResourceEvaluator implements
RangerResourceEvaluator {
return resource != null && resource.getResource() != null ?
resource.getResource().keySet() : Collections.emptySet();
}
+ public boolean isConditional() { return conditionEvaluator != null; }
+
+ public Set<String> getAllowedAccessTypes() { return allowedAccessTypes; }
+
public boolean isAllowed(RangerAccessRequest request) {
LOG.debug("==> GdsSharedResourceEvaluator.evaluate({})", request);
@@ -132,6 +137,22 @@ public class GdsSharedResourceEvaluator implements
RangerResourceEvaluator {
return ret;
}
+ public void getResourceACLs(RangerAccessRequest request,
RangerResourceACLs acls, boolean isConditional, List<GdsDshidEvaluator>
dshidEvaluators, Map<Long, GdsDatasetEvaluator> datasets, Map<Long,
GdsProjectEvaluator> projects) {
+ LOG.debug("==> GdsSharedResourceEvaluator.getResourceACLs({}, {})",
request, acls);
+
+ boolean isResourceMatch =
policyResourceMatcher.isMatch(request.getResource(),
request.getResourceElementMatchingScopes(), request.getContext());
+
+ if (isResourceMatch) {
+ isConditional = isConditional || conditionEvaluator != null;
+
+ for (GdsDshidEvaluator dshidEvaluator : dshidEvaluators) {
+ dshidEvaluator.getResourceACLs(request, acls, isConditional,
datasets, projects, getAllowedAccessTypes());
+ }
+ }
+
+ LOG.debug("<== GdsSharedResourceEvaluator.getResourceACLs({}, {})",
request, acls);
+ }
+
public RangerPolicyItemRowFilterInfo getRowFilter() {
return resource.getRowFilter();
}
diff --git
a/agents-common/src/main/java/org/apache/ranger/plugin/policyevaluator/RangerAbstractPolicyEvaluator.java
b/agents-common/src/main/java/org/apache/ranger/plugin/policyevaluator/RangerAbstractPolicyEvaluator.java
index b60fc9fb1..07fe6a38d 100644
---
a/agents-common/src/main/java/org/apache/ranger/plugin/policyevaluator/RangerAbstractPolicyEvaluator.java
+++
b/agents-common/src/main/java/org/apache/ranger/plugin/policyevaluator/RangerAbstractPolicyEvaluator.java
@@ -154,7 +154,7 @@ public abstract class RangerAbstractPolicyEvaluator
implements RangerPolicyEvalu
}
@Override
- public void getResourceACLs(RangerAccessRequest request,
RangerResourceACLs acls, boolean isConditional, MatchType matchType,
PolicyEngine policyEngine) {
+ public void getResourceACLs(RangerAccessRequest request,
RangerResourceACLs acls, boolean isConditional, Set<String> targetAccessTypes,
MatchType matchType, PolicyEngine policyEngine) {
boolean isMatched = false;
boolean isConditionalMatch = false;
@@ -186,11 +186,11 @@ public abstract class RangerAbstractPolicyEvaluator
implements RangerPolicyEvalu
int policyType = getPolicyType();
if (policyType == RangerPolicy.POLICY_TYPE_ACCESS) {
- updateFromPolicyACLs(isConditionalMatch, acls);
+ updateFromPolicyACLs(isConditionalMatch, acls,
targetAccessTypes);
} else if (policyType ==
RangerPolicy.POLICY_TYPE_ROWFILTER) {
- updateRowFiltersFromPolicy(isConditionalMatch,
acls);
+ updateRowFiltersFromPolicy(isConditionalMatch,
acls, targetAccessTypes);
} else if (policyType ==
RangerPolicy.POLICY_TYPE_DATAMASK) {
- updateDataMasksFromPolicy(isConditionalMatch,
acls);
+ updateDataMasksFromPolicy(isConditionalMatch,
acls, targetAccessTypes);
}
}
}
@@ -317,7 +317,7 @@ public abstract class RangerAbstractPolicyEvaluator
implements RangerPolicyEvalu
}
- private void updateFromPolicyACLs(boolean isConditional,
RangerResourceACLs resourceACLs) {
+ private void updateFromPolicyACLs(boolean isConditional,
RangerResourceACLs resourceACLs, Set<String> targetAccessTypes) {
PolicyACLSummary aclSummary = getPolicyACLSummary();
if (aclSummary == null) {
@@ -328,6 +328,12 @@ public abstract class RangerAbstractPolicyEvaluator
implements RangerPolicyEvalu
final String userName = userAccessInfo.getKey();
for (Map.Entry<String, PolicyACLSummary.AccessResult>
accessInfo : userAccessInfo.getValue().entrySet()) {
+ String accessType = accessInfo.getKey();
+
+ if (targetAccessTypes != null &&
!targetAccessTypes.contains(accessType)) {
+ continue;
+ }
+
Integer accessResult;
if (isConditional) {
@@ -342,7 +348,7 @@ public abstract class RangerAbstractPolicyEvaluator
implements RangerPolicyEvalu
RangerPolicy policy = getPolicy();
- resourceACLs.setUserAccessInfo(userName,
accessInfo.getKey(), accessResult, policy);
+ resourceACLs.setUserAccessInfo(userName,
accessType, accessResult, policy);
}
}
@@ -350,6 +356,12 @@ public abstract class RangerAbstractPolicyEvaluator
implements RangerPolicyEvalu
final String groupName = groupAccessInfo.getKey();
for (Map.Entry<String, PolicyACLSummary.AccessResult>
accessInfo : groupAccessInfo.getValue().entrySet()) {
+ String accessType = accessInfo.getKey();
+
+ if (targetAccessTypes != null &&
!targetAccessTypes.contains(accessType)) {
+ continue;
+ }
+
Integer accessResult;
if (isConditional) {
@@ -364,7 +376,7 @@ public abstract class RangerAbstractPolicyEvaluator
implements RangerPolicyEvalu
RangerPolicy policy = getPolicy();
- resourceACLs.setGroupAccessInfo(groupName,
accessInfo.getKey(), accessResult, policy);
+ resourceACLs.setGroupAccessInfo(groupName,
accessType, accessResult, policy);
}
}
@@ -372,6 +384,12 @@ public abstract class RangerAbstractPolicyEvaluator
implements RangerPolicyEvalu
final String roleName = roleAccessInfo.getKey();
for (Map.Entry<String, PolicyACLSummary.AccessResult>
accessInfo : roleAccessInfo.getValue().entrySet()) {
+ String accessType = accessInfo.getKey();
+
+ if (targetAccessTypes != null &&
!targetAccessTypes.contains(accessType)) {
+ continue;
+ }
+
Integer accessResult;
if (isConditional) {
@@ -386,16 +404,20 @@ public abstract class RangerAbstractPolicyEvaluator
implements RangerPolicyEvalu
RangerPolicy policy = getPolicy();
- resourceACLs.setRoleAccessInfo(roleName,
accessInfo.getKey(), accessResult, policy);
+ resourceACLs.setRoleAccessInfo(roleName,
accessType, accessResult, policy);
}
}
}
- private void updateRowFiltersFromPolicy(boolean isConditional,
RangerResourceACLs resourceACLs) {
+ private void updateRowFiltersFromPolicy(boolean isConditional,
RangerResourceACLs resourceACLs, Set<String> targetAccessTypes) {
PolicyACLSummary aclSummary = getPolicyACLSummary();
if (aclSummary != null) {
for (RowFilterResult rowFilterResult :
aclSummary.getRowFilters()) {
+ if (targetAccessTypes != null &&
!CollectionUtils.containsAny(targetAccessTypes,
rowFilterResult.getAccessTypes())) {
+ continue;
+ }
+
rowFilterResult =
copyRowFilter(rowFilterResult);
if (isConditional) {
@@ -407,11 +429,15 @@ public abstract class RangerAbstractPolicyEvaluator
implements RangerPolicyEvalu
}
}
- private void updateDataMasksFromPolicy(boolean isConditional,
RangerResourceACLs resourceACLs) {
+ private void updateDataMasksFromPolicy(boolean isConditional,
RangerResourceACLs resourceACLs, Set<String> targetAccessTypes) {
PolicyACLSummary aclSummary = getPolicyACLSummary();
if (aclSummary != null) {
for (DataMaskResult dataMaskResult :
aclSummary.getDataMasks()) {
+ if (targetAccessTypes != null &&
!CollectionUtils.containsAny(targetAccessTypes,
dataMaskResult.getAccessTypes())) {
+ continue;
+ }
+
dataMaskResult = copyDataMask(dataMaskResult);
if (isConditional) {
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 0a14b387a..2856ccc6b 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
@@ -104,7 +104,7 @@ public interface RangerPolicyEvaluator {
void evaluate(RangerAccessRequest request, RangerAccessResult result);
- void getResourceACLs(RangerAccessRequest request, RangerResourceACLs
acls, boolean isConditional, MatchType matchType, PolicyEngine policyEngine);
+ void getResourceACLs(RangerAccessRequest request, RangerResourceACLs
acls, boolean isConditional, Set<String> targetAccessTypes, MatchType
matchType, PolicyEngine policyEngine);
boolean isMatch(RangerAccessResource resource, Map<String, Object>
evalContext);
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 71478f4bb..748efd681 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
@@ -51,6 +51,7 @@ import
org.apache.ranger.plugin.policyengine.RangerPolicyEngine;
import org.apache.ranger.plugin.policyengine.RangerPolicyEngineImpl;
import org.apache.ranger.plugin.policyengine.RangerResourceACLs;
import org.apache.ranger.plugin.policyengine.RangerResourceAccessInfo;
+import org.apache.ranger.plugin.policyengine.gds.GdsPolicyEngine;
import org.apache.ranger.plugin.policyevaluator.RangerPolicyEvaluator;
import org.apache.ranger.plugin.store.EmbeddedServiceDefsUtil;
import org.apache.ranger.plugin.util.*;
@@ -698,6 +699,20 @@ public class RangerBasePlugin {
}
}
+ GdsPolicyEngine gdsPolicyEngine = getGdsPolicyEngine();
+
+ if (gdsPolicyEngine != null) {
+ RangerResourceACLs gdsACLs =
gdsPolicyEngine.getResourceACLs(request);
+
+ if (gdsACLs != null) {
+ if (ret != null) {
+ ret = getMergedResourceACLs(ret,
gdsACLs);
+ } else {
+ ret = gdsACLs;
+ }
+ }
+ }
+
return ret;
}
@@ -1139,6 +1154,31 @@ public class RangerBasePlugin {
return ret;
}
+ public GdsPolicyEngine getGdsPolicyEngine() {
+ GdsPolicyEngine ret = null;
+ RangerAuthContext authContext = getCurrentRangerAuthContext();
+
+ if (authContext != null) {
+ Map<RangerContextEnricher, Object> contextEnricherMap =
authContext.getRequestContextEnrichers();
+
+ if (MapUtils.isNotEmpty(contextEnricherMap)) {
+ Set<RangerContextEnricher> contextEnrichers =
contextEnricherMap.keySet();
+
+ for (RangerContextEnricher enricher :
contextEnrichers) {
+ if (enricher instanceof
RangerGdsEnricher) {
+ RangerGdsEnricher gdsEnricher =
(RangerGdsEnricher) enricher;
+
+ ret =
gdsEnricher.getGdsPolicyEngine();
+
+ break;
+ }
+ }
+ }
+ }
+
+ return ret;
+ }
+
public static RangerResourceACLs
getMergedResourceACLs(RangerResourceACLs baseACLs, RangerResourceACLs
chainedACLs) {
if (LOG.isDebugEnabled()) {
LOG.debug("==>
RangerBasePlugin.getMergedResourceACLs()");
@@ -1149,6 +1189,8 @@ public class RangerBasePlugin {
overrideACLs(chainedACLs, baseACLs,
RangerRolesUtil.ROLES_FOR.USER);
overrideACLs(chainedACLs, baseACLs,
RangerRolesUtil.ROLES_FOR.GROUP);
overrideACLs(chainedACLs, baseACLs,
RangerRolesUtil.ROLES_FOR.ROLE);
+ baseACLs.getDatasets().addAll(chainedACLs.getDatasets());
+ baseACLs.getProjects().addAll(chainedACLs.getProjects());
if (LOG.isDebugEnabled()) {
LOG.debug("<== RangerBasePlugin.getMergedResourceACLs()
: ret:[" + baseACLs + "]");
diff --git
a/agents-common/src/test/java/org/apache/ranger/plugin/policyengine/gds/TestGdsPolicyEngine.java
b/agents-common/src/test/java/org/apache/ranger/plugin/policyengine/gds/TestGdsPolicyEngine.java
index 83bfc99f5..b5ca483ad 100644
---
a/agents-common/src/test/java/org/apache/ranger/plugin/policyengine/gds/TestGdsPolicyEngine.java
+++
b/agents-common/src/test/java/org/apache/ranger/plugin/policyengine/gds/TestGdsPolicyEngine.java
@@ -80,9 +80,17 @@ public class TestGdsPolicyEngine {
RangerAccessRequestUtil.setResourceZoneNamesInContext(test.request, zoneNames);
- GdsAccessResult result = policyEngine.evaluate(test.request);
+ if (test.result != null) {
+ GdsAccessResult result = policyEngine.evaluate(test.request);
- assertEquals(test.name, test.result, result);
+ assertEquals(test.name, test.result, result);
+ }
+
+ if (test.acls != null) {
+ RangerResourceACLs acls =
policyEngine.getResourceACLs(test.request);
+
+ assertEquals(test.name, test.acls, acls);
+ }
}
}
@@ -97,6 +105,7 @@ public class TestGdsPolicyEngine {
public String name;
public RangerAccessRequest request;
public GdsAccessResult result;
+ public RangerResourceACLs acls;
}
static class RangerAccessRequestDeserializer implements
JsonDeserializer<RangerAccessRequest> {
diff --git
a/agents-common/src/test/resources/policyengine/gds/test_gds_policy_engine_hive.json
b/agents-common/src/test/resources/policyengine/gds/test_gds_policy_engine_hive.json
index 010baed5c..89fed5f9e 100644
---
a/agents-common/src/test/resources/policyengine/gds/test_gds_policy_engine_hive.json
+++
b/agents-common/src/test/resources/policyengine/gds/test_gds_policy_engine_hive.json
@@ -96,10 +96,10 @@
"id": 1,
"name": "dataset-1",
"policies": [
- { "id": 2001, "name": "dataset-3", "isEnabled": true,
"isAuditEnabled": true,
+ { "id": 2001, "name": "dataset-1", "isEnabled": true,
"isAuditEnabled": true,
"resources": { "dataset-id": { "values": ["1"] } },
"policyItems":[
- { "accesses":[ { "type": "_READ", "isAllowed": true } ],
"users": [ "ds-user" ], "groups": []}
+ { "accesses":[ { "type": "_ALL", "isAllowed": true } ], "users":
[ "ds-user" ], "groups": []}
]
}
]
@@ -111,7 +111,7 @@
{ "id": 2002, "name": "dataset-2", "isEnabled": true,
"isAuditEnabled": true,
"resources": { "dataset-id": { "values": ["2"] } },
"policyItems":[
- { "accesses":[ { "type": "_READ", "isAllowed": true } ],
"users": [ "ds-user" ], "groups": []}
+ { "accesses":[ { "type": "_ALL", "isAllowed": true } ], "users":
[ "ds-user" ], "groups": []}
]
}
]
@@ -123,7 +123,7 @@
{ "id": 2003, "name": "dataset-3", "isEnabled": true,
"isAuditEnabled": true,
"resources": { "dataset-id": { "values": ["3"] } },
"policyItems":[
- { "accesses":[ { "type": "_READ", "isAllowed": true } ],
"users": [ "ds-user" ], "groups": []}
+ { "accesses":[ { "type": "_ALL", "isAllowed": true } ], "users":
[ "ds-user" ], "groups": []}
]
}
]
@@ -135,7 +135,7 @@
{ "id": 2004, "name": "dataset-4", "isEnabled": true,
"isAuditEnabled": true,
"resources": { "dataset-id": { "values": ["4"] } },
"policyItems":[
- { "accesses":[ { "type": "_READ", "isAllowed": true } ],
"users": [ "ds-user" ], "groups": []}
+ { "accesses":[ { "type": "_ALL", "isAllowed": true } ], "users":
[ "ds-user" ], "groups": []}
]
}
]
@@ -149,7 +149,7 @@
{ "id": 3001, "name": "project-1", "isEnabled": true,
"isAuditEnabled": true,
"resources": { "project-id": { "values": ["1"] } },
"policyItems":[
- { "accesses":[ { "type": "_READ", "isAllowed": true } ],
"users": [ "proj-user" ], "groups": []}
+ { "accesses":[ { "type": "_ALL", "isAllowed": true } ], "users":
[ "proj-user" ], "groups": []}
]
}
]
@@ -161,7 +161,7 @@
{ "id": 3002, "name": "project-2", "isEnabled": true,
"isAuditEnabled": true,
"resources": { "project-id": { "values": ["2"] } },
"policyItems":[
- { "accesses":[ { "type": "_READ", "isAllowed": true } ],
"users": [ "proj-user" ], "groups": []}
+ { "accesses":[ { "type": "_ALL", "isAllowed": true } ], "users":
[ "proj-user" ], "groups": []}
]
}
]
@@ -376,6 +376,131 @@
"accessType": "update", "user": "ds-user", "userGroups": []
},
"result": { "datasets": null, "projects": null, "isAllowed": false,
"isAudited": false, "policyId": -1 }
+ },
+
+ {
+ "name": "ACLs: database: sales",
+ "request": { "resource": { "elements": { "database": "sales" } } },
+ "acls": { }
+ },
+ {
+ "name": "ACLs: table: sales.prospects",
+ "request": { "resource": { "elements": { "database": "sales", "table":
"prospects" } } },
+ "acls": {
+ "userACLs": {
+ "ds-user": { "select": { "result": 1, "isFinal": false } },
+ "proj-user": { "select": { "result": 1, "isFinal": false } }
+ },
+ "datasets": [ "dataset-1" ],
+ "projects": [ "project-1" ]
+ }
+ },
+ {
+ "name": "ACLs: table: sales.orders",
+ "request": { "resource": { "elements": { "database": "sales", "table":
"orders" } } },
+ "acls": {
+ "userACLs": {
+ "ds-user": { "select": { "result": 1, "isFinal": false } },
+ "proj-user": { "select": { "result": 1, "isFinal": false } }
+ },
+ "datasets": [ "dataset-1" ],
+ "projects": [ "project-1" ]
+ }
+ },
+ {
+ "name": "ACLs: table: sales.non_existent_table",
+ "request": { "resource": { "elements": { "database": "sales", "table":
"non_existent_table" } } },
+ "acls": { }
+ },
+ {
+ "name": "ACLs: column: sales.orders.created_time",
+ "request": { "resource": { "elements": { "database": "sales", "table":
"orders", "column": "created_time" } } },
+ "acls": {
+ "userACLs": {
+ "ds-user": { "select": { "result": 1, "isFinal": false } },
+ "proj-user": { "select": { "result": 1, "isFinal": false } }
+ },
+ "datasets": [ "dataset-1" ],
+ "projects": [ "project-1" ]
+ }
+ },
+ {
+ "name": "ACLs: database: finance",
+ "request": { "resource": { "elements": { "database": "finance" } } },
+ "acls": { }
+ },
+ {
+ "name": "ACLs: table: finance.invoices",
+ "request": { "resource": { "elements": { "database": "finance", "table":
"invoices" } } },
+ "acls": {
+ "userACLs": {
+ "ds-user": { "select": { "result": 1, "isFinal": false } },
+ "proj-user": { "select": { "result": 1, "isFinal": false } }
+ },
+ "datasets": [ "dataset-1", "dataset-2" ],
+ "projects": [ "project-1" ]
+ }
+ },
+ {
+ "name": "ACLs: table: finance.payments",
+ "request": { "resource": { "elements": { "database": "finance", "table":
"payments" } } },
+ "acls": {
+ "userACLs": {
+ "ds-user": { "select": { "result": 1, "isFinal": false } },
+ "proj-user": { "select": { "result": 1, "isFinal": false } }
+ },
+ "datasets": [ "dataset-1", "dataset-2" ],
+ "projects": [ "project-1" ]
+ }
+ },
+ {
+ "name": "ACLs: database: shipping",
+ "request": { "resource": { "elements": { "database": "shipping" } } },
+ "acls": { }
+ },
+ {
+ "name": "ACLs: table: shipping.shipments",
+ "request": { "resource": { "elements": { "database": "shipping",
"table": "shipments" } } },
+ "acls": {
+ "userACLs": {
+ "ds-user": { "select": { "result": 1, "isFinal": false } },
+ "proj-user": { "select": { "result": 1, "isFinal": false } }
+ },
+ "datasets": [ "dataset-2" ],
+ "projects": [ "project-1" ]
+ }
+ },
+ {
+ "name": "ACLs: database: customers",
+ "request": { "resource": { "elements": { "database": "customers" } } },
+ "acls": { }
+ },
+ {
+ "name": "ACLs: table: customers.contact_info",
+ "request": { "resource": { "elements": { "database": "customers",
"table": "contact_info" } } },
+ "acls": {
+ "userACLs": {
+ "ds-user": { "select": { "result": 1, "isFinal": false } },
+ "proj-user": { "select": { "result": 1, "isFinal": false } }
+ },
+ "datasets": [ "dataset-3" ],
+ "projects": [ "project-2" ]
+ }
+ },
+ {
+ "name": "ACLs: database: operations",
+ "request": { "resource": { "elements": { "database": "operations" } } },
+ "acls": { }
+ },
+ {
+ "name": "ACLs: table: operations.facilities",
+ "request": { "resource": { "elements": { "database": "operations",
"table": "facilities" } } },
+ "acls": {
+ "userACLs": {
+ "ds-user": { "select": { "result": 1, "isFinal": false } }
+ },
+ "datasets": [ "dataset-4" ]
+ }
}
]
}