From 5714317b4a59bf1a90af26315f24cf40bee63810 Mon Sep 17 00:00:00 2001 From: Cem Nura Date: Fri, 26 Mar 2021 03:30:23 +0300 Subject: [PATCH] Added keycloak-server test framework Signed-off-by: Cem Nura --- bom/application/pom.xml | 5 + integration-tests/oidc/pom.xml | 92 +------------ .../src/main/resources/application.properties | 2 +- .../BearerTokenAuthorizationTest.java | 7 +- test-framework/keycloak-server/pom.xml | 48 +++++++ .../KeycloakTestResourceLifecycleManager.java | 125 +++++++++++++----- test-framework/pom.xml | 1 + 7 files changed, 157 insertions(+), 123 deletions(-) create mode 100644 test-framework/keycloak-server/pom.xml rename integration-tests/oidc/src/test/java/io/quarkus/it/keycloak/KeycloakRealmResourceManager.java => test-framework/keycloak-server/src/main/java/io/quarkus/test/keycloak/server/KeycloakTestResourceLifecycleManager.java (65%) diff --git a/bom/application/pom.xml b/bom/application/pom.xml index 682969eaedc60..3cb6c7d7d54b7 100644 --- a/bom/application/pom.xml +++ b/bom/application/pom.xml @@ -688,6 +688,11 @@ quarkus-test-oidc-server ${project.version} + + io.quarkus + quarkus-test-keycloak-server + ${project.version} + io.quarkus quarkus-oidc-deployment diff --git a/integration-tests/oidc/pom.xml b/integration-tests/oidc/pom.xml index 128e44baf488e..66065311383b2 100644 --- a/integration-tests/oidc/pom.xml +++ b/integration-tests/oidc/pom.xml @@ -37,6 +37,11 @@ + + io.quarkus + quarkus-test-keycloak-server + test + io.quarkus quarkus-junit5 @@ -134,6 +139,7 @@ false + ${keycloak.docker.image} ${keycloak.ssl.url} @@ -143,6 +149,7 @@ false + ${keycloak.docker.image} ${keycloak.ssl.url} @@ -175,91 +182,6 @@ - - docker-keycloak - - - start-containers - - - - http://localhost:8180/auth - https://localhost:8543/auth - - - - - io.fabric8 - docker-maven-plugin - - - - ${keycloak.docker.image} - quarkus-test-keycloak - - - 8180:8080 - 8543:8443 - - - admin - admin - - - Keycloak: - default - cyan - - - - - http://localhost:8180 - - - - - - - true - - - - docker-start - compile - - stop - start - - - - docker-stop - post-integration-test - - stop - - - - - - org.codehaus.mojo - exec-maven-plugin - - - docker-prune - generate-resources - - exec - - - ${docker-prune.location} - - - - - - - - diff --git a/integration-tests/oidc/src/main/resources/application.properties b/integration-tests/oidc/src/main/resources/application.properties index 2a425123ef58e..bbeaa8b34ef8b 100644 --- a/integration-tests/oidc/src/main/resources/application.properties +++ b/integration-tests/oidc/src/main/resources/application.properties @@ -1,6 +1,6 @@ # Configuration file quarkus.oidc.auth-server-url=${keycloak.ssl.url}/realms/quarkus/ -quarkus.oidc.client-id=quarkus-app +quarkus.oidc.client-id=quarkus-service-app quarkus.oidc.credentials.secret=secret quarkus.oidc.token.principal-claim=email quarkus.oidc.tls.verification=none diff --git a/integration-tests/oidc/src/test/java/io/quarkus/it/keycloak/BearerTokenAuthorizationTest.java b/integration-tests/oidc/src/test/java/io/quarkus/it/keycloak/BearerTokenAuthorizationTest.java index b5a88e6f7584d..af69812984c1a 100644 --- a/integration-tests/oidc/src/test/java/io/quarkus/it/keycloak/BearerTokenAuthorizationTest.java +++ b/integration-tests/oidc/src/test/java/io/quarkus/it/keycloak/BearerTokenAuthorizationTest.java @@ -1,7 +1,7 @@ package io.quarkus.it.keycloak; -import static io.quarkus.it.keycloak.KeycloakRealmResourceManager.getAccessToken; -import static io.quarkus.it.keycloak.KeycloakRealmResourceManager.getRefreshToken; +import static io.quarkus.test.keycloak.server.KeycloakTestResourceLifecycleManager.getAccessToken; +import static io.quarkus.test.keycloak.server.KeycloakTestResourceLifecycleManager.getRefreshToken; import static org.awaitility.Awaitility.await; import static org.hamcrest.Matchers.equalTo; @@ -16,13 +16,14 @@ import io.quarkus.test.common.QuarkusTestResource; import io.quarkus.test.junit.QuarkusTest; +import io.quarkus.test.keycloak.server.KeycloakTestResourceLifecycleManager; import io.restassured.RestAssured; /** * @author Pedro Igor */ @QuarkusTest -@QuarkusTestResource(KeycloakRealmResourceManager.class) +@QuarkusTestResource(KeycloakTestResourceLifecycleManager.class) public class BearerTokenAuthorizationTest { @Test diff --git a/test-framework/keycloak-server/pom.xml b/test-framework/keycloak-server/pom.xml new file mode 100644 index 0000000000000..ccc211795dc24 --- /dev/null +++ b/test-framework/keycloak-server/pom.xml @@ -0,0 +1,48 @@ + + + 4.0.0 + + + io.quarkus + quarkus-test-framework + 999-SNAPSHOT + + + quarkus-test-keycloak-server + Quarkus - Test Framework - Keycloak Server support + + + org.keycloak + keycloak-adapter-core + + + org.keycloak + keycloak-core + + + org.testcontainers + testcontainers + + + io.rest-assured + rest-assured + + + io.rest-assured + xml-path + + + + + io.quarkus + quarkus-test-common + + + org.testcontainers + testcontainers + + + + diff --git a/integration-tests/oidc/src/test/java/io/quarkus/it/keycloak/KeycloakRealmResourceManager.java b/test-framework/keycloak-server/src/main/java/io/quarkus/test/keycloak/server/KeycloakTestResourceLifecycleManager.java similarity index 65% rename from integration-tests/oidc/src/test/java/io/quarkus/it/keycloak/KeycloakRealmResourceManager.java rename to test-framework/keycloak-server/src/main/java/io/quarkus/test/keycloak/server/KeycloakTestResourceLifecycleManager.java index 4ab07adb2bf32..04c9de75e9b5c 100644 --- a/integration-tests/oidc/src/test/java/io/quarkus/it/keycloak/KeycloakRealmResourceManager.java +++ b/test-framework/keycloak-server/src/main/java/io/quarkus/test/keycloak/server/KeycloakTestResourceLifecycleManager.java @@ -1,9 +1,9 @@ -package io.quarkus.it.keycloak; +package io.quarkus.test.keycloak.server; import java.io.IOException; import java.util.ArrayList; import java.util.Arrays; -import java.util.Collections; +import java.util.HashMap; import java.util.List; import java.util.Map; @@ -15,14 +15,20 @@ import org.keycloak.representations.idm.RolesRepresentation; import org.keycloak.representations.idm.UserRepresentation; import org.keycloak.util.JsonSerialization; +import org.testcontainers.containers.GenericContainer; +import org.testcontainers.containers.wait.strategy.Wait; import io.quarkus.test.common.QuarkusTestResourceLifecycleManager; import io.restassured.RestAssured; -public class KeycloakRealmResourceManager implements QuarkusTestResourceLifecycleManager { +public class KeycloakTestResourceLifecycleManager implements QuarkusTestResourceLifecycleManager { - private static final String KEYCLOAK_SERVER_URL = System.getProperty("keycloak.ssl.url", "https://localhost:8543/auth"); - private static final String KEYCLOAK_REALM = "quarkus"; + private GenericContainer keycloak; + + private static String KEYCLOAK_SERVER_URL; + private static final String KEYCLOAK_REALM = "quarkus-service-realm"; + private static final String KEYCLOAK_DOCKER_IMAGE = System.getProperty("keycloak.docker.image", + "quay.io/keycloak/keycloak:12.0.4"); static { RestAssured.useRelaxedHTTPSValidation(); @@ -30,14 +36,30 @@ public class KeycloakRealmResourceManager implements QuarkusTestResourceLifecycl @Override public Map start() { + keycloak = new GenericContainer(KEYCLOAK_DOCKER_IMAGE) + .withExposedPorts(8080, 8443) + .withEnv("DB_VENDOR", "H2") + .withEnv("KEYCLOAK_USER", "admin") + .withEnv("KEYCLOAK_PASSWORD", "admin") + .waitingFor(Wait.forHttp("/auth").forPort(8080)); + + keycloak.start(); + + KEYCLOAK_SERVER_URL = "https://localhost:" + keycloak.getMappedPort(8443) + "/auth"; RealmRepresentation realm = createRealm(KEYCLOAK_REALM); + postRealm(realm); - realm.getClients().add(createClient("quarkus-app")); - realm.getUsers().add(createUser("alice", "user")); - realm.getUsers().add(createUser("admin", "user", "admin")); - realm.getUsers().add(createUser("jdoe", "user", "confidential")); + RealmRepresentation webAppRealm = createWebAppRealm("quarkus-webapp-realm"); + postRealm(webAppRealm); + + Map conf = new HashMap<>(); + conf.put("quarkus.oidc.auth-server-url", KEYCLOAK_SERVER_URL + "/realms/" + KEYCLOAK_REALM); + return conf; + } + + private void postRealm(RealmRepresentation realm) { try { RestAssured .given() @@ -50,19 +72,6 @@ public Map start() { } catch (IOException e) { throw new RuntimeException(e); } - return Collections.emptyMap(); - } - - private static String getAdminAccessToken() { - return RestAssured - .given() - .param("grant_type", "password") - .param("username", "admin") - .param("password", "admin") - .param("client_id", "admin-cli") - .when() - .post(KEYCLOAK_SERVER_URL + "/realms/master/protocol/openid-connect/token") - .as(AccessTokenResponse.class).getToken(); } private static RealmRepresentation createRealm(String name) { @@ -84,9 +93,54 @@ private static RealmRepresentation createRealm(String name) { realm.getRoles().getRealm().add(new RoleRepresentation("admin", null, false)); realm.getRoles().getRealm().add(new RoleRepresentation("confidential", null, false)); + realm.getClients().add(createClient("quarkus-service-app")); + realm.getUsers().add(createUser("alice", "user")); + realm.getUsers().add(createUser("admin", "user", "admin")); + realm.getUsers().add(createUser("jdoe", "user", "confidential")); + return realm; } + private static RealmRepresentation createWebAppRealm(String name) { + RealmRepresentation realm = new RealmRepresentation(); + + realm.setRealm(name); + realm.setEnabled(true); + realm.setUsers(new ArrayList<>()); + realm.setClients(new ArrayList<>()); + realm.setSsoSessionMaxLifespan(3); // sec + realm.setAccessTokenLifespan(4); // 3 seconds + + RolesRepresentation roles = new RolesRepresentation(); + List realmRoles = new ArrayList<>(); + + roles.setRealm(realmRoles); + realm.setRoles(roles); + + realm.getRoles().getRealm().add(new RoleRepresentation("user", null, false)); + realm.getRoles().getRealm().add(new RoleRepresentation("admin", null, false)); + realm.getRoles().getRealm().add(new RoleRepresentation("confidential", null, false)); + + realm.getClients().add(createClient("quarkus-app")); + realm.getUsers().add(createUser("alice", "user")); + realm.getUsers().add(createUser("admin", "user", "admin")); + realm.getUsers().add(createUser("jdoe", "user", "confidential")); + + return realm; + } + + private static String getAdminAccessToken() { + return RestAssured + .given() + .param("grant_type", "password") + .param("username", "admin") + .param("password", "admin") + .param("client_id", "admin-cli") + .when() + .post(KEYCLOAK_SERVER_URL + "/realms/master/protocol/openid-connect/token") + .as(AccessTokenResponse.class).getToken(); + } + private static ClientRepresentation createClient(String clientId) { ClientRepresentation client = new ClientRepresentation(); @@ -119,23 +173,13 @@ private static UserRepresentation createUser(String username, String... realmRol return user; } - @Override - public void stop() { - - RestAssured - .given() - .auth().oauth2(getAdminAccessToken()) - .when() - .delete(KEYCLOAK_SERVER_URL + "/admin/realms/" + KEYCLOAK_REALM).then().statusCode(204); - } - public static String getAccessToken(String userName) { return RestAssured .given() .param("grant_type", "password") .param("username", userName) .param("password", userName) - .param("client_id", "quarkus-app") + .param("client_id", "quarkus-service-app") .param("client_secret", "secret") .when() .post(KEYCLOAK_SERVER_URL + "/realms/" + KEYCLOAK_REALM + "/protocol/openid-connect/token") @@ -148,10 +192,23 @@ public static String getRefreshToken(String userName) { .param("grant_type", "password") .param("username", userName) .param("password", userName) - .param("client_id", "quarkus-app") + .param("client_id", "quarkus-service-app") .param("client_secret", "secret") .when() .post(KEYCLOAK_SERVER_URL + "/realms/" + KEYCLOAK_REALM + "/protocol/openid-connect/token") .as(AccessTokenResponse.class).getRefreshToken(); } + + @Override + public void stop() { + + RestAssured + .given() + .auth().oauth2(getAdminAccessToken()) + .when() + .delete(KEYCLOAK_SERVER_URL + "/admin/realms/" + KEYCLOAK_REALM).then().statusCode(204); + + keycloak.stop(); + } + } diff --git a/test-framework/pom.xml b/test-framework/pom.xml index b245af38aa1c4..db2f816d0a165 100644 --- a/test-framework/pom.xml +++ b/test-framework/pom.xml @@ -37,6 +37,7 @@ ldap security oidc-server + keycloak-server jacoco