From b7a395a3efba785bae903975603f952d18564ffd Mon Sep 17 00:00:00 2001 From: Pedro Igor Date: Fri, 6 Mar 2020 10:29:55 -0300 Subject: [PATCH] [KEYCLOAK-11345] - Test basic features of Keycloak.X with current tetsuite --- .../server-x/src/main/content/bin/kc.sh | 1 + quarkus/extensions/pom.xml | 6 + quarkus/server/pom.xml | 16 ++ .../src/main/resources/application.properties | 2 +- .../NoCookieFlowRedirectAuthenticator.java | 4 +- testsuite/integration-arquillian/README.md | 20 +++ .../servers/auth-server/pom.xml | 9 + .../servers/auth-server/quarkus/assembly.xml | 46 ++++++ .../servers/auth-server/quarkus/pom.xml | 107 ++++++++++++ .../auth-server/quarkus/src/.dont-delete | 1 + .../quarkus/src/main/content/conf/cluster.xml | 104 ++++++++++++ .../KeycloakQuarkusConfiguration.java | 37 +++++ ...cloakQuarkusServerDeployableContainer.java | 155 ++++++++++++++++++ .../MultipleContainersExtension.java | 3 + .../base/src/test/resources/arquillian.xml | 7 + .../integration-arquillian/tests/pom.xml | 13 ++ 16 files changed, 529 insertions(+), 2 deletions(-) create mode 100644 testsuite/integration-arquillian/servers/auth-server/quarkus/assembly.xml create mode 100644 testsuite/integration-arquillian/servers/auth-server/quarkus/pom.xml create mode 100644 testsuite/integration-arquillian/servers/auth-server/quarkus/src/.dont-delete create mode 100644 testsuite/integration-arquillian/servers/auth-server/quarkus/src/main/content/conf/cluster.xml create mode 100644 testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/arquillian/containers/KeycloakQuarkusConfiguration.java create mode 100644 testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/arquillian/containers/KeycloakQuarkusServerDeployableContainer.java diff --git a/distribution/server-x/src/main/content/bin/kc.sh b/distribution/server-x/src/main/content/bin/kc.sh index cc8cfa41f5..bf1aa15da7 100644 --- a/distribution/server-x/src/main/content/bin/kc.sh +++ b/distribution/server-x/src/main/content/bin/kc.sh @@ -20,6 +20,7 @@ if [ "x$RESOLVED_NAME" = "x" ]; then RESOLVED_NAME="$0" fi +GREP="grep" DIRNAME=`dirname "$RESOLVED_NAME"` SERVER_OPTS="-Dkeycloak.home.dir=$DIRNAME/../ -Dkeycloak.theme.dir=$DIRNAME/../themes -Djava.util.logging.manager=org.jboss.logmanager.LogManager" diff --git a/quarkus/extensions/pom.xml b/quarkus/extensions/pom.xml index 19c86480b6..61f94e34af 100644 --- a/quarkus/extensions/pom.xml +++ b/quarkus/extensions/pom.xml @@ -55,6 +55,12 @@ org.infinispan infinispan-core + ${infinispan.version} + + + org.infinispan + infinispan-commons + ${infinispan.version} io.quarkus diff --git a/quarkus/server/pom.xml b/quarkus/server/pom.xml index 45ad8932ca..9f470a057d 100644 --- a/quarkus/server/pom.xml +++ b/quarkus/server/pom.xml @@ -402,6 +402,22 @@ + + com.sun.mail + jakarta.mail + ${jakarta.mail.version} + + + org.apache.santuario + xmlsec + ${xmlsec.version} + + + com.fasterxml.woodstox + woodstox-core + + + diff --git a/quarkus/server/src/main/resources/application.properties b/quarkus/server/src/main/resources/application.properties index 1683c209f6..f2b06d8be3 100644 --- a/quarkus/server/src/main/resources/application.properties +++ b/quarkus/server/src/main/resources/application.properties @@ -1,7 +1,7 @@ #quarkus.log.level = DEBUG quarkus.application.name=Keycloak -quarkus.servlet.context-path = / +quarkus.servlet.context-path = /auth quarkus.datasource.driver=org.h2.Driver resteasy.disable.html.sanitizer = true \ No newline at end of file diff --git a/services/src/main/java/org/keycloak/authentication/authenticators/challenge/NoCookieFlowRedirectAuthenticator.java b/services/src/main/java/org/keycloak/authentication/authenticators/challenge/NoCookieFlowRedirectAuthenticator.java index 3ee6eed245..4ac4aac3d8 100644 --- a/services/src/main/java/org/keycloak/authentication/authenticators/challenge/NoCookieFlowRedirectAuthenticator.java +++ b/services/src/main/java/org/keycloak/authentication/authenticators/challenge/NoCookieFlowRedirectAuthenticator.java @@ -24,6 +24,7 @@ import org.jboss.resteasy.spi.HttpRequest; import org.keycloak.authentication.AuthenticationFlowContext; import org.keycloak.authentication.Authenticator; import org.keycloak.models.KeycloakSession; +import org.keycloak.models.KeycloakUriInfo; import org.keycloak.models.RealmModel; import org.keycloak.models.UserModel; import org.keycloak.services.resources.LoginActionsService; @@ -45,7 +46,8 @@ public class NoCookieFlowRedirectAuthenticator implements Authenticator { // only do redirects for GET requests if (HttpMethod.GET.equalsIgnoreCase(httpRequest.getHttpMethod())) { - if (!httpRequest.getUri().getQueryParameters().containsKey(LoginActionsService.AUTH_SESSION_ID)) { + KeycloakUriInfo uriInfo = context.getSession().getContext().getUri(); + if (!uriInfo.getQueryParameters().containsKey(LoginActionsService.AUTH_SESSION_ID)) { Response response = Response.status(302).header(HttpHeaders.LOCATION, context.getRefreshUrl(true)).build(); context.challenge(response); return; diff --git a/testsuite/integration-arquillian/README.md b/testsuite/integration-arquillian/README.md index 9dab3859a7..e9eceb0da0 100644 --- a/testsuite/integration-arquillian/README.md +++ b/testsuite/integration-arquillian/README.md @@ -42,6 +42,26 @@ route add -net 224.0.0.0 netmask 240.0.0.0 dev lo ifconfig lo multicast ``` +#### Quarkus + +To run the tests against a Quarkus Server: + +``` + mvn -Pauth-server-quarkus -Dauth.server.ssl.required=false clean verify +``` + +NOTE: At the moment the Quarkus server does not support SSL, thus it *must* be disabled. + +To debug the server: + +``` + mvn -Pauth-server-quarkus -Dauth.server.ssl.required=false -Dauth.server.debug=true clean verify +``` + +By default, debug port is `5005`. To change it, set the `auth.server.debug.port` system property to another port. + +NOTE: Not all tests are passing, this is a working in progress. + ### App Servers / Adapter Tests Lifecycle of application server is always tied to a particular TestClass. diff --git a/testsuite/integration-arquillian/servers/auth-server/pom.xml b/testsuite/integration-arquillian/servers/auth-server/pom.xml index 4c41461839..f16933cdaa 100644 --- a/testsuite/integration-arquillian/servers/auth-server/pom.xml +++ b/testsuite/integration-arquillian/servers/auth-server/pom.xml @@ -39,5 +39,14 @@ jboss undertow + + + + quarkus + + quarkus + + + diff --git a/testsuite/integration-arquillian/servers/auth-server/quarkus/assembly.xml b/testsuite/integration-arquillian/servers/auth-server/quarkus/assembly.xml new file mode 100644 index 0000000000..98ca007188 --- /dev/null +++ b/testsuite/integration-arquillian/servers/auth-server/quarkus/assembly.xml @@ -0,0 +1,46 @@ + + + + + quarkus + + + zip + + + false + + + + ${auth.server.home} + auth-server-quarkus + + **/*.sh + + + + ${auth.server.home} + auth-server-quarkus + + **/*.sh + + 0755 + + + + diff --git a/testsuite/integration-arquillian/servers/auth-server/quarkus/pom.xml b/testsuite/integration-arquillian/servers/auth-server/quarkus/pom.xml new file mode 100644 index 0000000000..edc90a594f --- /dev/null +++ b/testsuite/integration-arquillian/servers/auth-server/quarkus/pom.xml @@ -0,0 +1,107 @@ + + + + integration-arquillian-servers-auth-server + org.keycloak.testsuite + 9.0.1-SNAPSHOT + + 4.0.0 + + Auth Server - Quarkus + integration-arquillian-servers-auth-server-quarkus + + + ${project.build.directory}/unpacked/keycloak.x-${project.version} + + + + + + maven-resources-plugin + + + copy-conf + process-resources + + copy-resources + + + ${auth.server.home}/conf + + + src/main/content/conf + + ** + + + + true + + + + + + maven-dependency-plugin + + + unpack-server-or-overlay + generate-resources + + unpack + + + + + org.keycloak + keycloak-server-x + ${project.version} + zip + ${project.build.directory}/unpacked + + + + + + copy-testsuite-providers + generate-resources + + copy + + + + + org.keycloak.testsuite + integration-arquillian-testsuite-providers + ${project.version} + jar + false + ${auth.server.home}/providers + + + + + + + + maven-assembly-plugin + + + create-zip + package + + single + + + + assembly.xml + + false + + + + + + + \ No newline at end of file diff --git a/testsuite/integration-arquillian/servers/auth-server/quarkus/src/.dont-delete b/testsuite/integration-arquillian/servers/auth-server/quarkus/src/.dont-delete new file mode 100644 index 0000000000..63f93b0dd0 --- /dev/null +++ b/testsuite/integration-arquillian/servers/auth-server/quarkus/src/.dont-delete @@ -0,0 +1 @@ +This file is to mark this Maven project as a valid option for building auth server artifact diff --git a/testsuite/integration-arquillian/servers/auth-server/quarkus/src/main/content/conf/cluster.xml b/testsuite/integration-arquillian/servers/auth-server/quarkus/src/main/content/conf/cluster.xml new file mode 100644 index 0000000000..17347704f9 --- /dev/null +++ b/testsuite/integration-arquillian/servers/auth-server/quarkus/src/main/content/conf/cluster.xml @@ -0,0 +1,104 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/arquillian/containers/KeycloakQuarkusConfiguration.java b/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/arquillian/containers/KeycloakQuarkusConfiguration.java new file mode 100644 index 0000000000..65a793ac62 --- /dev/null +++ b/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/arquillian/containers/KeycloakQuarkusConfiguration.java @@ -0,0 +1,37 @@ +package org.keycloak.testsuite.arquillian.containers; + +import org.jboss.arquillian.container.spi.ConfigurationException; +import org.jboss.arquillian.container.spi.client.container.ContainerConfiguration; + +import java.nio.file.Path; +import java.nio.file.Paths; + +/** + * @author mhajas + */ +public class KeycloakQuarkusConfiguration implements ContainerConfiguration { + + private Path providersPath = Paths.get(System.getProperty("auth.server.home")); + private int startupTimeoutInSeconds = 60; + + @Override + public void validate() throws ConfigurationException { + + } + + public Path getProvidersPath() { + return providersPath; + } + + public void setProvidersPath(Path providersPath) { + this.providersPath = providersPath; + } + + public int getStartupTimeoutInSeconds() { + return startupTimeoutInSeconds; + } + + public void setStartupTimeoutInSeconds(int startupTimeoutInSeconds) { + this.startupTimeoutInSeconds = startupTimeoutInSeconds; + } +} diff --git a/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/arquillian/containers/KeycloakQuarkusServerDeployableContainer.java b/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/arquillian/containers/KeycloakQuarkusServerDeployableContainer.java new file mode 100644 index 0000000000..11b44d85f3 --- /dev/null +++ b/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/arquillian/containers/KeycloakQuarkusServerDeployableContainer.java @@ -0,0 +1,155 @@ +package org.keycloak.testsuite.arquillian.containers; + +import java.io.File; +import java.io.IOException; +import java.net.HttpURLConnection; +import java.net.MalformedURLException; +import java.net.URL; +import java.util.ArrayList; +import java.util.List; +import java.util.concurrent.TimeUnit; + +import org.jboss.arquillian.container.spi.client.container.DeployableContainer; +import org.jboss.arquillian.container.spi.client.container.DeploymentException; +import org.jboss.arquillian.container.spi.client.container.LifecycleException; +import org.jboss.arquillian.container.spi.client.protocol.ProtocolDescription; +import org.jboss.arquillian.container.spi.client.protocol.metadata.ProtocolMetaData; +import org.jboss.arquillian.core.api.Instance; +import org.jboss.arquillian.core.api.annotation.Inject; +import org.jboss.logging.Logger; +import org.jboss.shrinkwrap.api.Archive; +import org.jboss.shrinkwrap.descriptor.api.Descriptor; +import org.keycloak.testsuite.arquillian.AuthServerTestEnricher; +import org.keycloak.testsuite.arquillian.SuiteContext; + +/** + * @author mhajas + */ +public class KeycloakQuarkusServerDeployableContainer implements DeployableContainer { + + protected static final Logger log = Logger.getLogger(KeycloakQuarkusServerDeployableContainer.class); + + private KeycloakQuarkusConfiguration configuration; + private Process container; + + @Inject + private Instance suiteContext; + + @Override + public Class getConfigurationClass() { + return KeycloakQuarkusConfiguration.class; + } + + @Override + public void setup(KeycloakQuarkusConfiguration configuration) { + this.configuration = configuration; + } + + @Override + public void start() throws LifecycleException { + try { + container = startContainer(); + waitForReadiness(); + } catch (Exception e) { + throw new RuntimeException(e); + } + } + + @Override + public void stop() throws LifecycleException { + container.destroy(); + } + + @Override + public ProtocolDescription getDefaultProtocol() { + return null; + } + + @Override + public ProtocolMetaData deploy(Archive archive) throws DeploymentException { + return null; + } + + @Override + public void undeploy(Archive archive) throws DeploymentException { + + } + + @Override + public void deploy(Descriptor descriptor) throws DeploymentException { + + } + + @Override + public void undeploy(Descriptor descriptor) throws DeploymentException { + + } + + private Process startContainer() throws IOException { + if (AuthServerTestEnricher.AUTH_SERVER_SSL_REQUIRED) { + throw new IllegalStateException("Quarkus server does not yet support SSL"); + } + + ProcessBuilder pb = new ProcessBuilder(getProcessCommands()); + File wrkDir = configuration.getProvidersPath().resolve("bin").toAbsolutePath().toFile(); + ProcessBuilder builder = pb.directory(wrkDir).inheritIO(); + + builder.environment().put("KEYCLOAK_ADMIN", "admin"); + builder.environment().put("KEYCLOAK_ADMIN_PASSWORD", "admin"); + + return builder.start(); + } + + private String[] getProcessCommands() { + List commands = new ArrayList<>(); + + commands.add("./kc.sh"); + + if (Boolean.valueOf(System.getProperty("auth.server.debug", "false"))) { + commands.add("--debug"); + commands.add(System.getProperty("auth.server.debug.port", "5005")); + } + + commands.add("-Dquarkus.http.port=" + suiteContext.get().getAuthServerInfo().getContextRoot().getPort()); + + return commands.toArray(new String[commands.size()]); + } + + private void waitForReadiness() throws MalformedURLException, LifecycleException { + SuiteContext suiteContext = this.suiteContext.get(); + //TODO: not sure if the best endpoint but it makes sure that everything is properly initialized. Once we have + // support for MP Health this should change + URL contextRoot = new URL(suiteContext.getAuthServerInfo().getContextRoot() + "/auth/realms/master/"); + HttpURLConnection connection; + + long startTime = System.currentTimeMillis(); + + while (true) { + if (System.currentTimeMillis() - startTime > getStartTimeout()) { + stop(); + throw new IllegalStateException("Timeout [" + getStartTimeout() + "] while waiting for Quarkus server"); + } + + try { + connection = (HttpURLConnection) contextRoot.openConnection(); + + connection.setReadTimeout((int) getStartTimeout()); + connection.setConnectTimeout((int) getStartTimeout()); + connection.connect(); + + if (connection.getResponseCode() == 200) { + break; + } + + connection.disconnect(); + } catch (Exception ignore) { + } + } + + log.infof("Keycloak is ready at %s", this.suiteContext.get().getAuthServerInfo().getContextRoot()); + } + + private long getStartTimeout() { + return TimeUnit.SECONDS.toMillis(configuration.getStartupTimeoutInSeconds()); + } +} diff --git a/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/arquillian/containers/MultipleContainersExtension.java b/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/arquillian/containers/MultipleContainersExtension.java index 4bd72f58c2..c2ec2af176 100644 --- a/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/arquillian/containers/MultipleContainersExtension.java +++ b/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/arquillian/containers/MultipleContainersExtension.java @@ -22,6 +22,7 @@ import org.jboss.arquillian.container.impl.client.container.DeploymentExceptionH import org.jboss.arquillian.container.impl.client.deployment.ArchiveDeploymentExporter; import org.jboss.arquillian.container.impl.context.ContainerContextImpl; import org.jboss.arquillian.container.impl.context.DeploymentContextImpl; +import org.jboss.arquillian.container.spi.client.container.DeployableContainer; import org.jboss.arquillian.core.spi.LoadableExtension; import java.util.logging.Logger; @@ -42,6 +43,8 @@ public class MultipleContainersExtension implements LoadableExtension { logger.info("Multiple containers extension registering."); + builder.service(DeployableContainer.class, KeycloakQuarkusServerDeployableContainer.class); + builder.context(ContainerContextImpl.class).context(DeploymentContextImpl.class); builder.observer(RegistryCreator.class) diff --git a/testsuite/integration-arquillian/tests/base/src/test/resources/arquillian.xml b/testsuite/integration-arquillian/tests/base/src/test/resources/arquillian.xml index 2e54ca5a22..f56f9bed90 100644 --- a/testsuite/integration-arquillian/tests/base/src/test/resources/arquillian.xml +++ b/testsuite/integration-arquillian/tests/base/src/test/resources/arquillian.xml @@ -585,6 +585,13 @@ + + + ${auth.server.quarkus} + org.keycloak.testsuite.arquillian.containers.KeycloakQuarkusServerDeployableContainer + + + diff --git a/testsuite/integration-arquillian/tests/pom.xml b/testsuite/integration-arquillian/tests/pom.xml index d833f6598f..eb98637b72 100755 --- a/testsuite/integration-arquillian/tests/pom.xml +++ b/testsuite/integration-arquillian/tests/pom.xml @@ -82,6 +82,8 @@ -agentlib:jdwp=transport=dt_socket,server=y,suspend=${auth.server.debug.suspend},address=${auth.server.host}:${auth.server.debug.port} false + false + @@ -487,6 +489,7 @@ ${backend.console.output} ${auth.server.remote} + ${auth.server.quarkus} ${adapter.test.props} ${examples.home} @@ -660,6 +663,16 @@ + + auth-server-quarkus + + quarkus + true + false + false + + + auth-server-wildfly