From f32960ae7fc4ec7c9e049f22539c477464ba5091 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michal=20Vav=C5=99=C3=ADk?= Date: Fri, 27 Sep 2024 21:01:21 +0200 Subject: [PATCH] Migrate 013-quarkus-oidc-restlcient to Keycloak 25 --- 013-quarkus-oidc-restclient/pom.xml | 24 ++++- .../LookupAuthorizationPongClient.java | 2 +- .../src/main/resources/application.properties | 19 ++-- .../qe/AbstractPingPongResourceTest.java | 29 +---- .../qe/containers/KeycloakTestResource.java | 100 ------------------ .../qe/secured/SecuredResourceTest.java | 5 +- .../ValidationOnResponseRouteHandler.java | 1 - 7 files changed, 41 insertions(+), 139 deletions(-) delete mode 100644 013-quarkus-oidc-restclient/src/test/java/io/quarkus/qe/containers/KeycloakTestResource.java diff --git a/013-quarkus-oidc-restclient/pom.xml b/013-quarkus-oidc-restclient/pom.xml index 66a0b07e..95a18a98 100644 --- a/013-quarkus-oidc-restclient/pom.xml +++ b/013-quarkus-oidc-restclient/pom.xml @@ -41,8 +41,8 @@ keycloak-authz-client - org.testcontainers - testcontainers + io.quarkus + quarkus-test-keycloak-server test @@ -66,6 +66,26 @@ + + maven-surefire-plugin + ${surefire-plugin.version} + + + 25.0.6 + false + + + + + maven-failsafe-plugin + ${surefire-plugin.version} + + + 25.0.6 + false + + + diff --git a/013-quarkus-oidc-restclient/src/main/java/io/quarkus/qe/ping/clients/LookupAuthorizationPongClient.java b/013-quarkus-oidc-restclient/src/main/java/io/quarkus/qe/ping/clients/LookupAuthorizationPongClient.java index af3f16ac..c0cd3f7c 100644 --- a/013-quarkus-oidc-restclient/src/main/java/io/quarkus/qe/ping/clients/LookupAuthorizationPongClient.java +++ b/013-quarkus-oidc-restclient/src/main/java/io/quarkus/qe/ping/clients/LookupAuthorizationPongClient.java @@ -68,6 +68,6 @@ default String lookupAuth() { Collections.singletonMap("secret", clientSecret), HttpClients.createDefault())); - return "Bearer " + authzClient.obtainAccessToken("test-user", "test-user").getToken(); + return "Bearer " + authzClient.obtainAccessToken("alice", "alice").getToken(); } } diff --git a/013-quarkus-oidc-restclient/src/main/resources/application.properties b/013-quarkus-oidc-restclient/src/main/resources/application.properties index 65dc15a7..7cc22996 100644 --- a/013-quarkus-oidc-restclient/src/main/resources/application.properties +++ b/013-quarkus-oidc-restclient/src/main/resources/application.properties @@ -2,9 +2,10 @@ quarkus.http.port=8081 # Security -quarkus.oidc.auth-server-url=http://localhost:8180/auth/realms/test-realm -quarkus.oidc.client-id=test-application-client -quarkus.oidc.credentials.secret=test-application-client-secret +# keycloak.url is set by KeycloakTestResourceLifecycleManager +quarkus.oidc.auth-server-url=${keycloak.url:replaced-by-test-resource}/realms/quarkus/ +quarkus.oidc.client-id=quarkus-service-app +quarkus.oidc.credentials.secret=secret quarkus.http.auth.permission.unsecured.paths=/generate-token/* quarkus.http.auth.permission.unsecured.policy=permit @@ -15,16 +16,16 @@ org.eclipse.microprofile.rest.client.propagateHeaders=Authorization # OIDC Client Configuration quarkus.oidc-client.auth-server-url=${quarkus.oidc.auth-server-url} -quarkus.oidc-client.client-id=test-application-client -quarkus.oidc-client.credentials.secret=test-application-client-secret +quarkus.oidc-client.client-id=${quarkus.oidc.client-id} +quarkus.oidc-client.credentials.secret=${quarkus.oidc.credentials.secret} ## Normal User Password quarkus.oidc-client.test-user.auth-server-url=${quarkus.oidc.auth-server-url} -quarkus.oidc-client.test-user.client-id=test-application-client -quarkus.oidc-client.test-user.credentials.secret=test-application-client-secret +quarkus.oidc-client.test-user.client-id=${quarkus.oidc.client-id} +quarkus.oidc-client.test-user.credentials.secret=${quarkus.oidc.credentials.secret} quarkus.oidc-client.test-user.grant.type=password -quarkus.oidc-client.test-user.grant-options.password.username=test-user -quarkus.oidc-client.test-user.grant-options.password.password=test-user +quarkus.oidc-client.test-user.grant-options.password.username=alice +quarkus.oidc-client.test-user.grant-options.password.password=alice # RestClient io.quarkus.qe.ping.clients.PongClient/mp-rest/url=http://localhost:8081 diff --git a/013-quarkus-oidc-restclient/src/test/java/io/quarkus/qe/AbstractPingPongResourceTest.java b/013-quarkus-oidc-restclient/src/test/java/io/quarkus/qe/AbstractPingPongResourceTest.java index 7788f0bd..ee0bb04c 100644 --- a/013-quarkus-oidc-restclient/src/test/java/io/quarkus/qe/AbstractPingPongResourceTest.java +++ b/013-quarkus-oidc-restclient/src/test/java/io/quarkus/qe/AbstractPingPongResourceTest.java @@ -1,47 +1,26 @@ package io.quarkus.qe; import static io.restassured.RestAssured.given; -import static io.restassured.config.HttpClientConfig.httpClientConfig; import static org.hamcrest.CoreMatchers.containsString; import static org.hamcrest.CoreMatchers.is; import java.util.UUID; import org.apache.http.HttpStatus; -import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; -import org.keycloak.authorization.client.AuthzClient; -import io.quarkus.qe.containers.KeycloakTestResource; import io.quarkus.qe.model.Score; -import io.quarkus.test.common.TestResourceScope; -import io.quarkus.test.common.WithTestResource; -import io.restassured.RestAssured; -import io.restassured.config.RestAssuredConfig; +import io.quarkus.test.common.QuarkusTestResource; +import io.quarkus.test.keycloak.server.KeycloakTestResourceLifecycleManager; import io.restassured.http.ContentType; -@WithTestResource(value = KeycloakTestResource.class, scope = TestResourceScope.MATCHING_RESOURCES) +@QuarkusTestResource(value = KeycloakTestResourceLifecycleManager.class) public abstract class AbstractPingPongResourceTest { private static final String PING_ENDPOINT = "/%s-ping"; private static final String PONG_ENDPOINT = "/%s-pong"; - private static final String USER = "test-user"; private static final String WRONG_TOKEN = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"; - private static final String HTTP_SOCKET_TIMEOUT_PROPERTY = "http.socket.timeout"; - private static final String HTTP_CONNECTION_TIMEOUT_PROPERTY = "http.connection.timeout"; - private static final int TIMEOUT_IN_SECONDS = 1000; - - AuthzClient authzClient; - - @BeforeEach - public void setup() { - RestAssured.config = RestAssuredConfig.config() - .httpClient(httpClientConfig() - .setParam(HTTP_SOCKET_TIMEOUT_PROPERTY, TIMEOUT_IN_SECONDS) - .setParam(HTTP_CONNECTION_TIMEOUT_PROPERTY, TIMEOUT_IN_SECONDS)); - } - @Test public void testPingUnauthorized() { given() @@ -152,6 +131,6 @@ protected String pongEndpoint() { } private String createToken() { - return authzClient.obtainAccessToken(USER, USER).getToken(); + return KeycloakTestResourceLifecycleManager.getAccessToken("alice"); } } diff --git a/013-quarkus-oidc-restclient/src/test/java/io/quarkus/qe/containers/KeycloakTestResource.java b/013-quarkus-oidc-restclient/src/test/java/io/quarkus/qe/containers/KeycloakTestResource.java deleted file mode 100644 index 627b5f87..00000000 --- a/013-quarkus-oidc-restclient/src/test/java/io/quarkus/qe/containers/KeycloakTestResource.java +++ /dev/null @@ -1,100 +0,0 @@ -package io.quarkus.qe.containers; - -import java.lang.reflect.Field; -import java.time.Duration; -import java.util.Collections; -import java.util.HashMap; -import java.util.Map; -import java.util.Optional; - -import org.apache.http.impl.client.HttpClients; -import org.keycloak.authorization.client.AuthzClient; -import org.keycloak.authorization.client.Configuration; -import org.testcontainers.containers.BindMode; -import org.testcontainers.containers.GenericContainer; -import org.testcontainers.containers.wait.strategy.Wait; - -import io.quarkus.test.common.QuarkusTestResourceLifecycleManager; - -public class KeycloakTestResource implements QuarkusTestResourceLifecycleManager { - - private static final String OIDC_AUTH_URL_PROPERTY = "quarkus.oidc.auth-server-url"; - private static final String OIDC_CLIENT_AUTH_URL_PROPERTY = "quarkus.oidc-client.auth-server-url"; - - private static final String USER = "admin"; - private static final String PASSWORD = "admin"; - private static final String REALM = "test-realm"; - private static final int PORT = 8080; - - private static final String REALM_FILE = "/tmp/realm.json"; - // TODO: update to newer Keycloak version, require code modifications - private static final String KEYCLOAK_IMAGE = "quay.io/keycloak/keycloak:11.0.3"; - - private GenericContainer container; - - @SuppressWarnings("resource") - @Override - public Map start() { - - container = new GenericContainer<>(KEYCLOAK_IMAGE) - .withEnv("KEYCLOAK_USER", USER) - .withEnv("KEYCLOAK_PASSWORD", PASSWORD) - .withEnv("KEYCLOAK_IMPORT", REALM_FILE) - .withClasspathResourceMapping("test-realm.json", REALM_FILE, BindMode.READ_ONLY) - .waitingFor(Wait.forHttp("/auth").withStartupTimeout(Duration.ofMinutes(5))); - container.addExposedPort(PORT); - container.start(); - - Map properties = new HashMap<>(); - properties.put(OIDC_AUTH_URL_PROPERTY, oidcAuthUrl()); - properties.put(OIDC_CLIENT_AUTH_URL_PROPERTY, oidcAuthUrl()); - - return properties; - } - - @Override - public void stop() { - Optional.ofNullable(container).ifPresent(GenericContainer::stop); - } - - @Override - public void inject(Object testInstance) { - Class c = testInstance.getClass(); - while (c != Object.class) { - for (Field f : c.getDeclaredFields()) { - if (f.getType().isAssignableFrom(AuthzClient.class)) { - setFieldValue(f, testInstance, initAuthzClient()); - } - } - c = c.getSuperclass(); - } - } - - private AuthzClient initAuthzClient() { - return AuthzClient.create(new Configuration( - keycloakUrl(), - REALM, - "test-application-client", - Collections.singletonMap("secret", "test-application-client-secret"), - HttpClients.createDefault())); - } - - private String keycloakUrl() { - return String.format("http://localhost:%s/auth", container.getMappedPort(PORT)); - } - - private String oidcAuthUrl() { - return String.format("%s/realms/%s", keycloakUrl(), REALM); - } - - private void setFieldValue(Field f, Object testInstance, Object value) { - try { - f.setAccessible(true); - f.set(testInstance, value); - return; - } catch (Exception e) { - throw new RuntimeException(e); - } - } - -} diff --git a/013-quarkus-oidc-restclient/src/test/java/io/quarkus/qe/secured/SecuredResourceTest.java b/013-quarkus-oidc-restclient/src/test/java/io/quarkus/qe/secured/SecuredResourceTest.java index 91a198ea..da899b99 100644 --- a/013-quarkus-oidc-restclient/src/test/java/io/quarkus/qe/secured/SecuredResourceTest.java +++ b/013-quarkus-oidc-restclient/src/test/java/io/quarkus/qe/secured/SecuredResourceTest.java @@ -6,8 +6,11 @@ import org.apache.http.HttpStatus; import org.junit.jupiter.api.Test; +import io.quarkus.test.common.QuarkusTestResource; import io.quarkus.test.junit.QuarkusTest; +import io.quarkus.test.keycloak.server.KeycloakTestResourceLifecycleManager; +@QuarkusTestResource(value = KeycloakTestResourceLifecycleManager.class) @QuarkusTest public class SecuredResourceTest { @@ -38,7 +41,7 @@ private String getClaimsFromToken() { } private String getClaimsInstancesFromPath(String path) { - String token = given().when().get("/generate-token/test-user").then().statusCode(200).extract().asString(); + String token = KeycloakTestResourceLifecycleManager.getAccessToken("alice"); return given() .auth().preemptive().oauth2(token) diff --git a/304-quarkus-vertx-routes/src/main/java/io/quarkus/qe/validation/ValidationOnResponseRouteHandler.java b/304-quarkus-vertx-routes/src/main/java/io/quarkus/qe/validation/ValidationOnResponseRouteHandler.java index e9ad540f..d67221ca 100644 --- a/304-quarkus-vertx-routes/src/main/java/io/quarkus/qe/validation/ValidationOnResponseRouteHandler.java +++ b/304-quarkus-vertx-routes/src/main/java/io/quarkus/qe/validation/ValidationOnResponseRouteHandler.java @@ -6,7 +6,6 @@ import io.smallrye.mutiny.Uni; import jakarta.validation.Valid; -import jakarta.validation.constraints.Size; @RouteBase(path = "/validate") public class ValidationOnResponseRouteHandler {