From e148021a67f8c8200949bc7c793ff41e2931e087 Mon Sep 17 00:00:00 2001 From: Steven Hawkins Date: Mon, 18 Dec 2023 07:50:47 -0500 Subject: [PATCH] fix: adding filtering to ignore anything runtime during a build (#25434) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit fix: adding filtering to ignore anything runtime during a build closes: #25166 Signed-off-by: Steve Hawkins Co-authored-by: Martin Bartoš --- .../topics/keycloak/changes-24_0_0.adoc | 6 +++- .../java/org/keycloak/config/HttpOptions.java | 1 + .../PropertyMappingInterceptor.java | 30 +++++++++++++++++++ .../configuration/mappers/PropertyMapper.java | 3 +- .../cli/dist/QuarkusPropertiesDistTest.java | 9 +++--- ...ndDistTest.testBuildHelp.unix.approved.txt | 3 ++ ...istTest.testBuildHelp.windows.approved.txt | 5 +++- ...t.testStartOptimizedHelp.unix.approved.txt | 3 -- ...estStartOptimizedHelp.windows.approved.txt | 26 ++++++++++++---- ...estStartOptimizedHelpAll.unix.approved.txt | 3 -- ...StartOptimizedHelpAll.windows.approved.txt | 28 +++++++++++++---- 11 files changed, 93 insertions(+), 24 deletions(-) diff --git a/docs/documentation/upgrading/topics/keycloak/changes-24_0_0.adoc b/docs/documentation/upgrading/topics/keycloak/changes-24_0_0.adoc index 97b98e07da..cb9638a6a8 100644 --- a/docs/documentation/upgrading/topics/keycloak/changes-24_0_0.adoc +++ b/docs/documentation/upgrading/topics/keycloak/changes-24_0_0.adoc @@ -65,4 +65,8 @@ Also the `getAttributes` method is targeted for representing only custom attribu mainly targeted for clients when updating or fetching any custom attribute for a give user. 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. \ No newline at end of file +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. \ No newline at end of file diff --git a/quarkus/config-api/src/main/java/org/keycloak/config/HttpOptions.java b/quarkus/config-api/src/main/java/org/keycloak/config/HttpOptions.java index 95c0477277..5966f29db9 100644 --- a/quarkus/config-api/src/main/java/org/keycloak/config/HttpOptions.java +++ b/quarkus/config-api/src/main/java/org/keycloak/config/HttpOptions.java @@ -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) diff --git a/quarkus/runtime/src/main/java/org/keycloak/quarkus/runtime/configuration/PropertyMappingInterceptor.java b/quarkus/runtime/src/main/java/org/keycloak/quarkus/runtime/configuration/PropertyMappingInterceptor.java index 6670e34de3..090d781b39 100644 --- a/quarkus/runtime/src/main/java/org/keycloak/quarkus/runtime/configuration/PropertyMappingInterceptor.java +++ b/quarkus/runtime/src/main/java/org/keycloak/quarkus/runtime/configuration/PropertyMappingInterceptor.java @@ -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; + /** *

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 { + Iterator filterRuntime(Iterator iter, Function 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 iterateNames(ConfigSourceInterceptorContext context) { + return filterRuntime(context.iterateNames(), Function.identity()); + } + + @Override + public Iterator iterateValues(ConfigSourceInterceptorContext context) { + return filterRuntime(context.iterateValues(), ConfigValue::getName); + } + @Override public ConfigValue getValue(ConfigSourceInterceptorContext context, String name) { ConfigValue value = PropertyMappers.getValue(context, name); diff --git a/quarkus/runtime/src/main/java/org/keycloak/quarkus/runtime/configuration/mappers/PropertyMapper.java b/quarkus/runtime/src/main/java/org/keycloak/quarkus/runtime/configuration/mappers/PropertyMapper.java index 851f2ced9c..91f1668a0f 100644 --- a/quarkus/runtime/src/main/java/org/keycloak/quarkus/runtime/configuration/mappers/PropertyMapper.java +++ b/quarkus/runtime/src/main/java/org/keycloak/quarkus/runtime/configuration/mappers/PropertyMapper.java @@ -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 { @@ -92,7 +93,7 @@ public class PropertyMapper { 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(); } diff --git a/quarkus/tests/integration/src/test/java/org/keycloak/it/cli/dist/QuarkusPropertiesDistTest.java b/quarkus/tests/integration/src/test/java/org/keycloak/it/cli/dist/QuarkusPropertiesDistTest.java index e94f7ec782..71ff823cb8 100644 --- a/quarkus/tests/integration/src/test/java/org/keycloak/it/cli/dist/QuarkusPropertiesDistTest.java +++ b/quarkus/tests/integration/src/test/java/org/keycloak/it/cli/dist/QuarkusPropertiesDistTest.java @@ -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 diff --git a/quarkus/tests/integration/src/test/resources/org/keycloak/it/cli/dist/approvals/cli/help/HelpCommandDistTest.testBuildHelp.unix.approved.txt b/quarkus/tests/integration/src/test/resources/org/keycloak/it/cli/dist/approvals/cli/help/HelpCommandDistTest.testBuildHelp.unix.approved.txt index 2d11bba701..c2fb77491f 100644 --- a/quarkus/tests/integration/src/test/resources/org/keycloak/it/cli/dist/approvals/cli/help/HelpCommandDistTest.testBuildHelp.unix.approved.txt +++ b/quarkus/tests/integration/src/test/resources/org/keycloak/it/cli/dist/approvals/cli/help/HelpCommandDistTest.testBuildHelp.unix.approved.txt @@ -65,6 +65,9 @@ HTTP(S): --http-relative-path Set the path relative to '/' for serving resources. The path must start with a '/'. Default: /. +--https-client-auth + Configures the server to require/request client authentication. Possible + values are: none, request, required. Default: none. Health: diff --git a/quarkus/tests/integration/src/test/resources/org/keycloak/it/cli/dist/approvals/cli/help/HelpCommandDistTest.testBuildHelp.windows.approved.txt b/quarkus/tests/integration/src/test/resources/org/keycloak/it/cli/dist/approvals/cli/help/HelpCommandDistTest.testBuildHelp.windows.approved.txt index 36997647e7..6a0f875fcd 100644 --- a/quarkus/tests/integration/src/test/resources/org/keycloak/it/cli/dist/approvals/cli/help/HelpCommandDistTest.testBuildHelp.windows.approved.txt +++ b/quarkus/tests/integration/src/test/resources/org/keycloak/it/cli/dist/approvals/cli/help/HelpCommandDistTest.testBuildHelp.windows.approved.txt @@ -65,6 +65,9 @@ HTTP(S): --http-relative-path Set the path relative to '/' for serving resources. The path must start with a '/'. Default: /. +--https-client-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 Enables a vault provider. Possible values are: file. +--vault Enables a vault provider. Possible values are: file, keystore. Security: diff --git a/quarkus/tests/integration/src/test/resources/org/keycloak/it/cli/dist/approvals/cli/help/HelpCommandDistTest.testStartOptimizedHelp.unix.approved.txt b/quarkus/tests/integration/src/test/resources/org/keycloak/it/cli/dist/approvals/cli/help/HelpCommandDistTest.testStartOptimizedHelp.unix.approved.txt index e57764518b..5656470c2e 100644 --- a/quarkus/tests/integration/src/test/resources/org/keycloak/it/cli/dist/approvals/cli/help/HelpCommandDistTest.testStartOptimizedHelp.unix.approved.txt +++ b/quarkus/tests/integration/src/test/resources/org/keycloak/it/cli/dist/approvals/cli/help/HelpCommandDistTest.testStartOptimizedHelp.unix.approved.txt @@ -91,9 +91,6 @@ HTTP(S): The file path to a private key in PEM format. --https-cipher-suites The cipher suites to use. If none is given, a reasonable default is selected. ---https-client-auth - Configures the server to require/request client authentication. Possible - values are: none, request, required. Default: none. --https-key-store-file The key store which holds the certificate information instead of specifying separate files. diff --git a/quarkus/tests/integration/src/test/resources/org/keycloak/it/cli/dist/approvals/cli/help/HelpCommandDistTest.testStartOptimizedHelp.windows.approved.txt b/quarkus/tests/integration/src/test/resources/org/keycloak/it/cli/dist/approvals/cli/help/HelpCommandDistTest.testStartOptimizedHelp.windows.approved.txt index b91195d7d4..af546c9889 100644 --- a/quarkus/tests/integration/src/test/resources/org/keycloak/it/cli/dist/approvals/cli/help/HelpCommandDistTest.testStartOptimizedHelp.windows.approved.txt +++ b/quarkus/tests/integration/src/test/resources/org/keycloak/it/cli/dist/approvals/cli/help/HelpCommandDistTest.testStartOptimizedHelp.windows.approved.txt @@ -17,6 +17,8 @@ Options: Database: +--db-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 The password of the database user. --db-pool-initial-size @@ -38,8 +40,10 @@ Database: --db-url-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 - 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 The username of the database user. @@ -54,6 +58,9 @@ Hostname: --hostname-admin-url Set the base URL for accessing the administration console, including scheme, host, port and path +--hostname-debug + Toggle the hostname debug page that is accessible at + /realms/master/hostname-debug Default: false. --hostname-path This should be set if proxy uses a different context-path for Keycloak. --hostname-port @@ -84,9 +91,6 @@ HTTP(S): The file path to a private key in PEM format. --https-cipher-suites The cipher suites to use. If none is given, a reasonable default is selected. ---https-client-auth - Configures the server to require/request client authentication. Possible - values are: none, request, required. Default: none. --https-key-store-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 + Specifies a path to the KeyStore Configuration Source. +--config-keystore-password + Specifies a password to the KeyStore Configuration Source. +--config-keystore-type + Specifies a type of the KeyStore Configuration Source. Default: PKCS12. + Proxy: --proxy DEPRECATED. The proxy address forwarding mode if the server is behind a @@ -126,6 +139,9 @@ Vault: --vault-dir

If set, secrets can be obtained by reading the content of files within the given directory. +--vault-file Path to the keystore file. +--vault-pass Password for the vault keystore. +--vault-type Specifies the type of the keystore file. Default: PKCS12. Logging: diff --git a/quarkus/tests/integration/src/test/resources/org/keycloak/it/cli/dist/approvals/cli/help/HelpCommandDistTest.testStartOptimizedHelpAll.unix.approved.txt b/quarkus/tests/integration/src/test/resources/org/keycloak/it/cli/dist/approvals/cli/help/HelpCommandDistTest.testStartOptimizedHelpAll.unix.approved.txt index e57764518b..5656470c2e 100644 --- a/quarkus/tests/integration/src/test/resources/org/keycloak/it/cli/dist/approvals/cli/help/HelpCommandDistTest.testStartOptimizedHelpAll.unix.approved.txt +++ b/quarkus/tests/integration/src/test/resources/org/keycloak/it/cli/dist/approvals/cli/help/HelpCommandDistTest.testStartOptimizedHelpAll.unix.approved.txt @@ -91,9 +91,6 @@ HTTP(S): The file path to a private key in PEM format. --https-cipher-suites The cipher suites to use. If none is given, a reasonable default is selected. ---https-client-auth - Configures the server to require/request client authentication. Possible - values are: none, request, required. Default: none. --https-key-store-file The key store which holds the certificate information instead of specifying separate files. diff --git a/quarkus/tests/integration/src/test/resources/org/keycloak/it/cli/dist/approvals/cli/help/HelpCommandDistTest.testStartOptimizedHelpAll.windows.approved.txt b/quarkus/tests/integration/src/test/resources/org/keycloak/it/cli/dist/approvals/cli/help/HelpCommandDistTest.testStartOptimizedHelpAll.windows.approved.txt index bbb2aa1880..af546c9889 100644 --- a/quarkus/tests/integration/src/test/resources/org/keycloak/it/cli/dist/approvals/cli/help/HelpCommandDistTest.testStartOptimizedHelpAll.windows.approved.txt +++ b/quarkus/tests/integration/src/test/resources/org/keycloak/it/cli/dist/approvals/cli/help/HelpCommandDistTest.testStartOptimizedHelpAll.windows.approved.txt @@ -17,6 +17,8 @@ Options: Database: +--db-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 The password of the database user. --db-pool-initial-size @@ -38,8 +40,10 @@ Database: --db-url-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 - 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 The username of the database user. @@ -54,6 +58,9 @@ Hostname: --hostname-admin-url Set the base URL for accessing the administration console, including scheme, host, port and path +--hostname-debug + Toggle the hostname debug page that is accessible at + /realms/master/hostname-debug Default: false. --hostname-path This should be set if proxy uses a different context-path for Keycloak. --hostname-port @@ -84,9 +91,6 @@ HTTP(S): The file path to a private key in PEM format. --https-cipher-suites The cipher suites to use. If none is given, a reasonable default is selected. ---https-client-auth - Configures the server to require/request client authentication. Possible - values are: none, request, required. Default: none. --https-key-store-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 + Specifies a path to the KeyStore Configuration Source. +--config-keystore-password + Specifies a password to the KeyStore Configuration Source. +--config-keystore-type + Specifies a type of the KeyStore Configuration Source. Default: PKCS12. + Proxy: --proxy DEPRECATED. The proxy address forwarding mode if the server is behind a @@ -126,6 +139,9 @@ Vault: --vault-dir If set, secrets can be obtained by reading the content of files within the given directory. +--vault-file Path to the keystore file. +--vault-pass Password for the vault keystore. +--vault-type Specifies the type of the keystore file. Default: PKCS12. Logging: @@ -193,4 +209,4 @@ By default, this command tries to update the server configuration by running a $ kc.bat start '--optimized' By doing that, the server should start faster based on any previous -configuration you have set when manually running the 'build' command. \ No newline at end of file +configuration you have set when manually running the 'build' command.