Allow custom masking config without defining allowed keys#319
Allow custom masking config without defining allowed keys#319andrebrait wants to merge 1 commit into
Conversation
|
Note These results are affected by shared workloads on GitHub runners. Use the results only to detect possible regressions, but always rerun on a more stable machine before drawing conclusions! Benchmark resultsBaselineBenchmark
Full results — BaselineBenchmark
InstanceCreationBenchmarkNo significant changes (all within 3.0%). Full results — InstanceCreationBenchmark
JsonMaskerBenchmark
Full results — JsonMaskerBenchmark
LargeKeySetInstanceCreationBenchmark
Full results — LargeKeySetInstanceCreationBenchmark
StreamTypeBenchmark
Full results — StreamTypeBenchmark
ValueMaskerBenchmark
Full results — ValueMaskerBenchmark
Raw output (PR @ 4514245)Raw output (master @ 550a7d4) |
|
I'll take a look and fix it. Weirdly enough, it all passed locally. |
| private static final JsonPathParser JSON_PATH_PARSER = new JsonPathParser(); | ||
|
|
||
| private final Set<String> targetKeys = new HashSet<>(); | ||
| private final Set<String> allowedKeys = new HashSet<>(); |
There was a problem hiding this comment.
@andrebrait I don't think this can be called allowedKeys it is only allowed in allow mode, they are target keys and have a TargetKeyMode
There was a problem hiding this comment.
Probably an accidental rename. I'll fix it.
There was a problem hiding this comment.
Pull request overview
This PR addresses issue #317 where JSONPath-specific masking configs were ignored in ALLOW mode when no allowed JSONPaths were configured, enabling “mask everything by default, but apply specific configs to selected keys/paths”.
Changes:
- Add coverage for ALLOW mode with empty
allowJsonPaths()while still applying key/JSONPath-specific configs. - Store JSONPath-specific masking configs separately from key configs and wire them into matcher initialization.
- Minor refactors in JSONPath parsing and ambiguity checking (including making
JsonPathcomparable).
Reviewed changes
Copilot reviewed 6 out of 6 changed files in this pull request and generated 5 comments.
Show a summary per file
| File | Description |
|---|---|
| src/test/java/dev/blaauwendraad/masker/json/CustomKeyMaskingConfigTest.java | Adds a regression test for ALLOW mode with empty allowed JSONPaths while using specific configs. |
| src/main/java/dev/blaauwendraad/masker/json/path/JsonPathParser.java | Refactors segment parsing and simplifies ambiguity sorting via Comparable. |
| src/main/java/dev/blaauwendraad/masker/json/path/JsonPath.java | Implements Comparable<JsonPath> to support natural sorting. |
| src/main/java/dev/blaauwendraad/masker/json/config/JsonMaskingConfig.java | Introduces separate JSONPath config storage and exposes JSONPath config accessors. |
| src/main/java/dev/blaauwendraad/masker/json/KeyMatcher.java | Inserts JSONPath config keys into the trie and resolves configs from either key or JSONPath config maps. |
| src/main/java/dev/blaauwendraad/masker/json/KeyContainsMasker.java | Ensures JSONPath tracking is enabled when JSONPath configs exist even if allow-list JSONPaths are empty. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| targetJsonPaths.add(parsed); | ||
| } | ||
| if (config != null) { | ||
| targetKeyConfigs.put(parsed.toString(), config); | ||
| targetJsonPathConfigs.put(parsed, config); | ||
| } |
There was a problem hiding this comment.
addMaskJsonPath now stores configs in targetJsonPathConfigs (instead of targetKeyConfigs), but the duplicate detection logic above still checks targetKeyConfigs.containsKey(parsed.toString()). In ALLOW mode (where the path isn’t added to targetJsonPaths), adding the same JSONPath config twice will no longer be rejected and will silently overwrite. Please update the duplicate check to consult targetJsonPathConfigs for this case.
| if (symbol == '.' || (symbol == '[' && !segment.isEmpty())) { | ||
| segments.add(segment.toString()); | ||
| segment = new StringBuilder(); | ||
| segment.setLength(0); |
There was a problem hiding this comment.
parseSegments uses segment.isEmpty() on a StringBuilder. This method is not available on JDK 11 (the library’s minimum runtime), so this can compile against a newer JDK but fail at runtime with NoSuchMethodError on Java 11. Use segment.length() != 0 (or segment.length() > 0) instead.
| if (!segment.isEmpty() || literal.endsWith("[]")) { | ||
| segments.add(segment.toString()); |
There was a problem hiding this comment.
Same JDK 11 compatibility issue here: StringBuilder#isEmpty() is not available on Java 11. Please replace with a segment.length() check.
| * Returns the config for the given JSON path. If no specific config is available for the given path, returns {@code null}. | ||
| * | ||
| * @param path the JSON path to be masked | ||
| * @return the config for the given key |
There was a problem hiding this comment.
Javadoc mismatch: getJsonPathConfig documents @return the config for the given key, but the method is for a JSON path. Please update the return description to refer to the JSON path to avoid confusion in generated docs.
| * @return the config for the given key | |
| * @return the config for the given JSON path |
| public Builder maskWith(KeyMaskingConfig maskingConfig) { | ||
| defaultConfigBuilder.maskStringsWith(maskingConfig.getStringValueMasker()) | ||
| .maskBooleansWith(maskingConfig.getBooleanValueMasker()) | ||
| .maskNumbersWith(maskingConfig.getNumberValueMasker()); | ||
| return this; | ||
| } |
There was a problem hiding this comment.
maskWith should validate maskingConfig similarly to the other builder methods (e.g., Objects.requireNonNull(maskingConfig)), so callers get a clear exception at the API boundary instead of an indirect NPE from get*ValueMasker().
Fixes #317