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 3842fd756 RANGER-4269: gds enricher implementation to grant access
using dataset/project policies
3842fd756 is described below
commit 3842fd75656c3dbf06328a501093ddae0ad3623b
Author: Madhan Neethiraj <[email protected]>
AuthorDate: Wed Nov 8 14:36:20 2023 -0800
RANGER-4269: gds enricher implementation to grant access using
dataset/project policies
---
.../plugin/contextenricher/RangerGdsEnricher.java | 126 +------
.../model/RangerPolicyResourceSignature.java | 26 ++
.../model/validation/RangerServiceDefHelper.java | 56 +++
.../plugin/policyengine/RangerAccessResult.java | 36 +-
.../policyengine/RangerPolicyEngineImpl.java | 39 +++
.../policyengine/RangerPolicyEngineOptions.java | 6 +
.../plugin/policyengine/gds/GdsAccessResult.java | 174 ++++++++++
.../policyengine/gds/GdsDataShareEvaluator.java | 164 +++++++++
.../policyengine/gds/GdsDatasetEvaluator.java | 175 ++++++++++
.../plugin/policyengine/gds/GdsDipEvaluator.java | 69 ++++
.../plugin/policyengine/gds/GdsDshidEvaluator.java | 69 ++++
.../plugin/policyengine/gds/GdsPolicyEngine.java | 298 ++++++++++++++++
.../policyengine/gds/GdsProjectEvaluator.java | 160 +++++++++
.../gds/GdsSharedResourceEvaluator.java | 179 ++++++++++
.../RangerCustomConditionEvaluator.java | 28 ++
.../plugin/util/RangerAccessRequestUtil.java | 29 ++
.../apache/ranger/plugin/util/ServiceGdsInfo.java | 78 +----
.../plugin/policyengine/TestRangerAuthContext.java | 5 +-
.../policyengine/gds/TestGdsPolicyEngine.java | 131 +++++++
.../gds/test_gds_policy_engine_hive.json | 381 +++++++++++++++++++++
.../java/org/apache/ranger/biz/GdsDBStore.java | 9 +
.../service/RangerGdsSharedResourceService.java | 2 +-
22 files changed, 2059 insertions(+), 181 deletions(-)
diff --git
a/agents-common/src/main/java/org/apache/ranger/plugin/contextenricher/RangerGdsEnricher.java
b/agents-common/src/main/java/org/apache/ranger/plugin/contextenricher/RangerGdsEnricher.java
index da51b9d85..8a7936766 100644
---
a/agents-common/src/main/java/org/apache/ranger/plugin/contextenricher/RangerGdsEnricher.java
+++
b/agents-common/src/main/java/org/apache/ranger/plugin/contextenricher/RangerGdsEnricher.java
@@ -22,17 +22,14 @@ package org.apache.ranger.plugin.contextenricher;
import org.apache.commons.lang3.StringUtils;
import org.apache.ranger.plugin.model.validation.RangerServiceDefHelper;
import org.apache.ranger.plugin.policyengine.RangerAccessRequest;
+import org.apache.ranger.plugin.policyengine.gds.GdsAccessResult;
+import org.apache.ranger.plugin.policyengine.gds.GdsPolicyEngine;
import org.apache.ranger.plugin.service.RangerAuthContext;
import org.apache.ranger.plugin.util.DownloadTrigger;
import org.apache.ranger.plugin.util.DownloaderTask;
import org.apache.ranger.plugin.util.JsonUtilsV2;
+import org.apache.ranger.plugin.util.RangerAccessRequestUtil;
import org.apache.ranger.plugin.util.ServiceGdsInfo;
-import org.apache.ranger.plugin.util.ServiceGdsInfo.DatasetInfo;
-import org.apache.ranger.plugin.util.ServiceGdsInfo.DatasetInProjectInfo;
-import org.apache.ranger.plugin.util.ServiceGdsInfo.DataShareInfo;
-import org.apache.ranger.plugin.util.ServiceGdsInfo.DataShareInDatasetInfo;
-import org.apache.ranger.plugin.util.ServiceGdsInfo.ProjectInfo;
-import org.apache.ranger.plugin.util.ServiceGdsInfo.SharedResourceInfo;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -50,7 +47,7 @@ public class RangerGdsEnricher extends
RangerAbstractContextEnricher {
private RangerGdsInfoRetriever gdsInfoRetriever;
private RangerGdsInfoRefresher gdsInfoRefresher;
private RangerServiceDefHelper serviceDefHelper;
- private EnhancedGdsInfo gdsInfo = null;
+ private GdsPolicyEngine gdsPolicyEngine = null;
@Override
public void init() {
@@ -145,24 +142,26 @@ public class RangerGdsEnricher extends
RangerAbstractContextEnricher {
public void enrich(RangerAccessRequest request, Object dataStore) {
LOG.debug("==> RangerGdsEnricher.enrich({}, {})", request, dataStore);
- EnhancedGdsInfo gdsInfo = (dataStore instanceof EnhancedGdsInfo) ?
(EnhancedGdsInfo) dataStore : this.gdsInfo;
+ GdsPolicyEngine policyEngine = (dataStore instanceof GdsPolicyEngine)
? (GdsPolicyEngine) dataStore : this.gdsPolicyEngine;
- LOG.debug("RangerGdsEnricher.enrich(): using gdsInfo={}", gdsInfo);
+ LOG.debug("RangerGdsEnricher.enrich(): using policyEngine={}",
policyEngine);
- // TODO:
+ GdsAccessResult result = policyEngine != null ?
policyEngine.evaluate(request) : null;
+
+ RangerAccessRequestUtil.setGdsResultInContext(request, result);
LOG.debug("<== RangerGdsEnricher.enrich({}, {})", request, dataStore);
}
public void setGdsInfo(ServiceGdsInfo gdsInfo) {
- this.gdsInfo = new EnhancedGdsInfo(gdsInfo);
+ this.gdsPolicyEngine = new GdsPolicyEngine(gdsInfo, serviceDefHelper,
getPluginContext());
setGdsInfoInPlugin();
}
public RangerServiceDefHelper getServiceDefHelper() { return
serviceDefHelper; }
- public EnhancedGdsInfo getGdsInfo() { return gdsInfo; }
+ public GdsPolicyEngine getGdsPolicyEngine() { return gdsPolicyEngine; }
private void setGdsInfoInPlugin() {
LOG.debug("==> setGdsInfoInPlugin()");
@@ -170,7 +169,7 @@ public class RangerGdsEnricher extends
RangerAbstractContextEnricher {
RangerAuthContext authContext = getAuthContext();
if (authContext != null) {
- authContext.addOrReplaceRequestContextEnricher(this, gdsInfo);
+ authContext.addOrReplaceRequestContextEnricher(this,
gdsPolicyEngine);
notifyAuthContextChanged();
}
@@ -345,105 +344,4 @@ public class RangerGdsEnricher extends
RangerAbstractContextEnricher {
LOG.debug("<==
RangerGdsInfoRefresher(serviceName={}).saveToCache()", getServiceName());
}
}
-
- public static class EnhancedGdsInfo {
- private final RangerServiceDefHelper
gdsServiceDefHelper;
- private final Map<String, List<DataShareInfo>> zoneShares;
- private final Map<Long, List<SharedResourceInfo>> shareResources;
- private final Map<Long, DatasetInfo> datasets;
- private final Map<Long, ProjectInfo> projects;
- private final Map<Long, List<DataShareInDatasetInfo>> shareDatasets;
- private final Map<Long, List<DatasetInProjectInfo>> datasetProjects;
-
- EnhancedGdsInfo(ServiceGdsInfo gdsInfo) {
- if (gdsInfo != null) {
- this.gdsServiceDefHelper = gdsInfo.getGdsServiceDef() != null
? new RangerServiceDefHelper(gdsInfo.getGdsServiceDef(), false) : null;
- this.zoneShares = new HashMap<>();
- this.shareResources = new HashMap<>();
- this.datasets = new HashMap<>();
- this.projects = new HashMap<>();
- this.shareDatasets = new HashMap<>();
- this.datasetProjects = new HashMap<>();
-
- if (gdsInfo.getDataShares() != null) {
- for (DataShareInfo dataShareInfo :
gdsInfo.getDataShares()) {
- if (dataShareInfo != null) {
- String zoneName =
dataShareInfo.getZoneName() == null ? StringUtils.EMPTY :
dataShareInfo.getZoneName();
- List<DataShareInfo> shares =
zoneShares.computeIfAbsent(zoneName, k -> new ArrayList<>());
-
- shares.add(dataShareInfo);
- }
- }
- }
-
- if (gdsInfo.getResources() != null) {
- for (SharedResourceInfo resource : gdsInfo.getResources())
{
- if (resource != null) {
- List<SharedResourceInfo> resources =
shareResources.computeIfAbsent(resource.getDataShareId(), k -> new
ArrayList<>());
-
- resources.add(resource);
- }
- }
- }
-
- if (gdsInfo.getDatasets() != null) {
- for (DatasetInfo datasetInfo : gdsInfo.getDatasets()) {
- if (datasetInfo != null) {
- datasets.put(datasetInfo.getId(), datasetInfo);
- }
- }
- }
-
- if (gdsInfo.getProjects() != null) {
- for (ProjectInfo projectInfo : gdsInfo.getProjects()) {
- if (projectInfo != null) {
- projects.put(projectInfo.getId(), projectInfo);
- }
- }
- }
-
- if (gdsInfo.getDshids() != null) {
- for (DataShareInDatasetInfo dshid : gdsInfo.getDshids()) {
- if (dshid != null) {
- List<DataShareInDatasetInfo> dshids =
shareDatasets.computeIfAbsent(dshid.getDatasetId(), k -> new ArrayList<>());
-
- dshids.add(dshid);
- }
- }
- }
-
- if (gdsInfo.getDips() != null) {
- for (DatasetInProjectInfo dip : gdsInfo.getDips()) {
- if (dip != null) {
- List<DatasetInProjectInfo> dips =
datasetProjects.computeIfAbsent(dip.getDatasetId(), k -> new ArrayList<>());
-
- dips.add(dip);
- }
- }
- }
- } else {
- this.gdsServiceDefHelper = null;
- this.zoneShares = Collections.emptyMap();
- this.shareResources = Collections.emptyMap();
- this.datasets = Collections.emptyMap();
- this.projects = Collections.emptyMap();
- this.shareDatasets = Collections.emptyMap();
- this.datasetProjects = Collections.emptyMap();
- }
- }
-
- public RangerServiceDefHelper getGdsServiceDefHelper() { return
gdsServiceDefHelper; }
-
- public List<DataShareInfo> getDataSharesForZone(String zoneName) {
return zoneShares.get(zoneName); }
-
- public List<SharedResourceInfo> getResourcesForDataShare(Long
dataShareId) { return shareResources.get(dataShareId); }
-
- public DatasetInfo getDatasetInfo(Long datasetId) { return
datasets.get(datasetId); }
-
- public ProjectInfo getProjectInfo(Long projectId) { return
projects.get(projectId); }
-
- public List<DataShareInDatasetInfo> getDatasetsForDataShare(Long
dataShareId) { return shareDatasets.get(dataShareId); }
-
- public List<DatasetInProjectInfo> getProjectsForDataset(Long
datasetId) { return datasetProjects.get(datasetId); }
- }
}
diff --git
a/agents-common/src/main/java/org/apache/ranger/plugin/model/RangerPolicyResourceSignature.java
b/agents-common/src/main/java/org/apache/ranger/plugin/model/RangerPolicyResourceSignature.java
index bcdc86779..75dc6870b 100755
---
a/agents-common/src/main/java/org/apache/ranger/plugin/model/RangerPolicyResourceSignature.java
+++
b/agents-common/src/main/java/org/apache/ranger/plugin/model/RangerPolicyResourceSignature.java
@@ -21,6 +21,7 @@ package org.apache.ranger.plugin.model;
import java.util.ArrayList;
import java.util.Collections;
+import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
@@ -30,6 +31,7 @@ import org.apache.commons.codec.digest.DigestUtils;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.collections.MapUtils;
import org.apache.ranger.authorization.hadoop.config.RangerAdminConfig;
+import org.apache.ranger.plugin.model.RangerGds.RangerSharedResource;
import org.apache.ranger.plugin.model.RangerPolicy.RangerPolicyResource;
import org.apache.ranger.plugin.model.RangerPolicy.RangerPolicyItemCondition;
import org.apache.commons.lang.StringUtils;
@@ -57,6 +59,10 @@ public class RangerPolicyResourceSignature {
}
}
+ public RangerPolicyResourceSignature(RangerSharedResource resource) {
+ this(toSignatureString(resource));
+ }
+
public RangerPolicyResourceSignature(Map<String, RangerPolicyResource>
resources) {
this(toSignatureString(resources));
}
@@ -214,6 +220,26 @@ public class RangerPolicyResourceSignature {
return ret;
}
+ public static String toSignatureString(RangerSharedResource resource) {
+ final Map<String, RangerPolicyResource> policyResource;
+
+ if (StringUtils.isNotBlank(resource.getSubResourceType()) &&
resource.getSubResource() != null &&
CollectionUtils.isNotEmpty(resource.getSubResource().getValues())) {
+ policyResource = new HashMap<>(resource.getResource());
+
+ policyResource.put(resource.getSubResourceType(),
resource.getSubResource());
+ } else {
+ policyResource = resource.getResource();
+ }
+
+ String signature = toSignatureString(policyResource);
+
+ if (StringUtils.isNotEmpty(resource.getConditionExpr())) {
+ signature += resource.getConditionExpr();
+ }
+
+ return String.format("{version=%d,ret=%s}", _SignatureVersion,
signature);
+ }
+
private static Map<String, RangerPolicyResource>
toPolicyResources(Map<String, List<String>> resources) {
Map<String, RangerPolicyResource> ret = new TreeMap<>();
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 d99d342bd..51a3aae6f 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
@@ -172,6 +172,14 @@ public class RangerServiceDefHelper {
_delegate.patchServiceDefWithDefaultValues();
}
+ public RangerResourceDef getResourceDef(String resourceName) {
+ return _delegate.getResourceDef(resourceName,
RangerPolicy.POLICY_TYPE_ACCESS);
+ }
+
+ public RangerResourceDef getResourceDef(String resourceName, Integer
policyType) {
+ return _delegate.getResourceDef(resourceName, policyType);
+ }
+
/**
* for a resource definition as follows:
*
@@ -346,6 +354,32 @@ public class RangerServiceDefHelper {
return _delegate.getImpliedAccessGrants();
}
+ public Set<String> expandImpliedAccessGrants(Set<String> accessTypes) {
+ final Set<String> ret;
+
+ if (CollectionUtils.isNotEmpty(accessTypes)) {
+ Map<String, Collection<String>> impliedGrants =
getImpliedAccessGrants();
+
+ if (CollectionUtils.containsAny(impliedGrants.keySet(),
accessTypes)) {
+ ret = new HashSet<>(accessTypes);
+
+ for (String accessType : accessTypes) {
+ Collection<String> impliedAccessTypes =
impliedGrants.get(accessType);
+
+ if
(CollectionUtils.isNotEmpty(impliedAccessTypes)) {
+ ret.addAll(impliedAccessTypes);
+ }
+ }
+ } else {
+ ret = accessTypes;
+ }
+ } else {
+ ret = Collections.emptySet();
+ }
+
+ return ret;
+ }
+
/**
* Not designed for public access. Package level only for testability.
*/
@@ -428,6 +462,28 @@ public class RangerServiceDefHelper {
}
}
+ public RangerResourceDef getResourceDef(String resourceName,
Integer policyType) {
+ RangerResourceDef ret = null;
+
+ if (policyType == null) {
+ policyType = RangerPolicy.POLICY_TYPE_ACCESS;
+ }
+
+ List<RangerResourceDef> resourceDefs =
this.getResourceDefs(_serviceDef, policyType);
+
+ if (resourceDefs != null) {
+ for (RangerResourceDef resourceDef :
resourceDefs) {
+ if (StringUtils.equals(resourceName,
resourceDef.getName())) {
+ ret = resourceDef;
+
+ break;
+ }
+ }
+ }
+
+ return ret;
+ }
+
public Set<List<RangerResourceDef>>
getResourceHierarchies(Integer policyType) {
if(policyType == null) {
policyType = RangerPolicy.POLICY_TYPE_ACCESS;
diff --git
a/agents-common/src/main/java/org/apache/ranger/plugin/policyengine/RangerAccessResult.java
b/agents-common/src/main/java/org/apache/ranger/plugin/policyengine/RangerAccessResult.java
index 407e3e747..69e8ed9fc 100644
---
a/agents-common/src/main/java/org/apache/ranger/plugin/policyengine/RangerAccessResult.java
+++
b/agents-common/src/main/java/org/apache/ranger/plugin/policyengine/RangerAccessResult.java
@@ -25,14 +25,16 @@ import org.apache.ranger.plugin.model.RangerServiceDef;
import org.apache.ranger.plugin.util.ServiceDefUtil;
import java.util.HashMap;
+import java.util.List;
import java.util.Map;
public class RangerAccessResult {
- public final static String KEY_MASK_TYPE = "maskType";
- public final static String KEY_MASK_CONDITION = "maskCondition";
- public final static String KEY_MASKED_VALUE = "maskedValue";
-
- private static String KEY_FILTER_EXPR = "filterExpr";
+ public final static String KEY_MASK_TYPE = "maskType";
+ public final static String KEY_MASK_CONDITION = "maskCondition";
+ public final static String KEY_MASKED_VALUE = "maskedValue";
+ private final static String KEY_FILTER_EXPR = "filterExpr";
+ private final static String KEY_DATASETS = "datasets";
+ private final static String KEY_PROJECTS = "projects";
private final String serviceName;
private final RangerServiceDef serviceDef;
@@ -326,6 +328,30 @@ public class RangerAccessResult {
return StringUtils.isNotEmpty(getFilterExpr());
}
+ public List<String> getDatasets() {
+ return additionalInfo == null ? null : (List<String>)
additionalInfo.get(KEY_DATASETS);
+ }
+
+ public void setDatasets(List<String> datasets) {
+ if (datasets == null) {
+ removeAdditionalInfo(KEY_DATASETS);
+ } else {
+ addAdditionalInfo(KEY_DATASETS, datasets);
+ }
+ }
+
+ public List<String> getProjects() {
+ return additionalInfo == null ? null : (List<String>)
additionalInfo.get(KEY_PROJECTS);
+ }
+
+ public void setProjects(List<String> projects) {
+ if (projects == null) {
+ removeAdditionalInfo(KEY_PROJECTS);
+ } else {
+ addAdditionalInfo(KEY_PROJECTS, projects);
+ }
+ }
+
@Override
public String toString( ) {
StringBuilder sb = new StringBuilder();
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 ed6ded49e..868122869 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
@@ -29,6 +29,7 @@ import org.apache.ranger.authorization.utils.StringUtil;
import org.apache.ranger.plugin.contextenricher.RangerTagForEval;
import org.apache.ranger.plugin.model.RangerPolicy;
import org.apache.ranger.plugin.model.RangerServiceDef;
+import org.apache.ranger.plugin.policyengine.gds.GdsAccessResult;
import org.apache.ranger.plugin.policyevaluator.RangerPolicyEvaluator;
import
org.apache.ranger.plugin.policyresourcematcher.RangerPolicyResourceMatcher.MatchType;
import org.apache.ranger.plugin.service.RangerDefaultRequestProcessor;
@@ -648,6 +649,8 @@ public class RangerPolicyEngineImpl implements
RangerPolicyEngine {
}
}
+ updateFromGdsResult(ret);
+
if (LOG.isDebugEnabled()) {
LOG.debug("<==
RangerPolicyEngineImpl.zoneAwareAccessEvaluationWithNoAudit(" + request + ",
policyType =" + policyType + "): " + ret);
}
@@ -1128,6 +1131,42 @@ public class RangerPolicyEngineImpl implements
RangerPolicyEngine {
return
policyEngine.getPluginContext().getConfig().getIsFallbackSupported();
}
+ private void updateFromGdsResult(RangerAccessResult result) {
+ if (LOG.isDebugEnabled()) {
+ LOG.debug("==> updateFromGdsResult(result={})", result);
+ }
+
+ RangerAccessRequest request = result.getAccessRequest();
+ GdsAccessResult gdsResult = request != null ?
RangerAccessRequestUtil.getGdsResultFromContext(request.getContext()) : null;
+
+ if (gdsResult != null) {
+ if (result.getPolicyType() ==
RangerPolicy.POLICY_TYPE_ACCESS) {
+ if (!result.getIsAccessDetermined() &&
gdsResult.getIsAllowed()) {
+ result.setIsAllowed(true);
+ result.setIsAccessDetermined(true);
+
result.setPolicyId(gdsResult.getPolicyId());
+
result.setPolicyVersion(gdsResult.getPolicyVersion());
+
result.setPolicyPriority(RangerPolicy.POLICY_PRIORITY_NORMAL);
+ }
+ }
+
+ if (!result.getIsAuditedDetermined() &&
gdsResult.getIsAudited()) {
+ result.setIsAudited(true);
+ }
+
+ result.setDatasets(gdsResult.getDatasetNames());
+ result.setProjects(gdsResult.getProjectNames());
+ } else {
+ if (LOG.isDebugEnabled()) {
+ LOG.debug("updateFromGdsResult(): no
GdsAccessResult found in request context({})", request);
+ }
+ }
+
+ if (LOG.isDebugEnabled()) {
+ LOG.debug("<== updateFromGdsResult(result={})", result);
+ }
+ }
+
private static class ServiceConfig {
private final Set<String> auditExcludedUsers;
private final Set<String> auditExcludedGroups;
diff --git
a/agents-common/src/main/java/org/apache/ranger/plugin/policyengine/RangerPolicyEngineOptions.java
b/agents-common/src/main/java/org/apache/ranger/plugin/policyengine/RangerPolicyEngineOptions.java
index bf9385720..a222eefef 100644
---
a/agents-common/src/main/java/org/apache/ranger/plugin/policyengine/RangerPolicyEngineOptions.java
+++
b/agents-common/src/main/java/org/apache/ranger/plugin/policyengine/RangerPolicyEngineOptions.java
@@ -69,6 +69,12 @@ public class RangerPolicyEngineOptions {
this.optimizeTagTrieForSpace = other.optimizeTagTrieForSpace;
}
+ public RangerPolicyEngineOptions(final RangerPolicyEngineOptions other,
RangerServiceDefHelper serviceDefHelper) {
+ this(other);
+
+ this.serviceDefHelper = serviceDefHelper;
+ }
+
public void configureForPlugin(Configuration conf, String
propertyPrefix) {
disableContextEnrichers = conf.getBoolean(propertyPrefix +
".policyengine.option.disable.context.enrichers", false);
disableCustomConditions = conf.getBoolean(propertyPrefix +
".policyengine.option.disable.custom.conditions", false);
diff --git
a/agents-common/src/main/java/org/apache/ranger/plugin/policyengine/gds/GdsAccessResult.java
b/agents-common/src/main/java/org/apache/ranger/plugin/policyengine/gds/GdsAccessResult.java
new file mode 100644
index 000000000..2d0ec0379
--- /dev/null
+++
b/agents-common/src/main/java/org/apache/ranger/plugin/policyengine/gds/GdsAccessResult.java
@@ -0,0 +1,174 @@
+/*
+ * 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.gds;
+
+
+import java.util.*;
+
+public class GdsAccessResult {
+ private Set<Long> datasets;
+ private Set<Long> projects;
+ private List<String> datasetNames;
+ private List<String> projectNames;
+ private boolean isAllowed;
+ private boolean isAudited;
+ private long policyId = -1;
+ private Long policyVersion;
+
+
+ public GdsAccessResult() {
+ }
+
+ public void addDataset(Long datasetId) {
+ if (datasets == null) {
+ datasets = new HashSet<>();
+ }
+
+ datasets.add(datasetId);
+ }
+
+ public boolean hasDataset(Long datasetId) {
+ return datasets != null && datasets.contains(datasetId);
+ }
+
+ public Set<Long> getDatasets() {
+ return datasets;
+ }
+
+ public void addDatasetName(String name) {
+ if (datasetNames == null) {
+ datasetNames = datasets == null ? new ArrayList<>() : new
ArrayList<>(datasets.size());
+ }
+
+ datasetNames.add(name);
+ }
+
+ public List<String> getDatasetNames() {
+ return datasetNames;
+ }
+
+ public void addProject(Long projectId) {
+ if (projects == null) {
+ projects = new HashSet<>();
+ }
+
+ projects.add(projectId);
+ }
+
+ public boolean hasProject(Long projectId) {
+ return projects != null && projects.contains(projectId);
+ }
+
+ public Set<Long> getProjects() {
+ return projects;
+ }
+
+ public void addProjectName(String name) {
+ if (projectNames == null) {
+ projectNames = projects == null ? new ArrayList<>() : new
ArrayList<>(projects.size());
+ }
+
+ projectNames.add(name);
+ }
+
+ public List<String> getProjectNames() {
+ return projectNames;
+ }
+
+ public boolean getIsAllowed() {
+ return isAllowed;
+ }
+
+ public void setIsAllowed(boolean allowed) {
+ isAllowed = allowed;
+ }
+
+ public boolean getIsAudited() {
+ return isAudited;
+ }
+
+ public void setIsAudited(boolean audited) {
+ isAudited = audited;
+ }
+
+ public long getPolicyId() {
+ return policyId;
+ }
+
+ public void setPolicyId(long policyId) {
+ this.policyId = policyId;
+ }
+
+ public Long getPolicyVersion() {
+ return policyVersion;
+ }
+
+ public void setPolicyVersion(Long policyVersion) {
+ this.policyVersion = policyVersion;
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(datasets, projects, datasetNames, projectNames,
isAllowed, isAudited, policyId, policyVersion);
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (obj == this) {
+ return true;
+ } else if ((obj == null) || !obj.getClass().equals(getClass())) {
+ return false;
+ } else {
+ GdsAccessResult other = (GdsAccessResult) obj;
+
+ return Objects.equals(datasets, other.datasets) &&
+ Objects.equals(projects, other.projects) &&
+ Objects.equals(datasetNames, other.datasetNames) &&
+ Objects.equals(projectNames, other.projectNames) &&
+ Objects.equals(isAllowed, other.isAllowed) &&
+ Objects.equals(isAudited, other.isAudited) &&
+ Objects.equals(policyId, other.policyId) &&
+ Objects.equals(policyVersion, other.policyVersion);
+ }
+ }
+
+ @Override
+ public String toString( ) {
+ StringBuilder sb = new StringBuilder();
+
+ toString(sb);
+
+ return sb.toString();
+ }
+
+ public StringBuilder toString(StringBuilder sb) {
+ sb.append("RangerGdsAccessResult={");
+ sb.append("datasets={").append(datasets).append("}");
+ sb.append(", projects={").append(projects).append("}");
+ sb.append(", datasetNames={").append(datasetNames).append("}");
+ sb.append(", projectNames={").append(projectNames).append("}");
+ sb.append(", isAllowed={").append(isAllowed).append("}");
+ sb.append(", isAudited={").append(isAudited).append("}");
+ sb.append(", policyId={").append(policyId).append("}");
+ sb.append(", policyVersion={").append(policyVersion).append("}");
+ sb.append("}");
+
+ return sb;
+ }
+}
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
new file mode 100644
index 000000000..198907855
--- /dev/null
+++
b/agents-common/src/main/java/org/apache/ranger/plugin/policyengine/gds/GdsDataShareEvaluator.java
@@ -0,0 +1,164 @@
+/*
+ * 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.gds;
+
+import org.apache.commons.lang.StringUtils;
+import org.apache.ranger.plugin.conditionevaluator.RangerConditionEvaluator;
+import org.apache.ranger.plugin.model.RangerServiceDef;
+import org.apache.ranger.plugin.model.validation.RangerServiceDefHelper;
+import org.apache.ranger.plugin.policyengine.RangerAccessRequest;
+import org.apache.ranger.plugin.policyengine.RangerResourceTrie;
+import org.apache.ranger.plugin.policyevaluator.RangerCustomConditionEvaluator;
+import org.apache.ranger.plugin.policyresourcematcher.RangerResourceEvaluator;
+import org.apache.ranger.plugin.util.RangerResourceEvaluatorsRetriever;
+import org.apache.ranger.plugin.util.ServiceGdsInfo.DataShareInfo;
+import org.apache.ranger.plugin.util.ServiceGdsInfo.SharedResourceInfo;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.*;
+
+public class GdsDataShareEvaluator {
+ private static final Logger LOG =
LoggerFactory.getLogger(GdsDataShareEvaluator.class);
+
+ public static final GdsDataShareEvalOrderComparator EVAL_ORDER_COMPARATOR
= new GdsDataShareEvalOrderComparator();
+
+ private final DataShareInfo
dsh;
+ private final String
name;
+ private final String
zoneName;
+ private final Map<String, RangerResourceTrie<GdsSharedResourceEvaluator>>
resourceTries = new HashMap<>();
+ private final List<GdsDshidEvaluator>
dsidEvaluators = new ArrayList<>();
+ private final RangerConditionEvaluator
conditionEvaluator;
+
+ public GdsDataShareEvaluator(DataShareInfo dsh, List<SharedResourceInfo>
resources, RangerServiceDefHelper serviceDefHelper) {
+ LOG.debug("==> GdsDataShareEvaluator({}, {})", dsh, resources);
+
+ this.dsh = dsh;
+ this.name = StringUtils.isBlank(dsh.getName()) ?
StringUtils.EMPTY : dsh.getName();
+ this.zoneName = StringUtils.isBlank(dsh.getZoneName()) ?
StringUtils.EMPTY : dsh.getZoneName();
+ this.conditionEvaluator =
RangerCustomConditionEvaluator.getInstance().getExpressionEvaluator(dsh.getConditionExpr(),
serviceDefHelper.getServiceDef());
+
+ if (resources != null) {
+ Set<String> resourceKeys = new HashSet<>();
+ List<RangerResourceEvaluator> evaluators = new
ArrayList<>(resources.size());
+
+ for (SharedResourceInfo resource : resources) {
+ GdsSharedResourceEvaluator evaluator = new
GdsSharedResourceEvaluator(resource, dsh.getDefaultAccessTypes(),
serviceDefHelper);
+
+ evaluators.add(evaluator);
+
+ resourceKeys.addAll(evaluator.getResourceKeys());
+ }
+
+ for (String resourceKey : resourceKeys) {
+ RangerServiceDef.RangerResourceDef resourceDef =
serviceDefHelper.getResourceDef(resourceKey);
+ RangerResourceTrie resourceTrie = new
RangerResourceTrie<>(resourceDef, evaluators);
+
+ resourceTries.put(resourceKey, resourceTrie);
+ }
+ }
+
+ LOG.debug("<== GdsDataShareEvaluator({}, {})", dsh, resources);
+ }
+
+ public Long getId() {
+ return dsh.getId();
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public String getZoneName() {
+ return zoneName;
+ }
+
+ public void addDshidEvaluator(GdsDshidEvaluator dhidEvaluator) {
+ dsidEvaluators.add(dhidEvaluator);
+ }
+
+ public void evaluate(RangerAccessRequest request, GdsAccessResult result) {
+ LOG.debug("==> GdsDataShareEvaluator.evaluate({}, {})", request,
result);
+
+ Collection<GdsSharedResourceEvaluator> evaluators =
RangerResourceEvaluatorsRetriever.getEvaluators(resourceTries,
request.getResource().getAsMap(), request.getResourceElementMatchingScopes());
+
+ if (evaluators == null) {
+ evaluators = Collections.emptyList();
+ } else if (evaluators.size() > 1) {
+ List<GdsSharedResourceEvaluator> list = new
ArrayList<>(evaluators);
+
+ list.sort(GdsSharedResourceEvaluator.EVAL_ORDER_COMPARATOR);
+
+ evaluators = list;
+ }
+
+ LOG.debug("GdsDataShareEvaluator.evaluate({}): found {} evaluators",
request, evaluators.size());
+
+ if (!evaluators.isEmpty()) {
+ boolean isAllowed = conditionEvaluator == null ||
conditionEvaluator.isMatched(request);
+
+ if (isAllowed) {
+ // find if any of the shared resources allow the request
+ for (GdsSharedResourceEvaluator evaluator : evaluators) {
+ isAllowed = evaluator.isAllowed(request);
+
+ if (isAllowed) {
+ break;
+ }
+ }
+
+ if (isAllowed) { // now find dsidEvaluators that allow the
request and collect their datasetIds
+ for (GdsDshidEvaluator dsidEvaluator : dsidEvaluators) {
+ if (!result.hasDataset(dsidEvaluator.getDatasetId())) {
+ if (dsidEvaluator.isAllowed(request)) {
+
result.addDataset(dsidEvaluator.getDatasetId());
+ }
+ }
+ }
+ }
+ } else {
+ LOG.debug("GdsDataShareEvaluator.evaluate({}): conditions {}
didn't match. Skipped", request, dsh.getConditionExpr());
+ }
+ }
+
+ LOG.debug("<== GdsDataShareEvaluator.evaluate({}, {})", request,
result);
+ }
+
+ public static class GdsDataShareEvalOrderComparator implements
Comparator<GdsDataShareEvaluator> {
+ @Override
+ public int compare(GdsDataShareEvaluator me, GdsDataShareEvaluator
other) {
+ int ret = 0;
+
+ if (me != null && other != null) {
+ ret = me.getName().compareTo(other.dsh.getName());
+
+ if (ret == 0) {
+ ret = me.getId().compareTo(other.getId());
+ }
+ } else if (me != null) {
+ ret = -1;
+ } else if (other != null) {
+ ret = 1;
+ }
+
+ return ret;
+ }
+ }
+}
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
new file mode 100644
index 000000000..1de430def
--- /dev/null
+++
b/agents-common/src/main/java/org/apache/ranger/plugin/policyengine/gds/GdsDatasetEvaluator.java
@@ -0,0 +1,175 @@
+/*
+ * 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.gds;
+
+import org.apache.commons.lang.StringUtils;
+import org.apache.ranger.plugin.model.RangerPolicy;
+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.util.ServiceGdsInfo.DatasetInfo;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.List;
+
+public class GdsDatasetEvaluator {
+ private static final Logger LOG =
LoggerFactory.getLogger(GdsDatasetEvaluator.class);
+
+ public static final GdsDatasetEvalOrderComparator EVAL_ORDER_COMPARATOR =
new GdsDatasetEvalOrderComparator();
+
+
+ private final DatasetInfo dataset;
+ private final String name;
+ private final List<GdsDipEvaluator> dipEvaluators = new
ArrayList<>();
+ private final List<RangerPolicyEvaluator> policyEvaluators;
+
+
+ public GdsDatasetEvaluator(DatasetInfo dataset, RangerServiceDef
gdsServiceDef, RangerPolicyEngineOptions options) {
+ LOG.debug("==> GdsDatasetEvaluator()");
+
+ this.dataset = dataset;
+ this.name = StringUtils.isBlank(dataset.getName()) ?
StringUtils.EMPTY : dataset.getName();
+
+ if (dataset.getPolicies() != null) {
+ policyEvaluators = new ArrayList<>(dataset.getPolicies().size());
+
+ for (RangerPolicy policy : dataset.getPolicies()) {
+ RangerPolicyEvaluator evaluator = new
RangerOptimizedPolicyEvaluator();
+
+ evaluator.init(policy, gdsServiceDef, options);
+
+ policyEvaluators.add(evaluator);
+ }
+ } else {
+ policyEvaluators = Collections.emptyList();
+ }
+
+ LOG.debug("<== GdsDatasetEvaluator()");
+ }
+
+ public Long getId() {
+ return dataset.getId();
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public void addDipEvaluator(GdsDipEvaluator dipEvaluator) {
+ dipEvaluators.add(dipEvaluator);
+ }
+
+ public void evaluate(RangerAccessRequest request, GdsAccessResult result,
RangerServiceDef gdsServiceDef) {
+ LOG.debug("==> GdsDatasetEvaluator.evaluate({}, {})", request, result);
+
+ result.addDatasetName(getName());
+
+ if (!policyEvaluators.isEmpty()) {
+ GdsDatasetAccessRequest datasetRequest = new
GdsDatasetAccessRequest(getId(), gdsServiceDef, request);
+ RangerAccessResult datasetResult =
datasetRequest.createAccessResult();
+
+ for (RangerPolicyEvaluator policyEvaluator : policyEvaluators) {
+ policyEvaluator.evaluate(datasetRequest, datasetResult);
+ }
+
+ if (!result.getIsAllowed()) {
+ if (datasetResult.getIsAllowed()) {
+ result.setIsAllowed(true);
+ result.setPolicyId(datasetResult.getPolicyId());
+ result.setPolicyVersion(datasetResult.getPolicyVersion());
+ }
+ }
+
+ if (!result.getIsAudited()) {
+ result.setIsAudited(datasetResult.getIsAudited());
+ }
+ }
+
+ for (GdsDipEvaluator dipEvaluator : dipEvaluators) {
+ if (!result.hasProject(dipEvaluator.getProjectId())) {
+ if (dipEvaluator.isAllowed(request)) {
+ result.addProject(dipEvaluator.getProjectId());
+ }
+ }
+ }
+
+ LOG.debug("<== GdsDatasetEvaluator.evaluate({}, {})", request, result);
+ }
+
+
+ public static class GdsDatasetAccessRequest extends
RangerAccessRequestImpl {
+ public GdsDatasetAccessRequest(Long datasetId, RangerServiceDef
gdsServiceDef, RangerAccessRequest request) {
+ super.setResource(new RangerDatasetResource(datasetId,
gdsServiceDef, request.getResource().getOwnerUser()));
+
+ super.setUser(request.getUser());
+ super.setUserGroups(request.getUserGroups());
+ super.setUserRoles(request.getUserRoles());
+ super.setAction(request.getAction());
+ super.setAccessType(request.getAccessType());
+ super.setAccessTime(request.getAccessTime());
+ super.setRequestData(request.getRequestData());
+ super.setContext(request.getContext());
+ super.setClientType(request.getClientType());
+ super.setClientIPAddress(request.getClientIPAddress());
+ super.setRemoteIPAddress(request.getRemoteIPAddress());
+ super.setForwardedAddresses(request.getForwardedAddresses());
+ super.setSessionId(request.getSessionId());
+ super.setResourceMatchingScope(request.getResourceMatchingScope());
+ }
+
+ public RangerAccessResult createAccessResult() {
+ return new RangerAccessResult(RangerPolicy.POLICY_TYPE_ACCESS,
GdsPolicyEngine.GDS_SERVICE_NAME, getResource().getServiceDef(), this);
+ }
+ }
+
+ public static class RangerDatasetResource extends RangerAccessResourceImpl
{
+ public RangerDatasetResource(Long datasetd, RangerServiceDef
gdsServiceDef, String ownerUser) {
+ super.setValue(GdsPolicyEngine.RESOURCE_NAME_DATASET_ID,
datasetd.toString());
+ super.setServiceDef(gdsServiceDef);
+ super.setOwnerUser(ownerUser);
+ }
+ }
+
+ public static class GdsDatasetEvalOrderComparator implements
Comparator<GdsDatasetEvaluator> {
+ @Override
+ public int compare(GdsDatasetEvaluator me, GdsDatasetEvaluator other) {
+ int ret = 0;
+
+ if (me != null && other != null) {
+ ret = me.getName().compareTo(other.getName());
+
+ if (ret == 0) {
+ ret = me.getId().compareTo(other.getId());
+ }
+ } else if (me != null) {
+ ret = -1;
+ } else if (other != null) {
+ ret = 1;
+ }
+
+ return ret;
+ }
+ }
+}
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
new file mode 100644
index 000000000..2198eadf1
--- /dev/null
+++
b/agents-common/src/main/java/org/apache/ranger/plugin/policyengine/gds/GdsDipEvaluator.java
@@ -0,0 +1,69 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.ranger.plugin.policyengine.gds;
+
+import org.apache.ranger.plugin.model.RangerGds;
+import org.apache.ranger.plugin.policyengine.RangerAccessRequest;
+import
org.apache.ranger.plugin.policyevaluator.RangerValidityScheduleEvaluator;
+import org.apache.ranger.plugin.util.ServiceGdsInfo.DatasetInProjectInfo;
+
+public class GdsDipEvaluator {
+ private final DatasetInProjectInfo dip;
+ private final RangerValidityScheduleEvaluator scheduleEvaluator;
+
+ public GdsDipEvaluator(DatasetInProjectInfo dip) {
+ this.dip = dip;
+
+ if (dip.getValiditySchedule() != null) {
+ scheduleEvaluator = new
RangerValidityScheduleEvaluator(dip.getValiditySchedule());
+ } else {
+ scheduleEvaluator = null;
+ }
+ }
+
+ public long getDatasetId() {
+ return dip.getDatasetId();
+ }
+
+ public long getProjectId() {
+ return dip.getProjectId();
+ }
+
+ public boolean isAllowed(RangerAccessRequest request) {
+ boolean ret = isActive();
+
+ if (ret) {
+ // TODO:
+ }
+
+ return ret;
+ }
+
+
+ private boolean isActive() {
+ boolean ret = dip.getStatus() == RangerGds.GdsShareStatus.ACTIVE;
+
+ if (ret && scheduleEvaluator != null) {
+ ret = scheduleEvaluator.isApplicable(System.currentTimeMillis());
+ }
+
+ return ret;
+ }
+}
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
new file mode 100644
index 000000000..97bb06b2e
--- /dev/null
+++
b/agents-common/src/main/java/org/apache/ranger/plugin/policyengine/gds/GdsDshidEvaluator.java
@@ -0,0 +1,69 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.ranger.plugin.policyengine.gds;
+
+import org.apache.ranger.plugin.model.RangerGds;
+import org.apache.ranger.plugin.policyengine.RangerAccessRequest;
+import
org.apache.ranger.plugin.policyevaluator.RangerValidityScheduleEvaluator;
+import org.apache.ranger.plugin.util.ServiceGdsInfo.DataShareInDatasetInfo;
+
+public class GdsDshidEvaluator {
+ private final DataShareInDatasetInfo dshid;
+ private final RangerValidityScheduleEvaluator scheduleEvaluator;
+
+ public GdsDshidEvaluator(DataShareInDatasetInfo dshid) {
+ this.dshid = dshid;
+
+ if (dshid.getValiditySchedule() != null) {
+ scheduleEvaluator = new
RangerValidityScheduleEvaluator(dshid.getValiditySchedule());
+ } else {
+ scheduleEvaluator = null;
+ }
+ }
+
+ public long getDataShareId() {
+ return dshid.getDataShareId();
+ }
+
+ public long getDatasetId() {
+ return dshid.getDatasetId();
+ }
+
+ public boolean isAllowed(RangerAccessRequest request) {
+ boolean ret = isActive();
+
+ if (ret) {
+ // TODO:
+ }
+
+ return ret;
+ }
+
+
+ private boolean isActive() {
+ boolean ret = dshid.getStatus() == RangerGds.GdsShareStatus.ACTIVE;
+
+ if (ret && scheduleEvaluator != null) {
+ ret = scheduleEvaluator.isApplicable(System.currentTimeMillis());
+ }
+
+ return ret;
+ }
+}
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
new file mode 100644
index 000000000..64be44893
--- /dev/null
+++
b/agents-common/src/main/java/org/apache/ranger/plugin/policyengine/gds/GdsPolicyEngine.java
@@ -0,0 +1,298 @@
+/*
+ * 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.gds;
+
+import org.apache.commons.collections.CollectionUtils;
+import org.apache.commons.lang.StringUtils;
+import org.apache.ranger.plugin.model.RangerGds;
+import org.apache.ranger.plugin.model.RangerServiceDef;
+import org.apache.ranger.plugin.model.RangerServiceDef.RangerAccessTypeDef;
+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.util.RangerAccessRequestUtil;
+import org.apache.ranger.plugin.util.ServiceGdsInfo;
+import org.apache.ranger.plugin.util.ServiceGdsInfo.DatasetInfo;
+import org.apache.ranger.plugin.util.ServiceGdsInfo.DatasetInProjectInfo;
+import org.apache.ranger.plugin.util.ServiceGdsInfo.DataShareInDatasetInfo;
+import org.apache.ranger.plugin.util.ServiceGdsInfo.DataShareInfo;
+import org.apache.ranger.plugin.util.ServiceGdsInfo.ProjectInfo;
+import org.apache.ranger.plugin.util.ServiceGdsInfo.SharedResourceInfo;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.*;
+
+
+public class GdsPolicyEngine {
+ private static final Logger LOG =
LoggerFactory.getLogger(GdsPolicyEngine.class);
+
+ public static final String GDS_SERVICE_NAME = "_gds";
+ public static final String RESOURCE_NAME_DATASET_ID = "dataset-id";
+ public static final String RESOURCE_NAME_PROJECT_ID = "project-id";
+
+ private final ServiceGdsInfo gdsInfo;
+ private final Map<String, List<GdsDataShareEvaluator>> zoneDataShares =
new HashMap<>();
+ private final Map<Long, GdsDatasetEvaluator> datasets =
new HashMap<>();
+ private final Map<Long, GdsProjectEvaluator> projects =
new HashMap<>();
+
+ public GdsPolicyEngine(ServiceGdsInfo gdsInfo, RangerServiceDefHelper
serviceDefHelper, RangerPluginContext pluginContext) {
+ LOG.debug("==> RangerGdsPolicyEngine()");
+
+ this.gdsInfo = gdsInfo;
+
+ init(serviceDefHelper, pluginContext);
+
+ LOG.debug("<== RangerGdsPolicyEngine()");
+ }
+
+ public GdsAccessResult evaluate(RangerAccessRequest request) {
+ LOG.debug("==> RangerGdsPolicyEngine.evaluate({})", request);;
+
+ GdsAccessResult ret = null;
+ List<GdsDataShareEvaluator> dataShares =
getDataShareEvaluators(request);
+
+ if (!dataShares.isEmpty()) {
+ ret = new GdsAccessResult();
+
+ if (dataShares.size() > 1) {
+ dataShares.sort(GdsDataShareEvaluator.EVAL_ORDER_COMPARATOR);
+ }
+
+ for (GdsDataShareEvaluator dshEvaluator : dataShares) {
+ dshEvaluator.evaluate(request, ret);
+ }
+
+ evaluateDatasetPolicies(ret.getDatasets(), request, ret);
+ evaluateProjectPolicies(ret.getProjects(), request, ret);
+ }
+
+ LOG.debug("<== RangerGdsPolicyEngine.evaluate({}): {}", request, ret);
+
+ return ret;
+ }
+
+ private void init(RangerServiceDefHelper serviceDefHelper,
RangerPluginContext pluginContext) {
+ LOG.debug("==> RangerGdsPolicyEngine.init()");
+
+ preprocessGdsServiceDef(gdsInfo.getGdsServiceDef(), serviceDefHelper);
+
+ RangerServiceDef gdsServiceDef =
gdsInfo.getGdsServiceDef();
+ RangerPolicyEngineOptions options = new
RangerPolicyEngineOptions(pluginContext.getConfig().getPolicyEngineOptions(),
new RangerServiceDefHelper(gdsServiceDef, false));
+ Map<Long, List<SharedResourceInfo>> dshResources = new HashMap<>();
+ Map<Long, GdsDataShareEvaluator> dshEvaluators = new HashMap<>();
+
+ if (gdsInfo.getProjects() != null) {
+ for (ProjectInfo projectInfo : gdsInfo.getProjects()) {
+ projects.put(projectInfo.getId(), new
GdsProjectEvaluator(projectInfo, gdsServiceDef, options));
+ }
+ }
+
+ if (gdsInfo.getDatasets() != null) {
+ for (DatasetInfo datasetInfo : gdsInfo.getDatasets()) {
+ datasets.put(datasetInfo.getId(), new
GdsDatasetEvaluator(datasetInfo, gdsServiceDef, options));
+ }
+ }
+
+ // dshResources must be populated before processing dataShares; hence
resources should be processed before dataShares
+ if (gdsInfo.getResources() != null) {
+ for (SharedResourceInfo resource : gdsInfo.getResources()) {
+ List<SharedResourceInfo> resources =
dshResources.computeIfAbsent(resource.getDataShareId(), k -> new ArrayList<>());
+
+ resources.add(resource);
+ }
+ }
+
+ if (gdsInfo.getDataShares() != null) {
+ for (DataShareInfo dsh : gdsInfo.getDataShares()) {
+ GdsDataShareEvaluator dshEvaluator = new
GdsDataShareEvaluator(dsh, dshResources.get(dsh.getId()), serviceDefHelper);
+ List<GdsDataShareEvaluator> zoneEvaluators =
zoneDataShares.computeIfAbsent(dshEvaluator.getZoneName(), k -> new
ArrayList<>());
+
+ zoneEvaluators.add(dshEvaluator);
+ dshEvaluators.put(dsh.getId(), dshEvaluator);
+ }
+ }
+
+ if (gdsInfo.getDshids() != null) {
+ for (DataShareInDatasetInfo dshid : gdsInfo.getDshids()) {
+ if (dshid.getStatus() != RangerGds.GdsShareStatus.ACTIVE) {
+ LOG.error("RangerGdsPolicyEngine(): dshid is not active
{}. Ignored", dshid);
+
+ continue;
+ }
+
+ GdsDataShareEvaluator dshEvaluator =
dshEvaluators.get(dshid.getDataShareId());
+
+ if (dshEvaluator == null) {
+ LOG.error("RangerGdsPolicyEngine(): invalid dataShareId in
dshid: {}. Ignored", dshid);
+
+ continue;
+ }
+
+ GdsDshidEvaluator dshidEvaluator = new
GdsDshidEvaluator(dshid);
+
+ dshEvaluator.addDshidEvaluator(dshidEvaluator);
+ }
+ }
+
+ if (gdsInfo.getDips() != null) {
+ for (DatasetInProjectInfo dip : gdsInfo.getDips()) {
+ if (dip.getStatus() != RangerGds.GdsShareStatus.ACTIVE) {
+ LOG.error("RangerGdsPolicyEngine(): dip is not active {}.
Ignored", dip);
+
+ continue;
+ }
+
+ GdsDatasetEvaluator datasetEvaluator =
datasets.get(dip.getDatasetId());
+
+ if (datasetEvaluator == null) {
+ LOG.error("RangerGdsPolicyEngine(): invalid datasetId in
dip: {}. Ignored", dip);
+
+ continue;
+ }
+
+ GdsDipEvaluator dipEvaluator = new GdsDipEvaluator(dip);
+
+ datasetEvaluator.addDipEvaluator(dipEvaluator);
+ }
+ }
+
+ LOG.debug("<== RangerGdsPolicyEngine.init()");
+ }
+
+ private void preprocessGdsServiceDef(RangerServiceDef gdsServiceDef,
RangerServiceDefHelper serviceDefHelper) {
+ // populate accessTypes in GDS servicedef with implied accessTypes
from the service
+ for (RangerAccessTypeDef gdsAccessTypeDef :
gdsServiceDef.getAccessTypes()) {
+ Collection<String> impliedGrants =
serviceDefHelper.getImpliedAccessGrants().get(gdsAccessTypeDef.getName());
+
+ if (impliedGrants != null) {
+ gdsAccessTypeDef.getImpliedGrants().addAll(impliedGrants);
+ }
+ }
+
+
gdsServiceDef.getAccessTypes().addAll(serviceDefHelper.getServiceDef().getAccessTypes());
+ }
+
+ private List<GdsDataShareEvaluator>
getDataShareEvaluators(RangerAccessRequest request) {
+ LOG.debug("==> RangerGdsPolicyEngine.getDataShareEvaluators({})",
request);
+
+ List<GdsDataShareEvaluator> ret = null;
+
+ if (!zoneDataShares.isEmpty()) {
+ Set<String> zoneNames =
RangerAccessRequestUtil.getResourceZoneNamesFromContext(request.getContext());
+
+ if (zoneNames == null || zoneNames.isEmpty()) {
+ zoneNames = Collections.singleton(StringUtils.EMPTY); //
unzoned
+ } else if (zoneNames.size() > 1 && !request.isAccessTypeAny()) {
+ LOG.warn("RangerGdsPolicyEngine.getDataShareEvaluators():
resource matches multiple zones and accessType is not ANY - ignored.
resource={}, zones={}", request.getResource(), zoneNames);
+
+ zoneNames = Collections.emptySet();
+ }
+
+ for (String zoneName : zoneNames) {
+ List<GdsDataShareEvaluator> zonEvaluators =
zoneDataShares.get(zoneName);
+
+ if (zonEvaluators != null && !zonEvaluators.isEmpty()) {
+ if (ret == null) {
+ ret = new ArrayList<>();
+ }
+
+ ret.addAll(zonEvaluators);
+ }
+ }
+ }
+
+ if (ret == null) {
+ ret = Collections.emptyList();
+ }
+
+ LOG.debug("<== RangerGdsPolicyEngine.getDataShareEvaluators({}): {}",
request, ret);
+
+ return ret;
+ }
+
+ private void evaluateDatasetPolicies(Set<Long> datasetIds,
RangerAccessRequest request, GdsAccessResult result) {
+ if (CollectionUtils.isNotEmpty(datasetIds)) {
+ List<GdsDatasetEvaluator> evaluators = new
ArrayList<>(datasetIds.size());
+
+ for (Long datasetId : datasetIds) {
+ GdsDatasetEvaluator evaluator = datasets.get(datasetId);
+
+ if (evaluator == null) {
+ LOG.error("evaluateDatasetPolicies(): invalid datasetId in
result: {}. Ignored", datasetId);
+
+ continue;
+ }
+
+ evaluators.add(evaluator);
+ }
+
+ if (evaluators.size() > 1) {
+ evaluators.sort(GdsDatasetEvaluator.EVAL_ORDER_COMPARATOR);
+ }
+
+ for (GdsDatasetEvaluator evaluator : evaluators) {
+ evaluator.evaluate(request, result,
gdsInfo.getGdsServiceDef());
+ }
+ }
+ }
+
+ private void evaluateProjectPolicies(Set<Long> projectIds,
RangerAccessRequest request, GdsAccessResult result) {
+ if (CollectionUtils.isNotEmpty(projectIds)) {
+ List<GdsProjectEvaluator> evaluators = new
ArrayList<>(projectIds.size());
+
+ for (Long projectId : projectIds) {
+ GdsProjectEvaluator evaluator = projects.get(projectId);
+
+ if (evaluator == null) {
+ LOG.error("evaluateProjectPolicies(): invalid projectId in
result: {}. Ignored", projectId);
+
+ continue;
+ }
+
+ evaluators.add(evaluator);
+ }
+
+ if (evaluators.size() > 1) {
+ evaluators.sort(GdsProjectEvaluator.EVAL_ORDER_COMPARATOR);
+ }
+
+ for (GdsProjectEvaluator evaluator : evaluators) {
+ evaluator.evaluate(request, result,
gdsInfo.getGdsServiceDef());
+ }
+ }
+ }
+}
+
+/*
+ sharedRes-1--\
+ |-- dataShare-1------- dataset-1--\
+ sharedRes-2--/ / \
+ / \_____ project-1
+ sharedRes-3------ dataShare-2---\ /
+ \___ dataset-2---/
+ /
+ sharedRes-4------ dataShare-3------/
+
+ sharedRes-5------ dataShare-4-------- dataset-3 --------- project-2
+
+ sharedRes-6------ dataShare-5-------- dataset-4
+ */
\ No newline at end of file
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
new file mode 100644
index 000000000..d5ce0e904
--- /dev/null
+++
b/agents-common/src/main/java/org/apache/ranger/plugin/policyengine/gds/GdsProjectEvaluator.java
@@ -0,0 +1,160 @@
+/*
+ * 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.gds;
+
+import org.apache.commons.lang.StringUtils;
+import org.apache.ranger.plugin.model.RangerPolicy;
+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.util.ServiceGdsInfo.ProjectInfo;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.List;
+
+public class GdsProjectEvaluator {
+ private static final Logger LOG =
LoggerFactory.getLogger(GdsDatasetEvaluator.class);
+
+ public static final GdsProjectEvalOrderComparator EVAL_ORDER_COMPARATOR =
new GdsProjectEvalOrderComparator();
+
+ private final ProjectInfo project;
+ private final String name;
+ private final List<RangerPolicyEvaluator> policyEvaluators;
+
+ public GdsProjectEvaluator(ProjectInfo project, RangerServiceDef
gdsServiceDef, RangerPolicyEngineOptions options) {
+ LOG.debug("==> GdsProjectEvaluator({})", project);
+
+ this.project = project;
+ this.name = StringUtils.isBlank(project.getName()) ?
StringUtils.EMPTY : project.getName();
+
+ if (project.getPolicies() != null) {
+ policyEvaluators = new ArrayList<>(project.getPolicies().size());
+
+ for (RangerPolicy policy : project.getPolicies()) {
+ RangerPolicyEvaluator evaluator = new
RangerOptimizedPolicyEvaluator();
+
+ evaluator.init(policy, gdsServiceDef, options);
+
+ policyEvaluators.add(evaluator);
+ }
+ } else {
+ policyEvaluators = Collections.emptyList();
+ }
+
+ LOG.debug("<== GdsProjectEvaluator({})", project);
+ }
+
+ public Long getId() {
+ return project.getId();
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public void evaluate(RangerAccessRequest request, GdsAccessResult result,
RangerServiceDef gdsServiceDef) {
+ LOG.debug("==> GdsDatasetEvaluator.evaluate({}, {})", request, result);
+
+ result.addProjectName(getName());
+
+ if (!policyEvaluators.isEmpty()) {
+ GdsProjectAccessRequest projectRequest = new
GdsProjectAccessRequest(getId(), gdsServiceDef, request);
+ RangerAccessResult projectResult =
projectRequest.createAccessResult();
+
+ for (RangerPolicyEvaluator policyEvaluator : policyEvaluators) {
+ policyEvaluator.evaluate(projectRequest, projectResult);
+ }
+
+ if (!result.getIsAllowed()) {
+ if (projectResult.getIsAllowed()) {
+ result.setIsAllowed(true);
+ result.setPolicyId(projectResult.getPolicyId());
+ result.setPolicyVersion(projectResult.getPolicyVersion());
+ }
+ }
+
+ if (!result.getIsAudited()) {
+ result.setIsAudited(projectResult.getIsAudited());
+ }
+ }
+
+ LOG.debug("<== GdsDatasetEvaluator.evaluate({}, {})", request, result);
+ }
+
+
+ public static class GdsProjectAccessRequest extends
RangerAccessRequestImpl {
+ public GdsProjectAccessRequest(Long projectId, RangerServiceDef
gdsServiceDef, RangerAccessRequest request) {
+ super.setResource(new RangerProjectResource(projectId,
gdsServiceDef, request.getResource().getOwnerUser()));
+
+ super.setUser(request.getUser());
+ super.setUserGroups(request.getUserGroups());
+ super.setUserRoles(request.getUserRoles());
+ super.setAction(request.getAction());
+ super.setAccessType(request.getAccessType());
+ super.setAccessTime(request.getAccessTime());
+ super.setRequestData(request.getRequestData());
+ super.setContext(request.getContext());
+ super.setClientType(request.getClientType());
+ super.setClientIPAddress(request.getClientIPAddress());
+ super.setRemoteIPAddress(request.getRemoteIPAddress());
+ super.setForwardedAddresses(request.getForwardedAddresses());
+ super.setSessionId(request.getSessionId());
+ super.setResourceMatchingScope(request.getResourceMatchingScope());
+ }
+
+ public RangerAccessResult createAccessResult() {
+ return new RangerAccessResult(RangerPolicy.POLICY_TYPE_ACCESS,
GdsPolicyEngine.GDS_SERVICE_NAME, getResource().getServiceDef(), this);
+ }
+ }
+
+ public static class RangerProjectResource extends RangerAccessResourceImpl
{
+ public RangerProjectResource(Long projectd, RangerServiceDef
gdsServiceDef, String ownerUser) {
+ super.setValue(GdsPolicyEngine.RESOURCE_NAME_PROJECT_ID,
projectd.toString());
+ super.setServiceDef(gdsServiceDef);
+ super.setOwnerUser(ownerUser);
+ }
+ }
+
+ public static class GdsProjectEvalOrderComparator implements
Comparator<GdsProjectEvaluator> {
+ @Override
+ public int compare(GdsProjectEvaluator me, GdsProjectEvaluator other) {
+ int ret = 0;
+
+ if (me != null && other != null) {
+ ret = me.getName().compareTo(other.getName());
+
+ if (ret == 0) {
+ ret = me.getId().compareTo(other.getId());
+ }
+ } else if (me != null) {
+ ret = -1;
+ } else if (other != null) {
+ ret = 1;
+ }
+
+ return ret;
+ }
+ }
+}
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
new file mode 100644
index 000000000..33a9e44fa
--- /dev/null
+++
b/agents-common/src/main/java/org/apache/ranger/plugin/policyengine/gds/GdsSharedResourceEvaluator.java
@@ -0,0 +1,179 @@
+/*
+ * 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.gds;
+
+import org.apache.commons.collections.CollectionUtils;
+import org.apache.commons.lang3.StringUtils;
+import org.apache.ranger.plugin.conditionevaluator.RangerConditionEvaluator;
+import org.apache.ranger.plugin.model.RangerPolicy;
+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.RangerServiceDef.RangerResourceDef;
+import org.apache.ranger.plugin.model.validation.RangerServiceDefHelper;
+import org.apache.ranger.plugin.policyengine.RangerAccessRequest;
+import org.apache.ranger.plugin.policyevaluator.RangerCustomConditionEvaluator;
+import
org.apache.ranger.plugin.policyresourcematcher.RangerDefaultPolicyResourceMatcher;
+import
org.apache.ranger.plugin.policyresourcematcher.RangerPolicyResourceMatcher;
+import org.apache.ranger.plugin.policyresourcematcher.RangerResourceEvaluator;
+import org.apache.ranger.plugin.resourcematcher.RangerResourceMatcher;
+import org.apache.ranger.plugin.util.ServiceDefUtil;
+import org.apache.ranger.plugin.util.ServiceGdsInfo.SharedResourceInfo;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.*;
+
+public class GdsSharedResourceEvaluator implements RangerResourceEvaluator {
+ private static final Logger LOG =
LoggerFactory.getLogger(GdsSharedResourceEvaluator.class);
+
+ public static final GdsSharedResourceEvalOrderComparator
EVAL_ORDER_COMPARATOR = new GdsSharedResourceEvalOrderComparator();
+
+ private final SharedResourceInfo resource;
+ private final RangerConditionEvaluator conditionEvaluator;
+ private final Map<String, RangerPolicyResource> policyResource;
+ private final RangerPolicyResourceMatcher policyResourceMatcher;
+ private final RangerResourceDef leafResourceDef;
+ private final Set<String> allowedAccessTypes;
+
+ public GdsSharedResourceEvaluator(SharedResourceInfo resource, Set<String>
defaultAccessTypes, RangerServiceDefHelper serviceDefHelper) {
+ this.resource = resource;
+ this.conditionEvaluator =
RangerCustomConditionEvaluator.getInstance().getExpressionEvaluator(resource.getConditionExpr(),
serviceDefHelper.getServiceDef());
+
+ if (this.resource.getResource() == null) {
+ this.resource.setResource(Collections.emptyMap());
+ }
+
+ if (StringUtils.isNotBlank(resource.getSubResourceType()) &&
resource.getSubResource() != null &&
CollectionUtils.isNotEmpty(resource.getSubResource().getValues())) {
+ this.policyResource = new HashMap<>(resource.getResource());
+
+ this.policyResource.put(resource.getSubResourceType(),
resource.getSubResource());
+ } else {
+ this.policyResource = resource.getResource();
+ }
+
+ this.policyResourceMatcher = initPolicyResourceMatcher(policyResource,
serviceDefHelper);
+ this.leafResourceDef =
ServiceDefUtil.getLeafResourceDef(serviceDefHelper.getServiceDef(),
policyResource);
+ this.allowedAccessTypes =
serviceDefHelper.expandImpliedAccessGrants(resource.getAccessTypes() != null ?
resource.getAccessTypes() : defaultAccessTypes);
+
+ LOG.debug("GdsSharedResourceEvaluator: resource={},
conditionEvaluator={}, policyResource={}, leafResourceDef={},
allowedAccessTypes={}",
+ resource, conditionEvaluator, policyResource,
leafResourceDef, allowedAccessTypes);
+ }
+
+ @Override
+ public long getId() {
+ return resource.getId();
+ }
+
+ @Override
+ public RangerPolicyResourceMatcher getPolicyResourceMatcher() {
+ return policyResourceMatcher;
+ }
+
+ @Override
+ public Map<String, RangerPolicyResource> getPolicyResource() {
+ return policyResource;
+ }
+
+ @Override
+ public RangerResourceMatcher getResourceMatcher(String resourceName) {
+ return policyResourceMatcher.getResourceMatcher(resourceName);
+ }
+
+ @Override
+ public boolean isAncestorOf(RangerResourceDef resourceDef) {
+ return
ServiceDefUtil.isAncestorOf(policyResourceMatcher.getServiceDef(),
leafResourceDef, resourceDef);
+ }
+
+ public Collection<String> getResourceKeys() {
+ return resource != null && resource.getResource() != null ?
resource.getResource().keySet() : Collections.emptySet();
+ }
+
+ public boolean isAllowed(RangerAccessRequest request) {
+ LOG.debug("==> GdsSharedResourceEvaluator.evaluate({})", request);
+
+ boolean ret = conditionEvaluator == null ||
conditionEvaluator.isMatched(request);
+
+ if (ret) {
+ ret = request.isAccessTypeAny() ? !allowedAccessTypes.isEmpty() :
allowedAccessTypes.contains(request.getAccessType());
+
+ if (ret) {
+ ret = policyResourceMatcher.isMatch(request.getResource(),
request.getResourceElementMatchingScopes(), request.getContext());
+
+ if (!ret) {
+ LOG.debug("GdsSharedResourceEvaluator.evaluate({}): not
matched for resource {}", request, request.getResource());
+ }
+ } else {
+ LOG.debug("GdsSharedResourceEvaluator.evaluate({}): not
matched for accessType {}", request, request.getAccessType());
+ }
+ } else {
+ LOG.debug("GdsSharedResourceEvaluator.evaluate({}): not matched
for condition {}", request, resource.getConditionExpr());
+ }
+
+ LOG.debug("<== GdsSharedResourceEvaluator.evaluate({})", request);
+
+ return ret;
+ }
+
+ public RangerPolicyItemRowFilterInfo getRowFilter() {
+ return resource.getRowFilter();
+ }
+
+ public RangerPolicyItemDataMaskInfo getDataMask(String subResourceName) {
+ return resource.getSubResourceMasks() != null ?
resource.getSubResourceMasks().get(subResourceName) : null;
+ }
+
+ private static RangerPolicyResourceMatcher
initPolicyResourceMatcher(Map<String, RangerPolicyResource> policyResource,
RangerServiceDefHelper serviceDefHelper) {
+ RangerDefaultPolicyResourceMatcher matcher = new
RangerDefaultPolicyResourceMatcher();
+
+ matcher.setServiceDefHelper(serviceDefHelper);
+ matcher.setServiceDef(serviceDefHelper.getServiceDef());
+ matcher.setPolicyResources(policyResource,
RangerPolicy.POLICY_TYPE_ACCESS);
+
+ matcher.init();
+
+ return matcher;
+ }
+
+ public static class GdsSharedResourceEvalOrderComparator implements
Comparator<GdsSharedResourceEvaluator> {
+ @Override
+ public int compare(GdsSharedResourceEvaluator me,
GdsSharedResourceEvaluator other) {
+ int ret = 0;
+
+ if (me != null && other != null) {
+ ret = StringUtils.compare(me.resource.getName(),
other.resource.getName());
+
+ if (ret == 0) {
+ ret = Integer.compare(me.resource.getResource().size(),
other.resource.getResource().size());
+
+ if (ret == 0) {
+ ret = Long.compare(me.getId(), other.getId());
+ }
+ }
+ } else if (me != null) {
+ ret = -1;
+ } else if (other != null) {
+ ret = 1;
+ }
+
+ return ret;
+ }
+ }
+}
diff --git
a/agents-common/src/main/java/org/apache/ranger/plugin/policyevaluator/RangerCustomConditionEvaluator.java
b/agents-common/src/main/java/org/apache/ranger/plugin/policyevaluator/RangerCustomConditionEvaluator.java
index 271edf97f..511c459a5 100644
---
a/agents-common/src/main/java/org/apache/ranger/plugin/policyevaluator/RangerCustomConditionEvaluator.java
+++
b/agents-common/src/main/java/org/apache/ranger/plugin/policyevaluator/RangerCustomConditionEvaluator.java
@@ -20,6 +20,7 @@
package org.apache.ranger.plugin.policyevaluator;
import org.apache.commons.collections.CollectionUtils;
+import org.apache.commons.lang.StringUtils;
import org.apache.ranger.plugin.conditionevaluator.RangerConditionEvaluator;
import org.apache.ranger.plugin.model.RangerPolicy;
import org.apache.ranger.plugin.model.RangerPolicy.RangerPolicyItemCondition;
@@ -36,6 +37,7 @@ import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
+
//
// this class should have been named RangerConditionEvaluatorFactory
//
@@ -45,6 +47,8 @@ public class RangerCustomConditionEvaluator {
private static final Logger PERF_POLICYITEM_INIT_LOG =
RangerPerfTracer.getPerfLogger("policyitem.init");
private static final Logger PERF_POLICYCONDITION_INIT_LOG =
RangerPerfTracer.getPerfLogger("policycondition.init");
+ private static final RangerPolicyConditionDef EXPRESSION_CONDITION_DEF =
ServiceDefUtil.createImplicitExpressionConditionDef(-1L);
+
public static RangerCustomConditionEvaluator getInstance() {
return RangerCustomConditionEvaluator.SingletonHolder.s_instance;
@@ -141,6 +145,30 @@ public class RangerCustomConditionEvaluator {
return ret;
}
+ public RangerConditionEvaluator getExpressionEvaluator(String expression,
RangerServiceDef serviceDef) {
+ final RangerConditionEvaluator ret;
+
+ if (StringUtils.isNotBlank(expression)) {
+ ret =
newConditionEvaluator(EXPRESSION_CONDITION_DEF.getEvaluator());
+
+ if (ret != null) {
+ ret.setServiceDef(serviceDef);
+ ret.setConditionDef(EXPRESSION_CONDITION_DEF);
+ ret.setPolicyItemCondition(new
RangerPolicyItemCondition(EXPRESSION_CONDITION_DEF.getName(),
Collections.singletonList(expression)));
+
+ RangerPerfTracer perf =
RangerPerfTracer.getPerfTracer(PERF_POLICYCONDITION_INIT_LOG,
"RangerConditionEvaluator.init(_expression)");
+
+ ret.init();
+
+ RangerPerfTracer.log(perf);
+ }
+ } else {
+ ret = null;
+ }
+
+ return ret;
+ }
+
private RangerConditionEvaluator newConditionEvaluator(String className) {
if (LOG.isDebugEnabled()) {
LOG.debug("==>
RangerCustomConditionEvaluator.newConditionEvaluator(" + className + ")");
diff --git
a/agents-common/src/main/java/org/apache/ranger/plugin/util/RangerAccessRequestUtil.java
b/agents-common/src/main/java/org/apache/ranger/plugin/util/RangerAccessRequestUtil.java
index b088ed7ef..92a4fe02e 100644
---
a/agents-common/src/main/java/org/apache/ranger/plugin/util/RangerAccessRequestUtil.java
+++
b/agents-common/src/main/java/org/apache/ranger/plugin/util/RangerAccessRequestUtil.java
@@ -29,6 +29,7 @@ import org.apache.commons.collections.MapUtils;
import org.apache.ranger.plugin.contextenricher.RangerTagForEval;
import org.apache.ranger.plugin.policyengine.RangerAccessRequest;
import org.apache.ranger.plugin.policyengine.RangerAccessResource;
+import org.apache.ranger.plugin.policyengine.gds.GdsAccessResult;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -47,6 +48,7 @@ public class RangerAccessRequestUtil {
public static final String KEY_CONTEXT_ACCESSTYPES = "ACCESSTYPES";
public static final String KEY_CONTEXT_IS_ANY_ACCESS = "ISANYACCESS";
public static final String KEY_CONTEXT_REQUEST = "_REQUEST";
+ public static final String KEY_CONTEXT_GDS_RESULT = "_GDS_RESULT";
public static final String KEY_CONTEXT_IS_REQUEST_PREPROCESSED =
"ISREQUESTPREPROCESSED";
public static final String KEY_CONTEXT_RESOURCE_ZONE_NAMES =
"RESOURCE_ZONE_NAMES";
@@ -134,6 +136,7 @@ public class RangerAccessRequestUtil {
ret.remove(KEY_CONTEXT_RESOURCE);
ret.remove(KEY_CONTEXT_RESOURCE_ZONE_NAMES);
ret.remove(KEY_CONTEXT_REQUEST);
+ ret.remove(KEY_CONTEXT_GDS_RESULT);
ret.remove(KEY_CONTEXT_ACCESSTYPES);
ret.remove(KEY_CONTEXT_IS_ANY_ACCESS);
ret.remove(KEY_CONTEXT_IS_REQUEST_PREPROCESSED);
@@ -259,6 +262,32 @@ public class RangerAccessRequestUtil {
return ret;
}
+ public static void setGdsResultInContext(RangerAccessRequest request,
GdsAccessResult result) {
+ Map<String, Object> context = request.getContext();
+
+ if (context != null) {
+ context.put(KEY_CONTEXT_GDS_RESULT, result);
+ }
+ }
+
+ public static GdsAccessResult getGdsResultFromContext(Map<String,
Object> context) {
+ GdsAccessResult ret = null;
+
+ if (context != null) {
+ Object val = context.get(KEY_CONTEXT_GDS_RESULT);
+
+ if (val != null) {
+ if (val instanceof GdsAccessResult) {
+ ret = (GdsAccessResult) val;
+ } else {
+ LOG.error("getGdsResultFromContext():
expected RangerGdsAccessResult, but found " +
val.getClass().getCanonicalName());
+ }
+ }
+ }
+
+ return ret;
+ }
+
public static void setResourceZoneNamesInContext(RangerAccessRequest
request, Set<String> zoneNames) {
Map<String, Object> context = request.getContext();
diff --git
a/agents-common/src/main/java/org/apache/ranger/plugin/util/ServiceGdsInfo.java
b/agents-common/src/main/java/org/apache/ranger/plugin/util/ServiceGdsInfo.java
index 928807382..40d6fa472 100644
---
a/agents-common/src/main/java/org/apache/ranger/plugin/util/ServiceGdsInfo.java
+++
b/agents-common/src/main/java/org/apache/ranger/plugin/util/ServiceGdsInfo.java
@@ -279,13 +279,12 @@ public class ServiceGdsInfo implements
java.io.Serializable {
public static class DataShareInfo implements java.io.Serializable {
private static final long serialVersionUID = 1L;
- private Long id;
- private String name;
- private String zoneName;
- private String conditionExpr;
- private Set<String> defaultAccessTypes;
- private List<RangerTagDataMaskInfo> defaultTagMasks;
- private List<DataShareInDatasetInfo> datasets;
+ private Long id;
+ private String name;
+ private String zoneName;
+ private String conditionExpr;
+ private Set<String> defaultAccessTypes;
+ private List<RangerTagDataMaskInfo> defaultTagMasks;
public DataShareInfo() {
}
@@ -338,22 +337,6 @@ public class ServiceGdsInfo implements
java.io.Serializable {
this.defaultTagMasks = defaultTagMasks;
}
- public List<DataShareInDatasetInfo> getDatasets() {
- return datasets;
- }
-
- public void setDatasets(List<DataShareInDatasetInfo> datasets) {
- this.datasets = datasets;
- }
-
- public void addDataset(DataShareInDatasetInfo dshInDsInfo) {
- if (datasets == null) {
- datasets = new ArrayList<>();
- }
-
- datasets.add(dshInDsInfo);
- }
-
@Override
public String toString( ) {
return toString(new StringBuilder()).toString();
@@ -383,14 +366,6 @@ public class ServiceGdsInfo implements
java.io.Serializable {
}
sb.append("]");
- sb.append(", datasets=[");
- if (datasets != null) {
- for (DataShareInDatasetInfo dataset : datasets) {
- dataset.toString(sb).append(", ");
- }
- }
- sb.append("]");
-
sb.append("}");
return sb;
@@ -404,6 +379,7 @@ public class ServiceGdsInfo implements java.io.Serializable
{
private static final long serialVersionUID = 1L;
private Long id;
+ private String name;
private Long dataShareId;
private Map<String, RangerPolicyResource> resource;
private RangerPolicyResource subResource;
@@ -422,6 +398,14 @@ public class ServiceGdsInfo implements
java.io.Serializable {
this.id = id;
}
+ public String getName() {
+ return name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
public Long getDataShareId() {
return dataShareId;
}
@@ -502,6 +486,7 @@ public class ServiceGdsInfo implements java.io.Serializable
{
public StringBuilder toString(StringBuilder sb) {
sb.append("SharedResourceInfo={")
.append("id=").append(id)
+ .append(", name=").append(name)
.append(", dataShareId=").append(dataShareId)
.append(", resource=").append(resource)
.append(", subResource=").append(subResource)
@@ -552,10 +537,9 @@ public class ServiceGdsInfo implements
java.io.Serializable {
public static class DatasetInfo implements java.io.Serializable {
private static final long serialVersionUID = 1L;
- private Long id;
- private String name;
- private List<RangerPolicy> policies;
- private List<DatasetInProjectInfo> projects;
+ private Long id;
+ private String name;
+ private List<RangerPolicy> policies;
public DatasetInfo() {
}
@@ -584,22 +568,6 @@ public class ServiceGdsInfo implements
java.io.Serializable {
this.policies = policies;
}
- public List<DatasetInProjectInfo> getProjects() {
- return projects;
- }
-
- public void setProjects(List<DatasetInProjectInfo> projects) {
- this.projects = projects;
- }
-
- public void addProject(DatasetInProjectInfo project) {
- if (projects == null) {
- projects = new ArrayList<>();
- }
-
- projects.add(project);
- }
-
@Override
public String toString( ) {
return toString(new StringBuilder()).toString();
@@ -618,14 +586,6 @@ public class ServiceGdsInfo implements
java.io.Serializable {
}
sb.append("]");
- sb.append(", projects=[");
- if (projects != null) {
- for (DatasetInProjectInfo project : projects) {
- project.toString(sb).append(", ");
- }
- }
- sb.append("]");
-
sb.append("}");
return sb;
diff --git
a/agents-common/src/test/java/org/apache/ranger/plugin/policyengine/TestRangerAuthContext.java
b/agents-common/src/test/java/org/apache/ranger/plugin/policyengine/TestRangerAuthContext.java
index a23765520..f45bc43f6 100644
---
a/agents-common/src/test/java/org/apache/ranger/plugin/policyengine/TestRangerAuthContext.java
+++
b/agents-common/src/test/java/org/apache/ranger/plugin/policyengine/TestRangerAuthContext.java
@@ -31,6 +31,7 @@ import org.apache.commons.collections.MapUtils;
import org.apache.ranger.plugin.contextenricher.RangerContextEnricher;
import org.apache.ranger.plugin.contextenricher.RangerGdsEnricher;
import org.apache.ranger.plugin.contextenricher.RangerTagEnricher;
+import org.apache.ranger.plugin.policyengine.gds.GdsPolicyEngine;
import org.apache.ranger.plugin.service.RangerAuthContext;
import org.apache.ranger.plugin.service.RangerBasePlugin;
import org.apache.ranger.plugin.util.ServicePolicies;
@@ -107,9 +108,9 @@ public class TestRangerAuthContext {
} else if (enricherName.equals("TagEnricher")) {
assertTrue("- Invalid contextEnricher",
(enricherData instanceof RangerTagEnricher || enricherData instanceof
RangerTagEnricher.EnrichedServiceTags));
} else if
(enricherName.equals(IMPLICIT_GDS_ENRICHER_NAME) || enricher instanceof
RangerGdsEnricher) {
- assertTrue("- Invalid contextEnricher",
(enricherData instanceof RangerGdsEnricher || enricherData instanceof
RangerGdsEnricher.EnhancedGdsInfo));
+ assertTrue("- Invalid contextEnricher",
(enricherData instanceof RangerGdsEnricher || enricherData instanceof
GdsPolicyEngine));
} else {
- assertTrue(fileName + "-" + testName +
" - Unexpected type of contextEnricher", false);
+ fail(fileName + "-" + testName + " -
Unexpected type of contextEnricher: " + enricher);
}
}
}
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
new file mode 100644
index 000000000..83bfc99f5
--- /dev/null
+++
b/agents-common/src/test/java/org/apache/ranger/plugin/policyengine/gds/TestGdsPolicyEngine.java
@@ -0,0 +1,131 @@
+/*
+ * 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.gds;
+
+import com.google.gson.*;
+import org.apache.ranger.authorization.hadoop.config.RangerPluginConfig;
+import org.apache.ranger.plugin.model.RangerServiceDef;
+import org.apache.ranger.plugin.model.validation.RangerServiceDefHelper;
+import org.apache.ranger.plugin.policyengine.*;
+import org.apache.ranger.plugin.util.RangerAccessRequestUtil;
+import org.apache.ranger.plugin.util.ServiceDefUtil;
+import org.apache.ranger.plugin.util.ServiceGdsInfo;
+import org.apache.ranger.plugin.util.ServicePolicies.SecurityZoneInfo;
+import org.junit.BeforeClass;
+import org.junit.Test;
+
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.Reader;
+import java.lang.reflect.Type;
+import java.util.*;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
+public class TestGdsPolicyEngine {
+ static Gson gsonBuilder;
+
+ @BeforeClass
+ public static void setUpBeforeClass() throws Exception {
+ gsonBuilder = new GsonBuilder().setDateFormat("yyyyMMdd-HH:mm:ss.SSSZ")
+ .setPrettyPrinting()
+ .registerTypeAdapter(RangerAccessRequest.class, new
RangerAccessRequestDeserializer())
+ .registerTypeAdapter(RangerAccessResource.class, new
RangerResourceDeserializer())
+ .create();
+ }
+
+ @Test
+ public void testGdsPolicyEngineHive() throws Exception {
+
runTestsFromResourceFile("/policyengine/gds/test_gds_policy_engine_hive.json");
+ }
+
+ private void runTestsFromResourceFile(String resourceFile) throws
Exception {
+ InputStream inStream =
this.getClass().getResourceAsStream(resourceFile);
+ InputStreamReader reader = new InputStreamReader(inStream);
+
+ runTests(reader, resourceFile);
+ }
+
+ private void runTests(Reader reader, String testName) {
+ GdsPolicyEngineTestCase testCase = gsonBuilder.fromJson(reader,
GdsPolicyEngineTestCase.class);
+
+ assertTrue("invalid input: " + testName, testCase != null &&
testCase.gdsInfo != null && testCase.tests != null);
+
+
testCase.serviceDef.setMarkerAccessTypes(ServiceDefUtil.getMarkerAccessTypes(testCase.serviceDef.getAccessTypes()));
+
+ RangerPluginContext pluginContext = new RangerPluginContext(new
RangerPluginConfig(testCase.serviceDef.getName(), null, "hive", "cl1",
"on-prem", null));
+ RangerSecurityZoneMatcher zoneMatcher = new
RangerSecurityZoneMatcher(testCase.securityZones, testCase.serviceDef,
pluginContext);
+ GdsPolicyEngine policyEngine = new
GdsPolicyEngine(testCase.gdsInfo, new
RangerServiceDefHelper(testCase.serviceDef, false), pluginContext);
+
+ for (TestData test : testCase.tests) {
+ Set<String> zoneNames =
zoneMatcher.getZonesForResourceAndChildren(test.request.getResource());
+
+
RangerAccessRequestUtil.setResourceZoneNamesInContext(test.request, zoneNames);
+
+ GdsAccessResult result = policyEngine.evaluate(test.request);
+
+ assertEquals(test.name, test.result, result);
+ }
+ }
+
+ static class GdsPolicyEngineTestCase {
+ public RangerServiceDef serviceDef;
+ public Map<String, SecurityZoneInfo> securityZones;
+ public ServiceGdsInfo gdsInfo;
+ public List<TestData> tests;
+ }
+
+ static class TestData {
+ public String name;
+ public RangerAccessRequest request;
+ public GdsAccessResult result;
+ }
+
+ static class RangerAccessRequestDeserializer implements
JsonDeserializer<RangerAccessRequest> {
+ @Override
+ public RangerAccessRequest deserialize(JsonElement jsonObj, Type type,
+ JsonDeserializationContext
context) throws JsonParseException {
+ RangerAccessRequestImpl ret = gsonBuilder.fromJson(jsonObj,
RangerAccessRequestImpl.class);
+
+ ret.setAccessType(ret.getAccessType()); // to force computation of
isAccessTypeAny and isAccessTypeDelegatedAdmin
+ if (ret.getAccessTime() == null) {
+ ret.setAccessTime(new Date());
+ }
+ Map<String, Object> reqContext = ret.getContext();
+ Object accessTypes = reqContext.get("ACCESSTYPES");
+ if (accessTypes != null) {
+ Collection<String> accessTypesCollection =
(Collection<String>) accessTypes;
+ Set<String> requestedAccesses = new
HashSet<>(accessTypesCollection);
+ ret.getContext().put("ACCESSTYPES", requestedAccesses);
+ }
+
+ return ret;
+ }
+ }
+
+ static class RangerResourceDeserializer implements
JsonDeserializer<RangerAccessResource> {
+ @Override
+ public RangerAccessResource deserialize(JsonElement jsonObj, Type type,
+ JsonDeserializationContext
context) throws JsonParseException {
+ return gsonBuilder.fromJson(jsonObj,
RangerAccessResourceImpl.class);
+ }
+ }
+}
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
new file mode 100644
index 000000000..c3ef3c484
--- /dev/null
+++
b/agents-common/src/test/resources/policyengine/gds/test_gds_policy_engine_hive.json
@@ -0,0 +1,381 @@
+{
+ "serviceDef":{
+ "name": "hive",
+ "id": 3,
+ "resources": [
+ { "name": "database", "level":1, "parent": "", "mandatory":
true, "lookupSupported": true, "matcher":
"org.apache.ranger.plugin.resourcematcher.RangerDefaultResourceMatcher",
"matcherOptions":{ "wildCard": true, "ignoreCase": true }, "label": "Hive
Database", "description": "Hive Database" },
+ { "name": "url", "level":1, "parent": "", "mandatory":
true, "lookupSupported": false, "matcher":
"org.apache.ranger.plugin.resourcematcher.RangerURLResourceMatcher",
"matcherOptions":{ "wildCard": true, "ignoreCase": true }, "label": "URL",
"description": "URL", "recursiveSupported": true },
+ { "name": "hiveservice", "level":1, "parent": "", "mandatory":
true, "lookupSupported": false, "matcher":
"org.apache.ranger.plugin.resourcematcher.RangerDefaultResourceMatcher",
"matcherOptions":{ "wildCard": true, "ignoreCase": true }, "label":
"HiveService", "description": "HiveService" },
+ { "name": "table", "level":2, "parent": "database", "mandatory":
true, "lookupSupported": true, "matcher":
"org.apache.ranger.plugin.resourcematcher.RangerDefaultResourceMatcher",
"matcherOptions":{ "wildCard": true, "ignoreCase": true }, "label": "Hive
Table", "description": "Hive Table" },
+ { "name": "udf", "level":2, "parent": "database", "mandatory":
true, "lookupSupported": true, "matcher":
"org.apache.ranger.plugin.resourcematcher.RangerDefaultResourceMatcher",
"matcherOptions":{ "wildCard": true, "ignoreCase": true }, "label": "Hive UDF",
"description": "Hive UDF" },
+ { "name": "column", "level":3, "parent": "table", "mandatory":
true, "lookupSupported": true, "matcher":
"org.apache.ranger.plugin.resourcematcher.RangerDefaultResourceMatcher",
"matcherOptions":{ "wildCard": true, "ignoreCase": true }, "label": "Hive
Column", "description": "Hive Column" }
+ ],
+ "accessTypes":[
+ { "name": "select", "label": "Select", "category": "READ"
},
+ { "name": "update", "label": "Update", "category": "UPDATE"
},
+ { "name": "create", "label": "Create", "category": "CREATE"
},
+ { "name": "drop", "label": "Drop", "category": "DELETE"
},
+ { "name": "alter", "label": "Alter", "category": "CREATE"
},
+ { "name": "index", "label": "Index", "category": "MANAGE"
},
+ { "name": "lock", "label": "Lock", "category": "MANAGE"
},
+ { "name": "read", "label": "Read", "category": "READ"
},
+ { "name": "write", "label": "Write", "category": "UPDATE"
},
+ { "name": "repladmin", "label": "ReplAdmin", "category": "MANAGE"
},
+ { "name": "serviceadmin", "label": "ServiceAdmin", "category": "MANAGE"
},
+ { "name": "all", "label": "All",
+ "impliedGrants": [ "select", "update", "create", "drop", "alter",
"index", "lock", "read", "write", "repladmin", "serviceadmin" ]
+ }
+ ]
+ },
+ "securityZones": {
+ "sales": { "zoneName": "sales", "resources": [ { "database": [
"sales" ] } ] },
+ "finance": { "zoneName": "finance", "resources": [ { "database": [
"finance" ] } ] },
+ "shipping": { "zoneName": "shipping", "resources": [ { "database": [
"shipping" ] } ] }
+ },
+ "gdsInfo": {
+ "serviceName": "dev_hive",
+ "dataShares": [
+ { "id": 1, "name": "hive-sales-2023", "zoneName": "sales",
"conditionExpr": "", "defaultAccessTypes": [ "_READ" ], "defaultTagMasks": [ ]
},
+ { "id": 2, "name": "hive-finance-2023", "zoneName": "finance",
"conditionExpr": "", "defaultAccessTypes": [ "_READ" ], "defaultTagMasks": [ ]
},
+ { "id": 3, "name": "hive-shipping-2023", "zoneName": "shipping",
"conditionExpr": "", "defaultAccessTypes": [ "_READ" ], "defaultTagMasks": [ ]
},
+ { "id": 4, "name": "hive-new-customers-2023", "zoneName": "",
"conditionExpr": "", "defaultAccessTypes": [ "_READ" ], "defaultTagMasks": [ ]
},
+ { "id": 5, "name": "hive-facilities", "zoneName": "",
"conditionExpr": "", "defaultAccessTypes": [ "_READ" ], "defaultTagMasks": [ ] }
+ ],
+ "dshids": [
+ { "dataShareId": 1, "datasetId": 1, "status": "ACTIVE",
"validitySchedule": null },
+ { "dataShareId": 2, "datasetId": 1, "status": "ACTIVE",
"validitySchedule": null },
+ { "dataShareId": 2, "datasetId": 2, "status": "ACTIVE",
"validitySchedule": null },
+ { "dataShareId": 3, "datasetId": 2, "status": "ACTIVE",
"validitySchedule": null },
+ { "dataShareId": 4, "datasetId": 3, "status": "ACTIVE",
"validitySchedule": null },
+ { "dataShareId": 5, "datasetId": 4, "status": "ACTIVE",
"validitySchedule": null }
+ ],
+ "dips": [
+ { "datasetId": 1, "projectId": 1, "status": "ACTIVE",
"validitySchedule": null },
+ { "datasetId": 2, "projectId": 1, "status": "ACTIVE",
"validitySchedule": null },
+ { "datasetId": 3, "projectId": 2, "status": "ACTIVE",
"validitySchedule": null }
+ ],
+ "resources": [
+ {
+ "id": 11, "dataShareId": 1, "conditionExpr": "", "accessTypes": [
"select" ],
+ "resource": { "database": { "values": [ "sales" ] }, "table": {
"values": [ "prospects" ] } }, "rowFilter": { "filterExpr": "created_time >=
'2023-01-01' and created_time < '2024-01-01'" },
+ "subResourceType": "column", "subResource": { "values": [ "*" ] },
"subResourceMasks": { }
+ },
+ {
+ "id": 12, "dataShareId": 1, "conditionExpr": "", "accessTypes": [
"select" ],
+ "resource": { "database": { "values": [ "sales" ] }, "table": {
"values": [ "orders" ] } }, "rowFilter": { "filterExpr": "created_time >=
'2023-01-01' and created_time < '2024-01-01'" },
+ "subResourceType": "column", "subResource": { "values": [ "*" ] },
"subResourceMasks": { }
+ },
+ {
+ "id": 21, "dataShareId": 2, "conditionExpr": "", "accessTypes": [
"select" ],
+ "resource": { "database": { "values": [ "finance" ] }, "table": {
"values": [ "invoices" ] } }, "rowFilter": { "filterExpr": "created_time >=
'2023-01-01' and created_time < '2024-01-01'" },
+ "subResourceType": "column", "subResource": { "values": [ "*" ] },
"subResourceMasks": { }
+ },
+ {
+ "id": 22, "dataShareId": 2, "conditionExpr": "", "accessTypes": [
"select" ],
+ "resource": { "database": { "values": [ "finance" ] }, "table": {
"values": [ "payments" ] } }, "rowFilter": { "filterExpr": "created_time >=
'2023-01-01' and created_time < '2024-01-01'" },
+ "subResourceType": "column", "subResource": { "values": [ "*" ] },
"subResourceMasks": { }
+ },
+ {
+ "id": 31, "dataShareId": 3, "conditionExpr": "", "accessTypes": [
"select" ],
+ "resource": { "database": { "values": [ "shipping" ] }, "table": {
"values": [ "shipments" ] } }, "rowFilter": { "filterExpr": "created_time >=
'2023-01-01' and created_time < '2024-01-01'" },
+ "subResourceType": "column", "subResource": { "values": [ "*" ] },
"subResourceMasks": { }
+ },
+ {
+ "id": 41, "dataShareId": 4, "conditionExpr": "", "accessTypes": [
"select" ],
+ "resource": { "database": { "values": [ "customers" ] }, "table": {
"values": [ "contact_info" ] } }, "rowFilter": { "filterExpr": "created_time >=
'2023-01-01' and created_time < '2024-01-01'" },
+ "subResourceType": "column", "subResource": { "values": [ "*" ] },
"subResourceMasks": null
+ },
+ {
+ "id": 51, "dataShareId": 5, "conditionExpr": "", "accessTypes": [
"select" ],
+ "resource": { "database": { "values": [ "operations" ] }, "table": {
"values": [ "facilities" ] } }, "rowFilter": null,
+ "subResourceType": "column", "subResource": { "values": [ "*" ] },
"subResourceMasks": null
+ }
+ ],
+ "datasets": [
+ {
+ "id": 1,
+ "name": "dataset-1",
+ "policies": [
+ { "id": 2001, "name": "dataset-3", "isEnabled": true,
"isAuditEnabled": true,
+ "resources": { "dataset-id": { "values": ["1"] } },
+ "policyItems":[
+ { "accesses":[ { "type": "_READ", "isAllowed": true } ],
"users": [ "ds-user" ], "groups": []}
+ ]
+ }
+ ]
+ },
+ {
+ "id": 2,
+ "name": "dataset-2",
+ "policies": [
+ { "id": 2002, "name": "dataset-2", "isEnabled": true,
"isAuditEnabled": true,
+ "resources": { "dataset-id": { "values": ["2"] } },
+ "policyItems":[
+ { "accesses":[ { "type": "_READ", "isAllowed": true } ],
"users": [ "ds-user" ], "groups": []}
+ ]
+ }
+ ]
+ },
+ {
+ "id": 3,
+ "name": "dataset-3",
+ "policies": [
+ { "id": 2003, "name": "dataset-3", "isEnabled": true,
"isAuditEnabled": true,
+ "resources": { "dataset-id": { "values": ["3"] } },
+ "policyItems":[
+ { "accesses":[ { "type": "_READ", "isAllowed": true } ],
"users": [ "ds-user" ], "groups": []}
+ ]
+ }
+ ]
+ },
+ {
+ "id": 4,
+ "name": "dataset-4",
+ "policies": [
+ { "id": 2004, "name": "dataset-4", "isEnabled": true,
"isAuditEnabled": true,
+ "resources": { "dataset-id": { "values": ["4"] } },
+ "policyItems":[
+ { "accesses":[ { "type": "_READ", "isAllowed": true } ],
"users": [ "ds-user" ], "groups": []}
+ ]
+ }
+ ]
+ }
+ ],
+ "projects": [
+ {
+ "id": 1,
+ "name": "project-1",
+ "policies": [
+ { "id": 3001, "name": "project-1", "isEnabled": true,
"isAuditEnabled": true,
+ "resources": { "project-id": { "values": ["1"] } },
+ "policyItems":[
+ { "accesses":[ { "type": "_READ", "isAllowed": true } ],
"users": [ "proj-user" ], "groups": []}
+ ]
+ }
+ ]
+ },
+ {
+ "id": 2,
+ "name": "project-2",
+ "policies": [
+ { "id": 3002, "name": "project-2", "isEnabled": true,
"isAuditEnabled": true,
+ "resources": { "project-id": { "values": ["2"] } },
+ "policyItems":[
+ { "accesses":[ { "type": "_READ", "isAllowed": true } ],
"users": [ "proj-user" ], "groups": []}
+ ]
+ }
+ ]
+ }
+ ],
+ "gdsServiceDef": {
+ "name": "gds",
+ "id": 3,
+ "resources": [
+ { "name": "dataset-id", "level":1, "parent": "", "mandatory": true,
"lookupSupported": false, "matcher":
"org.apache.ranger.plugin.resourcematcher.RangerDefaultResourceMatcher",
"matcherOptions":{ "wildCard": false, "ignoreCase": true }, "label": "Dataset
ID", "description": "Dataset ID" },
+ { "name": "project-id", "level":1, "parent": "", "mandatory": true,
"lookupSupported": false, "matcher":
"org.apache.ranger.plugin.resourcematcher.RangerDefaultResourceMatcher",
"matcherOptions":{ "wildCard": false, "ignoreCase": true }, "label": "Project
ID", "description": "Project ID" }
+ ],
+ "accessTypes":[
+ { "itemId": 1, "name": "_CREATE", "label": "_CREATE" },
+ { "itemId": 2, "name": "_READ", "label": "_READ" },
+ { "itemId": 3, "name": "_UPDATE", "label": "_UPDATE" },
+ { "itemId": 4, "name": "_DELETE", "label": "_DELETE" },
+ { "itemId": 5, "name": "_MANAGE", "label": "_MANAGE" },
+ { "itemId": 6, "name": "_ALL", "label": "_ALL" }
+ ]
+ },
+ "gdsVersion": 1
+ },
+ "tests": [
+ {
+ "name": "table: sales.prospects, user: ds-user, access: select",
+ "request": {
+ "resource": { "elements": { "database": "sales", "table":
"prospects" } },
+ "accessType": "select", "user": "ds-user", "userGroups": []
+ },
+ "result": { "datasets": [ 1 ], "projects": [ 1 ], "datasetNames": [
"dataset-1" ], "projectNames": [ "project-1" ], "isAllowed": true, "isAudited":
true, "policyId": 2001 }
+ },
+ {
+ "name": "table: sales.orders, user: ds-user, access: select",
+ "request": {
+ "resource": { "elements": { "database": "sales", "table": "orders" }
},
+ "accessType": "select", "user": "ds-user", "userGroups": []
+ },
+ "result": { "datasets": [ 1 ], "projects": [ 1 ], "datasetNames": [
"dataset-1" ], "projectNames": [ "project-1" ], "isAllowed": true, "isAudited":
true, "policyId": 2001 }
+ },
+ {
+ "name": "table: finance.invoices, user: ds-user, access: select",
+ "request": {
+ "resource": { "elements": { "database": "finance", "table":
"invoices" } },
+ "accessType": "select", "user": "ds-user", "userGroups": []
+ },
+ "result": { "datasets": [ 1, 2 ], "projects": [ 1 ], "datasetNames": [
"dataset-1", "dataset-2" ], "projectNames": [ "project-1" ], "isAllowed": true,
"isAudited": true, "policyId": 2001 }
+ },
+ {
+ "name": "table: finance.payments, user: ds-user, access: select",
+ "request": {
+ "resource": { "elements": { "database": "finance", "table":
"payments" } },
+ "accessType": "select", "user": "ds-user", "userGroups": []
+ },
+ "result": { "datasets": [ 1, 2 ], "projects": [ 1 ], "datasetNames": [
"dataset-1", "dataset-2" ], "projectNames": [ "project-1" ], "isAllowed": true,
"isAudited": true, "policyId": 2001 }
+ },
+ {
+ "name": "table: shipping.shipments, user: ds-user, access: select",
+ "request": {
+ "resource": { "elements": { "database": "shipping", "table":
"shipments" } },
+ "accessType": "select", "user": "ds-user", "userGroups": []
+ },
+ "result": { "datasets": [ 2 ], "projects": [ 1 ], "datasetNames": [
"dataset-2" ], "projectNames": [ "project-1" ], "isAllowed": true, "isAudited":
true, "policyId": 2002 }
+ },
+ {
+ "name": "table: customers.contact_info, user: ds-user, access: select",
+ "request": {
+ "resource": { "elements": { "database": "customers", "table":
"contact_info" } },
+ "accessType": "select", "user": "ds-user", "userGroups": []
+ },
+ "result": { "datasets": [ 3 ], "projects": [ 2 ], "datasetNames": [
"dataset-3" ], "projectNames": [ "project-2" ], "isAllowed": true, "isAudited":
true, "policyId": 2003 }
+ },
+ {
+ "name": "table: operations.facilities, user: ds-user, access: select",
+ "request": {
+ "resource": { "elements": { "database": "operations", "table":
"facilities" } },
+ "accessType": "select", "user": "ds-user", "userGroups": []
+ },
+ "result": { "datasets": [ 4 ], "projects": null, "datasetNames": [
"dataset-4" ], "projectNames": null, "isAllowed": true, "isAudited": true,
"policyId": 2004 }
+ },
+
+
+ {
+ "name": "table: sales.prospects, user: proj-user, access: select",
+ "request": {
+ "resource": { "elements": { "database": "sales", "table":
"prospects" } },
+ "accessType": "select", "user": "proj-user", "userGroups": []
+ },
+ "result": { "datasets": [ 1 ], "projects": [ 1 ], "datasetNames": [
"dataset-1" ], "projectNames": [ "project-1" ], "isAllowed": true, "isAudited":
true, "policyId": 3001 }
+ },
+ {
+ "name": "table: sales.orders, user: proj-user, access: select",
+ "request": {
+ "resource": { "elements": { "database": "sales", "table": "orders" }
},
+ "accessType": "select", "user": "proj-user", "userGroups": []
+ },
+ "result": { "datasets": [ 1 ], "projects": [ 1 ], "datasetNames": [
"dataset-1" ], "projectNames": [ "project-1" ], "isAllowed": true, "isAudited":
true, "policyId": 3001 }
+ },
+ {
+ "name": "table: finance.invoices, user: proj-user, access: select",
+ "request": {
+ "resource": { "elements": { "database": "finance", "table":
"invoices" } },
+ "accessType": "select", "user": "proj-user", "userGroups": []
+ },
+ "result": { "datasets": [ 1, 2 ], "projects": [ 1 ], "datasetNames": [
"dataset-1", "dataset-2" ], "projectNames": [ "project-1" ], "isAllowed": true,
"isAudited": true, "policyId": 3001 }
+ },
+ {
+ "name": "table: finance.payments, user: proj-user, access: select",
+ "request": {
+ "resource": { "elements": { "database": "finance", "table":
"payments" } },
+ "accessType": "select", "user": "proj-user", "userGroups": []
+ },
+ "result": { "datasets": [ 1, 2 ], "projects": [ 1 ], "datasetNames": [
"dataset-1", "dataset-2" ], "projectNames": [ "project-1" ], "isAllowed": true,
"isAudited": true, "policyId": 3001 }
+ },
+ {
+ "name": "table: shipping.shipments, user: proj-user, access: select",
+ "request": {
+ "resource": { "elements": { "database": "shipping", "table":
"shipments" } },
+ "accessType": "select", "user": "proj-user", "userGroups": []
+ },
+ "result": { "datasets": [ 2 ], "projects": [ 1 ], "datasetNames": [
"dataset-2" ], "projectNames": [ "project-1" ], "isAllowed": true, "isAudited":
true, "policyId": 3001 }
+ },
+ {
+ "name": "table: customers.contact_info, user: proj-user, access: select",
+ "request": {
+ "resource": { "elements": { "database": "customers", "table":
"contact_info" } },
+ "accessType": "select", "user": "proj-user", "userGroups": []
+ },
+ "result": { "datasets": [ 3 ], "projects": [ 2 ], "datasetNames": [
"dataset-3" ], "projectNames": [ "project-2" ], "isAllowed": true, "isAudited":
true, "policyId": 3002 }
+ },
+ {
+ "name": "table: operations.facilities, user: proj-user, access: select",
+ "request": {
+ "resource": { "elements": { "database": "operations", "table":
"facilities" } },
+ "accessType": "select", "user": "proj-user", "userGroups": []
+ },
+ "result": { "datasets": [ 4 ], "projects": null, "datasetNames": [
"dataset-4" ], "projectNames": null, "isAllowed": false, "isAudited": true,
"policyId": -1 }
+ },
+
+
+ {
+ "name": "table: sales.prospects, user: scott, access: select",
+ "request": {
+ "resource": { "elements": { "database": "sales", "table":
"prospects" } },
+ "accessType": "select", "user": "scott", "userGroups": []
+ },
+ "result": { "datasets": [ 1 ], "projects": [ 1 ], "datasetNames": [
"dataset-1" ], "projectNames": [ "project-1" ], "isAllowed": false,
"isAudited": true, "policyId": -1 }
+ },
+ {
+ "name": "table: sales.orders, user: scott, access: select",
+ "request": {
+ "resource": { "elements": { "database": "sales", "table": "orders" }
},
+ "accessType": "select", "user": "scott", "userGroups": []
+ },
+ "result": { "datasets": [ 1 ], "projects": [ 1 ], "datasetNames": [
"dataset-1" ], "projectNames": [ "project-1" ], "isAllowed": false,
"isAudited": true, "policyId": -1 }
+ },
+ {
+ "name": "table: finance.invoices, user: scott, access: select",
+ "request": {
+ "resource": { "elements": { "database": "finance", "table":
"invoices" } },
+ "accessType": "select", "user": "scott", "userGroups": []
+ },
+ "result": { "datasets": [ 1, 2 ], "projects": [ 1 ], "datasetNames": [
"dataset-1", "dataset-2" ], "projectNames": [ "project-1" ], "isAllowed":
false, "isAudited": true, "policyId": -1 }
+ },
+ {
+ "name": "table: finance.payments, user: scott, access: select",
+ "request": {
+ "resource": { "elements": { "database": "finance", "table":
"payments" } },
+ "accessType": "select", "user": "scott", "userGroups": []
+ },
+ "result": { "datasets": [ 1, 2 ], "projects": [ 1 ], "datasetNames": [
"dataset-1", "dataset-2" ], "projectNames": [ "project-1" ], "isAllowed":
false, "isAudited": true, "policyId": -1 }
+ },
+ {
+ "name": "table: shipping.shipments, user: scott, access: select",
+ "request": {
+ "resource": { "elements": { "database": "shipping", "table":
"shipments" } },
+ "accessType": "select", "user": "scott", "userGroups": []
+ },
+ "result": { "datasets": [ 2 ], "projects": [ 1 ], "datasetNames": [
"dataset-2" ], "projectNames": [ "project-1" ], "isAllowed": false,
"isAudited": true, "policyId": -1 }
+ },
+ {
+ "name": "table: customers.contact_info, user: scott, access: select",
+ "request": {
+ "resource": { "elements": { "database": "customers", "table":
"contact_info" } },
+ "accessType": "select", "user": "scott", "userGroups": []
+ },
+ "result": { "datasets": [ 3 ], "projects": [ 2 ], "datasetNames": [
"dataset-3" ], "projectNames": [ "project-2" ], "isAllowed": false,
"isAudited": true, "policyId": -1 }
+ },
+ {
+ "name": "table: operations.facilities, user: scott, access: select",
+ "request": {
+ "resource": { "elements": { "database": "operations", "table":
"facilities" } },
+ "accessType": "select", "user": "scott", "userGroups": []
+ },
+ "result": { "datasets": [ 4 ], "projects": null, "datasetNames": [
"dataset-4" ], "projectNames": null, "isAllowed": false, "isAudited": true,
"policyId": -1 }
+ },
+
+
+ {
+ "name": "table: operations.facilities, user: scott, access: select",
+ "request": {
+ "resource": { "elements": { "database": "operations", "table":
"facilities" } },
+ "accessType": "select", "user": "scott", "userGroups": []
+ },
+ "result": { "datasets": [ 4 ], "projects": null, "datasetNames": [
"dataset-4" ], "projectNames": null, "isAllowed": false, "isAudited": true,
"policyId": -1 }
+ },
+
+ {
+ "name": "table: operations.facilities, user: ds-user, access: update",
+ "request": {
+ "resource": { "elements": { "database": "operations", "table":
"facilities" } },
+ "accessType": "update", "user": "ds-user", "userGroups": []
+ },
+ "result": { "datasets": null, "projects": null, "datasetNames": null,
"projectNames": null, "isAllowed": false, "isAudited": false, "policyId": -1 }
+ }
+ ]
+}
diff --git a/security-admin/src/main/java/org/apache/ranger/biz/GdsDBStore.java
b/security-admin/src/main/java/org/apache/ranger/biz/GdsDBStore.java
index c8dd235e9..f58943617 100755
--- a/security-admin/src/main/java/org/apache/ranger/biz/GdsDBStore.java
+++ b/security-admin/src/main/java/org/apache/ranger/biz/GdsDBStore.java
@@ -1922,6 +1922,7 @@ public class GdsDBStore extends AbstractGdsStore {
SharedResourceInfo resourceInfo = new SharedResourceInfo();
resourceInfo.setId(resource.getId());
+ resourceInfo.setName(resource.getName());
resourceInfo.setDataShareId(resource.getDataShareId());
resourceInfo.setResource(resource.getResource());
resourceInfo.setSubResource(resource.getSubResource());
@@ -1938,6 +1939,10 @@ public class GdsDBStore extends AbstractGdsStore {
private void populateDataSharesInDataset(ServiceGdsInfo gdsInfo,
SearchFilter filter) {
for (RangerDataShareInDataset dshInDs :
dataShareInDatasetService.searchDataShareInDatasets(filter).getList()) {
+ if (dshInDs.getStatus() != GdsShareStatus.ACTIVE) {
+ continue;
+ }
+
DataShareInDatasetInfo dshInDsInfo = new DataShareInDatasetInfo();
dshInDsInfo.setDatasetId(dshInDs.getDatasetId());
@@ -1952,6 +1957,10 @@ public class GdsDBStore extends AbstractGdsStore {
private void populateDatasetsInProject(ServiceGdsInfo gdsInfo,
SearchFilter filter) {
for (RangerDatasetInProject dip :
datasetInProjectService.searchDatasetInProjects(filter).getList()) {
+ if (dip.getStatus() != GdsShareStatus.ACTIVE) {
+ continue;
+ }
+
DatasetInProjectInfo dipInfo = new DatasetInProjectInfo();
dipInfo.setDatasetId(dip.getDatasetId());
diff --git
a/security-admin/src/main/java/org/apache/ranger/service/RangerGdsSharedResourceService.java
b/security-admin/src/main/java/org/apache/ranger/service/RangerGdsSharedResourceService.java
index 4685bc4f3..b1b5a841a 100755
---
a/security-admin/src/main/java/org/apache/ranger/service/RangerGdsSharedResourceService.java
+++
b/security-admin/src/main/java/org/apache/ranger/service/RangerGdsSharedResourceService.java
@@ -216,7 +216,7 @@ public class RangerGdsSharedResourceService extends
RangerGdsBaseModelService<XX
xObj.setResource(JsonUtils.mapToJson(vObj.getResource()));
xObj.setSubResource(JsonUtils.objectToJson(vObj.getSubResource()));
xObj.setSubResourceType(vObj.getSubResourceType());
- xObj.setResourceSignature(new
RangerPolicyResourceSignature(vObj.getResource()).getSignature());
+ xObj.setResourceSignature(new
RangerPolicyResourceSignature(vObj).getSignature());
xObj.setConditionExpr(vObj.getConditionExpr());
xObj.setAccessTypes(JsonUtils.objectToJson(vObj.getAccessTypes()));
xObj.setRowFilter(JsonUtils.objectToJson(vObj.getRowFilter()));