diff --git a/examples/js-console/src/main/webapp/WEB-INF/web.xml b/examples/js-console/src/main/webapp/WEB-INF/web.xml new file mode 100644 index 0000000000..a7460c2e9f --- /dev/null +++ b/examples/js-console/src/main/webapp/WEB-INF/web.xml @@ -0,0 +1,8 @@ + + + + js-console + \ No newline at end of file diff --git a/testsuite/integration-arquillian/tests/adapters/wildfly/src/test/java/org/keycloak/testsuite/adapter/example/WildflyDemoExampleAdapterTest.java b/testsuite/integration-arquillian/tests/adapters/wildfly/src/test/java/org/keycloak/testsuite/adapter/example/WildflyDemoExampleAdapterTest.java new file mode 100644 index 0000000000..3f1aa7de16 --- /dev/null +++ b/testsuite/integration-arquillian/tests/adapters/wildfly/src/test/java/org/keycloak/testsuite/adapter/example/WildflyDemoExampleAdapterTest.java @@ -0,0 +1,14 @@ +package org.keycloak.testsuite.adapter.example; + +import org.keycloak.testsuite.arquillian.annotation.AdapterLibsLocationProperty; +import org.keycloak.testsuite.arquillian.annotation.AppServerContainer; + +/** + * + * @author tkyjovsk + */ +@AppServerContainer("app-server-wildfly") +@AdapterLibsLocationProperty("adapter.libs.wildfly") +public class WildflyDemoExampleAdapterTest extends AbstractDemoExampleAdapterTest { + +} \ No newline at end of file diff --git a/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/admin/ApiUtil.java b/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/admin/ApiUtil.java index a196fc7601..78c8f6f540 100644 --- a/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/admin/ApiUtil.java +++ b/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/admin/ApiUtil.java @@ -17,21 +17,22 @@ */ package org.keycloak.testsuite.admin; +import org.jboss.logging.Logger; +import org.keycloak.admin.client.resource.ClientResource; import org.keycloak.admin.client.resource.RealmResource; +import org.keycloak.admin.client.resource.UserResource; import org.keycloak.representations.idm.ClientRepresentation; +import org.keycloak.representations.idm.CredentialRepresentation; +import org.keycloak.representations.idm.RoleRepresentation; +import org.keycloak.representations.idm.UserRepresentation; import javax.ws.rs.core.Response; import java.net.URI; import java.util.ArrayList; import java.util.Arrays; import java.util.List; -import org.jboss.logging.Logger; -import org.keycloak.admin.client.resource.ClientResource; -import org.keycloak.admin.client.resource.UserResource; -import org.keycloak.representations.idm.CredentialRepresentation; + import static org.keycloak.representations.idm.CredentialRepresentation.PASSWORD; -import org.keycloak.representations.idm.RoleRepresentation; -import org.keycloak.representations.idm.UserRepresentation; /** * Created by st on 28.05.15. @@ -58,6 +59,15 @@ public class ApiUtil { return null; } + public static ClientResource findClientResourceByName(RealmResource realm, String name) { + for (ClientRepresentation c : realm.clients().findAll()) { + if (c.getName().equals(name)) { + return realm.clients().get(c.getId()); + } + } + return null; + } + public static ClientRepresentation findClientByClientId(RealmResource realm, String clientId) { ClientRepresentation client = null; for (ClientRepresentation c : realm.clients().findAll()) { diff --git a/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/auth/page/AuthRealm.java b/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/auth/page/AuthRealm.java index e8a435c1aa..f6ba6b4b81 100644 --- a/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/auth/page/AuthRealm.java +++ b/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/auth/page/AuthRealm.java @@ -1,15 +1,16 @@ package org.keycloak.testsuite.auth.page; -import org.keycloak.testsuite.auth.page.login.PageWithLoginUrl; -import java.net.URI; -import javax.ws.rs.core.UriBuilder; import org.keycloak.protocol.oidc.OIDCLoginProtocolService; +import org.keycloak.testsuite.auth.page.login.PageWithLoginUrl; + +import javax.ws.rs.core.UriBuilder; +import java.net.URI; /** * Keycloak realm. - * + *

* URL: http://localhost:${auth.server.http.port}/auth/realms/{authRealm} - * + * * @author tkyjovsk */ public class AuthRealm extends AuthServer implements PageWithLoginUrl { @@ -22,7 +23,7 @@ public class AuthRealm extends AuthServer implements PageWithLoginUrl { public static final String EXAMPLE = "example"; public static final String ADMIN = "admin"; - + public AuthRealm() { setUriParameter(AUTH_REALM, MASTER); } @@ -46,7 +47,6 @@ public class AuthRealm extends AuthServer implements PageWithLoginUrl { } /** - * * @return OIDC Login URL for authRealm */ @Override @@ -55,4 +55,9 @@ public class AuthRealm extends AuthServer implements PageWithLoginUrl { .build(getAuthRealm()); } + public URI getOIDCLogoutUrl() { + return OIDCLoginProtocolService.logoutUrl(UriBuilder.fromPath(getAuthRoot())) + .build(getAuthRealm()); + } + } diff --git a/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/auth/page/account/Applications.java b/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/auth/page/account/Applications.java index 5623198eda..7e50272750 100644 --- a/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/auth/page/account/Applications.java +++ b/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/auth/page/account/Applications.java @@ -17,14 +17,16 @@ */ package org.keycloak.testsuite.auth.page.account; -import java.util.List; -import javax.ws.rs.core.UriBuilder; +import org.openqa.selenium.By; import org.openqa.selenium.WebElement; import org.openqa.selenium.support.FindBy; +import javax.ws.rs.core.UriBuilder; +import java.util.List; + /** - * * @author Petr Mensik + * @author mhajas */ public class Applications extends AccountManagement { @@ -39,26 +41,42 @@ public class Applications extends AccountManagement { @FindBy(xpath = XPATH_APP_TABLE) protected WebElement appTable; - @FindBy(xpath = XPATH_APP_TABLE + "//a") - protected List applicationLinks; - + @FindBy(xpath = XPATH_APP_TABLE + "//tr") + private List applicationRows; + public boolean containsApplication(String application) { - boolean contains = false; - for (WebElement appLink : applicationLinks) { - if (appLink.getText().equals(application)) { - contains = true; - break; - } - } - return contains; - } - - public void clickApplication(String application) { - for (WebElement appLink : applicationLinks) { - if (appLink.getText().equals(application)) { - appLink.click(); - } - } + return getRowForLinkText(application) != null; } + public void clickApplication(String application) { + WebElement row = getRowForLinkText(application); + if (row == null) { + log.error("Application: " + application + " doesn't exist"); + throw new IllegalArgumentException("Application: " + application + " doesn't exist"); + } + + row.findElement(By.xpath(".//a")).click(); + } + + public void revokeGrantForApplication(String application) { + WebElement row = getRowForLinkText(application); + if (row == null) { + log.error("Application: " + application + " doesn't exist"); + throw new IllegalArgumentException("Application: " + application + " doesn't exist"); + } + + row.findElement(By.xpath("//button[@id='revoke-" + application + "']")).click(); + } + + private WebElement getRowForLinkText(String appLink) { + for (WebElement appRow : applicationRows) { + if (appRow.findElement(By.xpath(".//td")).getText().equals(appLink)) { + return appRow; + } + } + + return null; + } + + } diff --git a/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/auth/page/login/OAuthGrant.java b/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/auth/page/login/OAuthGrant.java new file mode 100644 index 0000000000..e3280143f2 --- /dev/null +++ b/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/auth/page/login/OAuthGrant.java @@ -0,0 +1,50 @@ +/* + * JBoss, Home of Professional Open Source. + * Copyright 2012, Red Hat, Inc., and individual contributors + * as indicated by the @author tags. See the copyright.txt file in the + * distribution for a full listing of individual contributors. + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this software; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA, or see the FSF site: http://www.fsf.org. + */ +package org.keycloak.testsuite.auth.page.login; + +import org.openqa.selenium.WebElement; +import org.openqa.selenium.support.FindBy; + +/** + * @author Stian Thorgersen + */ +public class OAuthGrant extends LoginActions { + + @FindBy(css = "input[name=\"accept\"]") + private WebElement acceptButton; + @FindBy(css = "input[name=\"cancel\"]") + private WebElement cancelButton; + + + public void accept() { + acceptButton.click(); + } + + public void cancel() { + cancelButton.click(); + } + + @Override + public boolean isCurrent() { + return driver.getTitle().equals("OAuth Grant"); + } +} diff --git a/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/console/page/clients/ClientSettingsForm.java b/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/console/page/clients/ClientSettingsForm.java index 41cdf71d21..589e68e0ab 100644 --- a/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/console/page/clients/ClientSettingsForm.java +++ b/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/console/page/clients/ClientSettingsForm.java @@ -1,15 +1,17 @@ package org.keycloak.testsuite.console.page.clients; -import java.util.ArrayList; -import java.util.List; import org.keycloak.representations.idm.ClientRepresentation; -import static org.keycloak.testsuite.auth.page.login.Login.OIDC; -import static org.keycloak.testsuite.util.WaitUtils.pause; +import org.keycloak.testsuite.console.page.fragment.OnOffSwitch; import org.openqa.selenium.WebElement; import org.openqa.selenium.support.FindBy; +import java.util.ArrayList; +import java.util.List; + +import static org.keycloak.testsuite.auth.page.login.Login.OIDC; +import static org.keycloak.testsuite.util.WaitUtils.pause; + /** - * * @author tkyjovsk */ public class ClientSettingsForm extends CreateClientForm { @@ -26,6 +28,9 @@ public class ClientSettingsForm extends CreateClientForm { @FindBy(xpath = ".//i[contains(@data-ng-click, 'deleteWebOrigin')]") private List deleteWebOriginIcons; + @FindBy(xpath = ".//div[@class='onoffswitch' and ./input[@id='consentRequired']]") + private OnOffSwitch consentRequired; + public void setBaseUrl(String baseUrl) { setInputValue(baseUrlInput, baseUrl); } @@ -88,4 +93,8 @@ public class ClientSettingsForm extends CreateClientForm { return values; } + public void setConsentRequired(boolean value) { + consentRequired.setOn(value); + } + } diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/adapter/example/AbstractDemoExampleAdapterTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/adapter/example/AbstractDemoExampleAdapterTest.java index d31d390e48..4d0eed9ba6 100644 --- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/adapter/example/AbstractDemoExampleAdapterTest.java +++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/adapter/example/AbstractDemoExampleAdapterTest.java @@ -1,34 +1,71 @@ package org.keycloak.testsuite.adapter.example; -import org.keycloak.testsuite.adapter.AbstractExampleAdapterTest; -import java.io.File; -import java.io.IOException; -import java.util.List; import org.jboss.arquillian.container.test.api.Deployment; import org.jboss.arquillian.graphene.page.Page; import org.jboss.shrinkwrap.api.spec.WebArchive; -import org.junit.*; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; +import org.keycloak.admin.client.resource.ClientResource; +import org.keycloak.representations.idm.ClientRepresentation; import org.keycloak.representations.idm.RealmRepresentation; -import org.keycloak.testsuite.auth.page.account.Account; -import static org.keycloak.testsuite.util.IOUtil.loadRealm; -import static org.keycloak.testsuite.util.URLAssert.assertCurrentUrlStartsWith; +import org.keycloak.testsuite.adapter.AbstractExampleAdapterTest; import org.keycloak.testsuite.adapter.page.CustomerPortalExample; import org.keycloak.testsuite.adapter.page.DatabaseServiceExample; import org.keycloak.testsuite.adapter.page.ProductPortalExample; -import static org.keycloak.testsuite.auth.page.AuthRealm.DEMO; +import org.keycloak.testsuite.admin.ApiUtil; +import org.keycloak.testsuite.auth.page.account.Account; +import org.keycloak.testsuite.auth.page.account.Applications; +import org.keycloak.testsuite.auth.page.login.OAuthGrant; +import org.keycloak.testsuite.console.page.clients.ClientSettings; +import org.keycloak.testsuite.console.page.clients.Clients; +import org.keycloak.testsuite.console.page.events.Config; +import org.keycloak.testsuite.console.page.events.LoginEvents; import org.openqa.selenium.By; +import org.openqa.selenium.WebElement; + +import java.io.File; +import java.io.IOException; +import java.util.Arrays; +import java.util.List; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; +import static org.keycloak.testsuite.auth.page.AuthRealm.DEMO; +import static org.keycloak.testsuite.util.IOUtil.loadRealm; +import static org.keycloak.testsuite.util.URLAssert.assertCurrentUrlStartsWith; public abstract class AbstractDemoExampleAdapterTest extends AbstractExampleAdapterTest { @Page - private CustomerPortalExample customerPortalExample; - @Page - private ProductPortalExample productPortalExample; - @Page - private DatabaseServiceExample databaseServiceExample; + private CustomerPortalExample customerPortalExamplePage; @Page - private Account testRealmAccount; + private ProductPortalExample productPortalExamplePage; + + @Page + private DatabaseServiceExample databaseServiceExamplePage; + + @Page + private Account testRealmAccountPage; + + @Page + private Clients clientsPage; + + @Page + private ClientSettings clientSettingsPage; + + @Page + private Config configPage; + + @Page + private LoginEvents loginEventsPage; + + @Page + private OAuthGrant oAuthGrantPage; + + @Page + private Applications applicationsPage; @Deployment(name = CustomerPortalExample.DEPLOYMENT_NAME) private static WebArchive customerPortalExample() throws IOException { @@ -56,27 +93,31 @@ public abstract class AbstractDemoExampleAdapterTest extends AbstractExampleAdap super.setDefaultPageUriParameters(); testRealmPage.setAuthRealm(DEMO); testRealmLoginPage.setAuthRealm(DEMO); - testRealmAccount.setAuthRealm(DEMO); + testRealmAccountPage.setAuthRealm(DEMO); + clientsPage.setConsoleRealm(DEMO); + configPage.setConsoleRealm(DEMO); + loginEventsPage.setConsoleRealm(DEMO); + applicationsPage.setAuthRealm(DEMO); } @Before public void beforeDemoExampleTest() { - customerPortalExample.navigateTo(); + customerPortalExamplePage.navigateTo(); driver.manage().deleteAllCookies(); - productPortalExample.navigateTo(); + productPortalExamplePage.navigateTo(); driver.manage().deleteAllCookies(); } @Test public void customerPortalListingTest() { - customerPortalExample.navigateTo(); - customerPortalExample.customerListing(); + customerPortalExamplePage.navigateTo(); + customerPortalExamplePage.customerListing(); testRealmLoginPage.form().login("bburke@redhat.com", "password"); - assertCurrentUrlStartsWith(customerPortalExample); - customerPortalExample.waitForCustomerListingHeader(); + assertCurrentUrlStartsWith(customerPortalExamplePage); + customerPortalExamplePage.waitForCustomerListingHeader(); Assert.assertTrue(driver.getPageSource().contains("Username: bburke@redhat.com")); Assert.assertTrue(driver.getPageSource().contains("Bill Burke")); @@ -86,72 +127,140 @@ public abstract class AbstractDemoExampleAdapterTest extends AbstractExampleAdap @Test public void customerPortalSessionTest() { - customerPortalExample.navigateTo(); - customerPortalExample.customerSession(); + customerPortalExamplePage.navigateTo(); + customerPortalExamplePage.customerSession(); testRealmLoginPage.form().login("bburke@redhat.com", "password"); - assertCurrentUrlStartsWith(customerPortalExample); + assertCurrentUrlStartsWith(customerPortalExamplePage); - customerPortalExample.waitForCustomerSessionHeader(); + customerPortalExamplePage.waitForCustomerSessionHeader(); Assert.assertTrue(driver.getPageSource().contains("You visited this page")); } @Test public void productPortalListingTest() { - productPortalExample.navigateTo(); - productPortalExample.productListing(); + productPortalExamplePage.navigateTo(); + productPortalExamplePage.productListing(); testRealmLoginPage.form().login("bburke@redhat.com", "password"); - assertCurrentUrlStartsWith(productPortalExample); - productPortalExample.waitForProductListingHeader(); + assertCurrentUrlStartsWith(productPortalExamplePage); + productPortalExamplePage.waitForProductListingHeader(); Assert.assertTrue(driver.getPageSource().contains("iphone")); Assert.assertTrue(driver.getPageSource().contains("ipad")); Assert.assertTrue(driver.getPageSource().contains("ipod")); - productPortalExample.goToCustomers(); + productPortalExamplePage.goToCustomers(); } @Test public void goToProductPortalWithOneLoginTest() { - productPortalExample.navigateTo(); - productPortalExample.productListing(); + productPortalExamplePage.navigateTo(); + productPortalExamplePage.productListing(); testRealmLoginPage.form().login("bburke@redhat.com", "password"); - assertCurrentUrlStartsWith(productPortalExample); - productPortalExample.waitForProductListingHeader(); - productPortalExample.goToCustomers(); + assertCurrentUrlStartsWith(productPortalExamplePage); + productPortalExamplePage.waitForProductListingHeader(); + productPortalExamplePage.goToCustomers(); - assertCurrentUrlStartsWith(customerPortalExample); - customerPortalExample.customerListing(); - customerPortalExample.goToProducts(); - assertCurrentUrlStartsWith(productPortalExample); + assertCurrentUrlStartsWith(customerPortalExamplePage); + customerPortalExamplePage.customerListing(); + customerPortalExamplePage.goToProducts(); + assertCurrentUrlStartsWith(productPortalExamplePage); } @Test public void logoutFromAllAppsTest() { - productPortalExample.navigateTo(); - productPortalExample.productListing(); + productPortalExamplePage.navigateTo(); + productPortalExamplePage.productListing(); testRealmLoginPage.form().login("bburke@redhat.com", "password"); - assertCurrentUrlStartsWith(productPortalExample); - productPortalExample.waitForProductListingHeader(); + assertCurrentUrlStartsWith(productPortalExamplePage); + productPortalExamplePage.waitForProductListingHeader(); - productPortalExample.logOut(); - assertCurrentUrlStartsWith(productPortalExample); - productPortalExample.productListing(); + if (isRelative()) { //KEYCLOAK-1546 + productPortalExamplePage.logOut(); + } else { + driver.navigate().to(testRealmPage.getOIDCLogoutUrl() + "?redirect_uri=" + productPortalExamplePage); + } - customerPortalExample.navigateTo(); - customerPortalExample.customerListing(); + assertCurrentUrlStartsWith(productPortalExamplePage); + productPortalExamplePage.productListing(); + + customerPortalExamplePage.navigateTo(); + customerPortalExamplePage.customerListing(); testRealmLoginPage.form().login("bburke@redhat.com", "password"); - customerPortalExample.logOut(); + customerPortalExamplePage.logOut(); + } + + @Test + public void grantServerBasedApp() { + clientsPage.navigateTo(); + loginPage.form().login(adminUser); + + ClientResource clientResource = ApiUtil.findClientResourceByClientId(testRealmResource(), "customer-portal"); + ClientRepresentation client = clientResource.toRepresentation(); + client.setConsentRequired(true); + clientResource.update(client); + + RealmRepresentation realm = testRealmResource().toRepresentation(); + realm.setEventsEnabled(true); + realm.setEnabledEventTypes(Arrays.asList("REVOKE_GRANT", "LOGIN")); + testRealmResource().update(realm); + + customerPortalExamplePage.navigateTo(); + customerPortalExamplePage.customerSession(); + + loginPage.form().login("bburke@redhat.com", "password"); + + assertTrue(oAuthGrantPage.isCurrent()); + + oAuthGrantPage.accept(); + + assertTrue(driver.getPageSource().contains("Your hostname:")); + assertTrue(driver.getPageSource().contains("You visited this page")); + + applicationsPage.navigateTo(); + applicationsPage.revokeGrantForApplication("customer-portal"); + + customerPortalExamplePage.navigateTo(); + customerPortalExamplePage.customerSession(); + + assertTrue(oAuthGrantPage.isCurrent()); + + loginEventsPage.navigateTo(); + loginEventsPage.table().filter(); + loginEventsPage.table().filterForm().addEventType("REVOKE_GRANT"); + loginEventsPage.table().update(); + + List resultList = loginEventsPage.table().rows(); + + assertEquals(2, resultList.size()); + + resultList.get(0).findElement(By.xpath(".//td[text()='REVOKE_GRANT']")); + resultList.get(0).findElement(By.xpath(".//td[text()='Client']/../td[text()='account']")); + resultList.get(0).findElement(By.xpath(".//td[text()='IP Address']/../td[text()='127.0.0.1']")); + resultList.get(0).findElement(By.xpath(".//td[text()='revoked_client']/../td[text()='customer-portal']")); + + loginEventsPage.table().reset(); + loginEventsPage.table().filterForm().addEventType("LOGIN"); + loginEventsPage.table().update(); + resultList = loginEventsPage.table().rows(); + + assertEquals(7, resultList.size()); + + resultList.get(0).findElement(By.xpath(".//td[text()='LOGIN']")); + resultList.get(0).findElement(By.xpath(".//td[text()='Client']/../td[text()='customer-portal']")); + resultList.get(0).findElement(By.xpath(".//td[text()='IP Address']/../td[text()='127.0.0.1']")); + resultList.get(0).findElement(By.xpath(".//td[text()='username']/../td[text()='bburke@redhat.com']")); + resultList.get(0).findElement(By.xpath(".//td[text()='consent']/../td[text()='consent_granted']")); } } diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/adapter/example/AbstractJSConsoleExampleAdapterTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/adapter/example/AbstractJSConsoleExampleAdapterTest.java index 61d8efae50..ab638626f8 100644 --- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/adapter/example/AbstractJSConsoleExampleAdapterTest.java +++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/adapter/example/AbstractJSConsoleExampleAdapterTest.java @@ -1,26 +1,59 @@ package org.keycloak.testsuite.adapter.example; -import org.keycloak.testsuite.adapter.AbstractExampleAdapterTest; -import java.io.File; -import java.io.IOException; -import java.util.List; import org.jboss.arquillian.container.test.api.Deployment; import org.jboss.arquillian.graphene.page.Page; import org.jboss.shrinkwrap.api.spec.WebArchive; -import static org.junit.Assert.assertTrue; import org.junit.Test; +import org.keycloak.admin.client.resource.ClientResource; +import org.keycloak.representations.idm.ClientRepresentation; import org.keycloak.representations.idm.RealmRepresentation; -import static org.keycloak.testsuite.util.IOUtil.loadRealm; -import static org.keycloak.testsuite.util.URLAssert.assertCurrentUrlStartsWith; +import org.keycloak.testsuite.adapter.AbstractExampleAdapterTest; import org.keycloak.testsuite.adapter.page.JSConsoleExample; +import org.keycloak.testsuite.admin.ApiUtil; +import org.keycloak.testsuite.auth.page.account.Applications; +import org.keycloak.testsuite.auth.page.login.OAuthGrant; +import org.keycloak.testsuite.console.page.clients.ClientSettings; +import org.keycloak.testsuite.console.page.clients.Clients; +import org.keycloak.testsuite.console.page.events.Config; +import org.keycloak.testsuite.console.page.events.LoginEvents; +import org.openqa.selenium.By; +import org.openqa.selenium.WebElement; + +import java.io.File; +import java.io.IOException; +import java.util.Arrays; +import java.util.List; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; import static org.keycloak.testsuite.auth.page.AuthRealm.EXAMPLE; +import static org.keycloak.testsuite.util.IOUtil.loadRealm; import static org.keycloak.testsuite.util.URLAssert.assertCurrentUrlDoesntStartWith; +import static org.keycloak.testsuite.util.URLAssert.assertCurrentUrlStartsWith; import static org.keycloak.testsuite.util.WaitUtils.pause; public abstract class AbstractJSConsoleExampleAdapterTest extends AbstractExampleAdapterTest { @Page - private JSConsoleExample jsConsoleExample; + private JSConsoleExample jsConsoleExamplePage; + + @Page + private Clients clientsPage; + + @Page + private ClientSettings clientSettingsPage; + + @Page + private Config configPage; + + @Page + private LoginEvents loginEventsPage; + + @Page + private OAuthGrant oAuthGrantPage; + + @Page + private Applications applicationsPage; public static int TOKEN_LIFESPAN_LEEWAY = 3; // seconds @@ -34,7 +67,7 @@ public abstract class AbstractJSConsoleExampleAdapterTest extends AbstractExampl RealmRepresentation jsConsoleRealm = loadRealm(new File(EXAMPLES_HOME_DIR + "/js-console/example-realm.json")); fixClientUrisUsingDeploymentUrl(jsConsoleRealm, - JSConsoleExample.CLIENT_ID, jsConsoleExample.buildUri().toASCIIString()); + JSConsoleExample.CLIENT_ID, jsConsoleExamplePage.buildUri().toASCIIString()); jsConsoleRealm.setAccessTokenLifespan(30 + TOKEN_LIFESPAN_LEEWAY); // seconds @@ -49,85 +82,157 @@ public abstract class AbstractJSConsoleExampleAdapterTest extends AbstractExampl @Test public void testJSConsoleAuth() { - jsConsoleExample.navigateTo(); - assertCurrentUrlStartsWith(jsConsoleExample); + jsConsoleExamplePage.navigateTo(); + assertCurrentUrlStartsWith(jsConsoleExamplePage); pause(1000); - jsConsoleExample.logIn(); + jsConsoleExamplePage.logIn(); testRealmLoginPage.form().login("user", "invalid-password"); - assertCurrentUrlDoesntStartWith(jsConsoleExample); + assertCurrentUrlDoesntStartWith(jsConsoleExamplePage); testRealmLoginPage.form().login("invalid-user", "password"); - assertCurrentUrlDoesntStartWith(jsConsoleExample); + assertCurrentUrlDoesntStartWith(jsConsoleExamplePage); testRealmLoginPage.form().login("user", "password"); - assertCurrentUrlStartsWith(jsConsoleExample); + assertCurrentUrlStartsWith(jsConsoleExamplePage); assertTrue(driver.getPageSource().contains("Init Success (Authenticated)")); assertTrue(driver.getPageSource().contains("Auth Success")); pause(1000); - jsConsoleExample.logOut(); - assertCurrentUrlStartsWith(jsConsoleExample); + jsConsoleExamplePage.logOut(); + assertCurrentUrlStartsWith(jsConsoleExamplePage); assertTrue(driver.getPageSource().contains("Init Success (Not Authenticated)")); } @Test public void testRefreshToken() { - jsConsoleExample.navigateTo(); - assertCurrentUrlStartsWith(jsConsoleExample); + jsConsoleExamplePage.navigateTo(); + assertCurrentUrlStartsWith(jsConsoleExamplePage); - jsConsoleExample.refreshToken(); + jsConsoleExamplePage.refreshToken(); assertTrue(driver.getPageSource().contains("Failed to refresh token")); - jsConsoleExample.logIn(); + jsConsoleExamplePage.logIn(); testRealmLoginPage.form().login("user", "password"); - assertCurrentUrlStartsWith(jsConsoleExample); + assertCurrentUrlStartsWith(jsConsoleExamplePage); assertTrue(driver.getPageSource().contains("Auth Success")); - jsConsoleExample.refreshToken(); + jsConsoleExamplePage.refreshToken(); assertTrue(driver.getPageSource().contains("Auth Refresh Success")); } @Test public void testRefreshTokenIfUnder30s() { - jsConsoleExample.navigateTo(); - assertCurrentUrlStartsWith(jsConsoleExample); + jsConsoleExamplePage.navigateTo(); + assertCurrentUrlStartsWith(jsConsoleExamplePage); - jsConsoleExample.refreshToken(); + jsConsoleExamplePage.refreshToken(); assertTrue(driver.getPageSource().contains("Failed to refresh token")); - jsConsoleExample.logIn(); + jsConsoleExamplePage.logIn(); testRealmLoginPage.form().login("user", "password"); - assertCurrentUrlStartsWith(jsConsoleExample); + assertCurrentUrlStartsWith(jsConsoleExamplePage); assertTrue(driver.getPageSource().contains("Auth Success")); - jsConsoleExample.refreshTokenIfUnder30s(); + jsConsoleExamplePage.refreshTokenIfUnder30s(); assertTrue(driver.getPageSource().contains("Token not refreshed, valid for")); pause((TOKEN_LIFESPAN_LEEWAY + 2) * 1000); - jsConsoleExample.refreshTokenIfUnder30s(); + jsConsoleExamplePage.refreshTokenIfUnder30s(); assertTrue(driver.getPageSource().contains("Auth Refresh Success")); } - - @Test + + @Test public void testGetProfile() { - jsConsoleExample.navigateTo(); - assertCurrentUrlStartsWith(jsConsoleExample); - - jsConsoleExample.getProfile(); + jsConsoleExamplePage.navigateTo(); + assertCurrentUrlStartsWith(jsConsoleExamplePage); + + jsConsoleExamplePage.getProfile(); assertTrue(driver.getPageSource().contains("Failed to load profile")); - - jsConsoleExample.logIn(); + + jsConsoleExamplePage.logIn(); testRealmLoginPage.form().login("user", "password"); - assertCurrentUrlStartsWith(jsConsoleExample); + assertCurrentUrlStartsWith(jsConsoleExamplePage); assertTrue(driver.getPageSource().contains("Auth Success")); - jsConsoleExample.getProfile(); + jsConsoleExamplePage.getProfile(); assertTrue(driver.getPageSource().contains("Failed to load profile")); assertTrue(driver.getPageSource().contains("\"username\": \"user\"")); } + @Test + public void grantBrowserBasedApp() { + testRealmPage.setAuthRealm(EXAMPLE); + testRealmLoginPage.setAuthRealm(EXAMPLE); + clientsPage.setConsoleRealm(EXAMPLE); + configPage.setConsoleRealm(EXAMPLE); + loginEventsPage.setConsoleRealm(EXAMPLE); + applicationsPage.setAuthRealm(EXAMPLE); + + jsConsoleExamplePage.navigateTo(); + driver.manage().deleteAllCookies(); + + clientsPage.navigateTo(); + + loginPage.form().login("admin", "admin"); + + ClientResource clientResource = ApiUtil.findClientResourceByClientId(testRealmResource(), "js-console"); + ClientRepresentation client = clientResource.toRepresentation(); + client.setConsentRequired(true); + clientResource.update(client); + + RealmRepresentation realm = testRealmResource().toRepresentation(); + realm.setEventsEnabled(true); + realm.setEnabledEventTypes(Arrays.asList("REVOKE_GRANT", "LOGIN")); + testRealmResource().update(realm); + + jsConsoleExamplePage.navigateTo(); + jsConsoleExamplePage.logIn(); + + testRealmLoginPage.form().login("user", "password"); + + assertTrue(oAuthGrantPage.isCurrent()); + oAuthGrantPage.accept(); + + assertTrue(driver.getPageSource().contains("Init Success (Authenticated)")); + + applicationsPage.navigateTo(); + applicationsPage.revokeGrantForApplication("js-console"); + + jsConsoleExamplePage.navigateTo(); + jsConsoleExamplePage.logIn(); + + assertTrue(oAuthGrantPage.isCurrent()); + + loginEventsPage.navigateTo(); + loginEventsPage.table().filter(); + loginEventsPage.table().filterForm().addEventType("REVOKE_GRANT"); + loginEventsPage.table().update(); + + List resultList = loginEventsPage.table().rows(); + + assertEquals(2, resultList.size()); + + resultList.get(0).findElement(By.xpath(".//td[text()='REVOKE_GRANT']")); + resultList.get(0).findElement(By.xpath(".//td[text()='Client']/../td[text()='account']")); + resultList.get(0).findElement(By.xpath(".//td[text()='IP Address']/../td[text()='127.0.0.1']")); + resultList.get(0).findElement(By.xpath(".//td[text()='revoked_client']/../td[text()='js-console']")); + + loginEventsPage.table().reset(); + loginEventsPage.table().filterForm().addEventType("LOGIN"); + loginEventsPage.table().update(); + resultList = loginEventsPage.table().rows(); + + assertEquals(7, resultList.size()); + + resultList.get(0).findElement(By.xpath(".//td[text()='LOGIN']")); + resultList.get(0).findElement(By.xpath(".//td[text()='Client']/../td[text()='js-console']")); + resultList.get(0).findElement(By.xpath(".//td[text()='IP Address']/../td[text()='127.0.0.1']")); + resultList.get(0).findElement(By.xpath(".//td[text()='username']/../td[text()='user']")); + resultList.get(0).findElement(By.xpath(".//td[text()='consent']/../td[text()='consent_granted']")); + } + } diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/console/events/ConfigTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/console/events/ConfigTest.java new file mode 100644 index 0000000000..0a58676a85 --- /dev/null +++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/console/events/ConfigTest.java @@ -0,0 +1,52 @@ +package org.keycloak.testsuite.console.events; + +import org.jboss.arquillian.graphene.page.Page; +import org.junit.Before; +import org.junit.Test; +import org.keycloak.representations.idm.RealmRepresentation; +import org.keycloak.testsuite.console.AbstractConsoleTest; +import org.keycloak.testsuite.console.page.events.Config; + +import static org.junit.Assert.*; + +/** + * @author mhajas + */ +public class ConfigTest extends AbstractConsoleTest { + + @Page + private Config configPage; + + @Before + public void beforeConfigTest() { + configPage.navigateTo(); + } + + @Test + public void configLoginEventsTest() { + configPage.form().setSaveEvents(true); + configPage.form().removeSaveType("LOGIN"); + configPage.form().addSaveType("REGISTER_NODE"); + configPage.form().setExpiration("50", "Days"); + configPage.form().save(); + assertFlashMessageSuccess(); + + RealmRepresentation realm = testRealmResource().toRepresentation(); + assertTrue(realm.isEventsEnabled()); + assertFalse(realm.getEnabledEventTypes().contains("LOGIN")); + assertTrue(realm.getEnabledEventTypes().contains("REGISTER_NODE")); + assertEquals(4320000L, realm.getEventsExpiration().longValue()); + } + + @Test + public void configAdminEventsTest() { + configPage.form().setSaveAdminEvents(true); + configPage.form().setIncludeRepresentation(true); + configPage.form().save(); + assertFlashMessageSuccess(); + + RealmRepresentation realm = testRealmResource().toRepresentation(); + assertTrue(realm.isAdminEventsEnabled()); + assertTrue(realm.isAdminEventsDetailsEnabled()); + } +}