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 <such...@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 <mad...@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>