Merge pull request #3563 from mposolda/undertow-adapter-tests
KEYCLOAK-3124 Possibility test adapter on embedded undertow
This commit is contained in:
commit
659892edcb
23 changed files with 782 additions and 38 deletions
|
@ -16,6 +16,7 @@ env:
|
||||||
- TESTS=group1
|
- TESTS=group1
|
||||||
- TESTS=group2
|
- TESTS=group2
|
||||||
- TESTS=group3
|
- TESTS=group3
|
||||||
|
- TESTS=group4
|
||||||
- TESTS=adapter
|
- TESTS=adapter
|
||||||
|
|
||||||
jdk:
|
jdk:
|
||||||
|
|
|
@ -66,6 +66,14 @@
|
||||||
<artifactId>keycloak-dependencies-server-all</artifactId>
|
<artifactId>keycloak-dependencies-server-all</artifactId>
|
||||||
<type>pom</type>
|
<type>pom</type>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.keycloak</groupId>
|
||||||
|
<artifactId>keycloak-undertow-adapter</artifactId>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.keycloak</groupId>
|
||||||
|
<artifactId>keycloak-servlet-filter-adapter</artifactId>
|
||||||
|
</dependency>
|
||||||
</dependencies>
|
</dependencies>
|
||||||
|
|
||||||
</project>
|
</project>
|
||||||
|
|
|
@ -18,10 +18,13 @@
|
||||||
package org.keycloak.testsuite.arquillian.undertow;
|
package org.keycloak.testsuite.arquillian.undertow;
|
||||||
|
|
||||||
import io.undertow.Undertow;
|
import io.undertow.Undertow;
|
||||||
|
import io.undertow.server.handlers.PathHandler;
|
||||||
import io.undertow.servlet.Servlets;
|
import io.undertow.servlet.Servlets;
|
||||||
import io.undertow.servlet.api.DefaultServletConfig;
|
import io.undertow.servlet.api.DefaultServletConfig;
|
||||||
import io.undertow.servlet.api.DeploymentInfo;
|
import io.undertow.servlet.api.DeploymentInfo;
|
||||||
|
import io.undertow.servlet.api.DeploymentManager;
|
||||||
import io.undertow.servlet.api.FilterInfo;
|
import io.undertow.servlet.api.FilterInfo;
|
||||||
|
import io.undertow.servlet.api.ServletContainer;
|
||||||
import io.undertow.servlet.api.ServletInfo;
|
import io.undertow.servlet.api.ServletInfo;
|
||||||
import org.jboss.arquillian.container.spi.client.container.DeployableContainer;
|
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.DeploymentException;
|
||||||
|
@ -34,14 +37,20 @@ import org.jboss.logging.Logger;
|
||||||
import org.jboss.resteasy.plugins.server.undertow.UndertowJaxrsServer;
|
import org.jboss.resteasy.plugins.server.undertow.UndertowJaxrsServer;
|
||||||
import org.jboss.resteasy.spi.ResteasyDeployment;
|
import org.jboss.resteasy.spi.ResteasyDeployment;
|
||||||
import org.jboss.shrinkwrap.api.Archive;
|
import org.jboss.shrinkwrap.api.Archive;
|
||||||
|
import org.jboss.shrinkwrap.api.spec.WebArchive;
|
||||||
import org.jboss.shrinkwrap.descriptor.api.Descriptor;
|
import org.jboss.shrinkwrap.descriptor.api.Descriptor;
|
||||||
import org.jboss.shrinkwrap.undertow.api.UndertowWebArchive;
|
import org.jboss.shrinkwrap.undertow.api.UndertowWebArchive;
|
||||||
|
import org.keycloak.common.util.reflections.Reflections;
|
||||||
import org.keycloak.models.KeycloakSessionFactory;
|
import org.keycloak.models.KeycloakSessionFactory;
|
||||||
import org.keycloak.services.filters.KeycloakSessionServletFilter;
|
import org.keycloak.services.filters.KeycloakSessionServletFilter;
|
||||||
import org.keycloak.services.resources.KeycloakApplication;
|
import org.keycloak.services.resources.KeycloakApplication;
|
||||||
|
|
||||||
import javax.servlet.DispatcherType;
|
import javax.servlet.DispatcherType;
|
||||||
|
import javax.servlet.ServletException;
|
||||||
|
|
||||||
|
import java.lang.reflect.Field;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
|
import java.util.HashMap;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
public class KeycloakOnUndertow implements DeployableContainer<KeycloakOnUndertowConfiguration> {
|
public class KeycloakOnUndertow implements DeployableContainer<KeycloakOnUndertowConfiguration> {
|
||||||
|
@ -52,6 +61,8 @@ public class KeycloakOnUndertow implements DeployableContainer<KeycloakOnUnderto
|
||||||
private KeycloakOnUndertowConfiguration configuration;
|
private KeycloakOnUndertowConfiguration configuration;
|
||||||
private KeycloakSessionFactory sessionFactory;
|
private KeycloakSessionFactory sessionFactory;
|
||||||
|
|
||||||
|
Map<String, String> deployedArchivesToContextPath = new HashMap<>();
|
||||||
|
|
||||||
private DeploymentInfo createAuthServerDeploymentInfo() {
|
private DeploymentInfo createAuthServerDeploymentInfo() {
|
||||||
ResteasyDeployment deployment = new ResteasyDeployment();
|
ResteasyDeployment deployment = new ResteasyDeployment();
|
||||||
deployment.setApplicationClass(KeycloakApplication.class.getName());
|
deployment.setApplicationClass(KeycloakApplication.class.getName());
|
||||||
|
@ -75,6 +86,8 @@ public class KeycloakOnUndertow implements DeployableContainer<KeycloakOnUnderto
|
||||||
public DeploymentInfo getDeplotymentInfoFromArchive(Archive<?> archive) {
|
public DeploymentInfo getDeplotymentInfoFromArchive(Archive<?> archive) {
|
||||||
if (archive instanceof UndertowWebArchive) {
|
if (archive instanceof UndertowWebArchive) {
|
||||||
return ((UndertowWebArchive) archive).getDeploymentInfo();
|
return ((UndertowWebArchive) archive).getDeploymentInfo();
|
||||||
|
} else if (archive instanceof WebArchive) {
|
||||||
|
return new UndertowDeployerHelper().getDeploymentInfo(configuration, (WebArchive)archive);
|
||||||
} else {
|
} else {
|
||||||
throw new IllegalArgumentException("UndertowContainer only supports UndertowWebArchive or WebArchive.");
|
throw new IllegalArgumentException("UndertowContainer only supports UndertowWebArchive or WebArchive.");
|
||||||
}
|
}
|
||||||
|
@ -93,7 +106,19 @@ public class KeycloakOnUndertow implements DeployableContainer<KeycloakOnUnderto
|
||||||
@Override
|
@Override
|
||||||
public ProtocolMetaData deploy(Archive<?> archive) throws DeploymentException {
|
public ProtocolMetaData deploy(Archive<?> archive) throws DeploymentException {
|
||||||
DeploymentInfo di = getDeplotymentInfoFromArchive(archive);
|
DeploymentInfo di = getDeplotymentInfoFromArchive(archive);
|
||||||
undertow.deploy(di);
|
|
||||||
|
ClassLoader parentCl = Thread.currentThread().getContextClassLoader();
|
||||||
|
UndertowWarClassLoader classLoader = new UndertowWarClassLoader(parentCl, archive);
|
||||||
|
Thread.currentThread().setContextClassLoader(classLoader);
|
||||||
|
|
||||||
|
try {
|
||||||
|
undertow.deploy(di);
|
||||||
|
} finally {
|
||||||
|
Thread.currentThread().setContextClassLoader(parentCl);
|
||||||
|
}
|
||||||
|
|
||||||
|
deployedArchivesToContextPath.put(archive.getName(), di.getContextPath());
|
||||||
|
|
||||||
return new ProtocolMetaData().addContext(
|
return new ProtocolMetaData().addContext(
|
||||||
createHttpContextForDeploymentInfo(di));
|
createHttpContextForDeploymentInfo(di));
|
||||||
}
|
}
|
||||||
|
@ -151,7 +176,29 @@ public class KeycloakOnUndertow implements DeployableContainer<KeycloakOnUnderto
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void undeploy(Archive<?> archive) throws DeploymentException {
|
public void undeploy(Archive<?> archive) throws DeploymentException {
|
||||||
throw new UnsupportedOperationException("Not implemented");
|
Field containerField = Reflections.findDeclaredField(UndertowJaxrsServer.class, "container");
|
||||||
|
Reflections.setAccessible(containerField);
|
||||||
|
ServletContainer container = (ServletContainer) Reflections.getFieldValue(containerField, undertow);
|
||||||
|
|
||||||
|
DeploymentManager deployment = container.getDeployment(archive.getName());
|
||||||
|
if (deployment != null) {
|
||||||
|
try {
|
||||||
|
deployment.stop();
|
||||||
|
} catch (ServletException se) {
|
||||||
|
throw new DeploymentException(se.getMessage(), se);
|
||||||
|
}
|
||||||
|
|
||||||
|
deployment.undeploy();
|
||||||
|
|
||||||
|
Field rootField = Reflections.findDeclaredField(UndertowJaxrsServer.class, "root");
|
||||||
|
Reflections.setAccessible(rootField);
|
||||||
|
PathHandler root = (PathHandler) Reflections.getFieldValue(rootField, undertow);
|
||||||
|
|
||||||
|
String path = deployedArchivesToContextPath.get(archive.getName());
|
||||||
|
root.removePrefixPath(path);
|
||||||
|
} else {
|
||||||
|
log.warnf("Deployment '%s' not found", archive.getName());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -0,0 +1,254 @@
|
||||||
|
/*
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.keycloak.testsuite.arquillian.undertow;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.LinkedList;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
|
||||||
|
import javax.servlet.DispatcherType;
|
||||||
|
import javax.servlet.Filter;
|
||||||
|
import javax.servlet.Servlet;
|
||||||
|
|
||||||
|
import io.undertow.servlet.api.DeploymentInfo;
|
||||||
|
import io.undertow.servlet.api.FilterInfo;
|
||||||
|
import io.undertow.servlet.api.LoginConfig;
|
||||||
|
import io.undertow.servlet.api.SecurityConstraint;
|
||||||
|
import io.undertow.servlet.api.SecurityInfo;
|
||||||
|
import io.undertow.servlet.api.ServletInfo;
|
||||||
|
import io.undertow.servlet.api.WebResourceCollection;
|
||||||
|
import org.jboss.logging.Logger;
|
||||||
|
import org.w3c.dom.Document;
|
||||||
|
import org.w3c.dom.Element;
|
||||||
|
import org.w3c.dom.Node;
|
||||||
|
import org.w3c.dom.NodeList;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Simple web.xml parser just to handle our test deployments
|
||||||
|
*
|
||||||
|
* @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
|
||||||
|
*/
|
||||||
|
class SimpleWebXmlParser {
|
||||||
|
|
||||||
|
private static final Logger log = Logger.getLogger(SimpleWebXmlParser.class);
|
||||||
|
|
||||||
|
void parseWebXml(Document webXml, DeploymentInfo di) {
|
||||||
|
try {
|
||||||
|
DocumentWrapper document = new DocumentWrapper(webXml);
|
||||||
|
|
||||||
|
// SERVLETS
|
||||||
|
|
||||||
|
Map<String, String> servletMappings = new HashMap<>();
|
||||||
|
List<ElementWrapper> sm = document.getElementsByTagName("servlet-mapping");
|
||||||
|
for (ElementWrapper mapping : sm) {
|
||||||
|
String servletName = mapping.getElementByTagName("servlet-name").getText();
|
||||||
|
String path = mapping.getElementByTagName("url-pattern").getText();
|
||||||
|
servletMappings.put(servletName, path);
|
||||||
|
}
|
||||||
|
|
||||||
|
List<ElementWrapper> servlets = document.getElementsByTagName("servlet");
|
||||||
|
for (ElementWrapper servlet : servlets) {
|
||||||
|
String servletName = servlet.getElementByTagName("servlet-name").getText();
|
||||||
|
String servletClass = servlet.getElementByTagName("servlet-class").getText();
|
||||||
|
|
||||||
|
Class<? extends Servlet> servletClazz = (Class<? extends Servlet>) Class.forName(servletClass);
|
||||||
|
ServletInfo undertowServlet = new ServletInfo(servletName, servletClazz);
|
||||||
|
|
||||||
|
if (servletMappings.containsKey(servletName)) {
|
||||||
|
undertowServlet.addMapping(servletMappings.get(servletName));
|
||||||
|
di.addServlet(undertowServlet);
|
||||||
|
} else {
|
||||||
|
log.warnf("Missing servlet-mapping for '%s'", servletName);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// FILTERS
|
||||||
|
Map<String, String> filterMappings = new HashMap<>();
|
||||||
|
List<ElementWrapper> fm = document.getElementsByTagName("filter-mapping");
|
||||||
|
for (ElementWrapper mapping : fm) {
|
||||||
|
String filterName = mapping.getElementByTagName("filter-name").getText();
|
||||||
|
String path = mapping.getElementByTagName("url-pattern").getText();
|
||||||
|
filterMappings.put(filterName, path);
|
||||||
|
}
|
||||||
|
|
||||||
|
List<ElementWrapper> filters = document.getElementsByTagName("filter");
|
||||||
|
for (ElementWrapper filter : filters) {
|
||||||
|
String filterName = filter.getElementByTagName("filter-name").getText();
|
||||||
|
String filterClass = filter.getElementByTagName("filter-class").getText();
|
||||||
|
|
||||||
|
Class<? extends Filter> filterClazz = (Class<? extends Filter>) Class.forName(filterClass);
|
||||||
|
FilterInfo undertowFilter = new FilterInfo(filterName, filterClazz);
|
||||||
|
di.addFilter(undertowFilter);
|
||||||
|
|
||||||
|
if (filterMappings.containsKey(filterName)) {
|
||||||
|
di.addFilterUrlMapping(filterName, filterMappings.get(filterName), DispatcherType.REQUEST);
|
||||||
|
} else {
|
||||||
|
log.warnf("Missing filter-mapping for '%s'", filterName);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// CONTEXT PARAMS
|
||||||
|
List<ElementWrapper> contextParams = document.getElementsByTagName("context-param");
|
||||||
|
for (ElementWrapper param : contextParams) {
|
||||||
|
String paramName = param.getElementByTagName("param-name").getText();
|
||||||
|
String paramValue = param.getElementByTagName("param-value").getText();
|
||||||
|
di.addInitParameter(paramName, paramValue);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// ROLES
|
||||||
|
List<ElementWrapper> securityRoles = document.getElementsByTagName("security-role");
|
||||||
|
for (ElementWrapper sr : securityRoles) {
|
||||||
|
String roleName = sr.getElementByTagName("role-name").getText();
|
||||||
|
di.addSecurityRole(roleName);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// SECURITY CONSTRAINTS
|
||||||
|
List<ElementWrapper> secConstraints = document.getElementsByTagName("security-constraint");
|
||||||
|
for (ElementWrapper constraint : secConstraints) {
|
||||||
|
String urlPattern = constraint.getElementByTagName("web-resource-collection")
|
||||||
|
.getElementByTagName("url-pattern")
|
||||||
|
.getText();
|
||||||
|
|
||||||
|
ElementWrapper authCsnt = constraint.getElementByTagName("auth-constraint");
|
||||||
|
String roleName = authCsnt==null ? null : authCsnt
|
||||||
|
.getElementByTagName("role-name")
|
||||||
|
.getText();
|
||||||
|
|
||||||
|
SecurityConstraint undertowConstraint = new SecurityConstraint();
|
||||||
|
WebResourceCollection collection = new WebResourceCollection();
|
||||||
|
collection.addUrlPattern(urlPattern);
|
||||||
|
undertowConstraint.addWebResourceCollection(collection);
|
||||||
|
|
||||||
|
if (roleName != null) {
|
||||||
|
undertowConstraint.addRoleAllowed(roleName);
|
||||||
|
} else {
|
||||||
|
undertowConstraint.setEmptyRoleSemantic(SecurityInfo.EmptyRoleSemantic.PERMIT);
|
||||||
|
}
|
||||||
|
di.addSecurityConstraint(undertowConstraint);
|
||||||
|
}
|
||||||
|
|
||||||
|
// LOGIN CONFIG
|
||||||
|
ElementWrapper loginCfg = document.getElementByTagName("login-config");
|
||||||
|
if (loginCfg != null) {
|
||||||
|
String mech = loginCfg.getElementByTagName("auth-method").getText();
|
||||||
|
String realmName = loginCfg.getElementByTagName("realm-name").getText();
|
||||||
|
|
||||||
|
ElementWrapper form = loginCfg.getElementByTagName("form-login-config");
|
||||||
|
if (form != null) {
|
||||||
|
String loginPage = form.getElementByTagName("form-login-page").getText();
|
||||||
|
String errorPage = form.getElementByTagName("form-error-page").getText();
|
||||||
|
di.setLoginConfig(new LoginConfig(mech, realmName, loginPage, errorPage));
|
||||||
|
} else {
|
||||||
|
di.setLoginConfig(new LoginConfig(realmName).addFirstAuthMethod(mech));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
} catch (ClassNotFoundException cnfe) {
|
||||||
|
throw new RuntimeException(cnfe);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private static abstract class XmlWrapper {
|
||||||
|
|
||||||
|
|
||||||
|
abstract List<ElementWrapper> getElementsByTagName(String tagName);
|
||||||
|
|
||||||
|
|
||||||
|
abstract ElementWrapper getElementByTagName(String tagName);
|
||||||
|
|
||||||
|
|
||||||
|
List<ElementWrapper> getElementsFromNodeList(NodeList nl) {
|
||||||
|
List<ElementWrapper> result = new LinkedList<>();
|
||||||
|
|
||||||
|
for (int i=0; i<nl.getLength() ; i++) {
|
||||||
|
Node node = nl.item(i);
|
||||||
|
if (node instanceof Element) {
|
||||||
|
result.add(new ElementWrapper((Element) node));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
ElementWrapper getElementFromNodeList(NodeList nl) {
|
||||||
|
if (nl.getLength() > 0) {
|
||||||
|
return new ElementWrapper((Element) nl.item(0));
|
||||||
|
} else {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private static class ElementWrapper extends XmlWrapper {
|
||||||
|
|
||||||
|
private final Element element;
|
||||||
|
|
||||||
|
public ElementWrapper(Element element) {
|
||||||
|
this.element = element;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<ElementWrapper> getElementsByTagName(String tagName) {
|
||||||
|
NodeList nl = element.getElementsByTagName(tagName);
|
||||||
|
return getElementsFromNodeList(nl);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ElementWrapper getElementByTagName(String tagName) {
|
||||||
|
NodeList nl = element.getElementsByTagName(tagName);
|
||||||
|
return getElementFromNodeList(nl);
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getText() {
|
||||||
|
return this.element.getTextContent();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private static class DocumentWrapper extends XmlWrapper {
|
||||||
|
|
||||||
|
private final Document document;
|
||||||
|
|
||||||
|
public DocumentWrapper(Document document) {
|
||||||
|
this.document = document;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
List<ElementWrapper> getElementsByTagName(String tagName) {
|
||||||
|
NodeList nl = document.getElementsByTagName(tagName);
|
||||||
|
return getElementsFromNodeList(nl);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
ElementWrapper getElementByTagName(String tagName) {
|
||||||
|
NodeList nl = document.getElementsByTagName(tagName);
|
||||||
|
return getElementFromNodeList(nl);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,194 @@
|
||||||
|
/*
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.keycloak.testsuite.arquillian.undertow;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.InputStream;
|
||||||
|
import java.net.URL;
|
||||||
|
import java.net.URLConnection;
|
||||||
|
import java.net.URLStreamHandler;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
import javax.servlet.Servlet;
|
||||||
|
import javax.servlet.annotation.WebServlet;
|
||||||
|
import javax.xml.parsers.DocumentBuilder;
|
||||||
|
import javax.xml.parsers.DocumentBuilderFactory;
|
||||||
|
import javax.xml.parsers.ParserConfigurationException;
|
||||||
|
|
||||||
|
import io.undertow.UndertowMessages;
|
||||||
|
import io.undertow.server.handlers.resource.Resource;
|
||||||
|
import io.undertow.server.handlers.resource.ResourceChangeListener;
|
||||||
|
import io.undertow.server.handlers.resource.ResourceManager;
|
||||||
|
import io.undertow.server.handlers.resource.URLResource;
|
||||||
|
import io.undertow.servlet.api.DeploymentInfo;
|
||||||
|
import io.undertow.servlet.api.ServletInfo;
|
||||||
|
import org.jboss.logging.Logger;
|
||||||
|
import org.jboss.shrinkwrap.api.Archive;
|
||||||
|
import org.jboss.shrinkwrap.api.ArchivePath;
|
||||||
|
import org.jboss.shrinkwrap.api.Node;
|
||||||
|
import org.jboss.shrinkwrap.api.asset.ClassAsset;
|
||||||
|
import org.jboss.shrinkwrap.api.spec.WebArchive;
|
||||||
|
import org.w3c.dom.Document;
|
||||||
|
import org.xml.sax.SAXException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
|
||||||
|
*/
|
||||||
|
class UndertowDeployerHelper {
|
||||||
|
|
||||||
|
private static final Logger log = Logger.getLogger(UndertowDeployerHelper.class);
|
||||||
|
|
||||||
|
DeploymentInfo getDeploymentInfo(KeycloakOnUndertowConfiguration config, WebArchive archive) {
|
||||||
|
String archiveName = archive.getName();
|
||||||
|
String contextPath = "/" + archive.getName().substring(0, archive.getName().lastIndexOf('.'));
|
||||||
|
String appContextUrl = "http://" + config.getBindAddress() + ":" + config.getBindHttpPort() + contextPath;
|
||||||
|
|
||||||
|
try {
|
||||||
|
DeploymentInfo di = new DeploymentInfo();
|
||||||
|
|
||||||
|
UndertowWarClassLoader classLoader = new UndertowWarClassLoader(UndertowDeployerHelper.class.getClassLoader(), archive);
|
||||||
|
di.setClassLoader(classLoader);
|
||||||
|
|
||||||
|
di.setDeploymentName(archiveName);
|
||||||
|
di.setContextPath(contextPath);
|
||||||
|
|
||||||
|
ResourceManager undertowResourcesWrapper = getResourceManager(appContextUrl, archive);
|
||||||
|
di.setResourceManager(undertowResourcesWrapper);
|
||||||
|
|
||||||
|
if (archive.contains("/WEB-INF/web.xml")) {
|
||||||
|
Document webXml = loadXML(archive.get("/WEB-INF/web.xml").getAsset().openStream());
|
||||||
|
new SimpleWebXmlParser().parseWebXml(webXml, di);
|
||||||
|
}
|
||||||
|
|
||||||
|
addAnnotatedServlets(di, archive);
|
||||||
|
|
||||||
|
return di;
|
||||||
|
} catch (Exception ioe) {
|
||||||
|
throw new RuntimeException("Error deploying " + archive.getName(), ioe);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private ResourceManager getResourceManager(final String appServerRoot, final WebArchive archive) throws IOException {
|
||||||
|
return new ResourceManager() {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Resource getResource(String path) throws IOException {
|
||||||
|
if (path == null || path.isEmpty()) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
Node node = archive.get(path);
|
||||||
|
if (node == null) {
|
||||||
|
log.warnf("Application '%s' did not found resource on path %s", archive.getName(), path);
|
||||||
|
return null;
|
||||||
|
} else {
|
||||||
|
URL contextUrl = new URL(appServerRoot);
|
||||||
|
|
||||||
|
URL myResourceUrl = new URL(contextUrl.getProtocol(), contextUrl.getHost(), contextUrl.getPort(), path, new URLStreamHandler() {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected URLConnection openConnection(URL u) throws IOException {
|
||||||
|
return new URLConnection(u) {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void connect() throws IOException {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public InputStream getInputStream() throws IOException {
|
||||||
|
return node.getAsset().openStream();
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
return new URLResource(myResourceUrl, myResourceUrl.openConnection(), path);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isResourceChangeListenerSupported() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void registerResourceChangeListener(ResourceChangeListener listener) {
|
||||||
|
throw UndertowMessages.MESSAGES.resourceChangeListenerNotSupported();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void removeResourceChangeListener(ResourceChangeListener listener) {
|
||||||
|
throw UndertowMessages.MESSAGES.resourceChangeListenerNotSupported();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void close() throws IOException {
|
||||||
|
// TODO: Should close open streams?
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private Document loadXML(InputStream is) {
|
||||||
|
try {
|
||||||
|
DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
|
||||||
|
DocumentBuilder dBuilder = dbFactory.newDocumentBuilder();
|
||||||
|
return dBuilder.parse(is);
|
||||||
|
} catch (ParserConfigurationException | SAXException | IOException e) {
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private void addAnnotatedServlets(DeploymentInfo di, Archive<?> archive) {
|
||||||
|
Map<ArchivePath, Node> classNodes = archive.getContent((ArchivePath path) -> {
|
||||||
|
|
||||||
|
String stringPath = path.get();
|
||||||
|
return (stringPath.startsWith("/WEB-INF/classes") && stringPath.endsWith("class"));
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
for (Map.Entry<ArchivePath, Node> entry : classNodes.entrySet()) {
|
||||||
|
Node n = entry.getValue();
|
||||||
|
ClassAsset classAsset = (ClassAsset) n.getAsset();
|
||||||
|
Class<?> clazz = classAsset.getSource();
|
||||||
|
|
||||||
|
WebServlet annotation = clazz.getAnnotation(WebServlet.class);
|
||||||
|
if (annotation != null) {
|
||||||
|
ServletInfo undertowServlet = new ServletInfo(clazz.getSimpleName(), (Class<? extends Servlet>) clazz);
|
||||||
|
|
||||||
|
String[] mappings = annotation.value();
|
||||||
|
if (mappings != null) {
|
||||||
|
for (String urlPattern : mappings) {
|
||||||
|
undertowServlet.addMapping(urlPattern);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
di.addServlet(undertowServlet);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,61 @@
|
||||||
|
/*
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.keycloak.testsuite.arquillian.undertow;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
import java.io.InputStream;
|
||||||
|
|
||||||
|
import org.jboss.shrinkwrap.api.Archive;
|
||||||
|
import org.jboss.shrinkwrap.api.Node;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
|
||||||
|
*/
|
||||||
|
public class UndertowWarClassLoader extends ClassLoader {
|
||||||
|
|
||||||
|
private final Archive<?> archive;
|
||||||
|
|
||||||
|
public UndertowWarClassLoader(ClassLoader parent, Archive<?> archive) {
|
||||||
|
super(parent);
|
||||||
|
this.archive = archive;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public InputStream getResourceAsStream(String name) {
|
||||||
|
InputStream is = super.getResourceAsStream(name);
|
||||||
|
if (is == null) {
|
||||||
|
String resourcePath = "/WEB-INF/classes";
|
||||||
|
if (!name.startsWith("/")) {
|
||||||
|
resourcePath = resourcePath + "/";
|
||||||
|
}
|
||||||
|
resourcePath = resourcePath + name;
|
||||||
|
|
||||||
|
Node node = archive.get(resourcePath);
|
||||||
|
if (node == null) {
|
||||||
|
return null;
|
||||||
|
} else {
|
||||||
|
return node.getAsset().openStream();
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return is;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -18,6 +18,7 @@
|
||||||
package org.keycloak.testsuite.adapter.servlet;
|
package org.keycloak.testsuite.adapter.servlet;
|
||||||
|
|
||||||
import org.keycloak.KeycloakSecurityContext;
|
import org.keycloak.KeycloakSecurityContext;
|
||||||
|
import org.keycloak.common.util.UriUtils;
|
||||||
|
|
||||||
import javax.servlet.ServletException;
|
import javax.servlet.ServletException;
|
||||||
import javax.servlet.annotation.WebServlet;
|
import javax.servlet.annotation.WebServlet;
|
||||||
|
@ -50,13 +51,7 @@ public class CustomerServlet extends HttpServlet {
|
||||||
|
|
||||||
//Clear principal form database-service by calling logout
|
//Clear principal form database-service by calling logout
|
||||||
StringBuilder result = new StringBuilder();
|
StringBuilder result = new StringBuilder();
|
||||||
String urlBase;
|
String urlBase = ServletTestUtils.getUrlBase(req);
|
||||||
|
|
||||||
if (System.getProperty("app.server.ssl.required", "false").equals("true")) {
|
|
||||||
urlBase = System.getProperty("app.server.ssl.base.url", "https://localhost:8643");
|
|
||||||
} else {
|
|
||||||
urlBase = System.getProperty("app.server.base.url", "http://localhost:8280");
|
|
||||||
}
|
|
||||||
|
|
||||||
URL url = new URL(urlBase + "/customer-db/");
|
URL url = new URL(urlBase + "/customer-db/");
|
||||||
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
|
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
|
||||||
|
@ -78,13 +73,7 @@ public class CustomerServlet extends HttpServlet {
|
||||||
|
|
||||||
//try {
|
//try {
|
||||||
StringBuilder result = new StringBuilder();
|
StringBuilder result = new StringBuilder();
|
||||||
String urlBase;
|
String urlBase = ServletTestUtils.getUrlBase(req);
|
||||||
|
|
||||||
if (System.getProperty("app.server.ssl.required", "false").equals("true")) {
|
|
||||||
urlBase = System.getProperty("app.server.ssl.base.url", "https://localhost:8643");
|
|
||||||
} else {
|
|
||||||
urlBase = System.getProperty("app.server.base.url", "http://localhost:8280");
|
|
||||||
}
|
|
||||||
|
|
||||||
URL url = new URL(urlBase + "/customer-db/");
|
URL url = new URL(urlBase + "/customer-db/");
|
||||||
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
|
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
|
||||||
|
@ -114,4 +103,5 @@ public class CustomerServlet extends HttpServlet {
|
||||||
// client.close();
|
// client.close();
|
||||||
// }
|
// }
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,6 +18,7 @@
|
||||||
package org.keycloak.testsuite.adapter.servlet;
|
package org.keycloak.testsuite.adapter.servlet;
|
||||||
|
|
||||||
import org.junit.Assert;
|
import org.junit.Assert;
|
||||||
|
import org.keycloak.common.util.UriUtils;
|
||||||
|
|
||||||
import javax.servlet.ServletException;
|
import javax.servlet.ServletException;
|
||||||
import javax.servlet.annotation.WebServlet;
|
import javax.servlet.annotation.WebServlet;
|
||||||
|
@ -37,12 +38,7 @@ public class InputServlet extends HttpServlet {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
|
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
|
||||||
String appBase;
|
String appBase = ServletTestUtils.getUrlBase(req);
|
||||||
if (System.getProperty("app.server.ssl.required", "false").equals("true")) {
|
|
||||||
appBase = System.getProperty("app.server.ssl.base.url", "https://localhost:8643");
|
|
||||||
} else {
|
|
||||||
appBase = System.getProperty("app.server.base.url", "http://localhost:8280");
|
|
||||||
}
|
|
||||||
String actionUrl = appBase + "/input-portal/secured/post";
|
String actionUrl = appBase + "/input-portal/secured/post";
|
||||||
|
|
||||||
if (req.getRequestURI().endsWith("insecure")) {
|
if (req.getRequestURI().endsWith("insecure")) {
|
||||||
|
@ -82,7 +78,7 @@ public class InputServlet extends HttpServlet {
|
||||||
|
|
||||||
resp.setContentType("text/plain");
|
resp.setContentType("text/plain");
|
||||||
PrintWriter pw = resp.getWriter();
|
PrintWriter pw = resp.getWriter();
|
||||||
pw.printf("parameter="+req.getParameter("parameter"));
|
pw.printf("parameter=" + req.getParameter("parameter"));
|
||||||
pw.flush();
|
pw.flush();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -13,9 +13,6 @@ import java.io.IOException;
|
||||||
*/
|
*/
|
||||||
public class OfflineTokenServlet extends AbstractShowTokensServlet {
|
public class OfflineTokenServlet extends AbstractShowTokensServlet {
|
||||||
|
|
||||||
private static final String OFFLINE_CLIENT_APP_URI = (System.getProperty("app.server.ssl.required", "false").equals("true")) ?
|
|
||||||
System.getProperty("app.server.ssl.base.url", "https://localhost:8643") + "/offline-client" :
|
|
||||||
System.getProperty("app.server.base.url", "http://localhost:8280") + "/offline-client";
|
|
||||||
private static final String ADAPTER_ROOT_URL = (System.getProperty("auth.server.ssl.required", "false").equals("true")) ?
|
private static final String ADAPTER_ROOT_URL = (System.getProperty("auth.server.ssl.required", "false").equals("true")) ?
|
||||||
System.getProperty("auth.server.ssl.base.url", "https://localhost:8543") :
|
System.getProperty("auth.server.ssl.base.url", "https://localhost:8543") :
|
||||||
System.getProperty("auth.server.base.url", "http://localhost:8180");
|
System.getProperty("auth.server.base.url", "http://localhost:8180");
|
||||||
|
@ -25,7 +22,7 @@ public class OfflineTokenServlet extends AbstractShowTokensServlet {
|
||||||
|
|
||||||
if (req.getRequestURI().endsWith("logout")) {
|
if (req.getRequestURI().endsWith("logout")) {
|
||||||
|
|
||||||
UriBuilder redirectUriBuilder = UriBuilder.fromUri(OFFLINE_CLIENT_APP_URI);
|
UriBuilder redirectUriBuilder = UriBuilder.fromUri(ServletTestUtils.getUrlBase(req) + "/offline-client");
|
||||||
if (req.getParameter(OAuth2Constants.SCOPE) != null) {
|
if (req.getParameter(OAuth2Constants.SCOPE) != null) {
|
||||||
redirectUriBuilder.queryParam(OAuth2Constants.SCOPE, req.getParameter(OAuth2Constants.SCOPE));
|
redirectUriBuilder.queryParam(OAuth2Constants.SCOPE, req.getParameter(OAuth2Constants.SCOPE));
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,48 @@
|
||||||
|
/*
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.keycloak.testsuite.adapter.servlet;
|
||||||
|
|
||||||
|
import javax.servlet.http.HttpServletRequest;
|
||||||
|
|
||||||
|
import org.keycloak.common.util.UriUtils;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
|
||||||
|
*/
|
||||||
|
public class ServletTestUtils {
|
||||||
|
|
||||||
|
// TODO: Couldn't just always read urlBase from req.getRequestURI() ?
|
||||||
|
public static String getUrlBase(HttpServletRequest req) {
|
||||||
|
if (System.getProperty("app.server.ssl.required", "false").equals("true")) {
|
||||||
|
return System.getProperty("app.server.ssl.base.url", "https://localhost:8643");
|
||||||
|
}
|
||||||
|
|
||||||
|
String urlBase = System.getProperty("app.server.base.url");
|
||||||
|
|
||||||
|
if (urlBase == null) {
|
||||||
|
String authServer = System.getProperty("auth.server.container", "auth-server-undertow");
|
||||||
|
if (authServer.contains("undertow")) {
|
||||||
|
urlBase = UriUtils.getOrigin(req.getRequestURL().toString());
|
||||||
|
} else {
|
||||||
|
urlBase = "http://localhost:8280";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return urlBase;
|
||||||
|
}
|
||||||
|
}
|
|
@ -40,6 +40,9 @@
|
||||||
<exclude.client>-</exclude.client>
|
<exclude.client>-</exclude.client>
|
||||||
<!--exclude cluster tests by default, enabled by 'auth-server-*-cluster' profiles in tests/pom.xml-->
|
<!--exclude cluster tests by default, enabled by 'auth-server-*-cluster' profiles in tests/pom.xml-->
|
||||||
<exclude.cluster>**/cluster/**/*Test.java</exclude.cluster>
|
<exclude.cluster>**/cluster/**/*Test.java</exclude.cluster>
|
||||||
|
|
||||||
|
<!-- exclude undertow adapter tests. They can be added by -Dtest=org.keycloak.testsuite.adapter.undertow.**.*Test -->
|
||||||
|
<exclude.undertow.adapter>**/adapter/undertow/**/*Test.java</exclude.undertow.adapter>
|
||||||
</properties>
|
</properties>
|
||||||
|
|
||||||
<dependencies>
|
<dependencies>
|
||||||
|
@ -103,6 +106,7 @@
|
||||||
<exclude>${exclude.account}</exclude>
|
<exclude>${exclude.account}</exclude>
|
||||||
<exclude>${exclude.client}</exclude>
|
<exclude>${exclude.client}</exclude>
|
||||||
<exclude>${exclude.cluster}</exclude>
|
<exclude>${exclude.cluster}</exclude>
|
||||||
|
<exclude>${exclude.undertow.adapter}</exclude>
|
||||||
</excludes>
|
</excludes>
|
||||||
</configuration>
|
</configuration>
|
||||||
</plugin>
|
</plugin>
|
||||||
|
|
|
@ -43,6 +43,10 @@ public class ContainerInfo {
|
||||||
this.contextRoot = contextRoot;
|
this.contextRoot = contextRoot;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean isUndertow() {
|
||||||
|
return getQualifier().toLowerCase().contains("undertow");
|
||||||
|
}
|
||||||
|
|
||||||
public boolean isAS7() {
|
public boolean isAS7() {
|
||||||
return getQualifier().toLowerCase().contains("as7");
|
return getQualifier().toLowerCase().contains("as7");
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,7 +19,10 @@ package org.keycloak.testsuite.arquillian;
|
||||||
|
|
||||||
import org.apache.tools.ant.DirectoryScanner;
|
import org.apache.tools.ant.DirectoryScanner;
|
||||||
import org.jboss.arquillian.container.test.spi.client.deployment.ApplicationArchiveProcessor;
|
import org.jboss.arquillian.container.test.spi.client.deployment.ApplicationArchiveProcessor;
|
||||||
|
import org.jboss.arquillian.core.api.InstanceProducer;
|
||||||
|
import org.jboss.arquillian.core.api.annotation.Inject;
|
||||||
import org.jboss.arquillian.test.spi.TestClass;
|
import org.jboss.arquillian.test.spi.TestClass;
|
||||||
|
import org.jboss.arquillian.test.spi.annotation.ClassScoped;
|
||||||
import org.jboss.logging.Logger;
|
import org.jboss.logging.Logger;
|
||||||
import org.jboss.logging.Logger.Level;
|
import org.jboss.logging.Logger.Level;
|
||||||
import org.jboss.shrinkwrap.api.Archive;
|
import org.jboss.shrinkwrap.api.Archive;
|
||||||
|
@ -62,6 +65,10 @@ public class DeploymentArchiveProcessor implements ApplicationArchiveProcessor {
|
||||||
public static final String SAML_ADAPTER_CONFIG_PATH = "/WEB-INF/keycloak-saml.xml";
|
public static final String SAML_ADAPTER_CONFIG_PATH = "/WEB-INF/keycloak-saml.xml";
|
||||||
public static final String JBOSS_DEPLOYMENT_XML_PATH = "/WEB-INF/jboss-deployment-structure.xml";
|
public static final String JBOSS_DEPLOYMENT_XML_PATH = "/WEB-INF/jboss-deployment-structure.xml";
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
@ClassScoped
|
||||||
|
private InstanceProducer<TestContext> testContextProducer;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void process(Archive<?> archive, TestClass testClass) {
|
public void process(Archive<?> archive, TestClass testClass) {
|
||||||
log.info("Processing archive " + archive.getName());
|
log.info("Processing archive " + archive.getName());
|
||||||
|
@ -158,6 +165,12 @@ public class DeploymentArchiveProcessor implements ApplicationArchiveProcessor {
|
||||||
|
|
||||||
public void addFilterDependencies(Archive<?> archive, TestClass testClass) {
|
public void addFilterDependencies(Archive<?> archive, TestClass testClass) {
|
||||||
log.info("Adding filter dependencies to " + archive.getName());
|
log.info("Adding filter dependencies to " + archive.getName());
|
||||||
|
|
||||||
|
TestContext testContext = testContextProducer.get();
|
||||||
|
if (testContext.getAppServerInfo().isUndertow()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
String dependency = testClass.getAnnotation(UseServletFilter.class).filterDependency();
|
String dependency = testClass.getAnnotation(UseServletFilter.class).filterDependency();
|
||||||
((WebArchive) archive).addAsLibraries(KeycloakDependenciesResolver.resolveDependencies((dependency + ":" + System.getProperty("project.version"))));
|
((WebArchive) archive).addAsLibraries(KeycloakDependenciesResolver.resolveDependencies((dependency + ":" + System.getProperty("project.version"))));
|
||||||
|
|
||||||
|
|
|
@ -146,7 +146,7 @@ public abstract class AbstractKeycloakTest {
|
||||||
setDefaultPageUriParameters();
|
setDefaultPageUriParameters();
|
||||||
|
|
||||||
driverSettings();
|
driverSettings();
|
||||||
|
|
||||||
TestEventsLogger.setDriver(driver);
|
TestEventsLogger.setDriver(driver);
|
||||||
|
|
||||||
if (!suiteContext.isAdminPasswordUpdated()) {
|
if (!suiteContext.isAdminPasswordUpdated()) {
|
||||||
|
|
|
@ -126,7 +126,7 @@ public abstract class AbstractDemoServletsAdapterTest extends AbstractServletsAd
|
||||||
|
|
||||||
@Deployment(name = CustomerPortal.DEPLOYMENT_NAME)
|
@Deployment(name = CustomerPortal.DEPLOYMENT_NAME)
|
||||||
protected static WebArchive customerPortal() {
|
protected static WebArchive customerPortal() {
|
||||||
return servletDeployment(CustomerPortal.DEPLOYMENT_NAME, CustomerServlet.class, ErrorServlet.class);
|
return servletDeployment(CustomerPortal.DEPLOYMENT_NAME, CustomerServlet.class, ErrorServlet.class, ServletTestUtils.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Deployment(name = CustomerPortalNoConf.DEPLOYMENT_NAME)
|
@Deployment(name = CustomerPortalNoConf.DEPLOYMENT_NAME)
|
||||||
|
@ -156,7 +156,7 @@ public abstract class AbstractDemoServletsAdapterTest extends AbstractServletsAd
|
||||||
|
|
||||||
@Deployment(name = InputPortal.DEPLOYMENT_NAME)
|
@Deployment(name = InputPortal.DEPLOYMENT_NAME)
|
||||||
protected static WebArchive inputPortal() {
|
protected static WebArchive inputPortal() {
|
||||||
return servletDeployment(InputPortal.DEPLOYMENT_NAME, "keycloak.json", InputServlet.class);
|
return servletDeployment(InputPortal.DEPLOYMENT_NAME, "keycloak.json", InputServlet.class, ServletTestUtils.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Deployment(name = TokenMinTTLPage.DEPLOYMENT_NAME)
|
@Deployment(name = TokenMinTTLPage.DEPLOYMENT_NAME)
|
||||||
|
@ -194,7 +194,7 @@ public abstract class AbstractDemoServletsAdapterTest extends AbstractServletsAd
|
||||||
|
|
||||||
assertCurrentUrlStartsWithLoginUrlOf(testRealmPage);
|
assertCurrentUrlStartsWithLoginUrlOf(testRealmPage);
|
||||||
testRealmLoginPage.form().login("bburke@redhat.com", "password");
|
testRealmLoginPage.form().login("bburke@redhat.com", "password");
|
||||||
assertEquals(driver.getCurrentUrl(), inputPortal + "/secured/post");
|
assertCurrentUrlEquals(driver, inputPortal + "/secured/post");
|
||||||
String pageSource = driver.getPageSource();
|
String pageSource = driver.getPageSource();
|
||||||
assertTrue(pageSource.contains("parameter=hello"));
|
assertTrue(pageSource.contains("parameter=hello"));
|
||||||
|
|
||||||
|
@ -641,6 +641,8 @@ public abstract class AbstractDemoServletsAdapterTest extends AbstractServletsAd
|
||||||
String value = "hello";
|
String value = "hello";
|
||||||
Client client = ClientBuilder.newClient();
|
Client client = ClientBuilder.newClient();
|
||||||
|
|
||||||
|
//pause(1000000);
|
||||||
|
|
||||||
Response response = client.target(basicAuthPage
|
Response response = client.target(basicAuthPage
|
||||||
.setTemplateValues("mposolda", "password", value).buildUri()).request().get();
|
.setTemplateValues("mposolda", "password", value).buildUri()).request().get();
|
||||||
|
|
||||||
|
@ -797,7 +799,8 @@ public abstract class AbstractDemoServletsAdapterTest extends AbstractServletsAd
|
||||||
|
|
||||||
String serverLogPath = null;
|
String serverLogPath = null;
|
||||||
|
|
||||||
if (System.getProperty("app.server").equals("wildfly") || System.getProperty("app.server").equals("eap6") || System.getProperty("app.server").equals("eap")) {
|
String appServer = System.getProperty("app.server");
|
||||||
|
if (appServer != null && (appServer.equals("wildfly") || appServer.equals("eap6") || appServer.equals("eap"))) {
|
||||||
serverLogPath = System.getProperty("app.server.home") + "/standalone/log/server.log";
|
serverLogPath = System.getProperty("app.server.home") + "/standalone/log/server.log";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -27,6 +27,7 @@ import java.util.List;
|
||||||
import static org.keycloak.testsuite.auth.page.AuthRealm.TEST;
|
import static org.keycloak.testsuite.auth.page.AuthRealm.TEST;
|
||||||
import static org.keycloak.testsuite.util.IOUtil.loadRealm;
|
import static org.keycloak.testsuite.util.IOUtil.loadRealm;
|
||||||
import static org.keycloak.testsuite.util.URLAssert.assertCurrentUrlDoesntStartWith;
|
import static org.keycloak.testsuite.util.URLAssert.assertCurrentUrlDoesntStartWith;
|
||||||
|
import static org.keycloak.testsuite.util.URLAssert.assertCurrentUrlEquals;
|
||||||
import static org.keycloak.testsuite.util.URLAssert.assertCurrentUrlStartsWith;
|
import static org.keycloak.testsuite.util.URLAssert.assertCurrentUrlStartsWith;
|
||||||
import static org.keycloak.testsuite.util.WaitUtils.pause;
|
import static org.keycloak.testsuite.util.WaitUtils.pause;
|
||||||
import static org.keycloak.testsuite.util.WaitUtils.waitUntilElement;
|
import static org.keycloak.testsuite.util.WaitUtils.waitUntilElement;
|
||||||
|
@ -49,7 +50,7 @@ public abstract class AbstractOfflineServletsAdapterTest extends AbstractServlet
|
||||||
|
|
||||||
@Deployment(name = OfflineToken.DEPLOYMENT_NAME)
|
@Deployment(name = OfflineToken.DEPLOYMENT_NAME)
|
||||||
protected static WebArchive offlineClient() {
|
protected static WebArchive offlineClient() {
|
||||||
return servletDeployment(OfflineToken.DEPLOYMENT_NAME, AdapterActionsFilter.class, AbstractShowTokensServlet.class, OfflineTokenServlet.class, ErrorServlet.class);
|
return servletDeployment(OfflineToken.DEPLOYMENT_NAME, AdapterActionsFilter.class, AbstractShowTokensServlet.class, OfflineTokenServlet.class, ErrorServlet.class, ServletTestUtils.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -92,8 +93,10 @@ public abstract class AbstractOfflineServletsAdapterTest extends AbstractServlet
|
||||||
|
|
||||||
// Ensure that logout works for webapp (even if offline token will be still valid in Keycloak DB)
|
// Ensure that logout works for webapp (even if offline token will be still valid in Keycloak DB)
|
||||||
offlineTokenPage.logout();
|
offlineTokenPage.logout();
|
||||||
|
assertCurrentUrlDoesntStartWith(offlineTokenPage);
|
||||||
loginPage.assertCurrent();
|
loginPage.assertCurrent();
|
||||||
offlineTokenPage.navigateTo();
|
offlineTokenPage.navigateTo();
|
||||||
|
assertCurrentUrlDoesntStartWith(offlineTokenPage);
|
||||||
loginPage.assertCurrent();
|
loginPage.assertCurrent();
|
||||||
|
|
||||||
setAdapterAndServerTimeOffset(0);
|
setAdapterAndServerTimeOffset(0);
|
||||||
|
@ -177,6 +180,7 @@ public abstract class AbstractOfflineServletsAdapterTest extends AbstractServlet
|
||||||
|
|
||||||
//This was necessary to be introduced, otherwise other testcases will fail
|
//This was necessary to be introduced, otherwise other testcases will fail
|
||||||
offlineTokenPage.logout();
|
offlineTokenPage.logout();
|
||||||
|
assertCurrentUrlDoesntStartWith(offlineTokenPage);
|
||||||
loginPage.assertCurrent();
|
loginPage.assertCurrent();
|
||||||
|
|
||||||
events.clear();
|
events.clear();
|
||||||
|
|
|
@ -144,7 +144,7 @@ public abstract class AbstractSessionServletAdapterTest extends AbstractServlets
|
||||||
sessionPortalPage.navigateTo();
|
sessionPortalPage.navigateTo();
|
||||||
assertCurrentUrlStartsWithLoginUrlOf(testRealmPage);
|
assertCurrentUrlStartsWithLoginUrlOf(testRealmPage);
|
||||||
testRealmLoginPage.form().login("bburke@redhat.com", "password");
|
testRealmLoginPage.form().login("bburke@redhat.com", "password");
|
||||||
assertEquals(driver.getCurrentUrl(), sessionPortalPage.toString());
|
assertCurrentUrlEquals(sessionPortalPage);
|
||||||
String pageSource = driver.getPageSource();
|
String pageSource = driver.getPageSource();
|
||||||
assertTrue(pageSource.contains("Counter=1"));
|
assertTrue(pageSource.contains("Counter=1"));
|
||||||
|
|
||||||
|
@ -164,7 +164,7 @@ public abstract class AbstractSessionServletAdapterTest extends AbstractServlets
|
||||||
|
|
||||||
// bburke should be still logged with original httpSession in our browser window
|
// bburke should be still logged with original httpSession in our browser window
|
||||||
sessionPortalPage.navigateTo();
|
sessionPortalPage.navigateTo();
|
||||||
assertEquals(driver.getCurrentUrl(), sessionPortalPage.toString());
|
assertCurrentUrlEquals(sessionPortalPage);
|
||||||
String pageSource = driver.getPageSource();
|
String pageSource = driver.getPageSource();
|
||||||
assertTrue(pageSource.contains("Counter=3"));
|
assertTrue(pageSource.contains("Counter=3"));
|
||||||
String logoutUri = OIDCLoginProtocolService.logoutUrl(authServerPage.createUriBuilder())
|
String logoutUri = OIDCLoginProtocolService.logoutUrl(authServerPage.createUriBuilder())
|
||||||
|
@ -186,7 +186,7 @@ public abstract class AbstractSessionServletAdapterTest extends AbstractServlets
|
||||||
sessionPortalPage.navigateTo();
|
sessionPortalPage.navigateTo();
|
||||||
assertCurrentUrlStartsWithLoginUrlOf(testRealmPage);
|
assertCurrentUrlStartsWithLoginUrlOf(testRealmPage);
|
||||||
login.form().login("bburke@redhat.com", "password");
|
login.form().login("bburke@redhat.com", "password");
|
||||||
assertEquals(driver.getCurrentUrl(), sessionPortalPage.toString());
|
assertCurrentUrlEquals(sessionPortalPage);
|
||||||
String pageSource = driver.getPageSource();
|
String pageSource = driver.getPageSource();
|
||||||
assertTrue(pageSource.contains("Counter=1"));
|
assertTrue(pageSource.contains("Counter=1"));
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,28 @@
|
||||||
|
/*
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.keycloak.testsuite.adapter.undertow.servlet;
|
||||||
|
|
||||||
|
import org.keycloak.testsuite.adapter.servlet.AbstractDemoFilterServletAdapterTest;
|
||||||
|
import org.keycloak.testsuite.arquillian.annotation.AppServerContainer;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
|
||||||
|
*/
|
||||||
|
@AppServerContainer("auth-server-undertow")
|
||||||
|
public class UndertowDemoFilterServletAdapterTest extends AbstractDemoFilterServletAdapterTest {
|
||||||
|
}
|
|
@ -0,0 +1,28 @@
|
||||||
|
/*
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.keycloak.testsuite.adapter.undertow.servlet;
|
||||||
|
|
||||||
|
import org.keycloak.testsuite.adapter.servlet.AbstractDemoServletsAdapterTest;
|
||||||
|
import org.keycloak.testsuite.arquillian.annotation.AppServerContainer;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
|
||||||
|
*/
|
||||||
|
@AppServerContainer("auth-server-undertow")
|
||||||
|
public class UndertowDemoServletsAdapterTest extends AbstractDemoServletsAdapterTest {
|
||||||
|
}
|
|
@ -0,0 +1,28 @@
|
||||||
|
/*
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.keycloak.testsuite.adapter.undertow.servlet;
|
||||||
|
|
||||||
|
import org.keycloak.testsuite.adapter.servlet.AbstractOfflineServletsAdapterTest;
|
||||||
|
import org.keycloak.testsuite.arquillian.annotation.AppServerContainer;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
|
||||||
|
*/
|
||||||
|
@AppServerContainer("auth-server-undertow")
|
||||||
|
public class UndertowOfflineServletsAdapterTest extends AbstractOfflineServletsAdapterTest {
|
||||||
|
}
|
|
@ -0,0 +1,28 @@
|
||||||
|
/*
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.keycloak.testsuite.adapter.undertow.servlet;
|
||||||
|
|
||||||
|
import org.keycloak.testsuite.adapter.servlet.AbstractSessionServletAdapterTest;
|
||||||
|
import org.keycloak.testsuite.arquillian.annotation.AppServerContainer;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
|
||||||
|
*/
|
||||||
|
@AppServerContainer("auth-server-undertow")
|
||||||
|
public class UndertowSessionServletAdapterTest extends AbstractSessionServletAdapterTest {
|
||||||
|
}
|
|
@ -56,6 +56,11 @@ public class URLAssert {
|
||||||
currentUrlEqual(driver, page.toString()));
|
currentUrlEqual(driver, page.toString()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static void assertCurrentUrlEquals(WebDriver driver, final String url) {
|
||||||
|
assertTrue("Expected URL: " + url + "; actual: " + driver.getCurrentUrl(),
|
||||||
|
currentUrlEqual(driver, url));
|
||||||
|
}
|
||||||
|
|
||||||
public static void assertCurrentUrlStartsWith(AbstractPage page) {
|
public static void assertCurrentUrlStartsWith(AbstractPage page) {
|
||||||
assertCurrentUrlStartsWith(page.getDriver(), page.toString());
|
assertCurrentUrlStartsWith(page.getDriver(), page.toString());
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,19 +6,22 @@ fi
|
||||||
|
|
||||||
if [ $1 == "group1" ]; then
|
if [ $1 == "group1" ]; then
|
||||||
mvn test -B -f testsuite/integration-arquillian/tests/base -Dtest=org.keycloak.testsuite.a**.*Test
|
mvn test -B -f testsuite/integration-arquillian/tests/base -Dtest=org.keycloak.testsuite.a**.*Test
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ $1 == "group2" ]; then
|
||||||
mvn test -B -f testsuite/integration-arquillian/tests/base -Dtest=org.keycloak.testsuite.b**.*Test
|
mvn test -B -f testsuite/integration-arquillian/tests/base -Dtest=org.keycloak.testsuite.b**.*Test
|
||||||
mvn test -B -f testsuite/integration-arquillian/tests/base -Dtest=org.keycloak.testsuite.cli**.*Test
|
mvn test -B -f testsuite/integration-arquillian/tests/base -Dtest=org.keycloak.testsuite.cli**.*Test
|
||||||
mvn test -B -f testsuite/integration-arquillian/tests/base -Dtest=org.keycloak.testsuite.com**.*Test
|
mvn test -B -f testsuite/integration-arquillian/tests/base -Dtest=org.keycloak.testsuite.com**.*Test
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if [ $1 == "group2" ]; then
|
if [ $1 == "group3" ]; then
|
||||||
mvn test -B -f testsuite/integration-arquillian/tests/base -Dtest=org.keycloak.testsuite.d**.*Test
|
mvn test -B -f testsuite/integration-arquillian/tests/base -Dtest=org.keycloak.testsuite.d**.*Test
|
||||||
mvn test -B -f testsuite/integration-arquillian/tests/base -Dtest=org.keycloak.testsuite.e**.*Test
|
mvn test -B -f testsuite/integration-arquillian/tests/base -Dtest=org.keycloak.testsuite.e**.*Test
|
||||||
mvn test -B -f testsuite/integration-arquillian/tests/base -Dtest=org.keycloak.testsuite.f**.*Test
|
mvn test -B -f testsuite/integration-arquillian/tests/base -Dtest=org.keycloak.testsuite.f**.*Test
|
||||||
mvn test -B -f testsuite/integration-arquillian/tests/base -Dtest=org.keycloak.testsuite.i**.*Test
|
mvn test -B -f testsuite/integration-arquillian/tests/base -Dtest=org.keycloak.testsuite.i**.*Test
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if [ $1 == "group3" ]; then
|
if [ $1 == "group4" ]; then
|
||||||
mvn test -B -f testsuite/integration-arquillian/tests/base -Dtest=org.keycloak.testsuite.k**.*Test
|
mvn test -B -f testsuite/integration-arquillian/tests/base -Dtest=org.keycloak.testsuite.k**.*Test
|
||||||
mvn test -B -f testsuite/integration-arquillian/tests/base -Dtest=org.keycloak.testsuite.m**.*Test
|
mvn test -B -f testsuite/integration-arquillian/tests/base -Dtest=org.keycloak.testsuite.m**.*Test
|
||||||
mvn test -B -f testsuite/integration-arquillian/tests/base -Dtest=org.keycloak.testsuite.o**.*Test
|
mvn test -B -f testsuite/integration-arquillian/tests/base -Dtest=org.keycloak.testsuite.o**.*Test
|
||||||
|
|
Loading…
Reference in a new issue