From 996389d61b1996ac6fe2ce2264fba0616f006055 Mon Sep 17 00:00:00 2001 From: Sebastian Laskawiec Date: Mon, 11 Feb 2019 14:28:38 +0100 Subject: [PATCH] KEYCLOAK-9512 Run x509 tests by default --- .../integration-arquillian/HOW-TO-RUN.md | 11 ----- .../integration-arquillian/tests/base/pom.xml | 6 --- .../testsuite/pages/AbstractPage.java | 5 +++ .../testsuite/util/PhantomJSBrowser.java | 30 ++++++++++++++ .../org/keycloak/testsuite/hok/HoKTest.java | 10 +++-- .../x509/AbstractX509AuthenticationTest.java | 41 ++++++++++++++++++- ...09BrowserLoginSubjectAltNameEmailTest.java | 16 ++++++++ .../testsuite/x509/X509BrowserLoginTest.java | 34 ++++++++++++--- .../testsuite/x509/X509DirectGrantTest.java | 13 ++++++ .../X509OCSPResponderSpecificCertTest.java | 12 ++++++ .../testsuite/x509/X509OCSPResponderTest.java | 12 ++++++ .../base/src/test/resources/arquillian.xml | 5 +++ 12 files changed, 166 insertions(+), 29 deletions(-) create mode 100644 testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/util/PhantomJSBrowser.java diff --git a/testsuite/integration-arquillian/HOW-TO-RUN.md b/testsuite/integration-arquillian/HOW-TO-RUN.md index 17d6316e32..27d923b216 100644 --- a/testsuite/integration-arquillian/HOW-TO-RUN.md +++ b/testsuite/integration-arquillian/HOW-TO-RUN.md @@ -511,17 +511,6 @@ To use a mobile browser you need to create a virtual device. The most convenient * **Supported mobile OS version:** iOS 11.x * **Run with:** `mvn clean test -Pios -Dappium.deviceName=device_name` where the device name is your device identification (e.g. `iPhone X`) -## Run X.509 tests - -To run the X.509 client certificate authentication tests: - - mvn -f testsuite/integration-arquillian/pom.xml \ - clean install \ - -Pauth-server-wildfly \ - -Dauth.server.ssl.required \ - -Dbrowser=phantomjs \ - "-Dtest=*.x509.*" - ## Disabling TLS (SSL) in the tests All tests are executed with TLS by default. In order to disable it, you need to switch the `auth.server.ssl.required` property off. diff --git a/testsuite/integration-arquillian/tests/base/pom.xml b/testsuite/integration-arquillian/tests/base/pom.xml index 6730eb0d6d..32d34529c6 100644 --- a/testsuite/integration-arquillian/tests/base/pom.xml +++ b/testsuite/integration-arquillian/tests/base/pom.xml @@ -41,10 +41,6 @@ **/cluster/**/*Test.java **/crossdc/**/*Test.java - - **/x509/*Test.java - - **/hok/**/*Test.java @@ -185,8 +181,6 @@ ${exclude.client} ${exclude.cluster} ${exclude.crossdc} - ${exclude.x509} - ${exclude.HoK} testsuiteVmId diff --git a/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/pages/AbstractPage.java b/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/pages/AbstractPage.java index 3f551ad370..8642568e9f 100755 --- a/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/pages/AbstractPage.java +++ b/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/pages/AbstractPage.java @@ -60,4 +60,9 @@ public abstract class AbstractPage { abstract public void open() throws Exception; + public void setDriver(WebDriver driver) { + this.driver = driver ; + oauth.setDriver(driver); + } + } diff --git a/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/util/PhantomJSBrowser.java b/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/util/PhantomJSBrowser.java new file mode 100644 index 0000000000..f8ce1db2a8 --- /dev/null +++ b/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/util/PhantomJSBrowser.java @@ -0,0 +1,30 @@ +/* + * Copyright 2019 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.util; + +import org.jboss.arquillian.drone.api.annotation.Qualifier; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +@Retention(RetentionPolicy.RUNTIME) +@Target({ElementType.FIELD, ElementType.PARAMETER}) +@Qualifier +public @interface PhantomJSBrowser { +} diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/hok/HoKTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/hok/HoKTest.java index 28bf78b772..9188848758 100644 --- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/hok/HoKTest.java +++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/hok/HoKTest.java @@ -29,10 +29,7 @@ import org.apache.http.client.methods.CloseableHttpResponse; import org.apache.http.impl.client.CloseableHttpClient; import org.hamcrest.Matchers; import org.jboss.arquillian.drone.api.annotation.Drone; -import org.junit.Assert; -import org.junit.Before; -import org.junit.Rule; -import org.junit.Test; +import org.junit.*; import org.keycloak.OAuth2Constants; import org.keycloak.OAuthErrorException; import org.keycloak.admin.client.resource.ClientResource; @@ -113,6 +110,11 @@ public class HoKTest extends AbstractTestRealmKeycloakTest { configTestRealmForTokenIntrospection(testRealm); } + @BeforeClass + public static void checkIfTLSIsTurnedOn() { + Assume.assumeTrue(AUTH_SERVER_SSL_REQUIRED); + } + private void addRedirectUrlForTls(RealmRepresentation testRealm, String clientId) { for (ClientRepresentation client : testRealm.getClients()) { if (client.getClientId().equals(clientId)) { diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/x509/AbstractX509AuthenticationTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/x509/AbstractX509AuthenticationTest.java index 4d1b22491a..e5190ee005 100644 --- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/x509/AbstractX509AuthenticationTest.java +++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/x509/AbstractX509AuthenticationTest.java @@ -18,8 +18,10 @@ package org.keycloak.testsuite.x509; +import org.jboss.arquillian.graphene.page.Page; import org.jboss.logging.Logger; import org.junit.Assert; +import org.junit.Assume; import org.junit.Before; import org.junit.BeforeClass; import org.junit.Rule; @@ -42,14 +44,21 @@ import org.keycloak.representations.idm.UserRepresentation; import org.keycloak.testsuite.AbstractTestRealmKeycloakTest; import org.keycloak.testsuite.AssertEvents; import org.keycloak.testsuite.admin.ApiUtil; +import org.keycloak.testsuite.pages.AbstractPage; import org.keycloak.testsuite.util.AdminEventPaths; import org.keycloak.testsuite.util.AssertAdminEvents; import org.keycloak.testsuite.util.ClientBuilder; +import org.keycloak.testsuite.util.DroneUtils; +import org.keycloak.testsuite.util.PhantomJSBrowser; import org.keycloak.testsuite.util.RealmBuilder; import org.keycloak.testsuite.util.UserBuilder; +import org.openqa.selenium.WebDriver; import javax.ws.rs.core.Response; +import java.lang.reflect.Field; import java.net.URI; +import java.util.ArrayList; +import java.util.Arrays; import java.util.HashMap; import java.util.List; import java.util.Map; @@ -67,7 +76,6 @@ import static org.keycloak.authentication.authenticators.x509.X509AuthenticatorC * @version $Revision: 1 $ * @since 10/28/2016 */ - public abstract class AbstractX509AuthenticationTest extends AbstractTestRealmKeycloakTest { public static final String EMPTY_CRL_PATH = "empty.crl"; @@ -103,9 +111,15 @@ public abstract class AbstractX509AuthenticationTest extends AbstractTestRealmKe return true; } + @Before + public void validateConfiguration() { + Assume.assumeTrue("Only JBoss AS has proper certificate configuration", isAuthServerJBoss()); + Assume.assumeTrue(AUTH_SERVER_SSL_REQUIRED); + } + @BeforeClass public static void onBeforeTestClass() { - if (Boolean.parseBoolean(System.getProperty("auth.server.jboss"))) { + if (isAuthServerJBoss()) { String authServerHome = System.getProperty("auth.server.home"); if (authServerHome != null && System.getProperty("auth.server.ssl.required") != null) { @@ -124,6 +138,10 @@ public abstract class AbstractX509AuthenticationTest extends AbstractTestRealmKe } } + private static boolean isAuthServerJBoss() { + return Boolean.parseBoolean(System.getProperty("auth.server.jboss")); + } + @Before public void configureFlows() { authMgmtResource = adminClient.realms().realm(REALM_NAME).flows(); @@ -373,4 +391,23 @@ public abstract class AbstractX509AuthenticationTest extends AbstractTestRealmKe updateUser(user); } + + public void replaceDefaultWebDriver(WebDriver driver) { + this.driver = driver; + DroneUtils.addWebDriver(driver); + + List allFields = new ArrayList<>(); + allFields.addAll(Arrays.asList(this.getClass().getDeclaredFields())); + allFields.addAll(Arrays.asList(this.getClass().getFields())); + for (Field f : allFields) { + if (f.getAnnotation(Page.class) != null) { + try { + AbstractPage page = (AbstractPage) f.get(this); + page.setDriver(driver); + } catch (IllegalAccessException e) { + throw new IllegalStateException("Could not replace the driver in " + f, e); + } + } + } + } } diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/x509/X509BrowserLoginSubjectAltNameEmailTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/x509/X509BrowserLoginSubjectAltNameEmailTest.java index e8cfc37e76..a91a492ff2 100644 --- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/x509/X509BrowserLoginSubjectAltNameEmailTest.java +++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/x509/X509BrowserLoginSubjectAltNameEmailTest.java @@ -17,8 +17,10 @@ package org.keycloak.testsuite.x509; +import org.jboss.arquillian.drone.api.annotation.Drone; import org.jboss.arquillian.graphene.page.Page; import org.junit.Assert; +import org.junit.Before; import org.junit.BeforeClass; import org.junit.Test; import org.keycloak.OAuth2Constants; @@ -28,6 +30,8 @@ import org.keycloak.representations.idm.AuthenticatorConfigRepresentation; import org.keycloak.testsuite.pages.AppPage; import org.keycloak.testsuite.pages.LoginPage; import org.keycloak.testsuite.pages.x509.X509IdentityConfirmationPage; +import org.keycloak.testsuite.util.PhantomJSBrowser; +import org.openqa.selenium.WebDriver; /** * @author Peter Nalyvayko @@ -38,14 +42,26 @@ import org.keycloak.testsuite.pages.x509.X509IdentityConfirmationPage; public class X509BrowserLoginSubjectAltNameEmailTest extends AbstractX509AuthenticationTest { @Page + @PhantomJSBrowser protected AppPage appPage; @Page + @PhantomJSBrowser protected X509IdentityConfirmationPage loginConfirmationPage; @Page + @PhantomJSBrowser protected LoginPage loginPage; + @Drone + @PhantomJSBrowser + private WebDriver phantomJS; + + @Before + public void replaceTheDefaultDriver() { + replaceDefaultWebDriver(phantomJS); + } + @BeforeClass public static void onBeforeTestClass() { if (Boolean.parseBoolean(System.getProperty("auth.server.jboss"))) { diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/x509/X509BrowserLoginTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/x509/X509BrowserLoginTest.java index 51f44530ae..9bb72ed229 100644 --- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/x509/X509BrowserLoginTest.java +++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/x509/X509BrowserLoginTest.java @@ -18,8 +18,11 @@ package org.keycloak.testsuite.x509; +import org.jboss.arquillian.drone.api.annotation.Drone; import org.jboss.arquillian.graphene.page.Page; +import org.jboss.arquillian.junit.InSequence; import org.junit.Assert; +import org.junit.Before; import org.junit.Test; import org.keycloak.OAuth2Constants; import org.keycloak.authentication.authenticators.x509.X509AuthenticatorConfigModel; @@ -43,6 +46,14 @@ import static org.keycloak.authentication.authenticators.x509.X509AuthenticatorC import static org.keycloak.authentication.authenticators.x509.X509AuthenticatorConfigModel.MappingSourceType.SUBJECTDN_EMAIL; import org.keycloak.testsuite.ProfileAssume; import org.keycloak.testsuite.util.DroneUtils; +import org.keycloak.testsuite.util.JavascriptBrowser; +import org.keycloak.testsuite.util.PhantomJSBrowser; +import org.keycloak.testsuite.util.SecondBrowser; +import org.openqa.selenium.WebDriver; +import org.openqa.selenium.firefox.FirefoxDriver; +import org.openqa.selenium.phantomjs.PhantomJSDriver; + +import java.util.List; /** * @author Peter Nalyvayko @@ -53,16 +64,27 @@ import org.keycloak.testsuite.util.DroneUtils; public class X509BrowserLoginTest extends AbstractX509AuthenticationTest { @Page + @PhantomJSBrowser protected AppPage appPage; @Page + @PhantomJSBrowser protected X509IdentityConfirmationPage loginConfirmationPage; @Page + @PhantomJSBrowser protected LoginPage loginPage; - private void login(X509AuthenticatorConfigModel config, String userId, String username, String attemptedUsername) { + @Drone + @PhantomJSBrowser + private WebDriver phantomJS; + @Before + public void replaceTheDefaultDriver() { + replaceDefaultWebDriver(phantomJS); + } + + private void login(X509AuthenticatorConfigModel config, String userId, String username, String attemptedUsername) { AuthenticatorConfigRepresentation cfg = newConfig("x509-browser-config", config.getConfig()); String cfgId = createConfig(browserExecution.getId(), cfg); Assert.assertNotNull(cfgId); @@ -492,28 +514,28 @@ public class X509BrowserLoginTest extends AbstractX509AuthenticationTest { @Test public void changeLocaleOnX509InfoPage() { ProfileAssume.assumeCommunity(); - + AuthenticatorConfigRepresentation cfg = newConfig("x509-browser-config", createLoginSubjectEmail2UsernameOrEmailConfig().getConfig()); String cfgId = createConfig(browserExecution.getId(), cfg); Assert.assertNotNull(cfgId); log.debug("Open confirm page"); loginConfirmationPage.open(); - + log.debug("check if on confirm page"); Assert.assertThat(loginConfirmationPage.getSubjectDistinguishedNameText(), startsWith("EMAILADDRESS=test-user@localhost")); log.debug("check if locale is EN"); Assert.assertThat(loginConfirmationPage.getLanguageDropdownText(), is(equalTo("English"))); - + log.debug("change locale to DE"); loginConfirmationPage.openLanguage("Deutsch"); log.debug("check if locale is DE"); Assert.assertThat(loginConfirmationPage.getLanguageDropdownText(), is(equalTo("Deutsch"))); Assert.assertThat(DroneUtils.getCurrentDriver().getPageSource(), containsString("X509 Client Zertifikat:")); - + log.debug("confirm cert"); loginConfirmationPage.confirm(); - + log.debug("check if logged in"); Assert.assertThat(appPage.getRequestType(), is(equalTo(AppPage.RequestType.AUTH_RESPONSE))); } diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/x509/X509DirectGrantTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/x509/X509DirectGrantTest.java index 51cd9527c2..6a6fece759 100644 --- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/x509/X509DirectGrantTest.java +++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/x509/X509DirectGrantTest.java @@ -18,7 +18,9 @@ package org.keycloak.testsuite.x509; +import org.jboss.arquillian.drone.api.annotation.Drone; import org.junit.Assert; +import org.junit.Before; import org.junit.Ignore; import org.junit.Test; import org.keycloak.OAuth2Constants; @@ -30,6 +32,8 @@ import org.keycloak.representations.RefreshToken; import org.keycloak.representations.idm.AuthenticatorConfigRepresentation; import org.keycloak.representations.idm.UserRepresentation; import org.keycloak.testsuite.util.OAuthClient; +import org.keycloak.testsuite.util.PhantomJSBrowser; +import org.openqa.selenium.WebDriver; import javax.ws.rs.core.Response; @@ -48,6 +52,15 @@ import static org.keycloak.authentication.authenticators.x509.X509AuthenticatorC public class X509DirectGrantTest extends AbstractX509AuthenticationTest { + @Drone + @PhantomJSBrowser + private WebDriver phantomJS; + + @Before + public void replaceTheDefaultDriver() { + replaceDefaultWebDriver(phantomJS); + } + @Test public void loginFailedOnDuplicateUsers() throws Exception { diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/x509/X509OCSPResponderSpecificCertTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/x509/X509OCSPResponderSpecificCertTest.java index 330b6dec89..aaa369dc1c 100644 --- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/x509/X509OCSPResponderSpecificCertTest.java +++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/x509/X509OCSPResponderSpecificCertTest.java @@ -18,6 +18,7 @@ package org.keycloak.testsuite.x509; +import org.jboss.arquillian.drone.api.annotation.Drone; import org.junit.After; import org.junit.Assert; import org.junit.Before; @@ -35,6 +36,8 @@ import static org.keycloak.authentication.authenticators.x509.X509AuthenticatorC import io.undertow.Undertow; import io.undertow.server.handlers.BlockingHandler; +import org.keycloak.testsuite.util.PhantomJSBrowser; +import org.openqa.selenium.WebDriver; /** * Verifies Certificate revocation using OCSP responder but specifying specific @@ -53,6 +56,15 @@ public class X509OCSPResponderSpecificCertTest extends AbstractX509Authenticatio private Undertow ocspResponder; + @Drone + @PhantomJSBrowser + private WebDriver phantomJS; + + @Before + public void replaceTheDefaultDriver() { + replaceDefaultWebDriver(phantomJS); + } + @Test public void loginFailedInvalidResponderOnOCSPResponderRevocationCheck() throws Exception { X509AuthenticatorConfigModel config = new X509AuthenticatorConfigModel() diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/x509/X509OCSPResponderTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/x509/X509OCSPResponderTest.java index 96146622cd..3573efefa6 100644 --- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/x509/X509OCSPResponderTest.java +++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/x509/X509OCSPResponderTest.java @@ -18,6 +18,7 @@ package org.keycloak.testsuite.x509; +import org.jboss.arquillian.drone.api.annotation.Drone; import org.junit.After; import org.junit.Assert; import org.junit.Before; @@ -35,6 +36,8 @@ import static org.keycloak.authentication.authenticators.x509.X509AuthenticatorC import io.undertow.Undertow; import io.undertow.server.handlers.BlockingHandler; +import org.keycloak.testsuite.util.PhantomJSBrowser; +import org.openqa.selenium.WebDriver; /** * Verifies Certificate revocation using OCSP responder. @@ -53,6 +56,15 @@ public class X509OCSPResponderTest extends AbstractX509AuthenticationTest { private Undertow ocspResponder; + @Drone + @PhantomJSBrowser + private WebDriver phantomJS; + + @Before + public void replaceTheDefaultDriver() { + replaceDefaultWebDriver(phantomJS); + } + @Test public void loginFailedOnOCSPResponderRevocationCheck() throws Exception { X509AuthenticatorConfigModel config = diff --git a/testsuite/integration-arquillian/tests/base/src/test/resources/arquillian.xml b/testsuite/integration-arquillian/tests/base/src/test/resources/arquillian.xml index 2c9368fe4d..101d92c23d 100644 --- a/testsuite/integration-arquillian/tests/base/src/test/resources/arquillian.xml +++ b/testsuite/integration-arquillian/tests/base/src/test/resources/arquillian.xml @@ -87,6 +87,11 @@ ${js.chromeArguments} + + phantomjs + ${webdriverDownloadBinaries} + + ${browser} ${firefox_binary}