keycloak-aplcache
Changes
integration/admin-client/src/main/java/org/keycloak/admin/client/resource/RealmResource.java 23(+23 -0)
testsuite/integration-arquillian/servers/app-server/karaf/fuse62/src/main/resources/update-config.cli 5(+5 -0)
testsuite/integration-arquillian/servers/app-server/karaf/karaf3/src/main/resources/update-config.cli 5(+5 -0)
testsuite/integration-arquillian/servers/auth-server/services/testsuite-providers/src/main/java/org/keycloak/testsuite/rest/TestApplicationResourceProvider.java 54(+53 -1)
testsuite/integration-arquillian/servers/auth-server/services/testsuite-providers/src/main/java/org/keycloak/testsuite/rest/TestApplicationResourceProviderFactory.java 12(+11 -1)
testsuite/integration-arquillian/servers/auth-server/services/testsuite-providers/src/main/java/org/keycloak/testsuite/rest/TestingResourceProvider.java 12(+12 -0)
testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/adapter/page/fuse/AbstractFuseExample.java 17(+16 -1)
testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/client/KeycloakTestingClient.java 3(+3 -0)
testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/client/resources/TestApplicationResource.java 50(+50 -0)
testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/client/resources/TestingResource.java 7(+7 -0)
testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/util/OAuthClient.java 11(+8 -3)
testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/AbstractKeycloakTest.java 9(+8 -1)
testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/adapter/example/AbstractFuseExampleAdapterTest.java 5(+3 -2)
testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/group/GroupMappersTest.java 1(+0 -1)
testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/realm/RealmTest.java 150(+150 -0)
testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/AssertEvents.java 9(+3 -6)
testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/oauth/ResourceOwnerPasswordCredentialsGrantTest.java 194(+91 -103)
testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/util/ClientManager.java 10(+9 -1)
testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/util/RealmManager.java 12(+12 -0)
Details
diff --git a/common/src/main/java/org/keycloak/common/ClientConnection.java b/common/src/main/java/org/keycloak/common/ClientConnection.java
index 3c4b449..5afbed6 100755
--- a/common/src/main/java/org/keycloak/common/ClientConnection.java
+++ b/common/src/main/java/org/keycloak/common/ClientConnection.java
@@ -24,7 +24,11 @@ package org.keycloak.common;
* @version $Revision: 1 $
*/
public interface ClientConnection {
+
String getRemoteAddr();
String getRemoteHost();
- int getReportPort();
+ int getRemotePort();
+
+ String getLocalAddr();
+ int getLocalPort();
}
diff --git a/integration/admin-client/src/main/java/org/keycloak/admin/client/resource/RealmResource.java b/integration/admin-client/src/main/java/org/keycloak/admin/client/resource/RealmResource.java
index 34ca64a..b6db357 100644
--- a/integration/admin-client/src/main/java/org/keycloak/admin/client/resource/RealmResource.java
+++ b/integration/admin-client/src/main/java/org/keycloak/admin/client/resource/RealmResource.java
@@ -18,6 +18,7 @@
package org.keycloak.admin.client.resource;
import org.jboss.resteasy.annotations.cache.NoCache;
+import org.keycloak.representations.adapters.action.GlobalRequestResult;
import org.keycloak.representations.idm.AdminEventRepresentation;
import org.keycloak.representations.idm.ClientRepresentation;
import org.keycloak.representations.idm.EventRepresentation;
@@ -170,4 +171,26 @@ public interface RealmResource {
@QueryParam("bindDn") String bindDn, @QueryParam("bindCredential") String bindCredential,
@QueryParam("useTruststoreSpi") String useTruststoreSpi);
+ @Path("clear-realm-cache")
+ @POST
+ void clearRealmCache();
+
+ @Path("clear-user-cache")
+ @POST
+ void clearUserCache();
+
+ @Path("push-revocation")
+ @POST
+ @Produces(MediaType.APPLICATION_JSON)
+ GlobalRequestResult pushRevocation();
+
+ @Path("logout-all")
+ @POST
+ @Produces(MediaType.APPLICATION_JSON)
+ GlobalRequestResult logoutAll();
+
+ @Path("sessions/{session}")
+ @DELETE
+ void deleteSession(@PathParam("session") String sessionId);
+
}
diff --git a/services/src/main/java/org/keycloak/services/filters/KeycloakSessionServletFilter.java b/services/src/main/java/org/keycloak/services/filters/KeycloakSessionServletFilter.java
index d6a3f13..282fd31 100755
--- a/services/src/main/java/org/keycloak/services/filters/KeycloakSessionServletFilter.java
+++ b/services/src/main/java/org/keycloak/services/filters/KeycloakSessionServletFilter.java
@@ -63,9 +63,19 @@ public class KeycloakSessionServletFilter implements Filter {
}
@Override
- public int getReportPort() {
+ public int getRemotePort() {
return request.getRemotePort();
}
+
+ @Override
+ public String getLocalAddr() {
+ return request.getLocalAddr();
+ }
+
+ @Override
+ public int getLocalPort() {
+ return request.getLocalPort();
+ }
};
session.getContext().setConnection(connection);
ResteasyProviderFactory.pushContext(ClientConnection.class, connection);
diff --git a/services/src/main/java/org/keycloak/services/resources/WelcomeResource.java b/services/src/main/java/org/keycloak/services/resources/WelcomeResource.java
index 54becb9..d57f0fe 100755
--- a/services/src/main/java/org/keycloak/services/resources/WelcomeResource.java
+++ b/services/src/main/java/org/keycloak/services/resources/WelcomeResource.java
@@ -20,14 +20,11 @@ import org.keycloak.Config;
import org.keycloak.common.ClientConnection;
import org.keycloak.common.util.MimeTypeUtil;
import org.keycloak.models.BrowserSecurityHeaders;
-import org.keycloak.models.Constants;
import org.keycloak.models.KeycloakSession;
-import org.keycloak.models.RealmModel;
import org.keycloak.models.utils.KeycloakModelUtils;
import org.keycloak.services.ForbiddenException;
import org.keycloak.services.ServicesLogger;
import org.keycloak.services.managers.ApplianceBootstrap;
-import org.keycloak.services.managers.AuthenticationManager;
import org.keycloak.services.util.CacheControlUtil;
import org.keycloak.services.util.CookieHelper;
import org.keycloak.theme.BrowserSecurityHeaderSetup;
@@ -225,13 +222,24 @@ public class WelcomeResource {
private boolean isLocal() {
try {
- InetAddress inetAddress = InetAddress.getByName(session.getContext().getConnection().getRemoteAddr());
- return inetAddress.isAnyLocalAddress() || inetAddress.isLoopbackAddress();
+ ClientConnection clientConnection = session.getContext().getConnection();
+ InetAddress remoteInetAddress = InetAddress.getByName(clientConnection.getRemoteAddr());
+ InetAddress localInetAddress = InetAddress.getByName(clientConnection.getLocalAddr());
+ String xForwardedFor = headers.getHeaderString("X-Forwarded-For");
+ logger.debugf("Checking WelcomePage. Remote address: %s, Local address: %s, X-Forwarded-For header: %s", remoteInetAddress.toString(), localInetAddress.toString(), xForwardedFor);
+
+ // Access through AJP protocol (loadbalancer) may cause that remoteAddress is "127.0.0.1".
+ // So consider that welcome page accessed locally just if it was accessed really through "localhost" URL and without loadbalancer (x-forwarded-for header is empty).
+ return isLocalAddress(remoteInetAddress) && isLocalAddress(localInetAddress) && xForwardedFor == null;
} catch (UnknownHostException e) {
throw new WebApplicationException(Response.Status.INTERNAL_SERVER_ERROR);
}
}
+ private boolean isLocalAddress(InetAddress inetAddress) {
+ return inetAddress.isAnyLocalAddress() || inetAddress.isLoopbackAddress();
+ }
+
private String updateCsrfChecks() {
String stateChecker = getCsrfCookie();
if (stateChecker != null) {
diff --git a/testsuite/integration-arquillian/servers/app-server/jboss/common/security-eap6.xsl b/testsuite/integration-arquillian/servers/app-server/jboss/common/security-eap6.xsl
new file mode 100644
index 0000000..b389cd1
--- /dev/null
+++ b/testsuite/integration-arquillian/servers/app-server/jboss/common/security-eap6.xsl
@@ -0,0 +1,51 @@
+<!--
+ ~ 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.
+ -->
+
+<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
+ xmlns:xalan="http://xml.apache.org/xalan"
+ xmlns:j="urn:jboss:domain:1.7"
+ xmlns:w="urn:jboss:domain:web:2.2"
+ version="2.0"
+ exclude-result-prefixes="xalan j ds k sec">
+
+ <xsl:param name="config"/>
+
+ <xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes" xalan:indent-amount="4" standalone="no"/>
+ <xsl:strip-space elements="*"/>
+
+ <xsl:template match="//w:connector[@name='http']">
+ <xsl:copy-of select="."/>
+ <connector name="https" protocol="HTTP/1.1" scheme="https" socket-binding="https" secure="true">
+ <ssl name="https" password="secret" certificate-key-file="${{jboss.server.config.dir}}/adapter.jks"/>
+ </connector>
+ </xsl:template>
+
+ <xsl:template match="//j:extensions">
+ <xsl:copy-of select="."/>
+ <system-properties>
+ <property name="javax.net.ssl.trustStore" value="${{jboss.server.config.dir}}/keycloak.truststore"/>
+ <property name="javax.net.ssl.trustStorePassword" value="secret"/>
+ </system-properties>
+ </xsl:template>
+
+ <xsl:template match="@*|node()">
+ <xsl:copy>
+ <xsl:apply-templates select="@*|node()" />
+ </xsl:copy>
+ </xsl:template>
+
+</xsl:stylesheet>
\ No newline at end of file
diff --git a/testsuite/integration-arquillian/servers/app-server/jboss/pom.xml b/testsuite/integration-arquillian/servers/app-server/jboss/pom.xml
index c9c9330..55ad021 100644
--- a/testsuite/integration-arquillian/servers/app-server/jboss/pom.xml
+++ b/testsuite/integration-arquillian/servers/app-server/jboss/pom.xml
@@ -33,6 +33,7 @@
<common.resources>${project.parent.basedir}/common</common.resources>
<assembly.xml>${project.parent.basedir}/assembly.xml</assembly.xml>
<app.server.jboss.home>${containers.home}/${app.server.jboss.unpacked.folder.name}</app.server.jboss.home>
+ <security.xslt>security.xsl</security.xslt>
</properties>
<profiles>
@@ -337,7 +338,7 @@
<includes>
<include>standalone.xml</include>
</includes>
- <stylesheet>${common.resources}/security.xsl</stylesheet>
+ <stylesheet>${common.resources}/${security.xslt}</stylesheet>
<outputDir>${app.server.jboss.home}/standalone/configuration</outputDir>
</transformationSet>
</transformationSets>
@@ -392,6 +393,9 @@
</profile>
<profile>
<id>app-server-eap6</id>
+ <properties>
+ <security.xslt>security-eap6.xsl</security.xslt>
+ </properties>
<modules>
<module>eap6</module>
</modules>
diff --git a/testsuite/integration-arquillian/servers/app-server/karaf/common/install-features.bat b/testsuite/integration-arquillian/servers/app-server/karaf/common/install-features.bat
index 7abbf5a..58d14ed 100644
--- a/testsuite/integration-arquillian/servers/app-server/karaf/common/install-features.bat
+++ b/testsuite/integration-arquillian/servers/app-server/karaf/common/install-features.bat
@@ -28,6 +28,10 @@ if "%UNINSTALL_PAX%" == "true" (
call client.bat %CLIENT_AUTH% -f uninstall-pax.cli
if %ERRORLEVEL% neq 0 set ERROR=%ERRORLEVEL%
)
+if "%UPDATE_CONFIG%" == "true" (
+ call client.bat %CLIENT_AUTH% -f update-config.cli
+ if %ERRORLEVEL% neq 0 set ERROR=%ERRORLEVEL%
+)
call client.bat %CLIENT_AUTH% -f install-features.cli
if %ERRORLEVEL% neq 0 set ERROR=%ERRORLEVEL%
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 4173908..d094ff4 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
@@ -22,6 +22,16 @@ do
if [ $? -ne 0 ]; then RESULT=1; fi
fi
+ if "$UPDATE_CONFIG" == "true"; then
+ echo "Updating Config - org.ops4j.pax.url.mvn"
+ ./client $CLIENT_AUTH -f update-config.cli
+ if [ $? -ne 0 ]; then
+ RESULT=1;
+ else
+ ./client $CLIENT_AUTH config:list | grep org.ops4j.pax.url.mvn.
+ fi
+ fi
+
echo "Installing features."
./client $CLIENT_AUTH -f install-features.cli
if [ $? -ne 0 ]; then RESULT=1; fi
diff --git a/testsuite/integration-arquillian/servers/app-server/karaf/fuse62/src/main/resources/update-config.cli b/testsuite/integration-arquillian/servers/app-server/karaf/fuse62/src/main/resources/update-config.cli
new file mode 100644
index 0000000..d6a425a
--- /dev/null
+++ b/testsuite/integration-arquillian/servers/app-server/karaf/fuse62/src/main/resources/update-config.cli
@@ -0,0 +1,5 @@
+config:edit org.ops4j.pax.url.mvn
+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
diff --git a/testsuite/integration-arquillian/servers/app-server/karaf/karaf3/src/main/resources/update-config.cli b/testsuite/integration-arquillian/servers/app-server/karaf/karaf3/src/main/resources/update-config.cli
new file mode 100644
index 0000000..908bd0e
--- /dev/null
+++ b/testsuite/integration-arquillian/servers/app-server/karaf/karaf3/src/main/resources/update-config.cli
@@ -0,0 +1,5 @@
+config:edit org.ops4j.pax.url.mvn
+config:property-set org.ops4j.pax.url.mvn.localRepository ${maven.repo.local}
+config:property-set org.ops4j.pax.url.mvn.settings ${maven.local.settings}
+config:property-append org.ops4j.pax.url.mvn.repositories ${repositories}
+config:update
diff --git a/testsuite/integration-arquillian/servers/app-server/karaf/pom.xml b/testsuite/integration-arquillian/servers/app-server/karaf/pom.xml
index 849162e..fa3cdc2 100644
--- a/testsuite/integration-arquillian/servers/app-server/karaf/pom.xml
+++ b/testsuite/integration-arquillian/servers/app-server/karaf/pom.xml
@@ -35,6 +35,7 @@
<app.server.karaf.home>${containers.home}/${app.server.karaf.unpacked.folder.name}</app.server.karaf.home>
<app.server.karaf.client.auth>-u karaf</app.server.karaf.client.auth>
<app.server.karaf.uninstall.pax>false</app.server.karaf.uninstall.pax>
+ <app.server.karaf.update.config>false</app.server.karaf.update.config>
</properties>
<profiles>
@@ -103,7 +104,7 @@
<artifactId>maven-resources-plugin</artifactId>
<executions>
<execution>
- <id>copy-features-clie</id>
+ <id>copy-clis</id>
<phase>process-resources</phase>
<goals>
<goal>copy-resources</goal>
@@ -115,6 +116,7 @@
<directory>src/main/resources</directory>
<includes>
<include>install-features.cli</include>
+ <include>update-config.cli</include>
</includes>
<filtering>true</filtering>
</resource>
@@ -161,6 +163,7 @@
<JAVA_HOME>${app.server.java.home}</JAVA_HOME>
<CLIENT_AUTH>${app.server.karaf.client.auth}</CLIENT_AUTH>
<UNINSTALL_PAX>${app.server.karaf.uninstall.pax}</UNINSTALL_PAX>
+ <UPDATE_CONFIG>${app.server.karaf.update.config}</UPDATE_CONFIG>
</environmentVariables>
</configuration>
</plugin>
diff --git a/testsuite/integration-arquillian/servers/auth-server/jboss/common/security.xsl b/testsuite/integration-arquillian/servers/auth-server/jboss/common/security.xsl
index ec6b9de..17550cf 100644
--- a/testsuite/integration-arquillian/servers/auth-server/jboss/common/security.xsl
+++ b/testsuite/integration-arquillian/servers/auth-server/jboss/common/security.xsl
@@ -17,11 +17,11 @@
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xalan="http://xml.apache.org/xalan"
- xmlns:j="urn:jboss:domain:4.0"
+ xmlns:j="urn:jboss:domain:4.1"
xmlns:ds="urn:jboss:domain:datasources:4.0"
xmlns:k="urn:jboss:domain:keycloak:1.1"
xmlns:sec="urn:jboss:domain:security:1.2"
- xmlns:u="urn:jboss:domain:undertow:3.0"
+ xmlns:u="urn:jboss:domain:undertow:3.1"
version="2.0"
exclude-result-prefixes="xalan j ds k sec">
diff --git a/testsuite/integration-arquillian/servers/auth-server/jboss/eap/pom.xml b/testsuite/integration-arquillian/servers/auth-server/jboss/eap/pom.xml
index b6911a8..b13d4eb 100644
--- a/testsuite/integration-arquillian/servers/auth-server/jboss/eap/pom.xml
+++ b/testsuite/integration-arquillian/servers/auth-server/jboss/eap/pom.xml
@@ -33,6 +33,7 @@
<properties>
<auth.server.jboss>eap</auth.server.jboss>
+ <auth.server.home>${project.build.directory}/unpacked/${product.unpacked.folder.name}</auth.server.home>
<!--server-dist-->
<auth.server.dist.version>${product.version}</auth.server.dist.version>
diff --git a/testsuite/integration-arquillian/servers/auth-server/services/testsuite-providers/src/main/java/org/keycloak/testsuite/rest/TestApplicationResourceProvider.java b/testsuite/integration-arquillian/servers/auth-server/services/testsuite-providers/src/main/java/org/keycloak/testsuite/rest/TestApplicationResourceProvider.java
index 52e5858..54149d9 100644
--- a/testsuite/integration-arquillian/servers/auth-server/services/testsuite-providers/src/main/java/org/keycloak/testsuite/rest/TestApplicationResourceProvider.java
+++ b/testsuite/integration-arquillian/servers/auth-server/services/testsuite-providers/src/main/java/org/keycloak/testsuite/rest/TestApplicationResourceProvider.java
@@ -17,16 +17,26 @@
package org.keycloak.testsuite.rest;
+import org.keycloak.jose.jws.JWSInput;
+import org.keycloak.jose.jws.JWSInputException;
import org.keycloak.models.KeycloakSession;
+import org.keycloak.representations.adapters.action.LogoutAction;
+import org.keycloak.representations.adapters.action.PushNotBeforeAction;
import org.keycloak.services.resource.RealmResourceProvider;
import org.keycloak.services.resources.RealmsResource;
+import org.keycloak.testsuite.events.EventsListenerProvider;
+import javax.ws.rs.Consumes;
import javax.ws.rs.GET;
+import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.Response;
import javax.ws.rs.core.UriBuilder;
+import java.util.concurrent.BlockingQueue;
+import java.util.concurrent.TimeUnit;
/**
* @author <a href="mailto:sthorger@redhat.com">Stian Thorgersen</a>
@@ -36,8 +46,50 @@ public class TestApplicationResourceProvider implements RealmResourceProvider {
private KeycloakSession session;
- public TestApplicationResourceProvider(KeycloakSession session) {
+ private final BlockingQueue<LogoutAction> adminLogoutActions;
+ private final BlockingQueue<PushNotBeforeAction> adminPushNotBeforeActions;
+
+ public TestApplicationResourceProvider(KeycloakSession session, BlockingQueue<LogoutAction> adminLogoutActions,
+ BlockingQueue<PushNotBeforeAction> adminPushNotBeforeActions) {
this.session = session;
+ this.adminLogoutActions = adminLogoutActions;
+ this.adminPushNotBeforeActions = adminPushNotBeforeActions;
+ }
+
+ @POST
+ @Consumes(MediaType.TEXT_PLAIN)
+ @Path("/admin/k_logout")
+ public void adminLogout(String data) throws JWSInputException {
+ adminLogoutActions.add(new JWSInput(data).readJsonContent(LogoutAction.class));
+ }
+
+ @POST
+ @Consumes(MediaType.TEXT_PLAIN)
+ @Path("/admin/k_push_not_before")
+ public void adminPushNotBefore(String data) throws JWSInputException {
+ adminPushNotBeforeActions.add(new JWSInput(data).readJsonContent(PushNotBeforeAction.class));
+ }
+
+ @GET
+ @Produces(MediaType.APPLICATION_JSON)
+ @Path("/poll-admin-logout")
+ public LogoutAction getAdminLogoutAction() throws InterruptedException {
+ return adminLogoutActions.poll(10, TimeUnit.SECONDS);
+ }
+
+ @GET
+ @Produces(MediaType.APPLICATION_JSON)
+ @Path("/poll-admin-not-before")
+ public PushNotBeforeAction getAdminPushNotBefore() throws InterruptedException {
+ return adminPushNotBeforeActions.poll(10, TimeUnit.SECONDS);
+ }
+
+ @POST
+ @Path("/clear-admin-actions")
+ public Response clearAdminActions() {
+ adminLogoutActions.clear();
+ adminPushNotBeforeActions.clear();
+ return Response.noContent().build();
}
@GET
diff --git a/testsuite/integration-arquillian/servers/auth-server/services/testsuite-providers/src/main/java/org/keycloak/testsuite/rest/TestApplicationResourceProviderFactory.java b/testsuite/integration-arquillian/servers/auth-server/services/testsuite-providers/src/main/java/org/keycloak/testsuite/rest/TestApplicationResourceProviderFactory.java
index e795420..40d6e2d 100644
--- a/testsuite/integration-arquillian/servers/auth-server/services/testsuite-providers/src/main/java/org/keycloak/testsuite/rest/TestApplicationResourceProviderFactory.java
+++ b/testsuite/integration-arquillian/servers/auth-server/services/testsuite-providers/src/main/java/org/keycloak/testsuite/rest/TestApplicationResourceProviderFactory.java
@@ -18,19 +18,29 @@
package org.keycloak.testsuite.rest;
import org.keycloak.Config.Scope;
+import org.keycloak.events.admin.AdminEvent;
import org.keycloak.models.KeycloakSession;
import org.keycloak.models.KeycloakSessionFactory;
+import org.keycloak.representations.adapters.action.AdminAction;
+import org.keycloak.representations.adapters.action.LogoutAction;
+import org.keycloak.representations.adapters.action.PushNotBeforeAction;
import org.keycloak.services.resource.RealmResourceProvider;
import org.keycloak.services.resource.RealmResourceProviderFactory;
+import java.util.concurrent.BlockingQueue;
+import java.util.concurrent.LinkedBlockingDeque;
+
/**
* @author <a href="mailto:sthorger@redhat.com">Stian Thorgersen</a>
*/
public class TestApplicationResourceProviderFactory implements RealmResourceProviderFactory {
+ private BlockingQueue<LogoutAction> adminLogoutActions = new LinkedBlockingDeque<>();
+ private BlockingQueue<PushNotBeforeAction> pushNotBeforeActions = new LinkedBlockingDeque<>();
+
@Override
public RealmResourceProvider create(KeycloakSession session) {
- return new TestApplicationResourceProvider(session);
+ return new TestApplicationResourceProvider(session, adminLogoutActions, pushNotBeforeActions);
}
@Override
diff --git a/testsuite/integration-arquillian/servers/auth-server/services/testsuite-providers/src/main/java/org/keycloak/testsuite/rest/TestingResourceProvider.java b/testsuite/integration-arquillian/servers/auth-server/services/testsuite-providers/src/main/java/org/keycloak/testsuite/rest/TestingResourceProvider.java
index 7b0bb29..2730eb0 100644
--- a/testsuite/integration-arquillian/servers/auth-server/services/testsuite-providers/src/main/java/org/keycloak/testsuite/rest/TestingResourceProvider.java
+++ b/testsuite/integration-arquillian/servers/auth-server/services/testsuite-providers/src/main/java/org/keycloak/testsuite/rest/TestingResourceProvider.java
@@ -17,7 +17,9 @@
package org.keycloak.testsuite.rest;
+import org.infinispan.Cache;
import org.keycloak.common.util.Time;
+import org.keycloak.connections.infinispan.InfinispanConnectionProvider;
import org.keycloak.events.Event;
import org.keycloak.models.KeycloakSession;
import org.keycloak.models.RealmModel;
@@ -34,6 +36,7 @@ import javax.ws.rs.NotFoundException;
import javax.ws.rs.POST;
import javax.ws.rs.PUT;
import javax.ws.rs.Path;
+import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.QueryParam;
import javax.ws.rs.core.MediaType;
@@ -130,6 +133,15 @@ public class TestingResourceProvider implements RealmResourceProvider {
return Response.ok().build();
}
+ @GET
+ @Path("/cache/{cache}/{id}")
+ @Produces(MediaType.APPLICATION_JSON)
+ public boolean isCached(@PathParam("cache") String cacheName, @PathParam("id") String id) {
+ InfinispanConnectionProvider provider = session.getProvider(InfinispanConnectionProvider.class);
+ Cache<Object, Object> cache = provider.getCache(cacheName);
+ return cache.containsKey(id);
+ }
+
@Override
public void close() {
}
diff --git a/testsuite/integration-arquillian/servers/pom.xml b/testsuite/integration-arquillian/servers/pom.xml
index 52ca04d..0a640f5 100644
--- a/testsuite/integration-arquillian/servers/pom.xml
+++ b/testsuite/integration-arquillian/servers/pom.xml
@@ -38,7 +38,6 @@
<eap.version>7.0.0.ER6-redhat-1</eap.version>
<eap6.version>7.5.6.Final-redhat-2</eap6.version>
<jboss.as.version>7.1.1.Final</jboss.as.version>
- <eap6.version>7.5.6.Final-redhat-2</eap6.version>
<tomcat7.version>7.0.68</tomcat7.version>
<tomcat8.version>8.0.32</tomcat8.version>
<tomcat9.version>9.0.0.M3</tomcat9.version>
diff --git a/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/adapter/page/fuse/AbstractFuseExample.java b/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/adapter/page/fuse/AbstractFuseExample.java
index 3553d66..ae91ab6 100644
--- a/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/adapter/page/fuse/AbstractFuseExample.java
+++ b/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/adapter/page/fuse/AbstractFuseExample.java
@@ -42,5 +42,20 @@ public abstract class AbstractFuseExample extends AppServerContextRoot {
}
return url;
}
-
+
+ /*
+ * non-javadoc
+ *
+ * When run tests with phantomjs customer or prutuct portal page isn't properly
+ * loaded. This method reloads page in such case.
+ */
+ @Override
+ public void navigateTo() {
+ super.navigateTo();
+
+ if (driver.getPageSource().contains("<html><head></head><body></body></html>")) {
+ log.debug("Page wasn't properly loaded - redirecting.");
+ super.navigateTo();
+ }
+ }
}
diff --git a/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/client/KeycloakTestingClient.java b/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/client/KeycloakTestingClient.java
index cbc639e..46f7b23 100755
--- a/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/client/KeycloakTestingClient.java
+++ b/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/client/KeycloakTestingClient.java
@@ -20,6 +20,7 @@ package org.keycloak.testsuite.client;
import org.jboss.resteasy.client.jaxrs.ResteasyClient;
import org.jboss.resteasy.client.jaxrs.ResteasyClientBuilder;
import org.jboss.resteasy.client.jaxrs.ResteasyWebTarget;
+import org.keycloak.testsuite.client.resources.TestApplicationResource;
import org.keycloak.testsuite.client.resources.TestingResource;
/**
@@ -42,6 +43,8 @@ public class KeycloakTestingClient {
return target.proxy(TestingResource.class);
}
+ public TestApplicationResource testApp() { return target.proxy(TestApplicationResource.class); }
+
public void close() {
client.close();
}
diff --git a/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/client/resources/TestApplicationResource.java b/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/client/resources/TestApplicationResource.java
new file mode 100644
index 0000000..8fb9b4c
--- /dev/null
+++ b/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/client/resources/TestApplicationResource.java
@@ -0,0 +1,50 @@
+/*
+ * 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.client.resources;
+
+import org.keycloak.representations.adapters.action.LogoutAction;
+import org.keycloak.representations.adapters.action.PushNotBeforeAction;
+
+import javax.ws.rs.GET;
+import javax.ws.rs.POST;
+import javax.ws.rs.Path;
+import javax.ws.rs.Produces;
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.Response;
+
+/**
+ * @author <a href="mailto:sthorger@redhat.com">Stian Thorgersen</a>
+ */
+@Path("/realms/master/app")
+public interface TestApplicationResource {
+
+ @GET
+ @Produces(MediaType.APPLICATION_JSON)
+ @Path("/poll-admin-logout")
+ LogoutAction getAdminLogoutAction();
+
+ @GET
+ @Produces(MediaType.APPLICATION_JSON)
+ @Path("/poll-admin-not-before")
+ PushNotBeforeAction getAdminPushNotBefore();
+
+ @POST
+ @Path("/clear-admin-actions")
+ Response clearAdminActions();
+
+}
diff --git a/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/client/resources/TestingResource.java b/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/client/resources/TestingResource.java
index 23337f0..310cffe 100644
--- a/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/client/resources/TestingResource.java
+++ b/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/client/resources/TestingResource.java
@@ -24,6 +24,7 @@ import javax.ws.rs.GET;
import javax.ws.rs.POST;
import javax.ws.rs.PUT;
import javax.ws.rs.Path;
+import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.QueryParam;
import javax.ws.rs.core.MediaType;
@@ -68,4 +69,10 @@ public interface TestingResource {
@Path("/remove-expired")
@Produces(MediaType.APPLICATION_JSON)
Response removeExpired(@QueryParam("realm") final String realm);
+
+ @GET
+ @Path("/cache/{cache}/{id}")
+ @Produces(MediaType.APPLICATION_JSON)
+ boolean isCached(@PathParam("cache") String cacheName, @PathParam("id") String id);
+
}
diff --git a/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/util/OAuthClient.java b/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/util/OAuthClient.java
index e294879..0ba3824 100644
--- a/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/util/OAuthClient.java
+++ b/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/util/OAuthClient.java
@@ -101,9 +101,14 @@ public class OAuthClient {
public AuthorizationCodeResponse doLogin(String username, String password) {
openLoginForm();
String src = driver.getPageSource();
- driver.findElement(By.id("username")).sendKeys(username);
- driver.findElement(By.id("password")).sendKeys(password);
- driver.findElement(By.name("login")).click();
+ try {
+ driver.findElement(By.id("username")).sendKeys(username);
+ driver.findElement(By.id("password")).sendKeys(password);
+ driver.findElement(By.name("login")).click();
+ } catch (Throwable t) {
+ System.err.println(src);
+ throw t;
+ }
return new AuthorizationCodeResponse(this);
}
diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/AbstractKeycloakTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/AbstractKeycloakTest.java
index 3a79611..8dfcdf0 100644
--- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/AbstractKeycloakTest.java
+++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/AbstractKeycloakTest.java
@@ -133,7 +133,7 @@ public abstract class AbstractKeycloakTest {
MASTER, ADMIN, ADMIN, Constants.ADMIN_CLI_CLIENT_ID);
deleteMeOAuthClient = new DeleteMeOAuthClient(AuthServerTestEnricher.getAuthServerContextRoot() + "/auth");
- testingClient = KeycloakTestingClient.getInstance(AuthServerTestEnricher.getAuthServerContextRoot() + "/auth");
+ getTestingClient();
adminUser = createAdminUserRepresentation();
@@ -188,6 +188,13 @@ public abstract class AbstractKeycloakTest {
loginPage.setAuthRealm(MASTER);
}
+ protected KeycloakTestingClient getTestingClient() {
+ if (testingClient == null) {
+ testingClient = KeycloakTestingClient.getInstance(AuthServerTestEnricher.getAuthServerContextRoot() + "/auth");
+ }
+ return testingClient;
+ }
+
public abstract void addTestRealms(List<RealmRepresentation> testRealms);
private void addTestRealms() {
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 1119eb7..cc13724 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
@@ -58,8 +58,8 @@ public abstract class AbstractFuseExampleAdapterTest extends AbstractExampleAdap
@Override
public void addAdapterTestRealms(List<RealmRepresentation> testRealms) {
- RealmRepresentation fureRealm = loadRealm(new File(EXAMPLES_HOME_DIR + "/fuse/testrealm.json"));
- testRealms.add(fureRealm);
+ RealmRepresentation fuseRealm = loadRealm(new File(EXAMPLES_HOME_DIR + "/fuse/testrealm.json"));
+ testRealms.add(fuseRealm);
}
@Override
@@ -121,6 +121,7 @@ public abstract class AbstractFuseExampleAdapterTest extends AbstractExampleAdap
pause(500);
assertCurrentUrlStartsWith(customerPortal);
+ customerPortal.navigateTo();//needed for phantomjs
customerPortal.clickAdminInterfaceLink();
assertCurrentUrlStartsWithLoginUrlOf(testRealmPage);
diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/group/GroupMappersTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/group/GroupMappersTest.java
index c1e59bd..d61a517 100644
--- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/group/GroupMappersTest.java
+++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/group/GroupMappersTest.java
@@ -109,7 +109,6 @@ public class GroupMappersTest extends AbstractGroupTest {
@Test
@SuppressWarnings("unchecked")
public void testGroupMappers() throws Exception {
- events.clear();
RealmResource realm = adminClient.realms().realm("test");
{
UserRepresentation user = realm.users().search("topGroupUser", -1, -1).get(0);
diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/realm/RealmTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/realm/RealmTest.java
index 84bb1b5..599c1cc 100755
--- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/realm/RealmTest.java
+++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/realm/RealmTest.java
@@ -18,30 +18,46 @@
package org.keycloak.testsuite.admin.realm;
import org.apache.commons.io.IOUtils;
+import org.junit.Rule;
import org.junit.Test;
+import org.keycloak.OAuth2Constants;
import org.keycloak.admin.client.Keycloak;
import org.keycloak.admin.client.resource.ServerInfoResource;
import org.keycloak.common.util.StreamUtil;
+import org.keycloak.common.util.Time;
import org.keycloak.models.Constants;
+import org.keycloak.representations.adapters.action.GlobalRequestResult;
+import org.keycloak.representations.adapters.action.PushNotBeforeAction;
import org.keycloak.representations.idm.ClientRepresentation;
+import org.keycloak.representations.idm.EventRepresentation;
import org.keycloak.representations.idm.RealmRepresentation;
import org.keycloak.representations.idm.RoleRepresentation;
+import org.keycloak.representations.idm.UserRepresentation;
import org.keycloak.testsuite.Assert;
+import org.keycloak.testsuite.AssertEvents;
import org.keycloak.testsuite.admin.AbstractAdminTest;
+import org.keycloak.testsuite.admin.ApiUtil;
import org.keycloak.testsuite.arquillian.AuthServerTestEnricher;
import org.keycloak.testsuite.auth.page.AuthRealm;
+import org.keycloak.testsuite.util.CredentialBuilder;
+import org.keycloak.testsuite.util.OAuthClient.AccessTokenResponse;
+import org.keycloak.testsuite.util.RealmBuilder;
+import org.keycloak.testsuite.util.UserBuilder;
import org.keycloak.util.JsonSerialization;
import javax.ws.rs.BadRequestException;
import javax.ws.rs.NotFoundException;
+import javax.ws.rs.core.Response;
import java.io.IOException;
import java.util.Collections;
import java.util.LinkedList;
import java.util.List;
import java.util.HashSet;
import java.util.Arrays;
+import java.util.Map;
import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
@@ -52,6 +68,9 @@ import static org.junit.Assert.fail;
*/
public class RealmTest extends AbstractAdminTest {
+ @Rule
+ public AssertEvents events = new AssertEvents(this);
+
public static final String PRIVATE_KEY = "MIICXAIBAAKBgQCrVrCuTtArbgaZzL1hvh0xtL5mc7o0NqPVnYXkLvgcwiC3BjLGw1tGEGoJaXDuSaRllobm53JBhjx33UNv+5z/UMG4kytBWxheNVKnL6GgqlNabMaFfPLPCF8kAgKnsi79NMo+n6KnSY8YeUmec/p2vjO2NjsSAVcWEQMVhJ31LwIDAQABAoGAfmO8gVhyBxdqlxmIuglbz8bcjQbhXJLR2EoS8ngTXmN1bo2L90M0mUKSdc7qF10LgETBzqL8jYlQIbt+e6TH8fcEpKCjUlyq0Mf/vVbfZSNaVycY13nTzo27iPyWQHK5NLuJzn1xvxxrUeXI6A2WFpGEBLbHjwpx5WQG9A+2scECQQDvdn9NE75HPTVPxBqsEd2z10TKkl9CZxu10Qby3iQQmWLEJ9LNmy3acvKrE3gMiYNWb6xHPKiIqOR1as7L24aTAkEAtyvQOlCvr5kAjVqrEKXalj0Tzewjweuxc0pskvArTI2Oo070h65GpoIKLc9jf+UA69cRtquwP93aZKtW06U8dQJAF2Y44ks/mK5+eyDqik3koCI08qaC8HYq2wVl7G2QkJ6sbAaILtcvD92ToOvyGyeE0flvmDZxMYlvaZnaQ0lcSQJBAKZU6umJi3/xeEbkJqMfeLclD27XGEFoPeNrmdx0q10Azp4NfJAY+Z8KRyQCR2BEG+oNitBOZ+YXF9KCpH3cdmECQHEigJhYg+ykOvr1aiZUMFT72HU0jnmQe2FVekuG+LJUt2Tm7GtMjTFoGpf0JwrVuZN39fOYAlo+nTixgeW7X8Y=";
public static final String PUBLIC_KEY = "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCrVrCuTtArbgaZzL1hvh0xtL5mc7o0NqPVnYXkLvgcwiC3BjLGw1tGEGoJaXDuSaRllobm53JBhjx33UNv+5z/UMG4kytBWxheNVKnL6GgqlNabMaFfPLPCF8kAgKnsi79NMo+n6KnSY8YeUmec/p2vjO2NjsSAVcWEQMVhJ31LwIDAQAB";
public static final String CERTIFICATE = "MIICsTCCAZkCBgFTLB5bhDANBgkqhkiG9w0BAQsFADAcMRowGAYDVQQDDBFhZG1pbi1jbGllbnQtdGVzdDAeFw0xNjAyMjkwODIwMDBaFw0yNjAyMjgwODIxNDBaMBwxGjAYBgNVBAMMEWFkbWluLWNsaWVudC10ZXN0MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAquzJtpAlpTFnJzILjTOHW+SOWav1eIsCtlAqiFTvBskbod6b4BtVaR3FVrQm8rFiwDOIEWT3IG3ZIz0LKYxnqvuffyLHGHjiroqrR63kY9Wa9B790lSEWVaGeNOMnKleqKu5QUNfL3wVebUh/C/QfxZ29R1EIbxNe2ThN8yuIca8Ltn43D5VlyatptojffxpCYiYqAmIwQDaq1um2cQ+4rPBLxC5jM9UBvYOMUP4u0caNSaPI1o9lHVKgTtWcdQzUeMmAGsnLV26XGhA/OwRduUxksumR1kh/KSqowasjgSrpVqtF/uo5TY57s7drD+zKG58cdHLreclB9AQNvNwZwIDAQABMA0GCSqGSIb3DQEBCwUAA4IBAQBh4iwg8GnadeQP52pV5vKJ4Z8A1R2aYCzoW7Lc3FI/pXWX9Af5dKILX5O2j/daamPS+WtDWxIuwvZC5drrkvJn/r8e4KstnXQzPQggIJbI9v3wfIX3VlFvwvZVGiuE5PSLSWb0L57PEojZVpIU5bLchq4yRSD2zK4dWX8Y6I/D40a74KDvPOlEL8405/T1iW7ytKT9awNJW04N91owoI+kdUL+DMnnGzIxDAoYAeZI/1vcwoaH24zyTLGItkzpKxqLOdB05cnxn5jCWY2Hyd1zqtRkadhgZaqu4lcDHAHEMDp6dEjLZW8ym8bnlto+MD2y//CsyPCzyCLlA726vrli";
@@ -425,4 +444,135 @@ public class RealmTest extends AbstractAdminTest {
assertEquals(certificate, rep.getCertificate());
}
+ @Test
+ public void clearRealmCache() {
+ RealmRepresentation realmRep = realm.toRepresentation();
+ assertTrue(testingClient.testing().isCached("realms", realmRep.getId()));
+ adminClient.realm("master").clearRealmCache();
+ assertFalse(testingClient.testing().isCached("realms", realmRep.getId()));
+ }
+
+ @Test
+ public void clearUserCache() {
+ UserRepresentation user = new UserRepresentation();
+ user.setUsername("clearcacheuser");
+ Response response = realm.users().create(user);
+ String userId = ApiUtil.getCreatedId(response);
+ response.close();
+
+ realm.users().get(userId).toRepresentation();
+
+ assertTrue(testingClient.testing().isCached("users", userId));
+ adminClient.realm("master").clearUserCache();
+ assertFalse(testingClient.testing().isCached("users", userId));
+ }
+
+ @Test
+ public void pushNotBefore() {
+ setupTestAppAndUser();
+
+ int time = Time.currentTime() - 60;
+
+ RealmRepresentation rep = realm.toRepresentation();
+ rep.setNotBefore(time);
+ realm.update(rep);
+
+ GlobalRequestResult globalRequestResult = realm.pushRevocation();
+ assertEquals(1, globalRequestResult.getSuccessRequests().size());
+ assertEquals("http://localhost:8180/auth/realms/master/app/admin", globalRequestResult.getSuccessRequests().get(0));
+ assertNull(globalRequestResult.getFailedRequests());
+
+ PushNotBeforeAction adminPushNotBefore = testingClient.testApp().getAdminPushNotBefore();
+ assertEquals(time, adminPushNotBefore.getNotBefore());
+ }
+
+ @Test
+ public void logoutAll() {
+ setupTestAppAndUser();
+
+ Response response = realm.users().create(UserBuilder.create().username("user").build());
+ String userId = ApiUtil.getCreatedId(response);
+ response.close();
+
+ realm.users().get(userId).resetPassword(CredentialBuilder.create().password("password").build());
+
+ oauth.doLogin("user", "password");
+
+ GlobalRequestResult globalRequestResult = realm.logoutAll();
+ assertEquals(1, globalRequestResult.getSuccessRequests().size());
+ assertEquals("http://localhost:8180/auth/realms/master/app/admin", globalRequestResult.getSuccessRequests().get(0));
+ assertNull(globalRequestResult.getFailedRequests());
+
+ assertNotNull(testingClient.testApp().getAdminLogoutAction());
+ }
+
+ @Test
+ public void deleteSession() {
+ setupTestAppAndUser();
+
+ oauth.doLogin("testuser", "password");
+ AccessTokenResponse tokenResponse = oauth.doAccessTokenRequest(oauth.getCurrentQuery().get(OAuth2Constants.CODE), "secret");
+ assertEquals(200, tokenResponse.getStatusCode());
+
+ EventRepresentation event = events.poll();
+ assertNotNull(event);
+
+ realm.deleteSession(event.getSessionId());
+ try {
+ realm.deleteSession(event.getSessionId());
+ fail("Expected 404");
+ } catch (NotFoundException e) {
+ }
+
+ tokenResponse = oauth.doRefreshTokenRequest(tokenResponse.getRefreshToken(), "secret");
+ assertEquals(400, tokenResponse.getStatusCode());
+ assertEquals("Session not active", tokenResponse.getErrorDescription());
+ }
+
+ @Test
+ public void clientSessionStats() {
+ setupTestAppAndUser();
+
+ List<Map<String, String>> sessionStats = realm.getClientSessionStats();
+ assertTrue(sessionStats.isEmpty());
+
+ System.out.println(sessionStats.size());
+
+ oauth.doLogin("testuser", "password");
+ AccessTokenResponse tokenResponse = oauth.doAccessTokenRequest(oauth.getCurrentQuery().get(OAuth2Constants.CODE), "secret");
+ assertEquals(200, tokenResponse.getStatusCode());
+
+ sessionStats = realm.getClientSessionStats();
+
+ assertEquals(1, sessionStats.size());
+ assertEquals("test-app", sessionStats.get(0).get("clientId"));
+ assertEquals("1", sessionStats.get(0).get("active"));
+ }
+
+ private void setupTestAppAndUser() {
+ realm.update(RealmBuilder.edit(realm.toRepresentation()).testEventListener().build());
+
+ testingClient.testApp().clearAdminActions();
+
+ String redirectUri = oauth.getRedirectUri().replace("/master/", "/" + REALM_NAME + "/");
+
+ ClientRepresentation client = new ClientRepresentation();
+ client.setClientId("test-app");
+ client.setAdminUrl(suiteContext.getAuthServerInfo().getContextRoot() + "/auth/realms/master/app/admin");
+ client.setRedirectUris(Collections.singletonList(redirectUri));
+ client.setSecret("secret");
+ realm.clients().create(client);
+
+ oauth.realm(REALM_NAME);
+ oauth.redirectUri(redirectUri);
+
+ Response response = realm.users().create(UserBuilder.create().username("testuser").build());
+ String userId = ApiUtil.getCreatedId(response);
+ response.close();
+
+ realm.users().get(userId).resetPassword(CredentialBuilder.create().password("password").build());
+
+ testingClient.testApp().clearAdminActions();
+ }
+
}
diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/AssertEvents.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/AssertEvents.java
index 56d2fd2..69e4a4c 100644
--- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/AssertEvents.java
+++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/AssertEvents.java
@@ -63,12 +63,9 @@ public class AssertEvents implements TestRule {
return new Statement() {
@Override
public void evaluate() throws Throwable {
- try {
- base.evaluate();
- } finally {
- // TODO Test should fail if there are leftover events
- context.testingClient.testing().clearQueue();
- }
+ context.getTestingClient().testing().clearQueue();
+ base.evaluate();
+ // TODO Test should fail if there are leftover events
}
};
}
diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/util/ClientManager.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/util/ClientManager.java
index 9c06c5d..5654814 100644
--- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/util/ClientManager.java
+++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/util/ClientManager.java
@@ -4,7 +4,7 @@ import org.keycloak.admin.client.resource.ClientResource;
import org.keycloak.admin.client.resource.RealmResource;
import org.keycloak.representations.idm.ClientRepresentation;
-import java.util.Map;
+import java.util.LinkedHashMap;
import static org.keycloak.testsuite.admin.ApiUtil.findClientByClientId;
@@ -49,9 +49,17 @@ public class ClientManager {
public void updateAttribute(String attribute, String value) {
ClientRepresentation app = clientResource.toRepresentation();
+ if (app.getAttributes() == null) {
+ app.setAttributes(new LinkedHashMap<String, String>());
+ }
app.getAttributes().put(attribute, value);
clientResource.update(app);
}
+ public void directAccessGrant(Boolean enable) {
+ ClientRepresentation app = clientResource.toRepresentation();
+ app.setDirectAccessGrantsEnabled(enable);
+ clientResource.update(app);
+ }
}
}
diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/util/RealmManager.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/util/RealmManager.java
index 59b9486..030f798 100644
--- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/util/RealmManager.java
+++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/util/RealmManager.java
@@ -23,4 +23,16 @@ public class RealmManager {
realmRepresentation.setAccessCodeLifespan(accessCodeLifespan);
realm.update(realmRepresentation);
}
+
+ public void verifyEmail(Boolean enabled) {
+ RealmRepresentation rep = realm.toRepresentation();
+ rep.setVerifyEmail(enabled);
+ realm.update(rep);
+ }
+
+ public void passwordPolicy(String passwordPolicy) {
+ RealmRepresentation rep = realm.toRepresentation();
+ rep.setPasswordPolicy(passwordPolicy);
+ realm.update(rep);
+ }
}
\ No newline at end of file
diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/util/UserBuilder.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/util/UserBuilder.java
index a8a0cbe..21dcc0e 100644
--- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/util/UserBuilder.java
+++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/util/UserBuilder.java
@@ -114,6 +114,20 @@ public class UserBuilder {
return this;
}
+ public UserBuilder totpSecret(String totpSecret) {
+ if (rep.getCredentials() == null) {
+ rep.setCredentials(new LinkedList<CredentialRepresentation>());
+ }
+
+ CredentialRepresentation credential = new CredentialRepresentation();
+ credential.setType(CredentialRepresentation.TOTP);
+ credential.setValue(totpSecret);
+
+ rep.getCredentials().add(credential);
+ rep.setTotp(true);
+ return this;
+ }
+
public UserRepresentation build() {
return rep;
}
diff --git a/testsuite/integration-arquillian/tests/other/adapters/karaf/fuse62/src/test/java/org/keycloak/testsuite/adapter/example/Fuse62ExampleAdapterTest.java b/testsuite/integration-arquillian/tests/other/adapters/karaf/fuse62/src/test/java/org/keycloak/testsuite/adapter/example/Fuse62ExampleAdapterTest.java
index 73af6e9..1a6e304 100644
--- a/testsuite/integration-arquillian/tests/other/adapters/karaf/fuse62/src/test/java/org/keycloak/testsuite/adapter/example/Fuse62ExampleAdapterTest.java
+++ b/testsuite/integration-arquillian/tests/other/adapters/karaf/fuse62/src/test/java/org/keycloak/testsuite/adapter/example/Fuse62ExampleAdapterTest.java
@@ -1,3 +1,19 @@
+/*
+ * 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.example;
import org.keycloak.testsuite.arquillian.annotation.AppServerContainer;