in agents-common/src/main/java/org/apache/ranger/plugin/model/validation/RangerPolicyValidator.java [115:455]
boolean isValid(RangerPolicy policy, Action action, boolean isAdmin, List<ValidationFailureDetails> failures) {
LOG.debug("==> RangerPolicyValidator.isValid({}, {}, {}, {})", 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 policyServicetype = policy.getServiceType();
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;
String serviceType = service.getType();
if (StringUtils.isNotEmpty(serviceType) && StringUtils.isNotEmpty(policyServicetype)) {
if (!serviceType.equalsIgnoreCase(policyServicetype)) {
ValidationErrorCode error = ValidationErrorCode.POLICY_VALIDATION_ERR_INVALID_SERVICE_TYPE;
failures.add(new ValidationFailureDetailsBuilder()
.field("service type")
.isSemanticallyIncorrect()
.becauseOf(error.getMessage(policyServicetype, serviceName))
.errorCode(error.getErrorCode())
.build());
valid = false;
}
}
}
}
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;
} else {
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;
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;
@SuppressWarnings("unchecked")
List<RangerPolicyItem> dataMaskPolicyItems = (List<RangerPolicyItem>) (List<?>) policy.getDataMaskPolicyItems();
valid = isValidPolicyItems(dataMaskPolicyItems, failures, serviceDef) && valid;
@SuppressWarnings("unchecked")
List<RangerPolicyItem> rowFilterPolicyItems = (List<RangerPolicyItem>) (List<?>) policy.getRowFilterPolicyItems();
valid = isValidPolicyItems(rowFilterPolicyItems, 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;
}
}
LOG.debug("<== RangerPolicyValidator.isValid({}, {}, {}, {}): {}", policy, action, isAdmin, failures, valid);
return valid;
}