Skip to content

Commit

Permalink
Merge pull request #45760 from gsmet/3.17.8-backports-1
Browse files Browse the repository at this point in the history
[3.17] 3.17.8 backports 1
  • Loading branch information
gsmet authored Jan 22, 2025
2 parents e632ab6 + 259cc87 commit 9add7f9
Show file tree
Hide file tree
Showing 36 changed files with 530 additions and 105 deletions.
15 changes: 8 additions & 7 deletions .github/workflows/ci-actions-incremental.yml
Original file line number Diff line number Diff line change
Expand Up @@ -315,13 +315,14 @@ jobs:
elif [ "${GIB_IMPACTED_MODULES}" != '_all_' ]
then
# Important: keep -pl ... in actual jobs in sync with the following grep commands!
if ! (echo -n "${GIB_IMPACTED_MODULES}" | grep -qPv 'integration-tests/(devtools|gradle|maven|devmode|kubernetes/.*)|tcks/.*'); then run_jvm=false; fi
if ! (echo -n "${GIB_IMPACTED_MODULES}" | grep -q 'integration-tests/devtools'); then run_devtools=false; fi
if ! (echo -n "${GIB_IMPACTED_MODULES}" | grep -q 'integration-tests/gradle'); then run_gradle=false; fi
if ! (echo -n "${GIB_IMPACTED_MODULES}" | grep -qP 'integration-tests/(maven|devmode)'); then run_maven=false; fi
if ! (echo -n "${GIB_IMPACTED_MODULES}" | grep -qP 'integration-tests/kubernetes/.*'); then run_kubernetes=false; fi
if ! (echo -n "${GIB_IMPACTED_MODULES}" | grep -qPv '(docs|integration-tests|tcks)/.*'); then run_quickstarts=false; fi
if ! (echo -n "${GIB_IMPACTED_MODULES}" | grep -q 'tcks/.*'); then run_tcks=false; fi
# do not use grep -q as it can exit before echo has finished outputting and cause broken pipes
if ! (echo -n "${GIB_IMPACTED_MODULES}" | grep -Pv 'integration-tests/(devtools|gradle|maven|devmode|kubernetes/.*)|tcks/.*' > /dev/null); then run_jvm=false; fi
if ! (echo -n "${GIB_IMPACTED_MODULES}" | grep 'integration-tests/devtools' > /dev/null); then run_devtools=false; fi
if ! (echo -n "${GIB_IMPACTED_MODULES}" | grep 'integration-tests/gradle' > /dev/null); then run_gradle=false; fi
if ! (echo -n "${GIB_IMPACTED_MODULES}" | grep -P 'integration-tests/(maven|devmode)' > /dev/null); then run_maven=false; fi
if ! (echo -n "${GIB_IMPACTED_MODULES}" | grep -P 'integration-tests/kubernetes/.*' > /dev/null); then run_kubernetes=false; fi
if ! (echo -n "${GIB_IMPACTED_MODULES}" | grep -Pv '(docs|integration-tests|tcks)/.*' > /dev/null); then run_quickstarts=false; fi
if ! (echo -n "${GIB_IMPACTED_MODULES}" | grep 'tcks/.*' > /dev/null); then run_tcks=false; fi
fi
echo "run_jvm=${run_jvm}, run_devtools=${run_devtools}, run_gradle=${run_gradle}, run_maven=${run_maven}, run_kubernetes=${run_kubernetes}, run_quickstarts=${run_quickstarts}, run_tcks=${run_tcks}"
echo "run_jvm=${run_jvm}" >> $GITHUB_OUTPUT
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,8 @@ public void beforeTest(Test task) {
Map<String, Object> props = task.getSystemProperties();
ApplicationModel appModel = getApplicationModel(TEST);

SmallRyeConfig config = buildEffectiveConfiguration(appModel.getAppArtifact()).getConfig();
SmallRyeConfig config = buildEffectiveConfiguration(appModel)
.getConfig();
config.getOptionalValue(TEST.getProfileKey(), String.class)
.ifPresent(value -> props.put(TEST.getProfileKey(), value));

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
import org.gradle.api.tasks.SourceSet;
import org.gradle.process.JavaForkOptions;

import io.quarkus.bootstrap.model.ApplicationModel;
import io.quarkus.gradle.dsl.Manifest;
import io.quarkus.maven.dependency.ResolvedDependency;
import io.smallrye.common.expression.Expression;
Expand Down Expand Up @@ -80,7 +81,7 @@ private BaseConfig buildBaseConfig() {

// Used to handle the (deprecated) buildNative and testNative tasks.
project.getExtensions().getExtraProperties().getProperties().forEach((k, v) -> {
if (k.startsWith("quarkus.")) {
if (k.startsWith("quarkus.") || k.startsWith("platform.quarkus.")) {
forcedPropertiesProperty.put(k, v.toString());
}
});
Expand Down Expand Up @@ -117,7 +118,9 @@ protected Manifest manifest() {
return baseConfig().manifest();
}

protected EffectiveConfig buildEffectiveConfiguration(ResolvedDependency appArtifact) {
protected EffectiveConfig buildEffectiveConfiguration(ApplicationModel appModel) {
ResolvedDependency appArtifact = appModel.getAppArtifact();

Map<String, Object> properties = new HashMap<>();
exportCustomManifestProperties(properties);

Expand All @@ -126,7 +129,7 @@ protected EffectiveConfig buildEffectiveConfiguration(ResolvedDependency appArti

// Used to handle the (deprecated) buildNative and testNative tasks.
project.getExtensions().getExtraProperties().getProperties().forEach((k, v) -> {
if (k.startsWith("quarkus.")) {
if (k.startsWith("quarkus.") || k.startsWith("platform.quarkus.")) {
forcedPropertiesProperty.put(k, v.toString());
}
});
Expand All @@ -140,6 +143,7 @@ protected EffectiveConfig buildEffectiveConfiguration(ResolvedDependency appArti
defaultProperties.putIfAbsent("quarkus.application.version", appArtifact.getVersion());

return EffectiveConfig.builder()
.withPlatformProperties(appModel.getPlatformProperties())
.withForcedProperties(forcedPropertiesProperty.get())
.withTaskProperties(properties)
.withBuildProperties(quarkusBuildProperties.get())
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,7 @@ public Deploy() {
public void checkRequiredExtensions() {
ApplicationModel appModel = resolveAppModelForBuild();
Properties sysProps = new Properties();
sysProps.putAll(extension().buildEffectiveConfiguration(appModel.getAppArtifact()).getValues());
sysProps.putAll(extension().buildEffectiveConfiguration(appModel).getValues());
try (CuratedApplication curatedApplication = QuarkusBootstrap.builder()
.setBaseClassLoader(getClass().getClassLoader())
.setExistingModel(appModel)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,15 @@ private EffectiveConfig(Builder builder) {
// 100 -> microprofile.properties in classpath (provided by default sources)
// 0 -> fallback config source for error workaround (see below)

PropertiesConfigSource platformPropertiesConfigSource;
if (builder.platformProperties.isEmpty()) {
// we don't have the model yet so we don't have the Platform properties around
platformPropertiesConfigSource = new PropertiesConfigSource(
Map.of("platform.quarkus.native.builder-image", "<<ignored>>"), "platformProperties", 0);
} else {
platformPropertiesConfigSource = new PropertiesConfigSource(builder.platformProperties, "platformProperties", 0);
}

this.config = ConfigUtils.emptyConfigBuilder()
.forClassLoader(toUrlClassloader(builder.sourceDirectories))
.withSources(new PropertiesConfigSource(builder.forcedProperties, "forcedProperties", 600))
Expand All @@ -70,9 +79,7 @@ private EffectiveConfig(Builder builder) {
.withSources(new YamlConfigSourceLoader.InFileSystem())
.withSources(new YamlConfigSourceLoader.InClassPath())
.addPropertiesSources()
// todo: this is due to ApplicationModel#getPlatformProperties not being included in the effective config
.withSources(new PropertiesConfigSource(Map.of("platform.quarkus.native.builder-image", "<<ignored>>"),
"NativeConfig#builderImage", 0))
.withSources(platformPropertiesConfigSource)
.withDefaultValues(builder.defaultProperties)
.withProfile(builder.profile)
.withMapping(PackageConfig.class)
Expand Down Expand Up @@ -122,6 +129,7 @@ static Builder builder() {
}

static final class Builder {
private Map<String, String> platformProperties = emptyMap();
private Map<String, String> forcedProperties = emptyMap();
private Map<String, ?> taskProperties = emptyMap();
private Map<String, String> buildProperties = emptyMap();
Expand All @@ -134,6 +142,11 @@ EffectiveConfig build() {
return new EffectiveConfig(this);
}

Builder withPlatformProperties(Map<String, String> platformProperties) {
this.platformProperties = platformProperties;
return this;
}

Builder withForcedProperties(Map<String, String> forcedProperties) {
this.forcedProperties = forcedProperties;
return this;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -144,7 +144,8 @@ private void jarDependencies(Path libBoot, Path libMain) {
}

ApplicationModel appModel = resolveAppModelForBuild();
SmallRyeConfig config = getExtensionView().buildEffectiveConfiguration(appModel.getAppArtifact(), new HashMap<>())
SmallRyeConfig config = getExtensionView()
.buildEffectiveConfiguration(appModel, new HashMap<>())
.getConfig();

// see https://quarkus.io/guides/class-loading-reference#configuring-class-loading
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -244,13 +244,16 @@ void generateBuild() {

ApplicationModel appModel = resolveAppModelForBuild();
SmallRyeConfig config = getExtensionView()
.buildEffectiveConfiguration(appModel.getAppArtifact(), getAdditionalForcedProperties().get().getProperties())
.buildEffectiveConfiguration(appModel, getAdditionalForcedProperties().get().getProperties())
.getConfig();
Map<String, String> quarkusProperties = Expressions.withoutExpansion(() -> {
Map<String, String> values = new HashMap<>();
for (String key : config.getMapKeys("quarkus").values()) {
values.put(key, config.getConfigValue(key).getValue());
}
for (String key : config.getMapKeys("platform.quarkus").values()) {
values.put(key, config.getConfigValue(key).getValue());
}
return values;
});

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,7 @@ public Set<File> getInputDirectory() {
public void generateCode() throws IOException {
ApplicationModel appModel = ToolingUtils.deserializeAppModel(getApplicationModel().get().getAsFile().toPath());
Map<String, String> configMap = getExtensionView()
.buildEffectiveConfiguration(appModel.getAppArtifact(), new HashMap<>()).getValues();
.buildEffectiveConfiguration(appModel, new HashMap<>()).getValues();

File outputPath = getGeneratedOutputDirectory().get().getAsFile();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@
import org.gradle.process.JavaForkOptions;
import org.gradle.util.GradleVersion;

import io.quarkus.bootstrap.model.ApplicationModel;
import io.quarkus.deployment.pkg.PackageConfig;
import io.quarkus.gradle.QuarkusPlugin;
import io.quarkus.gradle.dsl.Manifest;
Expand Down Expand Up @@ -209,8 +210,10 @@ private void exportCustomManifestProperties(Map<String, Object> properties) {
}
}

protected EffectiveConfig buildEffectiveConfiguration(ResolvedDependency appArtifact,
protected EffectiveConfig buildEffectiveConfiguration(ApplicationModel appModel,
Map<String, ?> additionalForcedProperties) {
ResolvedDependency appArtifact = appModel.getAppArtifact();

Map<String, Object> properties = new HashMap<>();
exportCustomManifestProperties(properties);

Expand All @@ -235,6 +238,7 @@ protected EffectiveConfig buildEffectiveConfiguration(ResolvedDependency appArti
forced.put("quarkus.native.enabled", "true");
}
return EffectiveConfig.builder()
.withPlatformProperties(appModel.getPlatformProperties())
.withForcedProperties(forced)
.withTaskProperties(properties)
.withBuildProperties(getQuarkusBuildProperties().get())
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,7 @@ public void setJvmArgs(List<String> jvmArgs) {
public void runQuarkus() {
ApplicationModel appModel = resolveAppModelForBuild();
Properties sysProps = new Properties();
sysProps.putAll(extension().buildEffectiveConfiguration(appModel.getAppArtifact()).getValues());
sysProps.putAll(extension().buildEffectiveConfiguration(appModel).getValues());
try (CuratedApplication curatedApplication = QuarkusBootstrap.builder()
.setBaseClassLoader(getClass().getClassLoader())
.setExistingModel(appModel)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ public void dumpEffectiveConfiguration() {
try {
ApplicationModel appModel = resolveAppModelForBuild();
EffectiveConfig effectiveConfig = getExtensionView()
.buildEffectiveConfiguration(appModel.getAppArtifact(),
.buildEffectiveConfiguration(appModel,
getAdditionalForcedProperties().get().getProperties());
SmallRyeConfig config = effectiveConfig.getConfig();
List<String> sourceNames = new ArrayList<>();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
import io.quarkus.utilities.OS;

public abstract class QuarkusTask extends DefaultTask {
private static final List<String> WORKER_BUILD_FORK_OPTIONS = List.of("quarkus.");
private static final List<String> WORKER_BUILD_FORK_OPTIONS = List.of("quarkus.", "platform.quarkus.");

private final transient QuarkusPluginExtension extension;
protected final File projectDir;
Expand Down
1 change: 1 addition & 0 deletions docs/src/main/asciidoc/cdi-reference.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -333,6 +333,7 @@ public class EagerAppBean {

NOTE: Quarkus users are encouraged to always prefer the `@Observes StartupEvent` to `@Initialized(ApplicationScoped.class)` as explained in the xref:lifecycle.adoc[Application Initialization and Termination] guide.

[[request-context-lifecycle]]
=== Request Context Lifecycle

The request context is also active:
Expand Down
12 changes: 6 additions & 6 deletions docs/src/main/asciidoc/kotlin.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -221,8 +221,8 @@ group = '...' // set your group
version = '1.0.0-SNAPSHOT'
java {
sourceCompatibility = JavaVersion.VERSION_11
targetCompatibility = JavaVersion.VERSION_11
sourceCompatibility = JavaVersion.VERSION_21
targetCompatibility = JavaVersion.VERSION_21
}
allOpen { // <2>
Expand All @@ -233,12 +233,12 @@ allOpen { // <2>
}
compileKotlin {
kotlinOptions.jvmTarget = JavaVersion.VERSION_11
kotlinOptions.jvmTarget = JavaVersion.VERSION_21
kotlinOptions.javaParameters = true
}
compileTestKotlin {
kotlinOptions.jvmTarget = JavaVersion.VERSION_11
kotlinOptions.jvmTarget = JavaVersion.VERSION_21
}
----

Expand Down Expand Up @@ -290,8 +290,8 @@ group = '...' // set your group
version = "1.0.0-SNAPSHOT"
java {
sourceCompatibility = JavaVersion.VERSION_11
targetCompatibility = JavaVersion.VERSION_11
sourceCompatibility = JavaVersion.VERSION_21
targetCompatibility = JavaVersion.VERSION_21
}
allOpen { // <2>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -123,9 +123,9 @@ public class CustomNamedHttpSecPolicy implements HttpSecurityPolicy {
public Uni<CheckResult> checkPermission(RoutingContext event, Uni<SecurityIdentity> identity,
AuthorizationRequestContext requestContext) {
if (customRequestAuthorization(event)) {
return Uni.createFrom().item(CheckResult.PERMIT);
return CheckResult.permit();
}
return Uni.createFrom().item(CheckResult.DENY);
return CheckResult.deny();
}
@Override
Expand Down Expand Up @@ -182,6 +182,17 @@ You can also create global `HttpSecurityPolicy` invoked on every request.
Just do not implement the `io.quarkus.vertx.http.runtime.security.HttpSecurityPolicy.name` method and leave the policy nameless.
====

[[policy-active-cdi-request-context]]
=== Inject `@RequestScoped` beans into `HttpSecurityPolicy`

`@RequestScoped` beans can only be injected when the xref:cdi-reference.adoc#request-context-lifecycle[CDI request context] is active.
The context can be activated by users, for example with the `@ActivateRequestContext`, however authorization happens before Quarkus prepares some `@RequestScoped` beans.
We recommend to let Quarkus activate and prepare CDI request context for you.
For example, consider a situation where you want to inject a bean from the Jakarta REST context, such as the `jakarta.ws.rs.core.UriInfo` bean.
In this case, you must apply the `HttpSecurityPolicy` to Jakarta REST endpoints. This can be achieved in one of the following ways:
* Use the `@AuthorizationPolicy` security annotation.
* Set the `quarkus.http.auth.permission.custom1.applies-to=jaxrs` configuration property.

=== Matching on paths and methods

Permission sets can also specify paths and methods as a comma-separated list.
Expand Down Expand Up @@ -494,7 +505,7 @@ s| `@PermitAll` | Specifies that all security roles are allowed to invoke the sp
s| `@RolesAllowed` | Specifies the list of security roles allowed to access methods in an application.
s| `@Authenticated` | {project-name} provides the `io.quarkus.security.Authenticated` annotation that permits any authenticated user to access the resource. It's equivalent to `@RolesAllowed("**")`.
s| `@PermissionsAllowed` | Specifies the list of permissions that are allowed to invoke the specified methods.
s| `@AuthorizationPolicy` | Specifies named `io.quarkus.vertx.http.runtime.security.HttpSecurityPolicy` that should authorize access to the specified endpoints.HttpSecurityPolicy.
s| `@AuthorizationPolicy` | Specifies named `io.quarkus.vertx.http.runtime.security.HttpSecurityPolicy` that should authorize access to the specified Jakarta REST endpoints.
Named HttpSecurityPolicy can be used for general authorization checks as demonstrated by <<authorization-policy-example>>.
|===

Expand Down
2 changes: 2 additions & 0 deletions docs/src/main/asciidoc/security-customization.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -242,6 +242,8 @@ You can enforce the order by implementing a default `SecurityIdentityAugmentor#p
By default, the request context is not activated when augmenting the security identity, this means that if you want to use for example Hibernate
that mandates a request context, you will have a `jakarta.enterprise.context.ContextNotActiveException`.

IMPORTANT: Please also review the xref:security-proactive-authentication.adoc#cdi-request-context-activation[Activating the CDI request context] section of the "Proactive authentication" guide.

The solution is to activate the request context, the following example shows how to get the roles from an Hibernate with Panache `UserRoleEntity`.

[source,java]
Expand Down
Loading

0 comments on commit 9add7f9

Please sign in to comment.