You are viewing a plain text version of this content. The canonical link for it is here.
Posted to oak-commits@jackrabbit.apache.org by re...@apache.org on 2024/10/10 09:36:00 UTC

(jackrabbit-oak) branch trunk updated: OAK-11181: SystemPropertySupplier: add feature to avoid logging of values (for instance, passwords) (#1777)

This is an automated email from the ASF dual-hosted git repository.

reschke pushed a commit to branch trunk
in repository https://gitbox.apache.org/repos/asf/jackrabbit-oak.git


The following commit(s) were added to refs/heads/trunk by this push:
     new d5e276dc2b OAK-11181: SystemPropertySupplier: add feature to avoid logging of values (for instance, passwords) (#1777)
d5e276dc2b is described below

commit d5e276dc2bf97296a4df52941ab96c6a9cbc746f
Author: Julian Reschke <re...@apache.org>
AuthorDate: Thu Oct 10 11:35:56 2024 +0200

    OAK-11181: SystemPropertySupplier: add feature to avoid logging of values (for instance, passwords) (#1777)
---
 .../commons/properties/SystemPropertySupplier.java | 35 +++++++++++++++-------
 .../oak/commons/properties/package-info.java       |  2 +-
 .../properties/SystemPropertySupplierTest.java     | 19 ++++++++++++
 3 files changed, 44 insertions(+), 12 deletions(-)

diff --git a/oak-commons/src/main/java/org/apache/jackrabbit/oak/commons/properties/SystemPropertySupplier.java b/oak-commons/src/main/java/org/apache/jackrabbit/oak/commons/properties/SystemPropertySupplier.java
index 30ad2c5961..de714ae0c2 100644
--- a/oak-commons/src/main/java/org/apache/jackrabbit/oak/commons/properties/SystemPropertySupplier.java
+++ b/oak-commons/src/main/java/org/apache/jackrabbit/oak/commons/properties/SystemPropertySupplier.java
@@ -50,11 +50,12 @@ public class SystemPropertySupplier<T> implements Supplier<T> {
 
     private Logger log = LOG;
     private String successLogLevel = "INFO";
+    private boolean hideValue = false;
+    private String hiddenReplacement = "*****";
     private Predicate<T> validator = (a) -> true;
     private Function<String, String> sysPropReader = System::getProperty;
-    private BiFunction<String, T, String> setMessageFormatter = (a, b) -> {
-        return String.format("System property %s found to be '%s'", a, b);
-    };
+    private BiFunction<String, T, String> setMessageFormatter = (a, b) -> String.format("System property %s found to be '%s'", a,
+            hideValue ? hiddenReplacement : b);
 
     private SystemPropertySupplier(@NotNull String propName, @NotNull T defaultValue) throws IllegalArgumentException {
         this.propName = Objects.requireNonNull(propName, "propertyName must be non-null");
@@ -115,6 +116,17 @@ public class SystemPropertySupplier<T> implements Supplier<T> {
         return this;
     }
 
+    /**
+     * Used to hide property value in log messages (for instance, for passwords)
+     * <p>
+     * <em>Note:</em> will have no effect when custom message formatter is used
+     * (see {@link #setMessageFormatter}).
+     */
+    public SystemPropertySupplier<T> hideValue() {
+        this.hideValue = true;
+        return this;
+    }
+
     /**
      * <em>For unit testing</em>: specify a function to read system properties
      * (overriding default of {@code System.getProperty(String}).
@@ -132,26 +144,27 @@ public class SystemPropertySupplier<T> implements Supplier<T> {
      */
     public T get() {
 
-        T ret = defaultValue;
+        T returnValue = defaultValue;
 
         String value = sysPropReader.apply(propName);
         if (value == null) {
             log.trace("System property {} not set", propName);
         } else {
-            log.trace("System property {} set to '{}'", propName, value);
+            String displayedValue = hideValue ? hiddenReplacement : value;
+            log.trace("System property {} set to '{}'", propName, displayedValue);
             try {
                 T v = parser.apply(value);
                 if (!validator.test(v)) {
-                    log.error("Ignoring invalid value '{}' for system property {}", value, propName);
+                    log.error("Ignoring invalid value '{}' for system property {}", displayedValue, propName);
                 } else {
-                    ret = v;
+                    returnValue = v;
                 }
             } catch (NumberFormatException ex) {
-                log.error("Ignoring malformed value '{}' for system property {}", value, propName);
+                log.error("Ignoring malformed value '{}' for system property {}", displayedValue, propName);
             }
 
-            if (!ret.equals(defaultValue)) {
-                String msg = setMessageFormatter.apply(propName, ret);
+            if (!returnValue.equals(defaultValue)) {
+                String msg = setMessageFormatter.apply(propName, returnValue);
                 switch (successLogLevel) {
                     case "INFO":
                         log.info(msg);
@@ -174,7 +187,7 @@ public class SystemPropertySupplier<T> implements Supplier<T> {
             }
         }
 
-        return ret;
+        return returnValue;
     }
 
     @SuppressWarnings("unchecked")
diff --git a/oak-commons/src/main/java/org/apache/jackrabbit/oak/commons/properties/package-info.java b/oak-commons/src/main/java/org/apache/jackrabbit/oak/commons/properties/package-info.java
index 9d8b109772..474329ac53 100644
--- a/oak-commons/src/main/java/org/apache/jackrabbit/oak/commons/properties/package-info.java
+++ b/oak-commons/src/main/java/org/apache/jackrabbit/oak/commons/properties/package-info.java
@@ -18,7 +18,7 @@
  * <em>For Oak internal use only. Do not use outside Oak components.</em>
  */
 @Internal(since = "1.1.0")
-@Version("2.0.0")
+@Version("2.1.0")
 package org.apache.jackrabbit.oak.commons.properties;
 
 import org.apache.jackrabbit.oak.commons.annotations.Internal;
diff --git a/oak-commons/src/test/java/org/apache/jackrabbit/oak/commons/properties/SystemPropertySupplierTest.java b/oak-commons/src/test/java/org/apache/jackrabbit/oak/commons/properties/SystemPropertySupplierTest.java
index 762185ffef..69ed32d9d4 100755
--- a/oak-commons/src/test/java/org/apache/jackrabbit/oak/commons/properties/SystemPropertySupplierTest.java
+++ b/oak-commons/src/test/java/org/apache/jackrabbit/oak/commons/properties/SystemPropertySupplierTest.java
@@ -17,6 +17,7 @@
 package org.apache.jackrabbit.oak.commons.properties;
 
 import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
 
 import org.apache.jackrabbit.oak.commons.junit.LogCustomizer;
 import org.junit.Test;
@@ -78,6 +79,24 @@ public class SystemPropertySupplierTest {
         }
     }
 
+    @Test
+    public void testHidden() {
+        String secret = "secret123";
+        LogCustomizer logCustomizer = LogCustomizer.forLogger(SystemPropertySupplierTest.class.getName()).enable(Level.TRACE)
+                .contains(secret).create();
+        logCustomizer.starting();
+
+        try {
+            String password = SystemPropertySupplier.create("password", "").hideValue().loggingTo(LOG)
+                    .usingSystemPropertyReader((n) -> secret).get();
+            assertEquals(secret, password);
+            assertTrue("Log message should not contain secret password, but found: " + logCustomizer.getLogs(),
+                    logCustomizer.getLogs().size() == 0);
+        } finally {
+            logCustomizer.finished();
+        }
+    }
+
     @Test
     public void testNonParseable() {
         LogCustomizer logCustomizer = LogCustomizer.forLogger(SystemPropertySupplierTest.class.getName()).enable(Level.ERROR)