Fix duplicate options in show-config
Closes #32182 Signed-off-by: Václav Muzikář <vmuzikar@redhat.com>
This commit is contained in:
parent
74fec50ac5
commit
799201f406
5 changed files with 79 additions and 85 deletions
|
@ -18,34 +18,35 @@
|
|||
package org.keycloak.quarkus.runtime.configuration;
|
||||
|
||||
import static io.smallrye.config.common.utils.StringUtil.replaceNonAlphanumericByUnderscores;
|
||||
import static org.keycloak.quarkus.runtime.configuration.MicroProfileConfigProvider.NS_KEYCLOAK_PREFIX;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import io.smallrye.config.PropertiesConfigSource;
|
||||
import org.keycloak.quarkus.runtime.configuration.mappers.PropertyMapper;
|
||||
import org.keycloak.quarkus.runtime.configuration.mappers.PropertyMappers;
|
||||
|
||||
import io.smallrye.config.EnvConfigSource;
|
||||
|
||||
public class KcEnvConfigSource extends EnvConfigSource {
|
||||
// Not extending EnvConfigSource as it's too smart for our own good. It does unnecessary mapping of provided keys
|
||||
// leading to e.g. duplicate entries (like kc.db-password and kc.db.password), or incorrectly handling getters due to
|
||||
// how equals() is implemented. We don't need that here as we do our own mapping.
|
||||
public class KcEnvConfigSource extends PropertiesConfigSource {
|
||||
|
||||
public static final String NAME = "KcEnvVarConfigSource";
|
||||
|
||||
public KcEnvConfigSource() {
|
||||
super(buildProperties(), 500);
|
||||
super(buildProperties(), NAME, 500);
|
||||
}
|
||||
|
||||
private static Map<String, String> buildProperties() {
|
||||
Map<String, String> properties = new HashMap<>();
|
||||
String kcPrefix = replaceNonAlphanumericByUnderscores(MicroProfileConfigProvider.NS_KEYCLOAK_PREFIX.toUpperCase());
|
||||
String kcPrefix = replaceNonAlphanumericByUnderscores(NS_KEYCLOAK_PREFIX.toUpperCase());
|
||||
|
||||
for (Map.Entry<String, String> entry : System.getenv().entrySet()) {
|
||||
String key = entry.getKey();
|
||||
String value = entry.getValue();
|
||||
|
||||
if (key.startsWith(kcPrefix)) {
|
||||
properties.put(key, value);
|
||||
|
||||
PropertyMapper<?> mapper = PropertyMappers.getMapper(key);
|
||||
|
||||
if (mapper != null) {
|
||||
|
@ -57,6 +58,11 @@ public class KcEnvConfigSource extends EnvConfigSource {
|
|||
|
||||
properties.put(mapper.getFrom(), value);
|
||||
}
|
||||
else {
|
||||
// most probably an SPI but could be also something else
|
||||
String transformedKey = NS_KEYCLOAK_PREFIX + key.substring(kcPrefix.length()).toLowerCase().replace("_", "-");
|
||||
properties.put(transformedKey, value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -64,6 +70,7 @@ public class KcEnvConfigSource extends EnvConfigSource {
|
|||
}
|
||||
|
||||
@Override
|
||||
// a workaround for https://github.com/smallrye/smallrye-config/issues/1207
|
||||
public String getName() {
|
||||
return NAME;
|
||||
}
|
||||
|
|
|
@ -183,7 +183,7 @@ public class ConfigurationTest extends AbstractConfigurationTest {
|
|||
System.getProperties().remove("kc.spi-client-registration-openid-connect-static-jwk-url");
|
||||
putEnvVar("KC_SPI_CLIENT_REGISTRATION_OPENID_CONNECT_STATIC_JWK_URL", "http://c.jwk.url/from-env");
|
||||
config = initConfig("client-registration", "openid-connect");
|
||||
assertEquals(1, config.getPropertyNames().size());
|
||||
assertEquals(2, config.getPropertyNames().size()); // transformed name is coming from KcEnvVarConfigSource, raw env var name is coming from EnvVarConfigSource
|
||||
assertEquals("http://c.jwk.url/from-env", config.get("static-jwk-url"));
|
||||
}
|
||||
|
||||
|
|
|
@ -1,76 +0,0 @@
|
|||
/*
|
||||
* Copyright 2021 Red Hat, Inc. and/or its affiliates
|
||||
* and other contributors as indicated by the @author tags.
|
||||
*
|
||||
* Licensed 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.keycloak.it.cli;
|
||||
|
||||
import io.quarkus.test.common.QuarkusTestResource;
|
||||
import io.quarkus.test.junit.main.Launch;
|
||||
import io.quarkus.test.junit.main.LaunchResult;
|
||||
import org.junit.jupiter.api.Assertions;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.keycloak.it.junit5.extension.CLITest;
|
||||
import org.keycloak.it.junit5.extension.ConfigurationTestResource;
|
||||
import org.keycloak.quarkus.runtime.cli.command.ShowConfig;
|
||||
import org.keycloak.quarkus.runtime.configuration.mappers.PropertyMappers;
|
||||
|
||||
import static org.hamcrest.MatcherAssert.assertThat;
|
||||
import static org.hamcrest.Matchers.containsString;
|
||||
import static org.hamcrest.Matchers.not;
|
||||
import static org.keycloak.quarkus.runtime.cli.command.Main.CONFIG_FILE_LONG_NAME;
|
||||
|
||||
@QuarkusTestResource(value = ConfigurationTestResource.class, restrictToAnnotatedClass = true)
|
||||
@CLITest
|
||||
public class ShowConfigCommandTest {
|
||||
|
||||
@Test
|
||||
@Launch({ ShowConfig.NAME })
|
||||
void testShowConfigCommandShowsRuntimeConfig(LaunchResult result) {
|
||||
Assertions.assertTrue(result.getOutput()
|
||||
.contains("Current Configuration"));
|
||||
}
|
||||
|
||||
@Test
|
||||
@Launch({ ShowConfig.NAME, "all" })
|
||||
void testShowConfigCommandWithAllShowsAllProfiles(LaunchResult result) {
|
||||
Assertions.assertTrue(result.getOutput()
|
||||
.contains("Current Configuration"));
|
||||
Assertions.assertTrue(result.getOutput()
|
||||
.contains("Quarkus Configuration"));
|
||||
}
|
||||
|
||||
@Test
|
||||
@Launch({ CONFIG_FILE_LONG_NAME+"=src/test/resources/ShowConfigCommandTest/keycloak.conf", ShowConfig.NAME, "all" })
|
||||
void testShowConfigCommandHidesCredentialsInProfiles(LaunchResult result) {
|
||||
String output = result.getOutput();
|
||||
Assertions.assertFalse(output.contains("testpw1"));
|
||||
Assertions.assertFalse(output.contains("testpw2"));
|
||||
Assertions.assertFalse(output.contains("testpw3"));
|
||||
Assertions.assertTrue(output.contains("kc.db-password = " + PropertyMappers.VALUE_MASK));
|
||||
}
|
||||
|
||||
@Test
|
||||
@Launch({ CONFIG_FILE_LONG_NAME+"=src/test/resources/ShowConfigCommandTest/keycloak-keystore.conf", ShowConfig.NAME, "all" })
|
||||
void testSmallRyeKeyStoreConfigSource(LaunchResult result) {
|
||||
// keystore is shared with QuarkusPropertiesDistTest#testSmallRyeKeyStoreConfigSource
|
||||
String output = result.getOutput();
|
||||
assertThat(output, containsString("kc.config-keystore-password = " + PropertyMappers.VALUE_MASK));
|
||||
assertThat(output, containsString("kc.log-level = " + PropertyMappers.VALUE_MASK));
|
||||
|
||||
assertThat(output, not(containsString("secret")));
|
||||
assertThat(output, not(containsString("debug")));
|
||||
}
|
||||
}
|
|
@ -1,10 +1,23 @@
|
|||
package org.keycloak.it.cli.dist;
|
||||
|
||||
import io.quarkus.test.junit.main.Launch;
|
||||
import io.quarkus.test.junit.main.LaunchResult;
|
||||
import org.junit.jupiter.api.Assertions;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.keycloak.it.junit5.extension.CLIResult;
|
||||
import org.keycloak.it.junit5.extension.DistributionTest;
|
||||
import org.keycloak.it.junit5.extension.RawDistOnly;
|
||||
import org.keycloak.it.junit5.extension.WithEnvVars;
|
||||
import org.keycloak.it.utils.KeycloakDistribution;
|
||||
import org.keycloak.quarkus.runtime.cli.command.ShowConfig;
|
||||
import org.keycloak.quarkus.runtime.configuration.mappers.PropertyMappers;
|
||||
|
||||
import java.nio.file.Paths;
|
||||
|
||||
import static org.hamcrest.MatcherAssert.assertThat;
|
||||
import static org.hamcrest.Matchers.containsString;
|
||||
import static org.hamcrest.Matchers.not;
|
||||
import static org.keycloak.quarkus.runtime.cli.command.Main.CONFIG_FILE_LONG_NAME;
|
||||
|
||||
@DistributionTest
|
||||
public class ShowConfigCommandDistTest {
|
||||
|
@ -28,4 +41,54 @@ public class ShowConfigCommandDistTest {
|
|||
resetResult.assertMessage("Current Mode: production");
|
||||
resetResult.assertMessage("kc.db = dev-file");
|
||||
}
|
||||
|
||||
@Test
|
||||
@Launch({ ShowConfig.NAME })
|
||||
void testShowConfigCommandShowsRuntimeConfig(LaunchResult result) {
|
||||
Assertions.assertTrue(result.getOutput()
|
||||
.contains("Current Configuration"));
|
||||
}
|
||||
|
||||
@Test
|
||||
@Launch({ ShowConfig.NAME, "all" })
|
||||
void testShowConfigCommandWithAllShowsAllProfiles(LaunchResult result) {
|
||||
Assertions.assertTrue(result.getOutput()
|
||||
.contains("Current Configuration"));
|
||||
Assertions.assertTrue(result.getOutput()
|
||||
.contains("Quarkus Configuration"));
|
||||
}
|
||||
|
||||
@Test
|
||||
@RawDistOnly(reason = "Containers are immutable")
|
||||
void testShowConfigCommandHidesCredentialsInProfiles(KeycloakDistribution distribution) {
|
||||
CLIResult result = distribution.run(String.format("%s=%s", CONFIG_FILE_LONG_NAME, Paths.get("src/test/resources/ShowConfigCommandTest/keycloak.conf").toAbsolutePath().normalize()), ShowConfig.NAME, "all");
|
||||
String output = result.getOutput();
|
||||
Assertions.assertFalse(output.contains("testpw1"));
|
||||
Assertions.assertFalse(output.contains("testpw2"));
|
||||
Assertions.assertFalse(output.contains("testpw3"));
|
||||
Assertions.assertTrue(output.contains("kc.db-password = " + PropertyMappers.VALUE_MASK));
|
||||
}
|
||||
|
||||
@Test
|
||||
@RawDistOnly(reason = "Containers are immutable")
|
||||
void testSmallRyeKeyStoreConfigSource(KeycloakDistribution distribution) {
|
||||
// keystore is shared with QuarkusPropertiesDistTest#testSmallRyeKeyStoreConfigSource
|
||||
CLIResult result = distribution.run(String.format("%s=%s", CONFIG_FILE_LONG_NAME, Paths.get("src/test/resources/ShowConfigCommandTest/keycloak-keystore.conf").toAbsolutePath().normalize()), ShowConfig.NAME, "all");
|
||||
String output = result.getOutput();
|
||||
assertThat(output, containsString("kc.config-keystore-password = " + PropertyMappers.VALUE_MASK));
|
||||
assertThat(output, containsString("kc.log-level = " + PropertyMappers.VALUE_MASK));
|
||||
|
||||
assertThat(output, not(containsString("secret")));
|
||||
assertThat(output, not(containsString("debug")));
|
||||
}
|
||||
|
||||
@Test
|
||||
@Launch({ ShowConfig.NAME })
|
||||
@WithEnvVars({"KC_DB_PASSWORD", "secret-pass"})
|
||||
void testNoDuplicitEnvVarEntries(LaunchResult result) {
|
||||
String output = result.getOutput();
|
||||
assertThat(output, containsString("kc.db-password = " + PropertyMappers.VALUE_MASK));
|
||||
assertThat(output, not(containsString("kc.db.password")));
|
||||
assertThat(output, not(containsString("secret-pass")));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,2 +1,2 @@
|
|||
config-keystore=src/test/resources/keystore
|
||||
config-keystore=../../../../src/test/resources/keystore
|
||||
config-keystore-password=secret
|
Loading…
Reference in a new issue