Sat. Apr 20th, 2024

In today’s times, the software is always handling personal information. As developers, we have to fight the battle between logging and seeing that information when we need to, and hiding that information when we need to. In my case on my local developer box or on the QA system the information can be shown because it’s all fake. However, when we go to a production system we need to hide that information.

So I created the PiiInfo class. a class designed to be used for displaying the real information when needed and hiding it when it should be. Very simple class, you can call a static method to set a Boolean Supplier to be used that will tell the class when it should show (true) or hide (false) the information. By default when the information is hidden it will display [PII INFORMATION] instead of the real information. This can be changed by calling PiiInfo::setPiiLabel(). By default, PiiInfo is set up to hide information all of the time.

To set your own BooleanSupplier to be used call PiiInfo::setDecisionMaker() this will allow you to create your own decision-maker that can be based on the profile being used in spring, configuration setting, or another method of your choice to determine when to show the data.

package name.mymiller.io;

import java.util.function.BooleanSupplier;


/**
 * Class to use to protect Private Information. Takes a string and checks against a lambda to see
 * if the PII information should be displayed, otherwise display [PII INFORMATION] in its place.
 * Defaults to hide PII Information.
 */
public class PiiInfo {
    static Object syncObject = new Object();
    static String PII_LABEL = "[PII INFORMATION]";
    static BooleanSupplier booleanSupplier = () -> {return false;};

    /**
     * Static method to return a PiiInfo object set to display the correct text.
     * @param information String that is the PII information that might be displayed in certain conditions.
     * @return PiiInfo object to correctly display the information
     */
    static PiiInfo protect(String information) {
        if(booleanSupplier.getAsBoolean()) {
            return new PiiInfo(information);
        }
        return new PiiInfo(PiiInfo.PII_LABEL);
    }

    /**
     * Set the label to use for PII when hidden.
     * @param label String containing the new label to replace [PII INFORMATION]
     */
    public static void setPiiLabel(String label) {
        synchronized (syncObject) {
            PiiInfo.PII_LABEL = label;
        }
    }

    /**
     * Setup a BooleanSupplier that will check conditiions to determine if PII information maybe displayed.
     * Examples might to check if this is a Production environment and to hide all PII information and to
     * display in test, development environments.
     * @param booleanSupplier  returns TRUE to display the PII Information and FALSE to hide.
     */
    public static void setDecisionMaker(BooleanSupplier booleanSupplier) {
        synchronized (syncObject) {
            PiiInfo.booleanSupplier = booleanSupplier;
        }
    }

    /**
     * Local variable to contain the text to display, defaults to the PII Label.
     */
    private String display = PiiInfo.PII_LABEL;

    /**
     * Priviate Constructor to create the PiiINfo object
     * @param display Data to display.
     */
    private PiiInfo(String display) {
        this.display = display;
    }

    @Override
    public String toString() {
        return this.display;
    }
}

Using this is simply a change to your logging system.

log.debug("Email: {}",PiiInfo.protect(email));

By Jeffery Miller

I am known for being able to quickly decipher difficult problems to assist development teams in producing a solution. I have been called upon to be the Team Lead for multiple large-scale projects. I have a keen interest in learning new technologies, always ready for a new challenge.

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.