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 03694df358..dff315a2e8 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 @@ -27,6 +27,7 @@ import org.jboss.logging.Logger; import org.junit.After; import org.junit.Before; import org.junit.runner.RunWith; +import org.junit.runners.model.TestTimedOutException; import org.keycloak.admin.client.Keycloak; import org.keycloak.admin.client.resource.AuthenticationManagementResource; import org.keycloak.admin.client.resource.RealmsResource; @@ -78,6 +79,7 @@ import java.util.Collections; import java.util.List; import java.util.Map; import java.util.Scanner; +import java.util.concurrent.*; import java.util.function.Consumer; import static org.hamcrest.Matchers.equalTo; @@ -403,6 +405,34 @@ public abstract class AbstractKeycloakTest { .replace("8180", "8543"); } + protected interface ExecutableTestMethod { + void execute() throws Exception; + } + + protected void runTestWithTimeout(long timeout, ExecutableTestMethod executableTestMethod) throws Exception { + ExecutorService service = Executors.newSingleThreadExecutor(); + Callable callable = new Callable() { + public Object call() throws Exception { + executableTestMethod.execute(); + return null; + } + }; + Future result = service.submit(callable); + service.shutdown(); + try { + boolean terminated = service.awaitTermination(timeout, + TimeUnit.MILLISECONDS); + if (!terminated) { + service.shutdownNow(); + } + result.get(0, TimeUnit.MILLISECONDS); // throws the exception if one occurred during the invocation + } catch (TimeoutException e) { + throw new TestTimedOutException(timeout, TimeUnit.MILLISECONDS); + } catch (Exception e) { + throw new Exception(e); + } + } + /** * @return Return true if you wish to automatically post-process realm and replace * all http values with https (and correct ports). diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/federation/storage/ClientStorageTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/federation/storage/ClientStorageTest.java index af845ae686..a5ef55ef28 100644 --- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/federation/storage/ClientStorageTest.java +++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/federation/storage/ClientStorageTest.java @@ -132,41 +132,42 @@ public class ClientStorageTest extends AbstractTestRealmKeycloakTest { oauth.clientId("hardcoded-client"); } - @Test(timeout = 4000) - @AuthServerContainerExclude(AuthServer.REMOTE) // testingClient doesn't work with remote - public void testSearchTimeout() { - String hardcodedClient = HardcodedClientStorageProviderFactory.PROVIDER_ID; - String delayedSearch = HardcodedClientStorageProviderFactory.DELAYED_SEARCH; - String providerId = this.providerId; - testingClient.server().run(session -> { - RealmModel realm = session.realms().getRealmByName(AuthRealm.TEST); - - assertThat(session.clientStorageManager() - .searchClientsByClientIdStream(realm, "client", null, null) - .map(ClientModel::getClientId) - .collect(Collectors.toList()), - allOf( - hasItem(hardcodedClient), - hasItem("root-url-client")) - ); - - //update the provider to simulate delay during the search - ComponentModel memoryProvider = realm.getComponent(providerId); - memoryProvider.getConfig().putSingle(delayedSearch, Boolean.toString(true)); - realm.updateComponent(memoryProvider); + @Test + public void testSearchTimeout() throws Exception{ + runTestWithTimeout(4000, () -> { + String hardcodedClient = HardcodedClientStorageProviderFactory.PROVIDER_ID; + String delayedSearch = HardcodedClientStorageProviderFactory.DELAYED_SEARCH; + String providerId = this.providerId; + testingClient.server().run(session -> { + RealmModel realm = session.realms().getRealmByName(AuthRealm.TEST); - }); - - testingClient.server().run(session -> { - // search for clients and check hardcoded-client is not present - assertThat(session.clientStorageManager() - .searchClientsByClientIdStream(session.realms().getRealmByName(AuthRealm.TEST), "client", null, null) - .map(ClientModel::getClientId) - .collect(Collectors.toList()), - allOf( - not(hasItem(hardcodedClient)), - hasItem("root-url-client") - )); + assertThat(session.clientStorageManager() + .searchClientsByClientIdStream(realm, "client", null, null) + .map(ClientModel::getClientId) + .collect(Collectors.toList()), + allOf( + hasItem(hardcodedClient), + hasItem("root-url-client")) + ); + + //update the provider to simulate delay during the search + ComponentModel memoryProvider = realm.getComponent(providerId); + memoryProvider.getConfig().putSingle(delayedSearch, Boolean.toString(true)); + realm.updateComponent(memoryProvider); + + }); + + testingClient.server().run(session -> { + // search for clients and check hardcoded-client is not present + assertThat(session.clientStorageManager() + .searchClientsByClientIdStream(session.realms().getRealmByName(AuthRealm.TEST), "client", null, null) + .map(ClientModel::getClientId) + .collect(Collectors.toList()), + allOf( + not(hasItem(hardcodedClient)), + hasItem("root-url-client") + )); + }); }); } diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/federation/storage/GroupStorageTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/federation/storage/GroupStorageTest.java index 8b0a83e3a1..49cce598ad 100644 --- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/federation/storage/GroupStorageTest.java +++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/federation/storage/GroupStorageTest.java @@ -86,41 +86,42 @@ public class GroupStorageTest extends AbstractTestRealmKeycloakTest { }); } - @Test(timeout = 4000) - @AuthServerContainerExclude(AuthServer.REMOTE) // testingClient doesn't work with remote - public void testSearchTimeout() { - String hardcodedGroup = HardcodedGroupStorageProviderFactory.PROVIDER_ID; - String delayedSearch = HardcodedGroupStorageProviderFactory.DELAYED_SEARCH; - String providerId = this.providerId; - testingClient.server().run(session -> { - RealmModel realm = session.realms().getRealmByName(AuthRealm.TEST); + @Test + public void testSearchTimeout() throws Exception{ + runTestWithTimeout(4000, () -> { + String hardcodedGroup = HardcodedGroupStorageProviderFactory.PROVIDER_ID; + String delayedSearch = HardcodedGroupStorageProviderFactory.DELAYED_SEARCH; + String providerId = this.providerId; + testingClient.server().run(session -> { + RealmModel realm = session.realms().getRealmByName(AuthRealm.TEST); - assertThat(session.groupStorageManager() - .searchForGroupByName(realm, "group", null, null).stream() - .map(GroupModel::getName) - .collect(Collectors.toList()), - allOf( - hasItem(hardcodedGroup), - hasItem("sample-realm-group")) - ); + assertThat(session.groupStorageManager() + .searchForGroupByName(realm, "group", null, null).stream() + .map(GroupModel::getName) + .collect(Collectors.toList()), + allOf( + hasItem(hardcodedGroup), + hasItem("sample-realm-group")) + ); - //update the provider to simulate delay during the search - ComponentModel memoryProvider = realm.getComponent(providerId); - memoryProvider.getConfig().putSingle(delayedSearch, Boolean.toString(true)); - realm.updateComponent(memoryProvider); - }); + //update the provider to simulate delay during the search + ComponentModel memoryProvider = realm.getComponent(providerId); + memoryProvider.getConfig().putSingle(delayedSearch, Boolean.toString(true)); + realm.updateComponent(memoryProvider); + }); - testingClient.server().run(session -> { - RealmModel realm = session.realms().getRealmByName(AuthRealm.TEST); - // search for groups and check hardcoded-group is not present - assertThat(session.groupStorageManager() - .searchForGroupByName(realm, "group", null, null).stream() - .map(GroupModel::getName) - .collect(Collectors.toList()), - allOf( - not(hasItem(hardcodedGroup)), - hasItem("sample-realm-group") - )); + testingClient.server().run(session -> { + RealmModel realm = session.realms().getRealmByName(AuthRealm.TEST); + // search for groups and check hardcoded-group is not present + assertThat(session.groupStorageManager() + .searchForGroupByName(realm, "group", null, null).stream() + .map(GroupModel::getName) + .collect(Collectors.toList()), + allOf( + not(hasItem(hardcodedGroup)), + hasItem("sample-realm-group") + )); + }); }); } diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/federation/storage/RoleStorageTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/federation/storage/RoleStorageTest.java index 08771edee6..b583f76edd 100644 --- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/federation/storage/RoleStorageTest.java +++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/federation/storage/RoleStorageTest.java @@ -93,41 +93,42 @@ public class RoleStorageTest extends AbstractTestRealmKeycloakTest { }); } - @Test(timeout = 4000) - @AuthServerContainerExclude(AuthServer.REMOTE) // testingClient doesn't work with remote - public void testSearchTimeout() { - String hardcodedRole = HardcodedRoleStorageProviderFactory.PROVIDER_ID; - String delayedSearch = HardcodedRoleStorageProviderFactory.DELAYED_SEARCH; - String providerId = this.providerId; - testingClient.server().run(session -> { - RealmModel realm = session.realms().getRealmByName(AuthRealm.TEST); + @Test + public void testSearchTimeout() throws Exception{ + runTestWithTimeout(4000, () -> { + String hardcodedRole = HardcodedRoleStorageProviderFactory.PROVIDER_ID; + String delayedSearch = HardcodedRoleStorageProviderFactory.DELAYED_SEARCH; + String providerId = this.providerId; + testingClient.server().run(session -> { + RealmModel realm = session.realms().getRealmByName(AuthRealm.TEST); - assertThat(session.roleStorageManager() - .searchForRolesStream(realm, "role", null, null) - .map(RoleModel::getName) - .collect(Collectors.toList()), - allOf( - hasItem(hardcodedRole), - hasItem("sample-realm-role")) - ); + assertThat(session.roleStorageManager() + .searchForRolesStream(realm, "role", null, null) + .map(RoleModel::getName) + .collect(Collectors.toList()), + allOf( + hasItem(hardcodedRole), + hasItem("sample-realm-role")) + ); - //update the provider to simulate delay during the search - ComponentModel memoryProvider = realm.getComponent(providerId); - memoryProvider.getConfig().putSingle(delayedSearch, Boolean.toString(true)); - realm.updateComponent(memoryProvider); - }); + //update the provider to simulate delay during the search + ComponentModel memoryProvider = realm.getComponent(providerId); + memoryProvider.getConfig().putSingle(delayedSearch, Boolean.toString(true)); + realm.updateComponent(memoryProvider); + }); - testingClient.server().run(session -> { - RealmModel realm = session.realms().getRealmByName(AuthRealm.TEST); - // search for roles and check hardcoded-role is not present - assertThat(session.roleStorageManager() - .searchForRolesStream(realm, "role", null, null) - .map(RoleModel::getName) - .collect(Collectors.toList()), - allOf( - not(hasItem(hardcodedRole)), - hasItem("sample-realm-role") - )); + testingClient.server().run(session -> { + RealmModel realm = session.realms().getRealmByName(AuthRealm.TEST); + // search for roles and check hardcoded-role is not present + assertThat(session.roleStorageManager() + .searchForRolesStream(realm, "role", null, null) + .map(RoleModel::getName) + .collect(Collectors.toList()), + allOf( + not(hasItem(hardcodedRole)), + hasItem("sample-realm-role") + )); + }); }); } diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/saml/SamlXMLAttacksTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/saml/SamlXMLAttacksTest.java index 36f8e79f50..a10731473a 100644 --- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/saml/SamlXMLAttacksTest.java +++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/saml/SamlXMLAttacksTest.java @@ -43,47 +43,48 @@ import static org.keycloak.testsuite.util.Matchers.statusCodeIsHC; @AppServerContainer(ContainerConstants.APP_SERVER_TOMCAT9) public class SamlXMLAttacksTest extends AbstractSamlTest { - @Test(timeout = 4000) + @Test public void testXMLBombAttackResistance() throws Exception { + runTestWithTimeout(4000, () -> { + String bombDoctype = "" + + "" + + "" + + "" + + "" + + "" + + "" + + "" + + "" + + "" + + "" + + "]>"; - String bombDoctype = "" + - "" + - "" + - "" + - "" + - "" + - "" + - "" + - "" + - "" + - "" + - "]>"; - - String samlAuthnRequest = "" + - "" + SAML_CLIENT_ID_SALES_POST + "&lol9;" + - ""; + String samlAuthnRequest = "" + + "" + SAML_CLIENT_ID_SALES_POST + "&lol9;" + + ""; - try (CloseableHttpClient client = HttpClientBuilder.create().build()) { - HttpPost post = new HttpPost(getAuthServerSamlEndpoint(REALM_NAME)); + try (CloseableHttpClient client = HttpClientBuilder.create().build()) { + HttpPost post = new HttpPost(getAuthServerSamlEndpoint(REALM_NAME)); - List parameters = new LinkedList<>(); - String encoded = PostBindingUtil.base64Encode(bombDoctype + samlAuthnRequest); - parameters.add(new BasicNameValuePair(GeneralConstants.SAML_REQUEST_KEY, encoded)); + List parameters = new LinkedList<>(); + String encoded = PostBindingUtil.base64Encode(bombDoctype + samlAuthnRequest); + parameters.add(new BasicNameValuePair(GeneralConstants.SAML_REQUEST_KEY, encoded)); - UrlEncodedFormEntity formEntity; - try { - formEntity = new UrlEncodedFormEntity(parameters, "UTF-8"); - } catch (UnsupportedEncodingException e) { - throw new RuntimeException(e); + UrlEncodedFormEntity formEntity; + try { + formEntity = new UrlEncodedFormEntity(parameters, "UTF-8"); + } catch (UnsupportedEncodingException e) { + throw new RuntimeException(e); + } + + post.setEntity(formEntity); + + try (CloseableHttpResponse response = client.execute(post)) { + assertThat(response, bodyHC(containsString("Invalid Request"))); + } } - - post.setEntity(formEntity); - - try (CloseableHttpResponse response = client.execute(post)) { - assertThat(response, bodyHC(containsString("Invalid Request"))); - } - } + }); } @Deployment(name = "DTD")