Skip to content

Commit

Permalink
Added MaskingPatternLayout
Browse files Browse the repository at this point in the history
  • Loading branch information
gmsdelmundo committed Sep 27, 2023
1 parent 4a41303 commit 8d6e982
Show file tree
Hide file tree
Showing 3 changed files with 105 additions and 0 deletions.
5 changes: 5 additions & 0 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,11 @@
<artifactId>micrometer-registry-prometheus</artifactId>
<version>${micrometer.version}</version>
</dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<version>1.3.5</version>
</dependency>
<dependency>
<groupId>com.github.ben-manes.caffeine</groupId>
<artifactId>caffeine</artifactId>
Expand Down
31 changes: 31 additions & 0 deletions src/main/java/com/uid2/shared/util/MaskingPatternLayout.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
package com.uid2.shared.util;

import ch.qos.logback.classic.PatternLayout;
import ch.qos.logback.classic.spi.ILoggingEvent;

import java.util.Map;

public class MaskingPatternLayout extends PatternLayout {
private static final Map<String, String> MASKING_PATTERNS = Map.of(
"[^\\s]+s3\\.amazonaws\\.com\\/.*X-Amz-Security-Token=[^\\s]+", "REDACTED - S3"
);

@Override
public String doLayout(ILoggingEvent event) {
return mask(super.doLayout(event));
}

private String mask(String message) {
if (message == null) {
return null;
}

String maskedMessage = message;
for (Map.Entry<String, String> entry : MASKING_PATTERNS.entrySet()) {
String regex = entry.getKey();
String mask = entry.getValue();
maskedMessage = maskedMessage.replaceAll(regex, mask);
}
return maskedMessage;
}
}
69 changes: 69 additions & 0 deletions src/test/java/com/uid2/shared/util/MaskingPatternLayoutTest.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
package com.uid2.shared.util;

import ch.qos.logback.classic.Level;
import ch.qos.logback.classic.Logger;
import ch.qos.logback.classic.LoggerContext;
import ch.qos.logback.classic.spi.ILoggingEvent;
import ch.qos.logback.classic.spi.LoggingEvent;
import ch.qos.logback.core.pattern.FormattingConverter;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.extension.ExtendWith;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.Arguments;
import org.junit.jupiter.params.provider.MethodSource;
import org.mockito.junit.jupiter.MockitoExtension;
import org.slf4j.LoggerFactory;

import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;

import static org.junit.jupiter.api.Assertions.assertAll;
import static org.junit.jupiter.api.Assertions.assertEquals;

@ExtendWith(MockitoExtension.class)
public class MaskingPatternLayoutTest {
private static final Logger LOGGER = (Logger) LoggerFactory.getLogger(MaskingPatternLayoutTest.class);
private static final MaskingPatternLayout MASKING_PATTERN_LAYOUT = new MaskingPatternLayout();

@BeforeAll
public static void setupAll() {
LoggerContext loggerContext = LOGGER.getLoggerContext();
MASKING_PATTERN_LAYOUT.setPattern("%msg %ex");
MASKING_PATTERN_LAYOUT.setContext(loggerContext);
MASKING_PATTERN_LAYOUT.start();
}

@ParameterizedTest
@MethodSource("maskedMessagesWithS3")
public void testMaskedMessagesWithS3(String message, String maskedMessage) {
String log = MASKING_PATTERN_LAYOUT.doLayout(getLoggingEvent(message));

assertAll(
"testMaskingMessageWithS3",
() -> assertEquals(maskedMessage, log.trim())
);
}

private static Set<Arguments> maskedMessagesWithS3() {
String urlWithoutProtocol = "myservice.s3.amazonaws.com/some/path?param1=value1&X-Amz-Security-Token=mysecurityToken&param3=value3";
Map<String, String> maskedMessages = Map.of(
"Error: " + urlWithoutProtocol + " and something else", "Error: REDACTED - S3 and something else",
"https://" + urlWithoutProtocol, "REDACTED - S3",
"http://" + urlWithoutProtocol, "REDACTED - S3",
urlWithoutProtocol, "REDACTED - S3"
);

return maskedMessages.entrySet().stream()
.map(entry -> Arguments.of(entry.getKey(), entry.getValue()))
.collect(Collectors.toSet());
}

private static ILoggingEvent getLoggingEvent(String msg, Exception ex) {
return new LoggingEvent(FormattingConverter.class.getName(), LOGGER, Level.ERROR, msg, ex, null);
}

private static ILoggingEvent getLoggingEvent(String msg) {
return getLoggingEvent(msg, null);
}
}

0 comments on commit 8d6e982

Please sign in to comment.