Merge pull request #2832 from ssilvert/migrate-account

KEYCLOAK-2909 Migrate account package to new testsuite
This commit is contained in:
Stian Thorgersen 2016-05-20 08:40:15 +02:00
commit fe841e560d
14 changed files with 759 additions and 1395 deletions

View file

@ -56,7 +56,7 @@ public class AccountUpdateProfilePage extends AbstractAccountPage {
@FindBy(className = "alert-error") @FindBy(className = "alert-error")
private WebElement errorMessage; private WebElement errorMessage;
private String getPath() { public String getPath() {
return RealmsResource.accountUrl(UriBuilder.fromUri(getAuthServerRoot())).build("test").toString(); return RealmsResource.accountUrl(UriBuilder.fromUri(getAuthServerRoot())).build("test").toString();
} }

View file

@ -16,64 +16,656 @@
*/ */
package org.keycloak.testsuite.account; package org.keycloak.testsuite.account;
import org.jboss.arquillian.graphene.page.Page; import org.junit.Assert;
import org.junit.After;
import org.junit.Test;
import static org.junit.Assert.assertEquals;
import org.junit.Before; import org.junit.Before;
import org.keycloak.testsuite.auth.page.account.Account; import org.junit.Rule;
import org.junit.Test;
import org.keycloak.events.Details;
import org.keycloak.events.EventType;
import org.keycloak.models.utils.TimeBasedOTP;
import org.keycloak.services.resources.AccountService;
import org.keycloak.services.resources.RealmsResource;
import org.keycloak.testsuite.AssertEvents;
import org.keycloak.testsuite.pages.AccountApplicationsPage;
import org.keycloak.testsuite.pages.AccountLogPage;
import org.keycloak.testsuite.pages.AccountPasswordPage;
import org.keycloak.testsuite.pages.AccountSessionsPage;
import org.keycloak.testsuite.pages.AccountTotpPage;
import org.keycloak.testsuite.pages.AccountUpdateProfilePage;
import org.keycloak.testsuite.pages.AppPage;
import org.keycloak.testsuite.pages.AppPage.RequestType;
import org.keycloak.testsuite.pages.ErrorPage;
import org.keycloak.testsuite.pages.LoginPage;
import org.keycloak.testsuite.pages.RegisterPage;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import javax.ws.rs.core.UriBuilder;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import org.jboss.arquillian.drone.api.annotation.Drone;
import org.jboss.arquillian.graphene.page.Page;
import org.keycloak.representations.idm.EventRepresentation;
import org.keycloak.representations.idm.RealmRepresentation;
import org.keycloak.representations.idm.UserRepresentation;
import org.keycloak.testsuite.TestRealmKeycloakTest;
import org.keycloak.testsuite.admin.ApiUtil;
import org.keycloak.testsuite.drone.Different;
import org.keycloak.testsuite.util.OAuthClient;
import org.keycloak.testsuite.util.RealmBuilder;
import org.keycloak.testsuite.util.UserBuilder;
/** /**
* * @author <a href="mailto:sthorger@redhat.com">Stian Thorgersen</a>
* @author Petr Mensik * @author Stan Silvert ssilvert@redhat.com (C) 2016 Red Hat Inc.
* @author tkyjovsk
*/ */
public class AccountTest extends AbstractAccountManagementTest { public class AccountTest extends TestRealmKeycloakTest {
private static final String UPDATED_EMAIL = "new-name@email.test";
private static final String NEW_FIRST_NAME = "John";
private static final String NEW_LAST_NAME = "Smith";
@Page
private Account testRealmAccountPage;
@Override @Override
public void setDefaultPageUriParameters() { public void configureTestRealm(RealmRepresentation testRealm) {
super.setDefaultPageUriParameters(); //UserRepresentation user = findUserInRealmRep(testRealm, "test-user@localhost");
testRealmAccountPage.setAuthRealm(testRealmPage); //ClientRepresentation accountApp = findClientInRealmRep(testRealm, ACCOUNT_MANAGEMENT_CLIENT_ID);
UserRepresentation user2 = UserBuilder.create()
.enabled(true)
.username("test-user-no-access@localhost")
.email("test-user-no-access@localhost")
.password("password")
.build();
RealmBuilder.edit(testRealm)
.user(user2);
} }
private static final UriBuilder BASE = UriBuilder.fromUri("http://localhost:8180/auth");
private static final String ACCOUNT_URL = RealmsResource.accountUrl(BASE.clone()).build("test").toString();
public static String ACCOUNT_REDIRECT = AccountService.loginRedirectUrl(BASE.clone()).build("test").toString();
// Create second session
@Drone
@Different
WebDriver driver2;
@Rule
public AssertEvents events = new AssertEvents(this);
@Page
protected AppPage appPage;
@Page
protected LoginPage loginPage;
@Page
protected RegisterPage registerPage;
@Page
protected AccountPasswordPage changePasswordPage;
@Page
protected AccountUpdateProfilePage profilePage;
@Page
protected AccountTotpPage totpPage;
@Page
protected AccountLogPage logPage;
@Page
protected AccountSessionsPage sessionsPage;
@Page
protected AccountApplicationsPage applicationsPage;
@Page
protected ErrorPage errorPage;
private TimeBasedOTP totp = new TimeBasedOTP();
private String userId;
@Before @Before
public void beforeAccountTest() { public void before() {
testRealmAccountManagementPage.navigateTo(); oauth.state("mystate"); // keycloak enforces that a state param has been sent by client
testRealmLoginPage.form().login(testUser); userId = findUser("test-user@localhost").getId();
}
@After
public void afterAccountTest() {
testRealmAccountManagementPage.navigateTo();
testRealmAccountManagementPage.signOut();
} }
@Test @Test
public void editAccount() { public void returnToAppFromQueryParam() {
testRealmAccountManagementPage.account(); driver.navigate().to(profilePage.getPath() + "?referrer=test-app");
assertEquals(testRealmAccountPage.getUsername(), testUser.getUsername()); loginPage.login("test-user@localhost", "password");
Assert.assertTrue(profilePage.isCurrent());
profilePage.backToApplication();
testRealmAccountPage.setEmail(UPDATED_EMAIL); Assert.assertTrue(appPage.isCurrent());
testRealmAccountPage.setFirstName(NEW_FIRST_NAME);
testRealmAccountPage.setLastName(NEW_LAST_NAME);
testRealmAccountPage.save();
assertAlertSuccess();
testRealmAccountManagementPage.signOut(); driver.navigate().to(profilePage.getPath() + "?referrer=test-app&referrer_uri=http://localhost:8180/auth/realms/master/app/auth?test");
testRealmLoginPage.form().login(testUser); Assert.assertTrue(profilePage.isCurrent());
profilePage.backToApplication();
testRealmAccountManagementPage.account(); Assert.assertTrue(appPage.isCurrent());
assertEquals(testRealmAccountPage.getEmail(), UPDATED_EMAIL); Assert.assertEquals(appPage.baseUrl + "?test", driver.getCurrentUrl());
assertEquals(testRealmAccountPage.getFirstName(), NEW_FIRST_NAME);
assertEquals(testRealmAccountPage.getLastName(), NEW_LAST_NAME); driver.navigate().to(profilePage.getPath() + "?referrer=test-app");
Assert.assertTrue(profilePage.isCurrent());
driver.findElement(By.linkText("Authenticator")).click();
Assert.assertTrue(totpPage.isCurrent());
driver.findElement(By.linkText("Account")).click();
Assert.assertTrue(profilePage.isCurrent());
profilePage.backToApplication();
Assert.assertTrue(appPage.isCurrent());
events.clear();
}
@Test
public void changePassword() {
changePasswordPage.open();
loginPage.login("test-user@localhost", "password");
EventRepresentation event = events.expectLogin().client("account").detail(Details.REDIRECT_URI, ACCOUNT_REDIRECT + "?path=password").assertEvent();
String sessionId = event.getSessionId();
String userId = event.getUserId();
changePasswordPage.changePassword("", "new-password", "new-password");
Assert.assertEquals("Please specify password.", profilePage.getError());
changePasswordPage.changePassword("password", "new-password", "new-password2");
Assert.assertEquals("Password confirmation doesn't match.", profilePage.getError());
changePasswordPage.changePassword("password", "new-password", "new-password");
Assert.assertEquals("Your password has been updated.", profilePage.getSuccess());
events.expectAccount(EventType.UPDATE_PASSWORD).assertEvent();
changePasswordPage.logout();
events.expectLogout(sessionId).detail(Details.REDIRECT_URI, changePasswordPage.getPath()).assertEvent();
loginPage.open();
loginPage.login("test-user@localhost", "password");
Assert.assertEquals("Invalid username or password.", loginPage.getError());
events.expectLogin().session((String) null).error("invalid_user_credentials")
.removeDetail(Details.CONSENT)
.assertEvent();
loginPage.open();
loginPage.login("test-user@localhost", "new-password");
Assert.assertEquals(RequestType.AUTH_RESPONSE, appPage.getRequestType());
events.expectLogin().assertEvent();
}
private void setPasswordPolicy(String policy) {
RealmRepresentation testRealm = testRealm().toRepresentation();
testRealm.setPasswordPolicy(policy);
testRealm().update(testRealm);
}
@Test
public void changePasswordWithLengthPasswordPolicy() {
setPasswordPolicy("length");
changePasswordPage.open();
loginPage.login("test-user@localhost", "password");
events.expectLogin().client("account").detail(Details.REDIRECT_URI, ACCOUNT_REDIRECT + "?path=password").assertEvent();
changePasswordPage.changePassword("", "new", "new");
Assert.assertEquals("Please specify password.", profilePage.getError());
changePasswordPage.changePassword("password", "new-password", "new-password");
Assert.assertEquals("Your password has been updated.", profilePage.getSuccess());
events.expectAccount(EventType.UPDATE_PASSWORD).assertEvent();
}
@Test
public void changePasswordWithPasswordHistoryPolicy() {
setPasswordPolicy("passwordHistory(2)");
changePasswordPage.open();
loginPage.login("test-user@localhost", "password");
events.expectLogin().client("account").detail(Details.REDIRECT_URI, ACCOUNT_REDIRECT + "?path=password").assertEvent();
changePasswordPage.changePassword("password", "password", "password");
Assert.assertEquals("Invalid password: must not be equal to any of last 2 passwords.", profilePage.getError());
changePasswordPage.changePassword("password", "password1", "password1");
Assert.assertEquals("Your password has been updated.", profilePage.getSuccess());
events.expectAccount(EventType.UPDATE_PASSWORD).assertEvent();
changePasswordPage.changePassword("password1", "password", "password");
Assert.assertEquals("Invalid password: must not be equal to any of last 2 passwords.", profilePage.getError());
changePasswordPage.changePassword("password1", "password1", "password1");
Assert.assertEquals("Invalid password: must not be equal to any of last 2 passwords.", profilePage.getError());
changePasswordPage.changePassword("password1", "password2", "password2");
Assert.assertEquals("Your password has been updated.", profilePage.getSuccess());
events.expectAccount(EventType.UPDATE_PASSWORD).assertEvent();
}
@Test
public void changeProfile() {
profilePage.open();
loginPage.login("test-user@localhost", "password");
events.expectLogin().client("account").detail(Details.REDIRECT_URI, ACCOUNT_REDIRECT).assertEvent();
Assert.assertEquals("Tom", profilePage.getFirstName());
Assert.assertEquals("Brady", profilePage.getLastName());
Assert.assertEquals("test-user@localhost", profilePage.getEmail());
// All fields are required, so there should be an error when something is missing.
profilePage.updateProfile("", "New last", "new@email.com");
Assert.assertEquals("Please specify first name.", profilePage.getError());
Assert.assertEquals("", profilePage.getFirstName());
Assert.assertEquals("New last", profilePage.getLastName());
Assert.assertEquals("new@email.com", profilePage.getEmail());
events.assertEmpty();
profilePage.updateProfile("New first", "", "new@email.com");
Assert.assertEquals("Please specify last name.", profilePage.getError());
Assert.assertEquals("New first", profilePage.getFirstName());
Assert.assertEquals("", profilePage.getLastName());
Assert.assertEquals("new@email.com", profilePage.getEmail());
events.assertEmpty();
profilePage.updateProfile("New first", "New last", "");
Assert.assertEquals("Please specify email.", profilePage.getError());
Assert.assertEquals("New first", profilePage.getFirstName());
Assert.assertEquals("New last", profilePage.getLastName());
Assert.assertEquals("", profilePage.getEmail());
events.assertEmpty();
profilePage.clickCancel();
Assert.assertEquals("Tom", profilePage.getFirstName());
Assert.assertEquals("Brady", profilePage.getLastName());
Assert.assertEquals("test-user@localhost", profilePage.getEmail());
events.assertEmpty();
profilePage.updateProfile("New first", "New last", "new@email.com");
Assert.assertEquals("Your account has been updated.", profilePage.getSuccess());
Assert.assertEquals("New first", profilePage.getFirstName());
Assert.assertEquals("New last", profilePage.getLastName());
Assert.assertEquals("new@email.com", profilePage.getEmail());
events.expectAccount(EventType.UPDATE_PROFILE).assertEvent();
events.expectAccount(EventType.UPDATE_EMAIL).detail(Details.PREVIOUS_EMAIL, "test-user@localhost").detail(Details.UPDATED_EMAIL, "new@email.com").assertEvent();
// reset user for other tests
profilePage.updateProfile("Tom", "Brady", "test-user@localhost");
events.clear();
}
private void setEditUsernameAllowed() {
RealmRepresentation testRealm = testRealm().toRepresentation();
testRealm.setEditUsernameAllowed(true);
testRealm().update(testRealm);
}
@Test
public void changeUsername() {
// allow to edit the username in realm
setEditUsernameAllowed();
profilePage.open();
loginPage.login("test-user@localhost", "password");
events.expectLogin().client("account").detail(Details.REDIRECT_URI, ACCOUNT_REDIRECT).assertEvent();
Assert.assertEquals("test-user@localhost", profilePage.getUsername());
Assert.assertEquals("Tom", profilePage.getFirstName());
Assert.assertEquals("Brady", profilePage.getLastName());
Assert.assertEquals("test-user@localhost", profilePage.getEmail());
// All fields are required, so there should be an error when something is missing.
profilePage.updateProfile("", "New first", "New last", "new@email.com");
Assert.assertEquals("Please specify username.", profilePage.getError());
Assert.assertEquals("", profilePage.getUsername());
Assert.assertEquals("New first", profilePage.getFirstName());
Assert.assertEquals("New last", profilePage.getLastName());
Assert.assertEquals("new@email.com", profilePage.getEmail());
events.assertEmpty();
// Change to the username already occupied by other user
profilePage.updateProfile("test-user-no-access@localhost", "New first", "New last", "new@email.com");
Assert.assertEquals("Username already exists.", profilePage.getError());
Assert.assertEquals("test-user-no-access@localhost", profilePage.getUsername());
Assert.assertEquals("New first", profilePage.getFirstName());
Assert.assertEquals("New last", profilePage.getLastName());
Assert.assertEquals("new@email.com", profilePage.getEmail());
events.assertEmpty();
profilePage.updateProfile("test-user-new@localhost", "New first", "New last", "new@email.com");
Assert.assertEquals("Your account has been updated.", profilePage.getSuccess());
Assert.assertEquals("test-user-new@localhost", profilePage.getUsername());
Assert.assertEquals("New first", profilePage.getFirstName());
Assert.assertEquals("New last", profilePage.getLastName());
Assert.assertEquals("new@email.com", profilePage.getEmail());
}
private void addUser(String username, String email) {
UserRepresentation user = UserBuilder.create()
.username(username)
.enabled(true)
.email(email)
.firstName("first")
.lastName("last")
.build();
ApiUtil.createUserAndResetPasswordWithAdminClient(testRealm(), user, "password");
}
@Test
public void changeUsernameLoginWithOldUsername() {
addUser("change-username", "change-username@localhost");
setEditUsernameAllowed();
profilePage.open();
loginPage.login("change-username", "password");
profilePage.updateUsername("change-username-updated");
Assert.assertEquals("Your account has been updated.", profilePage.getSuccess());
profilePage.logout();
profilePage.open();
Assert.assertTrue(loginPage.isCurrent());
loginPage.login("change-username", "password");
Assert.assertTrue(loginPage.isCurrent());
Assert.assertEquals("Invalid username or password.", loginPage.getError());
loginPage.login("change-username-updated", "password");
}
@Test
public void changeEmailLoginWithOldEmail() {
addUser("change-email", "change-username@localhost");
setEditUsernameAllowed();
profilePage.open();
loginPage.login("change-username@localhost", "password");
profilePage.updateEmail("change-username-updated@localhost");
Assert.assertEquals("Your account has been updated.", profilePage.getSuccess());
profilePage.logout();
profilePage.open();
Assert.assertTrue(loginPage.isCurrent());
loginPage.login("change-username@localhost", "password");
Assert.assertTrue(loginPage.isCurrent());
Assert.assertEquals("Invalid username or password.", loginPage.getError());
loginPage.login("change-username-updated@localhost", "password");
}
// KEYCLOAK-1534
@Test
public void changeEmailToExisting() {
profilePage.open();
loginPage.login("test-user@localhost", "password");
events.expectLogin().client("account").detail(Details.REDIRECT_URI, ACCOUNT_REDIRECT).assertEvent();
Assert.assertEquals("test-user@localhost", profilePage.getUsername());
Assert.assertEquals("test-user@localhost", profilePage.getEmail());
// Change to the email, which some other user has
profilePage.updateProfile("New first", "New last", "test-user-no-access@localhost");
profilePage.assertCurrent();
Assert.assertEquals("Email already exists.", profilePage.getError());
Assert.assertEquals("New first", profilePage.getFirstName());
Assert.assertEquals("New last", profilePage.getLastName());
Assert.assertEquals("test-user-no-access@localhost", profilePage.getEmail());
events.assertEmpty();
// Change some other things, but not email
profilePage.updateProfile("New first", "New last", "test-user@localhost");
Assert.assertEquals("Your account has been updated.", profilePage.getSuccess());
Assert.assertEquals("New first", profilePage.getFirstName());
Assert.assertEquals("New last", profilePage.getLastName());
Assert.assertEquals("test-user@localhost", profilePage.getEmail());
events.expectAccount(EventType.UPDATE_PROFILE).assertEvent();
// Change email and other things to original values
profilePage.updateProfile("Tom", "Brady", "test-user@localhost");
events.expectAccount(EventType.UPDATE_PROFILE).assertEvent();
}
@Test
public void setupTotp() {
totpPage.open();
loginPage.login("test-user@localhost", "password");
events.expectLogin().client("account").detail(Details.REDIRECT_URI, ACCOUNT_REDIRECT + "?path=totp").assertEvent();
Assert.assertTrue(totpPage.isCurrent());
Assert.assertFalse(driver.getPageSource().contains("Remove Google"));
// Error with false code
totpPage.configure(totp.generateTOTP(totpPage.getTotpSecret() + "123"));
Assert.assertEquals("Invalid authenticator code.", profilePage.getError());
totpPage.configure(totp.generateTOTP(totpPage.getTotpSecret()));
Assert.assertEquals("Mobile authenticator configured.", profilePage.getSuccess());
events.expectAccount(EventType.UPDATE_TOTP).assertEvent();
Assert.assertTrue(driver.getPageSource().contains("pficon-delete"));
totpPage.removeTotp();
events.expectAccount(EventType.REMOVE_TOTP).assertEvent();
}
@Test
public void changeProfileNoAccess() throws Exception {
profilePage.open();
loginPage.login("test-user-no-access@localhost", "password");
UserRepresentation noAccessUser = this.findUser("test-user-no-access@localhost");
events.expectLogin().client("account").user(noAccessUser.getId())
.detail(Details.USERNAME, "test-user-no-access@localhost")
.detail(Details.REDIRECT_URI, ACCOUNT_REDIRECT).assertEvent();
Assert.assertTrue(errorPage.isCurrent());
Assert.assertEquals("No access", errorPage.getError());
}
private void setEventsEnabled() {
RealmRepresentation testRealm = testRealm().toRepresentation();
testRealm.setEventsEnabled(true);
testRealm().update(testRealm);
}
@Test
public void viewLog() {
setEventsEnabled();
List<EventRepresentation> expectedEvents = new LinkedList<>();
loginPage.open();
loginPage.clickRegister();
registerPage.register("view", "log", "view-log@localhost", "view-log", "password", "password");
expectedEvents.add(events.poll());
expectedEvents.add(events.poll());
profilePage.open();
profilePage.updateProfile("view", "log2", "view-log@localhost");
expectedEvents.add(events.poll());
logPage.open();
Assert.assertTrue(logPage.isCurrent());
List<List<String>> actualEvents = logPage.getEvents();
Assert.assertEquals(expectedEvents.size(), actualEvents.size());
for (EventRepresentation e : expectedEvents) {
boolean match = false;
for (List<String> a : logPage.getEvents()) {
if (e.getType().toString().replace('_', ' ').toLowerCase().equals(a.get(1)) &&
e.getIpAddress().equals(a.get(2)) &&
e.getClientId().equals(a.get(3))) {
match = true;
break;
}
}
if (!match) {
Assert.fail("Event not found " + e.getType());
}
}
}
@Test
public void sessions() {
loginPage.open();
loginPage.clickRegister();
registerPage.register("view", "sessions", "view-sessions@localhost", "view-sessions", "password", "password");
EventRepresentation registerEvent = events.expectRegister("view-sessions", "view-sessions@localhost").assertEvent();
String userId = registerEvent.getUserId();
events.expectLogin().user(userId).detail(Details.USERNAME, "view-sessions").assertEvent();
sessionsPage.open();
Assert.assertTrue(sessionsPage.isCurrent());
List<List<String>> sessions = sessionsPage.getSessions();
Assert.assertEquals(1, sessions.size());
Assert.assertEquals("127.0.0.1", sessions.get(0).get(0));
// Create second session
try {
OAuthClient oauth2 = new OAuthClient();
oauth2.init(adminClient, driver2);
oauth2.state("mystate");
oauth2.doLogin("view-sessions", "password");
EventRepresentation login2Event = events.expectLogin().user(userId).detail(Details.USERNAME, "view-sessions").assertEvent();
sessionsPage.open();
sessions = sessionsPage.getSessions();
Assert.assertEquals(2, sessions.size());
sessionsPage.logoutAll();
events.expectLogout(registerEvent.getSessionId());
events.expectLogout(login2Event.getSessionId());
} finally {
driver2.close();
}
}
// More tests (including revoke) are in OAuthGrantTest and OfflineTokenTest
@Test
public void applications() {
applicationsPage.open();
loginPage.login("test-user@localhost", "password");
events.expectLogin().client("account").detail(Details.REDIRECT_URI, ACCOUNT_REDIRECT + "?path=applications").assertEvent();
Assert.assertTrue(applicationsPage.isCurrent());
Map<String, AccountApplicationsPage.AppEntry> apps = applicationsPage.getApplications();
Assert.assertEquals(3, apps.size());
AccountApplicationsPage.AppEntry accountEntry = apps.get("Account");
Assert.assertEquals(2, accountEntry.getRolesAvailable().size());
Assert.assertTrue(accountEntry.getRolesAvailable().contains("Manage account in Account"));
Assert.assertTrue(accountEntry.getRolesAvailable().contains("View profile in Account"));
Assert.assertEquals(1, accountEntry.getRolesGranted().size());
Assert.assertTrue(accountEntry.getRolesGranted().contains("Full Access"));
Assert.assertEquals(1, accountEntry.getProtocolMappersGranted().size());
Assert.assertTrue(accountEntry.getProtocolMappersGranted().contains("Full Access"));
AccountApplicationsPage.AppEntry testAppEntry = apps.get("test-app");
Assert.assertEquals(5, testAppEntry.getRolesAvailable().size());
Assert.assertTrue(testAppEntry.getRolesAvailable().contains("Offline access"));
Assert.assertTrue(testAppEntry.getRolesGranted().contains("Full Access"));
Assert.assertTrue(testAppEntry.getProtocolMappersGranted().contains("Full Access"));
AccountApplicationsPage.AppEntry thirdPartyEntry = apps.get("third-party");
Assert.assertEquals(2, thirdPartyEntry.getRolesAvailable().size());
Assert.assertTrue(thirdPartyEntry.getRolesAvailable().contains("Have User privileges"));
Assert.assertTrue(thirdPartyEntry.getRolesAvailable().contains("Have Customer User privileges in test-app"));
Assert.assertEquals(0, thirdPartyEntry.getRolesGranted().size());
Assert.assertEquals(0, thirdPartyEntry.getProtocolMappersGranted().size());
}
@Test
public void loginToSpecificPage() {
changePasswordPage.open();
loginPage.login("test-user@localhost", "password");
Assert.assertTrue(changePasswordPage.isCurrent());
events.clear();
}
@Test
public void loginToSpecificPageWithReferrer() {
driver.navigate().to(changePasswordPage.getPath() + "?referrer=account");
System.out.println(driver.getCurrentUrl());
loginPage.login("test-user@localhost", "password");
System.out.println(driver.getCurrentUrl());
Assert.assertTrue(changePasswordPage.isCurrent());
events.clear();
} }
} }

View file

@ -1,87 +0,0 @@
/*
* 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.account;
import org.jboss.arquillian.graphene.page.Page;
import org.junit.Before;
import org.junit.Test;
import org.keycloak.testsuite.auth.page.account.ChangePassword;
import static org.keycloak.testsuite.admin.Users.getPasswordOf;
import static org.keycloak.testsuite.util.URLAssert.assertCurrentUrlStartsWith;
/**
*
* @author tkyjovsk
*/
public class ChangePasswordTest extends AbstractAccountManagementTest {
private static final String NEW_PASSWORD = "newpassword";
private static final String WRONG_PASSWORD = "wrongpassword";
@Page
private ChangePassword testRealmChangePasswordPage;
private String correctPassword;
@Override
public void setDefaultPageUriParameters() {
super.setDefaultPageUriParameters();
testRealmChangePasswordPage.setAuthRealm(testRealmPage);
}
@Before
public void beforeChangePasswordTest() {
correctPassword = getPasswordOf(testUser);
testRealmAccountManagementPage.navigateTo();
testRealmLoginPage.form().login(testUser);
testRealmAccountManagementPage.password();
}
@Test
public void invalidChangeAttempts() {
testRealmChangePasswordPage.save();
assertAlertError();
testRealmChangePasswordPage.changePasswords(WRONG_PASSWORD, NEW_PASSWORD, NEW_PASSWORD);
assertAlertError();
testRealmChangePasswordPage.changePasswords(correctPassword, NEW_PASSWORD, NEW_PASSWORD + "-mismatch");
assertAlertError();
testRealmChangePasswordPage.changePasswords(correctPassword, " ", " ");
assertAlertError();
}
@Test
public void successfulChangeAttempts() {
// change password successfully
testRealmChangePasswordPage.changePasswords(correctPassword, NEW_PASSWORD, NEW_PASSWORD);
assertAlertSuccess();
// login using new password
testRealmAccountManagementPage.signOut();
testRealmLoginPage.form().login(testUser.getUsername(), NEW_PASSWORD);
assertCurrentUrlStartsWith(testRealmAccountManagementPage);
// change password back
testRealmAccountManagementPage.password();
testRealmChangePasswordPage.changePasswords(NEW_PASSWORD, correctPassword, correctPassword);
assertAlertSuccess();
}
}

View file

@ -23,96 +23,110 @@ import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient; import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet; import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.DefaultHttpClient; import org.apache.http.impl.client.DefaultHttpClient;
import org.json.JSONArray;
import org.json.JSONObject;
import org.junit.ClassRule;
import org.junit.Rule;
import org.junit.Test; import org.junit.Test;
import org.keycloak.OAuth2Constants; import org.keycloak.OAuth2Constants;
import org.keycloak.models.AccountRoles;
import org.keycloak.models.ClientModel;
import org.keycloak.models.RealmModel;
import org.keycloak.models.UserCredentialModel;
import org.keycloak.models.UserModel;
import org.keycloak.representations.idm.CredentialRepresentation;
import org.keycloak.services.managers.RealmManager;
import org.keycloak.services.resources.RealmsResource; import org.keycloak.services.resources.RealmsResource;
import org.keycloak.testsuite.Constants;
import org.keycloak.testsuite.OAuthClient;
import org.keycloak.testsuite.pages.AccountApplicationsPage; import org.keycloak.testsuite.pages.AccountApplicationsPage;
import org.keycloak.testsuite.pages.AccountUpdateProfilePage; import org.keycloak.testsuite.pages.AccountUpdateProfilePage;
import org.keycloak.testsuite.pages.LoginPage; import org.keycloak.testsuite.pages.LoginPage;
import org.keycloak.testsuite.pages.OAuthGrantPage; import org.keycloak.testsuite.pages.OAuthGrantPage;
import org.keycloak.testsuite.rule.KeycloakRule;
import org.keycloak.testsuite.rule.WebResource;
import org.keycloak.testsuite.rule.WebRule;
import org.openqa.selenium.JavascriptExecutor; import org.openqa.selenium.JavascriptExecutor;
import org.openqa.selenium.WebDriver;
import javax.ws.rs.core.MediaType; import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.UriBuilder; import javax.ws.rs.core.UriBuilder;
import java.io.IOException; import java.io.IOException;
import java.net.URI; import java.net.URI;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.jboss.arquillian.graphene.page.Page;
import org.junit.Before;
import org.keycloak.admin.client.resource.ClientResource;
import org.keycloak.admin.client.resource.RoleMappingResource;
import org.keycloak.admin.client.resource.RoleScopeResource;
import org.keycloak.models.AccountRoles;
import org.keycloak.representations.idm.RealmRepresentation;
import org.keycloak.representations.idm.RoleRepresentation;
import org.keycloak.representations.idm.UserRepresentation;
import org.keycloak.testsuite.TestRealmKeycloakTest;
import org.keycloak.testsuite.admin.ApiUtil;
import org.keycloak.testsuite.util.ClientBuilder;
import org.keycloak.testsuite.util.RealmBuilder;
import org.keycloak.testsuite.util.UserBuilder;
import twitter4j.JSONArray;
import twitter4j.JSONObject;
import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertEquals;
import static org.junit.Assert.fail; import static org.junit.Assert.fail;
/** /**
* @author <a href="mailto:sthorger@redhat.com">Stian Thorgersen</a> * @author <a href="mailto:sthorger@redhat.com">Stian Thorgersen</a>
* @author Stan Silvert ssilvert@redhat.com (C) 2016 Red Hat Inc.
*/ */
public class ProfileTest { public class ProfileTest extends TestRealmKeycloakTest {
@ClassRule
public static KeycloakRule keycloakRule = new KeycloakRule(new KeycloakRule.KeycloakSetup() {
@Override @Override
public void config(RealmManager manager, RealmModel adminstrationRealm, RealmModel appRealm) { public void configureTestRealm(RealmRepresentation testRealm) {
UserModel user = manager.getSession().users().getUserByUsername("test-user@localhost", appRealm); UserRepresentation user = findUserInRealmRep(testRealm, "test-user@localhost");
user.setFirstName("First"); user.setFirstName("First");
user.setLastName("Last"); user.setLastName("Last");
user.setSingleAttribute("key1", "value1"); Map<String, Object> attributes = user.getAttributes();
user.setSingleAttribute("key2", "value2"); if (attributes == null) {
attributes = new HashMap<>();
ClientModel accountApp = appRealm.getClientByClientId(org.keycloak.models.Constants.ACCOUNT_MANAGEMENT_CLIENT_ID); user.setAttributes(attributes);
UserModel user2 = manager.getSession().users().addUser(appRealm, "test-user-no-access@localhost");
user2.setEnabled(true);
for (String r : accountApp.getDefaultRoles()) {
user2.deleteRoleMapping(accountApp.getRole(r));
} }
UserCredentialModel creds = new UserCredentialModel(); attributes.put("key1", "value1");
creds.setType(CredentialRepresentation.PASSWORD); attributes.put("key2", "value2");
creds.setValue("password");
user2.updateCredential(creds);
ClientModel app = appRealm.getClientByClientId("test-app"); UserRepresentation user2 = UserBuilder.create()
app.addScopeMapping(accountApp.getRole(AccountRoles.VIEW_PROFILE)); .enabled(true)
app.addRedirectUri("http://localhost:8081/app/*"); .username("test-user-no-access@localhost")
app.addWebOrigin("http://localtest.me:8081"); .password("password")
.build();
RealmBuilder.edit(testRealm)
.user(user2);
ClientModel thirdParty = appRealm.getClientByClientId("third-party"); ClientBuilder.edit(findClientInRealmRep(testRealm, "test-app"))
thirdParty.addScopeMapping(accountApp.getRole(AccountRoles.VIEW_PROFILE)); .addWebOrigin("http://localtest.me:8180");
} }
});
@Rule private RoleRepresentation findViewProfileRole(ClientResource accountApp) {
public WebRule webRule = new WebRule(this); RoleMappingResource scopeMappings = accountApp.getScopeMappings();
RoleScopeResource clientLevelMappings = scopeMappings.clientLevel(accountApp.toRepresentation().getId());
List<RoleRepresentation> accountRoleList = clientLevelMappings.listEffective();
@WebResource for (RoleRepresentation role : accountRoleList) {
protected WebDriver driver; if (role.getName().equals(AccountRoles.VIEW_PROFILE)) return role;
}
@WebResource return null;
protected OAuthClient oauth; }
@WebResource @Before
public void addScopeMappings() {
String accountClientId = org.keycloak.models.Constants.ACCOUNT_MANAGEMENT_CLIENT_ID;
ClientResource accountApp = ApiUtil.findClientByClientId(testRealm(), accountClientId);
RoleRepresentation role = findViewProfileRole(accountApp);
String accountAppId = accountApp.toRepresentation().getId();
ClientResource app = ApiUtil.findClientByClientId(testRealm(), "test-app");
app.getScopeMappings().clientLevel(accountAppId).add(Collections.singletonList(role));
ClientResource thirdParty = ApiUtil.findClientByClientId(testRealm(), "third-party");
thirdParty.getScopeMappings().clientLevel(accountAppId).add(Collections.singletonList(role));
}
@Page
protected AccountUpdateProfilePage profilePage; protected AccountUpdateProfilePage profilePage;
@WebResource @Page
protected AccountApplicationsPage accountApplicationsPage; protected AccountApplicationsPage accountApplicationsPage;
@WebResource @Page
protected LoginPage loginPage; protected LoginPage loginPage;
@WebResource @Page
protected OAuthGrantPage grantPage; protected OAuthGrantPage grantPage;
@Test @Test
@ -147,7 +161,7 @@ public class ProfileTest {
String code = oauth.getCurrentQuery().get(OAuth2Constants.CODE); String code = oauth.getCurrentQuery().get(OAuth2Constants.CODE);
String token = oauth.doAccessTokenRequest(code, "password").getAccessToken(); String token = oauth.doAccessTokenRequest(code, "password").getAccessToken();
driver.navigate().to("http://localtest.me:8081/app"); driver.navigate().to("http://localtest.me:8180/app");
String[] response = doGetProfileJs(token); String[] response = doGetProfileJs(token);
assertEquals("200", response[0]); assertEquals("200", response[0]);
@ -160,7 +174,7 @@ public class ProfileTest {
String code = oauth.getCurrentQuery().get(OAuth2Constants.CODE); String code = oauth.getCurrentQuery().get(OAuth2Constants.CODE);
String token = oauth.doAccessTokenRequest(code, "password").getAccessToken(); String token = oauth.doAccessTokenRequest(code, "password").getAccessToken();
driver.navigate().to("http://invalid.localtest.me:8081"); driver.navigate().to("http://invalid.localtest.me:8180");
try { try {
doGetProfileJs(token); doGetProfileJs(token);
@ -229,7 +243,7 @@ public class ProfileTest {
} }
private URI getAccountURI() { private URI getAccountURI() {
return RealmsResource.accountUrl(UriBuilder.fromUri(Constants.AUTH_SERVER_ROOT)).build(oauth.getRealm()); return RealmsResource.accountUrl(UriBuilder.fromUri(oauth.AUTH_SERVER_ROOT)).build(oauth.getRealm());
} }
private HttpResponse doGetProfile(String token, String origin) throws IOException { private HttpResponse doGetProfile(String token, String origin) throws IOException {

View file

@ -1,134 +0,0 @@
/*
* 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.account;
import org.jboss.arquillian.graphene.page.Page;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
import org.junit.Test;
import org.keycloak.testsuite.auth.page.login.Registration;
import org.junit.Before;
import static org.keycloak.representations.idm.CredentialRepresentation.PASSWORD;
import org.keycloak.representations.idm.RealmRepresentation;
import org.keycloak.representations.idm.UserRepresentation;
import static org.keycloak.testsuite.admin.ApiUtil.findUserByUsername;
import static org.keycloak.testsuite.admin.Users.getPasswordOf;
import static org.keycloak.testsuite.admin.Users.setPasswordFor;
/**
*
* @author Petr Mensik
* @author tkyjovsk
*/
public class RegistrationTest extends AbstractAccountManagementTest {
@Page
private Registration testRealmRegistrationPage;
private UserRepresentation newUser;
@Override
public void setDefaultPageUriParameters() {
super.setDefaultPageUriParameters();
testRealmRegistrationPage.setAuthRealm(testRealmPage);
}
@Before
public void beforeUserRegistration() {
// enable user registration in test realm
RealmRepresentation testRealmRep = testRealmResource().toRepresentation();
testRealmRep.setRegistrationAllowed(true);
testRealmResource().update(testRealmRep);
newUser = createUserRepresentation("new_user", "new_user@email.test", "new", "user", true);
setPasswordFor(newUser, PASSWORD);
testRealmAccountManagementPage.navigateTo();
assertTrue("Registration should be allowed.", testRealmResource().toRepresentation().isRegistrationAllowed());
testRealmLoginPage.form().register();
}
public void assertUserExistsWithAdminClient(UserRepresentation user) {
assertNotNull(findUserByUsername(testRealmResource(), user.getUsername()));
}
public void assertUserDoesntExistWithAdminClient(UserRepresentation user) {
assertNull(findUserByUsername(testRealmResource(), user.getUsername()));
}
public void assertMessageAttributeMissing(String attributeName) {
String feedbackTest = testRealmRegistrationPage.getFeedbackText();
String contains = "Please specify " + attributeName + ".";
assertTrue("'" + feedbackTest + "' doesn't contain '" + contains + "'", feedbackTest.contains(contains));
}
@Test
public void successfulRegistration() {
testRealmRegistrationPage.register(newUser);
assertUserExistsWithAdminClient(newUser);
}
@Test
public void invalidEmail() {
newUser.setEmail("invalid.email.value");
testRealmRegistrationPage.register(newUser);
assertEquals("Invalid email address.", testRealmRegistrationPage.getFeedbackText());
assertUserDoesntExistWithAdminClient(newUser);
}
@Test
public void emptyAttributes() {
UserRepresentation newUserEmpty = new UserRepresentation(); // empty user attributes
testRealmRegistrationPage.register(newUserEmpty);
assertMessageAttributeMissing("username");
newUserEmpty.setUsername(newUser.getUsername());
testRealmRegistrationPage.register(newUserEmpty);
assertMessageAttributeMissing("first name");
newUserEmpty.setFirstName(newUser.getFirstName());
testRealmRegistrationPage.register(newUserEmpty);
assertMessageAttributeMissing("last name");
newUserEmpty.setLastName(newUser.getLastName());
testRealmRegistrationPage.register(newUserEmpty);
assertMessageAttributeMissing("email");
newUserEmpty.setEmail(newUser.getEmail());
testRealmRegistrationPage.register(newUserEmpty);
assertMessageAttributeMissing("password");
setPasswordFor(newUserEmpty, getPasswordOf(newUser));
testRealmRegistrationPage.register(newUser);
assertUserExistsWithAdminClient(newUserEmpty);
}
@Test
public void notMatchingPasswords() {
testRealmRegistrationPage.setValues(newUser, "not-matching-password");
testRealmRegistrationPage.submit();
assertEquals("Password confirmation doesn't match.", testRealmRegistrationPage.getFeedbackText());
testRealmRegistrationPage.register(newUser);
assertUserExistsWithAdminClient(newUser);
}
}

View file

@ -1,70 +0,0 @@
/*
* 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.account;
import org.junit.Before;
import org.junit.Ignore;
import org.junit.Test;
import org.keycloak.representations.idm.RealmRepresentation;
/**
*
* @author vramik
*/
@Ignore //TODO find out the way how to restart browser during the test
public class RememberMeTest extends AbstractAccountManagementTest {
@Before
public void beforeRememberMe() {
// enable remember me in test realm
RealmRepresentation testRealmRep = testRealmResource().toRepresentation();
testRealmRep.setRememberMe(true);
testRealmResource().update(testRealmRep);
}
@Test
public void rememberMe() {
testRealmAccountManagementPage.navigateTo();
log.info("login with remember me unchecked");
testRealmLoginPage.form().login(testUser);
testRealmAccountManagementPage.waitForAccountLinkPresent();
log.debug("logged in");
//TODO: restart browser
testRealmAccountManagementPage.navigateTo();
log.debug("user shouldn't be logged in");
testRealmLoginPage.form().waitForRememberMePresent();
log.info("login with remember me checked");
testRealmLoginPage.form().rememberMe(true);
testRealmLoginPage.form().login(testUser);
testRealmAccountManagementPage.waitForAccountLinkPresent();
//TODO: restart browser
testRealmAccountManagementPage.navigateTo();
log.debug("user should be logged in");
testRealmAccountManagementPage.waitForAccountLinkPresent();
}
}

View file

@ -1,102 +0,0 @@
/*
* 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.account;
import org.jboss.arquillian.graphene.page.Page;
import org.junit.AfterClass;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
import org.junit.Before;
import org.junit.Test;
import org.keycloak.representations.idm.RealmRepresentation;
import org.keycloak.testsuite.auth.page.login.ResetCredentials;
import static org.keycloak.testsuite.util.MailAssert.assertEmailAndGetUrl;
import org.keycloak.testsuite.util.MailServer;
import org.keycloak.testsuite.util.MailServerConfiguration;
import static org.keycloak.testsuite.util.URLAssert.assertCurrentUrlStartsWith;
/**
*
* @author vramik
*/
public class ResetCredentialsTest extends AbstractAccountManagementTest {
@Page
private ResetCredentials testRealmResetCredentialsPage;
private static boolean init = false;
@Override
public void setDefaultPageUriParameters() {
super.setDefaultPageUriParameters();
testRealmResetCredentialsPage.setAuthRealm(testRealmPage);
}
@Before
public void beforeResetCredentials() {
// enable reset credentials and configure smpt server in test realm
RealmRepresentation testRealmRep = testRealmResource().toRepresentation();
testRealmRep.setSmtpServer(suiteContext.getSmtpServer());
testRealmRep.setResetPasswordAllowed(true);
testRealmResource().update(testRealmRep);
if (!init) {
init = true;
MailServer.start();
MailServer.createEmailAccount(testUser.getEmail(), "password");
}
testRealmAccountManagementPage.navigateTo();
assertTrue("Reset password should be allowed.", testRealmResource().toRepresentation().isResetPasswordAllowed());
testRealmLoginPage.form().forgotPassword();
}
@AfterClass
public static void afterClass() {
MailServer.stop();
}
@Test
public void resetCredentialsWithEmail() {
testRealmResetCredentialsPage.resetCredentials(testUser.getEmail());
resetCredentialsAndLoginWithNewPassword();
}
@Test
public void resetCredentialsWithUsername() {
testRealmResetCredentialsPage.resetCredentials(testUser.getUsername());
resetCredentialsAndLoginWithNewPassword();
}
private void resetCredentialsAndLoginWithNewPassword() {
assertEquals("You should receive an email shortly with further instructions.",
testRealmResetCredentialsPage.getFeedbackText());
String url = assertEmailAndGetUrl(MailServerConfiguration.FROM, testUser.getEmail(),
"Someone just requested to change your Test account's credentials.");
log.info("navigating to " + url);
driver.navigate().to(url);
//assertCurrentUrlStartsWith(testRealmResetCredentialsPage);
testRealmResetCredentialsPage.updatePassword("newPassword");
assertCurrentUrlStartsWith(testRealmAccountManagementPage);
testRealmAccountManagementPage.signOut();
testRealmLoginPage.form().login("test", "newPassword");
assertCurrentUrlStartsWith(testRealmAccountManagementPage);
}
}

View file

@ -1,87 +0,0 @@
/*
* 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.account;
import org.jboss.arquillian.graphene.page.Page;
import org.junit.AfterClass;
import static org.junit.Assert.assertEquals;
import org.junit.Before;
import org.junit.Test;
import org.keycloak.representations.idm.RealmRepresentation;
import org.keycloak.testsuite.auth.page.login.VerifyEmail;
import static org.keycloak.testsuite.util.MailAssert.assertEmailAndGetUrl;
import org.keycloak.testsuite.util.MailServer;
import org.keycloak.testsuite.util.MailServerConfiguration;
import static org.keycloak.testsuite.util.URLAssert.assertCurrentUrlStartsWith;
/**
*
* @author vramik
*/
public class VerifyEmailTest extends AbstractAccountManagementTest {
@Page
private VerifyEmail testRealmVerifyEmailPage;
private static boolean init = false;
@Override
public void setDefaultPageUriParameters() {
super.setDefaultPageUriParameters();
testRealmVerifyEmailPage.setAuthRealm(testRealmPage);
}
@Before
public void beforeVerifyEmail() {
log.info("enable verify email and configure smpt server in test realm");
RealmRepresentation testRealmRep = testRealmResource().toRepresentation();
testRealmRep.setSmtpServer(suiteContext.getSmtpServer());
testRealmRep.setVerifyEmail(true);
testRealmResource().update(testRealmRep);
if (!init) {
init = true;
MailServer.start();
MailServer.createEmailAccount(testUser.getEmail(), "password");
}
}
@AfterClass
public static void afterClass() {
MailServer.stop();
}
@Test
public void verifyEmail() {
testRealmAccountManagementPage.navigateTo();
testRealmLoginPage.form().login(testUser);
assertEquals("You need to verify your email address to activate your account.",
testRealmVerifyEmailPage.getFeedbackText());
String verifyEmailUrl = assertEmailAndGetUrl(MailServerConfiguration.FROM, testUser.getEmail(),
"Someone has created a Test account with this email address.");
log.info("navigating to url from email: " + verifyEmailUrl);
driver.navigate().to(verifyEmailUrl);
assertCurrentUrlStartsWith(testRealmAccountManagementPage);
testRealmAccountManagementPage.signOut();
testRealmLoginPage.form().login(testUser);
assertCurrentUrlStartsWith(testRealmAccountManagementPage);
}
}

View file

@ -15,7 +15,7 @@
* limitations under the License. * limitations under the License.
*/ */
package org.keycloak.testsuite.account; package org.keycloak.testsuite.account.custom;
import org.jboss.arquillian.graphene.page.Page; import org.jboss.arquillian.graphene.page.Page;
import static org.junit.Assert.assertTrue; import static org.junit.Assert.assertTrue;

View file

@ -23,7 +23,6 @@ import org.junit.Before;
import org.keycloak.admin.client.resource.AuthenticationManagementResource; import org.keycloak.admin.client.resource.AuthenticationManagementResource;
import org.keycloak.models.AuthenticationExecutionModel; import org.keycloak.models.AuthenticationExecutionModel;
import org.keycloak.representations.idm.AuthenticationExecutionInfoRepresentation; import org.keycloak.representations.idm.AuthenticationExecutionInfoRepresentation;
import org.keycloak.testsuite.account.AbstractAccountManagementTest;
/** /**
* *

View file

@ -17,11 +17,14 @@
package org.keycloak.testsuite.util; package org.keycloak.testsuite.util;
import java.util.ArrayList;
import org.keycloak.dom.saml.v2.ac.BooleanType; import org.keycloak.dom.saml.v2.ac.BooleanType;
import org.keycloak.representations.idm.ClientRepresentation; import org.keycloak.representations.idm.ClientRepresentation;
import java.util.Arrays; import java.util.Arrays;
import java.util.HashMap; import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map; import java.util.Map;
/** /**
@ -29,14 +32,20 @@ import java.util.Map;
*/ */
public class ClientBuilder { public class ClientBuilder {
private ClientRepresentation rep = new ClientRepresentation(); private ClientRepresentation rep;
public static ClientBuilder create() { public static ClientBuilder create() {
return new ClientBuilder(); ClientRepresentation rep = new ClientRepresentation();
rep.setEnabled(Boolean.TRUE);
return new ClientBuilder(rep);
} }
private ClientBuilder() { public static ClientBuilder edit(ClientRepresentation rep) {
rep.setEnabled(true); return new ClientBuilder(rep);
}
private ClientBuilder(ClientRepresentation rep) {
this.rep = rep;
} }
public ClientBuilder id(String id) { public ClientBuilder id(String id) {
@ -100,6 +109,26 @@ public class ClientBuilder {
return this; return this;
} }
public ClientBuilder addWebOrigin(String webOrigin) {
List<String> uris = rep.getWebOrigins();
if (uris == null) {
uris = new LinkedList<>();
rep.setWebOrigins(uris);
}
uris.add(webOrigin);
return this;
}
public ClientBuilder addRedirectUri(String redirectUri) {
List<String> uris = rep.getRedirectUris();
if (uris == null) {
uris = new LinkedList<>();
rep.setRedirectUris(uris);
}
uris.add(redirectUri);
return this;
}
public ClientBuilder redirectUris(String... redirectUris) { public ClientBuilder redirectUris(String... redirectUris) {
rep.setRedirectUris(Arrays.asList(redirectUris)); rep.setRedirectUris(Arrays.asList(redirectUris));
return this; return this;

View file

@ -56,6 +56,16 @@ public class UserBuilder {
return this; return this;
} }
public UserBuilder firstName(String firstName) {
rep.setFirstName(firstName);
return this;
}
public UserBuilder lastName(String lastName) {
rep.setLastName(lastName);
return this;
}
/** /**
* This method adds additional passwords to the user. * This method adds additional passwords to the user.
*/ */

View file

@ -101,7 +101,7 @@
{ {
"clientId": "test-app", "clientId": "test-app",
"enabled": true, "enabled": true,
"baseUrl": "http://localhost:8180/auth/realms/master/app", "baseUrl": "http://localhost:8180/auth/realms/master/app/auth",
"redirectUris": [ "redirectUris": [
"http://localhost:8180/auth/realms/master/app/*" "http://localhost:8180/auth/realms/master/app/*"
], ],

View file

@ -1,800 +0,0 @@
/*
* 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.account;
import org.junit.After;
import org.junit.Assert;
import org.junit.Before;
import org.junit.ClassRule;
import org.junit.Rule;
import org.junit.Test;
import org.keycloak.events.Details;
import org.keycloak.events.Event;
import org.keycloak.events.EventType;
import org.keycloak.migration.MigrationModel;
import org.keycloak.models.ClientModel;
import org.keycloak.models.KeycloakSession;
import org.keycloak.models.PasswordPolicy;
import org.keycloak.models.RealmModel;
import org.keycloak.models.UserCredentialModel;
import org.keycloak.models.UserModel;
import org.keycloak.models.utils.TimeBasedOTP;
import org.keycloak.representations.idm.CredentialRepresentation;
import org.keycloak.services.managers.RealmManager;
import org.keycloak.services.resources.AccountService;
import org.keycloak.services.resources.RealmsResource;
import org.keycloak.testsuite.AssertEvents;
import org.keycloak.testsuite.OAuthClient;
import org.keycloak.testsuite.pages.AccountApplicationsPage;
import org.keycloak.testsuite.pages.AccountLogPage;
import org.keycloak.testsuite.pages.AccountPasswordPage;
import org.keycloak.testsuite.pages.AccountSessionsPage;
import org.keycloak.testsuite.pages.AccountTotpPage;
import org.keycloak.testsuite.pages.AccountUpdateProfilePage;
import org.keycloak.testsuite.pages.AppPage;
import org.keycloak.testsuite.pages.AppPage.RequestType;
import org.keycloak.testsuite.pages.ErrorPage;
import org.keycloak.testsuite.pages.LoginPage;
import org.keycloak.testsuite.pages.RegisterPage;
import org.keycloak.testsuite.rule.KeycloakRule;
import org.keycloak.testsuite.rule.KeycloakRule.KeycloakSetup;
import org.keycloak.testsuite.rule.WebResource;
import org.keycloak.testsuite.rule.WebRule;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import javax.ws.rs.core.UriBuilder;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
/**
* @author <a href="mailto:sthorger@redhat.com">Stian Thorgersen</a>
*/
public class AccountTest {
@ClassRule
public static KeycloakRule keycloakRule = new KeycloakRule(new KeycloakSetup() {
@Override
public void config(RealmManager manager, RealmModel adminstrationRealm, RealmModel appRealm) {
UserModel user = manager.getSession().users().getUserByUsername("test-user@localhost", appRealm);
ClientModel accountApp = appRealm.getClientByClientId(org.keycloak.models.Constants.ACCOUNT_MANAGEMENT_CLIENT_ID);
UserModel user2 = manager.getSession().users().addUser(appRealm, "test-user-no-access@localhost");
user2.setEnabled(true);
user2.setEmail("test-user-no-access@localhost");
for (String r : accountApp.getDefaultRoles()) {
user2.deleteRoleMapping(accountApp.getRole(r));
}
UserCredentialModel creds = new UserCredentialModel();
creds.setType(CredentialRepresentation.PASSWORD);
creds.setValue("password");
user2.updateCredential(creds);
}
});
private static final UriBuilder BASE = UriBuilder.fromUri("http://localhost:8081/auth");
private static final String ACCOUNT_URL = RealmsResource.accountUrl(BASE.clone()).build("test").toString();
public static String ACCOUNT_REDIRECT = AccountService.loginRedirectUrl(BASE.clone()).build("test").toString();
@Rule
public AssertEvents events = new AssertEvents(keycloakRule);
@Rule
public WebRule webRule = new WebRule(this);
@WebResource
protected WebDriver driver;
@WebResource
protected OAuthClient oauth;
@WebResource
protected AppPage appPage;
@WebResource
protected LoginPage loginPage;
@WebResource
protected RegisterPage registerPage;
@WebResource
protected AccountPasswordPage changePasswordPage;
@WebResource
protected AccountUpdateProfilePage profilePage;
@WebResource
protected AccountTotpPage totpPage;
@WebResource
protected AccountLogPage logPage;
@WebResource
protected AccountSessionsPage sessionsPage;
@WebResource
protected AccountApplicationsPage applicationsPage;
@WebResource
protected ErrorPage errorPage;
private TimeBasedOTP totp = new TimeBasedOTP();
private String userId;
@Before
public void before() {
oauth.state("mystate"); // keycloak enforces that a state param has been sent by client
userId = keycloakRule.getUser("test", "test-user@localhost").getId();
}
@After
public void after() {
keycloakRule.update(new KeycloakSetup() {
@Override
public void config(RealmManager manager, RealmModel defaultRealm, RealmModel appRealm) {
UserModel user = manager.getSession().users().getUserByUsername("test-user@localhost", appRealm);
user.setFirstName("Tom");
user.setLastName("Brady");
user.setEmail("test-user@localhost");
UserCredentialModel cred = new UserCredentialModel();
cred.setType(CredentialRepresentation.PASSWORD);
cred.setValue("password");
user.updateCredential(cred);
}
});
}
//@Test
public void ideTesting() throws Exception {
Thread.sleep(100000000);
}
@Test
public void testMigrationModel() {
KeycloakSession keycloakSession = keycloakRule.startSession();
Assert.assertEquals(keycloakSession.realms().getMigrationModel().getStoredVersion(), MigrationModel.LATEST_VERSION);
keycloakSession.close();
}
@Test
public void returnToAppFromQueryParam() {
driver.navigate().to(AccountUpdateProfilePage.PATH + "?referrer=test-app");
loginPage.login("test-user@localhost", "password");
Assert.assertTrue(profilePage.isCurrent());
profilePage.backToApplication();
Assert.assertTrue(appPage.isCurrent());
driver.navigate().to(AccountUpdateProfilePage.PATH + "?referrer=test-app&referrer_uri=http://localhost:8081/app?test");
Assert.assertTrue(profilePage.isCurrent());
profilePage.backToApplication();
Assert.assertTrue(appPage.isCurrent());
Assert.assertEquals(appPage.baseUrl + "?test", driver.getCurrentUrl());
driver.navigate().to(AccountUpdateProfilePage.PATH + "?referrer=test-app");
Assert.assertTrue(profilePage.isCurrent());
driver.findElement(By.linkText("Authenticator")).click();
Assert.assertTrue(totpPage.isCurrent());
driver.findElement(By.linkText("Account")).click();
Assert.assertTrue(profilePage.isCurrent());
profilePage.backToApplication();
Assert.assertTrue(appPage.isCurrent());
events.clear();
}
@Test
public void changePassword() {
changePasswordPage.open();
loginPage.login("test-user@localhost", "password");
Event event = events.expectLogin().client("account").detail(Details.REDIRECT_URI, ACCOUNT_REDIRECT + "?path=password").assertEvent();
String sessionId = event.getSessionId();
String userId = event.getUserId();
changePasswordPage.changePassword("", "new-password", "new-password");
Assert.assertEquals("Please specify password.", profilePage.getError());
changePasswordPage.changePassword("password", "new-password", "new-password2");
Assert.assertEquals("Password confirmation doesn't match.", profilePage.getError());
changePasswordPage.changePassword("password", "new-password", "new-password");
Assert.assertEquals("Your password has been updated.", profilePage.getSuccess());
events.expectAccount(EventType.UPDATE_PASSWORD).assertEvent();
changePasswordPage.logout();
events.expectLogout(sessionId).detail(Details.REDIRECT_URI, changePasswordPage.getPath()).assertEvent();
loginPage.open();
loginPage.login("test-user@localhost", "password");
Assert.assertEquals("Invalid username or password.", loginPage.getError());
events.expectLogin().session((String) null).error("invalid_user_credentials")
.removeDetail(Details.CONSENT)
.assertEvent();
loginPage.open();
loginPage.login("test-user@localhost", "new-password");
Assert.assertEquals(RequestType.AUTH_RESPONSE, appPage.getRequestType());
events.expectLogin().assertEvent();
}
@Test
public void changePasswordWithLengthPasswordPolicy() {
keycloakRule.update(new KeycloakRule.KeycloakSetup() {
@Override
public void config(RealmManager manager, RealmModel adminstrationRealm, RealmModel appRealm) {
appRealm.setPasswordPolicy(new PasswordPolicy("length"));
}
});
try {
changePasswordPage.open();
loginPage.login("test-user@localhost", "password");
events.expectLogin().client("account").detail(Details.REDIRECT_URI, ACCOUNT_REDIRECT + "?path=password").assertEvent();
changePasswordPage.changePassword("", "new", "new");
Assert.assertEquals("Please specify password.", profilePage.getError());
changePasswordPage.changePassword("password", "new-password", "new-password");
Assert.assertEquals("Your password has been updated.", profilePage.getSuccess());
events.expectAccount(EventType.UPDATE_PASSWORD).assertEvent();
} finally {
keycloakRule.update(new KeycloakRule.KeycloakSetup() {
@Override
public void config(RealmManager manager, RealmModel adminstrationRealm, RealmModel appRealm) {
appRealm.setPasswordPolicy(new PasswordPolicy(null));
}
});
}
}
@Test
public void changePasswordWithPasswordHistoryPolicy() {
keycloakRule.update(new KeycloakRule.KeycloakSetup() {
@Override
public void config(RealmManager manager, RealmModel adminstrationRealm, RealmModel appRealm) {
appRealm.setPasswordPolicy(new PasswordPolicy("passwordHistory(2)"));
}
});
try {
changePasswordPage.open();
loginPage.login("test-user@localhost", "password");
events.expectLogin().client("account").detail(Details.REDIRECT_URI, ACCOUNT_REDIRECT + "?path=password").assertEvent();
changePasswordPage.changePassword("password", "password", "password");
Assert.assertEquals("Invalid password: must not be equal to any of last 2 passwords.", profilePage.getError());
changePasswordPage.changePassword("password", "password1", "password1");
Assert.assertEquals("Your password has been updated.", profilePage.getSuccess());
events.expectAccount(EventType.UPDATE_PASSWORD).assertEvent();
changePasswordPage.changePassword("password1", "password", "password");
Assert.assertEquals("Invalid password: must not be equal to any of last 2 passwords.", profilePage.getError());
changePasswordPage.changePassword("password1", "password1", "password1");
Assert.assertEquals("Invalid password: must not be equal to any of last 2 passwords.", profilePage.getError());
changePasswordPage.changePassword("password1", "password2", "password2");
Assert.assertEquals("Your password has been updated.", profilePage.getSuccess());
events.expectAccount(EventType.UPDATE_PASSWORD).assertEvent();
} finally {
keycloakRule.update(new KeycloakRule.KeycloakSetup() {
@Override
public void config(RealmManager manager, RealmModel adminstrationRealm, RealmModel appRealm) {
appRealm.setPasswordPolicy(new PasswordPolicy(null));
}
});
}
}
@Test
public void changeProfile() {
profilePage.open();
loginPage.login("test-user@localhost", "password");
events.expectLogin().client("account").detail(Details.REDIRECT_URI, ACCOUNT_REDIRECT).assertEvent();
Assert.assertEquals("Tom", profilePage.getFirstName());
Assert.assertEquals("Brady", profilePage.getLastName());
Assert.assertEquals("test-user@localhost", profilePage.getEmail());
// All fields are required, so there should be an error when something is missing.
profilePage.updateProfile("", "New last", "new@email.com");
Assert.assertEquals("Please specify first name.", profilePage.getError());
Assert.assertEquals("", profilePage.getFirstName());
Assert.assertEquals("New last", profilePage.getLastName());
Assert.assertEquals("new@email.com", profilePage.getEmail());
events.assertEmpty();
profilePage.updateProfile("New first", "", "new@email.com");
Assert.assertEquals("Please specify last name.", profilePage.getError());
Assert.assertEquals("New first", profilePage.getFirstName());
Assert.assertEquals("", profilePage.getLastName());
Assert.assertEquals("new@email.com", profilePage.getEmail());
events.assertEmpty();
profilePage.updateProfile("New first", "New last", "");
Assert.assertEquals("Please specify email.", profilePage.getError());
Assert.assertEquals("New first", profilePage.getFirstName());
Assert.assertEquals("New last", profilePage.getLastName());
Assert.assertEquals("", profilePage.getEmail());
events.assertEmpty();
profilePage.clickCancel();
Assert.assertEquals("Tom", profilePage.getFirstName());
Assert.assertEquals("Brady", profilePage.getLastName());
Assert.assertEquals("test-user@localhost", profilePage.getEmail());
events.assertEmpty();
profilePage.updateProfile("New first", "New last", "new@email.com");
Assert.assertEquals("Your account has been updated.", profilePage.getSuccess());
Assert.assertEquals("New first", profilePage.getFirstName());
Assert.assertEquals("New last", profilePage.getLastName());
Assert.assertEquals("new@email.com", profilePage.getEmail());
events.expectAccount(EventType.UPDATE_PROFILE).assertEvent();
events.expectAccount(EventType.UPDATE_EMAIL).detail(Details.PREVIOUS_EMAIL, "test-user@localhost").detail(Details.UPDATED_EMAIL, "new@email.com").assertEvent();
// reset user for other tests
profilePage.updateProfile("Tom", "Brady", "test-user@localhost");
events.clear();
}
@Test
public void changeUsername() {
// allow to edit the username in realm
keycloakRule.update(new KeycloakRule.KeycloakSetup() {
@Override
public void config(RealmManager manager, RealmModel adminstrationRealm, RealmModel appRealm) {
appRealm.setEditUsernameAllowed(true);
}
});
try {
profilePage.open();
loginPage.login("test-user@localhost", "password");
events.expectLogin().client("account").detail(Details.REDIRECT_URI, ACCOUNT_REDIRECT).assertEvent();
Assert.assertEquals("test-user@localhost", profilePage.getUsername());
Assert.assertEquals("Tom", profilePage.getFirstName());
Assert.assertEquals("Brady", profilePage.getLastName());
Assert.assertEquals("test-user@localhost", profilePage.getEmail());
// All fields are required, so there should be an error when something is missing.
profilePage.updateProfile("", "New first", "New last", "new@email.com");
Assert.assertEquals("Please specify username.", profilePage.getError());
Assert.assertEquals("", profilePage.getUsername());
Assert.assertEquals("New first", profilePage.getFirstName());
Assert.assertEquals("New last", profilePage.getLastName());
Assert.assertEquals("new@email.com", profilePage.getEmail());
events.assertEmpty();
// Change to the username already occupied by other user
profilePage.updateProfile("test-user-no-access@localhost", "New first", "New last", "new@email.com");
Assert.assertEquals("Username already exists.", profilePage.getError());
Assert.assertEquals("test-user-no-access@localhost", profilePage.getUsername());
Assert.assertEquals("New first", profilePage.getFirstName());
Assert.assertEquals("New last", profilePage.getLastName());
Assert.assertEquals("new@email.com", profilePage.getEmail());
events.assertEmpty();
profilePage.updateProfile("test-user-new@localhost", "New first", "New last", "new@email.com");
Assert.assertEquals("Your account has been updated.", profilePage.getSuccess());
Assert.assertEquals("test-user-new@localhost", profilePage.getUsername());
Assert.assertEquals("New first", profilePage.getFirstName());
Assert.assertEquals("New last", profilePage.getLastName());
Assert.assertEquals("new@email.com", profilePage.getEmail());
} finally {
// reset user for other tests
profilePage.updateProfile("test-user@localhost", "Tom", "Brady", "test-user@localhost");
events.clear();
// reset realm
keycloakRule.update(new KeycloakRule.KeycloakSetup() {
@Override
public void config(RealmManager manager, RealmModel adminstrationRealm, RealmModel appRealm) {
appRealm.setEditUsernameAllowed(false);
}
});
}
}
@Test
public void changeUsernameLoginWithOldUsername() {
KeycloakSession session = keycloakRule.startSession();
UserModel user = session.users().addUser(session.realms().getRealm("test"), "change-username");
user.setEnabled(true);
user.setEmail("change-username@localhost");
user.setFirstName("first");
user.setLastName("last");
user.updateCredential(UserCredentialModel.password("password"));
keycloakRule.stopSession(session, true);
keycloakRule.update(new KeycloakRule.KeycloakSetup() {
@Override
public void config(RealmManager manager, RealmModel adminstrationRealm, RealmModel appRealm) {
appRealm.setEditUsernameAllowed(true);
}
});
try {
profilePage.open();
loginPage.login("change-username", "password");
profilePage.updateUsername("change-username-updated");
Assert.assertEquals("Your account has been updated.", profilePage.getSuccess());
profilePage.logout();
profilePage.open();
Assert.assertTrue(loginPage.isCurrent());
loginPage.login("change-username", "password");
Assert.assertTrue(loginPage.isCurrent());
Assert.assertEquals("Invalid username or password.", loginPage.getError());
loginPage.login("change-username-updated", "password");
} finally {
events.clear();
keycloakRule.update(new KeycloakRule.KeycloakSetup() {
@Override
public void config(RealmManager manager, RealmModel adminstrationRealm, RealmModel appRealm) {
appRealm.setEditUsernameAllowed(false);
}
});
}
}
@Test
public void changeEmailLoginWithOldEmail() {
KeycloakSession session = keycloakRule.startSession();
UserModel user = session.users().addUser(session.realms().getRealm("test"), "change-email");
user.setEnabled(true);
user.setEmail("change-username@localhost");
user.setFirstName("first");
user.setLastName("last");
user.updateCredential(UserCredentialModel.password("password"));
keycloakRule.stopSession(session, true);
keycloakRule.update(new KeycloakRule.KeycloakSetup() {
@Override
public void config(RealmManager manager, RealmModel adminstrationRealm, RealmModel appRealm) {
appRealm.setEditUsernameAllowed(true);
}
});
try {
profilePage.open();
loginPage.login("change-username@localhost", "password");
profilePage.updateEmail("change-username-updated@localhost");
Assert.assertEquals("Your account has been updated.", profilePage.getSuccess());
profilePage.logout();
profilePage.open();
Assert.assertTrue(loginPage.isCurrent());
loginPage.login("change-username@localhost", "password");
Assert.assertTrue(loginPage.isCurrent());
Assert.assertEquals("Invalid username or password.", loginPage.getError());
loginPage.login("change-username-updated@localhost", "password");
} finally {
events.clear();
keycloakRule.update(new KeycloakRule.KeycloakSetup() {
@Override
public void config(RealmManager manager, RealmModel adminstrationRealm, RealmModel appRealm) {
appRealm.setEditUsernameAllowed(false);
}
});
}
}
// KEYCLOAK-1534
@Test
public void changeEmailToExisting() {
profilePage.open();
loginPage.login("test-user@localhost", "password");
events.expectLogin().client("account").detail(Details.REDIRECT_URI, ACCOUNT_REDIRECT).assertEvent();
Assert.assertEquals("test-user@localhost", profilePage.getUsername());
Assert.assertEquals("test-user@localhost", profilePage.getEmail());
// Change to the email, which some other user has
profilePage.updateProfile("New first", "New last", "test-user-no-access@localhost");
profilePage.assertCurrent();
Assert.assertEquals("Email already exists.", profilePage.getError());
Assert.assertEquals("New first", profilePage.getFirstName());
Assert.assertEquals("New last", profilePage.getLastName());
Assert.assertEquals("test-user-no-access@localhost", profilePage.getEmail());
events.assertEmpty();
// Change some other things, but not email
profilePage.updateProfile("New first", "New last", "test-user@localhost");
Assert.assertEquals("Your account has been updated.", profilePage.getSuccess());
Assert.assertEquals("New first", profilePage.getFirstName());
Assert.assertEquals("New last", profilePage.getLastName());
Assert.assertEquals("test-user@localhost", profilePage.getEmail());
events.expectAccount(EventType.UPDATE_PROFILE).assertEvent();
// Change email and other things to original values
profilePage.updateProfile("Tom", "Brady", "test-user@localhost");
events.expectAccount(EventType.UPDATE_PROFILE).assertEvent();
}
@Test
public void setupTotp() {
totpPage.open();
loginPage.login("test-user@localhost", "password");
events.expectLogin().client("account").detail(Details.REDIRECT_URI, ACCOUNT_REDIRECT + "?path=totp").assertEvent();
Assert.assertTrue(totpPage.isCurrent());
Assert.assertFalse(driver.getPageSource().contains("Remove Google"));
// Error with false code
totpPage.configure(totp.generateTOTP(totpPage.getTotpSecret() + "123"));
Assert.assertEquals("Invalid authenticator code.", profilePage.getError());
totpPage.configure(totp.generateTOTP(totpPage.getTotpSecret()));
Assert.assertEquals("Mobile authenticator configured.", profilePage.getSuccess());
events.expectAccount(EventType.UPDATE_TOTP).assertEvent();
Assert.assertTrue(driver.getPageSource().contains("pficon-delete"));
totpPage.removeTotp();
events.expectAccount(EventType.REMOVE_TOTP).assertEvent();
}
@Test
public void changeProfileNoAccess() throws Exception {
profilePage.open();
loginPage.login("test-user-no-access@localhost", "password");
events.expectLogin().client("account").user(keycloakRule.getUser("test", "test-user-no-access@localhost").getId())
.detail(Details.USERNAME, "test-user-no-access@localhost")
.detail(Details.REDIRECT_URI, ACCOUNT_REDIRECT).assertEvent();
Assert.assertTrue(errorPage.isCurrent());
Assert.assertEquals("No access", errorPage.getError());
}
@Test
public void viewLog() {
keycloakRule.update(new KeycloakSetup() {
@Override
public void config(RealmManager manager, RealmModel adminstrationRealm, RealmModel appRealm) {
appRealm.setEventsEnabled(true);
}
});
try {
List<Event> expectedEvents = new LinkedList<Event>();
loginPage.open();
loginPage.clickRegister();
registerPage.register("view", "log", "view-log@localhost", "view-log", "password", "password");
expectedEvents.add(events.poll());
expectedEvents.add(events.poll());
profilePage.open();
profilePage.updateProfile("view", "log2", "view-log@localhost");
expectedEvents.add(events.poll());
logPage.open();
Assert.assertTrue(logPage.isCurrent());
List<List<String>> actualEvents = logPage.getEvents();
Assert.assertEquals(expectedEvents.size(), actualEvents.size());
for (Event e : expectedEvents) {
boolean match = false;
for (List<String> a : logPage.getEvents()) {
if (e.getType().toString().replace('_', ' ').toLowerCase().equals(a.get(1)) &&
e.getIpAddress().equals(a.get(2)) &&
e.getClientId().equals(a.get(3))) {
match = true;
break;
}
}
if (!match) {
Assert.fail("Event not found " + e.getType());
}
}
} finally {
keycloakRule.update(new KeycloakSetup() {
@Override
public void config(RealmManager manager, RealmModel adminstrationRealm, RealmModel appRealm) {
appRealm.setEventsEnabled(false);
}
});
}
}
@Test
public void sessions() {
loginPage.open();
loginPage.clickRegister();
registerPage.register("view", "sessions", "view-sessions@localhost", "view-sessions", "password", "password");
Event registerEvent = events.expectRegister("view-sessions", "view-sessions@localhost").assertEvent();
String userId = registerEvent.getUserId();
events.expectLogin().user(userId).detail(Details.USERNAME, "view-sessions").assertEvent();
sessionsPage.open();
Assert.assertTrue(sessionsPage.isCurrent());
List<List<String>> sessions = sessionsPage.getSessions();
Assert.assertEquals(1, sessions.size());
Assert.assertEquals("127.0.0.1", sessions.get(0).get(0));
// Create second session
WebDriver driver2 = WebRule.createWebDriver();
try {
OAuthClient oauth2 = new OAuthClient(driver2);
oauth2.state("mystate");
oauth2.doLogin("view-sessions", "password");
Event login2Event = events.expectLogin().user(userId).detail(Details.USERNAME, "view-sessions").assertEvent();
sessionsPage.open();
sessions = sessionsPage.getSessions();
Assert.assertEquals(2, sessions.size());
sessionsPage.logoutAll();
events.expectLogout(registerEvent.getSessionId());
events.expectLogout(login2Event.getSessionId());
} finally {
driver2.close();
}
}
// More tests (including revoke) are in OAuthGrantTest and OfflineTokenTest
@Test
public void applications() {
applicationsPage.open();
loginPage.login("test-user@localhost", "password");
events.expectLogin().client("account").detail(Details.REDIRECT_URI, ACCOUNT_REDIRECT + "?path=applications").assertEvent();
Assert.assertTrue(applicationsPage.isCurrent());
Map<String, AccountApplicationsPage.AppEntry> apps = applicationsPage.getApplications();
Assert.assertEquals(3, apps.size());
AccountApplicationsPage.AppEntry accountEntry = apps.get("Account");
Assert.assertEquals(2, accountEntry.getRolesAvailable().size());
Assert.assertTrue(accountEntry.getRolesAvailable().contains("Manage account in Account"));
Assert.assertTrue(accountEntry.getRolesAvailable().contains("View profile in Account"));
Assert.assertEquals(1, accountEntry.getRolesGranted().size());
Assert.assertTrue(accountEntry.getRolesGranted().contains("Full Access"));
Assert.assertEquals(1, accountEntry.getProtocolMappersGranted().size());
Assert.assertTrue(accountEntry.getProtocolMappersGranted().contains("Full Access"));
AccountApplicationsPage.AppEntry testAppEntry = apps.get("test-app");
Assert.assertEquals(5, testAppEntry.getRolesAvailable().size());
Assert.assertTrue(testAppEntry.getRolesAvailable().contains("Offline access"));
Assert.assertTrue(testAppEntry.getRolesGranted().contains("Full Access"));
Assert.assertTrue(testAppEntry.getProtocolMappersGranted().contains("Full Access"));
AccountApplicationsPage.AppEntry thirdPartyEntry = apps.get("third-party");
Assert.assertEquals(2, thirdPartyEntry.getRolesAvailable().size());
Assert.assertTrue(thirdPartyEntry.getRolesAvailable().contains("Have User privileges"));
Assert.assertTrue(thirdPartyEntry.getRolesAvailable().contains("Have Customer User privileges in test-app"));
Assert.assertEquals(0, thirdPartyEntry.getRolesGranted().size());
Assert.assertEquals(0, thirdPartyEntry.getProtocolMappersGranted().size());
}
@Test
public void loginToSpecificPage() {
changePasswordPage.open();
loginPage.login("test-user@localhost", "password");
Assert.assertTrue(changePasswordPage.isCurrent());
events.clear();
}
@Test
public void loginToSpecificPageWithReferrer() {
driver.navigate().to(changePasswordPage.getPath() + "?referrer=account");
System.out.println(driver.getCurrentUrl());
loginPage.login("test-user@localhost", "password");
System.out.println(driver.getCurrentUrl());
Assert.assertTrue(changePasswordPage.isCurrent());
events.clear();
}
}