| /* |
| * Licensed to the Apache Software Foundation (ASF) under one |
| * or more contributor license agreements. See the NOTICE file |
| * distributed with this work for additional information |
| * regarding copyright ownership. The ASF licenses this file |
| * to you under the Apache License, Version 2.0 (the |
| * "License"); you may not use this file except in compliance |
| * with the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, |
| * software distributed under the License is distributed on an |
| * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
| * KIND, either express or implied. See the License for the |
| * specific language governing permissions and limitations |
| * under the License. |
| */ |
| |
| package org.apache.ranger.plugin.model.validation; |
| |
| import java.util.*; |
| |
| import org.apache.commons.collections.CollectionUtils; |
| import org.apache.commons.lang.StringUtils; |
| import org.apache.commons.logging.Log; |
| import org.apache.commons.logging.LogFactory; |
| import org.apache.ranger.plugin.errors.ValidationErrorCode; |
| import org.apache.ranger.plugin.model.RangerPolicy; |
| import org.apache.ranger.plugin.model.RangerPolicy.RangerDataMaskPolicyItem; |
| import org.apache.ranger.plugin.model.RangerPolicy.RangerPolicyItem; |
| import org.apache.ranger.plugin.model.RangerPolicy.RangerPolicyItemAccess; |
| import org.apache.ranger.plugin.model.RangerPolicy.RangerPolicyResource; |
| import org.apache.ranger.plugin.model.RangerPolicy.RangerRowFilterPolicyItem; |
| import org.apache.ranger.plugin.model.RangerPolicyResourceSignature; |
| import org.apache.ranger.plugin.model.RangerSecurityZone; |
| import org.apache.ranger.plugin.model.RangerService; |
| 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.apache.ranger.plugin.model.RangerValiditySchedule; |
| import org.apache.ranger.plugin.store.ServiceStore; |
| |
| public class RangerPolicyValidator extends RangerValidator { |
| |
| private static final Log LOG = LogFactory.getLog(RangerPolicyValidator.class); |
| |
| public RangerPolicyValidator(ServiceStore store) { |
| super(store); |
| } |
| |
| public void validate(RangerPolicy policy, Action action, boolean isAdmin) throws Exception { |
| if(LOG.isDebugEnabled()) { |
| LOG.debug(String.format("==> RangerPolicyValidator.validate(%s, %s, %s)", policy, action, isAdmin)); |
| } |
| |
| List<ValidationFailureDetails> failures = new ArrayList<>(); |
| boolean valid = isValid(policy, action, isAdmin, failures); |
| String message = ""; |
| try { |
| if (!valid) { |
| message = serializeFailures(failures); |
| throw new Exception(message); |
| } |
| } finally { |
| if(LOG.isDebugEnabled()) { |
| LOG.debug(String.format("<== RangerPolicyValidator.validate(%s, %s, %s): %s, reason[%s]", policy, action, isAdmin, valid, message)); |
| } |
| } |
| } |
| |
| @Override |
| boolean isValid(Long id, Action action, List<ValidationFailureDetails> failures) { |
| if(LOG.isDebugEnabled()) { |
| LOG.debug(String.format("==> RangerPolicyValidator.isValid(%s, %s, %s)", id, action, failures)); |
| } |
| |
| boolean valid = true; |
| if (action != Action.DELETE) { |
| ValidationErrorCode error = ValidationErrorCode.POLICY_VALIDATION_ERR_UNSUPPORTED_ACTION; |
| failures.add(new ValidationFailureDetailsBuilder() |
| .isAnInternalError() |
| .becauseOf(error.getMessage()) |
| .errorCode(error.getErrorCode()) |
| .build()); |
| valid = false; |
| } else if (id == null) { |
| ValidationErrorCode error = ValidationErrorCode.POLICY_VALIDATION_ERR_MISSING_FIELD; |
| failures.add(new ValidationFailureDetailsBuilder() |
| .becauseOf("policy id was null/missing") |
| .field("id") |
| .isMissing() |
| .errorCode(error.getErrorCode()) |
| .becauseOf(error.getMessage("id")) |
| .build()); |
| valid = false; |
| } else if (policyExists(id)) { |
| if (LOG.isDebugEnabled()) { |
| LOG.debug("No policy found for id[" + id + "]! ok!"); |
| } |
| } |
| |
| if(LOG.isDebugEnabled()) { |
| LOG.debug(String.format("<== RangerPolicyValidator.isValid(%s, %s, %s): %s", id, action, failures, valid)); |
| } |
| return valid; |
| } |
| |
| boolean isValid(RangerPolicy policy, Action action, boolean isAdmin, List<ValidationFailureDetails> failures) { |
| if(LOG.isDebugEnabled()) { |
| LOG.debug(String.format("==> RangerPolicyValidator.isValid(%s, %s, %s, %s)", policy, action, isAdmin, failures)); |
| } |
| |
| if (!(action == Action.CREATE || action == Action.UPDATE)) { |
| throw new IllegalArgumentException("isValid(RangerPolicy, ...) is only supported for create/update"); |
| } |
| boolean valid = true; |
| if (policy == null) { |
| ValidationErrorCode error = ValidationErrorCode.POLICY_VALIDATION_ERR_NULL_POLICY_OBJECT; |
| failures.add(new ValidationFailureDetailsBuilder() |
| .field("policy") |
| .isMissing() |
| .becauseOf(error.getMessage()) |
| .errorCode(error.getErrorCode()) |
| .build()); |
| valid = false; |
| } else { |
| Integer priority = policy.getPolicyPriority(); |
| if (priority != null) { |
| if (priority < RangerPolicy.POLICY_PRIORITY_NORMAL || priority > RangerPolicy.POLICY_PRIORITY_OVERRIDE) { |
| ValidationErrorCode error = ValidationErrorCode.POLICY_VALIDATION_ERR_POLICY_INVALID_PRIORITY; |
| failures.add(new ValidationFailureDetailsBuilder() |
| .field("policyPriority") |
| .isSemanticallyIncorrect() |
| .becauseOf(error.getMessage("out of range")) |
| .errorCode(error.getErrorCode()) |
| .build()); |
| valid = false; |
| } |
| } |
| Long id = policy.getId(); |
| RangerPolicy existingPolicy = null; |
| |
| if (action == Action.UPDATE) { // id is ignored for CREATE |
| if (id == null) { |
| ValidationErrorCode error = ValidationErrorCode.POLICY_VALIDATION_ERR_MISSING_FIELD; |
| failures.add(new ValidationFailureDetailsBuilder() |
| .field("id") |
| .isMissing() |
| .becauseOf(error.getMessage("id")) |
| .errorCode(error.getErrorCode()) |
| .build()); |
| valid = false; |
| } |
| |
| existingPolicy = getPolicy(id); |
| |
| if (existingPolicy == null) { |
| ValidationErrorCode error = ValidationErrorCode.POLICY_VALIDATION_ERR_INVALID_POLICY_ID; |
| failures.add(new ValidationFailureDetailsBuilder() |
| .field("id") |
| .isSemanticallyIncorrect() |
| .becauseOf(error.getMessage(id)) |
| .errorCode(error.getErrorCode()) |
| .build()); |
| valid = false; |
| } |
| } |
| String policyName = policy.getName(); |
| String serviceName = policy.getService(); |
| String zoneName = policy.getZoneName(); |
| |
| RangerService service = null; |
| RangerSecurityZone zone = null; |
| boolean serviceNameValid = false; |
| if (StringUtils.isBlank(serviceName)) { |
| ValidationErrorCode error = ValidationErrorCode.POLICY_VALIDATION_ERR_MISSING_FIELD; |
| failures.add(new ValidationFailureDetailsBuilder() |
| .field("service name") |
| .isMissing() |
| .becauseOf(error.getMessage("service name")) |
| .errorCode(error.getErrorCode()) |
| .build()); |
| valid = false; |
| } else { |
| service = getService(serviceName); |
| if (service == null) { |
| ValidationErrorCode error = ValidationErrorCode.POLICY_VALIDATION_ERR_INVALID_SERVICE_NAME; |
| failures.add(new ValidationFailureDetailsBuilder() |
| .field("service name") |
| .isSemanticallyIncorrect() |
| .becauseOf(error.getMessage(serviceName)) |
| .errorCode(error.getErrorCode()) |
| .build()); |
| valid = false; |
| } else { |
| serviceNameValid = true; |
| } |
| } |
| |
| if (StringUtils.isNotEmpty(zoneName)) { |
| zone = getSecurityZone(zoneName); |
| if (zone == null) { |
| ValidationErrorCode error = ValidationErrorCode.POLICY_VALIDATION_ERR_NONEXISTANT_ZONE_NAME; |
| failures.add(new ValidationFailureDetailsBuilder() |
| .field("zoneName") |
| .isSemanticallyIncorrect() |
| .becauseOf(error.getMessage(id, zoneName)) |
| .errorCode(error.getErrorCode()) |
| .build()); |
| valid = false; |
| } |
| List<String> tagSvcList = zone.getTagServices(); |
| Set<String> svcNameSet = zone.getServices().keySet(); |
| if(!svcNameSet.contains(serviceName) && !tagSvcList.contains(serviceName)){ |
| ValidationErrorCode error = ValidationErrorCode.POLICY_VALIDATION_ERR_SERVICE_NOT_ASSOCIATED_TO_ZONE; |
| failures.add(new ValidationFailureDetailsBuilder() |
| .field("zoneName") |
| .isSemanticallyIncorrect() |
| .becauseOf(error.getMessage(serviceName, zoneName)) |
| .errorCode(error.getErrorCode()) |
| .build()); |
| valid = false; |
| } |
| } |
| |
| if (StringUtils.isBlank(policyName)) { |
| ValidationErrorCode error = ValidationErrorCode.POLICY_VALIDATION_ERR_MISSING_FIELD; |
| failures.add(new ValidationFailureDetailsBuilder() |
| .field("name") |
| .isMissing() |
| .becauseOf(error.getMessage("name")) |
| .errorCode(error.getErrorCode()) |
| .build()); |
| valid = false; |
| } else { |
| if (service != null && (StringUtils.isEmpty(zoneName) || zone != null)) { |
| Long zoneId = zone != null ? zone.getId() : RangerSecurityZone.RANGER_UNZONED_SECURITY_ZONE_ID; |
| Long policyId = getPolicyId(service.getId(), policyName, zoneId); |
| |
| if (policyId != null) { |
| if (action == Action.CREATE) { |
| ValidationErrorCode error = ValidationErrorCode.POLICY_VALIDATION_ERR_POLICY_NAME_CONFLICT; |
| failures.add(new ValidationFailureDetailsBuilder() |
| .field("policy name") |
| .isSemanticallyIncorrect() |
| .becauseOf(error.getMessage(policyId, serviceName)) |
| .errorCode(error.getErrorCode()) |
| .build()); |
| valid = false; |
| } else if (!policyId.equals(id)) { // action == UPDATE |
| ValidationErrorCode error = ValidationErrorCode.POLICY_VALIDATION_ERR_POLICY_NAME_CONFLICT; |
| failures.add(new ValidationFailureDetailsBuilder() |
| .field("id/name") |
| .isSemanticallyIncorrect() |
| .becauseOf(error.getMessage(policyId, serviceName)) |
| .errorCode(error.getErrorCode()) |
| .build()); |
| valid = false; |
| } |
| } |
| } |
| } |
| |
| if(existingPolicy != null) { |
| if (!StringUtils.equalsIgnoreCase(existingPolicy.getService(), policy.getService())) { |
| ValidationErrorCode error = ValidationErrorCode.POLICY_VALIDATION_ERR_POLICY_UPDATE_MOVE_SERVICE_NOT_ALLOWED; |
| failures.add(new ValidationFailureDetailsBuilder() |
| .field("service name") |
| .isSemanticallyIncorrect() |
| .becauseOf(error.getMessage(policy.getId(), existingPolicy.getService(), policy.getService())) |
| .errorCode(error.getErrorCode()) |
| .build()); |
| valid = false; |
| } |
| |
| int existingPolicyType = existingPolicy.getPolicyType() == null ? RangerPolicy.POLICY_TYPE_ACCESS : existingPolicy.getPolicyType(); |
| int policyType = policy.getPolicyType() == null ? RangerPolicy.POLICY_TYPE_ACCESS : policy.getPolicyType(); |
| |
| if (existingPolicyType != policyType) { |
| ValidationErrorCode error = ValidationErrorCode.POLICY_VALIDATION_ERR_POLICY_TYPE_CHANGE_NOT_ALLOWED; |
| failures.add(new ValidationFailureDetailsBuilder() |
| .field("policy type") |
| .isSemanticallyIncorrect() |
| .becauseOf(error.getMessage(policy.getId(), existingPolicyType, policyType)) |
| .errorCode(error.getErrorCode()) |
| .build()); |
| valid = false; |
| } |
| |
| String existingZoneName = existingPolicy.getZoneName(); |
| |
| if (StringUtils.isNotEmpty(zoneName) || StringUtils.isNotEmpty(existingZoneName)) { |
| if (!StringUtils.equals(existingZoneName, zoneName)) { |
| ValidationErrorCode error = ValidationErrorCode.POLICY_VALIDATION_ERR_UPDATE_ZONE_NAME_NOT_ALLOWED; |
| failures.add(new ValidationFailureDetailsBuilder() |
| .field("zoneName") |
| .isSemanticallyIncorrect() |
| .becauseOf(error.getMessage(existingZoneName, zoneName)) |
| .errorCode(error.getErrorCode()) |
| .build()); |
| valid = false; |
| } |
| } |
| } |
| |
| boolean isAuditEnabled = getIsAuditEnabled(policy); |
| String serviceDefName = null; |
| RangerServiceDef serviceDef = null; |
| int policyItemsCount = 0; |
| |
| int policyType=policy.getPolicyType() == null ? RangerPolicy.POLICY_TYPE_ACCESS : policy.getPolicyType(); |
| switch (policyType) { |
| case RangerPolicy.POLICY_TYPE_DATAMASK: |
| if (CollectionUtils.isNotEmpty(policy.getDataMaskPolicyItems())) { |
| policyItemsCount += policy.getDataMaskPolicyItems().size(); |
| } |
| break; |
| case RangerPolicy.POLICY_TYPE_ROWFILTER: |
| if (CollectionUtils.isNotEmpty(policy.getRowFilterPolicyItems())) { |
| policyItemsCount += policy.getRowFilterPolicyItems().size(); |
| } |
| break; |
| default: |
| if (CollectionUtils.isNotEmpty(policy.getPolicyItems())){ |
| policyItemsCount += policy.getPolicyItems().size(); |
| } |
| if(CollectionUtils.isNotEmpty(policy.getDenyPolicyItems())) { |
| policyItemsCount += policy.getDenyPolicyItems().size(); |
| } |
| break; |
| } |
| |
| if (policyItemsCount == 0 && !isAuditEnabled) { |
| ValidationErrorCode error = ValidationErrorCode.POLICY_VALIDATION_ERR_MISSING_POLICY_ITEMS; |
| failures.add(new ValidationFailureDetailsBuilder() |
| .field("policy items") |
| .isMissing() |
| .becauseOf(error.getMessage()) |
| .errorCode(error.getErrorCode()) |
| .build()); |
| valid = false; |
| } else if (service != null) { |
| serviceDefName = service.getType(); |
| serviceDef = getServiceDef(serviceDefName); |
| if (serviceDef == null) { |
| ValidationErrorCode error = ValidationErrorCode.POLICY_VALIDATION_ERR_MISSING_SERVICE_DEF; |
| failures.add(new ValidationFailureDetailsBuilder() |
| .field("policy service def") |
| .isAnInternalError() |
| .becauseOf(error.getMessage(serviceDefName, serviceName)) |
| .errorCode(error.getErrorCode()) |
| .build()); |
| valid = false; |
| } else { |
| if (Boolean.TRUE.equals(policy.getIsDenyAllElse())) { |
| if (CollectionUtils.isNotEmpty(policy.getDenyPolicyItems()) || CollectionUtils.isNotEmpty(policy.getDenyExceptions())) { |
| ValidationErrorCode error = ValidationErrorCode.POLICY_VALIDATION_ERR_UNSUPPORTED_POLICY_ITEM_TYPE; |
| failures.add(new ValidationFailureDetailsBuilder() |
| .field("policy items") |
| .becauseOf(error.getMessage()) |
| .errorCode(error.getErrorCode()) |
| .build()); |
| valid = false; |
| } |
| } |
| valid = isValidPolicyItems(policy.getPolicyItems(), failures, serviceDef) && valid; |
| valid = isValidPolicyItems(policy.getDenyPolicyItems(), failures, serviceDef) && valid; |
| valid = isValidPolicyItems(policy.getAllowExceptions(), failures, serviceDef) && valid; |
| valid = isValidPolicyItems(policy.getDenyExceptions(), failures, serviceDef) && valid; |
| } |
| } |
| |
| if (serviceNameValid) { // resource checks can't be done meaningfully otherwise |
| valid = isValidValiditySchedule(policy, failures, action) && valid; |
| valid = isValidResources(policy, failures, action, isAdmin, serviceDef) && valid; |
| valid = isValidAccessTypeDef(policy, failures, action, isAdmin, serviceDef) && valid; |
| } |
| } |
| |
| if(LOG.isDebugEnabled()) { |
| LOG.debug(String.format("<== RangerPolicyValidator.isValid(%s, %s, %s, %s): %s", policy, action, isAdmin, failures, valid)); |
| } |
| return valid; |
| } |
| |
| boolean isValidAccessTypeDef(RangerPolicy policy, final List<ValidationFailureDetails> failures, Action action,boolean isAdmin, final RangerServiceDef serviceDef) { |
| boolean valid = true; |
| if(LOG.isDebugEnabled()) { |
| LOG.debug(String.format("==> RangerPolicyValidator.isValidAccessTypeDef(%s, %s, %s,%s,%s)", policy, failures, action,isAdmin,serviceDef)); |
| } |
| int policyType=policy.getPolicyType() == null ? RangerPolicy.POLICY_TYPE_ACCESS : policy.getPolicyType(); |
| //row filter policy |
| if (policyType==RangerPolicy.POLICY_TYPE_ROWFILTER){ |
| List<String> rowFilterAccessTypeDefNames=new ArrayList<String>(); |
| if(serviceDef!=null && serviceDef.getRowFilterDef()!=null){ |
| if(!CollectionUtils.isEmpty(serviceDef.getRowFilterDef().getAccessTypes())){ |
| for(RangerAccessTypeDef rangerAccessTypeDef:serviceDef.getRowFilterDef().getAccessTypes()){ |
| rowFilterAccessTypeDefNames.add(rangerAccessTypeDef.getName().toLowerCase()); |
| } |
| } |
| } |
| |
| if(!CollectionUtils.isEmpty(policy.getRowFilterPolicyItems())){ |
| for(RangerRowFilterPolicyItem rangerRowFilterPolicyItem:policy.getRowFilterPolicyItems()){ |
| if(!CollectionUtils.isEmpty(rangerRowFilterPolicyItem.getAccesses())){ |
| for(RangerPolicyItemAccess rangerPolicyItemAccess : rangerRowFilterPolicyItem.getAccesses()){ |
| if(!rowFilterAccessTypeDefNames.contains(rangerPolicyItemAccess.getType().toLowerCase())){ |
| ValidationErrorCode error = ValidationErrorCode.POLICY_VALIDATION_ERR_POLICY_ITEM_ACCESS_TYPE_INVALID; |
| failures.add(new ValidationFailureDetailsBuilder() |
| .field("row filter policy item access type") |
| .isSemanticallyIncorrect() |
| .becauseOf(error.getMessage(rangerPolicyItemAccess.getType(), rowFilterAccessTypeDefNames)) |
| .errorCode(error.getErrorCode()) |
| .build()); |
| valid = false; |
| } |
| } |
| } |
| } |
| } |
| } |
| //data mask policy |
| if (policyType==RangerPolicy.POLICY_TYPE_DATAMASK){ |
| List<String> dataMaskAccessTypeDefNames=new ArrayList<String>(); |
| if(serviceDef!=null && serviceDef.getDataMaskDef()!=null){ |
| if(!CollectionUtils.isEmpty(serviceDef.getDataMaskDef().getAccessTypes())){ |
| for(RangerAccessTypeDef rangerAccessTypeDef:serviceDef.getDataMaskDef().getAccessTypes()){ |
| dataMaskAccessTypeDefNames.add(rangerAccessTypeDef.getName().toLowerCase()); |
| } |
| } |
| } |
| |
| if(!CollectionUtils.isEmpty(policy.getDataMaskPolicyItems())){ |
| for(RangerDataMaskPolicyItem rangerDataMaskPolicyItem:policy.getDataMaskPolicyItems()){ |
| if(!CollectionUtils.isEmpty(rangerDataMaskPolicyItem.getAccesses())){ |
| for(RangerPolicyItemAccess rangerPolicyItemAccess : rangerDataMaskPolicyItem.getAccesses()){ |
| if(!dataMaskAccessTypeDefNames.contains(rangerPolicyItemAccess.getType().toLowerCase())){ |
| ValidationErrorCode error = ValidationErrorCode.POLICY_VALIDATION_ERR_POLICY_ITEM_ACCESS_TYPE_INVALID; |
| failures.add(new ValidationFailureDetailsBuilder() |
| .field("data masking policy item access type") |
| .isSemanticallyIncorrect() |
| .becauseOf(error.getMessage(rangerPolicyItemAccess.getType(), dataMaskAccessTypeDefNames)) |
| .errorCode(error.getErrorCode()) |
| .build()); |
| valid = false; |
| } |
| } |
| } |
| } |
| } |
| } |
| |
| if(LOG.isDebugEnabled()) { |
| LOG.debug(String.format("<== RangerPolicyValidator.isValidAccessTypeDef(%s, %s, %s,%s,%s)", policy, failures, action,isAdmin,serviceDef)); |
| } |
| return valid; |
| } |
| |
| boolean isValidResources(RangerPolicy policy, final List<ValidationFailureDetails> failures, Action action, |
| boolean isAdmin, final RangerServiceDef serviceDef) { |
| |
| if(LOG.isDebugEnabled()) { |
| LOG.debug(String.format("==> RangerPolicyValidator.isValidResources(%s, %s, %s, %s, %s)", policy, failures, action, isAdmin, serviceDef)); |
| } |
| |
| boolean valid = true; |
| Map<String, RangerPolicyResource> resourceMap = policy.getResources(); |
| if (resourceMap != null) { // following checks can't be done meaningfully otherwise |
| valid = isPolicyResourceUnique(policy, failures, action) && valid; |
| if (serviceDef != null) { // following checks can't be done meaningfully otherwise |
| valid = isValidResourceNames(policy, failures, serviceDef) && valid; |
| valid = isValidResourceValues(resourceMap, failures, serviceDef) && valid; |
| valid = isValidResourceFlags(resourceMap, failures, serviceDef.getResources(), serviceDef.getName(), policy.getName(), isAdmin) && valid; |
| } |
| } |
| |
| if(LOG.isDebugEnabled()) { |
| LOG.debug(String.format("<== RangerPolicyValidator.isValidResources(%s, %s, %s, %s, %s): %s", policy, failures, action, isAdmin, serviceDef, valid)); |
| } |
| return valid; |
| } |
| |
| boolean isValidValiditySchedule(RangerPolicy policy, final List<ValidationFailureDetails> failures, Action action) { |
| |
| boolean valid = true; |
| if (LOG.isDebugEnabled()) { |
| LOG.debug(String.format("==> RangerPolicyValidator.isValidValiditySchedule(%s, %s, %s)", policy, failures, action)); |
| } |
| List<RangerValiditySchedule> validitySchedules = policy.getValiditySchedules(); |
| List<RangerValiditySchedule> normalizedValiditySchedules = null; |
| |
| for (RangerValiditySchedule entry : validitySchedules) { |
| RangerValidityScheduleValidator validator = new RangerValidityScheduleValidator(entry); |
| |
| RangerValiditySchedule normalizedValiditySchedule = validator.validate(failures); |
| if (normalizedValiditySchedule == null) { |
| valid = false; |
| if (LOG.isDebugEnabled()) { |
| LOG.debug("Invalid Validity-Schedule:[" + entry +"]"); |
| } |
| } else { |
| if (normalizedValiditySchedules == null) { |
| normalizedValiditySchedules = new ArrayList<>(); |
| } |
| normalizedValiditySchedules.add(normalizedValiditySchedule); |
| } |
| } |
| if (valid && CollectionUtils.isNotEmpty(normalizedValiditySchedules)) { |
| policy.setValiditySchedules(normalizedValiditySchedules); |
| } |
| if (LOG.isDebugEnabled()) { |
| LOG.debug(String.format("<== RangerPolicyValidator.isValidValiditySchedule(%s, %s, %s): %s", policy, failures, action, valid)); |
| } |
| return valid; |
| } |
| |
| boolean isPolicyResourceUnique(RangerPolicy policy, final List<ValidationFailureDetails> failures, Action action) { |
| |
| if(LOG.isDebugEnabled()) { |
| LOG.debug(String.format("==> RangerPolicyValidator.isPolicyResourceUnique(%s, %s, %s)", policy, failures, action)); |
| } |
| |
| boolean valid = true; |
| if (!Boolean.TRUE.equals(policy.getIsEnabled())) { |
| LOG.debug("Policy is disabled. Skipping resource uniqueness validation."); |
| } else { |
| RangerPolicyResourceSignature policySignature = _factory.createPolicyResourceSignature(policy); |
| String signature = policySignature.getSignature(); |
| List<RangerPolicy> policies = getPoliciesForResourceSignature(policy.getService(), signature); |
| if (CollectionUtils.isNotEmpty(policies)) { |
| ValidationErrorCode error = ValidationErrorCode.POLICY_VALIDATION_ERR_DUPLICATE_POLICY_RESOURCE; |
| RangerPolicy matchedPolicy = policies.iterator().next(); |
| // there shouldn't be a matching policy for create. During update only match should be to itself |
| if (action == Action.CREATE || (action == Action.UPDATE && (policies.size() > 1 || !matchedPolicy.getId().equals(policy.getId())))) { |
| failures.add(new ValidationFailureDetailsBuilder() |
| .field("resources") |
| .isSemanticallyIncorrect() |
| .becauseOf(error.getMessage(matchedPolicy.getName(), policy.getService())) |
| .errorCode(error.getErrorCode()) |
| .build()); |
| valid = false; |
| } |
| } |
| } |
| |
| if(LOG.isDebugEnabled()) { |
| LOG.debug(String.format("<== RangerPolicyValidator.isPolicyResourceUnique(%s, %s, %s): %s", policy, failures, action, valid)); |
| } |
| return valid; |
| } |
| |
| boolean isValidResourceNames(final RangerPolicy policy, final List<ValidationFailureDetails> failures, final RangerServiceDef serviceDef) { |
| |
| if(LOG.isDebugEnabled()) { |
| LOG.debug(String.format("==> RangerPolicyValidator.isValidResourceNames(%s, %s, %s)", policy, failures, serviceDef)); |
| } |
| |
| boolean valid = true; |
| convertPolicyResourceNamesToLower(policy); |
| Set<String> policyResources = policy.getResources().keySet(); |
| |
| RangerServiceDefHelper defHelper = new RangerServiceDefHelper(serviceDef); |
| Set<List<RangerResourceDef>> hierarchies = defHelper.getResourceHierarchies(policy.getPolicyType()); // this can be empty but not null! |
| if (hierarchies.isEmpty()) { |
| if (LOG.isDebugEnabled()) { |
| LOG.debug("RangerPolicyValidator.isValidResourceNames: serviceDef does not have any resource hierarchies, possibly due to invalid service def!!"); |
| } |
| ValidationErrorCode error = ValidationErrorCode.POLICY_VALIDATION_ERR_INVALID_RESOURCE_NO_COMPATIBLE_HIERARCHY; |
| failures.add(new ValidationFailureDetailsBuilder() |
| .field("service def resource hierarchies") |
| .subField("incompatible") |
| .isSemanticallyIncorrect() |
| .becauseOf(error.getMessage(serviceDef.getName(), " does not have any resource hierarchies")) |
| .errorCode(error.getErrorCode()) |
| .build()); |
| valid = false; |
| } else { |
| /* |
| * A policy is for a single hierarchy however, it doesn't specify which one. So we have to guess which hierarchy(s) it possibly be for. First, see if the policy could be for |
| * any of the known hierarchies? A candidate hierarchy is one whose resource levels are a superset of those in the policy. |
| * Why? What we want to catch at this stage is policies that straddles multiple hierarchies, e.g. db, udf and column for a hive policy. |
| * This has the side effect of catch spurious levels specified on the policy, e.g. having a level "blah" on a hive policy. |
| */ |
| Set<List<RangerResourceDef>> candidateHierarchies = filterHierarchies_hierarchyHasAllPolicyResources(policyResources, hierarchies, defHelper); |
| if (candidateHierarchies.isEmpty()) { |
| if (LOG.isDebugEnabled()) { |
| LOG.debug(String.format("No compatible resource hierarchies found: resource[%s], service-def[%s], valid-resource-hierarchies[%s]", |
| policyResources.toString(), serviceDef.getName(), toStringHierarchies_all(hierarchies, defHelper))); |
| } |
| ValidationErrorCode error; |
| if (hierarchies.size() == 1) { // we can give a simpler message for single hierarchy service-defs which is the majority of cases |
| error = ValidationErrorCode.POLICY_VALIDATION_ERR_INVALID_RESOURCE_NO_COMPATIBLE_HIERARCHY_SINGLE; |
| } else { |
| error = ValidationErrorCode.POLICY_VALIDATION_ERR_INVALID_RESOURCE_NO_COMPATIBLE_HIERARCHY; |
| } |
| failures.add(new ValidationFailureDetailsBuilder() |
| .field("policy resources") |
| .subField("incompatible") |
| .isSemanticallyIncorrect() |
| .becauseOf(error.getMessage(serviceDef.getName(), toStringHierarchies_all(hierarchies, defHelper))) |
| .errorCode(error.getErrorCode()) |
| .build()); |
| valid = false; |
| } else { |
| if (LOG.isDebugEnabled()) { |
| LOG.debug("isValidResourceNames: Found [" + candidateHierarchies.size() + "] compatible hierarchies: " + toStringHierarchies_all(candidateHierarchies, defHelper)); |
| } |
| /* |
| * Among the candidate hierarchies there should be at least one for which policy specifies all of the mandatory resources. Note that there could be multiple |
| * hierarchies that meet that criteria, e.g. a hive policy that specified only DB. It is not clear if it belongs to DB->UDF or DB->TBL->COL hierarchy. |
| * However, if both UDF and TBL were required then we can detect that policy does not specify mandatory levels for any of the candidate hierarchies. |
| */ |
| Set<List<RangerResourceDef>> validHierarchies = filterHierarchies_mandatoryResourcesSpecifiedInPolicy(policyResources, candidateHierarchies, defHelper); |
| if (validHierarchies.isEmpty()) { |
| ValidationErrorCode error; |
| if (candidateHierarchies.size() == 1) { // we can provide better message if there is a single candidate hierarchy |
| error = ValidationErrorCode.POLICY_VALIDATION_ERR_INVALID_RESOURCE_MISSING_MANDATORY_SINGLE; |
| } else { |
| error = ValidationErrorCode.POLICY_VALIDATION_ERR_INVALID_RESOURCE_MISSING_MANDATORY; |
| } |
| failures.add(new ValidationFailureDetailsBuilder() |
| .field("policy resources") |
| .subField("missing mandatory") |
| .isSemanticallyIncorrect() |
| .becauseOf(error.getMessage(serviceDef.getName(), toStringHierarchies_mandatory(candidateHierarchies, defHelper))) |
| .errorCode(error.getErrorCode()) |
| .build()); |
| valid = false; |
| } else { |
| if (LOG.isDebugEnabled()) { |
| LOG.debug("isValidResourceNames: Found hierarchies with all mandatory fields specified: " + toStringHierarchies_mandatory(validHierarchies, defHelper)); |
| } |
| } |
| } |
| } |
| |
| if(LOG.isDebugEnabled()) { |
| LOG.debug(String.format("<== RangerPolicyValidator.isValidResourceNames(%s, %s, %s): %s", policy, failures, serviceDef, valid)); |
| } |
| return valid; |
| } |
| |
| /** |
| * String representation of mandatory resources of all the hierarchies suitable of showing to user. Mandatory resources within a hierarchy are not ordered per the hierarchy. |
| * @param hierarchies |
| * @param defHelper |
| * @return |
| */ |
| String toStringHierarchies_mandatory(Set<List<RangerResourceDef>> hierarchies, RangerServiceDefHelper defHelper) { |
| |
| // helper function skipping sanity checks of getting null arguments passed |
| StringBuilder builder = new StringBuilder(); |
| for (List<RangerResourceDef> aHierarchy : hierarchies) { |
| builder.append(defHelper.getMandatoryResourceNames(aHierarchy)); |
| builder.append(" "); |
| } |
| return builder.toString(); |
| } |
| |
| /** |
| * String representation of all resources of all hierarchies. Resources within a hierarchy are ordered per the hierarchy. |
| * @param hierarchies |
| * @param defHelper |
| * @return |
| */ |
| String toStringHierarchies_all(Set<List<RangerResourceDef>> hierarchies, RangerServiceDefHelper defHelper) { |
| |
| // helper function skipping sanity checks of getting null arguments passed |
| StringBuilder builder = new StringBuilder(); |
| for (List<RangerResourceDef> aHierarchy : hierarchies) { |
| builder.append(defHelper.getAllResourceNamesOrdered(aHierarchy)); |
| builder.append(" "); |
| } |
| return builder.toString(); |
| } |
| /** |
| * Returns the subset of all hierarchies that are a superset of the policy's resources. |
| * @param policyResources |
| * @param hierarchies |
| * @return |
| */ |
| Set<List<RangerResourceDef>> filterHierarchies_hierarchyHasAllPolicyResources(Set<String> policyResources, Set<List<RangerResourceDef>> hierarchies, RangerServiceDefHelper defHelper) { |
| |
| // helper function skipping sanity checks of getting null arguments passed |
| Set<List<RangerResourceDef>> result = new HashSet<List<RangerResourceDef>>(hierarchies.size()); |
| for (List<RangerResourceDef> aHierarchy : hierarchies) { |
| if (defHelper.hierarchyHasAllResources(aHierarchy, policyResources)) { |
| result.add(aHierarchy); |
| } |
| } |
| return result; |
| } |
| |
| /** |
| * Returns the subset of hierarchies all of whose mandatory resources were found in policy's resource set. candidate hierarchies are expected to have passed |
| * <code>filterHierarchies_hierarchyHasAllPolicyResources</code> check first. |
| * @param policyResources |
| * @param hierarchies |
| * @param defHelper |
| * @return |
| */ |
| Set<List<RangerResourceDef>> filterHierarchies_mandatoryResourcesSpecifiedInPolicy(Set<String> policyResources, Set<List<RangerResourceDef>> hierarchies, RangerServiceDefHelper defHelper) { |
| |
| // helper function skipping sanity checks of getting null arguments passed |
| Set<List<RangerResourceDef>> result = new HashSet<List<RangerResourceDef>>(hierarchies.size()); |
| for (List<RangerResourceDef> aHierarchy : hierarchies) { |
| Set<String> mandatoryResources = defHelper.getMandatoryResourceNames(aHierarchy); |
| if (policyResources.containsAll(mandatoryResources)) { |
| result.add(aHierarchy); |
| } |
| } |
| return result; |
| } |
| |
| boolean isValidResourceFlags(final Map<String, RangerPolicyResource> inputPolicyResources, final List<ValidationFailureDetails> failures, |
| final List<RangerResourceDef> resourceDefs, final String serviceDefName, final String policyName, boolean isAdmin) { |
| if(LOG.isDebugEnabled()) { |
| LOG.debug(String.format("==> RangerPolicyValidator.isValidResourceFlags(%s, %s, %s, %s, %s, %s)", inputPolicyResources, failures, resourceDefs, serviceDefName, policyName, isAdmin)); |
| } |
| |
| boolean valid = true; |
| if (resourceDefs == null) { |
| LOG.debug("isValidResourceFlags: service Def is null"); |
| } else { |
| Map<String, RangerPolicyResource> policyResources = getPolicyResourceWithLowerCaseKeys(inputPolicyResources); |
| for (RangerResourceDef resourceDef : resourceDefs) { |
| if (resourceDef == null) { |
| ValidationErrorCode error = ValidationErrorCode.POLICY_VALIDATION_ERR_NULL_RESOURCE_DEF; |
| failures.add(new ValidationFailureDetailsBuilder() |
| .field("resource-def") |
| .isAnInternalError() |
| .becauseOf(error.getMessage(serviceDefName)) |
| .errorCode(error.getErrorCode()) |
| .build()); |
| valid = false; |
| } else if (StringUtils.isBlank(resourceDef.getName())) { |
| ValidationErrorCode error = ValidationErrorCode.POLICY_VALIDATION_ERR_MISSING_RESOURCE_DEF_NAME; |
| failures.add(new ValidationFailureDetailsBuilder() |
| .field("resource-def-name") |
| .isAnInternalError() |
| .becauseOf(error.getMessage(serviceDefName)) |
| .errorCode(error.getErrorCode()) |
| .build()); |
| valid = false; |
| } else { |
| String resourceName = resourceDef.getName().toLowerCase(); |
| RangerPolicyResource policyResource = policyResources.get(resourceName); |
| if (policyResource == null) { |
| if (LOG.isDebugEnabled()) { |
| LOG.debug("a policy-resource object for resource[" + resourceName + "] on policy [" + policyName + "] was null"); |
| } |
| } else { |
| boolean excludesSupported = Boolean.TRUE.equals(resourceDef.getExcludesSupported()); // could be null |
| boolean policyResourceIsExcludes = Boolean.TRUE.equals(policyResource.getIsExcludes()); // could be null |
| if (policyResourceIsExcludes && !excludesSupported) { |
| ValidationErrorCode error = ValidationErrorCode.POLICY_VALIDATION_ERR_EXCLUDES_NOT_SUPPORTED; |
| failures.add(new ValidationFailureDetailsBuilder() |
| .field("isExcludes") |
| .subField(resourceName) |
| .isSemanticallyIncorrect() |
| .becauseOf(error.getMessage(resourceName)) |
| .errorCode(error.getErrorCode()) |
| .build()); |
| valid = false; |
| } |
| if (policyResourceIsExcludes && !isAdmin) { |
| ValidationErrorCode error = ValidationErrorCode.POLICY_VALIDATION_ERR_EXCLUDES_REQUIRES_ADMIN; |
| failures.add(new ValidationFailureDetailsBuilder() |
| .field("isExcludes") |
| .subField("isAdmin") |
| .isSemanticallyIncorrect() |
| .becauseOf(error.getMessage()) |
| .errorCode(error.getErrorCode()) |
| .build()); |
| valid = false; |
| } |
| boolean recursiveSupported = Boolean.TRUE.equals(resourceDef.getRecursiveSupported()); |
| boolean policyIsRecursive = Boolean.TRUE.equals(policyResource.getIsRecursive()); |
| if (policyIsRecursive && !recursiveSupported) { |
| ValidationErrorCode error = ValidationErrorCode.POLICY_VALIDATION_ERR_RECURSIVE_NOT_SUPPORTED; |
| failures.add(new ValidationFailureDetailsBuilder() |
| .field("isRecursive") |
| .subField(resourceName) |
| .isSemanticallyIncorrect() |
| .becauseOf(error.getMessage(resourceName)) |
| .errorCode(error.getErrorCode()) |
| .build()); |
| valid = false; |
| } |
| } |
| } |
| } |
| } |
| |
| if(LOG.isDebugEnabled()) { |
| LOG.debug(String.format("<== RangerPolicyValidator.isValidResourceFlags(%s, %s, %s, %s, %s, %s): %s", inputPolicyResources, failures, resourceDefs, serviceDefName, policyName, isAdmin, valid)); |
| } |
| return valid; |
| } |
| |
| boolean isValidResourceValues(Map<String, RangerPolicyResource> resourceMap, List<ValidationFailureDetails> failures, RangerServiceDef serviceDef) { |
| if(LOG.isDebugEnabled()) { |
| LOG.debug(String.format("==> RangerPolicyValidator.isValidResourceValues(%s, %s, %s)", resourceMap, failures, serviceDef)); |
| } |
| |
| boolean valid = true; |
| Map<String, String> validationRegExMap = getValidationRegExes(serviceDef); |
| for (Map.Entry<String, RangerPolicyResource> entry : resourceMap.entrySet()) { |
| String name = entry.getKey(); |
| RangerPolicyResource policyResource = entry.getValue(); |
| if(policyResource != null) { |
| if(CollectionUtils.isNotEmpty(policyResource.getValues())) { |
| Set<String> resources = new HashSet<>(policyResource.getValues()); |
| for (String aValue : resources) { |
| if (StringUtils.isBlank(aValue)) { |
| policyResource.getValues().remove(aValue); |
| } |
| } |
| } |
| |
| if(CollectionUtils.isEmpty(policyResource.getValues())){ |
| ValidationErrorCode error = ValidationErrorCode.POLICY_VALIDATION_ERR_MISSING_RESOURCE_LIST; |
| if(LOG.isDebugEnabled()) { |
| LOG.debug(String.format("Resource list was empty or contains null: value[%s], resource-name[%s], service-def-name[%s]", policyResource.getValues(), name, serviceDef.getName())); |
| } |
| failures.add(new ValidationFailureDetailsBuilder() |
| .field("resource-values") |
| .subField(name) |
| .isMissing() |
| .becauseOf(error.getMessage(name)) |
| .errorCode(error.getErrorCode()) |
| .build()); |
| valid=false; |
| } |
| |
| if (validationRegExMap.containsKey(name) && CollectionUtils.isNotEmpty(policyResource.getValues())) { |
| String regEx = validationRegExMap.get(name); |
| for (String aValue : policyResource.getValues()) { |
| if (!aValue.matches(regEx)) { |
| if (LOG.isDebugEnabled()) { |
| LOG.debug(String.format("Resource failed regex check: value[%s], resource-name[%s], regEx[%s], service-def-name[%s]", aValue, name, regEx, serviceDef.getName())); |
| } |
| ValidationErrorCode error = ValidationErrorCode.POLICY_VALIDATION_ERR_INVALID_RESOURCE_VALUE_REGEX; |
| failures.add(new ValidationFailureDetailsBuilder() |
| .field("resource-values") |
| .subField(name) |
| .isSemanticallyIncorrect() |
| .becauseOf(error.getMessage(aValue, name)) |
| .errorCode(error.getErrorCode()) |
| .build()); |
| valid = false; |
| } |
| } |
| } |
| } |
| } |
| |
| if(LOG.isDebugEnabled()) { |
| LOG.debug(String.format("<== RangerPolicyValidator.isValidResourceValues(%s, %s, %s): %s", resourceMap, failures, serviceDef, valid)); |
| } |
| return valid; |
| } |
| |
| boolean isValidPolicyItems(List<RangerPolicyItem> policyItems, List<ValidationFailureDetails> failures, RangerServiceDef serviceDef) { |
| if(LOG.isDebugEnabled()) { |
| LOG.debug(String.format("==> RangerPolicyValidator.isValid(%s, %s, %s)", policyItems, failures, serviceDef)); |
| } |
| |
| boolean valid = true; |
| if (CollectionUtils.isEmpty(policyItems)) { |
| LOG.debug("policy items collection was null/empty"); |
| } else { |
| for (RangerPolicyItem policyItem : policyItems) { |
| if (policyItem == null) { |
| ValidationErrorCode error = ValidationErrorCode.POLICY_VALIDATION_ERR_NULL_POLICY_ITEM; |
| failures.add(new ValidationFailureDetailsBuilder() |
| .field("policy item") |
| .isMissing() |
| .becauseOf(error.getMessage()) |
| .errorCode(error.getErrorCode()) |
| .build()); |
| valid = false; |
| } else { |
| // we want to go through all elements even though one may be bad so all failures are captured |
| valid = isValidPolicyItem(policyItem, failures, serviceDef) && valid; |
| } |
| } |
| } |
| |
| if(LOG.isDebugEnabled()) { |
| LOG.debug(String.format("<== RangerPolicyValidator.isValid(%s, %s, %s): %s", policyItems, failures, serviceDef, valid)); |
| } |
| return valid; |
| } |
| |
| boolean isValidPolicyItem(RangerPolicyItem policyItem, List<ValidationFailureDetails> failures, RangerServiceDef serviceDef) { |
| if(LOG.isDebugEnabled()) { |
| LOG.debug(String.format("==> RangerPolicyValidator.isValid(%s, %s, %s)", policyItem, failures, serviceDef)); |
| } |
| |
| boolean valid = true; |
| if (policyItem == null) { |
| LOG.debug("policy item was null!"); |
| } else { |
| // access items collection can't be empty (unless delegated admin is true) and should be otherwise valid |
| if (CollectionUtils.isEmpty(policyItem.getAccesses())) { |
| if (!Boolean.TRUE.equals(policyItem.getDelegateAdmin())) { |
| ValidationErrorCode error = ValidationErrorCode.POLICY_VALIDATION_ERR_MISSING_FIELD; |
| failures.add(new ValidationFailureDetailsBuilder() |
| .field("policy item accesses") |
| .isMissing() |
| .becauseOf(error.getMessage("policy item accesses")) |
| .errorCode(error.getErrorCode()) |
| .build()); |
| valid = false; |
| } else { |
| LOG.debug("policy item collection was null but delegated admin is true. Ok"); |
| } |
| } else { |
| valid = isValidItemAccesses(policyItem.getAccesses(), failures, serviceDef) && valid; |
| } |
| // both users and user-groups collections can't be empty |
| if (CollectionUtils.isEmpty(policyItem.getUsers()) && CollectionUtils.isEmpty(policyItem.getGroups()) && CollectionUtils.isEmpty(policyItem.getRoles())) { |
| ValidationErrorCode error = ValidationErrorCode.POLICY_VALIDATION_ERR_MISSING_USER_AND_GROUPS; |
| failures.add(new ValidationFailureDetailsBuilder() |
| .field("policy item users/user-groups/roles") |
| .isMissing() |
| .becauseOf(error.getMessage()) |
| .errorCode(error.getErrorCode()) |
| .build()); |
| valid = false; |
| } |
| } |
| |
| if(LOG.isDebugEnabled()) { |
| LOG.debug(String.format("<== RangerPolicyValidator.isValid(%s, %s, %s): %s", policyItem, failures, serviceDef, valid)); |
| } |
| return valid; |
| } |
| |
| boolean isValidItemAccesses(List<RangerPolicyItemAccess> accesses, List<ValidationFailureDetails> failures, RangerServiceDef serviceDef) { |
| if(LOG.isDebugEnabled()) { |
| LOG.debug(String.format("==> RangerPolicyValidator.isValid(%s, %s, %s)", accesses, failures, serviceDef)); |
| } |
| |
| boolean valid = true; |
| if (CollectionUtils.isEmpty(accesses)) { |
| LOG.debug("policy item accesses collection was null/empty!"); |
| } else { |
| Set<String> accessTypes = getAccessTypes(serviceDef); |
| for (RangerPolicyItemAccess access : accesses) { |
| if (access == null) { |
| ValidationErrorCode error = ValidationErrorCode.POLICY_VALIDATION_ERR_NULL_POLICY_ITEM_ACCESS; |
| failures.add(new ValidationFailureDetailsBuilder() |
| .field("policy item access") |
| .isMissing() |
| .becauseOf(error.getMessage()) |
| .errorCode(error.getErrorCode()) |
| .build()); |
| valid = false; |
| } else { |
| // we want to go through all elements even though one may be bad so all failures are captured |
| valid = isValidPolicyItemAccess(access, failures, accessTypes) && valid; |
| } |
| } |
| } |
| |
| if(LOG.isDebugEnabled()) { |
| LOG.debug(String.format("<== RangerPolicyValidator.isValid(%s, %s, %s): %b", accesses, failures, serviceDef, valid)); |
| } |
| return valid; |
| } |
| |
| boolean isValidPolicyItemAccess(RangerPolicyItemAccess access, List<ValidationFailureDetails> failures, Set<String> accessTypes) { |
| if(LOG.isDebugEnabled()) { |
| LOG.debug(String.format("==> RangerPolicyValidator.isValidPolicyItemAccess(%s, %s, %s)", access, failures, accessTypes)); |
| } |
| |
| boolean valid = true; |
| if (CollectionUtils.isEmpty(accessTypes)) { // caller should firewall this argument! |
| LOG.debug("isValidPolicyItemAccess: accessTypes was null!"); |
| } else if (access == null) { |
| LOG.debug("isValidPolicyItemAccess: policy item access was null!"); |
| } else { |
| String accessType = access.getType(); |
| if (StringUtils.isBlank(accessType)) { |
| ValidationErrorCode error = ValidationErrorCode.POLICY_VALIDATION_ERR_MISSING_FIELD; |
| failures.add(new ValidationFailureDetailsBuilder() |
| .field("policy item access type") |
| .isMissing() |
| .becauseOf(error.getMessage("policy item access type")) |
| .errorCode(error.getErrorCode()) |
| .build()); |
| valid = false; |
| } else { |
| String matchedAccessType = getMatchedAccessType(accessType, accessTypes); |
| if (StringUtils.isEmpty(matchedAccessType)) { |
| ValidationErrorCode error = ValidationErrorCode.POLICY_VALIDATION_ERR_POLICY_ITEM_ACCESS_TYPE_INVALID; |
| failures.add(new ValidationFailureDetailsBuilder() |
| .field("policy item access type") |
| .isSemanticallyIncorrect() |
| .becauseOf(error.getMessage(accessType, accessTypes)) |
| .errorCode(error.getErrorCode()) |
| .build()); |
| valid = false; |
| } else { |
| access.setType(matchedAccessType); |
| } |
| } |
| Boolean isAllowed = access.getIsAllowed(); |
| // it can be null (which is treated as allowed) but not false |
| if (isAllowed != null && isAllowed == false) { |
| ValidationErrorCode error = ValidationErrorCode.POLICY_VALIDATION_ERR_POLICY_ITEM_ACCESS_TYPE_DENY; |
| failures.add(new ValidationFailureDetailsBuilder() |
| .field("policy item access type allowed") |
| .isSemanticallyIncorrect() |
| .becauseOf(error.getMessage()) |
| .errorCode(error.getErrorCode()) |
| .build()); |
| valid = false; |
| } |
| } |
| |
| if(LOG.isDebugEnabled()) { |
| LOG.debug(String.format("<== RangerPolicyValidator.isValidPolicyItemAccess(%s, %s, %s): %s", access, failures, accessTypes, valid)); |
| } |
| return valid; |
| } |
| |
| String getMatchedAccessType(String accessType, Set<String> validAccessTypes) { |
| String ret = null; |
| for (String validType : validAccessTypes) { |
| if (StringUtils.equalsIgnoreCase(accessType, validType)) { |
| ret = validType; |
| break; |
| } |
| } |
| return ret; |
| } |
| } |