This is an automated email from the ASF dual-hosted git repository. reta pushed a commit to branch 4.0.x-fixes in repository https://gitbox.apache.org/repos/asf/cxf.git
commit bb711dd1773dcce423ffb802a2ed2b7a6a7097a4 Author: Andriy Redko <[email protected]> AuthorDate: Sat Apr 26 09:54:39 2025 -0400 CXF-8985: headers masking implementation not replaceable (in DefaultLogEventMapper) (#2376) (cherry picked from commit 1ea7df1fbc43f245dbe242e7b1137c68f847069b) --- .../ext/logging/AbstractLoggingInterceptor.java | 4 +- .../ext/logging/event/DefaultLogEventMapper.java | 14 ++- .../cxf/ext/logging/LoggingInInterceptorTest.java | 117 +++++++++++++++++++++ .../apache/cxf/ext/logging/TestEventSender.java | 38 +++++++ 4 files changed, 171 insertions(+), 2 deletions(-) diff --git a/rt/features/logging/src/main/java/org/apache/cxf/ext/logging/AbstractLoggingInterceptor.java b/rt/features/logging/src/main/java/org/apache/cxf/ext/logging/AbstractLoggingInterceptor.java index 956727c8eb..971335854c 100644 --- a/rt/features/logging/src/main/java/org/apache/cxf/ext/logging/AbstractLoggingInterceptor.java +++ b/rt/features/logging/src/main/java/org/apache/cxf/ext/logging/AbstractLoggingInterceptor.java @@ -50,7 +50,7 @@ public abstract class AbstractLoggingInterceptor extends AbstractPhaseIntercepto protected boolean logMultipart = true; protected LogEventSender sender; - protected final DefaultLogEventMapper eventMapper = new DefaultLogEventMapper(); + protected final DefaultLogEventMapper eventMapper; protected MaskSensitiveHelper maskSensitiveHelper = new MaskSensitiveHelper(); @@ -59,6 +59,7 @@ public abstract class AbstractLoggingInterceptor extends AbstractPhaseIntercepto public AbstractLoggingInterceptor(String phase, LogEventSender sender) { super(phase); this.sender = sender; + this.eventMapper = new DefaultLogEventMapper(maskSensitiveHelper); } protected static boolean isLoggingDisabledNow(Message message) throws Fault { @@ -105,6 +106,7 @@ public abstract class AbstractLoggingInterceptor extends AbstractPhaseIntercepto public void setSensitiveDataHelper(MaskSensitiveHelper helper) { this.maskSensitiveHelper = helper; + this.eventMapper.setSensitiveDataHelper(helper); } public void setPrettyLogging(boolean prettyLogging) { diff --git a/rt/features/logging/src/main/java/org/apache/cxf/ext/logging/event/DefaultLogEventMapper.java b/rt/features/logging/src/main/java/org/apache/cxf/ext/logging/event/DefaultLogEventMapper.java index 6140201fee..4e8ee740d3 100644 --- a/rt/features/logging/src/main/java/org/apache/cxf/ext/logging/event/DefaultLogEventMapper.java +++ b/rt/features/logging/src/main/java/org/apache/cxf/ext/logging/event/DefaultLogEventMapper.java @@ -65,7 +65,19 @@ public class DefaultLogEventMapper { private final Set<String> binaryContentMediaTypes = new HashSet<>(DEFAULT_BINARY_CONTENT_MEDIA_TYPES); - private MaskSensitiveHelper maskSensitiveHelper = new MaskSensitiveHelper(); + private MaskSensitiveHelper maskSensitiveHelper; + + public DefaultLogEventMapper() { + this(new MaskSensitiveHelper()); + } + + public DefaultLogEventMapper(final MaskSensitiveHelper helper) { + this.maskSensitiveHelper = helper; + } + + public void setSensitiveDataHelper(MaskSensitiveHelper helper) { + this.maskSensitiveHelper = helper; + } public void addBinaryContentMediaTypes(String mediaTypes) { if (mediaTypes != null) { diff --git a/rt/features/logging/src/test/java/org/apache/cxf/ext/logging/LoggingInInterceptorTest.java b/rt/features/logging/src/test/java/org/apache/cxf/ext/logging/LoggingInInterceptorTest.java new file mode 100644 index 0000000000..fda5b7bf04 --- /dev/null +++ b/rt/features/logging/src/test/java/org/apache/cxf/ext/logging/LoggingInInterceptorTest.java @@ -0,0 +1,117 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.apache.cxf.ext.logging; + +import java.util.Arrays; +import java.util.Collections; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Map; +import java.util.Set; + +import org.apache.cxf.ext.logging.event.LogEvent; +import org.apache.cxf.message.ExchangeImpl; +import org.apache.cxf.message.Message; +import org.apache.cxf.message.MessageImpl; + +import org.junit.Before; +import org.junit.Test; + +import static org.apache.cxf.ext.logging.event.DefaultLogEventMapper.MASKED_HEADER_VALUE; +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.hasSize; +import static org.junit.Assert.assertEquals; + +public class LoggingInInterceptorTest { + private static final String TEST_HEADER_VALUE = "TestValue"; + private static final String TEST_HEADER_NAME = "TestHeader"; + + private TestEventSender sender; + private LoggingInInterceptor interceptor; + private Message message; + + @Before + public void setUp() { + sender = new TestEventSender(); + interceptor = new LoggingInInterceptor(sender); + message = new MessageImpl(); + message.setExchange(new ExchangeImpl()); + } + + @Test + public void testRest() { + message.put(Message.HTTP_REQUEST_METHOD, "GET"); + message.put(Message.REQUEST_URI, "test"); + + interceptor.handleMessage(message); + + assertThat(sender.getEvents(), hasSize(1)); + LogEvent event = sender.getEvents().get(0); + + assertEquals("GET[test]", event.getOperationName()); + } + + @Test + public void shouldMaskHeaders() { + message.put(Message.ENDPOINT_ADDRESS, "http://localhost:9001/"); + message.put(Message.REQUEST_URI, "/api"); + + final Map<String, Object> headers = new HashMap<>(); + headers.put(TEST_HEADER_NAME, Arrays.asList(TEST_HEADER_VALUE)); + final Set<String> sensitiveHeaders = new HashSet<>(); + sensitiveHeaders.add(TEST_HEADER_NAME); + message.put(Message.PROTOCOL_HEADERS, headers); + + interceptor.setSensitiveProtocolHeaderNames(Collections.singleton(TEST_HEADER_NAME)); + interceptor.handleMessage(message); + + assertThat(sender.getEvents(), hasSize(1)); + LogEvent event = sender.getEvents().get(0); + + assertEquals(MASKED_HEADER_VALUE, event.getHeaders().get(TEST_HEADER_NAME)); + } + + @Test + public void shouldMaskUsingCustomMaskSensitiveHelper() { + message.put(Message.ENDPOINT_ADDRESS, "http://localhost:9001/"); + message.put(Message.REQUEST_URI, "/api"); + + final MaskSensitiveHelper helper = new MaskSensitiveHelper() { + public void maskHeaders(Map<String, String> headerMap, Set<String> sensitiveHeaderNames) { + // Do nothing + } + }; + + final Map<String, Object> headers = new HashMap<>(); + headers.put(TEST_HEADER_NAME, Arrays.asList(TEST_HEADER_VALUE)); + final Set<String> sensitiveHeaders = new HashSet<>(); + sensitiveHeaders.add(TEST_HEADER_NAME); + message.put(Message.PROTOCOL_HEADERS, headers); + + interceptor.setSensitiveDataHelper(helper); + interceptor.setSensitiveProtocolHeaderNames(Collections.singleton(TEST_HEADER_NAME)); + interceptor.handleMessage(message); + + assertThat(sender.getEvents(), hasSize(1)); + LogEvent event = sender.getEvents().get(0); + + assertEquals(TEST_HEADER_VALUE, event.getHeaders().get(TEST_HEADER_NAME)); + } +} diff --git a/rt/features/logging/src/test/java/org/apache/cxf/ext/logging/TestEventSender.java b/rt/features/logging/src/test/java/org/apache/cxf/ext/logging/TestEventSender.java new file mode 100644 index 0000000000..b204e84be7 --- /dev/null +++ b/rt/features/logging/src/test/java/org/apache/cxf/ext/logging/TestEventSender.java @@ -0,0 +1,38 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.cxf.ext.logging; + +import java.util.List; +import java.util.concurrent.CopyOnWriteArrayList; + +import org.apache.cxf.ext.logging.event.LogEvent; +import org.apache.cxf.ext.logging.event.LogEventSender; + +final class TestEventSender implements LogEventSender { + private final List<LogEvent> events = new CopyOnWriteArrayList<>(); + + @Override + public void send(LogEvent event) { + events.add(event); + } + + public List<LogEvent> getEvents() { + return events; + } +} \ No newline at end of file
