json-masker

Template repo to speed up creating new library projects

License

License

Categories

Categories

JSON Data
GroupId

GroupId

com.github.michaelruocco
ArtifactId

ArtifactId

json-masker
Last Version

Last Version

1.0.7
Release Date

Release Date

Type

Type

jar
Description

Description

json-masker
Template repo to speed up creating new library projects
Project URL

Project URL

https://github.com/michaelruocco/json-masker
Source Code Management

Source Code Management

https://github.com/michaelruocco/json-masker

Download json-masker

How to add to project

<!-- https://jarcasting.com/artifacts/com.github.michaelruocco/json-masker/ -->
<dependency>
    <groupId>com.github.michaelruocco</groupId>
    <artifactId>json-masker</artifactId>
    <version>1.0.7</version>
</dependency>
// https://jarcasting.com/artifacts/com.github.michaelruocco/json-masker/
implementation 'com.github.michaelruocco:json-masker:1.0.7'
// https://jarcasting.com/artifacts/com.github.michaelruocco/json-masker/
implementation ("com.github.michaelruocco:json-masker:1.0.7")
'com.github.michaelruocco:json-masker:jar:1.0.7'
<dependency org="com.github.michaelruocco" name="json-masker" rev="1.0.7">
  <artifact name="json-masker" type="jar" />
</dependency>
@Grapes(
@Grab(group='com.github.michaelruocco', module='json-masker', version='1.0.7')
)
libraryDependencies += "com.github.michaelruocco" % "json-masker" % "1.0.7"
[com.github.michaelruocco/json-masker "1.0.7"]

Dependencies

runtime (6)

Group / Artifact Type Version
org.slf4j : slf4j-api jar 1.7.30
com.fasterxml.jackson.core : jackson-core jar 2.12.2
com.fasterxml.jackson.core : jackson-databind jar 2.12.2
com.jayway.jsonpath : json-path jar 2.5.0
org.apache.commons : commons-lang3 jar 3.12.0
com.github.michaelruocco : string-utils jar 0.1.5

Project Modules

There are no modules declared in this project.

JSON Masker

Build codecov Codacy Badge BCH compliance Quality Gate Status Technical Debt Coverage Lines of Code Maven Central License: MIT

Overview

This library allows the masking of specific values within a JSON payload by specifying JSON path configurations

It uses a combination of Jackson and JsonPath to achieve this. Hopefully the tests, particularly the integration tests, give some examples of how the library should be used, but some additional explanation is below.

Setup

The first step is to create an instance of the JsonMasker, in order to do this 4 other instances are required:

  • An instance of a Jackson ObjectMapper

  • A Collection of JsonPath objects, these paths should point to the values in your JSON payload that you want to mask

  • An instance of a class implementing the MapFunction interface from the JsonPath library, this is class is responsible for applying a transformation to any JSON fields that match the collection of JsonPath objects that you provide. There is a default implementation of this class that is used if you do not provide one which is called MaskFunction this will simply mask the entire value using asterisks.

  • An instance of the Configuration class that also comes from the JsonPath library, this provides configuration options that JsonPath uses when parsing your json payload. There is a default set of options provided if you do not provide one specifically which is created by the JsonPathConfig factory class. By default it will use Jackson as the JSON provider and will suppress any exceptions, so as an example the masker will not error if the JsonPath you have provided does not find a match in the input JSON payload. Of course because this can be passed in you can set up any different configuration options you wish to.

As an example, if you wanted to use the default MapFunction and Configuration classes described above, you can set up an instance of the JsonMasker as follows:

ObjectMapper mapper = new ObjectMapper();
Collection<String> paths = Arrays.asList("$.myField1", "$.myField3");
JsonMasker myMasker = JsonMasker.builder()
    .mapper(mapper)
    .paths(JsonPathFactory.toJsonPaths(paths))
    .build();

This example just passes a simple new instance of ObjectMapper with no customizations, you can set it up however you need to before passing in to the masker if required. You can set up your paths as a simple Collection of Strings and then use the JsonPathFactory to convert those into the JsonPath objects that are required, or you can build them yourself if you prefer.

Performing Masking

Once you have an instance of the masker set up as above, all you need to do is call the apply method passing in the json payload you want to mask. e.g.

String payload = "{\"myField1\":\"mask me\"}";
String maskedPayload = myMasker.apply(payload);

JsonMasker implements the UnaryOperator interface which means you can use it when processing java Streams if required. The example above is configured to mask two fields in a JSON payload named myField1 and myField3. If the masker were to be passed the following json payload:

{
  "myField1": "mask me",
  "myField2": "another value",
  "myField3": 123
}

Then it would return the following:

{
  "myField1": "*******",
  "myField2": "another value",
  "myField3": "***"
}

So it will replace all characters with an asterisk. It is worth noting that it has turned the last numeric field into a string to ensure that it still returns valid JSON.

Customising

As mentioned above it is possible to provide your own MapFunction, so you can customize the way the fields are masked, or if you wish, apply some completely different type of transformation on the values. The MapFunction itself requires another lower level object called an ObjectMasker which in turn requires an instance of the UnaryOperator interface, this is what actually does the work of applying the masking / transform to each value. There are currently three implementations available by default:

  • StringMasker, which performs the simple replacement of all chars with an asterisk as shown above, this is what you get by default if you don't provide one specifically

  • IgnoreLastNCharsMasker, this is the same as above except will ignore the last N characters, if you provide 3 as the lastN value it would take the string "my-value" and return "*****lue"

  • IgnoreFirstNAndLastNCharsMasker, as the name suggests this is similar to IgnoreLastNCharsMasker except it also ignores the first N chars too, so if you provide 2 as the firstN value and 3 as the lastN value it would take the string "my-value" and return "my***lue"

As these are all implementing an interface, you are free to provide a custom implementation if you wish to. As a very simple example, lets say you wanted to mask your string but leave the last 3 characters in the clear, and you wanted to use a hyphen instead of an asterisk as the mask character, you could set your object mapper up like this:

ObjectMapper mapper = new ObjectMapper();
Collection<String> paths = Arrays.asList("$.myField1", "$.myField3");
return JsonMasker.builder()
        .maskFunction(new MaskFunction(new ObjectMasker(new IgnoreLastNCharsMasker(3, '-'))))
        .paths(JsonPathFactory.toJsonPaths(paths))
        .mapper(MAPPER);

As this is just a noddy example I have just created instances of each class directly, if you have commonly used classes then you can extend any of these classes and customise them as you wish, if you write something you find particularly useful you could even consider contributing it back to into this library but again that is up to you.

Useful Commands

// cleans build directories
// prints currentVersion
// formats code
// builds code
// runs tests
// runs integration tests
// checks for gradle issues
// checks dependency versions
./gradlew clean currentVersion dependencyUpdates spotlessApply lintGradle build integrationTest

Versions

Version
1.0.7
1.0.6
1.0.5
1.0.4
1.0.3
1.0.2
1.0.1
1.0.0
0.1.7
0.1.4
0.1.2
0.1.0