blob: 79af9f6501b9cd4f5d39aa80b88b51ec3c72b2b7 [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.authorization.nestedstructure.authorizer;
import com.google.gson.JsonParser;
import org.testng.Assert;
import org.testng.annotations.DataProvider;
import org.testng.annotations.Test;
import java.util.Arrays;
import java.util.List;
import java.util.Set;
import static org.apache.ranger.authorization.nestedstructure.authorizer.MaskTypes.*;
public class TestJsonManipulator {
static final String testString1 = "{\n" +
" \"customerRelationshipId\": \"42207ad4\",\n" +
" \"accountnumber\": \"12345678\",\n" +
" \"partner\": \"dance\",\n" +
" \"acquisitionDate\": \"2018-02-01\",\n" +
" \"customerSubtype\": [\n" +
" \"type1\",\n" +
" \"type2\"\n" +
" ],\n" +
" \"address\": {\n" +
" \"addressLine1\": \"123 Main St\",\n" +
" \"addressLine2\": \"Apt1\",\n" +
" \"city\": \"philadelphia\",\n" +
" \"state\": \"PA\",\n" +
" \"zipCode\": \"19019\",\n" +
" \"zipCodePlus4\": \"1111\",\n" +
" \"country\": \"USA\"\n" +
" }\n" +
"}\n";
static final String bigTester = "{" +
" \"someString\": \"42207ad4-590e-4d5d-a65f-6a4ccddca9e3002\"," +
" \"someNumber\": 12345678," +
" \"someBoolean\": true," +
" \"stringArray\": [\"thing1\", \"thing2\"]," +
" \"numberArray\": [1, 2, 3]," +
" \"booleanArray\": [true, false, true]," +
" \"aMap\": {" +
" \"mapString\": \"123 Main St\"," +
" \"mapBoolean\": false," +
" \"mapNumber\": 987," +
" \"mapStrinArray\": [\"one\", \"two\"]," +
" \"mapMap\": {\"mapMapString\": \"19019\"}" +
" }\n" +
"}\n";
@Test
public void testFieldNames1() {
JsonManipulator js = new JsonManipulator("{foo: 1}");
Assert.assertEquals(js.getFields().size(), 1);
}
@Test
public void testFieldNames2() {
JsonManipulator js = new JsonManipulator("{foo: 1, bar: 2}");
Assert.assertEquals(js.getFields().size(), 2);
}
@Test
public void testFieldNamesBigger() {
JsonManipulator js = new JsonManipulator(testString1);
System.out.println(js.getFields());
Set<String> fields = js.getFields();
Assert.assertTrue(fields.contains("customerRelationshipId"));
Assert.assertTrue(fields.contains("partner"));
Assert.assertTrue(fields.contains("acquisitionDate"));
Assert.assertTrue(fields.contains("customerSubtype.*"));
Assert.assertTrue(fields.contains("accountnumber"));
Assert.assertTrue(fields.contains("address.addressLine1"));
Assert.assertTrue(fields.contains("address.addressLine2"));
Assert.assertTrue(fields.contains("address.city"));
Assert.assertTrue(fields.contains("address.zipCode"));
Assert.assertTrue(fields.contains("address.zipCodePlus4"));
Assert.assertTrue(fields.contains("address.state"));
Assert.assertTrue(fields.contains("address.country"));
Assert.assertEquals(js.getFields().size(), 12);
}
@Test(expectedExceptions = {MaskingException.class})
public void invalidJson() {
JsonManipulator js = new JsonManipulator("{foo:\"bar\"");
Assert.assertEquals(js.getFields().size(), 1);
}
@Test
public void testToString() {
String condensedString = JsonParser.parseString(testString1).toString();
JsonManipulator man = new JsonManipulator(condensedString);
Assert.assertEquals(man.getJsonString(), condensedString);
}
@Test
public void testBigTesterFieldNames() {
JsonManipulator man = new JsonManipulator(bigTester);
Assert.assertEquals(man.getFields().size(), 11);
}
@DataProvider(name = "simpleMasks")
public Object[][] simpleMasks(){
return new Object[][] {
//basic string masking
{"{\"string1\":\"value1\"}",
Arrays.asList(
new FieldLevelAccess("string1", true, 1L, true, MASK_NULL, "customValue")),
"{\"string1\":null}"},
{"{\"string1\":\"value1\"}",
Arrays.asList(
new FieldLevelAccess("string1", true, 1L, true, CUSTOM, "customValue")),
"{\"string1\":\"customValue\"}"},
{"{\"string1\":\"value1\"}",
Arrays.asList(
new FieldLevelAccess("string1", true, 1L, true, MASK_NONE, "customValue")),
"{\"string1\":\"value1\"}"},
{"{\"string1\":\"value1\"}",
Arrays.asList(
new FieldLevelAccess("string1", true, 1L, true, MASK_SHOW_FIRST_4, "customValue")),
"{\"string1\":\"valuxx\"}"},
{"{\"string1\":\"value1\"}",
Arrays.asList(
new FieldLevelAccess("string1", true, 1L, true, MASK_SHOW_LAST_4, "customValue")),
"{\"string1\":\"xxlue1\"}"},
{"{\"string1\":\"value1\"}",
Arrays.asList(
new FieldLevelAccess("string1", true, 1L, true, MASK_HASH, "customValue")),
"{\"string1\":\"3c9683017f9e4bf33d0fbedd26bf143fd72de9b9dd145441b75f0604047ea28e\"}"},
{"{\"string1\":\"2021-12-25\"}",
Arrays.asList(
new FieldLevelAccess("string1", true, 1L, true, MASK_DATE_SHOW_YEAR, "customValue")),
"{\"string1\":\"2021\"}"},
//basic number masking
{"{\"string1\":123456}",
Arrays.asList(
new FieldLevelAccess("string1", true, 1L, true, MASK_NULL, "100")),
"{\"string1\":null}"},
{"{\"string1\":123456}",
Arrays.asList(
new FieldLevelAccess("string1", true, 1L, true, CUSTOM, "100")),
"{\"string1\":100}"},
{"{\"string1\":123456}",
Arrays.asList(
new FieldLevelAccess("string1", true, 1L, true, MASK_NONE, "100")),
"{\"string1\":123456}"},
{"{\"string1\":123456}",
Arrays.asList(
new FieldLevelAccess("string1", true, 1L, true, MASK, "100")),
"{\"string1\":-11111}"},
//basic boolean masking
{"{\"string1\":true}",
Arrays.asList(
new FieldLevelAccess("string1", true, 1L, true, MASK_NULL, "true")),
"{\"string1\":null}"},
{"{\"string1\":true}",
Arrays.asList(
new FieldLevelAccess("string1", true, 1L, true, CUSTOM, "false")),
"{\"string1\":false}"},
{"{\"string1\":true}",
Arrays.asList(
new FieldLevelAccess("string1", true, 1L, true, MASK_NONE, "true")),
"{\"string1\":true}"},
{"{\"string1\":true}",
Arrays.asList(
new FieldLevelAccess("string1", true, 1L, true, MASK, "true")),
"{\"string1\":false}"},
//array string masking
{"{\"string1\":[\"aaaaaaa\",\"bbbbbbb\"]}",
Arrays.asList(
new FieldLevelAccess("string1.*", true, 1L, true, MASK_NULL, "true")),
"{\"string1\":[null,null]}"},
{"{\"string1\":[\"aaaaaaa\",\"bbbbbbb\"]}",
Arrays.asList(
new FieldLevelAccess("string1.*", true, 1L, true, CUSTOM, "false")),
"{\"string1\":[\"false\",\"false\"]}"},
{"{\"string1\":[\"aaaaaaa\",\"bbbbbbb\"]}",
Arrays.asList(
new FieldLevelAccess("string1.*", true, 1L, true, MASK_NONE, "true")),
"{\"string1\":[\"aaaaaaa\",\"bbbbbbb\"]}"},
{"{\"string1\":[\"aaaaaaa\",\"bbbbbbbbbb\"]}",
Arrays.asList(
new FieldLevelAccess("string1.*", true, 1L, true, MASK, "true")),
"{\"string1\":[\"*******\",\"**********\"]}"},
};
}
@Test(dataProvider = "simpleMasks")
void testSimpleMasks(String json, List<FieldLevelAccess> fieldAccess, String outputJson){
JsonManipulator man = new JsonManipulator(json);
man.maskFields(fieldAccess);
Assert.assertEquals(man.getJsonString(), outputJson);
}
@DataProvider(name = "complexMasks")
public Object[][] complexMasks(){
return new Object[][] {
//test masking two fields
{bigTester,
Arrays.asList(
new FieldLevelAccess("someNumber", true, 1L, true, CUSTOM, "555"),
new FieldLevelAccess("someBoolean", true, 1L, true, CUSTOM, "false")),
"someNumber", "555"},
{bigTester,
Arrays.asList(
new FieldLevelAccess("someNumber", true, 1L, true, CUSTOM, "555"),
new FieldLevelAccess("someBoolean", true, 1L, true, CUSTOM, "false")),
"someBoolean", "false"},
{bigTester,
Arrays.asList(
new FieldLevelAccess("someString", true, 1L, true, CUSTOM, "555")),
"someString", "555"},
{bigTester,
Arrays.asList(
new FieldLevelAccess("someNumber", true, 1L, true, CUSTOM, "555")),
"someNumber", "555"},
{bigTester,
Arrays.asList(
new FieldLevelAccess("stringArray.*", true, 1L, true, CUSTOM, "555")),
"stringArray.*", "[\"555\",\"555\"]"},
{bigTester,
Arrays.asList(
new FieldLevelAccess("booleanArray.*", true, 1L, true, CUSTOM, "false")),
"booleanArray.*", "[false,false,false]"},
{bigTester,
Arrays.asList(
new FieldLevelAccess("aMap.mapString", true, 1L, true, CUSTOM, "foo")),
"aMap.mapString", "foo"},
{bigTester,
Arrays.asList(
new FieldLevelAccess("aMap.mapBoolean", true, 1L, true, CUSTOM, "true")),
"aMap.mapBoolean", "true"},
{bigTester,
Arrays.asList(
new FieldLevelAccess("aMap.mapNumber", true, 1L, true, CUSTOM, "444")),
"aMap.mapNumber", "444"},
{bigTester,
Arrays.asList(
new FieldLevelAccess("aMap.mapStrinArray.*", true, 1L, true, CUSTOM, "baa")),
"aMap.mapStrinArray.*", "[\"baa\",\"baa\"]"},
{bigTester,
Arrays.asList(
new FieldLevelAccess("aMap.mapMap.mapMapString", true, 1L, true, CUSTOM, "444qqq")),
"aMap.mapMap.mapMapString", "444qqq"},
{bigTester,
Arrays.asList(
new FieldLevelAccess("aMap.mapMap.mapMapString", false, 1L, true, CUSTOM, "444qqq")),
"aMap.mapMap.mapMapString", "19019"},
{bigTester,
Arrays.asList(
new FieldLevelAccess("aMap.mapMap.mapMapString", true, 1L, false, CUSTOM, "444qqq")),
"aMap.mapMap.mapMapString", "19019"},
};
}
@Test(dataProvider = "complexMasks")
void testComplexMasks(String json, List<FieldLevelAccess> fieldAccess, String fieldName, String value){
JsonManipulator man = new JsonManipulator(json);
man.maskFields(fieldAccess);
Assert.assertEquals(man.readString(fieldName), value);
}
@Test
void testRecordsInArray(){
String json = "{\n" +
" \"modifiedTimestamp\": \"2000-01-23T04:56:07.000Z\",\n" +
" \"source\": [\n" +
" {\n" +
" \"sourceId\": \"123456\",\n" +
" \"sourceType\": \"a type\",\n" +
" \"sourceType2\": \"type two\",\n" +
" \"sourceSystem\": \"Source System\"\n" +
" }\n" +
" ],\n" +
" \"channel\": \"channel 4\",\n" +
" \"transactionStatus\": \"SUCCESS\",\n" +
" \"customAttributes\": [\n" +
" {\n" +
" \"key\": \"new\",\n" +
" \"value\": \"value1\"\n" +
" }\n" +
" ],\n" +
" \"modifiedBy\": \"batchJob\"\n" +
"}";
JsonManipulator man = new JsonManipulator(json);
Assert.assertEquals(man.getFields().size(), 10);
}
@Test
void testRecordsInArray2(){
String json = "{\n" +
" \"modifiedTimestamp\": \"2000-01-23T04:56:07.000Z\",\n" +
" \"source\": [\n" +
" {\n" +
" \"sourceId\": \"123456\",\n" +
" \"sourceType\": \"a type\",\n" +
" \"sourceType2\": \"type two\",\n" +
" \"sourceSystem\": \"Source System\"\n" +
" }\n" +
" ],\n" +
" \"channel\": \"channel 4\",\n" +
" \"transactionStatus\": \"SUCCESS\",\n" +
" \"customAttributes\": [\n" +
" {\n" +
" \"key\": \"new\",\n" +
" \"value\": \"value1\"\n" +
" },\n" +
" {\n" +
" \"key\": \"new22\",\n" +
" \"value\": \"value22\"\n" +
" }\n" +
" ],\n" +
" \"modifiedBy\": \"batchJob\"\n" +
"}";
JsonManipulator man = new JsonManipulator(json);
Assert.assertEquals(man.getFields().size(), 10);
FieldLevelAccess fieldAccess = new FieldLevelAccess("customAttributes.*.key",
true, 1L, true, CUSTOM, "THEMASK");
man.maskFields(Arrays.asList(fieldAccess));
Assert.assertEquals(man.readString("customAttributes.[0].key"), "THEMASK");
}
}