You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ranger.apache.org by ma...@apache.org on 2023/09/29 19:40:54 UTC
[ranger] 03/03: RANGER-4323: added API to get dataset header info for dataset listing page
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
commit e9f02a412af5c5047d1c79e8c1de4b6c3505913e
Author: Subhrat Chaudhary <su...@yahoo.com>
AuthorDate: Fri Sep 29 11:48:37 2023 -0700
RANGER-4323: added API to get dataset header info for dataset listing page
Signed-off-by: Madhan Neethiraj <ma...@apache.org>
---
.../ranger/plugin/model/RangerDatasetHeader.java | 99 ++++++++++
.../apache/ranger/plugin/util/SearchFilter.java | 7 +-
.../java/org/apache/ranger/biz/GdsDBStore.java | 215 +++++++++++++++++----
.../org/apache/ranger/common/RangerSearchUtil.java | 5 +
.../ranger/db/XXGdsDataShareInDatasetDao.java | 28 ++-
.../java/org/apache/ranger/db/XXPolicyDao.java | 19 +-
.../main/java/org/apache/ranger/rest/GdsREST.java | 30 +++
.../ranger/security/context/RangerAPIList.java | 1 +
.../ranger/service/RangerBaseModelService.java | 3 +-
.../service/RangerGdsDatasetInProjectService.java | 14 ++
.../ranger/service/RangerGdsDatasetService.java | 4 +
.../service/RangerGdsSharedResourceService.java | 14 ++
.../ranger/validation/RangerGdsValidator.java | 47 ++++-
.../main/resources/META-INF/jpa_named_queries.xml | 13 ++
14 files changed, 455 insertions(+), 44 deletions(-)
diff --git a/agents-common/src/main/java/org/apache/ranger/plugin/model/RangerDatasetHeader.java b/agents-common/src/main/java/org/apache/ranger/plugin/model/RangerDatasetHeader.java
new file mode 100644
index 000000000..9ab1cfac6
--- /dev/null
+++ b/agents-common/src/main/java/org/apache/ranger/plugin/model/RangerDatasetHeader.java
@@ -0,0 +1,99 @@
+/*
+ * 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.model;
+
+import org.codehaus.jackson.annotate.JsonAutoDetect;
+import org.codehaus.jackson.annotate.JsonIgnoreProperties;
+import org.codehaus.jackson.map.annotate.JsonSerialize;
+
+import javax.xml.bind.annotation.XmlAccessType;
+import javax.xml.bind.annotation.XmlAccessorType;
+import javax.xml.bind.annotation.XmlRootElement;
+import java.util.Map;
+
+public class RangerDatasetHeader {
+ @JsonAutoDetect(fieldVisibility = JsonAutoDetect.Visibility.ANY)
+ @JsonSerialize(include = JsonSerialize.Inclusion.NON_EMPTY)
+ @JsonIgnoreProperties(ignoreUnknown = true)
+ @XmlRootElement
+ @XmlAccessorType(XmlAccessType.FIELD)
+ public static class RangerDatasetHeaderInfo extends RangerBaseModelObject implements java.io.Serializable {
+ private static final long serialVersionUID = 1L;
+
+ private String name;
+ private Map<RangerGds.GdsShareStatus, Long> dataSharesCountByStatus;
+ private Map<RangerPrincipal.PrincipalType, Long> principalsCountByType;
+ private Long projectsCount;
+ private String permissionForCaller;
+ private Long resourceCount;
+
+ public RangerDatasetHeaderInfo() {
+ super();
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ public Map<RangerGds.GdsShareStatus, Long> getDataSharesCountByStatus() {
+ return dataSharesCountByStatus;
+ }
+
+ public void setDataSharesCountByStatus(Map<RangerGds.GdsShareStatus, Long> dataSharesCountByStatus) {
+ this.dataSharesCountByStatus = dataSharesCountByStatus;
+ }
+
+ public Map<RangerPrincipal.PrincipalType, Long> getPrincipalsCountByType() {
+ return principalsCountByType;
+ }
+
+ public void setPrincipalsCountByType(Map<RangerPrincipal.PrincipalType, Long> principalsCountByType) {
+ this.principalsCountByType = principalsCountByType;
+ }
+
+ public Long getProjectsCount() {
+ return projectsCount;
+ }
+
+ public void setProjectsCount(Long projectsCount) {
+ this.projectsCount = projectsCount;
+ }
+
+ public String getPermissionForCaller() {
+ return permissionForCaller;
+ }
+
+ public void setPermissionForCaller(String permissionForCaller) {
+ this.permissionForCaller = permissionForCaller;
+ }
+
+ public Long getResourceCount() {
+ return resourceCount;
+ }
+
+ public void setResourceCount(Long resourceCount) {
+ this.resourceCount = resourceCount;
+ }
+ }
+}
diff --git a/agents-common/src/main/java/org/apache/ranger/plugin/util/SearchFilter.java b/agents-common/src/main/java/org/apache/ranger/plugin/util/SearchFilter.java
index 5be7cebbb..f969cffc0 100755
--- a/agents-common/src/main/java/org/apache/ranger/plugin/util/SearchFilter.java
+++ b/agents-common/src/main/java/org/apache/ranger/plugin/util/SearchFilter.java
@@ -115,7 +115,12 @@ public class SearchFilter {
public static final String OWNER_TYPE = "ownerType"; // search: valid-values(user, group, role)
public static final String DATA_SHARE_IN_DATASET_ID = "dataShareInDatasetId"; // search, sort
public static final String DATASET_IN_PROJECT_ID = "datasetInProjectId"; // search, sort
- public static final String IS_DISTINCT = "isDistinct"; // search, sort
+ public static final String GDS_PERMISSION = "gdsPermission"; // search, sort
+ public static final String CREATE_TIME_START = "createdTimeStart"; // search
+ public static final String CREATE_TIME_END = "createdTimeEnd"; // search
+ public static final String UPDATE_TIME_START = "updatedTimeStart"; // search
+ public static final String UPDATE_TIME_END = "updatedTimeEnd"; // search
+ public static final String IS_DISTINCT = "isDistinct"; // search, sort
private Map<String, String> params;
private int startIndex;
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 909a74fe2..ce4769569 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
@@ -31,14 +31,21 @@ import org.apache.ranger.db.XXGdsProjectDao;
import org.apache.ranger.entity.XXGdsDataShareInDataset;
import org.apache.ranger.entity.XXGdsDataset;
import org.apache.ranger.entity.XXGdsDatasetInProject;
+import org.apache.ranger.entity.XXPolicy;
import org.apache.ranger.entity.XXGdsProject;
+import org.apache.ranger.plugin.model.RangerDatasetHeader.RangerDatasetHeaderInfo;
+import org.apache.ranger.plugin.model.RangerPolicy;
import org.apache.ranger.plugin.model.RangerGds.GdsPermission;
+import org.apache.ranger.plugin.model.RangerGds.GdsShareStatus;
import org.apache.ranger.plugin.model.RangerGds.RangerDataShare;
import org.apache.ranger.plugin.model.RangerGds.RangerDataShareInDataset;
import org.apache.ranger.plugin.model.RangerGds.RangerDataset;
import org.apache.ranger.plugin.model.RangerGds.RangerDatasetInProject;
import org.apache.ranger.plugin.model.RangerGds.RangerProject;
import org.apache.ranger.plugin.model.RangerGds.RangerSharedResource;
+import org.apache.ranger.plugin.model.RangerPolicy.RangerPolicyItem;
+import org.apache.ranger.plugin.model.RangerPolicy.RangerPolicyResource;
+import org.apache.ranger.plugin.model.RangerPrincipal.PrincipalType;
import org.apache.ranger.plugin.store.AbstractGdsStore;
import org.apache.ranger.plugin.store.PList;
import org.apache.ranger.plugin.util.SearchFilter;
@@ -48,6 +55,7 @@ import org.apache.ranger.service.RangerGdsDatasetService;
import org.apache.ranger.service.RangerGdsDatasetInProjectService;
import org.apache.ranger.service.RangerGdsProjectService;
import org.apache.ranger.service.RangerGdsSharedResourceService;
+import org.apache.ranger.service.RangerPolicyService;
import org.apache.ranger.service.RangerServiceService;
import org.apache.ranger.validation.RangerGdsValidator;
import org.apache.ranger.view.RangerGdsVList.RangerDataShareList;
@@ -68,6 +76,8 @@ import java.util.*;
import static org.apache.ranger.db.XXGlobalStateDao.RANGER_GLOBAL_STATE_NAME_DATASET;
import static org.apache.ranger.db.XXGlobalStateDao.RANGER_GLOBAL_STATE_NAME_DATA_SHARE;
import static org.apache.ranger.db.XXGlobalStateDao.RANGER_GLOBAL_STATE_NAME_PROJECT;
+import static org.apache.ranger.plugin.store.EmbeddedServiceDefsUtil.EMBEDDED_SERVICEDEF_GDS_NAME;
+
@Component
public class GdsDBStore extends AbstractGdsStore {
@@ -103,6 +113,13 @@ public class GdsDBStore extends AbstractGdsStore {
@Autowired
GUIDUtil guidUtil;
+ @Autowired
+ RangerPolicyService policyService;
+
+ @Autowired
+ RangerBizUtil bizUtil;
+
+
@PostConstruct
public void initStore() {
if (LOG.isDebugEnabled()) {
@@ -114,6 +131,20 @@ public class GdsDBStore extends AbstractGdsStore {
}
}
+ public PList<RangerDatasetHeaderInfo> getDatasetHeaders(SearchFilter filter) throws Exception {
+ LOG.debug("==> getDatasetHeaders({})", filter);
+
+ PList<RangerDataset> datasets = getUnscrubbedDatasets(filter);
+ List<RangerDatasetHeaderInfo> datasetHeaders = toDatasetHeaders(datasets.getList(), getGdsPermissionFromFilter(filter));
+ PList<RangerDatasetHeaderInfo> ret = new PList<>(datasetHeaders, datasets.getStartIndex(), datasets.getPageSize(), datasets.getTotalCount(), datasets.getResultSize(), datasets.getSortType(), datasets.getSortBy());
+
+ ret.setQueryTimeMS(datasets.getQueryTimeMS());
+
+ LOG.debug("<== getDatasetHeaders({}): ret={}", filter, ret);
+
+ return ret;
+ }
+
@Override
public RangerDataset createDataset(RangerDataset dataset) throws Exception {
LOG.debug("==> createDataset({})", dataset);
@@ -245,53 +276,21 @@ public class GdsDBStore extends AbstractGdsStore {
public PList<RangerDataset> searchDatasets(SearchFilter filter) throws Exception {
LOG.debug("==> searchDatasets({})", filter);
- int maxRows = filter.getMaxRows();
- int startIndex = filter.getStartIndex();
- filter.setStartIndex(0);
- filter.setMaxRows(0);
-
- String gdsPermissionStr = filter.getParam(SearchFilter.GDS_PERMISSION);
- GdsPermission gdsPermission = null;
+ PList<RangerDataset> ret = getUnscrubbedDatasets(filter);
+ List<RangerDataset> datasets = ret.getList();
+ GdsPermission gdsPermission = getGdsPermissionFromFilter(filter);
- if (StringUtils.isNotEmpty(gdsPermissionStr)) {
- try {
- gdsPermission = GdsPermission.valueOf(gdsPermissionStr);
- } catch (IllegalArgumentException ex) {
- LOG.info("Ignoring invalid GdsPermission: {}", gdsPermissionStr);
+ for (RangerDataset dataset : datasets) {
+ if (gdsPermission.equals(GdsPermission.LIST)) {
+ scrubDatasetForListing(dataset);
}
}
- if (gdsPermission == null) {
- gdsPermission = GdsPermission.VIEW;
- }
- RangerDatasetList result = datasetService.searchDatasets(filter);
- List<RangerDataset> datasets = new ArrayList<>();
-
- for (RangerDataset dataset : result.getList()) {
- if (dataset != null && validator.hasPermission(dataset.getAcl(), gdsPermission)) {
- if (gdsPermission.equals(GdsPermission.LIST)) {
- scrubForListing(dataset);
- }
-
- datasets.add(dataset);
- }
- }
-
- int endIndex = Math.min((startIndex + maxRows), datasets.size());
- List<RangerDataset> paginatedDatasets = datasets.subList(startIndex, endIndex);
- PList<RangerDataset> ret = new PList<>(paginatedDatasets, startIndex, maxRows, datasets.size(), paginatedDatasets.size(), result.getSortBy(), result.getSortType());
-
LOG.debug("<== searchDatasets({}): ret={}", filter, ret);
return ret;
}
- private void scrubForListing(RangerDataset dataset) {
- dataset.setAcl(null);
- dataset.setOptions(null);
- dataset.setAdditionalInfo(null);
- }
-
@Override
public RangerProject createProject(RangerProject project) throws Exception {
LOG.debug("==> createProject({})", project);
@@ -752,7 +751,6 @@ public class GdsDBStore extends AbstractGdsStore {
return ret;
}
-
@Override
public RangerDatasetInProject addDatasetInProject(RangerDatasetInProject datasetInProject) throws Exception {
LOG.debug("==> addDatasetInProject({})", datasetInProject);
@@ -874,4 +872,143 @@ public class GdsDBStore extends AbstractGdsStore {
}
}
+ private List<RangerDatasetHeaderInfo> toDatasetHeaders(List<RangerDataset> datasets, GdsPermission gdsPermission) {
+ List<RangerDatasetHeaderInfo> ret = new ArrayList<>();
+
+ for (RangerDataset dataset : datasets) {
+ RangerDatasetHeaderInfo datasetHeader = new RangerDatasetHeaderInfo();
+
+ if (gdsPermission.equals(GdsPermission.LIST)) {
+ final GdsPermission permissionForUser = validator.getGdsPermissionForUser(dataset.getAcl(), bizUtil.getCurrentUserLoginId());
+
+ if (permissionForUser.equals(GdsPermission.NONE)) {
+ continue;
+ } else {
+ datasetHeader.setPermissionForCaller(permissionForUser.toString());
+ }
+ } else {
+ datasetHeader.setDataSharesCountByStatus(getDataSharesInDatasetCountByStatus(dataset.getId()));
+ datasetHeader.setProjectsCount(getDIPCountForDataset(dataset.getId()));
+ datasetHeader.setPrincipalsCountByType(getPrincipalCountForDataset(dataset.getName()));
+
+ datasetHeader.setResourceCount(getResourceCountInDataset(dataset.getId()));
+ }
+
+ datasetHeader.setId(dataset.getId());
+ datasetHeader.setName(dataset.getName());
+ datasetHeader.setCreateTime(dataset.getCreateTime());
+ datasetHeader.setUpdateTime(dataset.getUpdateTime());
+ datasetHeader.setCreatedBy(dataset.getCreatedBy());
+ datasetHeader.setUpdatedBy(dataset.getUpdatedBy());
+ datasetHeader.setIsEnabled(dataset.getIsEnabled());
+ datasetHeader.setGuid(dataset.getGuid());
+ datasetHeader.setVersion(dataset.getVersion());
+
+ ret.add(datasetHeader);
+ }
+
+ return ret;
+ }
+
+ private Map<GdsShareStatus, Long> getDataSharesInDatasetCountByStatus(Long datasetId) {
+ Map<GdsShareStatus, Long> ret = new HashMap<>();
+ Map<Short, Long> countsByStatus = daoMgr.getXXGdsDataShareInDataset().getDataSharesInDatasetCountByStatus(datasetId);
+
+ for (Map.Entry<Short, Long> entry : countsByStatus.entrySet()) {
+ ret.put(RangerGdsDatasetInProjectService.toShareStatus(entry.getKey()), entry.getValue());
+ }
+
+ return ret;
+ }
+
+ private Long getDIPCountForDataset(Long datasetId) {
+ return datasetInProjectService.getDatasetsInProjectCount(datasetId);
+ }
+
+ private Long getResourceCountInDataset(Long datasetId) {
+ return sharedResourceService.getResourceCountInDataset(datasetId);
+ }
+
+ private Map<PrincipalType, Long> getPrincipalCountForDataset(String datasetName) {
+ Map<PrincipalType, Long> ret = new HashMap<>();
+ Set<String> users = new HashSet<>();
+ Set<String> groups = new HashSet<>();
+ Set<String> roles = new HashSet<>();
+
+ if (StringUtils.isNotEmpty(datasetName)) {
+ List<XXPolicy> policies = daoMgr.getXXPolicy().findByServiceType(EMBEDDED_SERVICEDEF_GDS_NAME);
+
+ for (XXPolicy policyFromDb : policies) {
+ RangerPolicy policy = policyService.getPopulatedViewObject(policyFromDb);
+ Collection<RangerPolicyResource> resources = policy.getResources().values();
+
+ for (RangerPolicyResource resource : resources) {
+ if (resource.getValues().contains(datasetName)){
+ List<RangerPolicyItem> policyItems = policy.getPolicyItems();
+
+ for (RangerPolicyItem policyItem : policyItems) {
+ users.addAll(policyItem.getUsers());
+ groups.addAll(policyItem.getGroups());
+ roles.addAll(policyItem.getRoles());
+ }
+ }
+ }
+ }
+ }
+
+ ret.put(PrincipalType.USER, (long) users.size());
+ ret.put(PrincipalType.GROUP, (long) groups.size());
+ ret.put(PrincipalType.ROLE, (long) roles.size());
+
+ return ret;
+ }
+
+ private PList<RangerDataset> getUnscrubbedDatasets(SearchFilter filter) throws Exception {
+ int maxRows = filter.getMaxRows();
+ int startIndex = filter.getStartIndex();
+
+ filter.setStartIndex(0);
+ filter.setMaxRows(0);
+
+ GdsPermission gdsPermission = getGdsPermissionFromFilter(filter);
+ RangerDatasetList result = datasetService.searchDatasets(filter);
+ List<RangerDataset> datasets = new ArrayList<>();
+
+ for (RangerDataset dataset : result.getList()) {
+ if (dataset != null && validator.hasPermission(dataset.getAcl(), gdsPermission)) {
+ datasets.add(dataset);
+ }
+ }
+
+ int endIndex = Math.min((startIndex + maxRows), datasets.size());
+ List<RangerDataset> paginatedDatasets = datasets.subList(startIndex, endIndex);
+ PList<RangerDataset> ret = new PList<>(paginatedDatasets, startIndex, maxRows, datasets.size(), paginatedDatasets.size(), result.getSortBy(), result.getSortType());
+
+ return ret;
+ }
+
+ private GdsPermission getGdsPermissionFromFilter(SearchFilter filter) {
+ String gdsPermissionStr = filter.getParam(SearchFilter.GDS_PERMISSION);
+ GdsPermission gdsPermission = null;
+
+ if (StringUtils.isNotEmpty(gdsPermissionStr)) {
+ try {
+ gdsPermission = GdsPermission.valueOf(gdsPermissionStr);
+ } catch (IllegalArgumentException ex) {
+ LOG.info("Ignoring invalid GdsPermission: {}", gdsPermissionStr);
+ }
+ }
+
+ if (gdsPermission == null) {
+ gdsPermission = GdsPermission.VIEW;
+ }
+
+ return gdsPermission;
+ }
+
+ private void scrubDatasetForListing(RangerDataset dataset) {
+ dataset.setAcl(null);
+ dataset.setOptions(null);
+ dataset.setAdditionalInfo(null);
+ }
}
diff --git a/security-admin/src/main/java/org/apache/ranger/common/RangerSearchUtil.java b/security-admin/src/main/java/org/apache/ranger/common/RangerSearchUtil.java
index 66accbc0c..89174b2e4 100755
--- a/security-admin/src/main/java/org/apache/ranger/common/RangerSearchUtil.java
+++ b/security-admin/src/main/java/org/apache/ranger/common/RangerSearchUtil.java
@@ -114,6 +114,11 @@ public class RangerSearchUtil extends SearchUtil {
ret.setParam(SearchFilter.PROFILE_NAME, request.getParameter(SearchFilter.PROFILE_NAME));
ret.setParam(SearchFilter.OWNER_NAME, request.getParameter(SearchFilter.OWNER_NAME));
ret.setParam(SearchFilter.OWNER_TYPE, request.getParameter(SearchFilter.OWNER_TYPE));
+ ret.setParam(SearchFilter.GDS_PERMISSION, request.getParameter(SearchFilter.GDS_PERMISSION));
+ ret.setParam(SearchFilter.CREATE_TIME_START, request.getParameter(SearchFilter.CREATE_TIME_START));
+ ret.setParam(SearchFilter.CREATE_TIME_END, request.getParameter(SearchFilter.CREATE_TIME_END));
+ ret.setParam(SearchFilter.UPDATE_TIME_START, request.getParameter(SearchFilter.UPDATE_TIME_START));
+ ret.setParam(SearchFilter.UPDATE_TIME_END, request.getParameter(SearchFilter.UPDATE_TIME_END));
extractCommonCriteriasForFilter(request, ret, sortFields);
diff --git a/security-admin/src/main/java/org/apache/ranger/db/XXGdsDataShareInDatasetDao.java b/security-admin/src/main/java/org/apache/ranger/db/XXGdsDataShareInDatasetDao.java
old mode 100644
new mode 100755
index 52c441104..7637b275d
--- a/security-admin/src/main/java/org/apache/ranger/db/XXGdsDataShareInDatasetDao.java
+++ b/security-admin/src/main/java/org/apache/ranger/db/XXGdsDataShareInDatasetDao.java
@@ -28,8 +28,10 @@ import org.springframework.stereotype.Service;
import javax.persistence.NoResultException;
import java.util.Collections;
+import java.util.HashMap;
import java.util.List;
-
+import java.util.Map;
+import java.util.Objects;
@Service
public class XXGdsDataShareInDatasetDao extends BaseDao<XXGdsDataShareInDataset> {
@@ -99,4 +101,28 @@ public class XXGdsDataShareInDatasetDao extends BaseDao<XXGdsDataShareInDataset>
return ret != null ? ret : Collections.emptyList();
}
+
+ public Map<Short, Long> getDataSharesInDatasetCountByStatus(Long datasetId) {
+ Map<Short, Long> ret = Collections.emptyMap();
+
+ if (datasetId != null) {
+ try {
+ List<Object[]> rows = getEntityManager().createNamedQuery("XXGdsDataShareInDataset.getDataSharesInDatasetCountByStatus", Object[].class)
+ .setParameter("datasetId", datasetId).getResultList();
+ if (rows != null) {
+ ret = new HashMap<>();
+
+ for (Object[] row : rows) {
+ if (Objects.nonNull(row) && Objects.nonNull(row[0]) && Objects.nonNull(row[1]) && (!row[0].toString().isEmpty())) {
+ ret.put((Short) row[0], (Long) row[1]);
+ }
+ }
+ }
+ } catch (NoResultException e) {
+ LOG.debug("getDataSharesInDatasetCountByStatus({}): ", datasetId, e);
+ }
+ }
+
+ return ret;
+ }
}
diff --git a/security-admin/src/main/java/org/apache/ranger/db/XXPolicyDao.java b/security-admin/src/main/java/org/apache/ranger/db/XXPolicyDao.java
old mode 100644
new mode 100755
index f020acb21..9ff7f0a68
--- a/security-admin/src/main/java/org/apache/ranger/db/XXPolicyDao.java
+++ b/security-admin/src/main/java/org/apache/ranger/db/XXPolicyDao.java
@@ -18,6 +18,7 @@
package org.apache.ranger.db;
import java.util.ArrayList;
+import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@@ -417,4 +418,20 @@ public class XXPolicyDao extends BaseDao<XXPolicy> {
return new ArrayList<XXPolicy>();
}
}
-}
\ No newline at end of file
+
+ public List<XXPolicy> findByServiceType(String serviceType) {
+ List<XXPolicy> ret = Collections.emptyList();
+
+ if (serviceType != null && !serviceType.isEmpty()) {
+ try {
+ ret = getEntityManager().createNamedQuery("XXPolicy.findByServiceType", tClass)
+ .setParameter("serviceType", serviceType)
+ .getResultList();
+ } catch (NoResultException e) {
+ // ignore
+ }
+ }
+
+ return ret;
+ }
+}
diff --git a/security-admin/src/main/java/org/apache/ranger/rest/GdsREST.java b/security-admin/src/main/java/org/apache/ranger/rest/GdsREST.java
old mode 100644
new mode 100755
index 653e397d4..56b908625
--- a/security-admin/src/main/java/org/apache/ranger/rest/GdsREST.java
+++ b/security-admin/src/main/java/org/apache/ranger/rest/GdsREST.java
@@ -33,6 +33,8 @@ import org.apache.ranger.plugin.util.RangerPerfTracer;
import org.apache.ranger.plugin.util.SearchFilter;
import org.apache.ranger.security.context.RangerAPIList;
import org.apache.ranger.service.RangerGdsDatasetService;
+import org.apache.ranger.plugin.model.RangerDatasetHeader.RangerDatasetHeaderInfo;
+
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
@@ -263,6 +265,34 @@ public class GdsREST {
return ret;
}
+ @GET
+ @Path("/dataset/info")
+ @Produces({ "application/json" })
+ @PreAuthorize("@rangerPreAuthSecurityHandler.isAPIAccessible(\"" + RangerAPIList.GET_DATASETS_HEADER + "\")")
+ public PList<RangerDatasetHeaderInfo> getDatasetHeaderInfo(@Context HttpServletRequest request) {
+ LOG.debug("==> GdsREST.getDatasetHeaderInfo()");
+
+ PList<RangerDatasetHeaderInfo> ret;
+
+ try {
+ SearchFilter filter = searchUtil.getSearchFilter(request, datasetService.sortFields);
+
+ ret = gdsStore.getDatasetHeaders(filter);
+ } catch (WebApplicationException we) {
+ LOG.error("getDatasets() failed", we);
+
+ throw restErrorUtil.createRESTException(we.getMessage());
+ } catch (Throwable ex) {
+ LOG.error("getDatasets() failed", ex);
+
+ throw restErrorUtil.createRESTException(ex.getMessage());
+ }
+
+ LOG.debug("<== GdsREST.getDatasetHeaderInfo(): {}", ret);
+
+ return ret;
+ }
+
@POST
@Path("/project")
@Consumes({ "application/json" })
diff --git a/security-admin/src/main/java/org/apache/ranger/security/context/RangerAPIList.java b/security-admin/src/main/java/org/apache/ranger/security/context/RangerAPIList.java
old mode 100644
new mode 100755
index de9014072..b22208773
--- a/security-admin/src/main/java/org/apache/ranger/security/context/RangerAPIList.java
+++ b/security-admin/src/main/java/org/apache/ranger/security/context/RangerAPIList.java
@@ -216,6 +216,7 @@ public class RangerAPIList {
/**
* List of APIs for DataShareREST
*/
+ public static final String GET_DATASETS_HEADER = "GdsREST.getDatasetHeaderInfo";
public static final String CREATE_DATASET = "GdsREST.createDataset";
public static final String UPDATE_DATASET = "GdsREST.updateDataset";
public static final String DELETE_DATASET = "GdsREST.deleteDataset";
diff --git a/security-admin/src/main/java/org/apache/ranger/service/RangerBaseModelService.java b/security-admin/src/main/java/org/apache/ranger/service/RangerBaseModelService.java
index 032978701..26f76578e 100755
--- a/security-admin/src/main/java/org/apache/ranger/service/RangerBaseModelService.java
+++ b/security-admin/src/main/java/org/apache/ranger/service/RangerBaseModelService.java
@@ -398,7 +398,8 @@ public abstract class RangerBaseModelService<T extends XXDBBase, V extends Range
return resultList;
}
- protected long getCountForSearchQuery(SearchFilter searchCriteria, List<SearchField> searchFieldList) {
+ //If not efficient we need to review this and add jpa_named queries to get the count
+ public long getCountForSearchQuery(SearchFilter searchCriteria, List<SearchField> searchFieldList) {
String q = searchCriteria.isDistinct() ? distinctCountQueryStr : countQueryStr;
Query query = createQuery(q, null, searchCriteria, searchFieldList, true);
Long count = getDao().executeCountQueryInSecurityContext(tEntityClass, query);
diff --git a/security-admin/src/main/java/org/apache/ranger/service/RangerGdsDatasetInProjectService.java b/security-admin/src/main/java/org/apache/ranger/service/RangerGdsDatasetInProjectService.java
index 0ed51c249..0d839346b 100644
--- a/security-admin/src/main/java/org/apache/ranger/service/RangerGdsDatasetInProjectService.java
+++ b/security-admin/src/main/java/org/apache/ranger/service/RangerGdsDatasetInProjectService.java
@@ -262,4 +262,18 @@ public class RangerGdsDatasetInProjectService extends RangerGdsBaseModelService<
return ret;
}
+
+ public Long getDatasetsInProjectCount(long datasetId) {
+ LOG.debug("==> getDatasetsInProjectCount({})", datasetId);
+
+ SearchFilter filter = new SearchFilter();
+
+ filter.setParam(SearchFilter.DATASET_ID, String.valueOf(datasetId));
+
+ Long ret = super.getCountForSearchQuery(filter, searchFields);
+
+ LOG.debug("<== getDatasetsInProjectCount({}): ret={}", datasetId, ret);
+
+ return ret;
+ }
}
diff --git a/security-admin/src/main/java/org/apache/ranger/service/RangerGdsDatasetService.java b/security-admin/src/main/java/org/apache/ranger/service/RangerGdsDatasetService.java
index 3cf4815c7..344b4ec33 100755
--- a/security-admin/src/main/java/org/apache/ranger/service/RangerGdsDatasetService.java
+++ b/security-admin/src/main/java/org/apache/ranger/service/RangerGdsDatasetService.java
@@ -68,6 +68,10 @@ public class RangerGdsDatasetService extends RangerGdsBaseModelService<XXGdsData
searchFields.add(new SearchField(SearchFilter.ZONE_NAME, "z.name", SearchField.DATA_TYPE.STRING, SearchField.SEARCH_TYPE.FULL, "XXGdsDataShareInDataset dshid, XXGdsDataShare dsh, XXSecurityZone z", "obj.id = dshid.datasetId and dshid.dataShareId = dsh.id and dsh.zoneId = z.id"));
searchFields.add(new SearchField(SearchFilter.ZONE_NAME_PARTIAL, "z.name", SearchField.DATA_TYPE.STRING, SearchField.SEARCH_TYPE.PARTIAL, "XXGdsDataShareInDataset dshid, XXGdsDataShare dsh, XXSecurityZone z", "obj.id = dshid.datasetId and dshid.dataShareId = dsh.id and dsh.zoneId = z.id"));
searchFields.add(new SearchField(SearchFilter.ZONE_ID, "dsh.zoneId", SearchField.DATA_TYPE.INTEGER, SearchField.SEARCH_TYPE.FULL, "XXGdsDataShareInDataset dshid, XXGdsDataShare dsh, XXSecurityZone z", "obj.id = dshid.datasetId and dshid.dataShareId = dsh.id and dsh.zoneId = z.id"));
+ searchFields.add(new SearchField(SearchFilter.CREATE_TIME_START, "obj.createTime", SearchField.DATA_TYPE.DATE, SearchField.SEARCH_TYPE.GREATER_EQUAL_THAN));
+ searchFields.add(new SearchField(SearchFilter.CREATE_TIME_END, "obj.createTime", SearchField.DATA_TYPE.DATE, SearchField.SEARCH_TYPE.LESS_EQUAL_THAN));
+ searchFields.add(new SearchField(SearchFilter.UPDATE_TIME_START, "obj.updateTime", SearchField.DATA_TYPE.DATE, SearchField.SEARCH_TYPE.GREATER_EQUAL_THAN));
+ searchFields.add(new SearchField(SearchFilter.UPDATE_TIME_END, "obj.createTime", SearchField.DATA_TYPE.DATE, SearchField.SEARCH_TYPE.LESS_EQUAL_THAN));
sortFields.add(new SortField(SearchFilter.CREATE_TIME, "obj.createTime"));
sortFields.add(new SortField(SearchFilter.UPDATE_TIME, "obj.updateTime"));
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 6a963da60..eadbb9228 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
@@ -247,4 +247,18 @@ public class RangerGdsSharedResourceService extends RangerGdsBaseModelService<XX
return ret;
}
+
+ public Long getResourceCountInDataset(long datasetId) {
+ LOG.debug("==> getResourceCountInDataset({})", datasetId);
+
+ SearchFilter filter = new SearchFilter();
+
+ filter.setParam(SearchFilter.DATASET_ID, String.valueOf(datasetId));
+
+ Long ret = super.getCountForSearchQuery(filter, searchFields);
+
+ LOG.debug("<== getResourceCountInDataset({}): ret={}", datasetId, ret);
+
+ return ret;
+ }
}
diff --git a/security-admin/src/main/java/org/apache/ranger/validation/RangerGdsValidator.java b/security-admin/src/main/java/org/apache/ranger/validation/RangerGdsValidator.java
index 374ac046d..be5ac56e6 100755
--- a/security-admin/src/main/java/org/apache/ranger/validation/RangerGdsValidator.java
+++ b/security-admin/src/main/java/org/apache/ranger/validation/RangerGdsValidator.java
@@ -17,6 +17,7 @@
package org.apache.ranger.validation;
+import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.collections.MapUtils;
import org.apache.commons.lang.StringUtils;
import org.apache.ranger.common.MessageEnums;
@@ -50,11 +51,44 @@ public class RangerGdsValidator {
@Autowired
RESTErrorUtil restErrorUtil;
-
public RangerGdsValidator(RangerGdsValidationDataProvider dataProvider) {
this.dataProvider = dataProvider;
}
+ public GdsPermission getGdsPermissionForUser(RangerGds.RangerGdsObjectACL acl, String user) {
+ if (dataProvider.isAdminUser()) {
+ return GdsPermission.ADMIN;
+ }
+
+ GdsPermission permission = GdsPermission.NONE;
+
+ if (acl.getUsers() != null) {
+ permission = getHigherPrivilegePermission(permission, acl.getUsers().get(user));
+ }
+
+ if (acl.getGroups() != null) {
+ Set<String> groups = dataProvider.getGroupsForUser(user);
+
+ if (CollectionUtils.isNotEmpty(groups)) {
+ for (String group : groups) {
+ permission = getHigherPrivilegePermission(permission, acl.getGroups().get(group));
+ }
+ }
+ }
+
+ if (acl.getRoles() != null) {
+ Set<String> roles = dataProvider.getRolesForUser(user);
+
+ if (CollectionUtils.isNotEmpty(roles)) {
+ for (String role : roles) {
+ permission = getHigherPrivilegePermission(permission, acl.getRoles().get(role));
+ }
+ }
+ }
+
+ return permission;
+ }
+
public void validateCreate(RangerDataset dataset) {
LOG.debug("==> validateCreate(dataset={})", dataset);
@@ -749,6 +783,17 @@ public class RangerGdsValidator {
return ret;
}
+
+ private GdsPermission getHigherPrivilegePermission(GdsPermission permission1, GdsPermission permission2) {
+ GdsPermission ret = permission1;
+
+ if (permission2 != null) {
+ ret = permission1.compareTo(permission2) > 0 ? permission1 : permission2;
+ }
+
+ return ret;
+ }
+
public class ValidationResult {
private final List<ValidationFailureDetails> validationFailures = new ArrayList<>();
diff --git a/security-admin/src/main/resources/META-INF/jpa_named_queries.xml b/security-admin/src/main/resources/META-INF/jpa_named_queries.xml
index f02101f09..41a9bfef6 100755
--- a/security-admin/src/main/resources/META-INF/jpa_named_queries.xml
+++ b/security-admin/src/main/resources/META-INF/jpa_named_queries.xml
@@ -2122,6 +2122,13 @@
<query>select obj from XXPolicy obj where obj.zoneId = :zoneId</query>
</named-query>
+ <named-query name="XXPolicy.findByServiceType">
+ <query>SELECT obj FROM XXPolicy obj
+ JOIN XXService xs ON obj.service = xs.id
+ JOIN XXServiceDef xsd ON xsd.id = xs.type
+ WHERE xsd.name = :serviceType</query>
+ </named-query>
+
<named-query name="XXGdsDataset.findByGuid">
<query>select obj from XXGdsDataset obj where obj.guid = :guid</query>
</named-query>
@@ -2250,4 +2257,10 @@
<named-query name="XXGdsDatasetInProject.findByProjectId">
<query>select obj from XXGdsDatasetInProject obj where obj.projectId = :projectId</query>
</named-query>
+
+ <named-query name="XXGdsDataShareInDataset.getDataSharesInDatasetCountByStatus">
+ <query>SELECT obj.status, COUNT(obj) FROM XXGdsDataShareInDataset obj
+ WHERE obj.datasetId = :datasetId
+ GROUP BY obj.status</query>
+ </named-query>
</entity-mappings>