Skip to content

Commit

Permalink
Merge pull request #39010 from gsmet/3.8.1-backports-1
Browse files Browse the repository at this point in the history
3.8.1 backports 1
  • Loading branch information
gsmet authored Feb 27, 2024
2 parents bc84000 + d662f44 commit 90b63ff
Show file tree
Hide file tree
Showing 38 changed files with 525 additions and 104 deletions.
11 changes: 11 additions & 0 deletions .github/ci-prerequisites.sh
Original file line number Diff line number Diff line change
Expand Up @@ -41,8 +41,19 @@ time sudo rm -rf /usr/share/swift || true
time sudo rm -rf /usr/local/lib/android || true
# Remove Haskell
time sudo rm -rf /opt/ghc || true
time sudo rm -rf /usr/local/.ghcup || true
# Remove pipx
time sudo rm -rf /opt/pipx || true
# Remove Rust
time sudo rm -rf /usr/share/rust || true
# Remove Go
time sudo rm -rf /usr/local/go || true
# Remove miniconda
time sudo rm -rf /usr/share/miniconda || true
# Remove powershell
time sudo rm -rf /usr/local/share/powershell || true
# Remove Google Cloud SDK
time sudo rm -rf /usr/lib/google-cloud-sdk || true

# Remove infrastructure things that are unused and take a lot of space
time sudo rm -rf /opt/hostedtoolcache/CodeQL || true
Expand Down
3 changes: 3 additions & 0 deletions .github/workflows/ci-actions-incremental.yml
Original file line number Diff line number Diff line change
Expand Up @@ -371,6 +371,9 @@ jobs:
- name: Clean Gradle temp directory
if: always()
run: devtools/gradle/gradlew --stop && rm -rf devtools/gradle/gradle-extension-plugin/build/tmp
- name: Analyze disk space
if: always() && !startsWith(matrix.java.os-name, 'windows') && !startsWith(matrix.java.os-name, 'macos')
run: .github/ci-disk-usage.sh
- name: Prepare failure archive (if maven failed)
if: failure()
run: find . -name '*-reports' -type d -o -name '*.log' | tar -czf test-reports.tgz -T -
Expand Down
6 changes: 3 additions & 3 deletions bom/application/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@
<smallrye-config.version>3.5.4</smallrye-config.version>
<smallrye-health.version>4.1.0</smallrye-health.version>
<smallrye-metrics.version>4.0.0</smallrye-metrics.version>
<smallrye-open-api.version>3.9.0</smallrye-open-api.version>
<smallrye-open-api.version>3.10.0</smallrye-open-api.version>
<smallrye-graphql.version>2.7.0</smallrye-graphql.version>
<smallrye-fault-tolerance.version>6.2.6</smallrye-fault-tolerance.version>
<smallrye-jwt.version>4.4.0</smallrye-jwt.version>
Expand Down Expand Up @@ -128,7 +128,7 @@
<cronutils.version>9.2.1</cronutils.version>
<quartz.version>2.3.2</quartz.version>
<h2.version>2.2.224</h2.version> <!-- When updating, needs to be matched in io.quarkus.hibernate.orm.runtime.config.DialectVersions -->
<postgresql-jdbc.version>42.7.1</postgresql-jdbc.version>
<postgresql-jdbc.version>42.7.2</postgresql-jdbc.version>
<mariadb-jdbc.version>3.3.2</mariadb-jdbc.version>
<mysql-jdbc.version>8.3.0</mysql-jdbc.version>
<mssql-jdbc.version>12.4.2.jre11</mssql-jdbc.version>
Expand All @@ -148,7 +148,7 @@
<brotli4j.version>1.12.0</brotli4j.version>
<reactive-streams.version>1.0.4</reactive-streams.version>
<jboss-logging.version>3.5.3.Final</jboss-logging.version>
<mutiny.version>2.5.6</mutiny.version>
<mutiny.version>2.5.7</mutiny.version>
<kafka3.version>3.6.1</kafka3.version>
<lz4.version>1.8.0</lz4.version> <!-- dependency of the kafka-clients that could be overridden by other imported BOMs in the platform -->
<snappy.version>1.1.10.5</snappy.version>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -61,9 +61,14 @@ WorkQueue workQueue(Map<String, String> configMap, Supplier<List<Action<? super
private void configureProcessWorkerSpec(ProcessWorkerSpec processWorkerSpec, Map<String, String> configMap,
List<Action<? super JavaForkOptions>> customizations) {
JavaForkOptions forkOptions = processWorkerSpec.getForkOptions();

customizations.forEach(a -> a.execute(forkOptions));

// Propagate user.dir to load config sources that use it (instead of the worker user.dir)
String userDir = configMap.get("user.dir");
if (userDir != null) {
forkOptions.systemProperty("user.dir", userDir);
}

String quarkusWorkerMaxHeap = System.getProperty("quarkus.gradle-worker.max-heap");
if (quarkusWorkerMaxHeap != null && forkOptions.getAllJvmArgs().stream().noneMatch(arg -> arg.startsWith("-Xmx"))) {
forkOptions.jvmArgs("-Xmx" + quarkusWorkerMaxHeap);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
import org.eclipse.microprofile.health.Readiness;

import io.agroal.api.AgroalDataSource;
import io.quarkus.agroal.runtime.AgroalDataSourceSupport;
import io.quarkus.agroal.runtime.DataSources;
import io.quarkus.arc.Arc;
import io.quarkus.datasource.common.runtime.DataSourceUtil;
Expand All @@ -40,10 +41,12 @@ protected void init() {
}
DataSourceSupport support = Arc.container().instance(DataSourceSupport.class)
.get();
AgroalDataSourceSupport agroalSupport = Arc.container().instance(AgroalDataSourceSupport.class)
.get();
Set<String> names = support.getConfiguredNames();
Set<String> excludedNames = support.getInactiveOrHealthCheckExcludedNames();
for (String name : names) {
if (excludedNames.contains(name)) {
if (excludedNames.contains(name) || !agroalSupport.entries.containsKey(name)) {
continue;
}
DataSource ds = dataSources.get().getDataSource(name);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
import io.quarkus.deployment.builditem.FeatureBuildItem;
import io.quarkus.deployment.builditem.NativeImageFeatureBuildItem;
import io.quarkus.deployment.builditem.SslNativeConfigBuildItem;
import io.quarkus.deployment.builditem.nativeimage.RuntimeReinitializedClassBuildItem;
import io.quarkus.deployment.builditem.nativeimage.ServiceProviderBuildItem;
import io.quarkus.deployment.pkg.steps.NativeOrNativeSourcesBuild;
import io.quarkus.jdbc.postgresql.runtime.PostgreSQLAgroalConnectionConfigurer;
Expand All @@ -32,6 +33,11 @@ NativeImageFeatureBuildItem nativeImageFeature() {
return new NativeImageFeatureBuildItem(SQLXMLFeature.class);
}

@BuildStep(onlyIf = NativeOrNativeSourcesBuild.class)
RuntimeReinitializedClassBuildItem runtimeReinitialize() {
return new RuntimeReinitializedClassBuildItem("org.postgresql.util.PasswordUtil$SecureRandomHolder");
}

@BuildStep
void registerDriver(BuildProducer<JdbcDriverBuildItem> jdbcDriver,
SslNativeConfigBuildItem sslNativeConfigBuildItem) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@
import org.keycloak.json.StringOrArraySerializer;

import io.quarkus.arc.deployment.SyntheticBeanBuildItem;
import io.quarkus.deployment.Capabilities;
import io.quarkus.deployment.Capability;
import io.quarkus.deployment.annotations.BuildProducer;
import io.quarkus.deployment.annotations.BuildStep;
import io.quarkus.deployment.annotations.ExecutionTime;
Expand Down Expand Up @@ -49,8 +51,10 @@ ReflectiveClassBuildItem reflect() {
@Record(ExecutionTime.STATIC_INIT)
@Produce(ServiceStartBuildItem.class)
@BuildStep
public void integrate(ResteasyKeycloakAdminClientRecorder recorder, TlsConfig tlsConfig) {
recorder.setClientProvider(tlsConfig.trustAll);
public void integrate(ResteasyKeycloakAdminClientRecorder recorder, TlsConfig tlsConfig, Capabilities capabilities) {
boolean areJSONBProvidersPresent = capabilities.isPresent(Capability.RESTEASY_JSON_JSONB)
|| capabilities.isPresent(Capability.RESTEASY_JSON_JSONB_CLIENT);
recorder.setClientProvider(tlsConfig.trustAll, areJSONBProvidersPresent);
}

@Record(ExecutionTime.RUNTIME_INIT)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,18 @@

import javax.net.ssl.SSLContext;

import jakarta.ws.rs.Consumes;
import jakarta.ws.rs.Produces;
import jakarta.ws.rs.client.Client;
import jakarta.ws.rs.core.MediaType;

import org.keycloak.admin.client.ClientBuilderWrapper;
import org.keycloak.admin.client.Keycloak;
import org.keycloak.admin.client.KeycloakBuilder;
import org.keycloak.admin.client.spi.ResteasyClientClassicProvider;

import io.quarkus.keycloak.admin.client.common.KeycloakAdminClientConfig;
import io.quarkus.resteasy.common.runtime.jackson.QuarkusJacksonSerializer;
import io.quarkus.runtime.RuntimeValue;
import io.quarkus.runtime.annotations.Recorder;

Expand Down Expand Up @@ -58,14 +62,25 @@ public Keycloak get() {
};
}

public void setClientProvider(boolean tlsTrustAll) {
public void setClientProvider(boolean tlsTrustAll, boolean areJSONBProvidersPresent) {
Keycloak.setClientProvider(new ResteasyClientClassicProvider() {
@Override
public Client newRestEasyClient(Object customJacksonProvider, SSLContext sslContext, boolean disableTrustManager) {
// point here is to use default Quarkus providers rather than org.keycloak.admin.client.JacksonProvider
// as it doesn't work properly in native mode
return ClientBuilderWrapper.create(sslContext, tlsTrustAll || disableTrustManager).build();
var builder = ClientBuilderWrapper.create(sslContext, tlsTrustAll || disableTrustManager);
if (areJSONBProvidersPresent) {
// when both Jackson and JSONB providers are present, we need to ensure Jackson is used
builder.register(new AppJsonQuarkusJacksonSerializer(), 100);
}
return builder.build();
}
});
}

// makes media type more specific which ensures that it will be used first
@Produces(MediaType.APPLICATION_JSON)
@Consumes(MediaType.APPLICATION_JSON)
static class AppJsonQuarkusJacksonSerializer extends QuarkusJacksonSerializer {
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,8 @@ private void initCronJobResourceWithDefaults(CronJobBuilder builder) {
// - match labels
if (jobTemplateSpec.buildSelector().getMatchLabels() == null) {
jobTemplateSpec.editSelector().withMatchLabels(new HashMap<>()).endSelector();
} else {
jobTemplateSpec.withSelector(null);
}
// - termination grace period seconds
if (jobTemplateSpec.buildTemplate().getSpec().getTerminationGracePeriodSeconds() == null) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -194,7 +194,7 @@ public static class CertificateChain {
* A parameter to specify the password of the truststore file if it is configured with {@link #trustStoreFile}.
*/
@ConfigItem
public Optional<String> trustStorePassword;
public Optional<String> trustStorePassword = Optional.empty();

/**
* A parameter to specify the alias of the truststore certificate.
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
package io.quarkus.oidc.runtime;

import java.security.Key;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.function.Function;

import jakarta.enterprise.event.Observes;
Expand All @@ -24,6 +26,9 @@

public class DynamicVerificationKeyResolver {
private static final Logger LOG = Logger.getLogger(DynamicVerificationKeyResolver.class);
private static final Set<String> KEY_HEADERS = Set.of(HeaderParameterNames.KEY_ID,
HeaderParameterNames.X509_CERTIFICATE_SHA256_THUMBPRINT,
HeaderParameterNames.X509_CERTIFICATE_THUMBPRINT);

private final OidcProviderClient client;
private final MemoryCache<Key> cache;
Expand All @@ -46,6 +51,12 @@ public Uni<VerificationKeyResolver> resolve(TokenCredential tokenCred) {
if (key != null) {
return Uni.createFrom().item(new SingleKeyVerificationKeyResolver(key));
}
if (chainResolverFallback != null && headers.containsKey(HeaderParameterNames.X509_CERTIFICATE_CHAIN)
&& Collections.disjoint(KEY_HEADERS, headers.fieldNames())) {
// If none of the key headers is available which can be used to resolve JWK then do
// not try to get another JWK set but delegate to the chain resolver fallback if it is available
return getChainResolver();
}

return client.getJsonWebKeySet(new OidcRequestContextProperties(
Map.of(OidcRequestContextProperties.TOKEN, tokenCred.getToken(),
Expand Down Expand Up @@ -105,9 +116,7 @@ public Uni<? extends VerificationKeyResolver> apply(JsonWebKeySet jwks) {
}

if (newKey == null && chainResolverFallback != null) {
LOG.debug("JWK is not available, neither 'kid' nor 'x5t#S256' nor 'x5t' token headers are set,"
+ " falling back to the certificate chain resolver");
return Uni.createFrom().item(chainResolverFallback);
return getChainResolver();
}

if (newKey == null) {
Expand All @@ -121,6 +130,12 @@ public Uni<? extends VerificationKeyResolver> apply(JsonWebKeySet jwks) {
});
}

private Uni<VerificationKeyResolver> getChainResolver() {
LOG.debug("JWK is not available, neither 'kid' nor 'x5t#S256' nor 'x5t' token headers are set,"
+ " falling back to the certificate chain resolver");
return Uni.createFrom().item(chainResolverFallback);
}

private static Key getKeyWithId(JsonWebKeySet jwks, String kid) {
if (kid != null) {
return jwks.getKeyWithId(kid);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@

import io.quarkus.oidc.AccessTokenCredential;
import io.quarkus.oidc.IdTokenCredential;
import io.quarkus.oidc.OIDCException;
import io.quarkus.oidc.OidcTenantConfig;
import io.quarkus.oidc.OidcTenantConfig.Roles.Source;
import io.quarkus.oidc.TokenIntrospection;
Expand Down Expand Up @@ -98,14 +99,16 @@ protected Map<String, Object> getRequestData(TokenAuthenticationRequest request)

private Uni<SecurityIdentity> authenticate(TokenAuthenticationRequest request, Map<String, Object> requestData,
TenantConfigContext resolvedContext) {
if (resolvedContext.oidcConfig.publicKey.isPresent()) {
LOG.debug("Performing token verification with a configured public key");
return validateTokenWithoutOidcServer(request, resolvedContext);
if (resolvedContext.oidcConfig.authServerUrl.isPresent()) {
return validateAllTokensWithOidcServer(requestData, request, resolvedContext);
} else if (resolvedContext.oidcConfig.getCertificateChain().trustStoreFile.isPresent()) {
LOG.debug("Performing token verification with a public key inlined in the certificate chain");
return validateTokenWithoutOidcServer(request, resolvedContext);
} else if (resolvedContext.oidcConfig.publicKey.isPresent()) {
LOG.debug("Performing token verification with a configured public key");
return validateTokenWithoutOidcServer(request, resolvedContext);
} else {
return validateAllTokensWithOidcServer(requestData, request, resolvedContext);
return Uni.createFrom().failure(new OIDCException("Unexpected authentication request"));
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -87,8 +87,15 @@ public OidcProvider(OidcProviderClient client, OidcTenantConfig oidcConfig, Json
this.client = client;
this.oidcConfig = oidcConfig;
this.tokenCustomizer = tokenCustomizer;
this.asymmetricKeyResolver = jwks == null ? null
: new JsonWebKeyResolver(jwks, oidcConfig.token.forcedJwkRefreshInterval, oidcConfig.certificateChain);
if (jwks != null) {
this.asymmetricKeyResolver = new JsonWebKeyResolver(jwks, oidcConfig.token.forcedJwkRefreshInterval,
oidcConfig.certificateChain);
} else if (oidcConfig != null && oidcConfig.certificateChain.trustStoreFile.isPresent()) {
this.asymmetricKeyResolver = new CertChainPublicKeyResolver(oidcConfig.certificateChain);
} else {
this.asymmetricKeyResolver = null;
}

if (client != null && oidcConfig != null && !oidcConfig.jwks.resolveEarly) {
this.keyResolverProvider = new DynamicVerificationKeyResolver(client, oidcConfig);
} else {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,22 +10,22 @@

import io.quarkus.oidc.OIDCException;
import io.quarkus.oidc.TokenCustomizer;
import io.quarkus.oidc.common.runtime.OidcConstants;
import io.quarkus.oidc.runtime.OidcUtils;

@Named("azure-access-token-customizer")
@ApplicationScoped
public class AzureAccessTokenCustomizer implements TokenCustomizer {
private static final String NONCE = "nonce";

@Override
public JsonObject customizeHeaders(JsonObject headers) {
try {
String nonce = headers.getString(NONCE);
String nonce = headers.containsKey(OidcConstants.NONCE) ? headers.getString(OidcConstants.NONCE) : null;
if (nonce != null) {
byte[] nonceSha256 = OidcUtils.getSha256Digest(nonce.getBytes(StandardCharsets.UTF_8));
byte[] newNonceBytes = Base64.getUrlEncoder().withoutPadding().encode(nonceSha256);
return Json.createObjectBuilder(headers)
.add(NONCE, new String(newNonceBytes, StandardCharsets.UTF_8)).build();
.add(OidcConstants.NONCE, new String(newNonceBytes, StandardCharsets.UTF_8)).build();
}
return null;
} catch (Exception ex) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ public Scope attach(io.vertx.core.Context vertxContext, Context toAttach) {
public void close() {
final Context before = getContext(vertxContext);
if (before != toAttach) {
log.warn("Context in storage not the expected context, Scope.close was not called correctly. Details:" +
log.info("Context in storage not the expected context, Scope.close was not called correctly. Details:" +
" OTel context before: " + OpenTelemetryUtil.getSpanData(before) +
". OTel context toAttach: " + spanDataToAttach);
}
Expand Down
Loading

0 comments on commit 90b63ff

Please sign in to comment.