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)