diff --git a/src/main/java/dev/blaauwendraad/masker/json/JsonPathNode.java b/src/main/java/dev/blaauwendraad/masker/json/JsonPathNode.java deleted file mode 100644 index c5e0b4f4..00000000 --- a/src/main/java/dev/blaauwendraad/masker/json/JsonPathNode.java +++ /dev/null @@ -1,36 +0,0 @@ -package dev.blaauwendraad.masker.json; - -/** - * A mutable reference to a sequence of bytes in {@link MaskingState#getMessage()}. - * It is used to represent JSONPath nodes. - *

- * There are two types of nodes: - *

- */ -sealed interface JsonPathNode permits JsonPathNode.Array, JsonPathNode.Node { - final class Node implements JsonPathNode { - private final int offset; - private final int length; - - Node(int index, int length) { - this.offset = index; - this.length = length; - } - - public int getOffset() { - return this.offset; - } - - public int getLength() { - return this.length; - } - } - - final class Array implements JsonPathNode { - // only wildcard indexes are supported - } -} diff --git a/src/main/java/dev/blaauwendraad/masker/json/KeyContainsMasker.java b/src/main/java/dev/blaauwendraad/masker/json/KeyContainsMasker.java index 0232e74d..015fa643 100644 --- a/src/main/java/dev/blaauwendraad/masker/json/KeyContainsMasker.java +++ b/src/main/java/dev/blaauwendraad/masker/json/KeyContainsMasker.java @@ -6,12 +6,11 @@ import dev.blaauwendraad.masker.json.util.AsciiJsonUtil; import javax.annotation.CheckForNull; -import java.util.Collections; /** * Default implementation of the {@link JsonMasker}. */ - final class KeyContainsMasker implements JsonMasker { +final class KeyContainsMasker implements JsonMasker { /** * Look-up trie containing the target keys. */ @@ -46,13 +45,8 @@ public byte[] mask(byte[] input) { KeyMaskingConfig keyMaskingConfig = maskingConfig.isInAllowMode() ? maskingConfig.getDefaultConfig() : null; if (maskingState.jsonPathEnabled()) { - // Check for "$" JSONPath key. - keyMaskingConfig = keyMatcher.getMaskConfigIfMatched( - maskingState.getMessage(), - -1, - -1, - Collections.emptyIterator() - ); + maskingState.expandCurrentJsonPath(keyMatcher.getJsonPathRootNode()); + keyMaskingConfig = keyMatcher.getMaskConfigIfMatched(maskingState.getMessage(), -1, -1, maskingState.getCurrentJsonPathNode()); } stepOverWhitespaceCharacters(maskingState); @@ -118,7 +112,7 @@ private void visitValue(MaskingState maskingState, @CheckForNull KeyMaskingConfi * {@link KeyMaskingConfig}. Otherwise, the value is not masked */ private void visitArray(MaskingState maskingState, @CheckForNull KeyMaskingConfig keyMaskingConfig) { - maskingState.expandCurrentJsonPathWithArray(); + maskingState.expandCurrentJsonPath(keyMatcher.traverseJsonPathSegment(maskingState.getMessage(), maskingState.getCurrentJsonPathNode(), -1, -1)); while (maskingState.next()) { stepOverWhitespaceCharacters(maskingState); // check if we're in an empty array @@ -164,13 +158,9 @@ private void visitObject(MaskingState maskingState, @CheckForNull KeyMaskingConf int afterClosingQuoteIndex = maskingState.currentIndex(); int keyLength = afterClosingQuoteIndex - openingQuoteIndex - 2; // minus the opening and closing quotes - maskingState.expandCurrentJsonPath(openingQuoteIndex + 1, keyLength); - KeyMaskingConfig keyMaskingConfig = keyMatcher.getMaskConfigIfMatched( - maskingState.getMessage(), - openingQuoteIndex + 1, // plus one for the opening quote - keyLength, - maskingState.getCurrentJsonPath() - ); + maskingState.expandCurrentJsonPath(keyMatcher.traverseJsonPathSegment(maskingState.getMessage(), maskingState.getCurrentJsonPathNode(), openingQuoteIndex + 1, keyLength)); + KeyMaskingConfig keyMaskingConfig = keyMatcher.getMaskConfigIfMatched(maskingState.getMessage(), openingQuoteIndex + 1, // plus one for the opening quote + keyLength, maskingState.getCurrentJsonPathNode()); stepOverWhitespaceCharacters(maskingState); // step over the colon ':' maskingState.next(); @@ -187,8 +177,7 @@ private void visitObject(MaskingState maskingState, @CheckForNull KeyMaskingConf // we got was the default config, then it means that the key doesn't have a specific configuration and // we should fall back to key specific config that the object is being masked with. // E.g.: '{ "a": { "b": "value" } }' we want to use config of 'b' if any, but fallback to config of 'a' - if (parentKeyMaskingConfig != null && (keyMaskingConfig == null - || keyMaskingConfig == maskingConfig.getDefaultConfig())) { + if (parentKeyMaskingConfig != null && (keyMaskingConfig == null || keyMaskingConfig == maskingConfig.getDefaultConfig())) { keyMaskingConfig = parentKeyMaskingConfig; } visitValue(maskingState, keyMaskingConfig); @@ -304,8 +293,7 @@ private static void stepOverWhitespaceCharacters(MaskingState maskingState) { private static void stepOverNumericValue(MaskingState maskingState) { // step over the first numeric character maskingState.next(); - while (maskingState.currentIndex() < maskingState.getMessage().length - && AsciiJsonUtil.isNumericCharacter(maskingState.byteAtCurrentIndex())) { + while (maskingState.currentIndex() < maskingState.getMessage().length && AsciiJsonUtil.isNumericCharacter(maskingState.byteAtCurrentIndex())) { maskingState.next(); } } diff --git a/src/main/java/dev/blaauwendraad/masker/json/KeyMatcher.java b/src/main/java/dev/blaauwendraad/masker/json/KeyMatcher.java index 822e0b20..d714fb7c 100644 --- a/src/main/java/dev/blaauwendraad/masker/json/KeyMatcher.java +++ b/src/main/java/dev/blaauwendraad/masker/json/KeyMatcher.java @@ -5,7 +5,6 @@ import javax.annotation.CheckForNull; import java.nio.charset.StandardCharsets; -import java.util.Iterator; /** * This key matcher is build using a byte trie structure to optimize the look-ups for JSON keys in the target key set. @@ -133,14 +132,14 @@ private void insert(String word, boolean negativeMatch) { * @return the config if the key needs to be masked, {@code null} if key does not need to be masked */ @CheckForNull - public KeyMaskingConfig getMaskConfigIfMatched(byte[] bytes, int keyOffset, int keyLength, Iterator jsonPath) { + public KeyMaskingConfig getMaskConfigIfMatched(byte[] bytes, int keyOffset, int keyLength, @CheckForNull TrieNode currentJsonPathNode) { // first search by key if (maskingConfig.isInMaskMode()) { // check JSONPath first, as it's more specific - TrieNode node = searchForJsonPathKeyNode(bytes, jsonPath); + TrieNode node = currentJsonPathNode; // if found - mask with this config // if not found - do not mask - if (node != null && !node.negativeMatch) { + if (node != null && node.endOfWord && !node.negativeMatch) { return node.keyMaskingConfig; } else if (keyLength != SKIP_KEY_LOOKUP) { // also check regular key @@ -152,11 +151,11 @@ public KeyMaskingConfig getMaskConfigIfMatched(byte[] bytes, int keyOffset, int return null; } else { // check JSONPath first, as it's more specific - TrieNode node = searchForJsonPathKeyNode(bytes, jsonPath); + TrieNode node = currentJsonPathNode; // if found and is not negativeMatch - do not mask // if found and is negative match - mask, but with a specific config // if not found - mask with default config - if (node != null) { + if (node != null && node.endOfWord) { if (node.negativeMatch) { return node.keyMaskingConfig; } @@ -199,52 +198,41 @@ private TrieNode searchNode(byte[] bytes, int offset, int length) { } @CheckForNull - private TrieNode searchForJsonPathKeyNode(byte[] bytes, Iterator jsonPath) { - TrieNode node = root; - node = node.children['$' + BYTE_OFFSET]; - if (node == null) { + public TrieNode getJsonPathRootNode() { + return root.children['$' + BYTE_OFFSET]; + } + + /** + * Traverses the trie along the passed JSONPath segment starting from {@code begin} node. + * The passed segment is represented as a key {@code (keyOffset, keyLength)} reference in {@code bytes} array. + * + * @param bytes the message bytes. + * @param begin a TrieNode from which the traversal begins. + * @param keyOffset the offset in {@code bytes} of the segment. + * @param keyLength the length of the segment. + * @return a TrieNode of the last symbol of the segment. {@code null} if the segment is not in the trie. + */ + @CheckForNull + public TrieNode traverseJsonPathSegment(byte[] bytes, @CheckForNull final TrieNode begin, int keyOffset, int keyLength) { + if (begin == null) { return null; } - if (node.endOfWord) { - return node; + TrieNode current = begin.children['.' + BYTE_OFFSET]; + if (current == null) { + return null; } - while (jsonPath.hasNext()) { - node = node.children['.' + BYTE_OFFSET]; - if (node == null) { - return null; - } - JsonPathNode jsonPathSegmentReference = jsonPath.next(); - TrieNode wildcardLookAhead = node.children['*' + BYTE_OFFSET]; - if (wildcardLookAhead != null && (wildcardLookAhead.endOfWord || wildcardLookAhead.children['.' + BYTE_OFFSET] != null)) { - node = wildcardLookAhead; - if (node.endOfWord) { - return node; - } - continue; - } - if (jsonPathSegmentReference instanceof JsonPathNode.Node jsonPathNode) { - int keyOffset = jsonPathNode.getOffset(); - int keyLength = jsonPathNode.getLength(); - for (int i = keyOffset; i < keyOffset + keyLength; i++) { - int b = bytes[i]; - node = node.children[b + BYTE_OFFSET]; - if (node == null) { - return null; - } - } - } else if (jsonPathSegmentReference instanceof JsonPathNode.Array) { - // only wildcard indexes are supported + TrieNode wildcardLookAhead = current.children['*' + BYTE_OFFSET]; + if (wildcardLookAhead != null && (wildcardLookAhead.endOfWord || wildcardLookAhead.children['.' + BYTE_OFFSET] != null)) { + return wildcardLookAhead; + } + for (int i = keyOffset; i < keyOffset + keyLength; i++) { + int b = bytes[i]; + current = current.children[b + BYTE_OFFSET]; + if (current == null) { return null; - } else { - throw new IllegalStateException("Unknown JSONPath segment reference type " + jsonPathSegmentReference.getClass()); } } - - if (!node.endOfWord) { - return null; - } - - return node; + return current; } /** @@ -252,20 +240,20 @@ private TrieNode searchForJsonPathKeyNode(byte[] bytes, Iterator currentJsonPath; - + private KeyMatcher.TrieNode[] currentJsonPath = null; + private int currentJsonPathIndex = -1; private int currentValueStartIndex = -1; public MaskingState(byte[] message, boolean trackJsonPath) { this.message = message; if (trackJsonPath) { - currentJsonPath = new ArrayDeque<>(); - } else { - currentJsonPath = null; + currentJsonPath = new KeyMatcher.TrieNode[100]; } } @@ -148,22 +145,17 @@ boolean jsonPathEnabled() { } /** - * Expands current jsonpath with a new "key" segment. - * @param start the index of a new segment start in message - * @param offset the length of a new segment. - */ - void expandCurrentJsonPath(int start, int offset) { - if (currentJsonPath != null) { - currentJsonPath.push(new JsonPathNode.Node(start, offset)); - } - } - - /** - * Expands current jsonpath with a new array segment. + * Expands current jsonpath. + * + * @param trieNode a node in the trie where the new segment ends. */ - void expandCurrentJsonPathWithArray() { + void expandCurrentJsonPath(@CheckForNull KeyMatcher.TrieNode trieNode) { if (currentJsonPath != null) { - currentJsonPath.push(new JsonPathNode.Array()); + currentJsonPath[++currentJsonPathIndex] = trieNode; + if (currentJsonPathIndex == currentJsonPath.length - 1) { + // resize + currentJsonPath = Arrays.copyOf(currentJsonPath, currentJsonPath.length*2); + } } } @@ -172,18 +164,18 @@ void expandCurrentJsonPathWithArray() { */ void backtrackCurrentJsonPath() { if (currentJsonPath != null) { - currentJsonPath.pop(); + currentJsonPath[currentJsonPathIndex--] = null; } } /** - * Returns the iterator over the JSONPath component references from head to tail + * Returns the TrieNode that references the end of the latest segment in the current jsonpath */ - Iterator getCurrentJsonPath() { - if (currentJsonPath != null) { - return currentJsonPath.descendingIterator(); + public KeyMatcher.TrieNode getCurrentJsonPathNode() { + if (currentJsonPath != null && currentJsonPathIndex != -1) { + return currentJsonPath[currentJsonPathIndex]; } else { - return Collections.emptyIterator(); + return null; } } diff --git a/src/main/java/dev/blaauwendraad/masker/json/config/JsonMaskingConfig.java b/src/main/java/dev/blaauwendraad/masker/json/config/JsonMaskingConfig.java index da044c77..ea6bccb9 100644 --- a/src/main/java/dev/blaauwendraad/masker/json/config/JsonMaskingConfig.java +++ b/src/main/java/dev/blaauwendraad/masker/json/config/JsonMaskingConfig.java @@ -233,6 +233,9 @@ public Builder allowJsonPaths(Set jsonPaths) { if (targetKeyMode == TargetKeyMode.MASK) { throw new IllegalArgumentException("Cannot allow keys when in MASK mode"); } + if (jsonPaths.contains("$")) { + throw new IllegalArgumentException("Root node JSONPath is not allowed in ALLOW mode"); + } targetKeyMode = TargetKeyMode.ALLOW; for (String jsonPath : jsonPaths) { JsonPath parsed = JSON_PATH_PARSER.parse(jsonPath); diff --git a/src/test/java/dev/blaauwendraad/masker/json/KeyMatcherTest.java b/src/test/java/dev/blaauwendraad/masker/json/KeyMatcherTest.java index 88a6726c..efaa8c24 100644 --- a/src/test/java/dev/blaauwendraad/masker/json/KeyMatcherTest.java +++ b/src/test/java/dev/blaauwendraad/masker/json/KeyMatcherTest.java @@ -8,8 +8,6 @@ import org.junit.jupiter.api.Test; import java.nio.charset.StandardCharsets; -import java.util.Collections; -import java.util.List; import java.util.Locale; import java.util.Set; @@ -57,8 +55,8 @@ void shouldBeAbleToSearchByOffset() { {"maskMe": "secret"} """.strip().getBytes(StandardCharsets.UTF_8); - assertThat(keyMatcher.getMaskConfigIfMatched(bytes, 0, bytes.length, Collections.emptyIterator())).isNotNull(); - assertThat(keyMatcher.getMaskConfigIfMatched(bytesWithPadding, 2, bytes.length, Collections.emptyIterator())).isNotNull(); + assertThat(keyMatcher.getMaskConfigIfMatched(bytes, 0, bytes.length, null)).isNotNull(); + assertThat(keyMatcher.getMaskConfigIfMatched(bytesWithPadding, 2, bytes.length, null)).isNotNull(); } @Test @@ -112,28 +110,16 @@ void shouldMatchJsonPaths() { {"a":{"b":1,"c":2}} """; byte[] bytes = json.getBytes(StandardCharsets.UTF_8); - assertThat(keyMatcher.getMaskConfigIfMatched( - bytes, - 0, - 0, // skip regular key matching - List.of( - new JsonPathNode.Node(indexOf(bytes, 'a'), 1), - new JsonPathNode.Node(indexOf(bytes, 'b'), 1) - ).iterator() - ) - ) - .isNotNull(); - assertThat(keyMatcher.getMaskConfigIfMatched( - bytes, - 0, - 0, // skip regular key matching - List.of( - new JsonPathNode.Node(indexOf(bytes, 'a'), 1), - new JsonPathNode.Node(indexOf(bytes, 'c'), 1) - ).iterator() - ) - ) - .isNull(); + + KeyMatcher.TrieNode node = keyMatcher.getJsonPathRootNode(); + node = keyMatcher.traverseJsonPathSegment(bytes, node, indexOf(bytes, 'a'), 1); + node = keyMatcher.traverseJsonPathSegment(bytes, node, indexOf(bytes, 'b'), 1); + assertThat(keyMatcher.getMaskConfigIfMatched(bytes, 0, 0, node)).isNotNull(); + + node = keyMatcher.getJsonPathRootNode(); + node = keyMatcher.traverseJsonPathSegment(bytes, node, indexOf(bytes, 'a'), 1); + node = keyMatcher.traverseJsonPathSegment(bytes, node, indexOf(bytes, 'c'), 1); + assertThat(keyMatcher.getMaskConfigIfMatched(bytes, 0, 0, node)).isNull(); } @Test @@ -163,42 +149,24 @@ void shouldMatchJsonPathArrays() { } """; byte[] bytes = json.getBytes(StandardCharsets.UTF_8); - assertThat(keyMatcher.getMaskConfigIfMatched( - bytes, - 0, - -1, // skip regular key matching - List.of( - new JsonPathNode.Node(indexOf(bytes, 'a'), 1), - new JsonPathNode.Array(), - new JsonPathNode.Node(indexOf(bytes, 'b'), 1) - ).iterator() - ) - ) - .isNotNull(); - assertThat(keyMatcher.getMaskConfigIfMatched( - bytes, - 0, - -1, // skip regular key matching - List.of( - new JsonPathNode.Node(indexOf(bytes, 'a'), 1), - new JsonPathNode.Array(), - new JsonPathNode.Node(indexOf(bytes, 'c'), 1) - ).iterator() - ) - ) - .isNotNull(); - assertThat(keyMatcher.getMaskConfigIfMatched( - bytes, - 0, - -1, // skip regular key matching - List.of( - new JsonPathNode.Node(indexOf(bytes, 'a'), 1), - new JsonPathNode.Array(), - new JsonPathNode.Node(indexOf(bytes, 'd'), 1) - ).iterator() - ) - ) - .isNull(); + + KeyMatcher.TrieNode node = keyMatcher.getJsonPathRootNode(); + node = keyMatcher.traverseJsonPathSegment(bytes, node, indexOf(bytes, 'a'), 1); + node = keyMatcher.traverseJsonPathSegment(bytes, node, -1, -1); + node = keyMatcher.traverseJsonPathSegment(bytes, node, indexOf(bytes, 'b'), 1); + assertThat(keyMatcher.getMaskConfigIfMatched(bytes, 0, -1, node)).isNotNull(); + + node = keyMatcher.getJsonPathRootNode(); + node = keyMatcher.traverseJsonPathSegment(bytes, node, indexOf(bytes, 'a'), 1); + node = keyMatcher.traverseJsonPathSegment(bytes, node, -1, -1); + node = keyMatcher.traverseJsonPathSegment(bytes, node, indexOf(bytes, 'c'), 1); + assertThat(keyMatcher.getMaskConfigIfMatched(bytes, 0, -1, node)).isNotNull(); + + node = keyMatcher.getJsonPathRootNode(); + node = keyMatcher.traverseJsonPathSegment(bytes, node, indexOf(bytes, 'a'), 1); + node = keyMatcher.traverseJsonPathSegment(bytes, node, -1, -1); + node = keyMatcher.traverseJsonPathSegment(bytes, node, indexOf(bytes, 'd'), 1); + assertThat(keyMatcher.getMaskConfigIfMatched(bytes, 0, -1, node)).isNull(); } @Test @@ -215,23 +183,14 @@ void shouldNotMatchJsonPathPrefix() { {"maskMe":"secret"} """; byte[] bytes = json.getBytes(StandardCharsets.UTF_8); - assertThat(keyMatcher.getMaskConfigIfMatched( - bytes, - 0, - -1, // skip regular key matching - List.of(new JsonPathNode.Node(2, 4)).iterator() // $.mask - ) - ) - .isNull(); - - assertThat(keyMatcher.getMaskConfigIfMatched( - bytes, - 0, - -1, // skip regular key matching - List.of(new JsonPathNode.Node(2, 6)).iterator() // $.maskMe - ) - ) - .isNotNull(); + + KeyMatcher.TrieNode node = keyMatcher.getJsonPathRootNode(); + node = keyMatcher.traverseJsonPathSegment(bytes, node, 2, 4); + assertThat(keyMatcher.getMaskConfigIfMatched(bytes, 0, -1, node)).isNull(); + + node = keyMatcher.getJsonPathRootNode(); + node = keyMatcher.traverseJsonPathSegment(bytes, node, 2, 6); + assertThat(keyMatcher.getMaskConfigIfMatched(bytes, 0, -1, node)).isNotNull(); } @Test @@ -246,34 +205,22 @@ void shouldReturnMaskingConfigForJsonPathInAllowMode() { {"allowMe":"value","maskMe":"secret","maskMeLikeCIA":"secret"} """; byte[] bytes = json.getBytes(StandardCharsets.UTF_8); - assertThat(keyMatcher.getMaskConfigIfMatched( - bytes, - 0, - -1, // skip regular key matching - List.of(new JsonPathNode.Node(2, 7)).iterator() // $.allowMe - ) - ) - .isNull(); - - assertThat(keyMatcher.getMaskConfigIfMatched( - bytes, - 0, - -1, // skip regular key matching - List.of(new JsonPathNode.Node(20, 6)).iterator() // $.maskMe - ) - ) + + KeyMatcher.TrieNode node = keyMatcher.getJsonPathRootNode(); + node = keyMatcher.traverseJsonPathSegment(bytes, node, 2, 7); + assertThat(keyMatcher.getMaskConfigIfMatched(bytes, 0, -1, node)).isNull(); + + node = keyMatcher.getJsonPathRootNode(); + node = keyMatcher.traverseJsonPathSegment(bytes, node, 20, 6); + assertThat(keyMatcher.getMaskConfigIfMatched(bytes, 0, -1, node)) .isNotNull() .extracting(KeyMaskingConfig::getStringValueMasker) .extracting(masker -> ByteValueMaskerContext.maskStringWith("value", masker)) .isEqualTo("\"***\""); - assertThat(keyMatcher.getMaskConfigIfMatched( - bytes, - 0, - -1, // skip regular key matching - List.of(new JsonPathNode.Node(38, 13)).iterator() // $.maskMeLikeCIA - ) - ) + node = keyMatcher.getJsonPathRootNode(); + node = keyMatcher.traverseJsonPathSegment(bytes, node, 38, 13); + assertThat(keyMatcher.getMaskConfigIfMatched(bytes, 0, -1, node)) .isNotNull() .extracting(KeyMaskingConfig::getStringValueMasker) .extracting(masker -> ByteValueMaskerContext.maskStringWith("value", masker)) @@ -282,7 +229,7 @@ void shouldReturnMaskingConfigForJsonPathInAllowMode() { private ObjectAssert assertThatConfig(KeyMatcher keyMatcher, String key) { byte[] bytes = key.getBytes(StandardCharsets.UTF_8); - return Assertions.assertThat(keyMatcher.getMaskConfigIfMatched(bytes, 0, bytes.length, Collections.emptyIterator())); + return Assertions.assertThat(keyMatcher.getMaskConfigIfMatched(bytes, 0, bytes.length, null)); } // utility to find specific char in the array, must not be duplicated diff --git a/src/test/java/dev/blaauwendraad/masker/json/MaskingStateTest.java b/src/test/java/dev/blaauwendraad/masker/json/MaskingStateTest.java index 9b99be85..8957891d 100644 --- a/src/test/java/dev/blaauwendraad/masker/json/MaskingStateTest.java +++ b/src/test/java/dev/blaauwendraad/masker/json/MaskingStateTest.java @@ -41,4 +41,19 @@ void shouldReturnStringRepresentationForDebugging() { > """.stripTrailing()); } + + @Test + void jsonPathExceedsCapacity() { + MaskingState maskingState = new MaskingState("[]".getBytes(StandardCharsets.UTF_8), true); + for (int i = 0; i < 101; i++) { + maskingState.expandCurrentJsonPath(new KeyMatcher.TrieNode()); + } + Assertions.assertThat(maskingState.getCurrentJsonPathNode()).isNotNull(); + } + + @Test + void getCurrentJsonPathNodeFromEmptyJsonPath() { + MaskingState maskingState = new MaskingState("[]".getBytes(StandardCharsets.UTF_8), true); + Assertions.assertThat(maskingState.getCurrentJsonPathNode()).isNull(); + } } \ No newline at end of file diff --git a/src/test/java/dev/blaauwendraad/masker/json/config/JsonMaskingConfigTest.java b/src/test/java/dev/blaauwendraad/masker/json/config/JsonMaskingConfigTest.java index 93ffd66f..249e895b 100644 --- a/src/test/java/dev/blaauwendraad/masker/json/config/JsonMaskingConfigTest.java +++ b/src/test/java/dev/blaauwendraad/masker/json/config/JsonMaskingConfigTest.java @@ -35,6 +35,7 @@ private static Stream> invalidBuilders() { () -> JsonMaskingConfig.builder().allowJsonPaths(Set.of("$.allowMe")).allowJsonPaths(Set.of("$.allowMe")), () -> JsonMaskingConfig.builder().allowJsonPaths(Set.of("$.allowMe")).maskKeys(Set.of("maskMe")), () -> JsonMaskingConfig.builder().allowJsonPaths(Set.of("$.allowMe")).maskJsonPaths(Set.of("$.maskMe")), + () -> JsonMaskingConfig.builder().allowJsonPaths(Set.of("$")), () -> JsonMaskingConfig.builder().caseSensitiveTargetKeys().caseSensitiveTargetKeys(), () -> JsonMaskingConfig.builder().maskStringsWith("***").maskStringsWith("***"), () -> JsonMaskingConfig.builder().maskStringsWith("***").maskStringCharactersWith("*"), diff --git a/src/test/resources/test-json-path.json b/src/test/resources/test-json-path.json index c7ae1e80..5ba16805 100644 --- a/src/test/resources/test-json-path.json +++ b/src/test/resources/test-json-path.json @@ -1393,31 +1393,6 @@ } ] }, - { - "maskingConfig": { - "allowJsonPaths": [ - "$" - ] - }, - "input": [ - { - "key": "do not mask" - }, - "do not mask", - { - "key": "do not mask" - } - ], - "expectedOutput": [ - { - "key": "do not mask" - }, - "do not mask", - { - "key": "do not mask" - } - ] - }, { "maskingConfig": { "maskJsonPaths": [