keycloak-uncached
Changes
testsuite/integration-arquillian/servers/auth-server/services/testsuite-providers/src/main/java/org/keycloak/testsuite/rest/TestSamlApplicationResourceProvider.java 178(+178 -0)
testsuite/integration-arquillian/servers/auth-server/services/testsuite-providers/src/main/java/org/keycloak/testsuite/rest/TestSamlApplicationResourceProviderFactory.java 64(+64 -0)
testsuite/integration-arquillian/servers/auth-server/services/testsuite-providers/src/main/resources/META-INF/services/org.keycloak.services.resource.RealmResourceProviderFactory 1(+1 -0)
testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/client/KeycloakTestingClient.java 4(+3 -1)
testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/client/resources/TestSamlApplicationResource.java 55(+55 -0)
Details
diff --git a/server-spi-private/src/main/java/org/keycloak/protocol/LoginProtocol.java b/server-spi-private/src/main/java/org/keycloak/protocol/LoginProtocol.java
index 569a2c0..e367bf2 100755
--- a/server-spi-private/src/main/java/org/keycloak/protocol/LoginProtocol.java
+++ b/server-spi-private/src/main/java/org/keycloak/protocol/LoginProtocol.java
@@ -19,6 +19,7 @@ package org.keycloak.protocol;
import org.keycloak.events.EventBuilder;
import org.keycloak.models.AuthenticatedClientSessionModel;
+import org.keycloak.models.ClientModel;
import org.keycloak.models.KeycloakSession;
import org.keycloak.models.RealmModel;
import org.keycloak.models.UserSessionModel;
@@ -81,4 +82,16 @@ public interface LoginProtocol extends Provider {
*/
boolean requireReauthentication(UserSessionModel userSession, AuthenticationSessionModel authSession);
+ /**
+ * Send not-before revocation policy to the given client.
+ * @param realm
+ * @param resource
+ * @param notBefore
+ * @param managementUrl
+ * @return {@code true} if revocation policy was successfully updated at the client, {@code false} otherwise.
+ */
+ default boolean sendPushRevocationPolicyRequest(RealmModel realm, ClientModel resource, int notBefore, String managementUrl) {
+ return false;
+ }
+
}
diff --git a/services/src/main/java/org/keycloak/protocol/oidc/OIDCLoginProtocol.java b/services/src/main/java/org/keycloak/protocol/oidc/OIDCLoginProtocol.java
index eb1aede..aa0377e 100755
--- a/services/src/main/java/org/keycloak/protocol/oidc/OIDCLoginProtocol.java
+++ b/services/src/main/java/org/keycloak/protocol/oidc/OIDCLoginProtocol.java
@@ -19,7 +19,10 @@ package org.keycloak.protocol.oidc;
import org.jboss.logging.Logger;
import org.keycloak.OAuth2Constants;
import org.keycloak.OAuthErrorException;
+import org.keycloak.TokenIdGenerator;
import org.keycloak.common.util.Time;
+import org.keycloak.connections.httpclient.HttpClientProvider;
+import org.keycloak.constants.AdapterConstants;
import org.keycloak.events.Details;
import org.keycloak.events.EventBuilder;
import org.keycloak.events.EventType;
@@ -33,6 +36,7 @@ import org.keycloak.protocol.oidc.utils.OIDCRedirectUriBuilder;
import org.keycloak.protocol.oidc.utils.OIDCResponseMode;
import org.keycloak.protocol.oidc.utils.OIDCResponseType;
import org.keycloak.representations.AccessTokenResponse;
+import org.keycloak.representations.adapters.action.PushNotBeforeAction;
import org.keycloak.services.ServicesLogger;
import org.keycloak.services.managers.AuthenticationManager;
import org.keycloak.services.managers.AuthenticationSessionManager;
@@ -41,6 +45,8 @@ import org.keycloak.services.managers.ResourceAdminManager;
import org.keycloak.sessions.AuthenticationSessionModel;
import org.keycloak.util.TokenUtil;
+import java.io.IOException;
+import java.net.URI;
import javax.ws.rs.core.HttpHeaders;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.UriBuilder;
@@ -324,6 +330,23 @@ public class OIDCLoginProtocol implements LoginProtocol {
}
@Override
+ public boolean sendPushRevocationPolicyRequest(RealmModel realm, ClientModel resource, int notBefore, String managementUrl) {
+ PushNotBeforeAction adminAction = new PushNotBeforeAction(TokenIdGenerator.generateId(), Time.currentTime() + 30, resource.getClientId(), notBefore);
+ String token = new TokenManager().encodeToken(session, realm, adminAction);
+ logger.debugv("pushRevocation resource: {0} url: {1}", resource.getClientId(), managementUrl);
+ URI target = UriBuilder.fromUri(managementUrl).path(AdapterConstants.K_PUSH_NOT_BEFORE).build();
+ try {
+ int status = session.getProvider(HttpClientProvider.class).postText(target.toString(), token);
+ boolean success = status == 204 || status == 200;
+ logger.debugf("pushRevocation success for %s: %s", managementUrl, success);
+ return success;
+ } catch (IOException e) {
+ ServicesLogger.LOGGER.failedToSendRevocation(e);
+ return false;
+ }
+ }
+
+ @Override
public void close() {
}
diff --git a/services/src/main/java/org/keycloak/services/managers/ResourceAdminManager.java b/services/src/main/java/org/keycloak/services/managers/ResourceAdminManager.java
index dbb0e78..34c85b8 100755
--- a/services/src/main/java/org/keycloak/services/managers/ResourceAdminManager.java
+++ b/services/src/main/java/org/keycloak/services/managers/ResourceAdminManager.java
@@ -30,6 +30,9 @@ import org.keycloak.models.KeycloakSession;
import org.keycloak.models.RealmModel;
import org.keycloak.models.UserModel;
import org.keycloak.models.UserSessionModel;
+import org.keycloak.protocol.LoginProtocol;
+import org.keycloak.protocol.LoginProtocolFactory;
+import org.keycloak.protocol.oidc.OIDCLoginProtocol;
import org.keycloak.protocol.oidc.TokenManager;
import org.keycloak.representations.adapters.action.GlobalRequestResult;
import org.keycloak.representations.adapters.action.LogoutAction;
@@ -286,19 +289,14 @@ public class ResourceAdminManager {
}
protected boolean sendPushRevocationPolicyRequest(RealmModel realm, ClientModel resource, int notBefore, String managementUrl) {
- PushNotBeforeAction adminAction = new PushNotBeforeAction(TokenIdGenerator.generateId(), Time.currentTime() + 30, resource.getClientId(), notBefore);
- String token = new TokenManager().encodeToken(session, realm, adminAction);
- logger.debugv("pushRevocation resource: {0} url: {1}", resource.getClientId(), managementUrl);
- URI target = UriBuilder.fromUri(managementUrl).path(AdapterConstants.K_PUSH_NOT_BEFORE).build();
- try {
- int status = session.getProvider(HttpClientProvider.class).postText(target.toString(), token);
- boolean success = status == 204 || status == 200;
- logger.debugf("pushRevocation success for %s: %s", managementUrl, success);
- return success;
- } catch (IOException e) {
- ServicesLogger.LOGGER.failedToSendRevocation(e);
- return false;
+ String protocol = resource.getProtocol();
+ if (protocol == null) {
+ protocol = OIDCLoginProtocol.LOGIN_PROTOCOL;
}
+ LoginProtocol loginProtocol = (LoginProtocol) session.getProvider(LoginProtocol.class, protocol);
+ return loginProtocol == null
+ ? false
+ : loginProtocol.sendPushRevocationPolicyRequest(realm, resource, notBefore, managementUrl);
}
public GlobalRequestResult testNodesAvailability(URI requestUri, RealmModel realm, ClientModel client) {
diff --git a/testsuite/integration-arquillian/servers/auth-server/services/testsuite-providers/src/main/java/org/keycloak/testsuite/rest/TestSamlApplicationResourceProvider.java b/testsuite/integration-arquillian/servers/auth-server/services/testsuite-providers/src/main/java/org/keycloak/testsuite/rest/TestSamlApplicationResourceProvider.java
new file mode 100644
index 0000000..02e4214
--- /dev/null
+++ b/testsuite/integration-arquillian/servers/auth-server/services/testsuite-providers/src/main/java/org/keycloak/testsuite/rest/TestSamlApplicationResourceProvider.java
@@ -0,0 +1,178 @@
+/*
+ * 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.rest;
+
+import org.jboss.resteasy.annotations.cache.NoCache;
+import org.jboss.resteasy.spi.HttpRequest;
+import org.jboss.resteasy.spi.ResteasyProviderFactory;
+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.representations.adapters.action.TestAvailabilityAction;
+import org.keycloak.services.resource.RealmResourceProvider;
+import org.keycloak.services.resources.RealmsResource;
+import org.keycloak.utils.MediaType;
+
+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.QueryParam;
+import javax.ws.rs.core.MultivaluedMap;
+import javax.ws.rs.core.Response;
+import javax.ws.rs.core.UriBuilder;
+import java.util.concurrent.BlockingQueue;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * Copied from {@link TestApplicationResourceProvider}
+ * @author <a href="mailto:sthorger@redhat.com">Stian Thorgersen</a>
+ * @author Stan Silvert ssilvert@redhat.com (C) 2016 Red Hat Inc.
+ */
+public class TestSamlApplicationResourceProvider implements RealmResourceProvider {
+
+ private final KeycloakSession session;
+
+ private final BlockingQueue<LogoutAction> adminLogoutActions;
+ private final BlockingQueue<PushNotBeforeAction> adminPushNotBeforeActions;
+ private final BlockingQueue<TestAvailabilityAction> adminTestAvailabilityAction;
+
+ public TestSamlApplicationResourceProvider(KeycloakSession session, BlockingQueue<LogoutAction> adminLogoutActions,
+ BlockingQueue<PushNotBeforeAction> adminPushNotBeforeActions,
+ BlockingQueue<TestAvailabilityAction> adminTestAvailabilityAction) {
+ this.session = session;
+ this.adminLogoutActions = adminLogoutActions;
+ this.adminPushNotBeforeActions = adminPushNotBeforeActions;
+ this.adminTestAvailabilityAction = adminTestAvailabilityAction;
+ }
+
+ @POST
+ @Consumes(MediaType.TEXT_PLAIN_UTF_8)
+ @Path("/saml/k_logout")
+ public void adminLogout(String data) throws JWSInputException {
+ adminLogoutActions.add(new JWSInput(data).readJsonContent(LogoutAction.class));
+ }
+
+ @POST
+ @Consumes(MediaType.TEXT_PLAIN_UTF_8)
+ @Path("/saml/k_push_not_before")
+ public void adminPushNotBefore(String data) throws JWSInputException {
+ adminPushNotBeforeActions.add(new JWSInput(data).readJsonContent(PushNotBeforeAction.class));
+ }
+
+ @POST
+ @Consumes(MediaType.TEXT_PLAIN_UTF_8)
+ @Path("/saml/k_test_available")
+ public void testAvailable(String data) throws JWSInputException {
+ adminTestAvailabilityAction.add(new JWSInput(data).readJsonContent(TestAvailabilityAction.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);
+ }
+
+ @GET
+ @Produces(MediaType.APPLICATION_JSON)
+ @Path("/poll-test-available")
+ public TestAvailabilityAction getTestAvailable() throws InterruptedException {
+ return adminTestAvailabilityAction.poll(10, TimeUnit.SECONDS);
+ }
+
+ @POST
+ @Path("/clear-admin-actions")
+ public Response clearAdminActions() {
+ adminLogoutActions.clear();
+ adminPushNotBeforeActions.clear();
+ return Response.noContent().build();
+ }
+
+ @POST
+ @Produces(MediaType.TEXT_HTML_UTF_8)
+ @Path("/{action}")
+ public String post(@PathParam("action") String action) {
+ String title = "APP_REQUEST";
+ if (action.equals("auth")) {
+ title = "AUTH_RESPONSE";
+ } else if (action.equals("logout")) {
+ title = "LOGOUT_REQUEST";
+ }
+
+ StringBuilder sb = new StringBuilder();
+ sb.append("<html><head><title>" + title + "</title></head><body>");
+
+ sb.append("<b>Form parameters: </b><br>");
+ HttpRequest request = ResteasyProviderFactory.getContextData(HttpRequest.class);
+ MultivaluedMap<String, String> formParams = request.getDecodedFormParameters();
+ for (String paramName : formParams.keySet()) {
+ sb.append(paramName).append(": ").append("<span id=\"").append(paramName).append("\">").append(formParams.getFirst(paramName)).append("</span><br>");
+ }
+ sb.append("<br>");
+
+ UriBuilder base = UriBuilder.fromUri("http://localhost:8180/auth");
+ sb.append("<a href=\"" + RealmsResource.accountUrl(base).build("test").toString() + "\" id=\"account\">account</a>");
+
+ sb.append("</body></html>");
+ return sb.toString();
+ }
+
+ @GET
+ @Produces(MediaType.TEXT_HTML_UTF_8)
+ @Path("/{action}")
+ public String get(@PathParam("action") String action) {
+ //String requestUri = session.getContext().getUri().getRequestUri().toString();
+
+ String title = "APP_REQUEST";
+ if (action.equals("auth")) {
+ title = "AUTH_RESPONSE";
+ } else if (action.equals("logout")) {
+ title = "LOGOUT_REQUEST";
+ }
+
+ StringBuilder sb = new StringBuilder();
+ sb.append("<html><head><title>" + title + "</title></head><body>");
+ UriBuilder base = UriBuilder.fromUri("http://localhost:8180/auth");
+ sb.append("<a href=\"" + RealmsResource.accountUrl(base).build("test").toString() + "\" id=\"account\">account</a>");
+
+ sb.append("</body></html>");
+ return sb.toString();
+ }
+
+ @Override
+ public Object getResource() {
+ return this;
+ }
+
+ @Override
+ public void close() {
+
+ }
+}
diff --git a/testsuite/integration-arquillian/servers/auth-server/services/testsuite-providers/src/main/java/org/keycloak/testsuite/rest/TestSamlApplicationResourceProviderFactory.java b/testsuite/integration-arquillian/servers/auth-server/services/testsuite-providers/src/main/java/org/keycloak/testsuite/rest/TestSamlApplicationResourceProviderFactory.java
new file mode 100644
index 0000000..c9493e7
--- /dev/null
+++ b/testsuite/integration-arquillian/servers/auth-server/services/testsuite-providers/src/main/java/org/keycloak/testsuite/rest/TestSamlApplicationResourceProviderFactory.java
@@ -0,0 +1,64 @@
+/*
+ * 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.rest;
+
+import org.keycloak.Config.Scope;
+import org.keycloak.models.KeycloakSession;
+import org.keycloak.models.KeycloakSessionFactory;
+import org.keycloak.representations.adapters.action.LogoutAction;
+import org.keycloak.representations.adapters.action.PushNotBeforeAction;
+import org.keycloak.representations.adapters.action.TestAvailabilityAction;
+import org.keycloak.services.resource.RealmResourceProvider;
+import org.keycloak.services.resource.RealmResourceProviderFactory;
+
+import java.security.KeyPair;
+import java.util.List;
+import java.util.concurrent.BlockingQueue;
+import java.util.concurrent.LinkedBlockingDeque;
+
+/**
+ * @author <a href="mailto:sthorger@redhat.com">Stian Thorgersen</a>
+ */
+public class TestSamlApplicationResourceProviderFactory implements RealmResourceProviderFactory {
+
+ private final BlockingQueue<LogoutAction> adminLogoutActions = new LinkedBlockingDeque<>();
+ private final BlockingQueue<PushNotBeforeAction> pushNotBeforeActions = new LinkedBlockingDeque<>();
+ private final BlockingQueue<TestAvailabilityAction> testAvailabilityActions = new LinkedBlockingDeque<>();
+
+ @Override
+ public RealmResourceProvider create(KeycloakSession session) {
+ return new TestSamlApplicationResourceProvider(session, adminLogoutActions, pushNotBeforeActions, testAvailabilityActions);
+ }
+
+ @Override
+ public void init(Scope config) {
+ }
+
+ @Override
+ public void postInit(KeycloakSessionFactory factory) {
+ }
+
+ @Override
+ public void close() {
+ }
+
+ @Override
+ public String getId() {
+ return "saml-app";
+ }
+}
diff --git a/testsuite/integration-arquillian/servers/auth-server/services/testsuite-providers/src/main/resources/META-INF/services/org.keycloak.services.resource.RealmResourceProviderFactory b/testsuite/integration-arquillian/servers/auth-server/services/testsuite-providers/src/main/resources/META-INF/services/org.keycloak.services.resource.RealmResourceProviderFactory
index 1958ff0..810bdef 100644
--- a/testsuite/integration-arquillian/servers/auth-server/services/testsuite-providers/src/main/resources/META-INF/services/org.keycloak.services.resource.RealmResourceProviderFactory
+++ b/testsuite/integration-arquillian/servers/auth-server/services/testsuite-providers/src/main/resources/META-INF/services/org.keycloak.services.resource.RealmResourceProviderFactory
@@ -17,4 +17,5 @@
org.keycloak.testsuite.rest.TestingResourceProviderFactory
org.keycloak.testsuite.rest.TestApplicationResourceProviderFactory
+org.keycloak.testsuite.rest.TestSamlApplicationResourceProviderFactory
org.keycloak.testsuite.domainextension.rest.ExampleRealmResourceProviderFactory
\ No newline at end of file
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 57b9afc..09c280b 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
@@ -22,12 +22,12 @@ 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.TestExampleCompanyResource;
+import org.keycloak.testsuite.client.resources.TestSamlApplicationResource;
import org.keycloak.testsuite.client.resources.TestingResource;
import org.keycloak.testsuite.runonserver.*;
import org.keycloak.util.JsonSerialization;
import javax.net.ssl.HostnameVerifier;
-import javax.net.ssl.SSLSession;
/**
* @author <a href="mailto:mstrukel@redhat.com">Marko Strukelj</a>
@@ -70,6 +70,8 @@ public class KeycloakTestingClient {
public TestApplicationResource testApp() { return target.proxy(TestApplicationResource.class); }
+ public TestSamlApplicationResource testSamlApp() { return target.proxy(TestSamlApplicationResource.class); }
+
public TestExampleCompanyResource testExampleCompany() { return target.proxy(TestExampleCompanyResource.class); }
public Server server() {
diff --git a/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/client/resources/TestSamlApplicationResource.java b/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/client/resources/TestSamlApplicationResource.java
new file mode 100644
index 0000000..e0bf6d7
--- /dev/null
+++ b/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/client/resources/TestSamlApplicationResource.java
@@ -0,0 +1,55 @@
+/*
+ * 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 org.keycloak.representations.adapters.action.TestAvailabilityAction;
+import org.keycloak.utils.MediaType;
+
+import javax.ws.rs.GET;
+import javax.ws.rs.POST;
+import javax.ws.rs.Path;
+import javax.ws.rs.Produces;
+import javax.ws.rs.QueryParam;
+
+/**
+ * @author <a href="mailto:sthorger@redhat.com">Stian Thorgersen</a>
+ */
+@Path("/realms/master/saml-app")
+public interface TestSamlApplicationResource {
+
+ @GET
+ @Produces(MediaType.APPLICATION_JSON)
+ @Path("/poll-admin-logout")
+ LogoutAction getAdminLogoutAction();
+
+ @GET
+ @Produces(MediaType.APPLICATION_JSON)
+ @Path("/poll-admin-not-before")
+ PushNotBeforeAction getAdminPushNotBefore();
+
+ @GET
+ @Produces(MediaType.APPLICATION_JSON)
+ @Path("/poll-test-available")
+ TestAvailabilityAction getTestAvailable();
+
+ @POST
+ @Path("/clear-admin-actions")
+ void clearAdminActions();
+}
diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/ClientTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/ClientTest.java
index 9b001ac..7e8be2a 100644
--- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/ClientTest.java
+++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/ClientTest.java
@@ -27,6 +27,7 @@ import org.keycloak.events.admin.OperationType;
import org.keycloak.events.admin.ResourceType;
import org.keycloak.models.AccountRoles;
import org.keycloak.models.Constants;
+import org.keycloak.protocol.oidc.OIDCLoginProtocol;
import org.keycloak.protocol.oidc.OIDCLoginProtocolFactory;
import org.keycloak.representations.adapters.action.GlobalRequestResult;
import org.keycloak.representations.adapters.action.PushNotBeforeAction;
@@ -304,6 +305,7 @@ public class ClientTest extends AbstractAdminTest {
client.setAdminUrl(suiteContext.getAuthServerInfo().getContextRoot() + "/auth/realms/master/app/admin");
client.setRedirectUris(Collections.singletonList(redirectUri));
client.setSecret("secret");
+ client.setProtocol(OIDCLoginProtocol.LOGIN_PROTOCOL);
int notBefore = Time.currentTime() - 60;
client.setNotBefore(notBefore);
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 7f811c6..dbd8c43 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
@@ -30,6 +30,8 @@ import org.keycloak.common.util.Time;
import org.keycloak.events.admin.OperationType;
import org.keycloak.events.admin.ResourceType;
import org.keycloak.models.Constants;
+import org.keycloak.protocol.oidc.OIDCLoginProtocol;
+import org.keycloak.protocol.saml.SamlProtocol;
import org.keycloak.representations.adapters.action.GlobalRequestResult;
import org.keycloak.representations.adapters.action.PushNotBeforeAction;
import org.keycloak.representations.idm.AdminEventRepresentation;
@@ -49,6 +51,7 @@ import org.keycloak.testsuite.client.KeycloakTestingClient;
import org.keycloak.testsuite.runonserver.RunOnServerDeployment;
import org.keycloak.testsuite.runonserver.RunHelpers;
import org.keycloak.testsuite.util.AdminEventPaths;
+import org.keycloak.testsuite.util.ClientBuilder;
import org.keycloak.testsuite.util.CredentialBuilder;
import org.keycloak.testsuite.util.OAuthClient.AccessTokenResponse;
import org.keycloak.testsuite.util.RealmBuilder;
@@ -66,12 +69,7 @@ import java.util.LinkedList;
import java.util.List;
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;
-import static org.junit.Assert.fail;
+import static org.junit.Assert.*;
/**
* @author <a href="mailto:sthorger@redhat.com">Stian Thorgersen</a>
@@ -541,8 +539,7 @@ public class RealmTest extends AbstractAdminTest {
GlobalRequestResult globalRequestResult = realm.pushRevocation();
assertAdminEvents.assertEvent(realmId, OperationType.ACTION, "push-revocation", globalRequestResult, ResourceType.REALM);
- assertEquals(1, globalRequestResult.getSuccessRequests().size());
- assertEquals("http://localhost:8180/auth/realms/master/app/admin", globalRequestResult.getSuccessRequests().get(0));
+ assertThat(globalRequestResult.getSuccessRequests(), Matchers.containsInAnyOrder("http://localhost:8180/auth/realms/master/app/admin"));
assertNull(globalRequestResult.getFailedRequests());
PushNotBeforeAction adminPushNotBefore = testingClient.testApp().getAdminPushNotBefore();
@@ -550,6 +547,28 @@ public class RealmTest extends AbstractAdminTest {
}
@Test
+ public void pushNotBeforeWithSamlApp() {
+ setupTestAppAndUser();
+ setupTestSamlApp();
+
+ int time = Time.currentTime() - 60;
+
+ RealmRepresentation rep = realm.toRepresentation();
+ rep.setNotBefore(time);
+ realm.update(rep);
+ assertAdminEvents.assertEvent(realmId, OperationType.UPDATE, Matchers.nullValue(String.class), rep, ResourceType.REALM);
+
+ GlobalRequestResult globalRequestResult = realm.pushRevocation();
+ assertAdminEvents.assertEvent(realmId, OperationType.ACTION, "push-revocation", globalRequestResult, ResourceType.REALM);
+
+ assertThat(globalRequestResult.getSuccessRequests(), Matchers.containsInAnyOrder("http://localhost:8180/auth/realms/master/app/admin"));
+ assertThat(globalRequestResult.getFailedRequests(), Matchers.containsInAnyOrder("http://localhost:8180/auth/realms/master/saml-app/saml"));
+
+ PushNotBeforeAction adminPushNotBefore = testingClient.testApp().getAdminPushNotBefore();
+ assertEquals(time, adminPushNotBefore.getNotBefore());
+ }
+
+ @Test
public void logoutAll() {
setupTestAppAndUser();
@@ -628,6 +647,7 @@ public class RealmTest extends AbstractAdminTest {
client.setClientId("test-app");
client.setAdminUrl(suiteContext.getAuthServerInfo().getContextRoot() + "/auth/realms/master/app/admin");
client.setRedirectUris(Collections.singletonList(redirectUri));
+ client.setProtocol(OIDCLoginProtocol.LOGIN_PROTOCOL);
client.setSecret("secret");
Response resp = realm.clients().create(client);
String clientDbId = ApiUtil.getCreatedId(resp);
@@ -651,4 +671,20 @@ public class RealmTest extends AbstractAdminTest {
testingClient.testApp().clearAdminActions();
}
+ private void setupTestSamlApp() {
+ String redirectUri = oauth.getRedirectUri().replace("/master/", "/" + REALM_NAME + "/");
+ ClientRepresentation client = ClientBuilder.create()
+ .clientId("test-saml-app")
+ .protocol(SamlProtocol.LOGIN_PROTOCOL)
+ .adminUrl(suiteContext.getAuthServerInfo().getContextRoot() + "/auth/realms/master/saml-app/saml")
+ .addRedirectUri(redirectUri)
+ .secret("secret")
+ .build();
+ Response resp = realm.clients().create(client);
+ String clientDbId = ApiUtil.getCreatedId(resp);
+ getCleanup().addClientUuid(clientDbId);
+ resp.close();
+ assertAdminEvents.assertEvent(realmId, OperationType.CREATE, AdminEventPaths.clientResourcePath(clientDbId), client, ResourceType.CLIENT);
+ }
+
}