package org.keycloak.testsuite.broker; import org.junit.After; import org.junit.Before; import org.junit.Test; import org.keycloak.admin.client.resource.IdentityProviderResource; import org.keycloak.admin.client.resource.RealmResource; import org.keycloak.admin.client.resource.UserResource; import org.keycloak.admin.client.resource.UsersResource; import org.keycloak.representations.idm.ClientRepresentation; import org.keycloak.representations.idm.IdentityProviderMapperRepresentation; import org.keycloak.representations.idm.RealmRepresentation; import org.keycloak.representations.idm.RoleRepresentation; import org.keycloak.representations.idm.UserRepresentation; import org.keycloak.testsuite.Assert; import org.keycloak.testsuite.admin.ApiUtil; import org.keycloak.testsuite.pages.ConsentPage; import org.keycloak.testsuite.util.*; import org.openqa.selenium.TimeoutException; import java.util.Collections; import java.util.List; import java.util.concurrent.TimeUnit; import java.util.stream.Collectors; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertTrue; import static org.keycloak.testsuite.admin.ApiUtil.createUserWithAdminClient; import static org.keycloak.testsuite.admin.ApiUtil.resetUserPassword; import static org.keycloak.testsuite.broker.BrokerTestConstants.USER_EMAIL; import static org.keycloak.testsuite.util.MailAssert.assertEmailAndGetUrl; import org.jboss.arquillian.graphene.page.Page; import javax.ws.rs.core.Response; import static org.keycloak.testsuite.broker.BrokerTestTools.*; public abstract class AbstractBrokerTest extends AbstractBaseBrokerTest { @Before public void beforeBrokerTest() { log.debug("creating user for realm " + bc.providerRealmName()); UserRepresentation user = new UserRepresentation(); user.setUsername(bc.getUserLogin()); user.setEmail(bc.getUserEmail()); user.setEmailVerified(true); user.setEnabled(true); RealmResource realmResource = adminClient.realm(bc.providerRealmName()); userId = createUserWithAdminClient(realmResource, user); resetUserPassword(realmResource.users().get(userId), bc.getUserPassword(), false); if (testContext.isInitialized()) { return; } log.debug("adding identity provider to realm " + bc.consumerRealmName()); RealmResource realm = adminClient.realm(bc.consumerRealmName()); realm.identityProviders().create(bc.setUpIdentityProvider(suiteContext)); // addClients List<ClientRepresentation> clients = bc.createProviderClients(suiteContext); if (clients != null) { RealmResource providerRealm = adminClient.realm(bc.providerRealmName()); for (ClientRepresentation client : clients) { log.debug("adding client " + client.getName() + " to realm " + bc.providerRealmName()); providerRealm.clients().create(client); } } clients = bc.createConsumerClients(suiteContext); if (clients != null) { RealmResource consumerRealm = adminClient.realm(bc.consumerRealmName()); for (ClientRepresentation client : clients) { log.debug("adding client " + client.getName() + " to realm " + bc.consumerRealmName()); consumerRealm.clients().create(client); } } testContext.setInitialized(true); } @Test public void testLogInAsUserInIDP() { driver.navigate().to(getAccountUrl(bc.consumerRealmName())); log.debug("Clicking social " + bc.getIDPAlias()); accountLoginPage.clickSocial(bc.getIDPAlias()); waitForPage(driver, "log in to"); Assert.assertTrue("Driver should be on the provider realm page right now", driver.getCurrentUrl().contains("/auth/realms/" + bc.providerRealmName() + "/")); log.debug("Logging in"); accountLoginPage.login(bc.getUserLogin(), bc.getUserPassword()); waitForPage(driver, "update account information"); Assert.assertTrue(updateAccountInformationPage.isCurrent()); Assert.assertTrue("We must be on correct realm right now", driver.getCurrentUrl().contains("/auth/realms/" + bc.consumerRealmName() + "/")); log.debug("Updating info on updateAccount page"); updateAccountInformationPage.updateAccountInformation(bc.getUserLogin(), bc.getUserEmail(), "Firstname", "Lastname"); UsersResource consumerUsers = adminClient.realm(bc.consumerRealmName()).users(); int userCount = consumerUsers.count(); Assert.assertTrue("There must be at least one user", userCount > 0); List<UserRepresentation> users = consumerUsers.search("", 0, userCount); boolean isUserFound = false; for (UserRepresentation user : users) { if (user.getUsername().equals(bc.getUserLogin()) && user.getEmail().equals(bc.getUserEmail())) { isUserFound = true; break; } } Assert.assertTrue("There must be user " + bc.getUserLogin() + " in realm " + bc.consumerRealmName(), isUserFound); testSingleLogout(); } @Test public void loginWithExistingUser() { testLogInAsUserInIDP(); Integer userCount = adminClient.realm(bc.consumerRealmName()).users().count(); driver.navigate().to(getAccountUrl(bc.consumerRealmName())); log.debug("Clicking social " + bc.getIDPAlias()); accountLoginPage.clickSocial(bc.getIDPAlias()); waitForPage(driver, "log in to"); Assert.assertTrue("Driver should be on the provider realm page right now", driver.getCurrentUrl().contains("/auth/realms/" + bc.providerRealmName() + "/")); accountLoginPage.login(bc.getUserLogin(), bc.getUserPassword()); assertEquals(accountPage.buildUri().toASCIIString().replace("master", "consumer") + "/", driver.getCurrentUrl()); assertEquals(userCount, adminClient.realm(bc.consumerRealmName()).users().count()); } // KEYCLOAK-2957 @Test public void testLinkAccountWithEmailVerified() { //start mail server MailServer.start(); MailServer.createEmailAccount(USER_EMAIL, "password"); try { //configure smpt server in the realm RealmRepresentation master = adminClient.realm(bc.consumerRealmName()).toRepresentation(); master.setSmtpServer(suiteContext.getSmtpServer()); adminClient.realm(bc.consumerRealmName()).update(master); //create user on consumer's site who should be linked later UserRepresentation newUser = UserBuilder.create().username("consumer").email(USER_EMAIL).enabled(true).build(); String userId = createUserWithAdminClient(adminClient.realm(bc.consumerRealmName()), newUser); resetUserPassword(adminClient.realm(bc.consumerRealmName()).users().get(userId), "password", false); //test driver.navigate().to(getAccountUrl(bc.consumerRealmName())); log.debug("Clicking social " + bc.getIDPAlias()); accountLoginPage.clickSocial(bc.getIDPAlias()); waitForPage(driver, "log in to"); Assert.assertTrue("Driver should be on the provider realm page right now", driver.getCurrentUrl().contains("/auth/realms/" + bc.providerRealmName() + "/")); log.debug("Logging in"); accountLoginPage.login(bc.getUserLogin(), bc.getUserPassword()); waitForPage(driver, "update account information"); Assert.assertTrue(updateAccountInformationPage.isCurrent()); Assert.assertTrue("We must be on correct realm right now", driver.getCurrentUrl().contains("/auth/realms/" + bc.consumerRealmName() + "/")); log.debug("Updating info on updateAccount page"); updateAccountInformationPage.updateAccountInformation("Firstname", "Lastname"); //link account by email waitForPage(driver, "account already exists"); idpConfirmLinkPage.clickLinkAccount(); String url = assertEmailAndGetUrl(MailServerConfiguration.FROM, USER_EMAIL, "Someone wants to link your ", false); log.info("navigating to url from email: " + url); driver.navigate().to(url); //test if user is logged in assertEquals(accountPage.buildUri().toASCIIString().replace("master", "consumer") + "/", driver.getCurrentUrl()); //test if the user has verified email assertTrue(adminClient.realm(bc.consumerRealmName()).users().get(userId).toRepresentation().isEmailVerified()); } finally { // stop mail server MailServer.stop(); } } // KEYCLOAK-3267 @Test public void loginWithExistingUserWithBruteForceEnabled() { adminClient.realm(bc.consumerRealmName()).update(RealmBuilder.create().bruteForceProtected(true).failureFactor(2).build()); loginWithExistingUser(); driver.navigate().to(getAccountPasswordUrl(bc.consumerRealmName())); accountPasswordPage.changePassword("password", "password"); logoutFromRealm(bc.providerRealmName()); driver.navigate().to(getAccountUrl(bc.consumerRealmName())); try { waitForPage(driver, "log in to"); } catch (TimeoutException e) { log.debug(driver.getTitle()); log.debug(driver.getPageSource()); Assert.fail("Timeout while waiting for login page"); } for (int i = 0; i < 3; i++) { try { waitForElementEnabled(driver, "login"); } catch (TimeoutException e) { Assert.fail("Timeout while waiting for login element enabled"); } accountLoginPage.login(bc.getUserLogin(), "invalid"); } assertEquals("Invalid username or password.", accountLoginPage.getError()); accountLoginPage.clickSocial(bc.getIDPAlias()); try { waitForPage(driver, "log in to"); } catch (TimeoutException e) { log.debug(driver.getTitle()); log.debug(driver.getPageSource()); Assert.fail("Timeout while waiting for login page"); } Assert.assertTrue("Driver should be on the provider realm page right now", driver.getCurrentUrl().contains("/auth/realms/" + bc.providerRealmName() + "/")); accountLoginPage.login(bc.getUserLogin(), bc.getUserPassword()); assertEquals("Account is disabled, contact admin.", errorPage.getError()); } @Page ConsentPage consentPage; // KEYCLOAK-4181 @Test public void loginWithExistingUserWithErrorFromProviderIdP() { ClientRepresentation client = adminClient.realm(bc.providerRealmName()) .clients() .findByClientId(bc.getIDPClientIdInProviderRealm(suiteContext)) .get(0); adminClient.realm(bc.providerRealmName()) .clients() .get(client.getId()) .update(ClientBuilder.edit(client).consentRequired(true).build()); driver.navigate().to(getAccountUrl(bc.consumerRealmName())); log.debug("Clicking social " + bc.getIDPAlias()); accountLoginPage.clickSocial(bc.getIDPAlias()); waitForPage(driver, "log in to"); Assert.assertTrue("Driver should be on the provider realm page right now", driver.getCurrentUrl().contains("/auth/realms/" + bc.providerRealmName() + "/")); log.debug("Logging in"); accountLoginPage.login(bc.getUserLogin(), bc.getUserPassword()); driver.manage().timeouts().pageLoadTimeout(30, TimeUnit.MINUTES); waitForPage(driver, "grant access"); consentPage.cancel(); waitForPage(driver, "log in to"); // Revert consentRequired adminClient.realm(bc.providerRealmName()) .clients() .get(client.getId()) .update(ClientBuilder.edit(client).consentRequired(false).build()); } protected void testSingleLogout() { log.debug("Testing single log out"); driver.navigate().to(getAccountUrl(bc.providerRealmName())); Assert.assertTrue("Should be logged in the account page", driver.getTitle().endsWith("Account Management")); logoutFromRealm(bc.providerRealmName()); Assert.assertTrue("Should be on " + bc.providerRealmName() + " realm", driver.getCurrentUrl().contains("/auth/realms/" + bc.providerRealmName())); driver.navigate().to(getAccountUrl(bc.consumerRealmName())); Assert.assertTrue("Should be on " + bc.consumerRealmName() + " realm on login page", driver.getCurrentUrl().contains("/auth/realms/" + bc.consumerRealmName() + "/protocol/openid-connect/")); } protected void createRolesForRealm(String realm) { RoleRepresentation managerRole = new RoleRepresentation("manager",null, false); RoleRepresentation userRole = new RoleRepresentation("user",null, false); adminClient.realm(realm).roles().create(managerRole); adminClient.realm(realm).roles().create(userRole); } protected void createRoleMappersForConsumerRealm() { log.debug("adding mappers to identity provider in realm " + bc.consumerRealmName()); RealmResource realm = adminClient.realm(bc.consumerRealmName()); IdentityProviderResource idpResource = realm.identityProviders().get(bc.getIDPAlias()); for (IdentityProviderMapperRepresentation mapper : createIdentityProviderMappers()) { mapper.setIdentityProviderAlias(bc.getIDPAlias()); Response resp = idpResource.addMapper(mapper); resp.close(); } } protected abstract Iterable<IdentityProviderMapperRepresentation> createIdentityProviderMappers(); // KEYCLOAK-3987 @Test public void grantNewRoleFromToken() { createRolesForRealm(bc.providerRealmName()); createRolesForRealm(bc.consumerRealmName()); createRoleMappersForConsumerRealm(); RoleRepresentation managerRole = adminClient.realm(bc.providerRealmName()).roles().get("manager").toRepresentation(); RoleRepresentation userRole = adminClient.realm(bc.providerRealmName()).roles().get("user").toRepresentation(); UserResource userResource = adminClient.realm(bc.providerRealmName()).users().get(userId); userResource.roles().realmLevel().add(Collections.singletonList(managerRole)); logInAsUserInIDPForFirstTime(); List<RoleRepresentation> currentRoles = userResource.roles().realmLevel().listAll(); assertEquals("There should be manager role",1, currentRoles.stream().filter(role -> role.getName().equals("manager")).collect(Collectors.toList()).size()); assertEquals("User shouldn't have user role", 0, currentRoles.stream().filter(role -> role.getName().equals("user")).collect(Collectors.toList()).size()); logoutFromRealm(bc.consumerRealmName()); userResource.roles().realmLevel().add(Collections.singletonList(userRole)); logInAsUserInIDP(); currentRoles = userResource.roles().realmLevel().listAll(); assertEquals("There should be manager role",1, currentRoles.stream().filter(role -> role.getName().equals("manager")).collect(Collectors.toList()).size()); assertEquals("There should be user role",1, currentRoles.stream().filter(role -> role.getName().equals("user")).collect(Collectors.toList()).size()); logoutFromRealm(bc.providerRealmName()); logoutFromRealm(bc.consumerRealmName()); } }