Encode JSON string in Pulsar auth params

The values in the `spring.pulsar.client.authentication.param`
config props map are not currently JSON encoded. For simple
values this is fine. However, some custom auth modules may
require more complex parameter values that may contain special
characters that results in invalid JSON. This commmit encodes
the parameter values using a very simple hand-rolled escape
function.

See gh-40493
This commit is contained in:
Chris Bono 2024-04-23 18:15:42 -05:00 committed by Moritz Halbritter
parent d340f87c22
commit 7a7bcd07da
2 changed files with 20 additions and 5 deletions

View File

@ -89,7 +89,7 @@ final class PulsarPropertiesMapper {
try {
return sortedParams.entrySet()
.stream()
.map((entry) -> "\"%s\":\"%s\"".formatted(entry.getKey(), entry.getValue()))
.map((entry) -> "\"%s\":\"%s\"".formatted(entry.getKey(), escapeJson(entry.getValue())))
.collect(Collectors.joining(",", "{", "}"));
}
catch (Exception ex) {
@ -97,6 +97,17 @@ final class PulsarPropertiesMapper {
}
}
private String escapeJson(String raw) {
return raw.replace("\\", "\\\\")
.replace("\"", "\\\"")
.replace("/", "\\/")
.replace("\b", "\\b")
.replace("\t", "\\t")
.replace("\n", "\\n")
.replace("\f", "\\f")
.replace("\r", "\\r");
}
<T> void customizeProducerBuilder(ProducerBuilder<T> producerBuilder) {
PulsarProperties.Producer properties = this.properties.getProducer();
PropertyMapper map = PropertyMapper.get().alwaysApplyingWhenNonNull();

View File

@ -72,8 +72,10 @@ class PulsarPropertiesMapperTests {
@Test
void customizeClientBuilderWhenHasAuthentication() throws UnsupportedAuthenticationException {
PulsarProperties properties = new PulsarProperties();
Map<String, String> params = Map.of("param", "name");
String authParamString = "{\"param\":\"name\"}";
Map<String, String> params = Map.of("simpleParam", "foo", "complexParam",
"{\n\t\"k1\" : \"v1\",\n\t\"k2\":\"v2\"\n}");
String authParamString = "{\"complexParam\":\"{\\n\\t\\\"k1\\\" : \\\"v1\\\",\\n\\t\\\"k2\\\":\\\"v2\\\"\\n}\""
+ ",\"simpleParam\":\"foo\"}";
properties.getClient().getAuthentication().setPluginClassName("myclass");
properties.getClient().getAuthentication().setParam(params);
ClientBuilder builder = mock(ClientBuilder.class);
@ -112,8 +114,10 @@ class PulsarPropertiesMapperTests {
@Test
void customizeAdminBuilderWhenHasAuthentication() throws UnsupportedAuthenticationException {
PulsarProperties properties = new PulsarProperties();
Map<String, String> params = Map.of("param", "name");
String authParamString = "{\"param\":\"name\"}";
Map<String, String> params = Map.of("simpleParam", "foo", "complexParam",
"{\n\t\"k1\" : \"v1\",\n\t\"k2\":\"v2\"\n}");
String authParamString = "{\"complexParam\":\"{\\n\\t\\\"k1\\\" : \\\"v1\\\",\\n\\t\\\"k2\\\":\\\"v2\\\"\\n}\""
+ ",\"simpleParam\":\"foo\"}";
properties.getAdmin().getAuthentication().setPluginClassName("myclass");
properties.getAdmin().getAuthentication().setParam(params);
PulsarAdminBuilder builder = mock(PulsarAdminBuilder.class);