Skip to content

Commit

Permalink
upgrade spring version and added logging obfuscator configuration for…
Browse files Browse the repository at this point in the history
… sensitive field values
  • Loading branch information
Jonathan Henrique Medeiros committed Nov 22, 2024
1 parent 4d26d28 commit 3f29c8e
Show file tree
Hide file tree
Showing 8 changed files with 115 additions and 11 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ Esta arquitetura consiste em diminuir a concorrência entre transações da API
</br>

[![node](https://img.shields.io/badge/Azul_Zulu_OpenJDK-21-red.svg)](https://www.azul.com/downloads/?package=jdk#zulu)
[![node](https://img.shields.io/badge/Spring_Boot-3.3.0-green.svg)](https://spring.io/)
[![node](https://img.shields.io/badge/Spring_Boot-3.4.0-green.svg)](https://spring.io/)
[![node](https://img.shields.io/badge/MySQL-8.0.28-blue.svg)](https://www.mysql.com/)


Expand Down
10 changes: 5 additions & 5 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>3.3.3</version>
<version>3.4.0</version>
<relativePath/>
</parent>

Expand Down Expand Up @@ -106,6 +106,10 @@
<artifactId>springdoc-openapi-starter-webmvc-ui</artifactId>
<version>${springdoc-openapi-starter-webmvc-ui.version}</version>
</dependency>
<dependency>
<groupId>io.opentelemetry</groupId>
<artifactId>opentelemetry-api</artifactId>
</dependency>
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
Expand All @@ -116,10 +120,6 @@
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>io.opentelemetry</groupId>
<artifactId>opentelemetry-api</artifactId>
</dependency>
</dependencies>

<build>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
package br.com.multidatasources.config.logging;

import ch.qos.logback.classic.spi.ILoggingEvent;
import ch.qos.logback.core.pattern.CompositeConverter;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class ObfuscateLoggingConverter extends CompositeConverter<ILoggingEvent> {

private static final Map<String, Pattern> sensitiveFieldPatterns = new HashMap<>();
private static final int GROUP_FIELD_IN_MESSAGE_INDEX = 1;
private static final int GROUP_FIELD_IN_JSON_INDEX = 2;

static {
final List<String> fieldNames = getAllSensitiveFieldNames();
for (final String fieldName : fieldNames) {
final String regex = "(?i)\\b" + Pattern.quote(fieldName) + "\\b\\s*[:=]\\s*\"?([^\",\\s]*)\"?|\"" + Pattern.quote(fieldName) + "\":\"([^\"]*)\"";
sensitiveFieldPatterns.put(fieldName, Pattern.compile(regex));
}
}

@Override
protected String transform(final ILoggingEvent event, final String in) {
String message = in;
for (Map.Entry<String, Pattern> entry : sensitiveFieldPatterns.entrySet()) {
message = obfuscateFieldValue(message, entry.getValue());
}
message = obfuscateArguments(event.getArgumentArray(), message);
message = obfuscateMDC(event.getMDCPropertyMap(), message);
return message.concat("\n");
}

private static String obfuscateFieldValue(final String message, final Pattern pattern) {
final Matcher matcher = pattern.matcher(message);
final StringBuilder sb = new StringBuilder();
while (matcher.find()) {
if (matcher.group(GROUP_FIELD_IN_MESSAGE_INDEX) != null) {
matcher.appendReplacement(sb, matcher.group().replace(matcher.group(GROUP_FIELD_IN_MESSAGE_INDEX), "****"));
}
if (matcher.group(GROUP_FIELD_IN_JSON_INDEX) != null) {
matcher.appendReplacement(sb, matcher.group().replace(matcher.group(GROUP_FIELD_IN_JSON_INDEX), "****"));
}
}
matcher.appendTail(sb);
return sb.toString();
}

private static String obfuscateArguments(final Object[] arguments, String message) {
if (arguments != null) {
for (final Object arg : arguments) {
if (arg != null) {
for (final Pattern pattern : sensitiveFieldPatterns.values()) {
message = obfuscateFieldValue(message, pattern);
}
}
}
}
return message;
}

private static String obfuscateMDC(final Map<String, String> mdcPropertyMap, String message) {
if (mdcPropertyMap != null) {
for (final Map.Entry<String, String> entry : mdcPropertyMap.entrySet()) {
if (sensitiveFieldPatterns.containsKey(entry.getKey())) {
message = obfuscateFieldValue(message, sensitiveFieldPatterns.get(entry.getKey()));
}
}
}
return message;
}

private static List<String> getAllSensitiveFieldNames() {
try (final InputStream inputStream = ObfuscateLoggingConverter.class.getResourceAsStream("/obfuscate")) {
if (inputStream == null) {
return Collections.emptyList();
}
return new BufferedReader(new InputStreamReader(inputStream)).lines()
.map(String::trim)
.toList();
} catch (final IOException ex) {
return Collections.emptyList();
}
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@
import br.com.multidatasources.service.v1.idempotency.IdempotencyGenerator;
import jakarta.persistence.EntityExistsException;
import jakarta.persistence.EntityNotFoundException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

Expand All @@ -14,6 +16,8 @@
@Transactional
public class BillionaireService {

private static final Logger log = LoggerFactory.getLogger(BillionaireService.class);

private final BillionaireRepository billionaireRepository;
private final IdempotencyGenerator idempotencyGenerator;

Expand All @@ -27,6 +31,7 @@ public BillionaireService(

@Transactional(readOnly = true)
public Billionaire findById(final Long id) {
log.info("Find billionaire by id: {}", id);
return billionaireRepository.findById(id)
.orElseThrow(() -> new EntityNotFoundException(String.format("Register with id %s not found", id)));
}
Expand Down
2 changes: 1 addition & 1 deletion src/main/resources/application.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ logging:
br.com.multidatasources: INFO
appender: CONSOLE
pattern:
console: "%d{yyyy-MM-dd HH:mm:ss.SSS} %X{X-Request-ID} %highlight(%-5level) %magenta([%t]) %msg%n"
console: "%d{yyyy-MM-dd HH:mm:ss.SSS} %X{X-Request-ID} %highlight(%-5level) %magenta([%t]) %obfuscate(%msg)%n"

# DATABASE SCHEMA PROPERTIES
schema:
Expand Down
5 changes: 4 additions & 1 deletion src/main/resources/logback-spring.xml
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<conversionRule conversionWord="obfuscate" converterClass="br.com.multidatasources.config.logging.ObfuscateLoggingConverter" />

<include resource="org/springframework/boot/logging/logback/defaults.xml"/>

Expand All @@ -22,11 +23,13 @@
<version>[ignore]</version>
<levelValue>[ignore]</levelValue>
<timestamp>[ignore]</timestamp>
<message>[ignore]</message>
</fieldNames>
<provider class="net.logstash.logback.composite.loggingevent.LoggingEventPatternJsonProvider">
<pattern>
{
"timestamp_app": "%d{yyyy-MM-dd HH:mm:ss.SSS}"
"timestamp_app": "%d{yyyy-MM-dd HH:mm:ss.SSS}",
"message": "%obfuscate(%message)"
}
</pattern>
</provider>
Expand Down
2 changes: 2 additions & 0 deletions src/main/resources/obfuscate
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
billionaire_id
id
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.mock.mockito.SpyBean;
import org.springframework.test.context.bean.override.mockito.MockitoSpyBean;

import java.util.List;

Expand All @@ -23,11 +23,11 @@
@ExtendWith(DefaultBillionaireParameterResolverExtension.class)
class BillionaireServiceIntegrationTest {

@SpyBean
@MockitoSpyBean
private IdempotencyGenerator idempotencyGenerator;

@Autowired
@SpyBean
@MockitoSpyBean
private BillionaireRepository billionaireRepository;

@Autowired
Expand Down

0 comments on commit 3f29c8e

Please sign in to comment.