blob: f9816546a3308ef14e944adae83042d803d0f625 [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.apache.ranger.plugin.util;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.collections.MapUtils;
import org.apache.commons.lang.StringUtils;
import org.apache.hadoop.conf.Configuration;
import org.apache.ranger.plugin.conditionevaluator.RangerScriptConditionEvaluator;
import org.apache.ranger.plugin.contextenricher.RangerGdsEnricher;
import org.apache.ranger.plugin.contextenricher.RangerUserStoreEnricher;
import org.apache.ranger.plugin.model.RangerPolicy;
import org.apache.ranger.plugin.model.RangerPolicy.RangerPolicyItem;
import org.apache.ranger.plugin.model.RangerPolicy.RangerPolicyItemCondition;
import org.apache.ranger.plugin.model.RangerPolicy.RangerPolicyItemRowFilterInfo;
import org.apache.ranger.plugin.model.RangerPolicy.RangerPolicyItemDataMaskInfo;
import org.apache.ranger.plugin.model.RangerPolicy.RangerPolicyResource;
import org.apache.ranger.plugin.model.RangerPolicy.RangerRowFilterPolicyItem;
import org.apache.ranger.plugin.model.RangerPolicy.RangerDataMaskPolicyItem;
import org.apache.ranger.plugin.model.RangerPolicyDelta;
import org.apache.ranger.plugin.model.RangerServiceDef;
import org.apache.ranger.plugin.model.RangerServiceDef.RangerPolicyConditionDef;
import org.apache.ranger.plugin.model.RangerServiceDef.RangerAccessTypeDef;
import org.apache.ranger.plugin.model.RangerServiceDef.RangerContextEnricherDef;
import org.apache.ranger.plugin.model.RangerServiceDef.RangerDataMaskTypeDef;
import org.apache.ranger.plugin.model.RangerServiceDef.RangerResourceDef;
import org.apache.ranger.plugin.policyengine.RangerPluginContext;
import org.apache.ranger.plugin.policyengine.RangerRequestScriptEvaluator;
import org.apache.ranger.plugin.store.AbstractServiceStore;
import org.apache.ranger.plugin.store.EmbeddedServiceDefsUtil;
import org.apache.ranger.plugin.util.ServicePolicies.SecurityZoneInfo;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
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);
public static final String IMPLICIT_CONDITION_EXPRESSION_EVALUATOR = RangerScriptConditionEvaluator.class.getCanonicalName();
public static final String IMPLICIT_CONDITION_EXPRESSION_NAME = "_expression";
public static final String IMPLICIT_CONDITION_EXPRESSION_LABEL = "Enter boolean expression";
public static final String IMPLICIT_CONDITION_EXPRESSION_DESC = "Boolean expression";
public static final String IMPLICIT_GDS_ENRICHER_NAME = "gdsInfoEnricher";
private static final String USER_STORE_ENRICHER = RangerUserStoreEnricher.class.getCanonicalName();
private static final String GDSINFO_ENRICHER = RangerGdsEnricher.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;
if(serviceDef != null) {
Configuration config = pluginContext != null ? pluginContext.getConfig() : null;
boolean enableDenyAndExceptionsInPoliciesHiddenOption = config == null || config.getBoolean("ranger.servicedef.enableDenyAndExceptionsInPolicies", true);
boolean defaultValue = enableDenyAndExceptionsInPoliciesHiddenOption || StringUtils.equalsIgnoreCase(serviceDef.getName(), EmbeddedServiceDefsUtil.EMBEDDED_SERVICEDEF_TAG_NAME);
ret = ServiceDefUtil.getBooleanValue(serviceDef.getOptions(), RangerServiceDef.OPTION_ENABLE_DENY_AND_EXCEPTIONS_IN_POLICIES, defaultValue);
}
return ret;
}
public static RangerDataMaskTypeDef getDataMaskType(RangerServiceDef serviceDef, String typeName) {
RangerDataMaskTypeDef ret = null;
if(serviceDef != null && serviceDef.getDataMaskDef() != null) {
List<RangerDataMaskTypeDef> maskTypes = serviceDef.getDataMaskDef().getMaskTypes();
if(CollectionUtils.isNotEmpty(maskTypes)) {
for(RangerDataMaskTypeDef maskType : maskTypes) {
if(StringUtils.equals(maskType.getName(), typeName)) {
ret = maskType;
break;
}
}
}
}
return ret;
}
public static RangerServiceDef normalize(RangerServiceDef serviceDef) {
normalizeDataMaskDef(serviceDef);
normalizeRowFilterDef(serviceDef);
return serviceDef;
}
public static RangerPolicyConditionDef getConditionDef(RangerServiceDef serviceDef, String conditionName) {
RangerPolicyConditionDef ret = null;
if (serviceDef != null && serviceDef.getPolicyConditions() != null) {
for (RangerPolicyConditionDef conditionDef : serviceDef.getPolicyConditions()) {
if (StringUtils.equals(conditionDef.getName(), conditionName)) {
ret = conditionDef;
break;
}
}
}
return ret;
}
public static RangerResourceDef getResourceDef(RangerServiceDef serviceDef, String resource) {
RangerResourceDef ret = null;
if(serviceDef != null && resource != null && CollectionUtils.isNotEmpty(serviceDef.getResources())) {
for(RangerResourceDef resourceDef : serviceDef.getResources()) {
if(StringUtils.equalsIgnoreCase(resourceDef.getName(), resource)) {
ret = resourceDef;
break;
}
}
}
return ret;
}
public static Integer getLeafResourceLevel(RangerServiceDef serviceDef, Map<String, RangerPolicyResource> policyResource) {
Integer ret = null;
RangerResourceDef resourceDef = getLeafResourceDef(serviceDef, policyResource);
if (resourceDef != null) {
ret = resourceDef.getLevel();
}
return ret;
}
public static RangerResourceDef getLeafResourceDef(RangerServiceDef serviceDef, Map<String, RangerPolicyResource> policyResource) {
RangerResourceDef ret = null;
if(serviceDef != null && policyResource != null) {
for(Map.Entry<String, RangerPolicyResource> entry : policyResource.entrySet()) {
if (!isEmpty(entry.getValue())) {
String resource = entry.getKey();
RangerResourceDef resourceDef = ServiceDefUtil.getResourceDef(serviceDef, resource);
if (resourceDef != null && resourceDef.getLevel() != null) {
if (ret == null) {
ret = resourceDef;
} else if(ret.getLevel() < resourceDef.getLevel()) {
ret = resourceDef;
}
}
}
}
}
return ret;
}
public static boolean isAncestorOf(RangerServiceDef serviceDef, RangerResourceDef ancestor, RangerResourceDef descendant) {
boolean ret = false;
if (ancestor != null && descendant != null) {
final String ancestorName = ancestor.getName();
for (RangerResourceDef node = descendant; node != null; node = ServiceDefUtil.getResourceDef(serviceDef, node.getParent())) {
if (StringUtils.equalsIgnoreCase(ancestorName, node.getParent())) {
ret = true;
break;
}
}
}
return ret;
}
public static boolean isEmpty(RangerPolicyResource policyResource) {
boolean ret = true;
if (policyResource != null) {
List<String> resourceValues = policyResource.getValues();
if (CollectionUtils.isNotEmpty(resourceValues)) {
for (String resourceValue : resourceValues) {
if (StringUtils.isNotBlank(resourceValue)) {
ret = false;
break;
}
}
}
}
return ret;
}
public static String getOption(Map<String, String> options, String name, String defaultValue) {
String ret = options != null && name != null ? options.get(name) : null;
if(ret == null) {
ret = defaultValue;
}
return ret;
}
public static boolean getBooleanOption(Map<String, String> options, String name, boolean defaultValue) {
String val = getOption(options, name, null);
return val == null ? defaultValue : Boolean.parseBoolean(val);
}
public static char getCharOption(Map<String, String> options, String name, char defaultValue) {
String val = getOption(options, name, null);
return StringUtils.isEmpty(val) ? defaultValue : val.charAt(0);
}
public static RangerServiceDef normalizeAccessTypeDefs(RangerServiceDef serviceDef, final String componentType) {
if (serviceDef != null && StringUtils.isNotBlank(componentType)) {
normalizeAccessTypeDefs(serviceDef.getAccessTypes(), componentType);
normalizeAccessTypeDefs(serviceDef.getMarkerAccessTypes(), componentType);
if (serviceDef.getDataMaskDef() != null) {
normalizeAccessTypeDefs(serviceDef.getDataMaskDef().getAccessTypes(), componentType);
}
if (serviceDef.getRowFilterDef() != null) {
normalizeAccessTypeDefs(serviceDef.getRowFilterDef().getAccessTypes(), componentType);
}
}
return serviceDef;
}
private static void normalizeAccessTypeDefs(List<RangerAccessTypeDef> accessTypeDefs, String componentType) {
if (CollectionUtils.isNotEmpty(accessTypeDefs)) {
String prefix = componentType + AbstractServiceStore.COMPONENT_ACCESSTYPE_SEPARATOR;
List<RangerAccessTypeDef> unneededAccessTypeDefs = null;
for (RangerAccessTypeDef accessTypeDef : accessTypeDefs) {
String accessType = accessTypeDef.getName();
if (StringUtils.startsWith(accessType, prefix)) {
String newAccessType = StringUtils.removeStart(accessType, prefix);
accessTypeDef.setName(newAccessType);
} else if (StringUtils.contains(accessType, AbstractServiceStore.COMPONENT_ACCESSTYPE_SEPARATOR)) {
if (unneededAccessTypeDefs == null) {
unneededAccessTypeDefs = new ArrayList<>();
}
unneededAccessTypeDefs.add(accessTypeDef);
continue;
}
Collection<String> impliedGrants = accessTypeDef.getImpliedGrants();
if (CollectionUtils.isNotEmpty(impliedGrants)) {
Set<String> newImpliedGrants = new HashSet<>();
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);
}
}
accessTypeDef.setImpliedGrants(newImpliedGrants);
}
}
if (unneededAccessTypeDefs != null) {
accessTypeDefs.removeAll(unneededAccessTypeDefs);
}
}
}
private static void normalizeDataMaskDef(RangerServiceDef serviceDef) {
if(serviceDef != null && serviceDef.getDataMaskDef() != null) {
List<RangerResourceDef> dataMaskResources = serviceDef.getDataMaskDef().getResources();
List<RangerAccessTypeDef> dataMaskAccessTypes = serviceDef.getDataMaskDef().getAccessTypes();
if(CollectionUtils.isNotEmpty(dataMaskResources)) {
List<RangerResourceDef> resources = serviceDef.getResources();
List<RangerResourceDef> processedDefs = new ArrayList<RangerResourceDef>(dataMaskResources.size());
for(RangerResourceDef dataMaskResource : dataMaskResources) {
RangerResourceDef processedDef = dataMaskResource;
for(RangerResourceDef resourceDef : resources) {
if(StringUtils.equals(resourceDef.getName(), dataMaskResource.getName())) {
processedDef = ServiceDefUtil.mergeResourceDef(resourceDef, dataMaskResource);
break;
}
}
processedDefs.add(processedDef);
}
serviceDef.getDataMaskDef().setResources(processedDefs);
}
if(CollectionUtils.isNotEmpty(dataMaskAccessTypes)) {
List<RangerAccessTypeDef> accessTypes = serviceDef.getAccessTypes();
List<RangerAccessTypeDef> processedDefs = new ArrayList<RangerAccessTypeDef>(accessTypes.size());
for(RangerAccessTypeDef dataMaskAccessType : dataMaskAccessTypes) {
RangerAccessTypeDef processedDef = dataMaskAccessType;
for(RangerAccessTypeDef accessType : accessTypes) {
if(StringUtils.equals(accessType.getName(), dataMaskAccessType.getName())) {
processedDef = ServiceDefUtil.mergeAccessTypeDef(accessType, dataMaskAccessType);
break;
}
}
processedDefs.add(processedDef);
}
serviceDef.getDataMaskDef().setAccessTypes(processedDefs);
}
}
}
private static void normalizeRowFilterDef(RangerServiceDef serviceDef) {
if(serviceDef != null && serviceDef.getRowFilterDef() != null) {
List<RangerResourceDef> rowFilterResources = serviceDef.getRowFilterDef().getResources();
List<RangerAccessTypeDef> rowFilterAccessTypes = serviceDef.getRowFilterDef().getAccessTypes();
if(CollectionUtils.isNotEmpty(rowFilterResources)) {
List<RangerResourceDef> resources = serviceDef.getResources();
List<RangerResourceDef> processedDefs = new ArrayList<RangerResourceDef>(rowFilterResources.size());
for(RangerResourceDef rowFilterResource : rowFilterResources) {
RangerResourceDef processedDef = rowFilterResource;
for(RangerResourceDef resourceDef : resources) {
if(StringUtils.equals(resourceDef.getName(), rowFilterResource.getName())) {
processedDef = ServiceDefUtil.mergeResourceDef(resourceDef, rowFilterResource);
break;
}
}
processedDefs.add(processedDef);
}
serviceDef.getRowFilterDef().setResources(processedDefs);
}
if(CollectionUtils.isNotEmpty(rowFilterAccessTypes)) {
List<RangerAccessTypeDef> accessTypes = serviceDef.getAccessTypes();
List<RangerAccessTypeDef> processedDefs = new ArrayList<RangerAccessTypeDef>(accessTypes.size());
for(RangerAccessTypeDef rowFilterAccessType : rowFilterAccessTypes) {
RangerAccessTypeDef processedDef = rowFilterAccessType;
for(RangerAccessTypeDef accessType : accessTypes) {
if(StringUtils.equals(accessType.getName(), rowFilterAccessType.getName())) {
processedDef = ServiceDefUtil.mergeAccessTypeDef(accessType, rowFilterAccessType);
break;
}
}
processedDefs.add(processedDef);
}
serviceDef.getRowFilterDef().setAccessTypes(processedDefs);
}
}
}
private static RangerResourceDef mergeResourceDef(RangerResourceDef base, RangerResourceDef delta) {
RangerResourceDef ret = new RangerResourceDef(base);
// retain base values for: itemId, name, type, level, parent, lookupSupported
if(Boolean.TRUE.equals(delta.getMandatory()))
ret.setMandatory(delta.getMandatory());
if(delta.getRecursiveSupported() != null)
ret.setRecursiveSupported(delta.getRecursiveSupported());
if(delta.getExcludesSupported() != null)
ret.setExcludesSupported(delta.getExcludesSupported());
if(StringUtils.isNotEmpty(delta.getMatcher()))
ret.setMatcher(delta.getMatcher());
if(MapUtils.isNotEmpty(delta.getMatcherOptions())) {
if(ret.getMatcherOptions() == null) {
ret.setMatcherOptions(new HashMap<String, String>());
}
for(Map.Entry<String, String> e : delta.getMatcherOptions().entrySet()) {
ret.getMatcherOptions().put(e.getKey(), e.getValue());
}
}
if(StringUtils.isNotEmpty(delta.getValidationRegEx()))
ret.setValidationRegEx(delta.getValidationRegEx());
if(StringUtils.isNotEmpty(delta.getValidationMessage()))
ret.setValidationMessage(delta.getValidationMessage());
ret.setUiHint(delta.getUiHint());
if(StringUtils.isNotEmpty(delta.getLabel()))
ret.setLabel(delta.getLabel());
if(StringUtils.isNotEmpty(delta.getDescription()))
ret.setDescription(delta.getDescription());
if(StringUtils.isNotEmpty(delta.getRbKeyLabel()))
ret.setRbKeyLabel(delta.getRbKeyLabel());
if(StringUtils.isNotEmpty(delta.getRbKeyDescription()))
ret.setRbKeyDescription(delta.getRbKeyDescription());
if(StringUtils.isNotEmpty(delta.getRbKeyValidationMessage()))
ret.setRbKeyValidationMessage(delta.getRbKeyValidationMessage());
if(CollectionUtils.isNotEmpty(delta.getAccessTypeRestrictions()))
ret.setAccessTypeRestrictions(delta.getAccessTypeRestrictions());
boolean copyLeafValue = false;
if (ret.getIsValidLeaf() != null) {
if (!ret.getIsValidLeaf().equals(delta.getIsValidLeaf())) {
copyLeafValue = true;
}
} else {
if (delta.getIsValidLeaf() != null) {
copyLeafValue = true;
}
}
if (copyLeafValue)
ret.setIsValidLeaf(delta.getIsValidLeaf());
return ret;
}
private static RangerAccessTypeDef mergeAccessTypeDef(RangerAccessTypeDef base, RangerAccessTypeDef delta) {
RangerAccessTypeDef ret = new RangerAccessTypeDef(base);
// retain base values for: itemId, name, impliedGrants
if(StringUtils.isNotEmpty(delta.getLabel()))
ret.setLabel(delta.getLabel());
if(StringUtils.isNotEmpty(delta.getRbKeyLabel()))
ret.setRbKeyLabel(delta.getRbKeyLabel());
return ret;
}
public static boolean getBooleanValue(Map<String, String> map, String elementName, boolean defaultValue) {
boolean ret = defaultValue;
if(MapUtils.isNotEmpty(map) && map.containsKey(elementName)) {
String elementValue = map.get(elementName);
if(StringUtils.isNotEmpty(elementValue)) {
ret = Boolean.valueOf(elementValue.toString());
}
}
return ret;
}
public static Map<String, Collection<String>> getExpandedImpliedGrants(RangerServiceDef serviceDef) {
Map<String, Collection<String>> ret = new HashMap<>();
if(serviceDef != null && !CollectionUtils.isEmpty(serviceDef.getAccessTypes())) {
for(RangerAccessTypeDef accessTypeDef : serviceDef.getAccessTypes()) {
if(!CollectionUtils.isEmpty(accessTypeDef.getImpliedGrants())) {
Collection<String> impliedAccessGrants = ret.get(accessTypeDef.getName());
if(impliedAccessGrants == null) {
impliedAccessGrants = new HashSet<>();
ret.put(accessTypeDef.getName(), impliedAccessGrants);
}
impliedAccessGrants.addAll(accessTypeDef.getImpliedGrants());
impliedAccessGrants.add(accessTypeDef.getName());
} else {
ret.put(accessTypeDef.getName(), new HashSet<>(Collections.singleton(accessTypeDef.getName())));
}
}
}
return ret;
}
public static boolean isGdsInfoEnricherPresent(ServicePolicies policies) {
boolean ret = false;
RangerServiceDef serviceDef = policies != null ? policies.getServiceDef() : null;
List<RangerContextEnricherDef> enricherDefs = serviceDef != null ? serviceDef.getContextEnrichers() : null;
if (enricherDefs != null) {
for (RangerContextEnricherDef enricherDef : enricherDefs) {
if (StringUtils.equals(enricherDef.getEnricher(), GDSINFO_ENRICHER)) {
ret = true;
break;
}
}
}
LOG.debug("isGdsInfoEnricherPresent(service={}): ret={}", policies.getServiceName(), ret);
return ret;
}
public static boolean addGdsInfoEnricher(ServicePolicies policies, String retrieverClassName, String retrieverPollIntMs) {
boolean ret = false;
RangerServiceDef serviceDef = policies != null ? policies.getServiceDef() : null;
if (serviceDef != null && !isGdsInfoEnricherPresent(policies)) {
List<RangerContextEnricherDef> enricherDefs = serviceDef.getContextEnrichers();
if (enricherDefs == null) {
enricherDefs = new ArrayList<>();
}
long enricherItemId = enricherDefs.size() + 1;
for (RangerServiceDef.RangerContextEnricherDef enricherDef : enricherDefs) {
if (enricherDef.getItemId() >= enricherItemId) {
enricherItemId = enricherDef.getItemId() + 1;
}
}
Map<String, String> enricherOptions = new HashMap<>();
enricherOptions.put(RangerGdsEnricher.RETRIEVER_CLASSNAME_OPTION, retrieverClassName);
enricherOptions.put(RangerGdsEnricher.REFRESHER_POLLINGINTERVAL_OPTION, retrieverPollIntMs);
RangerServiceDef.RangerContextEnricherDef gdsInfoEnricher = new RangerServiceDef.RangerContextEnricherDef(enricherItemId, IMPLICIT_GDS_ENRICHER_NAME, GDSINFO_ENRICHER, enricherOptions);
enricherDefs.add(gdsInfoEnricher);
serviceDef.setContextEnrichers(enricherDefs);
ret = true;
LOG.info("addGdsInfoEnricher(serviceName={}): added gdsInfoEnricher {}", policies.getServiceName(), gdsInfoEnricher);
}
return ret;
}
public static boolean isUserStoreEnricherPresent(ServicePolicies policies) {
boolean ret = false;
RangerServiceDef serviceDef = policies != null ? policies.getServiceDef() : null;
List<RangerContextEnricherDef> enricherDefs = serviceDef != null ? serviceDef.getContextEnrichers() : null;
if (enricherDefs != null) {
for (RangerContextEnricherDef enricherDef : enricherDefs) {
if (StringUtils.equals(enricherDef.getEnricher(), USER_STORE_ENRICHER)) {
ret = true;
break;
}
}
}
if (LOG.isDebugEnabled()) {
LOG.debug("isUserStoreEnricherPresent(service={}): ret={}", policies.getServiceName(), ret);
}
return ret;
}
public static boolean addUserStoreEnricher(ServicePolicies policies, String retrieverClassName, String retrieverPollIntMs) {
boolean ret = false;
RangerServiceDef serviceDef = policies != null ? policies.getServiceDef() : null;
if (serviceDef != null && !isUserStoreEnricherPresent(policies)) {
List<RangerContextEnricherDef> enricherDefs = serviceDef.getContextEnrichers();
if (enricherDefs == null) {
enricherDefs = new ArrayList<>();
}
long enricherItemId = enricherDefs.size() + 1;
for (RangerServiceDef.RangerContextEnricherDef enricherDef : enricherDefs) {
if (enricherDef.getItemId() >= enricherItemId) {
enricherItemId = enricherDef.getItemId() + 1;
}
}
Map<String, String> enricherOptions = new HashMap<>();
enricherOptions.put(RangerUserStoreEnricher.USERSTORE_RETRIEVER_CLASSNAME_OPTION, retrieverClassName);
enricherOptions.put(RangerUserStoreEnricher.USERSTORE_REFRESHER_POLLINGINTERVAL_OPTION, retrieverPollIntMs);
RangerServiceDef.RangerContextEnricherDef userStoreEnricher = new RangerServiceDef.RangerContextEnricherDef(enricherItemId, "userStoreEnricher", USER_STORE_ENRICHER, enricherOptions);
enricherDefs.add(userStoreEnricher);
serviceDef.setContextEnrichers(enricherDefs);
ret = true;
LOG.info("addUserStoreEnricher(serviceName={}): added userStoreEnricher {}", policies.getServiceName(), userStoreEnricher);
}
return ret;
}
public static boolean addUserStoreEnricherIfNeeded(ServicePolicies policies, String retrieverClassName, String retrieverPollIntMs) {
boolean ret = false;
RangerServiceDef serviceDef = policies != null ? policies.getServiceDef() : null;
if (serviceDef != null && !isUserStoreEnricherPresent(policies)) {
boolean addEnricher = anyPolicyHasUserGroupAttributeExpression(policies.getPolicies());
if (!addEnricher) {
List<RangerPolicy> tagPolicies = policies.getTagPolicies() != null ? policies.getTagPolicies().getPolicies() : null;
addEnricher = anyPolicyHasUserGroupAttributeExpression(tagPolicies);
}
if (!addEnricher) {
addEnricher = anyPolicyDeltaHasUserGroupAttributeExpression(policies.getPolicyDeltas());
}
if (!addEnricher) {
Map<String, SecurityZoneInfo> zoneInfos = policies.getSecurityZones();
if (zoneInfos != null) {
for (SecurityZoneInfo zoneInfo : zoneInfos.values()) {
addEnricher = anyPolicyHasUserGroupAttributeExpression(zoneInfo.getPolicies());
if (!addEnricher) {
addEnricher = anyPolicyDeltaHasUserGroupAttributeExpression(zoneInfo.getPolicyDeltas());
}
if (addEnricher) {
break;
}
}
}
}
if (addEnricher) {
addUserStoreEnricher(policies, retrieverClassName, retrieverPollIntMs);
ret = true;
}
}
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;
}
public static RangerPolicyConditionDef createImplicitExpressionConditionDef(Long itemId) {
RangerPolicyConditionDef ret = new RangerPolicyConditionDef(itemId, IMPLICIT_CONDITION_EXPRESSION_NAME, IMPLICIT_CONDITION_EXPRESSION_EVALUATOR, new HashMap<>());
ret.getEvaluatorOptions().put("engineName", "JavaScript");
ret.getEvaluatorOptions().put("ui.isMultiline", "true");
ret.setLabel(IMPLICIT_CONDITION_EXPRESSION_LABEL);
ret.setDescription(IMPLICIT_CONDITION_EXPRESSION_DESC);
ret.setUiHint("{ \"isMultiline\":true }");
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;
}
public static long getConditionsMaxItemId(List<RangerPolicyConditionDef> conditions) {
long ret = 0;
if (conditions != null) {
for (RangerPolicyConditionDef condition : conditions) {
if (condition != null && condition.getItemId() != null && ret < condition.getItemId()) {
ret = condition.getItemId();
}
}
}
return ret;
}
private static boolean anyPolicyHasUserGroupAttributeExpression(List<RangerPolicy> policies) {
boolean ret = false;
if (policies != null) {
for (RangerPolicy policy : policies) {
if (policyHasUserGroupAttributeExpression(policy)) {
if (LOG.isDebugEnabled()) {
LOG.debug("addUserStoreEnricherIfNeeded(service={}): policy(id={}, name={}) has reference to user/group attribute. Adding enricher", policy.getService(), policy.getId(), policy.getName());
}
ret = true;
break;
}
}
}
return ret;
}
private static boolean anyPolicyDeltaHasUserGroupAttributeExpression(List<RangerPolicyDelta> policyDeltas) {
boolean ret = false;
if (policyDeltas != null) {
for (RangerPolicyDelta policyDelta : policyDeltas) {
RangerPolicy policy = policyDelta.getPolicy();
if (policyHasUserGroupAttributeExpression(policy)) {
if (LOG.isDebugEnabled()) {
LOG.debug("addUserStoreEnricherIfNeeded(service={}): policy(id={}, name={}) has reference to user/group attribute. Adding enricher", policy.getService(), policy.getId(), policy.getName());
}
ret = true;
break;
}
}
}
return ret;
}
private static boolean policyHasUserGroupAttributeExpression(RangerPolicy policy) {
boolean ret = false;
if (policy != null) {
if (MapUtils.isNotEmpty(policy.getResources())) {
for (RangerPolicyResource resource : policy.getResources().values()) {
ret = RangerRequestExprResolver.hasUserGroupAttributeInExpression(resource.getValues());
if (ret) {
break;
}
}
}
if (!ret) {
ret = anyPolicyConditionHasUserGroupAttributeReference(policy.getConditions());
}
if (!ret) {
ret = anyPolicyItemHasUserGroupAttributeExpression(policy.getPolicyItems()) ||
anyPolicyItemHasUserGroupAttributeExpression(policy.getDenyPolicyItems()) ||
anyPolicyItemHasUserGroupAttributeExpression(policy.getAllowExceptions()) ||
anyPolicyItemHasUserGroupAttributeExpression(policy.getDenyExceptions()) ||
anyPolicyItemHasUserGroupAttributeExpression(policy.getDataMaskPolicyItems()) ||
anyPolicyItemHasUserGroupAttributeExpression(policy.getRowFilterPolicyItems());
}
}
return ret;
}
private static boolean anyPolicyItemHasUserGroupAttributeExpression(List<? extends RangerPolicyItem> policyItems) {
boolean ret = false;
if (policyItems != null) {
for (RangerPolicyItem policyItem : policyItems) {
if (policyItemHasUserGroupAttributeExpression(policyItem)) {
ret = true;
break;
}
}
}
return ret;
}
private static boolean policyItemHasUserGroupAttributeExpression(RangerPolicyItem policyItem) {
boolean ret = false;
if (policyItem != null) {
ret = anyPolicyConditionHasUserGroupAttributeReference(policyItem.getConditions());
if (!ret && policyItem instanceof RangerRowFilterPolicyItem) {
RangerRowFilterPolicyItem rowFilterPolicyItem = (RangerRowFilterPolicyItem) policyItem;
RangerPolicyItemRowFilterInfo rowFilterInfo = rowFilterPolicyItem.getRowFilterInfo();
String filterExpr = rowFilterInfo != null ? rowFilterInfo.getFilterExpr() : "";
ret = RangerRequestExprResolver.hasUserGroupAttributeInExpression(filterExpr);
}
if (!ret && policyItem instanceof RangerDataMaskPolicyItem) {
RangerDataMaskPolicyItem dataMaskPolicyItem = (RangerDataMaskPolicyItem) policyItem;
RangerPolicyItemDataMaskInfo dataMaskInfo = dataMaskPolicyItem.getDataMaskInfo();
String maskedValue = dataMaskInfo != null ? dataMaskInfo.getValueExpr() : null;
ret = RangerRequestExprResolver.hasUserGroupAttributeInExpression(maskedValue);
if (!ret) {
String maskCondition = dataMaskInfo != null ? dataMaskInfo.getConditionExpr() : null;
ret = RangerRequestExprResolver.hasUserGroupAttributeInExpression(maskCondition);
}
}
}
return ret;
}
private static boolean anyPolicyConditionHasUserGroupAttributeReference(List<RangerPolicyItemCondition> conditions) {
boolean ret = false;
if (conditions != null) {
for (RangerPolicyItemCondition condition : conditions) {
if (RangerRequestScriptEvaluator.hasUserGroupAttributeReference(condition.getValues())) {
ret = true;
break;
}
}
}
return ret;
}
}