fix: adding filtering to ignore anything runtime during a build (#25434)

fix: adding filtering to ignore anything runtime during a build

closes: #25166

Signed-off-by: Steve Hawkins <shawkins@redhat.com>
Co-authored-by: Martin Bartoš <mabartos@redhat.com>
This commit is contained in:
Steven Hawkins 2023-12-18 07:50:47 -05:00 committed by GitHub
parent 2c341d4bc5
commit e148021a67
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
11 changed files with 93 additions and 24 deletions

View file

@ -66,3 +66,7 @@ mainly targeted for clients when updating or fetching any custom attribute for a
In order to resolve all the attributes including the root attributes, a new `getRawAttributes` method was added so that the resulting map also includes the root attributes. However,
this method is not available from the representation payload and it is targeted to be used by the server when managing user profiles.
= `https-client-auth` is a build time option
Option `https-client-auth` had been treated as a run time option, however this is not supported by Quarkus. The option needs to be handled at build time instead.

View file

@ -46,6 +46,7 @@ public class HttpOptions {
.category(OptionCategory.HTTP)
.description("Configures the server to require/request client authentication.")
.defaultValue(ClientAuth.none)
.buildTime(true)
.build();
public static final Option HTTPS_CIPHER_SUITES = new OptionBuilder<>("https-cipher-suites", String.class)

View file

@ -19,10 +19,18 @@ package org.keycloak.quarkus.runtime.configuration;
import io.smallrye.config.ConfigSourceInterceptor;
import io.smallrye.config.ConfigSourceInterceptorContext;
import io.smallrye.config.ConfigValue;
import org.apache.commons.collections4.iterators.FilterIterator;
import org.keycloak.common.util.StringPropertyReplacer;
import org.keycloak.quarkus.runtime.Environment;
import org.keycloak.quarkus.runtime.configuration.mappers.PropertyMapper;
import org.keycloak.quarkus.runtime.configuration.mappers.PropertyMappers;
import java.util.Iterator;
import java.util.function.Function;
import static org.keycloak.quarkus.runtime.Environment.isRebuild;
/**
* <p>This interceptor is responsible for mapping Keycloak properties to their corresponding properties in Quarkus.
*
@ -38,6 +46,28 @@ import org.keycloak.quarkus.runtime.configuration.mappers.PropertyMappers;
*/
public class PropertyMappingInterceptor implements ConfigSourceInterceptor {
<T> Iterator<T> filterRuntime(Iterator<T> iter, Function<T, String> nameFunc) {
if (!isRebuild() && !Environment.isRebuildCheck()) {
return iter;
}
return new FilterIterator<>(iter, item -> !isRuntime(nameFunc.apply(item)));
}
static boolean isRuntime(String name) {
PropertyMapper<?> mapper = PropertyMappers.getMapper(name);
return mapper != null && mapper.isRunTime();
}
@Override
public Iterator<String> iterateNames(ConfigSourceInterceptorContext context) {
return filterRuntime(context.iterateNames(), Function.identity());
}
@Override
public Iterator<ConfigValue> iterateValues(ConfigSourceInterceptorContext context) {
return filterRuntime(context.iterateValues(), ConfigValue::getName);
}
@Override
public ConfigValue getValue(ConfigSourceInterceptorContext context, String name) {
ConfigValue value = PropertyMappers.getValue(context, name);

View file

@ -36,6 +36,7 @@ import org.keycloak.config.DeprecatedMetadata;
import org.keycloak.config.Option;
import org.keycloak.config.OptionBuilder;
import org.keycloak.config.OptionCategory;
import org.keycloak.quarkus.runtime.Environment;
import org.keycloak.quarkus.runtime.configuration.MicroProfileConfigProvider;
public class PropertyMapper<T> {
@ -92,7 +93,7 @@ public class PropertyMapper<T> {
from = name.replace(to.substring(0, to.lastIndexOf('.')), from.substring(0, from.lastIndexOf(OPTION_PART_SEPARATOR_CHAR)));
}
if (isRebuild() && isRunTime() && name.startsWith(MicroProfileConfigProvider.NS_KEYCLOAK_PREFIX)) {
if ((isRebuild() || Environment.isRebuildCheck()) && isRunTime()) {
// during re-aug do not resolve the server runtime properties and avoid they included by quarkus in the default value config source
return ConfigValue.builder().withName(name).build();
}

View file

@ -24,6 +24,8 @@ import static org.junit.jupiter.api.Assertions.assertTrue;
import static org.keycloak.quarkus.runtime.cli.command.AbstractStartCommand.OPTIMIZED_BUILD_OPTION_LONG;
import java.util.function.Consumer;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.MethodOrderer.OrderAnnotation;
import org.junit.jupiter.api.Order;
import org.junit.jupiter.api.Test;
@ -130,16 +132,16 @@ public class QuarkusPropertiesDistTest {
void testMissingSmallRyeKeyStorePasswordProperty(LaunchResult result) {
CLIResult cliResult = (CLIResult) result;
cliResult.assertError("config-keystore-password must be specified");
cliResult.assertNoBuild();
}
@Disabled("Ensuring config-keystore is used only at runtime removes proactive validation of the path when only the keystore is used")
@Test
@Launch({ "start", "--http-enabled=true", "--hostname-strict=false", "--config-keystore-password=secret" })
@Order(10)
void testMissingSmallRyeKeyStorePathProperty(LaunchResult result) {
CLIResult cliResult = (CLIResult) result;
cliResult.assertBuild();
cliResult.assertError("config-keystore must be specified");
cliResult.assertNoBuild();
}
@Test
@ -149,7 +151,6 @@ public class QuarkusPropertiesDistTest {
void testInvalidSmallRyeKeyStorePathProperty(LaunchResult result) {
CLIResult cliResult = (CLIResult) result;
cliResult.assertError("java.lang.IllegalArgumentException: config-keystore path does not exist: /invalid/path");
cliResult.assertNoBuild();
}
@Test
@ -160,7 +161,7 @@ public class QuarkusPropertiesDistTest {
// keytool -importpass -alias kc.log-level -keystore keystore -storepass secret -storetype PKCS12 -v (with "debug" as the stored password)
CLIResult cliResult = (CLIResult) result;
assertTrue(cliResult.getOutput().contains("DEBUG"));
cliResult.assertBuild();
cliResult.assertStarted();
}
@Test

View file

@ -65,6 +65,9 @@ HTTP(S):
--http-relative-path <path>
Set the path relative to '/' for serving resources. The path must start with a
'/'. Default: /.
--https-client-auth <auth>
Configures the server to require/request client authentication. Possible
values are: none, request, required. Default: none.
Health:

View file

@ -65,6 +65,9 @@ HTTP(S):
--http-relative-path <path>
Set the path relative to '/' for serving resources. The path must start with a
'/'. Default: /.
--https-client-auth <auth>
Configures the server to require/request client authentication. Possible
values are: none, request, required. Default: none.
Health:
@ -81,7 +84,7 @@ Metrics:
Vault:
--vault <provider> Enables a vault provider. Possible values are: file.
--vault <provider> Enables a vault provider. Possible values are: file, keystore.
Security:

View file

@ -91,9 +91,6 @@ HTTP(S):
The file path to a private key in PEM format.
--https-cipher-suites <ciphers>
The cipher suites to use. If none is given, a reasonable default is selected.
--https-client-auth <auth>
Configures the server to require/request client authentication. Possible
values are: none, request, required. Default: none.
--https-key-store-file <file>
The key store which holds the certificate information instead of specifying
separate files.

View file

@ -17,6 +17,8 @@ Options:
Database:
--db-driver <driver> The fully qualified class name of the JDBC driver. If not set, a default
driver is set accordingly to the chosen database.
--db-password <password>
The password of the database user.
--db-pool-initial-size <size>
@ -38,8 +40,10 @@ Database:
--db-url-port <port> Sets the port of the default JDBC URL of the chosen vendor. If the `db-url`
option is set, this option is ignored.
--db-url-properties <properties>
Sets the properties of the default JDBC URL of the chosen vendor. If the
`db-url` option is set, this option is ignored.
Sets the properties of the default JDBC URL of the chosen vendor. Make sure to
set the properties accordingly to the format expected by the database
vendor, as well as appending the right character at the beginning of this
property value. If the `db-url` option is set, this option is ignored.
--db-username <username>
The username of the database user.
@ -54,6 +58,9 @@ Hostname:
--hostname-admin-url <url>
Set the base URL for accessing the administration console, including scheme,
host, port and path
--hostname-debug <true|false>
Toggle the hostname debug page that is accessible at
/realms/master/hostname-debug Default: false.
--hostname-path <path>
This should be set if proxy uses a different context-path for Keycloak.
--hostname-port <port>
@ -84,9 +91,6 @@ HTTP(S):
The file path to a private key in PEM format.
--https-cipher-suites <ciphers>
The cipher suites to use. If none is given, a reasonable default is selected.
--https-client-auth <auth>
Configures the server to require/request client authentication. Possible
values are: none, request, required. Default: none.
--https-key-store-file <file>
The key store which holds the certificate information instead of specifying
separate files.
@ -112,6 +116,15 @@ HTTP(S):
'strict' and no value is set, it defaults to 'BCFKS'. Use the System
Truststore instead, see the docs for details.
Config:
--config-keystore <config-keystore>
Specifies a path to the KeyStore Configuration Source.
--config-keystore-password <config-keystore-password>
Specifies a password to the KeyStore Configuration Source.
--config-keystore-type <config-keystore-type>
Specifies a type of the KeyStore Configuration Source. Default: PKCS12.
Proxy:
--proxy <mode> DEPRECATED. The proxy address forwarding mode if the server is behind a
@ -126,6 +139,9 @@ Vault:
--vault-dir <dir> If set, secrets can be obtained by reading the content of files within the
given directory.
--vault-file <file> Path to the keystore file.
--vault-pass <pass> Password for the vault keystore.
--vault-type <type> Specifies the type of the keystore file. Default: PKCS12.
Logging:

View file

@ -91,9 +91,6 @@ HTTP(S):
The file path to a private key in PEM format.
--https-cipher-suites <ciphers>
The cipher suites to use. If none is given, a reasonable default is selected.
--https-client-auth <auth>
Configures the server to require/request client authentication. Possible
values are: none, request, required. Default: none.
--https-key-store-file <file>
The key store which holds the certificate information instead of specifying
separate files.

View file

@ -17,6 +17,8 @@ Options:
Database:
--db-driver <driver> The fully qualified class name of the JDBC driver. If not set, a default
driver is set accordingly to the chosen database.
--db-password <password>
The password of the database user.
--db-pool-initial-size <size>
@ -38,8 +40,10 @@ Database:
--db-url-port <port> Sets the port of the default JDBC URL of the chosen vendor. If the `db-url`
option is set, this option is ignored.
--db-url-properties <properties>
Sets the properties of the default JDBC URL of the chosen vendor. If the
`db-url` option is set, this option is ignored.
Sets the properties of the default JDBC URL of the chosen vendor. Make sure to
set the properties accordingly to the format expected by the database
vendor, as well as appending the right character at the beginning of this
property value. If the `db-url` option is set, this option is ignored.
--db-username <username>
The username of the database user.
@ -54,6 +58,9 @@ Hostname:
--hostname-admin-url <url>
Set the base URL for accessing the administration console, including scheme,
host, port and path
--hostname-debug <true|false>
Toggle the hostname debug page that is accessible at
/realms/master/hostname-debug Default: false.
--hostname-path <path>
This should be set if proxy uses a different context-path for Keycloak.
--hostname-port <port>
@ -84,9 +91,6 @@ HTTP(S):
The file path to a private key in PEM format.
--https-cipher-suites <ciphers>
The cipher suites to use. If none is given, a reasonable default is selected.
--https-client-auth <auth>
Configures the server to require/request client authentication. Possible
values are: none, request, required. Default: none.
--https-key-store-file <file>
The key store which holds the certificate information instead of specifying
separate files.
@ -112,6 +116,15 @@ HTTP(S):
'strict' and no value is set, it defaults to 'BCFKS'. Use the System
Truststore instead, see the docs for details.
Config:
--config-keystore <config-keystore>
Specifies a path to the KeyStore Configuration Source.
--config-keystore-password <config-keystore-password>
Specifies a password to the KeyStore Configuration Source.
--config-keystore-type <config-keystore-type>
Specifies a type of the KeyStore Configuration Source. Default: PKCS12.
Proxy:
--proxy <mode> DEPRECATED. The proxy address forwarding mode if the server is behind a
@ -126,6 +139,9 @@ Vault:
--vault-dir <dir> If set, secrets can be obtained by reading the content of files within the
given directory.
--vault-file <file> Path to the keystore file.
--vault-pass <pass> Password for the vault keystore.
--vault-type <type> Specifies the type of the keystore file. Default: PKCS12.
Logging: