[KEYCLOAK-11345] - Test basic features of Keycloak.X with current tetsuite

This commit is contained in:
Pedro Igor 2020-03-06 10:29:55 -03:00 committed by Stian Thorgersen
parent 097a9b6e2e
commit b7a395a3ef
16 changed files with 529 additions and 2 deletions

View file

@ -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"

View file

@ -55,6 +55,12 @@
<dependency>
<groupId>org.infinispan</groupId>
<artifactId>infinispan-core</artifactId>
<version>${infinispan.version}</version>
</dependency>
<dependency>
<groupId>org.infinispan</groupId>
<artifactId>infinispan-commons</artifactId>
<version>${infinispan.version}</version>
</dependency>
<dependency>
<groupId>io.quarkus</groupId>

View file

@ -402,6 +402,22 @@
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>com.sun.mail</groupId>
<artifactId>jakarta.mail</artifactId>
<version>${jakarta.mail.version}</version>
</dependency>
<dependency>
<groupId>org.apache.santuario</groupId>
<artifactId>xmlsec</artifactId>
<version>${xmlsec.version}</version>
<exclusions>
<exclusion>
<groupId>com.fasterxml.woodstox</groupId>
<artifactId>woodstox-core</artifactId>
</exclusion>
</exclusions>
</dependency>
</dependencies>
<build>

View file

@ -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

View file

@ -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;

View file

@ -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.

View file

@ -39,5 +39,14 @@
<module>jboss</module>
<module>undertow</module>
</modules>
<profiles>
<profile>
<id>quarkus</id>
<modules>
<module>quarkus</module>
</modules>
</profile>
</profiles>
</project>

View file

@ -0,0 +1,46 @@
<!--
~ Copyright 2016 Red Hat, Inc. and/or its affiliates
~ and other contributors as indicated by the @author tags.
~
~ Licensed under the Apache License, Version 2.0 (the "License");
~ you may not use this file except in compliance with the License.
~ You may obtain a copy of the License at
~
~ http://www.apache.org/licenses/LICENSE-2.0
~
~ Unless required by applicable law or agreed to in writing, software
~ distributed under the License is distributed on an "AS IS" BASIS,
~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
~ See the License for the specific language governing permissions and
~ limitations under the License.
-->
<assembly>
<id>quarkus</id>
<formats>
<format>zip</format>
</formats>
<includeBaseDirectory>false</includeBaseDirectory>
<fileSets>
<fileSet>
<directory>${auth.server.home}</directory>
<outputDirectory>auth-server-quarkus</outputDirectory>
<excludes>
<exclude>**/*.sh</exclude>
</excludes>
</fileSet>
<fileSet>
<directory>${auth.server.home}</directory>
<outputDirectory>auth-server-quarkus</outputDirectory>
<includes>
<include>**/*.sh</include>
</includes>
<fileMode>0755</fileMode>
</fileSet>
</fileSets>
</assembly>

View file

@ -0,0 +1,107 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>integration-arquillian-servers-auth-server</artifactId>
<groupId>org.keycloak.testsuite</groupId>
<version>9.0.1-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<name>Auth Server - Quarkus</name>
<artifactId>integration-arquillian-servers-auth-server-quarkus</artifactId>
<properties>
<auth.server.home>${project.build.directory}/unpacked/keycloak.x-${project.version}</auth.server.home>
</properties>
<build>
<plugins>
<plugin>
<artifactId>maven-resources-plugin</artifactId>
<executions>
<execution>
<id>copy-conf</id>
<phase>process-resources</phase>
<goals>
<goal>copy-resources</goal>
</goals>
<configuration>
<outputDirectory>${auth.server.home}/conf</outputDirectory>
<resources>
<resource>
<directory>src/main/content/conf</directory>
<includes>
<include>**</include>
</includes>
</resource>
</resources>
<overwrite>true</overwrite>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<artifactId>maven-dependency-plugin</artifactId>
<executions>
<execution>
<id>unpack-server-or-overlay</id>
<phase>generate-resources</phase>
<goals>
<goal>unpack</goal>
</goals>
<configuration>
<artifactItems>
<artifactItem>
<groupId>org.keycloak</groupId>
<artifactId>keycloak-server-x</artifactId>
<version>${project.version}</version>
<type>zip</type>
<outputDirectory>${project.build.directory}/unpacked</outputDirectory>
</artifactItem>
</artifactItems>
</configuration>
</execution>
<execution>
<id>copy-testsuite-providers</id>
<phase>generate-resources</phase>
<goals>
<goal>copy</goal>
</goals>
<configuration>
<artifactItems>
<artifactItem>
<groupId>org.keycloak.testsuite</groupId>
<artifactId>integration-arquillian-testsuite-providers</artifactId>
<version>${project.version}</version>
<type>jar</type>
<overWrite>false</overWrite>
<outputDirectory>${auth.server.home}/providers</outputDirectory>
</artifactItem>
</artifactItems>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<artifactId>maven-assembly-plugin</artifactId>
<executions>
<execution>
<id>create-zip</id>
<phase>package</phase>
<goals>
<goal>single</goal>
</goals>
<configuration>
<descriptors>
<descriptor>assembly.xml</descriptor>
</descriptors>
<appendAssemblyId>false</appendAssemblyId>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>

View file

@ -0,0 +1 @@
This file is to mark this Maven project as a valid option for building auth server artifact

View file

@ -0,0 +1,104 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
~ Copyright 2019 Red Hat, Inc. and/or its affiliates
~ and other contributors as indicated by the @author tags.
~
~ Licensed under the Apache License, Version 2.0 (the "License");
~ you may not use this file except in compliance with the License.
~ You may obtain a copy of the License at
~
~ http://www.apache.org/licenses/LICENSE-2.0
~
~ Unless required by applicable law or agreed to in writing, software
~ distributed under the License is distributed on an "AS IS" BASIS,
~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
~ See the License for the specific language governing permissions and
~ limitations under the License.
-->
<infinispan
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="urn:infinispan:config:9.4 http://www.infinispan.org/schemas/infinispan-config-9.4.xsd"
xmlns="urn:infinispan:config:9.4">
<!-- Distributed Cache Container Configuration
<cache-container name="keycloak">
<transport lock-timeout="60000"/>
<local-cache name="realms">
<memory>
<object size="10000"/>
</memory>
</local-cache>
<local-cache name="users">
<memory>
<object size="10000"/>
</memory>
</local-cache>
<distributed-cache name="sessions" owners="1"/>
<distributed-cache name="authenticationSessions" owners="1"/>
<distributed-cache name="offlineSessions" owners="1"/>
<distributed-cache name="clientSessions" owners="1"/>
<distributed-cache name="offlineClientSessions" owners="1"/>
<distributed-cache name="loginFailures" owners="1"/>
<local-cache name="authorization">
<memory>
<object size="10000"/>
</memory>
</local-cache>
<replicated-cache name="work"/>
<local-cache name="keys">
<expiration max-idle="3600000"/>
<memory>
<object size="1000"/>
</memory>
</local-cache>
<distributed-cache name="actionTokens" owners="2">
<expiration max-idle="-1" interval="300000"/>
<memory>
<object size="-1"/>
</memory>
</distributed-cache>
</cache-container>
-->
<!-- Local Cache Container Configuration -->
<cache-container name="keycloak">
<local-cache name="default">
<transaction transaction-manager-lookup="org.infinispan.transaction.lookup.JBossStandaloneJTAManagerLookup"/>
</local-cache>
<local-cache name="realms">
<memory>
<object size="10000"/>
</memory>
</local-cache>
<local-cache name="users">
<memory>
<object size="10000"/>
</memory>
</local-cache>
<local-cache name="sessions"/>
<local-cache name="authenticationSessions"/>
<local-cache name="offlineSessions"/>
<local-cache name="clientSessions"/>
<local-cache name="offlineClientSessions"/>
<local-cache name="loginFailures"/>
<local-cache name="work"/>
<local-cache name="authorization">
<memory>
<object size="10000"/>
</memory>
</local-cache>
<local-cache name="keys">
<expiration max-idle="3600000"/>
<memory>
<object size="10000"/>
</memory>
</local-cache>
<local-cache name="actionTokens">
<expiration max-idle="-1" interval="300000"/>
<memory>
<object size="-1"/>
</memory>
</local-cache>
</cache-container>
</infinispan>

View file

@ -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;
}
}

View file

@ -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<KeycloakQuarkusConfiguration> {
protected static final Logger log = Logger.getLogger(KeycloakQuarkusServerDeployableContainer.class);
private KeycloakQuarkusConfiguration configuration;
private Process container;
@Inject
private Instance<SuiteContext> suiteContext;
@Override
public Class<KeycloakQuarkusConfiguration> 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<String> 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());
}
}

View file

@ -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)

View file

@ -585,6 +585,13 @@
</configuration>
</container>
<container qualifier="auth-server-quarkus" mode="manual" >
<configuration>
<property name="enabled">${auth.server.quarkus}</property>
<property name="adapterImplClass">org.keycloak.testsuite.arquillian.containers.KeycloakQuarkusServerDeployableContainer</property>
</configuration>
</container>
<!-- PREVIOUS VERSION OF KEYCLOAK FOR MIGRATION TESTS -->
<container qualifier="auth-server-jboss-migration" mode="manual" >

View file

@ -82,6 +82,8 @@
<auth.server.jboss.jvm.debug.args>-agentlib:jdwp=transport=dt_socket,server=y,suspend=${auth.server.debug.suspend},address=${auth.server.host}:${auth.server.debug.port}</auth.server.jboss.jvm.debug.args>
<auth.server.remote>false</auth.server.remote>
<auth.server.quarkus>false</auth.server.quarkus>
<auth.server.profile/>
<auth.server.feature/>
@ -487,6 +489,7 @@
<backends.console.output>${backend.console.output}</backends.console.output>
<auth.server.remote>${auth.server.remote}</auth.server.remote>
<auth.server.quarkus>${auth.server.quarkus}</auth.server.quarkus>
<adapter.test.props>${adapter.test.props}</adapter.test.props>
<examples.home>${examples.home}</examples.home>
@ -660,6 +663,16 @@
</dependencies>
</profile>
<profile>
<id>auth-server-quarkus</id>
<properties>
<auth.server>quarkus</auth.server>
<auth.server.quarkus>true</auth.server.quarkus>
<auth.server.jboss>false</auth.server.jboss>
<auth.server.undertow>false</auth.server.undertow>
</properties>
</profile>
<profile>
<id>auth-server-wildfly</id>
<properties>