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 e11431f8cc9fb643754f95e467f10331e32bcf5e Author: Madhan Neethiraj <[email protected]> AuthorDate: Thu Mar 9 02:15:07 2023 -0800 RANGER-4035: added catagory to access-types; added marker access-types.patch --- .../ranger/plugin/model/RangerServiceDef.java | 63 ++- .../model/validation/RangerPolicyValidator.java | 24 ++ .../model/validation/RangerServiceDefHelper.java | 48 +++ .../plugin/model/validation/RangerValidator.java | 8 + .../RangerAuditPolicyEvaluator.java | 6 +- .../RangerDefaultPolicyEvaluator.java | 33 +- .../apache/ranger/plugin/util/ServiceDefUtil.java | 174 ++++++-- .../model/validation/TestRangerValidator.java | 2 + .../plugin/policyengine/TestPolicyEngine.java | 7 + .../ranger/plugin/util/ServiceDefUtilTest.java | 147 +++++++ .../test_policyengine_marker_access_types.json | 435 +++++++++++++++++++ .../test/resources/test_servicedef-normalize.json | 478 +++++++++++++++++++++ .../apache_ranger/model/ranger_service_def.py | 50 +-- .../org/apache/ranger/biz/PolicyRefUpdater.java | 5 + .../java/org/apache/ranger/biz/ServiceDBStore.java | 3 + .../service/RangerServiceDefServiceBase.java | 2 + 16 files changed, 1388 insertions(+), 97 deletions(-) diff --git a/agents-common/src/main/java/org/apache/ranger/plugin/model/RangerServiceDef.java b/agents-common/src/main/java/org/apache/ranger/plugin/model/RangerServiceDef.java index e70a16592..375c6f335 100644 --- a/agents-common/src/main/java/org/apache/ranger/plugin/model/RangerServiceDef.java +++ b/agents-common/src/main/java/org/apache/ranger/plugin/model/RangerServiceDef.java @@ -65,6 +65,7 @@ public class RangerServiceDef extends RangerBaseModelObject implements java.io.S private List<RangerEnumDef> enums; private RangerDataMaskDef dataMaskDef; private RangerRowFilterDef rowFilterDef; + private List<RangerAccessTypeDef> markerAccessTypes; // read-only public RangerServiceDef() { this(null, null, null, null, null, null, null, null, null, null, null, null, null); @@ -104,6 +105,7 @@ public class RangerServiceDef extends RangerBaseModelObject implements java.io.S setEnums(enums); setDataMaskDef(dataMaskDef); setRowFilterDef(rowFilterDef); + setMarkerAccessTypes(null); } public RangerServiceDef(String name, String displayName, String implClass, String label, String description, @@ -137,6 +139,7 @@ public class RangerServiceDef extends RangerBaseModelObject implements java.io.S setEnums(other.getEnums()); setDataMaskDef(other.getDataMaskDef()); setRowFilterDef(other.getRowFilterDef()); + setMarkerAccessTypes(other.getMarkerAccessTypes()); } /** @@ -421,6 +424,26 @@ public class RangerServiceDef extends RangerBaseModelObject implements java.io.S this.rowFilterDef = rowFilterDef == null ? new RangerRowFilterDef() : rowFilterDef; } + public List<RangerAccessTypeDef> getMarkerAccessTypes() { + return markerAccessTypes; + } + + public void setMarkerAccessTypes(List<RangerAccessTypeDef> markerAccessTypes) { + if (this.markerAccessTypes == null) { + this.markerAccessTypes = new ArrayList<>(); + } + + if (this.markerAccessTypes == markerAccessTypes) { + return; + } + + this.markerAccessTypes.clear(); + + if(markerAccessTypes != null) { + this.markerAccessTypes.addAll(markerAccessTypes); + } + } + public String getDisplayName() { return displayName; } @@ -481,6 +504,12 @@ public class RangerServiceDef extends RangerBaseModelObject implements java.io.S if (rowFilterDef != null) { rowFilterDef.dedupStrings(strTbl); } + + if (markerAccessTypes != null) { + for (RangerAccessTypeDef accessType : markerAccessTypes) { + accessType.dedupStrings(strTbl); + } + } } @Override @@ -585,6 +614,16 @@ public class RangerServiceDef extends RangerBaseModelObject implements java.io.S } sb.append("} "); + sb.append("markerAccessTypes={"); + if(markerAccessTypes != null) { + for(RangerAccessTypeDef accessType : markerAccessTypes) { + if(accessType != null) { + accessType.toString(sb); + } + } + } + sb.append("} "); + sb.append("}"); return sb; @@ -1925,22 +1964,34 @@ public class RangerServiceDef extends RangerBaseModelObject implements java.io.S public static class RangerAccessTypeDef implements java.io.Serializable { private static final long serialVersionUID = 1L; + public enum AccessTypeCategory { CREATE, READ, UPDATE, DELETE, MANAGE } + private Long itemId; private String name; private String label; private String rbKeyLabel; private Collection<String> impliedGrants; + private AccessTypeCategory category; public RangerAccessTypeDef() { - this(null, null, null, null, null); + this(null, null, null, null, null, null); + } + + public RangerAccessTypeDef(String name) { + this(null, name, name, null, null, null); } public RangerAccessTypeDef(Long itemId, String name, String label, String rbKeyLabel, Collection<String> impliedGrants) { + this(itemId, name, label, rbKeyLabel, impliedGrants, null); + } + + public RangerAccessTypeDef(Long itemId, String name, String label, String rbKeyLabel, Collection<String> impliedGrants, AccessTypeCategory category) { setItemId(itemId); setName(name); setLabel(label); setRbKeyLabel(rbKeyLabel); setImpliedGrants(impliedGrants); + setCategory(category); } public RangerAccessTypeDef(RangerAccessTypeDef other) { @@ -1949,6 +2000,7 @@ public class RangerServiceDef extends RangerBaseModelObject implements java.io.S setLabel(other.getLabel()); setRbKeyLabel(other.getRbKeyLabel()); setImpliedGrants(other.getImpliedGrants()); + setCategory((other.getCategory())); } /** @@ -2033,6 +2085,14 @@ public class RangerServiceDef extends RangerBaseModelObject implements java.io.S } } + public AccessTypeCategory getCategory() { + return category; + } + + public void setCategory(AccessTypeCategory category) { + this.category = category; + } + public void dedupStrings(Map<String, String> strTbl) { name = StringUtil.dedupString(name, strTbl); label = StringUtil.dedupString(label, strTbl); @@ -2065,6 +2125,7 @@ public class RangerServiceDef extends RangerBaseModelObject implements java.io.S } } sb.append("} "); + sb.append("category={").append(category).append("} "); sb.append("}"); diff --git a/agents-common/src/main/java/org/apache/ranger/plugin/model/validation/RangerPolicyValidator.java b/agents-common/src/main/java/org/apache/ranger/plugin/model/validation/RangerPolicyValidator.java index e1b5fe8f1..30d8ed0fe 100644 --- a/agents-common/src/main/java/org/apache/ranger/plugin/model/validation/RangerPolicyValidator.java +++ b/agents-common/src/main/java/org/apache/ranger/plugin/model/validation/RangerPolicyValidator.java @@ -415,6 +415,18 @@ public class RangerPolicyValidator extends RangerValidator { for(RangerAccessTypeDef rangerAccessTypeDef:serviceDef.getRowFilterDef().getAccessTypes()){ rowFilterAccessTypeDefNames.add(rangerAccessTypeDef.getName().toLowerCase()); } + + if (serviceDef.getMarkerAccessTypes() != null) { + for (RangerAccessTypeDef accessTypeDef : serviceDef.getMarkerAccessTypes()) { + if (accessTypeDef == null || accessTypeDef.getImpliedGrants() == null) { + continue; + } + + if (CollectionUtils.containsAny(accessTypeDef.getImpliedGrants(), rowFilterAccessTypeDefNames)) { + rowFilterAccessTypeDefNames.add(accessTypeDef.getName()); + } + } + } } } @@ -445,6 +457,18 @@ public class RangerPolicyValidator extends RangerValidator { for(RangerAccessTypeDef rangerAccessTypeDef:serviceDef.getDataMaskDef().getAccessTypes()){ dataMaskAccessTypeDefNames.add(rangerAccessTypeDef.getName().toLowerCase()); } + + if (serviceDef.getMarkerAccessTypes() != null) { + for (RangerAccessTypeDef accessTypeDef : serviceDef.getMarkerAccessTypes()) { + if (accessTypeDef == null || accessTypeDef.getImpliedGrants() == null) { + continue; + } + + if (CollectionUtils.containsAny(accessTypeDef.getImpliedGrants(), dataMaskAccessTypeDefNames)) { + dataMaskAccessTypeDefNames.add(accessTypeDef.getName()); + } + } + } } } 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 4e287f9a4..025ea2ea4 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 @@ -36,6 +36,7 @@ import org.apache.commons.collections.CollectionUtils; 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.model.RangerServiceDef.RangerAccessTypeDef; import org.apache.ranger.plugin.model.RangerServiceDef.RangerResourceDef; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -311,6 +312,10 @@ public class RangerServiceDefHelper { return _delegate.getWildcardEnabledResourceDef(resourceName, policyType); } + public Map<String, Collection<String>> getImpliedAccessGrants() { + return _delegate.getImpliedAccessGrants(); + } + /** * Not designed for public access. Package level only for testability. */ @@ -323,6 +328,7 @@ public class RangerServiceDefHelper { final boolean _checkForCycles; final boolean _valid; final List<String> _orderedResourceNames; + final Map<String, Collection<String>> _impliedGrants; final static Set<List<RangerResourceDef>> EMPTY_RESOURCE_HIERARCHY = Collections.unmodifiableSet(new HashSet<List<RangerResourceDef>>()); @@ -352,6 +358,8 @@ public class RangerServiceDefHelper { } } + _impliedGrants = computeImpliedGrants(); + if (isValid) { _orderedResourceNames = buildSortedResourceNames(); } else { @@ -611,6 +619,46 @@ public class RangerServiceDefHelper { return this._orderedResourceNames; } + Map<String, Collection<String>> getImpliedAccessGrants() { return _impliedGrants; } + + private Map<String, Collection<String>> computeImpliedGrants() { + Map<String, Collection<String>> ret = new HashMap<>(); + + if (_serviceDef != null && CollectionUtils.isNotEmpty(_serviceDef.getAccessTypes())) { + for(RangerAccessTypeDef accessTypeDef : _serviceDef.getAccessTypes()) { + if(CollectionUtils.isNotEmpty(accessTypeDef.getImpliedGrants())) { + Collection<String> impliedAccessGrants = ret.get(accessTypeDef.getName()); + + if(impliedAccessGrants == null) { + impliedAccessGrants = new HashSet<>(); + + ret.put(accessTypeDef.getName(), impliedAccessGrants); + } + + impliedAccessGrants.addAll(accessTypeDef.getImpliedGrants()); + } + } + + if (_serviceDef.getMarkerAccessTypes() != null) { + for (RangerAccessTypeDef accessTypeDef : _serviceDef.getMarkerAccessTypes()) { + if(CollectionUtils.isNotEmpty(accessTypeDef.getImpliedGrants())) { + Collection<String> impliedAccessGrants = ret.get(accessTypeDef.getName()); + + if(impliedAccessGrants == null) { + impliedAccessGrants = new HashSet<>(); + + ret.put(accessTypeDef.getName(), impliedAccessGrants); + } + + impliedAccessGrants.addAll(accessTypeDef.getImpliedGrants()); + } + } + } + } + + return ret; + } + private static class ResourceNameLevel implements Comparable<ResourceNameLevel> { private String resourceName; private int level; diff --git a/agents-common/src/main/java/org/apache/ranger/plugin/model/validation/RangerValidator.java b/agents-common/src/main/java/org/apache/ranger/plugin/model/validation/RangerValidator.java index d47be1404..73f822836 100644 --- a/agents-common/src/main/java/org/apache/ranger/plugin/model/validation/RangerValidator.java +++ b/agents-common/src/main/java/org/apache/ranger/plugin/model/validation/RangerValidator.java @@ -434,6 +434,14 @@ public abstract class RangerValidator { } } } + + if (serviceDef.getMarkerAccessTypes() != null) { + for (RangerAccessTypeDef accessTypeDef : serviceDef.getMarkerAccessTypes()) { + if (accessTypeDef != null) { + accessTypes.add(accessTypeDef.getName()); + } + } + } } if(LOG.isDebugEnabled()) { diff --git a/agents-common/src/main/java/org/apache/ranger/plugin/policyevaluator/RangerAuditPolicyEvaluator.java b/agents-common/src/main/java/org/apache/ranger/plugin/policyevaluator/RangerAuditPolicyEvaluator.java index 1c46f184c..44ba838b4 100644 --- a/agents-common/src/main/java/org/apache/ranger/plugin/policyevaluator/RangerAuditPolicyEvaluator.java +++ b/agents-common/src/main/java/org/apache/ranger/plugin/policyevaluator/RangerAuditPolicyEvaluator.java @@ -100,10 +100,10 @@ public class RangerAuditPolicyEvaluator extends RangerDefaultPolicyEvaluator { } @Override - protected void preprocessPolicy(RangerPolicy policy, RangerServiceDef serviceDef) { - super.preprocessPolicy(policy, serviceDef); + protected void preprocessPolicy(RangerPolicy policy, RangerServiceDef serviceDef, RangerPolicyEngineOptions options) { + super.preprocessPolicy(policy, serviceDef, options); - Map<String, Collection<String>> impliedAccessGrants = getImpliedAccessGrants(serviceDef); + Map<String, Collection<String>> impliedAccessGrants = options.getServiceDefHelper().getImpliedAccessGrants(); if (impliedAccessGrants == null || impliedAccessGrants.isEmpty()) { return; diff --git a/agents-common/src/main/java/org/apache/ranger/plugin/policyevaluator/RangerDefaultPolicyEvaluator.java b/agents-common/src/main/java/org/apache/ranger/plugin/policyevaluator/RangerDefaultPolicyEvaluator.java index 2f9c1b019..855d52942 100644 --- a/agents-common/src/main/java/org/apache/ranger/plugin/policyevaluator/RangerDefaultPolicyEvaluator.java +++ b/agents-common/src/main/java/org/apache/ranger/plugin/policyevaluator/RangerDefaultPolicyEvaluator.java @@ -23,7 +23,6 @@ import java.util.ArrayList; import java.util.Collection; import java.util.Collections; import java.util.Date; -import java.util.HashMap; import java.util.HashSet; import java.util.List; import java.util.Map; @@ -113,7 +112,7 @@ public class RangerDefaultPolicyEvaluator extends RangerAbstractPolicyEvaluator policy = getPolicy(); - preprocessPolicy(policy, serviceDef); + preprocessPolicy(policy, serviceDef, options); if(policy != null) { validityScheduleEvaluators = createValidityScheduleEvaluators(policy); @@ -1145,12 +1144,12 @@ public class RangerDefaultPolicyEvaluator extends RangerAbstractPolicyEvaluator return sb; } - protected void preprocessPolicy(RangerPolicy policy, RangerServiceDef serviceDef) { + protected void preprocessPolicy(RangerPolicy policy, RangerServiceDef serviceDef, RangerPolicyEngineOptions options) { if(policy == null || (!hasAllow() && !hasDeny()) || serviceDef == null) { return; } - Map<String, Collection<String>> impliedAccessGrants = getImpliedAccessGrants(serviceDef); + Map<String, Collection<String>> impliedAccessGrants = options.getServiceDefHelper().getImpliedAccessGrants(); if(impliedAccessGrants == null || impliedAccessGrants.isEmpty()) { return; @@ -1199,32 +1198,6 @@ public class RangerDefaultPolicyEvaluator extends RangerAbstractPolicyEvaluator } } - protected Map<String, Collection<String>> getImpliedAccessGrants(RangerServiceDef serviceDef) { - Map<String, Collection<String>> ret = null; - - if(serviceDef != null && !CollectionUtils.isEmpty(serviceDef.getAccessTypes())) { - for(RangerAccessTypeDef accessTypeDef : serviceDef.getAccessTypes()) { - if(!CollectionUtils.isEmpty(accessTypeDef.getImpliedGrants())) { - if(ret == null) { - ret = new HashMap<>(); - } - - Collection<String> impliedAccessGrants = ret.get(accessTypeDef.getName()); - - if(impliedAccessGrants == null) { - impliedAccessGrants = new HashSet<>(); - - ret.put(accessTypeDef.getName(), impliedAccessGrants); - } - - impliedAccessGrants.addAll(accessTypeDef.getImpliedGrants()); - } - } - } - - return ret; - } - private RangerPolicyItemAccess getAccess(RangerPolicyItem policyItem, String accessType) { RangerPolicyItemAccess ret = null; diff --git a/agents-common/src/main/java/org/apache/ranger/plugin/util/ServiceDefUtil.java b/agents-common/src/main/java/org/apache/ranger/plugin/util/ServiceDefUtil.java index 4808dfd83..db63c936a 100644 --- a/agents-common/src/main/java/org/apache/ranger/plugin/util/ServiceDefUtil.java +++ b/agents-common/src/main/java/org/apache/ranger/plugin/util/ServiceDefUtil.java @@ -48,15 +48,39 @@ import java.util.ArrayList; import java.util.Collection; import java.util.Collections; import java.util.HashSet; +import java.util.LinkedHashSet; import java.util.List; import java.util.HashMap; import java.util.Map; +import java.util.Set; public class ServiceDefUtil { private static final Logger LOG = LoggerFactory.getLogger(ServiceDefUtil.class); private static final String USER_STORE_ENRICHER = RangerUserStoreEnricher.class.getCanonicalName(); + + public static final String ACCESS_TYPE_MARKER_CREATE = "_CREATE"; + public static final String ACCESS_TYPE_MARKER_READ = "_READ"; + public static final String ACCESS_TYPE_MARKER_UPDATE = "_UPDATE"; + public static final String ACCESS_TYPE_MARKER_DELETE = "_DELETE"; + public static final String ACCESS_TYPE_MARKER_MANAGE = "_MANAGE"; + public static final String ACCESS_TYPE_MARKER_ALL = "_ALL"; + public static final Set<String> ACCESS_TYPE_MARKERS; + + static { + Set<String> typeMarkers = new LinkedHashSet<>(); + + typeMarkers.add(ACCESS_TYPE_MARKER_CREATE); + typeMarkers.add(ACCESS_TYPE_MARKER_READ); + typeMarkers.add(ACCESS_TYPE_MARKER_UPDATE); + typeMarkers.add(ACCESS_TYPE_MARKER_DELETE); + typeMarkers.add(ACCESS_TYPE_MARKER_MANAGE); + typeMarkers.add(ACCESS_TYPE_MARKER_ALL); + + ACCESS_TYPE_MARKERS = Collections.unmodifiableSet(typeMarkers); + } + public static boolean getOption_enableDenyAndExceptionsInPolicies(RangerServiceDef serviceDef, RangerPluginContext pluginContext) { boolean ret = false; @@ -204,65 +228,67 @@ public class ServiceDefUtil { } public static RangerServiceDef normalizeAccessTypeDefs(RangerServiceDef serviceDef, final String componentType) { - if (serviceDef != null && StringUtils.isNotBlank(componentType)) { + normalizeAccessTypeDefs(serviceDef.getAccessTypes(), componentType); + normalizeAccessTypeDefs(serviceDef.getMarkerAccessTypes(), componentType); - List<RangerServiceDef.RangerAccessTypeDef> accessTypeDefs = serviceDef.getAccessTypes(); - - if (CollectionUtils.isNotEmpty(accessTypeDefs)) { - - String prefix = componentType + AbstractServiceStore.COMPONENT_ACCESSTYPE_SEPARATOR; - - List<RangerServiceDef.RangerAccessTypeDef> unneededAccessTypeDefs = null; - - for (RangerServiceDef.RangerAccessTypeDef accessTypeDef : accessTypeDefs) { - - String accessType = accessTypeDef.getName(); + if (serviceDef.getDataMaskDef() != null) { + normalizeAccessTypeDefs(serviceDef.getDataMaskDef().getAccessTypes(), componentType); + } - if (StringUtils.startsWith(accessType, prefix)) { + if (serviceDef.getRowFilterDef() != null) { + normalizeAccessTypeDefs(serviceDef.getRowFilterDef().getAccessTypes(), componentType); + } + } - String newAccessType = StringUtils.removeStart(accessType, prefix); + return serviceDef; + } - accessTypeDef.setName(newAccessType); + private static void normalizeAccessTypeDefs(List<RangerAccessTypeDef> accessTypeDefs, String componentType) { + if (CollectionUtils.isNotEmpty(accessTypeDefs)) { + String prefix = componentType + AbstractServiceStore.COMPONENT_ACCESSTYPE_SEPARATOR; + List<RangerAccessTypeDef> unneededAccessTypeDefs = null; - Collection<String> impliedGrants = accessTypeDef.getImpliedGrants(); + for (RangerAccessTypeDef accessTypeDef : accessTypeDefs) { + String accessType = accessTypeDef.getName(); - if (CollectionUtils.isNotEmpty(impliedGrants)) { + if (StringUtils.startsWith(accessType, prefix)) { + String newAccessType = StringUtils.removeStart(accessType, prefix); - Collection<String> newImpliedGrants = null; + accessTypeDef.setName(newAccessType); + } else if (StringUtils.contains(accessType, AbstractServiceStore.COMPONENT_ACCESSTYPE_SEPARATOR)) { + if (unneededAccessTypeDefs == null) { + unneededAccessTypeDefs = new ArrayList<>(); + } - for (String impliedGrant : impliedGrants) { + unneededAccessTypeDefs.add(accessTypeDef); - if (StringUtils.startsWith(impliedGrant, prefix)) { + continue; + } - String newImpliedGrant = StringUtils.removeStart(impliedGrant, prefix); + Collection<String> impliedGrants = accessTypeDef.getImpliedGrants(); - if (newImpliedGrants == null) { - newImpliedGrants = new ArrayList<>(); - } + if (CollectionUtils.isNotEmpty(impliedGrants)) { + Set<String> newImpliedGrants = new HashSet<>(); - newImpliedGrants.add(newImpliedGrant); - } - } - accessTypeDef.setImpliedGrants(newImpliedGrants); + for (String impliedGrant : impliedGrants) { + if (StringUtils.startsWith(impliedGrant, prefix)) { + String newImpliedGrant = StringUtils.removeStart(impliedGrant, prefix); + newImpliedGrants.add(newImpliedGrant); + } else if (!StringUtils.contains(impliedGrant, AbstractServiceStore.COMPONENT_ACCESSTYPE_SEPARATOR)) { + newImpliedGrants.add(impliedGrant); } - } else if (StringUtils.contains(accessType, AbstractServiceStore.COMPONENT_ACCESSTYPE_SEPARATOR)) { - if(unneededAccessTypeDefs == null) { - unneededAccessTypeDefs = new ArrayList<>(); - } - - unneededAccessTypeDefs.add(accessTypeDef); } - } - if(unneededAccessTypeDefs != null) { - accessTypeDefs.removeAll(unneededAccessTypeDefs); + accessTypeDef.setImpliedGrants(newImpliedGrants); } } - } - return serviceDef; + if (unneededAccessTypeDefs != null) { + accessTypeDefs.removeAll(unneededAccessTypeDefs); + } + } } private static void normalizeDataMaskDef(RangerServiceDef serviceDef) { @@ -585,6 +611,76 @@ public class ServiceDefUtil { return ret; } + public static List<RangerAccessTypeDef> getMarkerAccessTypes(List<RangerAccessTypeDef> accessTypeDefs) { + List<RangerAccessTypeDef> ret = new ArrayList<>(); + Map<String, Set<String>> markerTypeGrants = getMarkerAccessTypeGrants(accessTypeDefs); + long maxItemId = getMaxItemId(accessTypeDefs); + + for (String accessTypeMarker : ACCESS_TYPE_MARKERS) { + RangerAccessTypeDef accessTypeDef = new RangerAccessTypeDef(++maxItemId, accessTypeMarker, accessTypeMarker, null, markerTypeGrants.get(accessTypeMarker)); + + ret.add(accessTypeDef); + } + + return ret; + } + + private static Map<String, Set<String>> getMarkerAccessTypeGrants(List<RangerAccessTypeDef> accessTypeDefs) { + Map<String, Set<String>> ret = new HashMap<>(); + + for (String accessTypeMarker : ACCESS_TYPE_MARKERS) { + ret.put(accessTypeMarker, new HashSet<>()); + } + + if (CollectionUtils.isNotEmpty(accessTypeDefs)) { + for (RangerAccessTypeDef accessTypeDef : accessTypeDefs) { + if (accessTypeDef == null || StringUtils.isBlank(accessTypeDef.getName()) || ACCESS_TYPE_MARKERS.contains(accessTypeDef.getName())) { + continue; + } + + addToMarkerGrants(accessTypeDef, ret.get(ACCESS_TYPE_MARKER_ALL)); + + if (accessTypeDef.getCategory() == null) { + continue; + } else if (accessTypeDef.getCategory() == RangerAccessTypeDef.AccessTypeCategory.CREATE) { + addToMarkerGrants(accessTypeDef, ret.get(ACCESS_TYPE_MARKER_CREATE)); + } else if (accessTypeDef.getCategory() == RangerAccessTypeDef.AccessTypeCategory.READ) { + addToMarkerGrants(accessTypeDef, ret.get(ACCESS_TYPE_MARKER_READ)); + } else if (accessTypeDef.getCategory() == RangerAccessTypeDef.AccessTypeCategory.UPDATE) { + addToMarkerGrants(accessTypeDef, ret.get(ACCESS_TYPE_MARKER_UPDATE)); + } else if (accessTypeDef.getCategory() == RangerAccessTypeDef.AccessTypeCategory.DELETE) { + addToMarkerGrants(accessTypeDef, ret.get(ACCESS_TYPE_MARKER_DELETE)); + } else if (accessTypeDef.getCategory() == RangerAccessTypeDef.AccessTypeCategory.MANAGE) { + addToMarkerGrants(accessTypeDef, ret.get(ACCESS_TYPE_MARKER_MANAGE)); + } + } + } + + return ret; + } + + private static void addToMarkerGrants(RangerAccessTypeDef accessTypeDef, Set<String> markerGrants) { + markerGrants.add(accessTypeDef.getName()); + + if (CollectionUtils.isNotEmpty(accessTypeDef.getImpliedGrants())) { + markerGrants.addAll(accessTypeDef.getImpliedGrants()); + } + } + + private static long getMaxItemId(List<RangerAccessTypeDef> accessTypeDefs) { + long ret = -1; + + if (CollectionUtils.isNotEmpty(accessTypeDefs)) { + for (RangerAccessTypeDef accessTypeDef : accessTypeDefs) { + if (accessTypeDef.getItemId() != null && ret < accessTypeDef.getItemId()) { + ret = accessTypeDef.getItemId(); + } + } + } + + return ret; + } + private static boolean anyPolicyHasUserGroupAttributeExpression(List<RangerPolicy> policies) { boolean ret = false; diff --git a/agents-common/src/test/java/org/apache/ranger/plugin/model/validation/TestRangerValidator.java b/agents-common/src/test/java/org/apache/ranger/plugin/model/validation/TestRangerValidator.java index 6114225ca..3d5248ad6 100644 --- a/agents-common/src/test/java/org/apache/ranger/plugin/model/validation/TestRangerValidator.java +++ b/agents-common/src/test/java/org/apache/ranger/plugin/model/validation/TestRangerValidator.java @@ -41,6 +41,7 @@ import org.apache.ranger.plugin.model.RangerServiceDef.RangerResourceDef; import org.apache.ranger.plugin.model.RangerServiceDef.RangerServiceConfigDef; import org.apache.ranger.plugin.model.validation.RangerValidator.Action; import org.apache.ranger.plugin.store.ServiceStore; +import org.apache.ranger.plugin.util.ServiceDefUtil; import org.junit.Assert; import org.junit.Before; import org.junit.Test; @@ -258,6 +259,7 @@ public class TestRangerValidator { String[] names = new String[] { null, "", "a", " ", "b ", " ", " C", " D " }; accessTypeDefs.addAll(_utils.createAccessTypeDefs(names)); accessTypes = _validator.getAccessTypes(serviceDef); + accessTypes.removeAll(ServiceDefUtil.ACCESS_TYPE_MARKERS); Assert.assertEquals(4, accessTypes.size()); Assert.assertTrue(accessTypes.contains("a")); Assert.assertTrue(accessTypes.contains("b ")); diff --git a/agents-common/src/test/java/org/apache/ranger/plugin/policyengine/TestPolicyEngine.java b/agents-common/src/test/java/org/apache/ranger/plugin/policyengine/TestPolicyEngine.java index b2a5151e5..776b58480 100644 --- a/agents-common/src/test/java/org/apache/ranger/plugin/policyengine/TestPolicyEngine.java +++ b/agents-common/src/test/java/org/apache/ranger/plugin/policyengine/TestPolicyEngine.java @@ -482,6 +482,13 @@ public class TestPolicyEngine { runTestsFromResourceFiles(resourceFiles); } + @Test + public void testPolicyEngin_markerAccessTypes() { + String[] resourceFiles = {"/policyengine/test_policyengine_marker_access_types.json"}; + + runTestsFromResourceFiles(resourceFiles); + } + private void runTestsFromResourceFiles(String[] resourceNames) { for(String resourceName : resourceNames) { InputStream inStream = this.getClass().getResourceAsStream(resourceName); diff --git a/agents-common/src/test/java/org/apache/ranger/plugin/util/ServiceDefUtilTest.java b/agents-common/src/test/java/org/apache/ranger/plugin/util/ServiceDefUtilTest.java index 3cd42f44f..147cdaf2b 100644 --- a/agents-common/src/test/java/org/apache/ranger/plugin/util/ServiceDefUtilTest.java +++ b/agents-common/src/test/java/org/apache/ranger/plugin/util/ServiceDefUtilTest.java @@ -17,6 +17,9 @@ package org.apache.ranger.plugin.util; +import com.google.gson.Gson; +import com.google.gson.GsonBuilder; +import org.apache.commons.lang.StringUtils; import org.apache.ranger.plugin.contextenricher.RangerAdminUserStoreRetriever; import org.apache.ranger.plugin.model.RangerPolicy; import org.apache.ranger.plugin.model.RangerPolicy.RangerDataMaskPolicyItem; @@ -28,17 +31,28 @@ import org.apache.ranger.plugin.model.RangerPolicy.RangerRowFilterPolicyItem; import org.apache.ranger.plugin.model.RangerPolicy.RangerPolicyResource; import org.apache.ranger.plugin.model.RangerPolicyDelta; import org.apache.ranger.plugin.model.RangerServiceDef; +import org.apache.ranger.plugin.model.RangerServiceDef.RangerAccessTypeDef; +import org.apache.ranger.plugin.model.RangerServiceDef.RangerAccessTypeDef.AccessTypeCategory; import org.apache.ranger.plugin.store.EmbeddedServiceDefsUtil; 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.util.ArrayList; +import java.util.Arrays; import java.util.Collections; import java.util.HashMap; +import java.util.HashSet; import java.util.List; +import java.util.Set; +import static org.apache.ranger.plugin.util.ServiceDefUtil.*; +import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotEquals; import static org.junit.Assert.assertTrue; public class ServiceDefUtilTest { @@ -68,6 +82,13 @@ public class ServiceDefUtilTest { REF_USER_ATTR_NAMES_CSV_F, REF_USER_ATTR_NAMES_Q_CSV_F }; + static Gson gsonBuilder; + + @BeforeClass + public static void setUpBeforeClass() throws Exception { + gsonBuilder = new GsonBuilder().setDateFormat("yyyyMMdd-HH:mm:ss.SSSZ").setPrettyPrinting().create(); + } + @Test public void testNoUserGroupAttrRef() { ServicePolicies svcPolicies = getServicePolicies(); @@ -252,6 +273,132 @@ public class ServiceDefUtilTest { } } + @Test + public void testNormalizeAccessTypeDefs() throws Exception { + try (InputStream inStream = this.getClass().getResourceAsStream("/test_servicedef-normalize.json")) { + InputStreamReader reader = new InputStreamReader(inStream); + ServicePolicies policies = gsonBuilder.fromJson(reader, ServicePolicies.class); + + RangerAccessTypeDef serviceMarkerAll = getAccessType(policies.getServiceDef().getMarkerAccessTypes(), ACCESS_TYPE_MARKER_ALL); + RangerAccessTypeDef tagMarkerAll = getAccessType(policies.getTagPolicies().getServiceDef().getMarkerAccessTypes(), ACCESS_TYPE_MARKER_ALL); + + assertNotEquals("accessType count", policies.getServiceDef().getAccessTypes().size(), policies.getTagPolicies().getServiceDef().getAccessTypes().size()); + assertNotEquals("impliedGrants: _ALL", new HashSet<>(serviceMarkerAll.getImpliedGrants()), new HashSet<>(tagMarkerAll.getImpliedGrants())); + assertNotEquals("dataMask.accessType count", policies.getServiceDef().getDataMaskDef().getAccessTypes().size(), policies.getTagPolicies().getServiceDef().getDataMaskDef().getAccessTypes().size()); + assertNotEquals("rowFilter.accessType count", policies.getServiceDef().getRowFilterDef().getAccessTypes().size(), policies.getTagPolicies().getServiceDef().getRowFilterDef().getAccessTypes().size()); + + ServiceDefUtil.normalizeAccessTypeDefs(policies.getTagPolicies().getServiceDef(), policies.getServiceDef().getName()); + + serviceMarkerAll = getAccessType(policies.getServiceDef().getMarkerAccessTypes(), ACCESS_TYPE_MARKER_ALL); + tagMarkerAll = getAccessType(policies.getTagPolicies().getServiceDef().getMarkerAccessTypes(), ACCESS_TYPE_MARKER_ALL); + + assertEquals("accessType count", policies.getServiceDef().getAccessTypes().size(), policies.getTagPolicies().getServiceDef().getAccessTypes().size()); + assertEquals("impliedGrants: _ALL", new HashSet<>(serviceMarkerAll.getImpliedGrants()), new HashSet<>(tagMarkerAll.getImpliedGrants())); + assertEquals("dataMask.accessType count", policies.getServiceDef().getDataMaskDef().getAccessTypes().size(), policies.getTagPolicies().getServiceDef().getDataMaskDef().getAccessTypes().size()); + assertEquals("rowFilter.accessType count", 0, policies.getTagPolicies().getServiceDef().getRowFilterDef().getAccessTypes().size()); + } + } + + private RangerAccessTypeDef getAccessType(List<RangerAccessTypeDef> accessTypeDefs, String accessType) { + RangerAccessTypeDef ret = null; + + if (accessTypeDefs != null) { + for (RangerAccessTypeDef accessTypeDef : accessTypeDefs) { + if (StringUtils.equals(accessTypeDef.getName(), accessType)) { + ret = accessTypeDef; + + break; + } + } + } + + return ret; + } + + @Test + public void testAccessTypeMarkers() { + RangerAccessTypeDef create = new RangerAccessTypeDef(1L, "create", "create", null, null, AccessTypeCategory.CREATE); + RangerAccessTypeDef select = new RangerAccessTypeDef(2L, "select", "select", null, null, AccessTypeCategory.READ); + RangerAccessTypeDef update = new RangerAccessTypeDef(3L, "update", "update", null, null, AccessTypeCategory.UPDATE); + RangerAccessTypeDef delete = new RangerAccessTypeDef(4L, "delete", "delete", null, null, AccessTypeCategory.DELETE); + RangerAccessTypeDef manage = new RangerAccessTypeDef(5L, "manage", "manage", null, null, AccessTypeCategory.MANAGE); + RangerAccessTypeDef read = new RangerAccessTypeDef(6L, "read", "read", null, null, AccessTypeCategory.READ); + RangerAccessTypeDef write = new RangerAccessTypeDef(7L, "write", "write", null, null, AccessTypeCategory.UPDATE); + RangerAccessTypeDef execute = new RangerAccessTypeDef(8L, "execute", "execute", null, null, null); + Set<String> allNames = toSet(create.getName(), select.getName(), update.getName(), delete.getName(), manage.getName(), read.getName(), write.getName(), execute.getName()); + + // 6 marker access-types should be populated with impliedGrants + List<RangerAccessTypeDef> accessTypeDefs = Arrays.asList(create, select, update, delete, manage, read, write, execute); + List<RangerAccessTypeDef> markerTypeDefs = ServiceDefUtil.getMarkerAccessTypes(accessTypeDefs); + assertEquals("markerTypeDefs count", 6, markerTypeDefs.size()); + assertEquals("impliedGrants in " + ACCESS_TYPE_MARKER_CREATE, toSet(create.getName()), getImpliedGrants(markerTypeDefs, ACCESS_TYPE_MARKER_CREATE)); + assertEquals("impliedGrants in " + ACCESS_TYPE_MARKER_READ, toSet(select.getName(), read.getName()), getImpliedGrants(markerTypeDefs, ACCESS_TYPE_MARKER_READ)); + assertEquals("impliedGrants in " + ACCESS_TYPE_MARKER_UPDATE, toSet(update.getName(), write.getName()), getImpliedGrants(markerTypeDefs, ACCESS_TYPE_MARKER_UPDATE)); + assertEquals("impliedGrants in " + ACCESS_TYPE_MARKER_DELETE, toSet(delete.getName()), getImpliedGrants(markerTypeDefs, ACCESS_TYPE_MARKER_DELETE)); + assertEquals("impliedGrants in " + ACCESS_TYPE_MARKER_MANAGE, toSet(manage.getName()), getImpliedGrants(markerTypeDefs, ACCESS_TYPE_MARKER_MANAGE)); + assertEquals("impliedGrants in " + ACCESS_TYPE_MARKER_ALL, allNames, getImpliedGrants(markerTypeDefs, ACCESS_TYPE_MARKER_ALL)); + + // 2 marker access-types should be populated with impliedGrants: _CREATE, _ALL + accessTypeDefs = new ArrayList<>(Collections.singleton(create)); + markerTypeDefs = ServiceDefUtil.getMarkerAccessTypes(accessTypeDefs); + assertEquals("markerTypeDefs count", 6, markerTypeDefs.size()); + assertEquals("impliedGrants in " + ACCESS_TYPE_MARKER_CREATE, toSet(create.getName()), getImpliedGrants(markerTypeDefs, ACCESS_TYPE_MARKER_CREATE)); + assertEquals("impliedGrants in " + ACCESS_TYPE_MARKER_READ, Collections.emptySet(), getImpliedGrants(markerTypeDefs, ACCESS_TYPE_MARKER_READ)); + assertEquals("impliedGrants in " + ACCESS_TYPE_MARKER_UPDATE, Collections.emptySet(), getImpliedGrants(markerTypeDefs, ACCESS_TYPE_MARKER_UPDATE)); + assertEquals("impliedGrants in " + ACCESS_TYPE_MARKER_DELETE, Collections.emptySet(), getImpliedGrants(markerTypeDefs, ACCESS_TYPE_MARKER_DELETE)); + assertEquals("impliedGrants in " + ACCESS_TYPE_MARKER_MANAGE, Collections.emptySet(), getImpliedGrants(markerTypeDefs, ACCESS_TYPE_MARKER_MANAGE)); + assertEquals("impliedGrants in " + ACCESS_TYPE_MARKER_ALL, toSet(create.getName()), getImpliedGrants(markerTypeDefs, ACCESS_TYPE_MARKER_ALL)); + + // 2 marker access-types should be populated with impliedGrants: _READ, _ALL + accessTypeDefs = new ArrayList<>(Arrays.asList(select, read)); + markerTypeDefs = ServiceDefUtil.getMarkerAccessTypes(accessTypeDefs); + assertEquals("markerTypeDefs count", 6, markerTypeDefs.size()); + assertEquals("impliedGrants in " + ACCESS_TYPE_MARKER_CREATE, Collections.emptySet(), getImpliedGrants(markerTypeDefs, ACCESS_TYPE_MARKER_CREATE)); + assertEquals("impliedGrants in " + ACCESS_TYPE_MARKER_READ, toSet(select.getName(), read.getName()), getImpliedGrants(markerTypeDefs, ACCESS_TYPE_MARKER_READ)); + assertEquals("impliedGrants in " + ACCESS_TYPE_MARKER_UPDATE, Collections.emptySet(), getImpliedGrants(markerTypeDefs, ACCESS_TYPE_MARKER_UPDATE)); + assertEquals("impliedGrants in " + ACCESS_TYPE_MARKER_DELETE, Collections.emptySet(), getImpliedGrants(markerTypeDefs, ACCESS_TYPE_MARKER_DELETE)); + assertEquals("impliedGrants in " + ACCESS_TYPE_MARKER_MANAGE, Collections.emptySet(), getImpliedGrants(markerTypeDefs, ACCESS_TYPE_MARKER_MANAGE)); + assertEquals("impliedGrants in " + ACCESS_TYPE_MARKER_ALL, toSet(select.getName(), read.getName()), getImpliedGrants(markerTypeDefs, ACCESS_TYPE_MARKER_ALL)); + + // accessTypes with no category should be added to _ALL + accessTypeDefs = new ArrayList<>(Collections.singleton(execute)); + markerTypeDefs = ServiceDefUtil.getMarkerAccessTypes(accessTypeDefs); + assertEquals("markerTypeDefs count", 6, markerTypeDefs.size()); // 1 marker access-types should be added: _ALL + assertEquals("impliedGrants in " + ACCESS_TYPE_MARKER_CREATE, Collections.emptySet(), getImpliedGrants(markerTypeDefs, ACCESS_TYPE_MARKER_CREATE)); + assertEquals("impliedGrants in " + ACCESS_TYPE_MARKER_READ, Collections.emptySet(), getImpliedGrants(markerTypeDefs, ACCESS_TYPE_MARKER_READ)); + assertEquals("impliedGrants in " + ACCESS_TYPE_MARKER_UPDATE, Collections.emptySet(), getImpliedGrants(markerTypeDefs, ACCESS_TYPE_MARKER_UPDATE)); + assertEquals("impliedGrants in " + ACCESS_TYPE_MARKER_DELETE, Collections.emptySet(), getImpliedGrants(markerTypeDefs, ACCESS_TYPE_MARKER_DELETE)); + assertEquals("impliedGrants in " + ACCESS_TYPE_MARKER_MANAGE, Collections.emptySet(), getImpliedGrants(markerTypeDefs, ACCESS_TYPE_MARKER_MANAGE)); + assertEquals("impliedGrants in " + ACCESS_TYPE_MARKER_ALL, toSet(execute.getName()), getImpliedGrants(markerTypeDefs, ACCESS_TYPE_MARKER_ALL)); + } + + private Set<String> getImpliedGrants(List<RangerAccessTypeDef> accessTypeDefs, String accessType) { + Set<String> ret = null; + + if (accessTypeDefs != null) { + for (RangerAccessTypeDef accessTypeDef : accessTypeDefs) { + if (StringUtils.equals(accessTypeDef.getName(), accessType)) { + ret = new HashSet<>(accessTypeDef.getImpliedGrants()); + + break; + } + } + } + + return ret; + } + + private Set<String> toSet(String...values) { + Set<String> ret = new HashSet<>(); + + if (values != null) { + for (String value : values) { + ret.add(value); + } + } + + return ret; + } private ServicePolicies getServicePolicies() { ServicePolicies ret = new ServicePolicies(); diff --git a/agents-common/src/test/resources/policyengine/test_policyengine_marker_access_types.json b/agents-common/src/test/resources/policyengine/test_policyengine_marker_access_types.json new file mode 100644 index 000000000..a18523b60 --- /dev/null +++ b/agents-common/src/test/resources/policyengine/test_policyengine_marker_access_types.json @@ -0,0 +1,435 @@ +{ + "serviceName": "hivedev", + + "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" } + ], + "markerAccessTypes": [ + { "name": "_CREATE", "label": "_CREATE", "impliedGrants": [ "create", "alter" ] }, + { "name": "_READ", "label": "_READ", "impliedGrants": [ "select", "read" ] }, + { "name": "_UPDATE", "label": "_UPDATE", "impliedGrants": [ "update", "write" ] }, + { "name": "_DELETE", "label": "_DELETE", "impliedGrants": [ "drop", "alter" ] }, + { "name": "_MANAGE", "label": "_MANAGE", "impliedGrants": [ "index", "lock", "repladmin", "serviceadmin" ] }, + { "name": "_ALL", "label": "_ALL", "impliedGrants": [ "select", "update", "create", "drop", "alter", "index", "lock", "read", "write", "repladmin", "serviceadmin" ] } + ] + }, + + "policies": [ + { "id": 1, "name": "db=default: audit-all-access", "isEnabled": true, "isAuditEnabled": true, + "resources": { "database": { "values": [ "default" ] }, "table": { "values": [ "*" ] }, "column": { "values": [ "*" ] } } + }, + { "id": 2, "name": "db=default; table=test*; column=*", "isEnabled": true, "isAuditEnabled": true, + "resources": { "database": { "values": [ "default" ] }, "table": { "values": [ "test*" ] }, "column": { "values": [ "*" ] } }, + "policyItems": [ + { "accesses": [ { "type": "_READ", "isAllowed": true } ], "users": [ "user1", "user2" ], "groups": [ "group1", "group2" ], "delegateAdmin": false }, + { "accesses": [ { "type": "_CREATE", "isAllowed": true }, { "type": "_DELETE", "isAllowed": true } ], "users": [ "admin" ], "groups": [ "admin" ], "delegateAdmin": true } + ] + }, + { "id": 3, "name": "db=db1; table=tbl*; column=*", "isEnabled": true, "isAuditEnabled": true, + "resources": { "database": { "values": [ "db1" ] }, "table": { "values": [ "tbl*" ] }, "column": { "values": [ "*" ] } }, + "policyItems": [ + { "accesses": [ { "type": "_READ", "isAllowed": true } ], "users": [ "user1", "user2" ], "groups": [ "group1", "group2" ], "delegateAdmin": false } + ] + }, + { "id": 4, "name": "db=db1; table=tmp; column=tmp*", "isEnabled": true, "isAuditEnabled": true, + "resources": { "database": { "values": [ "db1" ] }, "table": { "values": [ "tmp" ] }, "column": { "values": [ "tmp*" ], "isExcludes": true } }, + "policyItems": [ + { "accesses": [ { "type": "_READ", "isAllowed": true } ], "users": [ "user1", "user2" ], "groups": [ "group1", "group2" ], "delegateAdmin": false } + ] + }, + { "id": 5, "name": "hiveservice=*", "isEnabled": true, "isAuditEnabled": true, + "resources": { "hiveservice": { "values": [ "*" ] } }, + "policyItems": [ + { "accesses": [ { "type": "_MANAGE", "isAllowed": true } ], "users": [ "user1" ], "groups": [], "delegateAdmin": false } + ] + }, + { "id": 6, "name": "db=demo1,demo2", "isEnabled": true, "isAuditEnabled": true, + "resources": { "database": { "values": [ "demo1", "demo2" ] } }, + "policyItems": [ + { "accesses": [ { "type": "_READ", "isAllowed": true } ], "users": [ "user1", "user2" ], "groups": [ "group1", "group2" ], "delegateAdmin": false } + ] + }, + { "id": 7, "name": "db=demo1; table=demo1_tbl1,demo1_tbl2; column=*", "isEnabled": true, "isAuditEnabled": true, + "resources": { "database": { "values": [ "demo1" ] }, "table": { "values": [ "demo1_tbl1", "demo1_tbl2" ] }, "column": { "values": [ "*" ] } }, + "policyItems": [ + { "accesses": [ { "type": "_CREATE", "isAllowed": true } ], "users": [ "user1", "user2" ], "groups": [ "group1", "group2" ], "delegateAdmin": false } + ] + }, + { "id": 8, "name": "db=dummy; table=*; column=*", "isEnabled": true, "isAuditEnabled": true, + "resources": { "database": { "values": [ "dummy" ] }, "table": { "values": [ "*" ] }, "column": { "values": [ "*" ] } }, + "policyItems": [ + { "accesses": [ { "type": "_CREATE", "isAllowed": true }, { "type": "_UPDATE", "isAllowed": true }, { "type": "_DELETE", "isAllowed": true } ], "users": [ "user1", "user2" ], "groups": [], "delegateAdmin": false } + ], + "allowExceptions": [ + { "accesses": [ { "type": "_CREATE", "isAllowed": true }, { "type": "_UPDATE", "isAllowed": true } ], "users": [ "user1" ], "groups": [], "delegateAdmin": false }, + { "accesses": [ { "type": "_CREATE", "isAllowed": true }, { "type": "_UPDATE", "isAllowed": true }, { "type": "_DELETE", "isAllowed": true } ], "users": [ "user2" ], "groups": [], "delegateAdmin": false } + ] + }, + { "id": 9, "name": "db=db1", "isEnabled": true, "isAuditEnabled": true, + "resources": { "database": { "values": [ "db1" ] } }, + "isDenyAllElse": true, + "policyItems": [ + { "accesses": [ { "type": "_READ", "isAllowed": true } ], "users": [ "user1", "user3", "user4" ], "groups": [ "group1", "group2" ], "delegateAdmin": false } + ] + }, + { "id": 200, "name": "url=s3a://qe-s3-bucket-mst/test_abcd/abcd; s3a://qe-s3-bucket-mst/demo/*: URL-access-policy", "isEnabled": true, "isAuditEnabled": true, + "resources": { "url": { "values": [ "s3a://qe-s3-bucket-mst/test_abcd/abcd", "s3a://qe-s3-bucket-mst/demo" ], "isRecursive": true } }, + "policyItems": [ + { "accesses": [ { "type": "_READ", "isAllowed": true }, { "type": "_UPDATE", "isAllowed": true } ], "users": [], "groups": [ "public" ], "delegateAdmin": false } + ] + }, + { "id": 201, "name": "url=http://qe-s3-bucket-mst/test_abcd/abcd/ URL-access-policy", "isEnabled": true, "isAuditEnabled": true, + "resources": { "url": { "values": [ "http://qe-s3-bucket-mst/test_abcd/abcd/" ], "isRecursive": true } }, + "policyItems": [ + { "accesses": [ { "type": "_READ", "isAllowed": true }, { "type": "_UPDATE", "isAllowed": true } ], "users": [ "user1" ], "groups": [], "delegateAdmin": false } + ] + } + ], + + "tests": [ + { "name": "ALLOW 'read http://qe-s3-bucket-mst/test_abcd/abcd;' for user1", + "request": { + "resource": { "elements": { "url": [ "http://qe-s3-bucket-mst/test_abcd/abcd", "http://qe-s3-bucket-mst/test_abcd/abcd/" ] } }, + "accessType": "read", "user": "user1", "userGroups": [ "users" ], "requestData": "read http://qe-s3-bucket-mst/test_abcd/abcd for user1" + }, + "result": { "isAudited": true, "isAllowed": true, "policyId": 201 } + }, + { "name": "ALLOW '_any access to no-database' for user5: match when request has less levels than policy", + "request": { + "resource": { "elements": {} }, + "accessType": "", "user": "user5", "userGroups": [ "users" ], "requestData": "show databases" + }, + "result": { "isAudited": true, "isAllowed": true, "policyId": 200 } + }, + { "name": "ALLOW '_any access to db1' for user5: match when request has less levels than policy", + "request": { + "resource": { "elements": { "database": "db1" } }, + "accessType": "", "user": "user5", "userGroups": [ "users" ], "requestData": "use db1" + }, + "result": { "isAudited": true, "isAllowed": false, "policyId": 9 } + }, + { "name": "DENY '_any access to db1' for user5: match when request has less levels than policy", + "request": { + "resource": { "elements": { "database": "db1" } }, + "accessType": "", "user": "user5", "userGroups": [ "users" ], "requestData": "use db1" + }, + "result": { "isAudited": true, "isAllowed": false, "policyId": 9 } + }, + { "name": "ALLOW 'any dummy/*/*;' for user1", + "request": { + "resource": { "elements": { "database": "dummy", "table": "dummy", "column": "dummy" } }, + "accessType": "", "user": "user1", "userGroups": [ "users" ], "requestData": "any dummy/dummy/dummy for user1" + }, + "result": { "isAudited": true, "isAllowed": true, "policyId": 8 } + }, + { "name": "DENY 'any dummy/*/*;' for user2", + "request": { + "resource": { "elements": { "database": "dummy", "table": "dummy", "column": "dummy" } }, + "accessType": "", "user": "user2", "userGroups": [ "users" ], "requestData": "any dummy/dummy/dummy for user2" + }, + "result": { "isAudited": true, "isAllowed": false, "policyId": -1 } + }, + { "name": "ALLOW 'read s3a://qe-s3-bucket-mst/demo;' for user1", + "request": { + "resource": { "elements": { "url": "s3a://qe-s3-bucket-mst/demo" } }, + "accessType": "read", "user": "user1", "userGroups": [ "users" ], "requestData": "read s3a://qe-s3-bucket-mst/demo for user1" + }, + "result": { "isAudited": true, "isAllowed": true, "policyId": 200 } + }, + { "name": "ALLOW 'read s3a://qe-s3-bucket-mst/test_abcd/abcd;' for user1", + "request": { + "resource": { "elements": { "url": "s3a://qe-s3-bucket-mst/test_abcd/abcd" } }, + "accessType": "read", "user": "user1", "userGroups": [ "users" ], "requestData": "read s3a://qe-s3-bucket-mst/test_abcd/abcd for user1" + }, + "result": { "isAudited": true, "isAllowed": true, "policyId": 200 } + }, + { "name": "ALLOW 'read s3a://qe-s3-bucket-mst/test_abcd/abcd/non-existent;' for user1", + "request": { + "resource": { "elements": { "url": "s3a://qe-s3-bucket-mst/test_abcd/abcd/non-existent" } }, + "accessType": "read", "user": "user1", "userGroups": [ "users" ], "requestData": "read s3a://qe-s3-bucket-mst/test_abcd/abcd/non-existent for user1" + }, + "result": { "isAudited": true, "isAllowed": true, "policyId": 200 } + }, + { "name": "ALLOW 'write s3a://qe-s3-bucket-mst/test_abcd/abcd/non-existent;' for user1", + "request": { + "resource": { "elements": { "url": "s3a://qe-s3-bucket-mst/test_abcd/abcd/non-existent" } }, + "accessType": "write", "user": "user1", "userGroups": [ "users" ], "requestData": "write s3a://qe-s3-bucket-mst/test_abcd/abcd/non-existent for user1" + }, + "result": { "isAudited": true, "isAllowed": true, "policyId": 200 } + }, + { "name": "DENY 'select tmp_1 from db1.tmp ;' for user1", + "request": { + "resource": { "elements": { "database": "db1", "table": "tmp", "column": "tmp_1" } }, + "accessType": "select", "user": "user1", "userGroups": [ "users" ], "requestData": "select tmp_1 from db1.tmp for user1" + , "remoteIPAddress": "1.1.1.1", "forwardedAddresses": [ "127.0.0.1", "10.10.10.10" ] + }, + "result": { "isAudited": false, "isAllowed": false, "policyId": -1 } + }, + { "name": "ALLOW 'select abc_1 from db1.tmp ;' for user1", + "request": { + "resource": { "elements": { "database": "db1", "table": "tmp", "column": "abc_1" } }, + "accessType": "select", "user": "user1", "userGroups": [ "users" ], "requestData": "select abc_1 from db1.tmp for user1" + }, + "result": { "isAudited": true, "isAllowed": true, "policyId": 4 } + }, + { "name": "ALLOW 'use default;' for user1", + "request": { + "resource": { "elements": { "database": "default" } }, + "accessType": "", "user": "user1", "userGroups": [ "users" ], "requestData": "use default" + }, + "result": { "isAudited": true, "isAllowed": true, "policyId": 2 } + }, + { "name": "ALLOW 'use default;' for user2", + "request": { + "resource": { "elements": { "database": "default" } }, + "accessType": "", "user": "user2", "userGroups": [ "users" ], "requestData": "use default" + }, + "result": { "isAudited": true, "isAllowed": true, "policyId": 2 } + }, + { "name": "DENY 'use default;' to user3", + "request": { + "resource": { "elements": { "database": "default" } }, + "accessType": "", "user": "user3", "userGroups": [ "users" ], "requestData": "use default" + }, + "result": { "isAudited": true, "isAllowed": false, "policyId": -1 } + }, + { "name": "ALLOW 'use default;' to group1", + "request": { + "resource": { "elements": { "database": "default" } }, + "accessType": "", "user": "user3", "userGroups": [ "users", "group1" ], "requestData": "use default" + }, + "result": { "isAudited": true, "isAllowed": true, "policyId": 2 } + }, + { "name": "ALLOW 'use default;' to group2", + "request": { + "resource": { "elements": { "database": "default" } }, + "accessType": "", "user": "user3", "userGroups": [ "users", "group2" ], "requestData": "use default" + }, + "result": { "isAudited": true, "isAllowed": true, "policyId": 2 } + }, + { "name": "DENY 'use default;' to user3/group3", + "request": { + "resource": { "elements": { "database": "default" } }, + "accessType": "", "user": "user3", "userGroups": [ "users", "group3" ], "requestData": "use default" + }, + "result": { "isAudited": true, "isAllowed": false, "policyId": -1 } + }, + { "name": "DENY 'use finance;' to user3/group3", + "request": { + "resource": { "elements": { "database": "finance" } }, + "accessType": "", "user": "user1", "userGroups": [ "users" ], "requestData": "use finance" + }, + "result": { "isAudited": false, "isAllowed": false, "policyId": -1 } + }, + { "name": "ALLOW 'select col1 from default.testtable;' to user1", + "request": { + "resource": { "elements": { "database": "default", "table": "testtable", "column": "col1" } }, + "accessType": "select", "user": "user1", "userGroups": [ "users" ], "requestData": "select col1 from default.testtable" + }, + "result": { "isAudited": true, "isAllowed": true, "policyId": 2 } + }, + { "name": "ALLOW 'select col1 from default.testtable;' to user2", + "request": { + "resource": { "elements": { "database": "default", "table": "testtable", "column": "col1" } }, + "accessType": "select", "user": "user2", "userGroups": [ "users" ], "requestData": "select col1 from default.testtable" + }, + "result": { "isAudited": true, "isAllowed": true, "policyId": 2 } + }, + { "name": "DENY 'select col1 from default.testtable;' to user3", + "request": { + "resource": { "elements": { "database": "default", "table": "testtable", "column": "col1" } }, + "accessType": "select", "user": "user3", "userGroups": [ "users" ], "requestData": "select col1 from default.testtable" + }, + "result": { "isAudited": true, "isAllowed": false, "policyId": -1 } + }, + { "name": "ALLOW 'select col1 from default.testtable;' to group1", + "request": { + "resource": { "elements": { "database": "default", "table": "testtable", "column": "col1" } }, + "accessType": "select", "user": "user3", "userGroups": [ "users", "group1" ], "requestData": "select col1 from default.testtable" + }, + "result": { "isAudited": true, "isAllowed": true, "policyId": 2 } + }, + { "name": "ALLOW 'select col1 from default.testtable;' to group2", + "request": { + "resource": { "elements": { "database": "default", "table": "testtable", "column": "col1" } }, + "accessType": "select", "user": "user3", "userGroups": [ "users", "group2" ], "requestData": "select col1 from default.testtable" + }, + "result": { "isAudited": true, "isAllowed": true, "policyId": 2 } + }, + { "name": "DENY 'select col1 from default.testtable;' to user3/group3", + "request": { + "resource": { "elements": { "database": "default", "table": "testtable", "column": "col1" } }, + "accessType": "select", "user": "user3", "userGroups": [ "users", "group3" ], "requestData": "select col1 from default.testtable" + }, + "result": { "isAudited": true, "isAllowed": false, "policyId": -1 } + }, + { "name": "DENY 'select col1 from default.table1;' to user1", + "request": { + "resource": { "elements": { "database": "default", "table": "table1", "column": "col1" } }, + "accessType": "select", "user": "user1", "userGroups": [ "users" ], "requestData": "select col1 from default.table1" + }, + "result": { "isAudited": true, "isAllowed": false, "policyId": -1 } + }, + { "name": "DENY 'create table default.testtable1;' to user1", + "request": { + "resource": { "elements": { "database": "default", "table": "testtable1" } }, + "accessType": "create", "user": "user1", "userGroups": [ "users" ], "requestData": "create table default.testtable1" + }, + "result": { "isAudited": true, "isAllowed": false, "policyId": -1 } + }, + { "name": "DENY 'create table default.testtable1;' to user1/group1", + "request": { + "resource": { "elements": { "database": "default", "table": "testtable1" } }, + "accessType": "create", "user": "user1", "userGroups": [ "users", "group1" ], "requestData": "create table default.testtable1" + }, + "result": { "isAudited": true, "isAllowed": false, "policyId": -1 } + }, + { "name": "ALLOW 'create table default.testtable1;' to admin", + "request": { + "resource": { "elements": { "database": "default", "table": "testtable1" } }, + "accessType": "create", "user": "admin", "userGroups": [ "users" ], "requestData": "create table default.testtable1" + }, + "result": { "isAudited": true, "isAllowed": true, "policyId": 2 } + }, + { "name": "ALLOW 'create table default.testtable1;' to user1/admin", + "request": { + "resource": { "elements": { "database": "default", "table": "testtable1" } }, + "accessType": "create", "user": "user1", "userGroups": [ "users", "admin" ], "requestData": "create table default.testtable1" + }, + "result": { "isAudited": true, "isAllowed": true, "policyId": 2 } + }, + { "name": "DENY 'drop table default.testtable1;' to user1", + "request": { + "resource": { "elements": { "database": "default", "table": "testtable1" } }, + "accessType": "drop", "user": "user1", "userGroups": [ "users" ], "requestData": "drop table default.testtable1" + }, + "result": { "isAudited": true, "isAllowed": false, "policyId": -1 } + }, + { "name": "DENY 'drop table default.testtable1;' to user1/group1", + "request": { + "resource": { "elements": { "database": "default", "table": "testtable1" } }, + "accessType": "drop", "user": "user1", "userGroups": [ "users", "group1" ], "requestData": "drop table default.testtable1" + }, + "result": { "isAudited": true, "isAllowed": false, "policyId": -1 } + }, + { "name": "ALLOW 'drop table default.testtable1;' to admin", + "request": { + "resource": { "elements": { "database": "default", "table": "testtable1" } }, + "accessType": "drop", "user": "admin", "userGroups": [ "users" ], "requestData": "drop table default.testtable1" + }, + "result": { "isAudited": true, "isAllowed": true, "policyId": 2 } + }, + { "name": "ALLOW 'drop table default.testtable1;' to user1/admin", + "request": { + "resource": { "elements": { "database": "default", "table": "testtable1" } }, + "accessType": "drop", "user": "user1", "userGroups": [ "users", "admin" ], "requestData": "drop table default.testtable1" + }, + "result": { "isAudited": true, "isAllowed": true, "policyId": 2 } + }, + { "name": "DENY 'create table default.table1;' to user1", + "request": { + "resource": { "elements": { "database": "default", "table": "table1" } }, + "accessType": "create", "user": "user1", "userGroups": [ "users" ], "requestData": "create table default.testtable1" + }, + "result": { "isAudited": true, "isAllowed": false, "policyId": -1 } + }, + { "name": "DENY 'create table default.table1;' to user1/admin", + "request": { + "resource": { "elements": { "database": "default", "table": "table1" } }, + "accessType": "create", "user": "user1", "userGroups": [ "users", "admin" ], "requestData": "create table default.testtable1" + }, + "result": { "isAudited": true, "isAllowed": false, "policyId": -1 } + }, + { "name": "DENY 'drop table default.table1;' to user1", + "request": { + "resource": { "elements": { "database": "default", "table": "table1" } }, + "accessType": "drop", "user": "user1", "userGroups": [ "users" ], "requestData": "drop table default.testtable1" + }, + "result": { "isAudited": true, "isAllowed": false, "policyId": -1 } + }, + { "name": "DENY 'drop table default.table1;' to user1/admin", + "request": { + "resource": { "elements": { "database": "default", "table": "table1" } }, + "accessType": "drop", "user": "user1", "userGroups": [ "users", "admin" ], "requestData": "drop table default.testtable1" + }, + "result": { "isAudited": true, "isAllowed": false, "policyId": -1 } + }, + { "name": "DENY 'select col1 from default.table1;' to user3", + "request": { + "resource": { "elements": { "database": "default", "table": "table1", "column": "col1" } }, + "accessType": "select", "user": "user3", "userGroups": [ "users" ], "requestData": "select col1 from default.table1" + }, + "result": { "isAudited": true, "isAllowed": false, "policyId": -1 } + }, + { "name": "DENY '_any access to db1/table1' for user1: table-level mismatch", + "request": { + "resource": { "elements": { "database": "db1", "table": "table1" } }, + "accessType": "", "user": "user1", "userGroups": [ "users" ], "requestData": "show columns in table1 from db1;" + }, + "result": { "isAudited": true, "isAllowed": false, "policyId": -1 } + }, + { "name": "DENY '_any access to db1/_/col1' for user1: table not specified but column was specified", + "request": { + "resource": { "elements": { "database": "db1", "column": "col1" } }, + "accessType": "", "user": "user1", "userGroups": [ "users" ], "requestData": "fictional use case when request specified a lower level resource by skipping intermediate resource" + }, + "result": { "isAudited": false, "isAllowed": false, "policyId": -1 } + }, + { "name": "ALLOW '_any access to db1' for user1: match when request has less levels than policy", + "request": { + "resource": { "elements": { "database": "db1" } }, + "accessType": "", "user": "user1", "userGroups": [ "users" ], "requestData": "use db1" + }, + "result": { "isAudited": true, "isAllowed": true, "policyId": 3 } + }, + { "name": "ALLOW '_any access to db1/tbl1' for user1: match when request has same levels as policy", + "request": { + "resource": { "elements": { "database": "db1", "table": "tbl1" } }, + "accessType": "", "user": "user1", "userGroups": [ "users" ], "requestData": "describe db1.tbl1" + }, + "result": { "isAudited": true, "isAllowed": true, "policyId": 3 } + }, + { "name": "ALLOW '_any access to db1/tbl1/col1' for user1: match when request has more specific levels than policy", + "request": { + "resource": { "elements": { "database": "db1", "table": "tbl1", "column": "col1" } }, + "accessType": "", "user": "user1", "userGroups": [ "users" ], "requestData": "fictional case: request for any match today happens only at a higher levels" + }, + "result": { "isAudited": true, "isAllowed": true, "policyId": 3 } + }, + { "name": "ALLOW 'kill_query' for user1 on any cluster", + "request": { + "resource": { "elements": { "hiveservice": "testcluster" } }, + "accessType": "serviceadmin", "user": "user1", "userGroups": [ "users" ], "requestData": "kill query 'dummyqueryid'" + }, + "result": { "isAudited": true, "isAllowed": true, "policyId": 5 } + }, + { "name": "ALLOW '_any access to demo1/demo_tbl1' for user1: show table test", + "request": { + "resource": { "elements": { "database": "demo1", "table": "demo1_tbl1" } }, + "accessType": "", "user": "user1", "userGroups": [ "users" ], "requestData": "show tables" + }, + "result": { "isAudited": true, "isAllowed": true, "policyId": 7 } + } + ] +} + diff --git a/agents-common/src/test/resources/test_servicedef-normalize.json b/agents-common/src/test/resources/test_servicedef-normalize.json new file mode 100644 index 000000000..52825f4f5 --- /dev/null +++ b/agents-common/src/test/resources/test_servicedef-normalize.json @@ -0,0 +1,478 @@ +{ + "serviceId": 4, + "serviceName": "dev_hive", + "serviceDef": { + "id": 3, + "isEnabled": true, + "name": "hive", + "displayName": "Hadoop SQL", + "implClass": "org.apache.ranger.services.hive.RangerServiceHive", + "label": "Hive Server2", + "description": "Hive Server2", + "options": { "enableDenyAndExceptionsInPolicies": "true" }, + "configs": [ + { "itemId": 1, "name": "username", "type": "string", "mandatory": true }, + { "itemId": 2, "name": "password", "type": "password", "mandatory": true }, + { "itemId": 3, "name": "jdbc.driverClassName", "type": "string", "mandatory": true, "defaultValue": "org.apache.hive.jdbc.HiveDriver" }, + { "itemId": 4, "name": "jdbc.url", "type": "string", "mandatory": true }, + { "itemId": 5, "name": "commonNameForCertificate", "type": "string", "mandatory": false }, + { "itemId": 6, "name": "ranger.plugin.audit.filters", "type": "string", "mandatory": false, "defaultValue": "[ {'accessResult': 'DENIED', 'isAudited': true}, {'actions':['METADATA OPERATION'], 'isAudited': false}, {'users':['hive','hue'],'actions':['SHOW_ROLES'],'isAudited':false} ]" } + ], + "resources": [ + { "itemId": 1, "name": "database", "type": "string", "level": 10, "mandatory": true, "lookupSupported": true, "recursiveSupported": false, "excludesSupported": true, "matcher": "org.apache.ranger.plugin.resourcematcher.RangerDefaultResourceMatcher", "matcherOptions": { "wildCard": "true", "ignoreCase": "true" }, "label": "Hive Database", "description": "Hive Database", "accessTypeRestrictions": [], "isValidLeaf": true }, + { "itemId": 2, "name": "table", "type": "string", "level": 20, "parent": "database", "mandatory": true, "lookupSupported": true, "recursiveSupported": false, "excludesSupported": true, "matcher": "org.apache.ranger.plugin.resourcematcher.RangerDefaultResourceMatcher", "matcherOptions": { "wildCard": "true", "ignoreCase": "true" }, "label": "Hive Table", "description": "Hive Table", "accessTypeRestrictions": [], "isValidLeaf": true }, + { "itemId": 3, "name": "udf", "type": "string", "level": 20, "parent": "database", "mandatory": true, "lookupSupported": true, "recursiveSupported": false, "excludesSupported": true, "matcher": "org.apache.ranger.plugin.resourcematcher.RangerDefaultResourceMatcher", "matcherOptions": { "wildCard": "true", "ignoreCase": "true" }, "label": "Hive UDF", "description": "Hive UDF", "accessTypeRestrictions": [], "isValidLeaf": true }, + { "itemId": 4, "name": "column", "type": "string", "level": 30, "parent": "table", "mandatory": true, "lookupSupported": true, "recursiveSupported": false, "excludesSupported": true, "matcher": "org.apache.ranger.plugin.resourcematcher.RangerDefaultResourceMatcher", "matcherOptions": { "wildCard": "true", "ignoreCase": "true" }, "label": "Hive Column", "description": "Hive Column", "accessTypeRestrictions": [], "isValidLeaf": true }, + { "itemId": 5, "name": "url", "type": "string", "level": 10, "mandatory": true, "lookupSupported": false, "recursiveSupported": true, "excludesSupported": false, "matcher": "org.apache.ranger.plugin.resourcematcher.RangerURLResourceMatcher", "matcherOptions": { "wildCard": "true", "ignoreCase": "false" }, "label": "URL", "description": "URL", "accessTypeRestrictions": [], "isValidLeaf": true }, + { "itemId": 6, "name": "hiveservice", "type": "string", "level": 10, "mandatory": true, "lookupSupported": false, "recursiveSupported": false, "excludesSupported": false, "matcher": "org.apache.ranger.plugin.resourcematcher.RangerDefaultResourceMatcher", "matcherOptions": { "wildCard": "true", "ignoreCase": "false" }, "label": "Hive Service", "description": "Hive Service", "accessTypeRestrictions": [], "isValidLeaf": true }, + { "itemId": 7, "name": "global", "type": "string", "level": 10, "mandatory": false, "lookupSupported": false, "recursiveSupported": false, "excludesSupported": false, "matcher": "org.apache.ranger.plugin.resourcematcher.RangerDefaultResourceMatcher", "matcherOptions": { "wildCard": "true", "ignoreCase": "false" }, "label": "Global", "description": "Global", "accessTypeRestrictions": [], "isValidLeaf": true } + ], + "accessTypes": [ + { "itemId": 1, "name": "select", "label": "select" }, + { "itemId": 2, "name": "update", "label": "update" }, + { "itemId": 3, "name": "create", "label": "Create" }, + { "itemId": 4, "name": "drop", "label": "Drop" }, + { "itemId": 5, "name": "alter", "label": "Alter" }, + { "itemId": 6, "name": "index", "label": "Index" }, + { "itemId": 7, "name": "lock", "label": "Lock" }, + { "itemId": 8, "name": "all", "label": "All", "impliedGrants": [ "select", "update", "create", "drop", "alter", "index", "lock", "read", "write", "repladmin", "serviceadmin", "refresh" ] }, + { "itemId": 9, "name": "read", "label": "Read" }, + { "itemId": 10, "name": "write", "label": "Write" }, + { "itemId": 11, "name": "repladmin", "label": "ReplAdmin" }, + { "itemId": 12, "name": "serviceadmin", "label": "Service Admin" }, + { "itemId": 13, "name": "tempudfadmin", "label": "Temporary UDF Admin" }, + { "itemId": 14, "name": "refresh", "label": "Refresh" } + ], + "policyConditions": [], + "contextEnrichers": [], + "enums": [], + "dataMaskDef": { + "maskTypes": [ + { "itemId": 1, "name": "MASK", "label": "Redact", "description": "Replace lowercase with 'x', uppercase with 'X', digits with '0'", "transformer": "mask({col})", "dataMaskOptions": {} }, + { "itemId": 2, "name": "MASK_SHOW_LAST_4", "label": "Partial mask: show last 4", "description": "Show last 4 characters; replace rest with 'x'", "transformer": "mask_show_last_n({col}, 4, 'x', 'x', 'x', -1, '1')", "dataMaskOptions": {} }, + { "itemId": 3, "name": "MASK_SHOW_FIRST_4", "label": "Partial mask: show first 4", "description": "Show first 4 characters; replace rest with 'x'", "transformer": "mask_show_first_n({col}, 4, 'x', 'x', 'x', -1, '1')", "dataMaskOptions": {} }, + { "itemId": 4, "name": "MASK_HASH", "label": "Hash", "description": "Hash the value", "transformer": "mask_hash({col})", "dataMaskOptions": {} }, + { "itemId": 5, "name": "MASK_NULL", "label": "Nullify", "description": "Replace with NULL", "dataMaskOptions": {} }, + { "itemId": 6, "name": "MASK_NONE", "label": "Unmasked (retain original value)", "description": "No masking", "dataMaskOptions": {} }, + { "itemId": 12, "name": "MASK_DATE_SHOW_YEAR", "label": "Date: show only year", "description": "Date: show only year", "transformer": "mask({col}, 'x', 'x', 'x', -1, '1', 1, 0, -1)", "dataMaskOptions": {} }, + { "itemId": 13, "name": "CUSTOM", "label": "Custom", "description": "Custom", "dataMaskOptions": {} } + ], + "accessTypes": [ + { "itemId": 1, "name": "select", "label": "select" } + ], + "resources": [ + { "itemId": 1, "name": "database", "type": "string", "level": 10, "mandatory": true, "lookupSupported": true, "recursiveSupported": false, "excludesSupported": false, "matcher": "org.apache.ranger.plugin.resourcematcher.RangerDefaultResourceMatcher", "matcherOptions": { "wildCard": "false", "ignoreCase": "true" }, "uiHint": "{ \"singleValue\":true }", "label": "Hive Database", "description": "Hive Database", "accessTypeRestrictions": [], "isValidLeaf": false }, + { "itemId": 2, "name": "table", "type": "string", "level": 20, "parent": "database", "mandatory": true, "lookupSupported": true, "recursiveSupported": false, "excludesSupported": false, "matcher": "org.apache.ranger.plugin.resourcematcher.RangerDefaultResourceMatcher", "matcherOptions": { "wildCard": "false", "ignoreCase": "true" }, "uiHint": "{ \"singleValue\":true }", "label": "Hive Table", "description": "Hive Table", "accessTypeRestrictions": [], "isValidLeaf": false }, + { "itemId": 4, "name": "column", "type": "string", "level": 30, "parent": "table", "mandatory": true, "lookupSupported": true, "recursiveSupported": false, "excludesSupported": false, "matcher": "org.apache.ranger.plugin.resourcematcher.RangerDefaultResourceMatcher", "matcherOptions": { "wildCard": "false", "ignoreCase": "true" }, "uiHint": "{ \"singleValue\":true }", "label": "Hive Column", "description": "Hive Column", "accessTypeRestrictions": [], "isValidLeaf": true + } + ] + }, + "rowFilterDef": { + "accessTypes": [ { "itemId": 1, "name": "select", "label": "select" } ], + "resources": [ + { "itemId": 1, "name": "database", "type": "string", "level": 10, "mandatory": true, "lookupSupported": true, "recursiveSupported": false, "excludesSupported": false, "matcher": "org.apache.ranger.plugin.resourcematcher.RangerDefaultResourceMatcher", "matcherOptions": { "wildCard": "false", "ignoreCase": "true" }, "uiHint": "{ \"singleValue\":true }", "label": "Hive Database", "description": "Hive Database", "accessTypeRestrictions": [], "isValidLeaf": false }, + { "itemId": 2, "name": "table", "type": "string", "level": 20, "parent": "database", "mandatory": true, "lookupSupported": true, "recursiveSupported": false, "excludesSupported": false, "matcher": "org.apache.ranger.plugin.resourcematcher.RangerDefaultResourceMatcher", "matcherOptions": { "wildCard": "false", "ignoreCase": "true" }, "uiHint": "{ \"singleValue\":true }", "label": "Hive Table", "description": "Hive Table", "accessTypeRestrictions": [], "isValidLeaf": true } + ] + }, + "markerAccessTypes": [ + { "itemId": 20, "name": "_ALL", "label": "_ALL", "impliedGrants": [ "drop", "all", "select", "read", "update", "index", "refresh", "tempudfadmin", "serviceadmin", "create", "lock", "repladmin", "write", "alter" ] } + ] + }, + "policies": [], + "auditMode": "audit-default", + "tagPolicies": { + "serviceId": 2, + "serviceName": "dev_tag", + "policies": [], + "serviceDef": { + "id": 100, + "name": "tag", + "isEnabled": true, + "implClass": "org.apache.ranger.services.tag.RangerServiceTag", + "options": { "enableDenyAndExceptionsInPolicies": "true", "ui.pages": "tag-based-policies" }, + "configs": [ + { "itemId": 1, "name": "ranger.plugin.audit.filters", "type": "string", "level": 1, "mandatory": false, "label": "Ranger Default Audit Filters" } + ], + "resources": [ + { "itemId": 1, "name": "tag", "type": "string", "level": 1, "mandatory": true, "lookupSupported": true, "recursiveSupported": false, "excludesSupported": false, "matcher": "org.apache.ranger.plugin.resourcematcher.RangerDefaultResourceMatcher", "matcherOptions": { "wildCard": "false", "ignoreCase": "false" }, "uiHint": "{ \"singleValue\":true }", "label": "TAG", "description": "TAG", "isValidLeaf": true } + ], + "accessTypes": [ + { "itemId": 14015, "name": "sqoop:READ", "label": "READ" }, + { "itemId": 14016, "name": "sqoop:WRITE", "label": "WRITE" }, + { "itemId": 12013, "name": "kylin:QUERY", "label": "QUERY" }, + { "itemId": 12014, "name": "kylin:OPERATION", "label": "OPERATION" }, + { "itemId": 12015, "name": "kylin:MANAGEMENT", "label": "MANAGEMENT" }, + { "itemId": 12016, "name": "kylin:ADMIN", "label": "ADMIN" }, + { "itemId": 16017, "name": "elasticsearch:all", "label": "all", "impliedGrants": [ "elasticsearch:read", "elasticsearch:read_cross_cluster", "elasticsearch:index", "elasticsearch:create", "elasticsearch:delete", "elasticsearch:write", "elasticsearch:delete_index", "elasticsearch:create_index", "elasticsearch:indices_put", "elasticsearch:indices_search_shards", "elasticsearch:indices_bulk", "elasticsearch:monitor", "elasticsearch:indices_index", "elasticsearch:manage", "elasticsearch:vi [...] + { "itemId": 16018, "name": "elasticsearch:monitor", "label": "monitor" }, + { "itemId": 16019, "name": "elasticsearch:manage", "label": "manage", "impliedGrants": [ "elasticsearch:monitor" ] }, + { "itemId": 16020, "name": "elasticsearch:view_index_metadata", "label": "view_index_metadata", "impliedGrants": [ "elasticsearch:indices_search_shards" ] }, + { "itemId": 16021, "name": "elasticsearch:read", "label": "read" }, + { "itemId": 16022, "name": "elasticsearch:read_cross_cluster", "label": "read_cross_cluster", "impliedGrants": [ "elasticsearch:indices_search_shards" ] }, + { "itemId": 16023, "name": "elasticsearch:index", "label": "index", "impliedGrants": [ "elasticsearch:indices_put", "elasticsearch:indices_bulk", "elasticsearch:indices_index" ] }, + { "itemId": 16024, "name": "elasticsearch:create", "label": "create", "impliedGrants": [ "elasticsearch:indices_put", "elasticsearch:indices_bulk", "elasticsearch:indices_index" ] }, + { "itemId": 16025, "name": "elasticsearch:delete", "label": "delete", "impliedGrants": [ "elasticsearch:indices_bulk" ] }, + { "itemId": 16026, "name": "elasticsearch:write", "label": "write", "impliedGrants": [ "elasticsearch:indices_put" ] }, + { "itemId": 16027, "name": "elasticsearch:delete_index", "label": "delete_index" }, + { "itemId": 16028, "name": "elasticsearch:create_index", "label": "create_index" }, + { "itemId": 203204, "name": "trino:select", "label": "Select" }, + { "itemId": 203205, "name": "trino:insert", "label": "Insert" }, + { "itemId": 203206, "name": "trino:create", "label": "Create" }, + { "itemId": 203207, "name": "trino:drop", "label": "Drop" }, + { "itemId": 203208, "name": "trino:delete", "label": "Delete" }, + { "itemId": 203209, "name": "trino:use", "label": "Use" }, + { "itemId": 203210, "name": "trino:alter", "label": "Alter" }, + { "itemId": 203211, "name": "trino:grant", "label": "Grant" }, + { "itemId": 203212, "name": "trino:revoke", "label": "Revoke" }, + { "itemId": 203213, "name": "trino:show", "label": "Show" }, + { "itemId": 203214, "name": "trino:impersonate", "label": "Impersonate" }, + { "itemId": 203215, "name": "trino:all", "label": "All", "impliedGrants": [ "trino:execute", "trino:delete", "trino:drop", "trino:create", "trino:insert", "trino:select", "trino:revoke", "trino:impersonate", "trino:show", "trino:use", "trino:alter", "trino:grant" ] }, + { "itemId": 203216, "name": "trino:execute", "label": "execute" }, + { "itemId": 17018, "name": "presto:select", "label": "Select" }, + { "itemId": 17019, "name": "presto:insert", "label": "Insert" }, + { "itemId": 17020, "name": "presto:create", "label": "Create" }, + { "itemId": 17021, "name": "presto:drop", "label": "Drop" }, + { "itemId": 17022, "name": "presto:delete", "label": "Delete" }, + { "itemId": 17023, "name": "presto:use", "label": "Use" }, + { "itemId": 17024, "name": "presto:alter", "label": "Alter" }, + { "itemId": 17025, "name": "presto:grant", "label": "Grant" }, + { "itemId": 17026, "name": "presto:revoke", "label": "Revoke" }, + { "itemId": 17027, "name": "presto:show", "label": "Show" }, + { "itemId": 17028, "name": "presto:impersonate", "label": "Impersonate" }, + { "itemId": 17029, "name": "presto:all", "label": "All", "impliedGrants": [ "presto:use", "presto:alter", "presto:execute", "presto:impersonate", "presto:show", "presto:revoke", "presto:grant", "presto:select", "presto:insert", "presto:create", "presto:delete", "presto:drop" ] }, + { "itemId": 17030, "name": "presto:execute", "label": "execute" }, + { "itemId": 201209, "name": "ozone:all", "label": "All", "impliedGrants": [ "ozone:create", "ozone:read", "ozone:write", "ozone:list", "ozone:delete", "ozone:read_acl", "ozone:write_acl" ] }, + { "itemId": 201202, "name": "ozone:read", "label": "Read" }, + { "itemId": 201203, "name": "ozone:write", "label": "Write" }, + { "itemId": 201204, "name": "ozone:create", "label": "Create" }, + { "itemId": 201205, "name": "ozone:list", "label": "List" }, + { "itemId": 201206, "name": "ozone:delete", "label": "Delete" }, + { "itemId": 201207, "name": "ozone:read_acl", "label": "Read_ACL" }, + { "itemId": 201208, "name": "ozone:write_acl", "label": "Write_ACL" }, + { "itemId": 105106, "name": "kudu:select", "label": "SELECT", "impliedGrants": [ "kudu:metadata" ] }, + { "itemId": 105107, "name": "kudu:insert", "label": "INSERT", "impliedGrants": [ "kudu:metadata" ] }, + { "itemId": 105108, "name": "kudu:update", "label": "UPDATE", "impliedGrants": [ "kudu:metadata" ] }, + { "itemId": 105109, "name": "kudu:delete", "label": "DELETE", "impliedGrants": [ "kudu:metadata" ] }, + { "itemId": 105110, "name": "kudu:alter", "label": "ALTER", "impliedGrants": [ "kudu:metadata" ] }, + { "itemId": 105111, "name": "kudu:create", "label": "CREATE", "impliedGrants": [ "kudu:metadata" ] }, + { "itemId": 105112, "name": "kudu:drop", "label": "DROP", "impliedGrants": [ "kudu:metadata" ] }, + { "itemId": 105113, "name": "kudu:metadata", "label": "METADATA" }, + { "itemId": 105114, "name": "kudu:all", "label": "ALL", "impliedGrants": [ "kudu:insert", "kudu:update", "kudu:delete", "kudu:alter", "kudu:create", "kudu:drop", "kudu:metadata", "kudu:select" ] }, + { "itemId": 205206, "name": "nestedstructure:read", "label": "Read" }, + { "itemId": 205207, "name": "nestedstructure:write", "label": "Write" }, + { "itemId": 1002, "name": "hdfs:read", "label": "Read" }, + { "itemId": 1003, "name": "hdfs:write", "label": "Write" }, + { "itemId": 1004, "name": "hdfs:execute", "label": "Execute" }, + { "itemId": 2003, "name": "hbase:read", "label": "Read" }, + { "itemId": 2004, "name": "hbase:write", "label": "Write" }, + { "itemId": 2005, "name": "hbase:create", "label": "Create" }, + { "itemId": 2006, "name": "hbase:admin", "label": "Admin", "impliedGrants": [ "hbase:write", "hbase:create", "hbase:read" ] }, + { "itemId": 2007, "name": "hbase:execute", "label": "Execute" }, + { "itemId": 3004, "name": "hive:select", "label": "select" }, + { "itemId": 3005, "name": "hive:update", "label": "update" }, + { "itemId": 3006, "name": "hive:create", "label": "Create" }, + { "itemId": 3007, "name": "hive:drop", "label": "Drop" }, + { "itemId": 3008, "name": "hive:alter", "label": "Alter" }, + { "itemId": 3009, "name": "hive:index", "label": "Index" }, + { "itemId": 3010, "name": "hive:lock", "label": "Lock" }, + { "itemId": 3011, "name": "hive:all", "label": "All", "impliedGrants": [ "hive:read", "hive:select", "hive:update", "hive:create", "hive:drop", "hive:alter", "hive:index", "hive:lock", "hive:write", "hive:repladmin", "hive:serviceadmin", "hive:refresh" ] }, + { "itemId": 3012, "name": "hive:read", "label": "Read" }, + { "itemId": 3013, "name": "hive:write", "label": "Write" }, + { "itemId": 3014, "name": "hive:repladmin", "label": "ReplAdmin" }, + { "itemId": 3015, "name": "hive:serviceadmin", "label": "Service Admin" }, + { "itemId": 3016, "name": "hive:tempudfadmin", "label": "Temporary UDF Admin" }, + { "itemId": 3017, "name": "hive:refresh", "label": "Refresh" }, + { "itemId": 7008, "name": "kms:create", "label": "Create" }, + { "itemId": 7009, "name": "kms:delete", "label": "Delete" }, + { "itemId": 7010, "name": "kms:rollover", "label": "Rollover" }, + { "itemId": 7011, "name": "kms:setkeymaterial", "label": "Set Key Material" }, + { "itemId": 7012, "name": "kms:get", "label": "Get" }, + { "itemId": 7013, "name": "kms:getkeys", "label": "Get Keys" }, + { "itemId": 7014, "name": "kms:getmetadata", "label": "Get Metadata" }, + { "itemId": 7015, "name": "kms:generateeek", "label": "Generate EEK" }, + { "itemId": 7016, "name": "kms:decrypteek", "label": "Decrypt EEK" }, + { "itemId": 5006, "name": "knox:allow", "label": "Allow" }, + { "itemId": 6007, "name": "storm:submitTopology", "label": "Submit Topology", "impliedGrants": [ "storm:fileUpload", "storm:fileDownload" ] }, + { "itemId": 6008, "name": "storm:fileUpload", "label": "File Upload" }, + { "itemId": 6011, "name": "storm:fileDownload", "label": "File Download" }, + { "itemId": 6012, "name": "storm:killTopology", "label": "Kill Topology" }, + { "itemId": 6013, "name": "storm:rebalance", "label": "Rebalance" }, + { "itemId": 6014, "name": "storm:activate", "label": "Activate" }, + { "itemId": 6015, "name": "storm:deactivate", "label": "Deactivate" }, + { "itemId": 6016, "name": "storm:getTopologyConf", "label": "Get Topology Conf" }, + { "itemId": 6017, "name": "storm:getTopology", "label": "Get Topology" }, + { "itemId": 6018, "name": "storm:getUserTopology", "label": "Get User Topology" }, + { "itemId": 6019, "name": "storm:getTopologyInfo", "label": "Get Topology Info" }, + { "itemId": 6020, "name": "storm:uploadNewCredentials", "label": "Upload New Credential" }, + { "itemId": 4005, "name": "yarn:submit-app", "label": "submit-app" }, + { "itemId": 4006, "name": "yarn:admin-queue", "label": "admin-queue", "impliedGrants": [ "yarn:submit-app" ] }, + { "itemId": 9010, "name": "kafka:publish", "label": "Publish", "impliedGrants": [ "kafka:describe" ] }, + { "itemId": 9011, "name": "kafka:consume", "label": "Consume", "impliedGrants": [ "kafka:describe" ] }, + { "itemId": 9014, "name": "kafka:configure", "label": "Configure", "impliedGrants": [ "kafka:describe" ] }, + { "itemId": 9015, "name": "kafka:describe", "label": "Describe" }, + { "itemId": 9016, "name": "kafka:kafka_admin", "label": "Kafka Admin", "impliedGrants": [ "kafka:consume", "kafka:configure", "kafka:alter_configs", "kafka:describe_configs", "kafka:create", "kafka:describe", "kafka:alter", "kafka:idempotent_write", "kafka:cluster_action", "kafka:delete", "kafka:publish" ] }, + { "itemId": 9017, "name": "kafka:create", "label": "Create" }, + { "itemId": 9018, "name": "kafka:delete", "label": "Delete", "impliedGrants": [ "kafka:describe" ] }, + { "itemId": 9019, "name": "kafka:idempotent_write", "label": "Idempotent Write" }, + { "itemId": 9020, "name": "kafka:describe_configs", "label": "Describe Configs" }, + { "itemId": 9021, "name": "kafka:alter_configs", "label": "Alter Configs", "impliedGrants": [ "kafka:describe_configs" ] }, + { "itemId": 9022, "name": "kafka:cluster_action", "label": "Cluster Action" }, + { "itemId": 9023, "name": "kafka:alter", "label": "Alter" }, + { "itemId": 8108, "name": "solr:query", "label": "Query" }, + { "itemId": 8208, "name": "solr:update", "label": "Update" }, + { "itemId": 202203, "name": "schema-registry:create", "label": "Create" }, + { "itemId": 202204, "name": "schema-registry:read", "label": "Read" }, + { "itemId": 202205, "name": "schema-registry:update", "label": "Update" }, + { "itemId": 202206, "name": "schema-registry:delete", "label": "Delete" }, + { "itemId": 10110, "name": "nifi:READ", "label": "Read" }, + { "itemId": 10210, "name": "nifi:WRITE", "label": "Write" }, + { "itemId": 13113, "name": "nifi-registry:READ", "label": "Read" }, + { "itemId": 13213, "name": "nifi-registry:WRITE", "label": "Write" }, + { "itemId": 13313, "name": "nifi-registry:DELETE", "label": "Delete" }, + { "itemId": 15016, "name": "atlas:type-create", "label": "Create Type", "impliedGrants": [ "atlas:type-read" ] }, + { "itemId": 15017, "name": "atlas:type-update", "label": "Update Type", "impliedGrants": [ "atlas:type-read" ] }, + { "itemId": 15018, "name": "atlas:type-delete", "label": "Delete Type", "impliedGrants": [ "atlas:type-read" ] }, + { "itemId": 15019, "name": "atlas:entity-read", "label": "Read Entity" }, + { "itemId": 15020, "name": "atlas:entity-create", "label": "Create Entity" }, + { "itemId": 15021, "name": "atlas:entity-update", "label": "Update Entity" }, + { "itemId": 15022, "name": "atlas:entity-delete", "label": "Delete Entity" }, + { "itemId": 15023, "name": "atlas:entity-add-classification", "label": "Add Classification" }, + { "itemId": 15024, "name": "atlas:entity-update-classification", "label": "Update Classification" }, + { "itemId": 15025, "name": "atlas:entity-remove-classification", "label": "Remove Classification" }, + { "itemId": 15026, "name": "atlas:admin-export", "label": "Admin Export" }, + { "itemId": 15027, "name": "atlas:admin-import", "label": "Admin Import" }, + { "itemId": 15028, "name": "atlas:add-relationship", "label": "Add Relationship" }, + { "itemId": 15029, "name": "atlas:update-relationship", "label": "Update Relationship" }, + { "itemId": 15030, "name": "atlas:remove-relationship", "label": "Remove Relationship" }, + { "itemId": 15031, "name": "atlas:admin-purge", "label": "Admin Purge" }, + { "itemId": 15032, "name": "atlas:entity-add-label", "label": "Add Label" }, + { "itemId": 15033, "name": "atlas:entity-remove-label", "label": "Remove Label" }, + { "itemId": 15034, "name": "atlas:entity-update-business-metadata", "label": "Update Business Metadata" }, + { "itemId": 15035, "name": "atlas:type-read", "label": "Read Type" }, + { "itemId": 15036, "name": "atlas:admin-audits", "label": "Admin Audits" } + ], + "policyConditions": [], + "contextEnrichers": [], + "dataMaskDef": { + "maskTypes": [ + { "itemId": 203204, "name": "trino:MASK", "label": "Redact", "description": "Replace lowercase with 'x', uppercase with 'X', digits with '0'", "transformer": "cast(regexp_replace(regexp_replace(regexp_replace({col},'([A-Z])', 'X'),'([a-z])','x'),'([0-9])','0') as {type})" + }, + { "itemId": 203205, "name": "trino:MASK_SHOW_LAST_4", "label": "Partial mask: show last 4", "description": "Show last 4 characters; replace rest with 'X'", "transformer": "cast(regexp_replace({col}, '(.*)(.{4}$)', x -> regexp_replace(x[1], '.', 'X') || x[2]) as {type})" }, + { "itemId": 203206, "name": "trino:MASK_SHOW_FIRST_4", "label": "Partial mask: show first 4", "description": "Show first 4 characters; replace rest with 'x'", "transformer": "cast(regexp_replace({col}, '(^.{4})(.*)', x -> x[1] || regexp_replace(x[2], '.', 'X')) as {type})" }, + { "itemId": 203207, "name": "trino:MASK_HASH", "label": "Hash", "description": "Hash the value of a varchar with sha256", "transformer": "cast(to_hex(sha256(to_utf8({col}))) as {type})" }, + { "itemId": 203208, "name": "trino:MASK_NULL", "label": "Nullify", "description": "Replace with NULL" }, + { "itemId": 203209, "name": "trino:MASK_NONE", "label": "Unmasked (retain original value)", "description": "No masking" }, + { "itemId": 203215, "name": "trino:MASK_DATE_SHOW_YEAR", "label": "Date: show only year", "description": "Date: show only year", "transformer": "date_trunc('year', {col})" }, + { "itemId": 203216, "name": "trino:CUSTOM", "label": "Custom", "description": "Custom" }, + { "itemId": 17018, "name": "presto:MASK", "label": "Redact", "description": "Replace lowercase with 'x', uppercase with 'X', digits with '0'", "transformer": "cast(regexp_replace(regexp_replace(regexp_replace({col},'([A-Z])', 'X'),'([a-z])','x'),'([0-9])','0') as {type})" }, + { "itemId": 17019, "name": "presto:MASK_SHOW_LAST_4", "label": "Partial mask: show last 4", "description": "Show last 4 characters; replace rest with 'X'", "transformer": "cast(regexp_replace({col}, '(.*)(.{4}$)', x -> regexp_replace(x[1], '.', 'X') || x[2]) as {type})" }, + { "itemId": 17020, "name": "presto:MASK_SHOW_FIRST_4", "label": "Partial mask: show first 4", "description": "Show first 4 characters; replace rest with 'x'", "transformer": "cast(regexp_replace({col}, '(^.{4})(.*)', x -> x[1] || regexp_replace(x[2], '.', 'X')) as {type})" }, + { "itemId": 17021, "name": "presto:MASK_HASH", "label": "Hash", "description": "Hash the value of a varchar with sha256", "transformer": "cast(to_hex(sha256(to_utf8({col}))) as {type})" }, + { "itemId": 17022, "name": "presto:MASK_NULL", "label": "Nullify", "description": "Replace with NULL" }, + { "itemId": 17023, "name": "presto:MASK_NONE", "label": "Unmasked (retain original value)", "description": "No masking" }, + { "itemId": 17029, "name": "presto:MASK_DATE_SHOW_YEAR", "label": "Date: show only year", "description": "Date: show only year", "transformer": "date_trunc('year', {col})" }, + { "itemId": 17030, "name": "presto:CUSTOM", "label": "Custom", "description": "Custom" }, + { "itemId": 205206, "name": "nestedstructure:MASK", "label": "Redact", "description": "Replace lowercase with 'x', uppercase with 'X', digits with '0'", "transformer": "mask({field})" }, + { "itemId": 205207, "name": "nestedstructure:MASK_SHOW_LAST_4", "label": "Partial mask: show last 4", "description": "Show last 4 characters; replace rest with 'x'", "transformer": "mask_show_last_n({field}, 4, 'x', 'x', 'x', -1, '1')" }, + { "itemId": 205208, "name": "nestedstructure:MASK_SHOW_FIRST_4", "label": "Partial mask: show first 4", "description": "Show first 4 characters; replace rest with 'x'", "transformer": "mask_show_first_n({field}, 4, 'x', 'x', 'x', -1, '1')" }, + { "itemId": 205209, "name": "nestedstructure:MASK_HASH", "label": "Hash", "description": "Hash the value", "transformer": "mask_hash({field})" }, + { "itemId": 205210, "name": "nestedstructure:MASK_NULL", "label": "Nullify", "description": "Replace with NULL" }, + { "itemId": 205211, "name": "nestedstructure:MASK_NONE", "label": "Unmasked (retain original value)", "description": "No masking" }, + { "itemId": 205217, "name": "nestedstructure:MASK_DATE_SHOW_YEAR", "label": "Date: show only year", "description": "Date: show only year", "transformer": "mask({field}, 'x', 'x', 'x', -1, '1', 1, 0, -1)" }, + { "itemId": 205218, "name": "nestedstructure:CUSTOM", "label": "Custom", "description": "Custom" }, + { "itemId": 3004, "name": "hive:MASK", "label": "Redact", "description": "Replace lowercase with 'x', uppercase with 'X', digits with '0'", "transformer": "mask({col})" }, + { "itemId": 3005, "name": "hive:MASK_SHOW_LAST_4", "label": "Partial mask: show last 4", "description": "Show last 4 characters; replace rest with 'x'", "transformer": "mask_show_last_n({col}, 4, 'x', 'x', 'x', -1, '1')" }, + { "itemId": 3006, "name": "hive:MASK_SHOW_FIRST_4", "label": "Partial mask: show first 4", "description": "Show first 4 characters; replace rest with 'x'", "transformer": "mask_show_first_n({col}, 4, 'x', 'x', 'x', -1, '1')" }, + { "itemId": 3007, "name": "hive:MASK_HASH", "label": "Hash", "description": "Hash the value", "transformer": "mask_hash({col})" }, + { "itemId": 3008, "name": "hive:MASK_NULL", "label": "Nullify", "description": "Replace with NULL" }, + { "itemId": 3009, "name": "hive:MASK_NONE", "label": "Unmasked (retain original value)", "description": "No masking" }, + { "itemId": 3015, "name": "hive:MASK_DATE_SHOW_YEAR", "label": "Date: show only year", "description": "Date: show only year", "transformer": "mask({col}, 'x', 'x', 'x', -1, '1', 1, 0, -1)" }, + { "itemId": 3016, "name": "hive:CUSTOM", "label": "Custom", "description": "Custom" } + ], + "accessTypes": [ + { "itemId": 203204, "name": "trino:select", "label": "Select" }, + { "itemId": 17018, "name": "presto:select", "label": "Select" }, + { "itemId": 205206, "name": "nestedstructure:read", "label": "Read" }, + { "itemId": 3004, "name": "hive:select", "label": "select" } + ], + "resources": [ + { "itemId": 1, "name": "tag", "type": "string", "level": 1, "mandatory": true, "lookupSupported": true, "recursiveSupported": false, "excludesSupported": false, "matcher": "org.apache.ranger.plugin.resourcematcher.RangerDefaultResourceMatcher", "matcherOptions": { "__isValidLeaf": "true", "wildCard": "false", "__accessTypeRestrictions": "[]", "ignoreCase": "false" }, "uiHint": "{ \"singleValue\":true }", "label": "TAG", "description": "TAG", "isValidLeaf": true } + ] + }, + "rowFilterDef": {}, + "markerAccessTypes": [ + { + "itemId": 205213, + "name": "_ALL", + "label": "_ALL", + "impliedGrants": [ + "ozone:write_acl", + "kms:get", + "atlas:type-delete", + "atlas:entity-create", + "hbase:execute", + "storm:fileDownload", + "kms:getkeys", + "storm:getTopologyConf", + "ozone:create", + "hive:tempudfadmin", + "kafka:idempotent_write", + "hive:write", + "trino:use", + "trino:grant", + "hdfs:execute", + "elasticsearch:indices_index", + "atlas:admin-export", + "kafka:configure", + "atlas:entity-read", + "presto:alter", + "atlas:entity-update-classification", + "trino:select", + "presto:execute", + "kafka:describe", + "atlas:admin-purge", + "kafka:consume", + "trino:delete", + "atlas:add-relationship", + "elasticsearch:indices_bulk", + "trino:drop", + "kudu:select", + "presto:use", + "hive:serviceadmin", + "elasticsearch:create_index", + "hive:index", + "nestedstructure:read", + "kms:setkeymaterial", + "kylin:OPERATION", + "schema-registry:create", + "presto:impersonate", + "storm:deactivate", + "elasticsearch:index", + "kafka:alter", + "atlas:entity-add-classification", + "atlas:entity-remove-classification", + "atlas:entity-add-label", + "schema-registry:update", + "kafka:kafka_admin", + "presto:drop", + "hive:refresh", + "atlas:entity-delete", + "presto:all", + "atlas:entity-update", + "elasticsearch:monitor", + "trino:insert", + "kudu:update", + "schema-registry:read", + "atlas:admin-audits", + "elasticsearch:delete_index", + "presto:show", + "ozone:write", + "hive:read", + "ozone:all", + "atlas:entity-remove-label", + "trino:all", + "presto:grant", + "kms:rollover", + "elasticsearch:view_index_metadata", + "presto:create", + "kafka:publish", + "kafka:create", + "trino:execute", + "hive:all", + "kms:delete", + "kylin:ADMIN", + "atlas:remove-relationship", + "kylin:MANAGEMENT", + "storm:killTopology", + "elasticsearch:indices_put", + "kudu:create", + "hive:update", + "sqoop:READ", + "presto:delete", + "atlas:entity-update-business-metadata", + "yarn:submit-app", + "solr:update", + "trino:create", + "hdfs:read", + "elasticsearch:write", + "hive:alter", + "kafka:alter_configs", + "storm:getUserTopology", + "storm:uploadNewCredentials", + "presto:insert", + "atlas:type-update", + "storm:submitTopology", + "storm:activate", + "kms:generateeek", + "kafka:cluster_action", + "trino:impersonate", + "hdfs:write", + "hbase:admin", + "elasticsearch:create", + "atlas:admin-import", + "kms:decrypteek", + "solr:query", + "atlas:type-create", + "kudu:all", + "nifi:WRITE", + "sqoop:WRITE", + "storm:getTopologyInfo", + "storm:getTopology", + "hbase:read", + "kms:getmetadata", + "storm:fileUpload", + "trino:alter", + "hive:drop", + "hive:create", + "yarn:admin-queue", + "kafka:describe_configs", + "ozone:delete", + "nifi-registry:READ", + "hive:repladmin", + "kudu:metadata", + "schema-registry:delete", + "nifi-registry:DELETE", + "kms:create", + "ozone:read", + "trino:show", + "ozone:read_acl", + "nifi:READ", + "hive:select", + "kudu:delete", + "atlas:type-read", + "kafka:delete", + "kylin:QUERY", + "elasticsearch:indices_search_shards", + "elasticsearch:read_cross_cluster", + "elasticsearch:manage", + "presto:select", + "ozone:list", + "nestedstructure:write", + "atlas:update-relationship", + "trino:revoke", + "nifi-registry:WRITE", + "storm:rebalance", + "hive:lock", + "presto:revoke", + "knox:allow", + "hbase:create", + "elasticsearch:delete", + "kudu:drop", + "hbase:write", + "elasticsearch:read", + "kudu:alter", + "kudu:insert", + "elasticsearch:all" + ] + } + ] + }, + "auditMode": "audit-default", + "serviceConfig": { + "ranger.plugin.audit.filters": "[ {'accessResult': 'DENIED', 'isAudited': true} ]" + } + }, + "serviceConfig": { + "ranger.plugin.audit.filters": "[ {'accessResult': 'DENIED', 'isAudited': true}, {'actions':['METADATA OPERATION'], 'isAudited': false}, {'users':['hive','hue'],'actions':['SHOW_ROLES'],'isAudited':false} ]" + } +} diff --git a/intg/src/main/python/apache_ranger/model/ranger_service_def.py b/intg/src/main/python/apache_ranger/model/ranger_service_def.py index 3fd90f706..b3aff1dce 100644 --- a/intg/src/main/python/apache_ranger/model/ranger_service_def.py +++ b/intg/src/main/python/apache_ranger/model/ranger_service_def.py @@ -27,34 +27,36 @@ class RangerServiceDef(RangerBaseModelObject): RangerBaseModelObject.__init__(self, attrs) - self.name = attrs.get('name') - self.displayName = attrs.get('displayName') - self.implClass = attrs.get('implClass') - self.label = attrs.get('label') - self.description = attrs.get('description') - self.rbKeyLabel = attrs.get('rbKeyLabel') - self.rbKeyDescription = attrs.get('rbKeyDescription') - self.options = attrs.get('options') - self.configs = attrs.get('configs') - self.resources = attrs.get('resources') - self.accessTypes = attrs.get('accessTypes') - self.policyConditions = attrs.get('policyConditions') - self.contextEnrichers = attrs.get('contextEnrichers') - self.enums = attrs.get('enums') - self.dataMaskDef = attrs.get('dataMaskDef') - self.rowFilterDef = attrs.get('rowFilterDef') + self.name = attrs.get('name') + self.displayName = attrs.get('displayName') + self.implClass = attrs.get('implClass') + self.label = attrs.get('label') + self.description = attrs.get('description') + self.rbKeyLabel = attrs.get('rbKeyLabel') + self.rbKeyDescription = attrs.get('rbKeyDescription') + self.options = attrs.get('options') + self.configs = attrs.get('configs') + self.resources = attrs.get('resources') + self.accessTypes = attrs.get('accessTypes') + self.policyConditions = attrs.get('policyConditions') + self.contextEnrichers = attrs.get('contextEnrichers') + self.enums = attrs.get('enums') + self.dataMaskDef = attrs.get('dataMaskDef') + self.rowFilterDef = attrs.get('rowFilterDef') + self.markerAccessTypes = attrs.get('markerAccessTypes') def type_coerce_attrs(self): super(RangerServiceDef, self).type_coerce_attrs() - self.configs = type_coerce_list(self.configs, RangerResourceDef) - self.resources = type_coerce_list(self.resources, RangerResourceDef) - self.accessTypes = type_coerce_list(self.accessTypes, RangerAccessTypeDef) - self.policyConditions = type_coerce_list(self.policyConditions, RangerPolicyConditionDef) - self.contextEnrichers = type_coerce_list(self.contextEnrichers, RangerContextEnricherDef) - self.enums = type_coerce_list(self.enums, RangerEnumDef) - self.dataMaskDef = type_coerce(self.dataMaskDef, RangerDataMaskDef) - self.rowFilterDef = type_coerce(self.rowFilterDef, RangerRowFilterDef) + self.configs = type_coerce_list(self.configs, RangerResourceDef) + self.resources = type_coerce_list(self.resources, RangerResourceDef) + self.accessTypes = type_coerce_list(self.accessTypes, RangerAccessTypeDef) + self.policyConditions = type_coerce_list(self.policyConditions, RangerPolicyConditionDef) + self.contextEnrichers = type_coerce_list(self.contextEnrichers, RangerContextEnricherDef) + self.enums = type_coerce_list(self.enums, RangerEnumDef) + self.dataMaskDef = type_coerce(self.dataMaskDef, RangerDataMaskDef) + self.rowFilterDef = type_coerce(self.rowFilterDef, RangerRowFilterDef) + self.markerAccessTypes = type_coerce_list(self.markerAccessTypes, RangerAccessTypeDef) class RangerServiceConfigDef: diff --git a/security-admin/src/main/java/org/apache/ranger/biz/PolicyRefUpdater.java b/security-admin/src/main/java/org/apache/ranger/biz/PolicyRefUpdater.java index 4581112fe..a49d0cd29 100644 --- a/security-admin/src/main/java/org/apache/ranger/biz/PolicyRefUpdater.java +++ b/security-admin/src/main/java/org/apache/ranger/biz/PolicyRefUpdater.java @@ -53,6 +53,7 @@ import org.apache.ranger.plugin.model.RangerPolicy.RangerPolicyItemAccess; import org.apache.ranger.plugin.model.RangerPolicy.RangerPolicyItemCondition; import org.apache.ranger.plugin.model.RangerPolicy.RangerPolicyItemDataMaskInfo; import org.apache.ranger.plugin.model.RangerRole; +import org.apache.ranger.plugin.util.ServiceDefUtil; import org.apache.ranger.service.RangerAuditFields; import org.apache.ranger.service.RangerServiceDefService; import org.apache.ranger.service.XGroupService; @@ -227,6 +228,10 @@ public class PolicyRefUpdater { } List<XXPolicyRefAccessType> xPolAccesses = new ArrayList<>(); + + // ignore built-in access-types while creating ref-table entries + accessTypes.removeAll(ServiceDefUtil.ACCESS_TYPE_MARKERS); + for (String accessType : accessTypes) { XXAccessTypeDef xAccTypeDef = daoMgr.getXXAccessTypeDef().findByNameAndServiceId(accessType, xPolicy.getService()); diff --git a/security-admin/src/main/java/org/apache/ranger/biz/ServiceDBStore.java b/security-admin/src/main/java/org/apache/ranger/biz/ServiceDBStore.java index 562467e80..0fc3b85ee 100644 --- a/security-admin/src/main/java/org/apache/ranger/biz/ServiceDBStore.java +++ b/security-admin/src/main/java/org/apache/ranger/biz/ServiceDBStore.java @@ -71,6 +71,7 @@ import org.apache.ranger.db.XXPolicyDao; import org.apache.ranger.entity.XXTagChangeLog; import org.apache.ranger.plugin.model.RangerSecurityZone; import org.apache.ranger.plugin.util.RangerCommonConstants; +import org.apache.ranger.plugin.util.ServiceDefUtil; import org.apache.ranger.plugin.util.ServiceTags; import org.apache.ranger.plugin.model.validation.RangerServiceDefValidator; import org.apache.ranger.plugin.model.validation.RangerValidator; @@ -2976,6 +2977,8 @@ public class ServiceDBStore extends AbstractServiceStore { throw new Exception("service-def does not exist. id=" + tagServiceDbObj.getType()); } + ServiceDefUtil.normalizeAccessTypeDefs(tagServiceDef, serviceType); + tagServiceVersionInfoDbObj = daoMgr.getXXServiceVersionInfo().findByServiceId(serviceDbObj.getTagService()); if (tagServiceVersionInfoDbObj == null) { diff --git a/security-admin/src/main/java/org/apache/ranger/service/RangerServiceDefServiceBase.java b/security-admin/src/main/java/org/apache/ranger/service/RangerServiceDefServiceBase.java index 91d5f26bc..bcaf70e2c 100644 --- a/security-admin/src/main/java/org/apache/ranger/service/RangerServiceDefServiceBase.java +++ b/security-admin/src/main/java/org/apache/ranger/service/RangerServiceDefServiceBase.java @@ -128,6 +128,8 @@ public abstract class RangerServiceDefServiceBase<T extends XXServiceDefBase, V serviceDef.setAccessTypes(accessTypes); } + serviceDef.setMarkerAccessTypes(ServiceDefUtil.getMarkerAccessTypes(serviceDef.getAccessTypes())); + List<XXPolicyConditionDef> xPolicyConditions = daoMgr.getXXPolicyConditionDef() .findByServiceDefId(serviceDefId); if (!stringUtil.isEmpty(xPolicyConditions)) {
