/*
* 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 static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.apache.commons.collections.CollectionUtils;
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.RangerServiceDef;
import org.apache.ranger.plugin.model.RangerServiceDef.RangerAccessTypeDef;
import org.apache.ranger.plugin.model.RangerServiceDef.RangerEnumDef;
import org.apache.ranger.plugin.model.RangerServiceDef.RangerEnumElementDef;
import org.apache.ranger.plugin.model.RangerServiceDef.RangerPolicyConditionDef;
import org.apache.ranger.plugin.model.RangerServiceDef.RangerResourceDef;
import org.apache.ranger.plugin.model.RangerServiceDef.RangerServiceConfigDef;
import org.junit.Assert;
public class ValidationTestUtils {
Map<String, String> createMap(String[] keys) {
Map<String, String> result = new HashMap<>();
for (String key : keys) {
result.put(key, "valueof-" + key);
}
return result;
}
// helper methods for tests
List<RangerServiceConfigDef> createServiceConditionDefs(Object[][] input) {
List<RangerServiceConfigDef> result = new ArrayList<>();
for (Object data[] : input) {
RangerServiceConfigDef aConfigDef = mock(RangerServiceConfigDef.class);
when(aConfigDef.getName()).thenReturn((String)data[0]);
when(aConfigDef.getMandatory()).thenReturn((boolean)data[1]);
result.add(aConfigDef);
}
return result;
}
void checkFailureForSemanticError(List<ValidationFailureDetails> failures, String fieldName) {
checkFailure(failures, null, null, true, fieldName, null);
}
void checkFailureForSemanticError(List<ValidationFailureDetails> failures, String fieldName, String subField) {
checkFailure(failures, null, null, true, fieldName, subField);
}
void checkFailureForMissingValue(List<ValidationFailureDetails> failures, String field) {
checkFailure(failures, null, true, null, field, null);
}
void checkFailureForMissingValue(List<ValidationFailureDetails> failures, String field, String subField) {
checkFailure(failures, null, true, null, field, subField);
}
// check if any one of the sub-fields is present
void checkFailureForMissingValue(List<ValidationFailureDetails> failures, String field, String[] subFields) {
if (CollectionUtils.isEmpty(failures)) {
Assert.fail("List of failures is null/empty!");
} else {
boolean found = false;
int i = 0;
while (!found && i < subFields.length) {
String subField = subFields[i];
if (hasFailure(failures, null, true, null, field, subField)) {
found = true;
}
i++;
}
Assert.assertTrue(failures.toString(), found);
}
}
void checkFailureForInternalError(List<ValidationFailureDetails> failures, String fieldName) {
checkFailure(failures, true, null, null, fieldName, null);
}
void checkFailureForInternalError(List<ValidationFailureDetails> failures) {
checkFailure(failures, true, null, null, null, null);
}
void checkFailure(List<ValidationFailureDetails> failures, Boolean internalError, Boolean missing, Boolean semanticError, String field, String subField) {
if (CollectionUtils.isEmpty(failures)) {
Assert.fail("List of failures is null/empty!");
} else {
boolean found = hasFailure(failures, internalError, missing, semanticError, field, subField);
Assert.assertTrue(failures.toString(), found);
}
}
boolean hasFailure(List<ValidationFailureDetails> failures, Boolean internalError, Boolean missing, Boolean semanticError, String field, String subField) {
boolean found = false;
for (ValidationFailureDetails f : failures) {
if ((internalError == null || internalError == f._internalError) &&
(missing == null || missing == f._missing) &&
(semanticError == null || semanticError == f._semanticError) &&
(field == null || field.equals(f._fieldName)) &&
(subField == null || subField.equals(f._subFieldName))) {
found = true;
}
}
return found;
}
List<RangerAccessTypeDef> createAccessTypeDefs(String[] names) {
Assert.assertFalse(names == null); // fail if null is passed in!
List<RangerAccessTypeDef> defs = new ArrayList<RangerServiceDef.RangerAccessTypeDef>();
for (String name : names) {
RangerAccessTypeDef def = mock(RangerAccessTypeDef.class);
when(def.getName()).thenReturn(name);
defs.add(def);
}
return defs;
}
List<RangerAccessTypeDef> createAccessTypeDefs(Object[][] data) {
if (data == null) {
return null;
}
List<RangerAccessTypeDef> result = new ArrayList<>();
if (data.length == 0) {
return result;
}
for (Object[] entry : data) {
Long itemId = (Long)entry[0];
String accessType = (String)entry[1];
String[] impliedAccessArray = (String[])entry[2];
List<String> impliedAccesses = null;
if (impliedAccessArray != null) {
impliedAccesses = Arrays.asList(impliedAccessArray);
}
RangerAccessTypeDef aTypeDef = mock(RangerAccessTypeDef.class);
when(aTypeDef.getName()).thenReturn(accessType);
when(aTypeDef.getImpliedGrants()).thenReturn(impliedAccesses);
when(aTypeDef.getItemId()).thenReturn(itemId);
result.add(aTypeDef);
}
return result;
}
RangerServiceDef createServiceDefWithAccessTypes(String[] accesses, String serviceName) {
RangerServiceDef serviceDef = createServiceDefWithAccessTypes(accesses);
when(serviceDef.getName()).thenReturn(serviceName);
return serviceDef;
}
RangerServiceDef createServiceDefWithAccessTypes(String[] accesses) {
RangerServiceDef serviceDef = mock(RangerServiceDef.class);
List<RangerAccessTypeDef> accessTypeDefs = new ArrayList<>();
for (String access : accesses) {
RangerAccessTypeDef accessTypeDef = mock(RangerAccessTypeDef.class);
when(accessTypeDef.getName()).thenReturn(access);
accessTypeDefs.add(accessTypeDef);
}
when(serviceDef.getAccessTypes()).thenReturn(accessTypeDefs);
return serviceDef;
}
List<RangerPolicyItemAccess> createItemAccess(Object[][] data) {
List<RangerPolicyItemAccess> accesses = new ArrayList<>();
for (Object[] row : data) {
RangerPolicyItemAccess access = mock(RangerPolicyItemAccess.class);
when(access.getType()).thenReturn((String)row[0]);
when(access.getIsAllowed()).thenReturn((Boolean)row[1]);
accesses.add(access);
}
return accesses;
}
List<RangerPolicyItem> createPolicyItems(Object[] data) {
List<RangerPolicyItem> policyItems = new ArrayList<>();
for (Object object : data) {
@SuppressWarnings("unchecked")
Map<String, Object[]> map = (Map<String, Object[]>) object;
RangerPolicyItem policyItem = mock(RangerPolicyItem.class);
List<String> usersList = null;
if (map.containsKey("users")) {
usersList = Arrays.asList((String[])map.get("users"));
}
when(policyItem.getUsers()).thenReturn(usersList);
List<String> groupsList = null;
if (map.containsKey("groups")) {
groupsList = Arrays.asList((String[])map.get("groups"));
}
when(policyItem.getGroups()).thenReturn(groupsList);
String[] accesses = (String[])map.get("accesses");
Boolean[] isAllowedFlags = (Boolean[])map.get("isAllowed");
List<RangerPolicyItemAccess> accessesList = null;
if (accesses != null && isAllowedFlags != null) {
accessesList = new ArrayList<>();
for (int i = 0; i < accesses.length; i++) {
String access = accesses[i];
Boolean isAllowed = isAllowedFlags[i];
RangerPolicyItemAccess itemAccess = mock(RangerPolicyItemAccess.class);
when(itemAccess.getType()).thenReturn(access);
when(itemAccess.getIsAllowed()).thenReturn(isAllowed);
accessesList.add(itemAccess);
}
}
when(policyItem.getAccesses()).thenReturn(accessesList);
policyItems.add(policyItem);
}
return policyItems;
}
List<RangerResourceDef> createResourceDefs(Object[][] data) {
// if data itself is null then return null back
if (data == null) {
return null;
}
List<RangerResourceDef> defs = new ArrayList<>();
for (Object[] row : data) {
RangerResourceDef aDef = null;
if (row != null) {
String name = null;
Boolean mandatory = null;
String regExPattern = null;
Boolean isExcludesSupported = null;
Boolean isRecursiveSupported = null;
String parent = null;
Integer level = null;
switch(row.length) {
case 7:
level = (Integer)row[6];
case 6:
parent = (String) row[5];
case 5:
regExPattern = (String)row[4];
case 4:
mandatory = (Boolean)row[3];
case 3:
isRecursiveSupported = (Boolean)row[2];
case 2:
isExcludesSupported = (Boolean)row[1];
case 1:
name = (String)row[0];
}
aDef = mock(RangerResourceDef.class);
when(aDef.getName()).thenReturn(name);
when(aDef.getMandatory()).thenReturn(mandatory);
when(aDef.getValidationRegEx()).thenReturn(regExPattern);
when(aDef.getExcludesSupported()).thenReturn(isExcludesSupported);
when(aDef.getRecursiveSupported()).thenReturn(isRecursiveSupported);
when(aDef.getParent()).thenReturn(parent);
when(aDef.getLevel()).thenReturn(level);
}
defs.add(aDef);
}
return defs;
}
List<RangerResourceDef> createResourceDefsWithRegEx(String[][] data) {
// if data itself is null then return null back
if (data == null) {
return null;
}
List<RangerResourceDef> defs = new ArrayList<>();
for (String[] row : data) {
RangerResourceDef aDef = null;
if (row != null) {
String name = row[0];
String regEx = row[1];
aDef = mock(RangerResourceDef.class);
when(aDef.getName()).thenReturn(name);
when(aDef.getValidationRegEx()).thenReturn(regEx);
}
defs.add(aDef);
}
return defs;
}
List<RangerResourceDef> createResourceDefsWithIds(Object[][] data) {
// if data itself is null then return null back
if (data == null) {
return null;
}
List<RangerResourceDef> defs = new ArrayList<>();
for (Object[] row : data) {
RangerResourceDef aDef = null;
if (row != null) {
Long itemId = (Long)row[0];
Integer level = (Integer)row[1];
String name = (String)row[2];
aDef = mock(RangerResourceDef.class);
when(aDef.getName()).thenReturn(name);
when(aDef.getItemId()).thenReturn(itemId);
when(aDef.getLevel()).thenReturn(level);
}
defs.add(aDef);
}
return defs;
}
List<RangerEnumElementDef> createEnumElementDefs(String[] input) {
if (input == null) {
return null;
}
Object[][] data = new Object[input.length][];
for (int i = 0; i < input.length; i++) {
data[i] = new Object[] { (long)i, input[i] };
}
return createEnumElementDefs(data);
}
List<RangerEnumElementDef> createEnumElementDefs(Object[][] input) {
if (input == null) {
return null;
}
List<RangerEnumElementDef> output = new ArrayList<>();
for (Object[] row : input) {
RangerEnumElementDef aDef = mock(RangerEnumElementDef.class);
switch(row.length) {
case 2:
when(aDef.getName()).thenReturn((String)row[1]);
case 1:
when(aDef.getItemId()).thenReturn((Long) row[0]);
}
output.add(aDef);
}
return output;
}
List<RangerEnumDef> createEnumDefs(Object[][] input) {
if (input == null) {
return null;
}
List<RangerEnumDef> defs = new ArrayList<>();
for (Object[] row : input) {
RangerEnumDef enumDef = mock(RangerEnumDef.class);
switch (row.length) {
case 3:
List<RangerEnumElementDef> elements = createEnumElementDefs((String[])row[2]);
when(enumDef.getElements()).thenReturn(elements);
// by default set default index to last element
when(enumDef.getDefaultIndex()).thenReturn(elements.size() - 1);
case 2:
String enumName = (String) row[1];
when(enumDef.getName()).thenReturn(enumName);
case 1:
when(enumDef.getItemId()).thenReturn((Long)row[0]);
}
defs.add(enumDef);
}
return defs;
}
public Map<String, RangerPolicyResource> createPolicyResourceMap(Object[][] input) {
if (input == null) {
return null;
}
Map<String, RangerPolicyResource> result = new HashMap<String, RangerPolicyResource>(input.length);
for (Object[] row : input) {
String resourceName = (String)row[0];
String[] valuesArray = (String[])row[1];
Boolean isExcludes = (Boolean)row[2];
Boolean isRecursive = (Boolean)row[3];
RangerPolicyResource aResource = mock(RangerPolicyResource.class);
if (valuesArray == null) {
when(aResource.getValues()).thenReturn(null);
} else {
when(aResource.getValues()).thenReturn(Arrays.asList(valuesArray));
}
when(aResource.getIsExcludes()).thenReturn(isExcludes);
when(aResource.getIsRecursive()).thenReturn(isRecursive);
result.put(resourceName, aResource);
}
return result;
}
List<RangerServiceConfigDef> createServiceDefConfigs(Object[][] input) {
if (input == null) {
return null;
}
List<RangerServiceConfigDef> result = new ArrayList<>();
for (Object[] row : input) {
RangerServiceConfigDef configDef = mock(RangerServiceConfigDef.class);
switch(row.length) {
case 5: // default value
when(configDef.getDefaultValue()).thenReturn((String)row[4]);
case 4: // subtype
when(configDef.getSubType()).thenReturn((String) row[3]);
case 3: // type
String type = (String)row[2];
when(configDef.getType()).thenReturn(type);
case 2: // name
String name = (String)row[1];
when(configDef.getName()).thenReturn(name);
case 1: // id
Long itemId = (Long)row[0];
when(configDef.getItemId()).thenReturn(itemId);
}
result.add(configDef);
}
return result;
}
List<RangerPolicyConditionDef> createPolicyConditionDefs(Object[][] input) {
List<RangerPolicyConditionDef> result = new ArrayList<>();
if (input != null) {
for (Object[] row : input) {
RangerPolicyConditionDef conditionDef = mock(RangerPolicyConditionDef.class);
when(conditionDef.getItemId()).thenReturn((Long)row[0]);
when(conditionDef.getName()).thenReturn((String)row[1]);
when(conditionDef.getEvaluator()).thenReturn((String)row[2]);
result.add(conditionDef);
}
}
return result;
}
}