keycloak-uncached
Changes
testsuite/integration-arquillian/servers/app-server/karaf/fuse63/src/main/resources/keycloak-direct-access.json 9(+9 -0)
testsuite/integration-arquillian/servers/app-server/karaf/fuse63/src/main/resources/keycloak-hawtio.json 9(+9 -0)
testsuite/integration-arquillian/servers/app-server/karaf/fuse63/src/main/resources/keycloak-hawtio-client.json 7(+7 -0)
testsuite/integration-arquillian/servers/app-server/karaf/fuse63/src/main/resources/update-config.cli 5(+5 -0)
testsuite/integration-arquillian/servers/app-server/karaf/fuse63/src/main/resources/update-config-auth.cli 8(+8 -0)
testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/arquillian/karaf/CustomKarafContainer.java 231(+231 -0)
testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/arquillian/KeycloakArquillianExtension.java 4(+3 -1)
testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/adapter/example/AbstractFuseAdminAdapterTest.java 258(+258 -0)
testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/adapter/example/AbstractFuseExampleAdapterTest.java 2(+1 -1)
Details
diff --git a/testsuite/integration-arquillian/servers/app-server/karaf/common/install-features.sh b/testsuite/integration-arquillian/servers/app-server/karaf/common/install-features.sh
index d094ff4..b8cba84 100755
--- a/testsuite/integration-arquillian/servers/app-server/karaf/common/install-features.sh
+++ b/testsuite/integration-arquillian/servers/app-server/karaf/common/install-features.sh
@@ -23,7 +23,7 @@ do
fi
if "$UPDATE_CONFIG" == "true"; then
- echo "Updating Config - org.ops4j.pax.url.mvn"
+ echo "Updating Config"
./client $CLIENT_AUTH -f update-config.cli
if [ $? -ne 0 ]; then
RESULT=1;
@@ -36,6 +36,14 @@ do
./client $CLIENT_AUTH -f install-features.cli
if [ $? -ne 0 ]; then RESULT=1; fi
+ if "$UPDATE_CONFIG" == "true"; then
+ echo "Updating Config - Keycloak authentication"
+ ./client $CLIENT_AUTH -f update-config-auth.cli
+ if [ $? -ne 0 ]; then
+ RESULT=1;
+ fi
+ fi
+
./stop
rm -rf ../data/log
rm -rf ../data/tmp
diff --git a/testsuite/integration-arquillian/servers/app-server/karaf/fuse63/pom.xml b/testsuite/integration-arquillian/servers/app-server/karaf/fuse63/pom.xml
index 80dfc56..a048eea 100644
--- a/testsuite/integration-arquillian/servers/app-server/karaf/fuse63/pom.xml
+++ b/testsuite/integration-arquillian/servers/app-server/karaf/fuse63/pom.xml
@@ -32,7 +32,7 @@
<properties>
<app.server.karaf>fuse63</app.server.karaf>
<app.server.karaf.groupId>org.jboss.fuse</app.server.karaf.groupId>
- <app.server.karaf.artifactId>jboss-fuse-full</app.server.karaf.artifactId>
+ <app.server.karaf.artifactId>jboss-fuse-karaf</app.server.karaf.artifactId>
<app.server.karaf.version>${fuse63.version}</app.server.karaf.version>
<app.server.karaf.unpacked.folder.name>jboss-fuse-${fuse63.version}</app.server.karaf.unpacked.folder.name>
<app.server.karaf.client.auth>-u admin -p admin</app.server.karaf.client.auth>
diff --git a/testsuite/integration-arquillian/servers/app-server/karaf/fuse63/src/main/resources/keycloak-direct-access.json b/testsuite/integration-arquillian/servers/app-server/karaf/fuse63/src/main/resources/keycloak-direct-access.json
new file mode 100644
index 0000000..2441134
--- /dev/null
+++ b/testsuite/integration-arquillian/servers/app-server/karaf/fuse63/src/main/resources/keycloak-direct-access.json
@@ -0,0 +1,9 @@
+{
+ "realm": "demo",
+ "resource": "ssh-jmx-admin-client",
+ "ssl-required" : "external",
+ "auth-server-url" : "http://localhost:8080/auth",
+ "credentials": {
+ "secret": "password"
+ }
+}
\ No newline at end of file
diff --git a/testsuite/integration-arquillian/servers/app-server/karaf/fuse63/src/main/resources/keycloak-hawtio.json b/testsuite/integration-arquillian/servers/app-server/karaf/fuse63/src/main/resources/keycloak-hawtio.json
new file mode 100644
index 0000000..36daac0
--- /dev/null
+++ b/testsuite/integration-arquillian/servers/app-server/karaf/fuse63/src/main/resources/keycloak-hawtio.json
@@ -0,0 +1,9 @@
+{
+ "realm" : "demo",
+ "resource" : "jaas",
+ "bearer-only" : true,
+ "auth-server-url" : "http://localhost:8080/auth",
+ "ssl-required" : "external",
+ "use-resource-role-mappings": false,
+ "principal-attribute": "preferred_username"
+}
\ No newline at end of file
diff --git a/testsuite/integration-arquillian/servers/app-server/karaf/fuse63/src/main/resources/keycloak-hawtio-client.json b/testsuite/integration-arquillian/servers/app-server/karaf/fuse63/src/main/resources/keycloak-hawtio-client.json
new file mode 100644
index 0000000..64d0d57
--- /dev/null
+++ b/testsuite/integration-arquillian/servers/app-server/karaf/fuse63/src/main/resources/keycloak-hawtio-client.json
@@ -0,0 +1,7 @@
+{
+ "realm" : "demo",
+ "resource" : "hawtio-client",
+ "auth-server-url" : "http://localhost:8080/auth",
+ "ssl-required" : "external",
+ "public-client" : true
+}
\ No newline at end of file
diff --git a/testsuite/integration-arquillian/servers/app-server/karaf/fuse63/src/main/resources/update-config.cli b/testsuite/integration-arquillian/servers/app-server/karaf/fuse63/src/main/resources/update-config.cli
index d6a425a..9a31940 100644
--- a/testsuite/integration-arquillian/servers/app-server/karaf/fuse63/src/main/resources/update-config.cli
+++ b/testsuite/integration-arquillian/servers/app-server/karaf/fuse63/src/main/resources/update-config.cli
@@ -3,3 +3,8 @@ config:propset org.ops4j.pax.url.mvn.localRepository ${maven.repo.local}
config:propset org.ops4j.pax.url.mvn.settings ${maven.local.settings}
config:propappend org.ops4j.pax.url.mvn.repositories ${repositories}
config:update
+config:edit jmx.acl.org.apache.karaf.security.jmx
+config:propappend list* viewer
+config:propappend set* jmxAdmin
+config:propappend * jmxAdmin,admin
+config:update
\ No newline at end of file
diff --git a/testsuite/integration-arquillian/servers/app-server/karaf/fuse63/src/main/resources/update-config-auth.cli b/testsuite/integration-arquillian/servers/app-server/karaf/fuse63/src/main/resources/update-config-auth.cli
new file mode 100644
index 0000000..2c3bc66
--- /dev/null
+++ b/testsuite/integration-arquillian/servers/app-server/karaf/fuse63/src/main/resources/update-config-auth.cli
@@ -0,0 +1,8 @@
+config:edit org.apache.karaf.shell
+config:propset sshRealm keycloak
+config:update
+system-property -p hawtio.roles admin,user
+system-property -p hawtio.keycloakEnabled true
+system-property -p hawtio.realm keycloak
+system-property -p hawtio.keycloakClientConfig \$\{karaf.base\}/etc/keycloak-hawtio-client.json
+system-property -p hawtio.rolePrincipalClasses org.keycloak.adapters.jaas.RolePrincipal,org.apache.karaf.jaas.boot.principal.RolePrincipal
diff --git a/testsuite/integration-arquillian/servers/app-server/karaf/pom.xml b/testsuite/integration-arquillian/servers/app-server/karaf/pom.xml
index ecff21a..b717b3d 100644
--- a/testsuite/integration-arquillian/servers/app-server/karaf/pom.xml
+++ b/testsuite/integration-arquillian/servers/app-server/karaf/pom.xml
@@ -117,6 +117,7 @@
<includes>
<include>install-features.cli</include>
<include>update-config.cli</include>
+ <include>update-config-auth.cli</include>
</includes>
<filtering>true</filtering>
</resource>
@@ -124,7 +125,7 @@
</configuration>
</execution>
<execution>
- <id>copy-users-properties</id>
+ <id>copy-configs</id>
<phase>process-resources</phase>
<goals>
<goal>copy-resources</goal>
@@ -137,6 +138,9 @@
<directory>src/main/resources</directory>
<includes>
<include>users.properties</include>
+ <include>keycloak-direct-access.json</include>
+ <include>keycloak-hawtio-client.json</include>
+ <include>keycloak-hawtio.json</include>
</includes>
</resource>
</resources>
diff --git a/testsuite/integration-arquillian/tests/base/pom.xml b/testsuite/integration-arquillian/tests/base/pom.xml
index 198c0aa..58050dd 100644
--- a/testsuite/integration-arquillian/tests/base/pom.xml
+++ b/testsuite/integration-arquillian/tests/base/pom.xml
@@ -81,6 +81,26 @@
<artifactId>greenmail</artifactId>
<scope>compile</scope>
</dependency>
+ <dependency>
+ <groupId>org.jboss.arquillian.container</groupId>
+ <artifactId>arquillian-container-karaf-managed</artifactId>
+ <version>2.1.0.CR18</version>
+ </dependency>
+ <dependency>
+ <groupId>org.jboss.arquillian.container</groupId>
+ <artifactId>arquillian-container-osgi</artifactId>
+ <version>2.1.0.CR18</version>
+ </dependency>
+ <dependency>
+ <groupId>org.osgi</groupId>
+ <artifactId>org.osgi.core</artifactId>
+ <scope>provided</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.osgi</groupId>
+ <artifactId>org.osgi.enterprise</artifactId>
+ <scope>provided</scope>
+ </dependency>
</dependencies>
<build>
diff --git a/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/arquillian/karaf/CustomKarafContainer.java b/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/arquillian/karaf/CustomKarafContainer.java
new file mode 100644
index 0000000..46f43a3
--- /dev/null
+++ b/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/arquillian/karaf/CustomKarafContainer.java
@@ -0,0 +1,231 @@
+package org.keycloak.testsuite.arquillian.karaf;
+
+import java.io.File;
+import java.io.FilenameFilter;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.TimeoutException;
+
+import javax.management.MBeanServerConnection;
+import javax.management.ObjectName;
+
+import org.jboss.arquillian.container.osgi.jmx.JMXDeployableContainer;
+import org.jboss.arquillian.container.osgi.jmx.ObjectNameFactory;
+import org.jboss.arquillian.container.osgi.karaf.managed.KarafManagedContainerConfiguration;
+import org.jboss.arquillian.container.spi.client.container.LifecycleException;
+import org.osgi.jmx.framework.BundleStateMBean;
+import org.osgi.jmx.framework.FrameworkMBean;
+import org.osgi.jmx.framework.ServiceStateMBean;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * KarafManagedDeployableContainer
+ *
+ * @author thomas.diesler@jboss.com
+ */
+public class CustomKarafContainer<T extends KarafManagedContainerConfiguration> extends JMXDeployableContainer<T> {
+
+ static final Logger _logger = LoggerFactory.getLogger(CustomKarafContainer.class.getPackage().getName());
+
+ private KarafManagedContainerConfiguration config;
+ private Process process;
+
+ @Override
+ public Class<T> getConfigurationClass() {
+ @SuppressWarnings("unchecked")
+ Class<T> clazz = (Class<T>) KarafManagedContainerConfiguration.class;
+ return clazz;
+ }
+
+ @Override
+ public void setup(T config) {
+ super.setup(config);
+ this.config = config;
+ }
+
+ @Override
+ public void start() throws LifecycleException {
+
+ // Try to connect to an already running server
+ MBeanServerConnection mbeanServer = null;
+ try {
+ mbeanServer = getMBeanServerConnection(500, TimeUnit.MILLISECONDS);
+ } catch (TimeoutException ex) {
+ // ignore
+ }
+
+ if (mbeanServer != null && !config.isAllowConnectingToRunningServer()) {
+ throw new LifecycleException(
+ "The server is already running! Managed containers does not support connecting to running server instances due to the " +
+ "possible harmful effect of connecting to the wrong server. Please stop server before running or change to another type of container.\n" +
+ "To disable this check and allow Arquillian to connect to a running server, set allowConnectingToRunningServer to true in the container configuration");
+ }
+
+ // Start the Karaf process
+ if (mbeanServer == null) {
+ String karafHome = config.getKarafHome();
+ if (karafHome == null)
+ throw new IllegalStateException("karafHome cannot be null");
+
+ File karafHomeDir = new File(karafHome).getAbsoluteFile();
+ if (!karafHomeDir.isDirectory())
+ throw new IllegalStateException("Not a valid Karaf home dir: " + karafHomeDir);
+
+ String java = System.getProperty("java.home") + File.separator + "bin" + File.separator + "java";
+ _logger.info(String.format("Using java: %s", java));
+
+ List<String> cmd = new ArrayList<String>();
+ cmd.add(java);
+
+ // JavaVM args
+ String javaArgs = config.getJavaVmArguments();
+ if (!javaArgs.contains("-Xmx")) {
+ javaArgs = KarafManagedContainerConfiguration.DEFAULT_JAVAVM_ARGUMENTS + " " + javaArgs;
+ }
+ cmd.addAll(Arrays.asList(javaArgs.split("\\s")));
+
+ // Karaf properties
+ cmd.add("-Dkaraf.home=" + karafHomeDir);
+ cmd.add("-Dkaraf.base=" + karafHomeDir);
+ cmd.add("-Dkaraf.etc=" + karafHomeDir + "/etc");
+ cmd.add("-Dkaraf.data=" + karafHomeDir + "/data");
+ cmd.add("-Dkaraf.instances=" + karafHomeDir + "/instances");
+ cmd.add("-Dkaraf.startLocalConsole=false");
+ cmd.add("-Dkaraf.startRemoteShell=true");
+
+ // Java properties
+ cmd.add("-Djava.io.tmpdir=" + new File(karafHomeDir, "data/tmp"));
+ cmd.add("-Djava.util.logging.config.file=" + new File(karafHomeDir, "etc/java.util.logging.properties"));
+ cmd.add("-Djava.endorsed.dirs=" + new File(karafHomeDir, "lib/endorsed"));
+
+ // Classpath
+ StringBuilder classPath = new StringBuilder();
+ File karafLibDir = new File(karafHomeDir, "lib");
+ String[] libs = karafLibDir.list(new FilenameFilter() {
+ @Override
+ public boolean accept(File dir, String name) {
+ return name.startsWith("karaf");
+ }
+ });
+ for (String lib : libs) {
+ String separator = classPath.length() > 0 ? File.pathSeparator : "";
+ classPath.append(separator).append(new File(karafHomeDir, "lib/" + lib));
+ }
+ cmd.add("-classpath");
+ cmd.add(classPath.toString());
+
+ // Main class
+ cmd.add("org.apache.karaf.main.Main");
+
+ // Output the startup command
+ StringBuffer cmdstr = new StringBuffer();
+ for (String tok : cmd) {
+ cmdstr.append(tok).append(" ");
+ }
+ _logger.debug("Starting Karaf with: {}", cmdstr);
+
+ try {
+ ProcessBuilder processBuilder = new ProcessBuilder(cmd);
+ processBuilder.directory(karafHomeDir);
+ processBuilder.redirectErrorStream(true);
+ process = processBuilder.start();
+ new Thread(new ConsoleConsumer()).start();
+ } catch (Exception ex) {
+ throw new LifecycleException("Cannot start managed Karaf container", ex);
+ }
+
+ // Get the MBeanServerConnection
+ try {
+ mbeanServer = getMBeanServerConnection(30, TimeUnit.SECONDS);
+ } catch (Exception ex) {
+ destroyKarafProcess();
+ throw new LifecycleException("Cannot obtain MBean server connection", ex);
+ }
+ }
+
+ mbeanServerInstance.set(mbeanServer);
+
+ try {
+ // Get the FrameworkMBean
+ ObjectName oname = ObjectNameFactory.create("osgi.core:type=framework,*");
+ frameworkMBean = getMBeanProxy(mbeanServer, oname, FrameworkMBean.class, 30, TimeUnit.SECONDS);
+
+ // Get the BundleStateMBean
+ oname = ObjectNameFactory.create("osgi.core:type=bundleState,*");
+ bundleStateMBean = getMBeanProxy(mbeanServer, oname, BundleStateMBean.class, 30, TimeUnit.SECONDS);
+
+ // Get the BundleStateMBean
+ oname = ObjectNameFactory.create("osgi.core:type=serviceState,*");
+ serviceStateMBean = getMBeanProxy(mbeanServer, oname, ServiceStateMBean.class, 30, TimeUnit.SECONDS);
+
+ // Install the arquillian bundle to become active
+ installArquillianBundle();
+
+ // Await the arquillian bundle to become active
+ awaitArquillianBundleActive(30, TimeUnit.SECONDS);
+
+ // Await the beginning start level
+ Integer beginningStartLevel = config.getKarafBeginningStartLevel();
+ if (beginningStartLevel != null)
+ awaitBeginningStartLevel(beginningStartLevel, 30, TimeUnit.SECONDS);
+
+ // Await bootsrap complete services
+ awaitBootstrapCompleteServices();
+
+ } catch (RuntimeException rte) {
+ destroyKarafProcess();
+ throw rte;
+ } catch (Exception ex) {
+ destroyKarafProcess();
+ throw new LifecycleException("Cannot start Karaf container", ex);
+ }
+ }
+
+ @Override
+ public void stop() throws LifecycleException {
+ super.stop();
+ destroyKarafProcess();
+ }
+
+ private void destroyKarafProcess() throws LifecycleException {
+ if (process != null) {
+ process.destroy();
+ try {
+ process.waitFor();
+ } catch (InterruptedException e) {
+ throw new LifecycleException("Cannot start Karaf container", e);
+ }
+ }
+ }
+
+ /**
+ * Runnable that consumes the output of the process. If nothing consumes the output the AS will hang on some platforms
+ *
+ * @author Stuart Douglas
+ */
+ private class ConsoleConsumer implements Runnable {
+
+ @Override
+ public void run() {
+ final InputStream stream = process.getInputStream();
+ final boolean writeOutput = config.isOutputToConsole();
+ try {
+ byte[] buf = new byte[32];
+ int num;
+ // Do not try reading a line cos it considers '\r' end of line
+ while ((num = stream.read(buf)) != -1) {
+ if (writeOutput)
+ System.out.write(buf, 0, num);
+ }
+ } catch (IOException ignored) {
+ }
+ }
+ }
+
+
+}
diff --git a/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/arquillian/KeycloakArquillianExtension.java b/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/arquillian/KeycloakArquillianExtension.java
index c9a9d89..310a3bc 100644
--- a/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/arquillian/KeycloakArquillianExtension.java
+++ b/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/arquillian/KeycloakArquillianExtension.java
@@ -17,6 +17,7 @@
package org.keycloak.testsuite.arquillian;
+import org.jboss.arquillian.container.spi.client.container.DeployableContainer;
import org.jboss.arquillian.container.test.impl.enricher.resource.URLResourceProvider;
import org.jboss.arquillian.container.test.spi.client.deployment.ApplicationArchiveProcessor;
import org.jboss.arquillian.container.test.spi.client.deployment.DeploymentScenarioGenerator;
@@ -26,6 +27,7 @@ import org.jboss.arquillian.graphene.location.CustomizableURLResourceProvider;
import org.jboss.arquillian.test.spi.enricher.resource.ResourceProvider;
import org.jboss.arquillian.test.spi.execution.TestExecutionDecider;
import org.keycloak.testsuite.arquillian.h2.H2TestEnricher;
+import org.keycloak.testsuite.arquillian.karaf.CustomKarafContainer;
import org.keycloak.testsuite.arquillian.migration.MigrationTestExecutionDecider;
import org.keycloak.testsuite.arquillian.provider.AdminClientProvider;
import org.keycloak.testsuite.arquillian.provider.OAuthClientProvider;
@@ -51,10 +53,10 @@ public class KeycloakArquillianExtension implements LoadableExtension {
builder
.service(DeploymentScenarioGenerator.class, DeploymentTargetModifier.class)
.service(ApplicationArchiveProcessor.class, DeploymentArchiveProcessor.class)
+ .service(DeployableContainer.class, CustomKarafContainer.class)
.observer(AuthServerTestEnricher.class)
.observer(AppServerTestEnricher.class)
.observer(H2TestEnricher.class);
-
builder
.service(TestExecutionDecider.class, MigrationTestExecutionDecider.class);
diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/adapter/example/AbstractFuseAdminAdapterTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/adapter/example/AbstractFuseAdminAdapterTest.java
new file mode 100644
index 0000000..3cc9b38
--- /dev/null
+++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/adapter/example/AbstractFuseAdminAdapterTest.java
@@ -0,0 +1,258 @@
+package org.keycloak.testsuite.adapter.example;
+
+import static org.junit.Assert.assertTrue;
+import static org.keycloak.testsuite.auth.page.AuthRealm.DEMO;
+import static org.keycloak.testsuite.util.IOUtil.loadRealm;
+import static org.keycloak.testsuite.util.URLAssert.assertCurrentUrlDoesntStartWith;
+import static org.keycloak.testsuite.util.URLAssert.assertCurrentUrlStartsWith;
+
+import java.io.ByteArrayOutputStream;
+import java.io.File;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.io.PipedInputStream;
+import java.io.PipedOutputStream;
+import java.util.Collections;
+import java.util.EnumSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.TimeoutException;
+
+import javax.management.InstanceNotFoundException;
+import javax.management.MBeanException;
+import javax.management.MBeanServerConnection;
+import javax.management.ObjectName;
+import javax.management.ReflectionException;
+import javax.management.remote.JMXConnector;
+import javax.management.remote.JMXConnectorFactory;
+import javax.management.remote.JMXServiceURL;
+
+import org.apache.sshd.client.SshClient;
+import org.apache.sshd.client.channel.ClientChannel;
+import org.apache.sshd.client.channel.ClientChannelEvent;
+import org.apache.sshd.client.future.ConnectFuture;
+import org.apache.sshd.client.session.ClientSession;
+import org.apache.sshd.client.session.ClientSession.ClientSessionEvent;
+import org.jboss.arquillian.graphene.page.Page;
+import org.junit.Assert;
+import org.junit.Test;
+import org.keycloak.representations.idm.RealmRepresentation;
+import org.keycloak.testsuite.adapter.AbstractExampleAdapterTest;
+import org.keycloak.testsuite.adapter.page.HawtioPage;
+
+public abstract class AbstractFuseAdminAdapterTest extends AbstractExampleAdapterTest {
+
+ @Page
+ private HawtioPage hawtioPage;
+
+ private SshClient client;
+
+ private ClientChannel channel;
+
+ private ClientSession session;
+
+ enum Result { OK, NOT_FOUND, NO_CREDENTIALS, NO_ROLES };
+
+ @Override
+ public void addAdapterTestRealms(List<RealmRepresentation> testRealms) {
+ RealmRepresentation fuseRealm = loadRealm(new File(EXAMPLES_HOME_DIR + "/fuse/demorealm.json"));
+ testRealms.add(fuseRealm);
+ }
+
+ @Override
+ public void setDefaultPageUriParameters() {
+ super.setDefaultPageUriParameters();
+ testRealmPage.setAuthRealm(DEMO);
+ testRealmLoginPage.setAuthRealm(DEMO);
+ }
+
+ @Test
+ public void hawtioLoginTest() throws Exception {
+ hawtioPage.navigateTo();
+ testRealmLoginPage.form().login("user", "invalid-password");
+ assertCurrentUrlDoesntStartWith(hawtioPage);
+
+ testRealmLoginPage.form().login("invalid-user", "password");
+ assertCurrentUrlDoesntStartWith(hawtioPage);
+
+ testRealmLoginPage.form().login("root", "password");
+ assertCurrentUrlStartsWith(hawtioPage.getDriver(), hawtioPage.toString() + "/welcome");
+ hawtioPage.logout();
+ assertCurrentUrlStartsWith(testRealmLoginPage);
+
+ hawtioPage.navigateTo();
+ testRealmLoginPage.form().login("mary", "password");
+ assertTrue(!driver.getPageSource().contains("welcome"));
+ }
+
+
+
+ @Test
+ public void sshLoginTest() throws Exception {
+ assertCommand("mary", "password", "shell:date", Result.NO_ROLES);
+ assertCommand("john", "password", "shell:info", Result.NO_CREDENTIALS);
+ assertCommand("john", "password", "shell:date", Result.OK);
+ assertCommand("root", "password", "shell:info", Result.OK);
+ }
+
+ @Test
+ public void jmxLoginTest() throws Exception {
+ setJMXAuthentication("keycloak", "password");
+ ObjectName mbean = new ObjectName("org.apache.karaf:type=config,name=root");
+ //invalid credentials
+ try {
+ getJMXConnector("mary", "password1").getMBeanServerConnection();
+ Assert.fail();
+ } catch (SecurityException se) {}
+ //no role
+ MBeanServerConnection connection = getJMXConnector("mary", "password").getMBeanServerConnection();
+ assertJmxInvoke(false, connection, mbean, "listProperties", new Object [] {""}, new String [] {String.class.getName()});
+ assertJmxInvoke(false, connection, mbean, "setProperty", new Object [] {"", "x", "y"}, new String [] {String.class.getName(), String.class.getName(), String.class.getName()});
+ //read only role
+ connection = getJMXConnector("john", "password").getMBeanServerConnection();
+ assertJmxInvoke(true, connection, mbean, "listProperties", new Object [] {""}, new String [] {String.class.getName()});
+ assertJmxInvoke(false, connection, mbean, "setProperty", new Object [] {"", "x", "y"}, new String [] {String.class.getName(), String.class.getName(), String.class.getName()});
+ //read write role
+ connection = getJMXConnector("root", "password").getMBeanServerConnection();
+ assertJmxInvoke(true, connection, mbean, "listProperties", new Object [] {""}, new String [] {String.class.getName()});
+ assertJmxInvoke(true, connection, mbean, "setProperty", new Object [] {"", "x", "y"}, new String [] {String.class.getName(), String.class.getName(), String.class.getName()});
+ setJMXAuthentication("karaf", "admin");
+ }
+
+ private String assertCommand(String user, String password, String command, Result result) throws Exception, IOException {
+ if (!command.endsWith("\n"))
+ command += "\n";
+
+ ByteArrayOutputStream out = new ByteArrayOutputStream();
+ OutputStream pipe = openSshChannel(user, password, out, out);
+ pipe.write(command.getBytes());
+ pipe.flush();
+
+ closeSshChannel(pipe);
+ String output = new String(out.toByteArray());
+
+ switch(result) {
+ case OK:
+ Assert.assertFalse("Should not contain 'Insufficient credentials' or 'Command not found': " + output,
+ output.contains("Insufficient credentials") || output.contains("Command not found"));
+ break;
+ case NOT_FOUND:
+ Assert.assertTrue("Should contain 'Command not found': " + output,
+ output.contains("Command not found"));
+ break;
+ case NO_CREDENTIALS:
+ Assert.assertTrue("Should contain 'Insufficient credentials': " + output,
+ output.contains("Insufficient credentials"));
+ break;
+ case NO_ROLES:
+ Assert.assertTrue("Should contain 'Current user has no associated roles': " + output,
+ output.contains("Current user has no associated roles"));
+ break;
+ default:
+ Assert.fail("Unexpected enum value: " + result);
+ }
+ return output;
+ }
+
+ private OutputStream openSshChannel(String username, String password, OutputStream ... outputs) throws Exception {
+ client = SshClient.setUpDefaultClient();
+ client.start();
+ ConnectFuture future = client.connect(username, "localhost", 8101);
+ future.await();
+ session = future.getSession();
+
+ Set<ClientSessionEvent> ret = EnumSet.of(ClientSessionEvent.WAIT_AUTH);
+ while (ret.contains(ClientSessionEvent.WAIT_AUTH)) {
+ session.addPasswordIdentity(password);
+ session.auth().verify();
+ ret = session.waitFor(EnumSet.of(ClientSessionEvent.WAIT_AUTH, ClientSessionEvent.CLOSED, ClientSessionEvent.AUTHED), 0);
+ }
+ if (ret.contains(ClientSessionEvent.CLOSED)) {
+ throw new Exception("Could not open SSH channel");
+ }
+ channel = session.createChannel("shell");
+ PipedOutputStream pipe = new PipedOutputStream();
+ channel.setIn(new PipedInputStream(pipe));
+
+ OutputStream out;
+ if (outputs.length >= 1) {
+ out = outputs[0];
+ } else {
+ out = new ByteArrayOutputStream();
+ }
+ channel.setOut(out);
+
+ OutputStream err;
+ if (outputs.length >= 2) {
+ err = outputs[1];
+ } else {
+ err = new ByteArrayOutputStream();
+ }
+ channel.setErr(err);
+ channel.open();
+
+ return pipe;
+ }
+
+ private void setJMXAuthentication(String realm, String password) throws Exception {
+ assertCommand("admin", "password", "config:edit org.apache.karaf.management; config:propset jmxRealm " + realm + "; config:update", Result.OK);
+ getMBeanServerConnection(10000, TimeUnit.MILLISECONDS, "admin", password);
+ }
+
+ private void closeSshChannel(OutputStream pipe) throws IOException {
+ pipe.write("logout\n".getBytes());
+ pipe.flush();
+
+ channel.waitFor(EnumSet.of(ClientChannelEvent.CLOSED), 0);
+ session.close(true);
+ client.stop();
+
+ client = null;
+ channel = null;
+ session = null;
+ }
+
+ private Object assertJmxInvoke(boolean expectSuccess, MBeanServerConnection connection, ObjectName mbean, String method,
+ Object[] params, String[] signature) throws InstanceNotFoundException, MBeanException, ReflectionException, IOException {
+ try {
+ Object result = connection.invoke(mbean, method, params, signature);
+ assertTrue(expectSuccess);
+ return result;
+ } catch (SecurityException se) {
+ assertTrue(!expectSuccess);
+ return null;
+ }
+ }
+
+ private MBeanServerConnection getMBeanServerConnection(long timeout, final TimeUnit unit, String username, String password) throws Exception {
+ Exception lastException = null;
+ long timeoutMillis = System.currentTimeMillis() + unit.toMillis(timeout);
+ while (System.currentTimeMillis() < timeoutMillis) {
+ try {
+ return getJMXConnector(username, password).getMBeanServerConnection();
+ } catch (Exception ex) {
+ lastException = ex;
+ Thread.sleep(500);
+ ex.printStackTrace();
+ }
+ }
+ TimeoutException timeoutException = new TimeoutException();
+ timeoutException.initCause(lastException);
+ throw timeoutException;
+ }
+
+ private JMXConnector getJMXConnector(String userName, String password) throws Exception {
+ JMXServiceURL url = new JMXServiceURL(getJmxServiceUrl());
+ String[] credentials = new String[] { userName, password };
+ Map<String, ?> env = Collections.singletonMap(JMXConnector.CREDENTIALS, credentials);
+ JMXConnector connector = JMXConnectorFactory.connect(url, env);
+ return connector;
+ }
+
+ private String getJmxServiceUrl() throws Exception {
+ return "service:jmx:rmi://localhost:44444/jndi/rmi://localhost:1099/karaf-root";
+ }
+
+}
diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/adapter/example/AbstractFuseExampleAdapterTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/adapter/example/AbstractFuseExampleAdapterTest.java
index b0583fb..f21a48c 100644
--- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/adapter/example/AbstractFuseExampleAdapterTest.java
+++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/adapter/example/AbstractFuseExampleAdapterTest.java
@@ -59,7 +59,7 @@ public abstract class AbstractFuseExampleAdapterTest extends AbstractExampleAdap
@Override
public void addAdapterTestRealms(List<RealmRepresentation> testRealms) {
- RealmRepresentation fuseRealm = loadRealm(new File(EXAMPLES_HOME_DIR + "/fuse/testrealm.json"));
+ RealmRepresentation fuseRealm = loadRealm(new File(EXAMPLES_HOME_DIR + "/fuse/demorealm.json"));
testRealms.add(fuseRealm);
}
diff --git a/testsuite/integration-arquillian/tests/other/adapters/karaf/common/xslt/arquillian.xsl b/testsuite/integration-arquillian/tests/other/adapters/karaf/common/xslt/arquillian.xsl
index 9c8f2a6..9c1b6eb 100644
--- a/testsuite/integration-arquillian/tests/other/adapters/karaf/common/xslt/arquillian.xsl
+++ b/testsuite/integration-arquillian/tests/other/adapters/karaf/common/xslt/arquillian.xsl
@@ -31,21 +31,19 @@
<container qualifier="app-server-${{app.server}}" mode="manual" >
<configuration>
<property name="enabled">true</property>
- <property name="adapterImplClass">org.jboss.arquillian.container.osgi.karaf.managed.KarafManagedDeployableContainer</property>
- <!--<property name="adapterImplClass">org.keycloak.testsuite.arquillian.karaf.CustomKarafContainer</property>-->
+<!-- <property name="adapterImplClass">org.jboss.arquillian.container.osgi.karaf.managed.KarafManagedDeployableContainer</property> -->
+ <property name="adapterImplClass">org.keycloak.testsuite.arquillian.karaf.CustomKarafContainer</property>
<property name="autostartBundle">false</property>
<property name="karafHome">${app.server.home}</property>
<property name="javaHome">${app.server.java.home}</property>
<property name="javaVmArguments">
- -agentlib:jdwp=transport=dt_socket,address=5005,server=y,suspend=n
${adapter.test.props}
</property>
<property name="jmxServiceURL">service:jmx:rmi://127.0.0.1:44444/jndi/rmi://127.0.0.1:1099/karaf-root</property>
<property name="jmxUsername">${app.server.management.user}</property>
- <property name="jmxPassword">${app.server.management.password}</property>
+ <property name="jmxPassword">${app.server.management.password}</property>
</configuration>
</container>
-
</xsl:copy>
</xsl:template>
diff --git a/testsuite/integration-arquillian/tests/other/adapters/karaf/fuse63/src/test/java/org/keycloak/testsuite/adapter/example/Fuse63AdminAdapterTest.java b/testsuite/integration-arquillian/tests/other/adapters/karaf/fuse63/src/test/java/org/keycloak/testsuite/adapter/example/Fuse63AdminAdapterTest.java
new file mode 100644
index 0000000..90f80d4
--- /dev/null
+++ b/testsuite/integration-arquillian/tests/other/adapters/karaf/fuse63/src/test/java/org/keycloak/testsuite/adapter/example/Fuse63AdminAdapterTest.java
@@ -0,0 +1,8 @@
+package org.keycloak.testsuite.adapter.example;
+
+import org.keycloak.testsuite.arquillian.annotation.AppServerContainer;
+
+@AppServerContainer("app-server-fuse63")
+public class Fuse63AdminAdapterTest extends AbstractFuseAdminAdapterTest {
+
+}
diff --git a/testsuite/integration-arquillian/tests/other/adapters/karaf/pom.xml b/testsuite/integration-arquillian/tests/other/adapters/karaf/pom.xml
index 70e4a2c..c930dec 100644
--- a/testsuite/integration-arquillian/tests/other/adapters/karaf/pom.xml
+++ b/testsuite/integration-arquillian/tests/other/adapters/karaf/pom.xml
@@ -86,7 +86,12 @@
<groupId>org.apache.karaf</groupId>
<artifactId>org.apache.karaf.client</artifactId>
<version>3.0.3</version>
- </dependency>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.sshd</groupId>
+ <artifactId>sshd-core</artifactId>
+ <version>1.2.0</version>
+ </dependency>
</dependencies>
<build>
<plugins>
diff --git a/testsuite/integration-arquillian/tests/pom.xml b/testsuite/integration-arquillian/tests/pom.xml
index 642087d..5c6a03f 100755
--- a/testsuite/integration-arquillian/tests/pom.xml
+++ b/testsuite/integration-arquillian/tests/pom.xml
@@ -719,6 +719,12 @@
<scope>compile</scope>
</dependency>
+ <dependency>
+ <groupId>org.apache.sshd</groupId>
+ <artifactId>sshd-core</artifactId>
+ <version>1.2.0</version>
+ </dependency>
+
<!-- Email Test Server -->
<dependency>
<groupId>com.icegreen</groupId>