From aff423c7e929ba78b9f4e33e0db02bfb4ae93273 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=A1clav=20Muzik=C3=A1=C5=99?= Date: Mon, 27 Jan 2025 18:20:05 +0100 Subject: [PATCH] Upgrade to Quarkus 3.17.8 (#36758) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Closes #36757 Closes #33475 Closes #34454 Signed-off-by: Václav Muzikář --- pom.xml | 19 ++++++-- .../keycloak/quarkus/runtime/cli/Picocli.java | 2 +- .../runtime/configuration/Configuration.java | 13 ++++- .../configuration/KcEnvConfigSource.java | 6 --- .../KeycloakConfigSourceProvider.java | 4 ++ .../KeycloakPropertiesConfigSource.java | 16 +------ .../configuration/PersistedConfigSource.java | 5 -- .../QuarkusPropertiesConfigSource.java | 7 +-- .../configuration/mappers/PropertyMapper.java | 12 ++--- .../mappers/PropertyMappers.java | 11 ++++- .../test/AbstractConfigurationTest.java | 12 ++--- .../keycloak/it/cli/dist/OptionsDistTest.java | 4 +- .../cli/dist/ShowConfigCommandDistTest.java | 19 ++++++++ .../keycloak/testframework/config/Config.java | 2 +- .../client/KeycloakTestingClient.java | 6 ++- .../testsuite/util/AdminClientUtil.java | 20 +++++--- .../servlet/SAMLServletAdapterTest.java | 2 +- .../testsuite/admin/ImpersonationTest.java | 48 ++++++++++++------- .../broker/AbstractAdvancedBrokerTest.java | 5 +- .../testsuite/oauth/TokenRevocationTest.java | 2 +- .../keycloak/testsuite/oauth/hok/HoKTest.java | 6 +-- 21 files changed, 129 insertions(+), 92 deletions(-) diff --git a/pom.xml b/pom.xml index 282be09e6d8..c2e5fd58427 100644 --- a/pom.xml +++ b/pom.xml @@ -52,8 +52,8 @@ jboss-snapshots-repository https://s01.oss.sonatype.org/content/repositories/snapshots/ - 3.15.2 - 3.15.2 + 3.17.8 + 3.17.8 ${timestamp} @@ -111,7 +111,8 @@ 2.0.1.Final 2.0.0.Final 1.2.17 - 6.2.9.Final + 2.24.3 + 6.2.11.Final ${resteasy.version} 20240325.1 2.0.6 @@ -124,7 +125,7 @@ ${undertow-legacy.version} 2.2.24.Final 2.3.2.Final - 2.5.2.Final + 2.6.0.Final 1.9.0.Final 6.0.3 1.5.4.Final-format-001 @@ -536,6 +537,16 @@ log4j ${log4j.version} + + org.apache.logging.log4j + log4j-core + ${log4j2-api.version} + + + org.apache.logging.log4j + log4j-api + ${log4j2-api.version} + com.googlecode.owasp-java-html-sanitizer owasp-java-html-sanitizer diff --git a/quarkus/runtime/src/main/java/org/keycloak/quarkus/runtime/cli/Picocli.java b/quarkus/runtime/src/main/java/org/keycloak/quarkus/runtime/cli/Picocli.java index ac70d6a5b8a..cdced90f9c2 100644 --- a/quarkus/runtime/src/main/java/org/keycloak/quarkus/runtime/cli/Picocli.java +++ b/quarkus/runtime/src/main/java/org/keycloak/quarkus/runtime/cli/Picocli.java @@ -586,7 +586,7 @@ public class Picocli { } ConfigValue value = Configuration.getNonPersistedConfigValue(name); if (value.getValue() == null || value.getConfigSourceName() == null - || (quarkus && !value.getConfigSourceName().equals(QuarkusPropertiesConfigSource.NAME))) { + || (quarkus && !value.getConfigSourceName().contains(QuarkusPropertiesConfigSource.NAME))) { // only persist build options resolved from config sources and not default values return; } diff --git a/quarkus/runtime/src/main/java/org/keycloak/quarkus/runtime/configuration/Configuration.java b/quarkus/runtime/src/main/java/org/keycloak/quarkus/runtime/configuration/Configuration.java index 071973da28f..addd56841ea 100644 --- a/quarkus/runtime/src/main/java/org/keycloak/quarkus/runtime/configuration/Configuration.java +++ b/quarkus/runtime/src/main/java/org/keycloak/quarkus/runtime/configuration/Configuration.java @@ -23,10 +23,10 @@ import java.util.Map; import java.util.Optional; import java.util.Properties; +import io.quarkus.runtime.configuration.ConfigUtils; import io.smallrye.config.ConfigValue; import io.smallrye.config.SmallRyeConfig; -import org.eclipse.microprofile.config.spi.ConfigProviderResolver; import org.keycloak.config.Option; import org.keycloak.quarkus.runtime.configuration.mappers.PropertyMapper; import org.keycloak.quarkus.runtime.configuration.mappers.PropertyMappers; @@ -43,6 +43,8 @@ public final class Configuration { public static final String OPTION_PART_SEPARATOR = String.valueOf(OPTION_PART_SEPARATOR_CHAR); public static final String KC_OPTIMIZED = NS_KEYCLOAK_PREFIX + "optimized"; + private static SmallRyeConfig config; + private Configuration() { } @@ -74,7 +76,14 @@ public final class Configuration { } public static synchronized SmallRyeConfig getConfig() { - return (SmallRyeConfig) ConfigProviderResolver.instance().getConfig(); + if (config == null) { + config = ConfigUtils.emptyConfigBuilder().addDiscoveredSources().build(); + } + return config; + } + + public static void resetConfig() { + config = null; } /** diff --git a/quarkus/runtime/src/main/java/org/keycloak/quarkus/runtime/configuration/KcEnvConfigSource.java b/quarkus/runtime/src/main/java/org/keycloak/quarkus/runtime/configuration/KcEnvConfigSource.java index 4aa0799931b..95a6fa3f369 100644 --- a/quarkus/runtime/src/main/java/org/keycloak/quarkus/runtime/configuration/KcEnvConfigSource.java +++ b/quarkus/runtime/src/main/java/org/keycloak/quarkus/runtime/configuration/KcEnvConfigSource.java @@ -70,10 +70,4 @@ public class KcEnvConfigSource extends PropertiesConfigSource { return properties; } - - @Override - // a workaround for https://github.com/smallrye/smallrye-config/issues/1207 - public String getName() { - return NAME; - } } diff --git a/quarkus/runtime/src/main/java/org/keycloak/quarkus/runtime/configuration/KeycloakConfigSourceProvider.java b/quarkus/runtime/src/main/java/org/keycloak/quarkus/runtime/configuration/KeycloakConfigSourceProvider.java index 516f86d36ac..bc1af31fcf2 100644 --- a/quarkus/runtime/src/main/java/org/keycloak/quarkus/runtime/configuration/KeycloakConfigSourceProvider.java +++ b/quarkus/runtime/src/main/java/org/keycloak/quarkus/runtime/configuration/KeycloakConfigSourceProvider.java @@ -91,6 +91,10 @@ public class KeycloakConfigSourceProvider implements ConfigSourceProvider, Confi return CONFIG_SOURCES; } + public static List getConfigSources() { + return CONFIG_SOURCES; + } + @Override public SmallRyeConfigBuilder configBuilder(SmallRyeConfigBuilder builder) { return builder.withSources(CONFIG_SOURCES); diff --git a/quarkus/runtime/src/main/java/org/keycloak/quarkus/runtime/configuration/KeycloakPropertiesConfigSource.java b/quarkus/runtime/src/main/java/org/keycloak/quarkus/runtime/configuration/KeycloakPropertiesConfigSource.java index 2c4e7173763..d6498ba6452 100644 --- a/quarkus/runtime/src/main/java/org/keycloak/quarkus/runtime/configuration/KeycloakPropertiesConfigSource.java +++ b/quarkus/runtime/src/main/java/org/keycloak/quarkus/runtime/configuration/KeycloakPropertiesConfigSource.java @@ -64,21 +64,7 @@ public class KeycloakPropertiesConfigSource extends AbstractLocationConfigSource @Override protected ConfigSource loadConfigSource(URL url, int ordinal) throws IOException { - // a workaround for https://github.com/smallrye/smallrye-config/issues/1207 - // replace by the following line when fixed: - // return new PropertiesConfigSource(transform(ConfigSourceUtil.urlToMap(url)), url.toString(), ordinal); - var cs = new PropertiesConfigSource(transform(ConfigSourceUtil.urlToMap(url)), url.toString(), ordinal) { - private String name; - @Override - public String getName() { - return name; - } - public void setName(String name) { - this.name = name; - } - }; - cs.setName(url.toString()); - return cs; + return new PropertiesConfigSource(transform(ConfigSourceUtil.urlToMap(url)), url.toString(), ordinal); } public static class InClassPath extends KeycloakPropertiesConfigSource implements ConfigSourceProvider { diff --git a/quarkus/runtime/src/main/java/org/keycloak/quarkus/runtime/configuration/PersistedConfigSource.java b/quarkus/runtime/src/main/java/org/keycloak/quarkus/runtime/configuration/PersistedConfigSource.java index 1ff7511ab2d..95f5a05ee3a 100644 --- a/quarkus/runtime/src/main/java/org/keycloak/quarkus/runtime/configuration/PersistedConfigSource.java +++ b/quarkus/runtime/src/main/java/org/keycloak/quarkus/runtime/configuration/PersistedConfigSource.java @@ -67,11 +67,6 @@ public final class PersistedConfigSource extends PropertiesConfigSource { return INSTANCE; } - @Override - public String getName() { - return NAME; - } - @Override public ConfigValue getConfigValue(String propertyName) { if (isEnabled()) { diff --git a/quarkus/runtime/src/main/java/org/keycloak/quarkus/runtime/configuration/QuarkusPropertiesConfigSource.java b/quarkus/runtime/src/main/java/org/keycloak/quarkus/runtime/configuration/QuarkusPropertiesConfigSource.java index d6b56a61c28..517058469d6 100644 --- a/quarkus/runtime/src/main/java/org/keycloak/quarkus/runtime/configuration/QuarkusPropertiesConfigSource.java +++ b/quarkus/runtime/src/main/java/org/keycloak/quarkus/runtime/configuration/QuarkusPropertiesConfigSource.java @@ -43,7 +43,7 @@ import io.smallrye.config.common.utils.ConfigSourceUtil; public final class QuarkusPropertiesConfigSource extends AbstractLocationConfigSourceLoader implements ConfigSourceProvider { private static final String FILE_NAME = "quarkus.properties"; - public static final String NAME = "QuarkusProperties"; + public static final String NAME = "KcQuarkusPropertiesConfigSource"; public static Path getConfigurationFile() { String homeDir = Environment.getHomeDir(); @@ -70,11 +70,6 @@ public final class QuarkusPropertiesConfigSource extends AbstractLocationConfigS protected ConfigSource loadConfigSource(URL url, int ordinal) throws IOException { String name = loadingFile ? NAME : (NAME + " " + url); return new PropertiesConfigSource(ConfigSourceUtil.urlToMap(url), name, ordinal) { - @Override - public String getName() { - return name; - } - @Override public String getValue(String propertyName) { if (propertyName.startsWith(NS_QUARKUS)) { 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 bb23e383431..d2e6711be04 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 @@ -23,6 +23,7 @@ import static org.keycloak.quarkus.runtime.configuration.Configuration.OPTION_PA import static org.keycloak.quarkus.runtime.configuration.Configuration.OPTION_PART_SEPARATOR_CHAR; import static org.keycloak.quarkus.runtime.configuration.Configuration.toCliFormat; import static org.keycloak.quarkus.runtime.configuration.Configuration.toEnvVarFormat; +import static org.keycloak.quarkus.runtime.configuration.MicroProfileConfigProvider.NS_KEYCLOAK_PREFIX; import java.util.Iterator; import java.util.List; @@ -85,7 +86,7 @@ public class PropertyMapper { String paramLabel, boolean mask, BiConsumer, ConfigValue> validator, String description, BooleanSupplier required, String requiredWhen, String from) { this.option = option; - this.from = from == null ? MicroProfileConfigProvider.NS_KEYCLOAK_PREFIX + this.option.getKey() : from; + this.from = from == null ? NS_KEYCLOAK_PREFIX + this.option.getKey() : from; this.to = to == null ? getFrom() : to; this.enabled = enabled; this.enabledWhen = enabledWhen; @@ -114,18 +115,15 @@ public class PropertyMapper { from = name.replace(to.substring(0, to.lastIndexOf('.')), from.substring(0, from.lastIndexOf(OPTION_PART_SEPARATOR_CHAR))); } - 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(); - } - // try to obtain the value for the property we want to map first ConfigValue config = convertValue(context.proceed(from)); boolean parentValue = false; if (mapFrom != null && (config == null || config.getValue() == null)) { // if the property we want to map depends on another one, we use the value from the other property to call the mapper - config = Configuration.getKcConfigValue(mapFrom); + // not getting the value directly from SmallRye Config to avoid the risk of infinite recursion when Config is initializing + String mapFromWithPrefix = NS_KEYCLOAK_PREFIX + mapFrom; + config = PropertyMappers.getMapper(mapFromWithPrefix).getConfigValue(mapFromWithPrefix, context); parentValue = true; } diff --git a/quarkus/runtime/src/main/java/org/keycloak/quarkus/runtime/configuration/mappers/PropertyMappers.java b/quarkus/runtime/src/main/java/org/keycloak/quarkus/runtime/configuration/mappers/PropertyMappers.java index 56c4885a3e4..109b024eb94 100644 --- a/quarkus/runtime/src/main/java/org/keycloak/quarkus/runtime/configuration/mappers/PropertyMappers.java +++ b/quarkus/runtime/src/main/java/org/keycloak/quarkus/runtime/configuration/mappers/PropertyMappers.java @@ -76,11 +76,18 @@ public final class PropertyMappers { } public static ConfigValue getValue(ConfigSourceInterceptorContext context, String name) { + name = removeProfilePrefixIfNeeded(name); PropertyMapper mapper = getMapper(name); - // during re-aug do not resolve the server runtime properties and avoid they included by quarkus in the default value config source - if ((isRebuild() || Environment.isRebuildCheck()) && isKeycloakRuntime(name, mapper)) { + + // During re-aug do not resolve the server runtime properties and avoid they included by quarkus in the default value config source. + // + // The special handling of log properties is because some logging runtime properties are requested during build time + // and we need to resolve them. That should be fine as they are generally not considered security sensitive. + // See https://github.com/quarkusio/quarkus/pull/42157 + if ((isRebuild() || Environment.isRebuildCheck()) && isKeycloakRuntime(name, mapper) && !name.startsWith("quarkus.log.")) { return ConfigValue.builder().withName(name).build(); } + if (mapper == null) { return context.proceed(name); } diff --git a/quarkus/runtime/src/test/java/org/keycloak/quarkus/runtime/configuration/test/AbstractConfigurationTest.java b/quarkus/runtime/src/test/java/org/keycloak/quarkus/runtime/configuration/test/AbstractConfigurationTest.java index c80e0d129a7..953fa713ea0 100644 --- a/quarkus/runtime/src/test/java/org/keycloak/quarkus/runtime/configuration/test/AbstractConfigurationTest.java +++ b/quarkus/runtime/src/test/java/org/keycloak/quarkus/runtime/configuration/test/AbstractConfigurationTest.java @@ -115,12 +115,11 @@ public abstract class AbstractConfigurationTest { } }); - SmallRyeConfigProviderResolver.class.cast(ConfigProviderResolver.instance()).releaseConfig(ConfigProvider.getConfig()); PropertyMappers.reset(); ConfigArgsConfigSource.setCliArgs(); PersistedConfigSource.getInstance().getConfigValueProperties().clear(); Profile.reset(); - ConfigProviderResolver.setInstance(null); + Configuration.resetConfig(); } @After @@ -134,14 +133,9 @@ public abstract class AbstractConfigurationTest { } static protected SmallRyeConfig createConfig() { + Configuration.resetConfig(); KeycloakConfigSourceProvider.reload(); - // older versions of quarkus implicitly picked up this config, now we - // must set it manually - SmallRyeConfig config = ConfigUtils.configBuilder(true, LaunchMode.NORMAL).build(); - SmallRyeConfigProviderResolver resolver = new SmallRyeConfigProviderResolver(); - resolver.registerConfig(config, Thread.currentThread().getContextClassLoader()); - ConfigProviderResolver.setInstance(resolver); - return config; + return Configuration.getConfig(); } protected void assertConfig(String key, String expectedValue, boolean isExternal) { diff --git a/quarkus/tests/integration/src/test/java/org/keycloak/it/cli/dist/OptionsDistTest.java b/quarkus/tests/integration/src/test/java/org/keycloak/it/cli/dist/OptionsDistTest.java index 43d773ff95d..6c6902b605b 100644 --- a/quarkus/tests/integration/src/test/java/org/keycloak/it/cli/dist/OptionsDistTest.java +++ b/quarkus/tests/integration/src/test/java/org/keycloak/it/cli/dist/OptionsDistTest.java @@ -76,13 +76,11 @@ public class OptionsDistTest { @Test @Order(5) - @WithEnvVars({"KC_LOG", "console", "KC_LOG_CONSOLE_COLOR", "true", "KC_LOG_FILE", "something-env", "KC_HTTP_ENABLED", "true", "KC_HOSTNAME_STRICT", "false"}) + @WithEnvVars({"KC_LOG", "console", "KC_LOG_FILE", "something-env", "KC_HTTP_ENABLED", "true", "KC_HOSTNAME_STRICT", "false"}) @Launch({"start", "--db=dev-file"}) public void testSettingEnvVars(CLIResult cliResult) { cliResult.assertMessage("The following used run time options are UNAVAILABLE and will be ignored during build time:"); cliResult.assertMessage("- log-file: Available only when File log handler is activated."); - cliResult.assertMessage("quarkus.log.console.color"); - cliResult.assertMessage("config property is deprecated and should not be used anymore"); } @DryRun diff --git a/quarkus/tests/integration/src/test/java/org/keycloak/it/cli/dist/ShowConfigCommandDistTest.java b/quarkus/tests/integration/src/test/java/org/keycloak/it/cli/dist/ShowConfigCommandDistTest.java index 9a10758153d..cc327d28bbc 100644 --- a/quarkus/tests/integration/src/test/java/org/keycloak/it/cli/dist/ShowConfigCommandDistTest.java +++ b/quarkus/tests/integration/src/test/java/org/keycloak/it/cli/dist/ShowConfigCommandDistTest.java @@ -93,4 +93,23 @@ public class ShowConfigCommandDistTest { assertThat(output, not(containsString("kc.db.password"))); assertThat(output, not(containsString("secret-pass"))); } + + @Test + @RawDistOnly(reason = "Containers are immutable") + void testConfigSourceNames(KeycloakDistribution distribution) { + CLIResult result = distribution.run("build"); + result.assertBuild(); + + distribution.setEnvVar("KC_LOG", "file"); + + 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"); + + result.assertMessage("(CLI)"); + result.assertMessage("(ENV)"); + result.assertMessage("(quarkus.properties)"); + result.assertMessage("(Persisted)"); + result.assertMessage("(config-keystore)"); + result.assertMessage("(classpath keycloak.conf)"); + result.assertMessage("(keycloak-keystore.conf)"); + } } diff --git a/test-framework/core/src/main/java/org/keycloak/testframework/config/Config.java b/test-framework/core/src/main/java/org/keycloak/testframework/config/Config.java index ed289e74656..491502d4bc8 100644 --- a/test-framework/core/src/main/java/org/keycloak/testframework/config/Config.java +++ b/test-framework/core/src/main/java/org/keycloak/testframework/config/Config.java @@ -61,7 +61,7 @@ public class Config { } else { testConfig = Thread.currentThread().getContextClassLoader().getResource("keycloak-test.properties"); } - return testConfig != null ? new PropertiesConfigSource(testConfig, "KeycloakTestConfig", 280) : null; + return testConfig != null ? new PropertiesConfigSource(testConfig, 280) : null; } catch (Exception e) { throw new RuntimeException(e); } diff --git a/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/client/KeycloakTestingClient.java b/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/client/KeycloakTestingClient.java index 888427dfef8..ba174bf70cb 100755 --- a/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/client/KeycloakTestingClient.java +++ b/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/client/KeycloakTestingClient.java @@ -56,7 +56,7 @@ public class KeycloakTestingClient implements AutoCloseable { public static ResteasyClientBuilder getRestEasyClientBuilder(String serverUrl) { ResteasyClientBuilder resteasyClientBuilder = (ResteasyClientBuilder) ResteasyClientBuilder.newBuilder(); resteasyClientBuilder.connectionPoolSize(10); - if (serverUrl.startsWith("https")) { + if ((serverUrl != null && serverUrl.startsWith("https")) || "true".equals(System.getProperty("auth.server.ssl.required"))) { // Disable PKIX path validation errors when running tests using SSL resteasyClientBuilder.disableTrustManager().hostnameVerification(ResteasyClientBuilder.HostnameVerificationPolicy.ANY); } @@ -64,6 +64,10 @@ public class KeycloakTestingClient implements AutoCloseable { return resteasyClientBuilder; } + public static ResteasyClientBuilder getRestEasyClientBuilder() { + return getRestEasyClientBuilder(null); + } + public static KeycloakTestingClient getInstance(String serverUrl) { return new KeycloakTestingClient(serverUrl, null); } diff --git a/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/util/AdminClientUtil.java b/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/util/AdminClientUtil.java index 1d0154c8e31..6e91d8ce1e9 100644 --- a/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/util/AdminClientUtil.java +++ b/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/util/AdminClientUtil.java @@ -137,12 +137,7 @@ public class AdminClientUtil { public static ResteasyClient createResteasyClient(boolean ignoreUnknownProperties, Boolean followRedirects) throws CertificateException, NoSuchAlgorithmException, KeyStoreException, IOException, KeyManagementException { ResteasyClientBuilder resteasyClientBuilder = (ResteasyClientBuilder) ResteasyClientBuilder.newBuilder(); - if ("true".equals(System.getProperty("auth.server.ssl.required"))) { - File truststore = new File(PROJECT_BUILD_DIRECTORY, "dependency/keystore/keycloak.truststore"); - resteasyClientBuilder.sslContext(getSSLContextWithTruststore(truststore, "secret")); - - System.setProperty("javax.net.ssl.trustStore", truststore.getAbsolutePath()); - } + resteasyClientBuilder.sslContext(getSSLContextWithTruststore()); // We need to ignore unknown JSON properties e.g. in the adapter configuration representation // during adapter backward compatibility testing @@ -199,6 +194,19 @@ public class AdminClientUtil { return theContext; } + public static SSLContext getSSLContextWithTruststore() { + try { + if ("true".equals(System.getProperty("auth.server.ssl.required"))) { + File truststore = new File(PROJECT_BUILD_DIRECTORY, "dependency/keystore/keycloak.truststore"); + System.setProperty("javax.net.ssl.trustStore", truststore.getAbsolutePath()); + return getSSLContextWithTruststore(truststore, "secret"); + } + } catch (Exception e) { + throw new RuntimeException(e); + } + return null; + } + private static SSLContext getSSLContextWithTruststoreAndKeystore( File trustStore, String truststorePassword, File keystore, String keystorePassword) throws CertificateException, NoSuchAlgorithmException, KeyStoreException, IOException, KeyManagementException, UnrecoverableKeyException { diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/adapter/servlet/SAMLServletAdapterTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/adapter/servlet/SAMLServletAdapterTest.java index dae9cee01c3..a99626fb167 100644 --- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/adapter/servlet/SAMLServletAdapterTest.java +++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/adapter/servlet/SAMLServletAdapterTest.java @@ -1976,7 +1976,7 @@ public class SAMLServletAdapterTest extends AbstractSAMLServletAdapterTest { BasicCookieStore cookieStore = new BasicCookieStore(); try (Keycloak client = KeycloakBuilder.builder().serverUrl(loginPage.getAuthRoot()).realm(SAMLSERVLETDEMO) .username(admin).password(adminPassword).clientId(Constants.ADMIN_CLI_CLIENT_ID) - .resteasyClient(ResteasyClientBuilder.newBuilder().build()).build(); + .resteasyClient(AdminClientUtil.createResteasyClient()).build(); CloseableHttpClient httpClient = HttpClientBuilder.create().setDefaultCookieStore(cookieStore).build()) { HttpUriRequest req = RequestBuilder.post() .setUri(loginPage.getAuthRoot() + "/admin/realms/" + SAMLSERVLETDEMO + "/users/" + userId + "/impersonation") diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/ImpersonationTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/ImpersonationTest.java index aa97302bd78..b600d5fa688 100755 --- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/ImpersonationTest.java +++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/ImpersonationTest.java @@ -17,6 +17,9 @@ package org.keycloak.testsuite.admin; +import jakarta.ws.rs.ClientErrorException; +import jakarta.ws.rs.core.HttpHeaders; +import jakarta.ws.rs.core.Response; import org.apache.http.HttpResponse; import org.apache.http.client.methods.HttpUriRequest; import org.apache.http.client.methods.RequestBuilder; @@ -27,7 +30,6 @@ import org.apache.http.util.EntityUtils; import org.hamcrest.MatcherAssert; import org.jboss.arquillian.graphene.page.Page; import org.jboss.resteasy.client.jaxrs.ResteasyClient; -import org.jboss.resteasy.client.jaxrs.ResteasyClientBuilder; import org.junit.Assert; import org.junit.Assume; import org.junit.Before; @@ -52,23 +54,39 @@ import org.keycloak.models.RealmModel; import org.keycloak.models.UserModel; import org.keycloak.models.UserSessionModel; import org.keycloak.models.utils.KeycloakModelUtils; -import org.keycloak.representations.idm.*; +import org.keycloak.representations.idm.ClientRepresentation; +import org.keycloak.representations.idm.ErrorRepresentation; +import org.keycloak.representations.idm.EventRepresentation; +import org.keycloak.representations.idm.RealmRepresentation; +import org.keycloak.representations.idm.RoleRepresentation; +import org.keycloak.representations.idm.UserRepresentation; import org.keycloak.testsuite.AbstractKeycloakTest; import org.keycloak.testsuite.AssertEvents; import org.keycloak.testsuite.auth.page.AuthRealm; import org.keycloak.testsuite.pages.AppPage; -import org.keycloak.testsuite.util.*; +import org.keycloak.testsuite.util.AdminClientUtil; +import org.keycloak.testsuite.util.ClientBuilder; +import org.keycloak.testsuite.util.ClientManager; +import org.keycloak.testsuite.util.CredentialBuilder; +import org.keycloak.testsuite.util.DroneUtils; +import org.keycloak.testsuite.util.OAuthClient; +import org.keycloak.testsuite.util.RealmBuilder; +import org.keycloak.testsuite.util.UserBuilder; import org.openqa.selenium.Cookie; -import jakarta.ws.rs.ClientErrorException; -import jakarta.ws.rs.core.HttpHeaders; -import jakarta.ws.rs.core.Response; import java.io.IOException; import java.net.URL; -import java.util.*; +import java.util.HashMap; +import java.util.LinkedList; +import java.util.List; +import java.util.Map; +import java.util.Set; import java.util.stream.Collectors; -import static org.hamcrest.Matchers.*; +import static org.hamcrest.Matchers.containsString; +import static org.hamcrest.Matchers.empty; +import static org.hamcrest.Matchers.is; +import static org.hamcrest.Matchers.not; import static org.keycloak.testsuite.util.OAuthClient.AUTH_SERVER_ROOT; import static org.keycloak.testsuite.util.ServerURLs.getAuthServerContextRoot; @@ -291,10 +309,7 @@ public class ImpersonationTest extends AbstractKeycloakTest { // Return the SSO cookie from the impersonated session protected Set testSuccessfulImpersonation(String admin, String adminRealm) { - ResteasyClientBuilder resteasyClientBuilder = (ResteasyClientBuilder) ResteasyClientBuilder.newBuilder(); - resteasyClientBuilder.connectionPoolSize(10); - resteasyClientBuilder.httpEngine(AdminClientUtil.getCustomClientHttpEngine(resteasyClientBuilder, 10, null)); - ResteasyClient resteasyClient = resteasyClientBuilder.build(); + ResteasyClient resteasyClient = AdminClientUtil.createResteasyClient(); // Login adminClient try (Keycloak client = login(admin, adminRealm, resteasyClient)) { @@ -387,6 +402,10 @@ public class ImpersonationTest extends AbstractKeycloakTest { password = username.equals("admin") ? "admin" : "password"; } + if (resteasyClient == null) { + resteasyClient = AdminClientUtil.createResteasyClient(); + } + return KeycloakBuilder.builder().serverUrl(getAuthServerContextRoot() + "/auth") .realm(realm) .username(username) @@ -415,10 +434,7 @@ public class ImpersonationTest extends AbstractKeycloakTest { // Return the SSO cookie from the impersonated session protected Set testSuccessfulServiceAccountImpersonation(UserRepresentation serviceAccount, String serviceAccountRealm) { - ResteasyClientBuilder resteasyClientBuilder = (ResteasyClientBuilder) ResteasyClientBuilder.newBuilder(); - resteasyClientBuilder.connectionPoolSize(10); - resteasyClientBuilder.httpEngine(AdminClientUtil.getCustomClientHttpEngine(resteasyClientBuilder, 10, null)); - ResteasyClient resteasyClient = resteasyClientBuilder.build(); + ResteasyClient resteasyClient = AdminClientUtil.createResteasyClient(); // Login adminClient try (Keycloak client = loginServiceAccount(serviceAccount, serviceAccountRealm, resteasyClient)) { diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/broker/AbstractAdvancedBrokerTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/broker/AbstractAdvancedBrokerTest.java index 78a11d80012..59c83806f74 100644 --- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/broker/AbstractAdvancedBrokerTest.java +++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/broker/AbstractAdvancedBrokerTest.java @@ -20,13 +20,13 @@ import org.keycloak.services.Urls; import org.keycloak.storage.UserStorageProvider; import org.keycloak.testsuite.Assert; import org.keycloak.testsuite.AssertEvents; +import org.keycloak.testsuite.client.KeycloakTestingClient; import org.keycloak.testsuite.federation.DummyUserFederationProviderFactory; import org.keycloak.testsuite.util.AccountHelper; import org.keycloak.testsuite.util.ClientBuilder; import org.keycloak.testsuite.util.OAuthClient; import org.keycloak.testsuite.util.RealmBuilder; import org.keycloak.testsuite.util.TestAppHelper; -import org.keycloak.testsuite.util.WaitUtils; import org.openqa.selenium.TimeoutException; import jakarta.ws.rs.client.Client; @@ -37,7 +37,6 @@ import jakarta.ws.rs.core.Response; import java.net.URI; import java.util.Arrays; import java.util.Collections; -import java.util.Map; import java.util.Set; import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicReference; @@ -201,7 +200,7 @@ public abstract class AbstractAdvancedBrokerTest extends AbstractBrokerTest { OAuthClient.AccessTokenResponse accessTokenResponse = oauth.realm(bc.consumerRealmName()).clientId("broker-app").doGrantAccessTokenRequest("broker-app-secret", bc.getUserLogin(), bc.getUserPassword()); AtomicReference accessToken = (AtomicReference) new AtomicReference<>(accessTokenResponse.getAccessToken()); - Client client = jakarta.ws.rs.client.ClientBuilder.newBuilder().register((ClientRequestFilter) request -> request.getHeaders().add(HttpHeaders.AUTHORIZATION, "Bearer " + accessToken.get())).build(); + Client client = KeycloakTestingClient.getRestEasyClientBuilder().register((ClientRequestFilter) request -> request.getHeaders().add(HttpHeaders.AUTHORIZATION, "Bearer " + accessToken.get())).build(); try { WebTarget target = client.target(Urls.identityProviderRetrieveToken(URI.create(getConsumerRoot() + "/auth"), bc.getIDPAlias(), bc.consumerRealmName())); diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/oauth/TokenRevocationTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/oauth/TokenRevocationTest.java index 9b35e23d634..65d406dc0bf 100644 --- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/oauth/TokenRevocationTest.java +++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/oauth/TokenRevocationTest.java @@ -391,7 +391,7 @@ public class TokenRevocationTest extends AbstractKeycloakTest { assertEquals(Status.UNAUTHORIZED.getStatusCode(), accountRequest.asStatus()); // Test admin REST not possible - try (Keycloak adminClient = Keycloak.getInstance(OAuthClient.AUTH_SERVER_ROOT, "test", "test-app", accessTokenString)) { + try (Keycloak adminClient = Keycloak.getInstance(OAuthClient.AUTH_SERVER_ROOT, "test", "test-app", accessTokenString, AdminClientUtil.getSSLContextWithTruststore())) { try { adminClient.realms().realm("test").toRepresentation(); Assert.fail("Not expected to obtain realm"); diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/oauth/hok/HoKTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/oauth/hok/HoKTest.java index eaad49ec710..f66b0120b5c 100644 --- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/oauth/hok/HoKTest.java +++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/oauth/hok/HoKTest.java @@ -63,6 +63,7 @@ import org.keycloak.testsuite.AbstractTestRealmKeycloakTest; import org.keycloak.testsuite.Assert; import org.keycloak.testsuite.AssertEvents; import org.keycloak.testsuite.admin.ApiUtil; +import org.keycloak.testsuite.client.KeycloakTestingClient; import org.keycloak.testsuite.drone.Different; import org.keycloak.testsuite.oauth.RefreshTokenTest; import org.keycloak.testsuite.util.ClientManager; @@ -497,8 +498,7 @@ public class HoKTest extends AbstractTestRealmKeycloakTest { events.expectCodeToToken(codeId, sessionId).assertEvent(); // execute the access token to get UserInfo without token binded client certificate in mutual authentication TLS - ClientBuilder clientBuilder = ClientBuilder.newBuilder(); - Client client = clientBuilder.build(); + Client client = KeycloakTestingClient.getRestEasyClientBuilder().build(); WebTarget userInfoTarget = null; Response response = null; try { @@ -506,7 +506,7 @@ public class HoKTest extends AbstractTestRealmKeycloakTest { response = userInfoTarget.request().header(HttpHeaders.AUTHORIZATION, "Bearer " + tokenResponse.getAccessToken()).get(); assertEquals(401, response.getStatus()); } finally { - response.close(); + if (response != null) response.close(); client.close(); }