Skip to content

Commit d400eb7

Browse files
authored
Merge pull request #43840 from phillip-kruger/dev-ui-add-ext
Allow adding and removing extensions from Dev UI
2 parents bef5c0d + 94b3209 commit d400eb7

File tree

18 files changed

+1044
-57
lines changed

18 files changed

+1044
-57
lines changed

extensions/smallrye-health/deployment/pom.xml

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,16 @@
6666
<artifactId>quarkus-smallrye-openapi-deployment</artifactId>
6767
<scope>test</scope>
6868
</dependency>
69+
<dependency>
70+
<groupId>io.quarkus</groupId>
71+
<artifactId>quarkus-security-test-utils</artifactId>
72+
<scope>test</scope>
73+
</dependency>
74+
<dependency>
75+
<groupId>io.vertx</groupId>
76+
<artifactId>vertx-web-client</artifactId>
77+
<scope>test</scope>
78+
</dependency>
6979
</dependencies>
7080

7181
<build>
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
package io.quarkus.smallrye.health.test;
2+
3+
import jakarta.enterprise.context.ApplicationScoped;
4+
import jakarta.enterprise.event.Observes;
5+
6+
import io.quarkus.vertx.http.runtime.security.QuarkusHttpUser;
7+
import io.vertx.core.Handler;
8+
import io.vertx.ext.web.Router;
9+
import io.vertx.ext.web.RoutingContext;
10+
11+
@ApplicationScoped
12+
public class PathHandler {
13+
14+
public void setup(@Observes Router router) {
15+
router.route().handler(new Handler<RoutingContext>() {
16+
@Override
17+
public void handle(RoutingContext event) {
18+
QuarkusHttpUser user = (QuarkusHttpUser) event.user();
19+
StringBuilder ret = new StringBuilder();
20+
if (user != null) {
21+
ret.append(user.getSecurityIdentity().getPrincipal().getName());
22+
}
23+
ret.append(":");
24+
ret.append(event.normalizedPath());
25+
event.response().end(ret.toString());
26+
}
27+
});
28+
}
29+
}
Lines changed: 101 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,101 @@
1+
package io.quarkus.smallrye.health.test;
2+
3+
import static org.awaitility.Awaitility.await;
4+
import static org.junit.jupiter.api.Assertions.assertEquals;
5+
6+
import java.net.URL;
7+
import java.time.Duration;
8+
9+
import jakarta.inject.Inject;
10+
11+
import org.jboss.shrinkwrap.api.asset.StringAsset;
12+
import org.junit.jupiter.api.AfterAll;
13+
import org.junit.jupiter.api.Assertions;
14+
import org.junit.jupiter.api.BeforeAll;
15+
import org.junit.jupiter.api.extension.RegisterExtension;
16+
import org.junit.jupiter.params.ParameterizedTest;
17+
import org.junit.jupiter.params.provider.ValueSource;
18+
19+
import io.quarkus.security.test.utils.TestIdentityController;
20+
import io.quarkus.security.test.utils.TestIdentityProvider;
21+
import io.quarkus.test.QuarkusUnitTest;
22+
import io.quarkus.test.common.http.TestHTTPResource;
23+
import io.vertx.core.Vertx;
24+
import io.vertx.ext.web.client.WebClient;
25+
26+
public class PathMatchingHttpSecurityPolicyTest {
27+
28+
private static final Duration REQUEST_TIMEOUT = Duration.ofSeconds(20);
29+
private static final String APP_PROPS = """
30+
quarkus.http.auth.permission.management.paths=/q/*
31+
quarkus.http.auth.permission.management.policy=authenticated
32+
""";
33+
private static WebClient client;
34+
35+
@RegisterExtension
36+
static QuarkusUnitTest runner = new QuarkusUnitTest()
37+
.withApplicationRoot((jar) -> jar
38+
.addClasses(TestIdentityController.class, TestIdentityProvider.class, PathHandler.class)
39+
.addAsResource(new StringAsset(APP_PROPS), "application.properties"));
40+
41+
@BeforeAll
42+
public static void setup() {
43+
TestIdentityController.resetRoles()
44+
.add("test", "test", "test");
45+
}
46+
47+
@AfterAll
48+
public static void cleanup() {
49+
if (client != null) {
50+
client.close();
51+
}
52+
}
53+
54+
@Inject
55+
Vertx vertx;
56+
57+
@TestHTTPResource
58+
URL url;
59+
60+
private WebClient getClient() {
61+
if (client == null) {
62+
client = WebClient.create(vertx);
63+
}
64+
return client;
65+
}
66+
67+
@ParameterizedTest
68+
@ValueSource(strings = {
69+
"/q/health", "/q/health/live", "/q/health/ready", "//q/health", "///q/health", "///q///health",
70+
"/q/health/", "/q///health/", "/q///health////live"
71+
})
72+
public void testHealthCheckPaths(String path) {
73+
assurePath(path, 401);
74+
assurePathAuthenticated(path, "UP");
75+
}
76+
77+
private void assurePath(String path, int expectedStatusCode) {
78+
assurePath(path, expectedStatusCode, null, null, null);
79+
}
80+
81+
private void assurePathAuthenticated(String path, String body) {
82+
assurePath(path, 200, body, "test", null);
83+
}
84+
85+
private void assurePath(String path, int expectedStatusCode, String body, String auth, String header) {
86+
var req = getClient().get(url.getPort(), url.getHost(), path);
87+
if (auth != null) {
88+
req.basicAuthentication(auth, auth);
89+
}
90+
if (header != null) {
91+
req.putHeader(header, header);
92+
}
93+
var result = req.send();
94+
await().atMost(REQUEST_TIMEOUT).until(result::isComplete);
95+
assertEquals(expectedStatusCode, result.result().statusCode(), path);
96+
97+
if (body != null) {
98+
Assertions.assertTrue(result.result().bodyAsString().contains(body), path);
99+
}
100+
}
101+
}

extensions/smallrye-openapi/deployment/pom.xml

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,16 @@
7777
<artifactId>quarkus-reactive-routes-deployment</artifactId>
7878
<scope>test</scope>
7979
</dependency>
80+
<dependency>
81+
<groupId>io.quarkus</groupId>
82+
<artifactId>quarkus-security-test-utils</artifactId>
83+
<scope>test</scope>
84+
</dependency>
85+
<dependency>
86+
<groupId>io.vertx</groupId>
87+
<artifactId>vertx-web-client</artifactId>
88+
<scope>test</scope>
89+
</dependency>
8090
<dependency>
8191
<groupId>io.quarkus</groupId>
8292
<artifactId>quarkus-junit5-internal</artifactId>
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
package io.quarkus.smallrye.openapi.test.jaxrs;
2+
3+
import jakarta.enterprise.context.ApplicationScoped;
4+
import jakarta.enterprise.event.Observes;
5+
6+
import io.quarkus.vertx.http.runtime.security.QuarkusHttpUser;
7+
import io.vertx.core.Handler;
8+
import io.vertx.ext.web.Router;
9+
import io.vertx.ext.web.RoutingContext;
10+
11+
@ApplicationScoped
12+
public class PathHandler {
13+
14+
public void setup(@Observes Router router) {
15+
router.route().handler(new Handler<RoutingContext>() {
16+
@Override
17+
public void handle(RoutingContext event) {
18+
QuarkusHttpUser user = (QuarkusHttpUser) event.user();
19+
StringBuilder ret = new StringBuilder();
20+
if (user != null) {
21+
ret.append(user.getSecurityIdentity().getPrincipal().getName());
22+
}
23+
ret.append(":");
24+
ret.append(event.normalizedPath());
25+
event.response().end(ret.toString());
26+
}
27+
});
28+
}
29+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,100 @@
1+
package io.quarkus.smallrye.openapi.test.jaxrs;
2+
3+
import static org.awaitility.Awaitility.await;
4+
import static org.junit.jupiter.api.Assertions.assertEquals;
5+
6+
import java.net.URL;
7+
import java.time.Duration;
8+
9+
import jakarta.inject.Inject;
10+
11+
import org.jboss.shrinkwrap.api.asset.StringAsset;
12+
import org.junit.jupiter.api.AfterAll;
13+
import org.junit.jupiter.api.Assertions;
14+
import org.junit.jupiter.api.BeforeAll;
15+
import org.junit.jupiter.api.extension.RegisterExtension;
16+
import org.junit.jupiter.params.ParameterizedTest;
17+
import org.junit.jupiter.params.provider.ValueSource;
18+
19+
import io.quarkus.security.test.utils.TestIdentityController;
20+
import io.quarkus.security.test.utils.TestIdentityProvider;
21+
import io.quarkus.test.QuarkusUnitTest;
22+
import io.quarkus.test.common.http.TestHTTPResource;
23+
import io.vertx.core.Vertx;
24+
import io.vertx.ext.web.client.WebClient;
25+
26+
public class PathMatchingHttpSecurityPolicyTest {
27+
28+
private static final Duration REQUEST_TIMEOUT = Duration.ofSeconds(20);
29+
private static final String APP_PROPS = """
30+
quarkus.http.auth.permission.management.paths=/q/*
31+
quarkus.http.auth.permission.management.policy=authenticated
32+
""";
33+
private static WebClient client;
34+
35+
@RegisterExtension
36+
static QuarkusUnitTest runner = new QuarkusUnitTest()
37+
.withApplicationRoot((jar) -> jar
38+
.addClasses(TestIdentityController.class, TestIdentityProvider.class, PathHandler.class)
39+
.addAsResource(new StringAsset(APP_PROPS), "application.properties"));
40+
41+
@BeforeAll
42+
public static void setup() {
43+
TestIdentityController.resetRoles()
44+
.add("test", "test", "test");
45+
}
46+
47+
@AfterAll
48+
public static void cleanup() {
49+
if (client != null) {
50+
client.close();
51+
}
52+
}
53+
54+
@Inject
55+
Vertx vertx;
56+
57+
@TestHTTPResource
58+
URL url;
59+
60+
private WebClient getClient() {
61+
if (client == null) {
62+
client = WebClient.create(vertx);
63+
}
64+
return client;
65+
}
66+
67+
@ParameterizedTest
68+
@ValueSource(strings = {
69+
"/q/openapi", "///q/openapi", "/q///openapi", "/q/openapi/", "/q/openapi///"
70+
})
71+
public void testOpenApiPath(String path) {
72+
assurePath(path, 401);
73+
assurePathAuthenticated(path, "openapi");
74+
}
75+
76+
private void assurePath(String path, int expectedStatusCode) {
77+
assurePath(path, expectedStatusCode, null, null, null);
78+
}
79+
80+
private void assurePathAuthenticated(String path, String body) {
81+
assurePath(path, 200, body, "test", null);
82+
}
83+
84+
private void assurePath(String path, int expectedStatusCode, String body, String auth, String header) {
85+
var req = getClient().get(url.getPort(), url.getHost(), path);
86+
if (auth != null) {
87+
req.basicAuthentication(auth, auth);
88+
}
89+
if (header != null) {
90+
req.putHeader(header, header);
91+
}
92+
var result = req.send();
93+
await().atMost(REQUEST_TIMEOUT).until(result::isComplete);
94+
assertEquals(expectedStatusCode, result.result().statusCode(), path);
95+
96+
if (body != null) {
97+
Assertions.assertTrue(result.result().bodyAsString().contains(body), path);
98+
}
99+
}
100+
}

extensions/vertx-http/deployment/pom.xml

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,17 @@
7676
<groupId>com.fasterxml.jackson.datatype</groupId>
7777
<artifactId>jackson-datatype-jdk8</artifactId>
7878
</dependency>
79-
79+
<dependency>
80+
<groupId>io.quarkus</groupId>
81+
<artifactId>quarkus-devtools-common</artifactId>
82+
<exclusions>
83+
<exclusion>
84+
<groupId>org.apache.maven.resolver</groupId>
85+
<artifactId>maven-resolver-connector-basic</artifactId>
86+
</exclusion>
87+
</exclusions>
88+
</dependency>
89+
8090
<!-- Test dependencies -->
8191
<dependency>
8292
<groupId>io.quarkus</groupId>

0 commit comments

Comments
 (0)