diff --git a/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/pages/AccountTotpPage.java b/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/pages/AccountTotpPage.java
deleted file mode 100755
index ff7f5d1599..0000000000
--- a/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/pages/AccountTotpPage.java
+++ /dev/null
@@ -1,90 +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.pages;
-
-import org.keycloak.services.resources.account.AccountFormService;
-import org.openqa.selenium.WebElement;
-import org.openqa.selenium.support.FindBy;
-
-import javax.ws.rs.core.UriBuilder;
-
-/**
- * @author Stian Thorgersen
- */
-public class AccountTotpPage extends AbstractAccountPage {
-
- @FindBy(id = "totpSecret")
- private WebElement totpSecret;
-
- @FindBy(id = "totp")
- private WebElement totpInput;
-
- @FindBy(id = "userLabel")
- private WebElement totpLabelInput;
-
- @FindBy(css = "button[type=\"submit\"]")
- private WebElement submitButton;
-
- @FindBy(id = "remove-mobile")
- private WebElement removeLink;
-
- @FindBy(id = "mode-barcode")
- private WebElement barcodeLink;
-
- @FindBy(id = "mode-manual")
- private WebElement manualLink;
-
- private String getPath() {
- return AccountFormService.totpUrl(UriBuilder.fromUri(getAuthServerRoot())).build("test").toString();
- }
-
- public void configure(String totp) {
- totpInput.sendKeys(totp);
- submitButton.click();
- }
-
- public void configure(String totp, String userLabel) {
- totpInput.sendKeys(totp);
- totpLabelInput.sendKeys(userLabel);
- submitButton.click();
- }
-
- public String getTotpSecret() {
- return totpSecret.getAttribute("value");
- }
-
- public boolean isCurrent() {
- return driver.getTitle().contains("Account Management") && driver.getCurrentUrl().split("\\?")[0].endsWith("/account/totp");
- }
-
- public void open() {
- driver.navigate().to(getPath());
- }
-
- public void removeTotp() {
- removeLink.click();
- }
-
- public void clickManual() {
- manualLink.click();
- }
-
- public void clickBarcode() {
- barcodeLink.click();
- }
-
-}
diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/AbstractAuthTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/AbstractAuthTest.java
index f00d06c809..e533520c26 100644
--- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/AbstractAuthTest.java
+++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/AbstractAuthTest.java
@@ -28,6 +28,8 @@ import org.keycloak.testsuite.auth.page.account.Account;
import org.keycloak.testsuite.auth.page.login.OIDCLogin;
import org.keycloak.testsuite.auth.page.login.SAMLPostLogin;
import org.keycloak.testsuite.auth.page.login.SAMLRedirectLogin;
+import org.keycloak.testsuite.util.ClientBuilder;
+import org.keycloak.testsuite.util.RealmBuilder;
import org.openqa.selenium.Cookie;
import java.text.MessageFormat;
diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/AbstractKeycloakTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/AbstractKeycloakTest.java
index 9f3a56ca65..eb87079664 100644
--- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/AbstractKeycloakTest.java
+++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/AbstractKeycloakTest.java
@@ -34,7 +34,6 @@ import org.keycloak.admin.client.resource.AuthenticationManagementResource;
import org.keycloak.admin.client.resource.RealmsResource;
import org.keycloak.admin.client.resource.UserResource;
import org.keycloak.admin.client.resource.UsersResource;
-import org.keycloak.common.Profile;
import org.keycloak.common.util.KeycloakUriBuilder;
import org.keycloak.common.util.Time;
import org.keycloak.models.RealmProvider;
diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/actions/AppInitiatedActionTotpSetupTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/actions/AppInitiatedActionTotpSetupTest.java
index 36dae497bb..e9c948a746 100755
--- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/actions/AppInitiatedActionTotpSetupTest.java
+++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/actions/AppInitiatedActionTotpSetupTest.java
@@ -24,7 +24,6 @@ import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
import org.keycloak.admin.client.resource.RealmResource;
-import org.keycloak.common.Profile;
import org.keycloak.events.Details;
import org.keycloak.events.EventType;
import org.keycloak.models.AuthenticationExecutionModel;
@@ -37,11 +36,10 @@ import org.keycloak.representations.idm.RealmRepresentation;
import org.keycloak.representations.idm.UserRepresentation;
import org.keycloak.testsuite.AssertEvents;
import org.keycloak.testsuite.admin.ApiUtil;
-import org.keycloak.testsuite.arquillian.annotation.DisableFeature;
-import org.keycloak.testsuite.pages.AccountTotpPage;
import org.keycloak.testsuite.pages.LoginConfigTotpPage;
import org.keycloak.testsuite.pages.LoginTotpPage;
import org.keycloak.testsuite.pages.RegisterPage;
+import org.keycloak.testsuite.util.AccountHelper;
import org.keycloak.testsuite.util.OAuthClient;
import org.keycloak.testsuite.util.RealmBuilder;
import org.keycloak.testsuite.util.UserBuilder;
@@ -93,9 +91,6 @@ public class AppInitiatedActionTotpSetupTest extends AbstractAppInitiatedActionT
@Page
protected LoginConfigTotpPage totpPage;
- @Page
- protected AccountTotpPage accountTotpPage;
-
@Page
protected RegisterPage registerPage;
@@ -111,7 +106,7 @@ public class AppInitiatedActionTotpSetupTest extends AbstractAppInitiatedActionT
doAIA();
- assertTrue(totpPage.isCurrent());
+ totpPage.assertCurrent();
totpPage.configure(totp.generateTOTP(totpPage.getTotpSecret()));
@@ -374,7 +369,6 @@ public class AppInitiatedActionTotpSetupTest extends AbstractAppInitiatedActionT
}
@Test
- @DisableFeature(value = Profile.Feature.ACCOUNT2, skipRestart = true) // TODO remove this (KEYCLOAK-16228)
public void setupTotpRegisteredAfterTotpRemoval() {
// Register new user
loginPage.open();
@@ -418,21 +412,11 @@ public class AppInitiatedActionTotpSetupTest extends AbstractAppInitiatedActionT
// Login with one-time password
loginTotpPage.login(totp.generateTOTP(totpCode));
+ events.expectLogin().user(userId).detail(Details.USERNAME, "setupTotp2").assertEvent();
- loginEvent = events.expectLogin().user(userId).detail(Details.USERNAME, "setupTotp2").assertEvent();
-
- // Open account page
- accountTotpPage.open();
- accountTotpPage.assertCurrent();
-
- // Remove google authentificator
- accountTotpPage.removeTotp();
-
- events.expectAccount(EventType.REMOVE_TOTP).user(userId).assertEvent();
-
- // Logout
- accountTotpPage.logout();
- events.expectLogout(loginEvent.getSessionId()).user(userId).detail(Details.REDIRECT_URI, oauth.AUTH_SERVER_ROOT + "/realms/test/account/totp").assertEvent();
+ // Remove google authenticator
+ Assert.assertTrue(AccountHelper.deleteTotpAuthentication(testRealm(),"setupTotp2"));
+ AccountHelper.logout(testRealm(),"setupTotp2");
// Try to login
loginPage.open();
diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/actions/RequiredActionTotpSetupTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/actions/RequiredActionTotpSetupTest.java
index 68660f0055..5cedb3c811 100755
--- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/actions/RequiredActionTotpSetupTest.java
+++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/actions/RequiredActionTotpSetupTest.java
@@ -23,7 +23,6 @@ import org.junit.Rule;
import org.junit.Test;
import org.keycloak.admin.client.resource.RealmResource;
import org.keycloak.admin.client.resource.UserResource;
-import org.keycloak.common.Profile;
import org.keycloak.events.Details;
import org.keycloak.events.EventType;
import org.keycloak.models.AuthenticationExecutionModel;
@@ -38,8 +37,6 @@ import org.keycloak.representations.idm.UserRepresentation;
import org.keycloak.testsuite.AssertEvents;
import org.keycloak.testsuite.AbstractTestRealmKeycloakTest;
import org.keycloak.testsuite.admin.ApiUtil;
-import org.keycloak.testsuite.arquillian.annotation.DisableFeature;
-import org.keycloak.testsuite.pages.AccountTotpPage;
import org.keycloak.testsuite.pages.AppPage;
import org.keycloak.testsuite.pages.AppPage.RequestType;
import org.keycloak.testsuite.pages.LanguageComboboxAwarePage;
@@ -48,6 +45,7 @@ import org.keycloak.testsuite.pages.LoginPage;
import org.keycloak.testsuite.pages.LoginTotpPage;
import org.keycloak.testsuite.pages.RegisterPage;
import org.keycloak.testsuite.updaters.RealmAttributeUpdater;
+import org.keycloak.testsuite.util.AccountHelper;
import org.keycloak.testsuite.util.OAuthClient;
import org.keycloak.testsuite.util.RealmBuilder;
import org.keycloak.testsuite.util.UserBuilder;
@@ -64,7 +62,6 @@ import static org.junit.Assert.assertTrue;
/**
* @author Stian Thorgersen
*/
-@DisableFeature(value = Profile.Feature.ACCOUNT2, skipRestart = true) // TODO remove this (KEYCLOAK-16228)
public class RequiredActionTotpSetupTest extends AbstractTestRealmKeycloakTest {
@Override
@@ -117,9 +114,6 @@ public class RequiredActionTotpSetupTest extends AbstractTestRealmKeycloakTest {
@Page
protected LoginConfigTotpPage totpPage;
- @Page
- protected AccountTotpPage accountTotpPage;
-
@Page
protected RegisterPage registerPage;
@@ -133,7 +127,7 @@ public class RequiredActionTotpSetupTest extends AbstractTestRealmKeycloakTest {
String userId = events.expectRegister("setupTotp", "email@mail.com").assertEvent().getUserId();
- assertTrue(totpPage.isCurrent());
+ totpPage.assertCurrent();
assertFalse(totpPage.isCancelDisplayed());
// assert attempted-username not shown when setup TOTP
@@ -278,7 +272,7 @@ public class RequiredActionTotpSetupTest extends AbstractTestRealmKeycloakTest {
String userId = events.expectRegister("setupTotpRegister", "setupTotpRegister@mail.com").assertEvent().getUserId();
- assertTrue(totpPage.isCurrent());
+ totpPage.assertCurrent();
// KEYCLOAK-11753 - Verify OTP label element present on "Configure OTP" required action form
driver.findElement(By.id("userLabel"));
@@ -290,12 +284,9 @@ public class RequiredActionTotpSetupTest extends AbstractTestRealmKeycloakTest {
// Set OTP label to a custom value
totpPage.configure(totp.generateTOTP(totpPage.getTotpSecret()), customOtpLabel);
- // Open account page & verify OTP authenticator with requested label was created
- accountTotpPage.open();
- accountTotpPage.assertCurrent();
-
- String pageSource = driver.getPageSource();
- assertTrue(pageSource.contains(customOtpLabel));
+ // Check if OTP credential is present
+ Assert.assertTrue(AccountHelper.isTotpPresent(testRealm(), "setupTotpRegister"));
+ Assert.assertTrue(AccountHelper.totpUserLabelComparator(testRealm(), "setupTotpRegister", customOtpLabel));
}
@Test
@@ -450,18 +441,9 @@ public class RequiredActionTotpSetupTest extends AbstractTestRealmKeycloakTest {
loginEvent = events.expectLogin().user(userId).detail(Details.USERNAME, "setupTotp2").assertEvent();
- // Open account page
- accountTotpPage.open();
- accountTotpPage.assertCurrent();
-
- // Remove google authentificator
- accountTotpPage.removeTotp();
-
- events.expectAccount(EventType.REMOVE_TOTP).user(userId).assertEvent();
-
- // Logout
- accountTotpPage.logout();
- events.expectLogout(loginEvent.getSessionId()).user(userId).detail(Details.REDIRECT_URI, oauth.AUTH_SERVER_ROOT + "/realms/test/account/totp").assertEvent();
+ // Remove google authenticator
+ Assert.assertTrue(AccountHelper.deleteTotpAuthentication(testRealm(),"setupTotp2"));
+ AccountHelper.logout(testRealm(),"setupTotp2");
setOtpTimeOffset(TimeBasedOTP.DEFAULT_INTERVAL_SECONDS, totp);
diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/UserTotpTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/UserTotpTest.java
deleted file mode 100644
index 9e92b6276a..0000000000
--- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/UserTotpTest.java
+++ /dev/null
@@ -1,103 +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.admin;
-
-import org.jboss.arquillian.graphene.page.Page;
-import org.junit.Assert;
-import org.junit.Rule;
-import org.junit.Test;
-import org.keycloak.common.Profile;
-import org.keycloak.events.Details;
-import org.keycloak.events.EventType;
-import org.keycloak.events.admin.OperationType;
-import org.keycloak.models.credential.OTPCredentialModel;
-import org.keycloak.models.utils.TimeBasedOTP;
-import org.keycloak.representations.idm.AdminEventRepresentation;
-import org.keycloak.representations.idm.CredentialRepresentation;
-import org.keycloak.representations.idm.RealmRepresentation;
-import org.keycloak.representations.idm.UserRepresentation;
-import org.keycloak.testsuite.AssertEvents;
-import org.keycloak.testsuite.AbstractTestRealmKeycloakTest;
-import org.keycloak.testsuite.arquillian.annotation.DisableFeature;
-import org.keycloak.testsuite.pages.AccountTotpPage;
-import org.keycloak.testsuite.pages.AccountUpdateProfilePage;
-import org.keycloak.testsuite.pages.LoginPage;
-
-import java.util.List;
-
-
-/**
- * @author Marko Strukelj
- */
-@DisableFeature(value = Profile.Feature.ACCOUNT2, skipRestart = true) // TODO remove this (KEYCLOAK-16228)
-public class UserTotpTest extends AbstractTestRealmKeycloakTest {
-
- @Rule
- public AssertEvents events = new AssertEvents(this);
-
- @Page
- protected AccountTotpPage totpPage;
-
- @Page
- protected AccountUpdateProfilePage profilePage;
-
- @Page
- protected LoginPage loginPage;
-
- private TimeBasedOTP totp = new TimeBasedOTP();
-
-
- @Override
- public void configureTestRealm(RealmRepresentation testRealm) {
- }
-
- @Test
- public void setupTotp() {
- totpPage.open();
- loginPage.login("test-user@localhost", "password");
-
- events.expectLogin().client("account").detail(Details.REDIRECT_URI, getAccountRedirectUrl() + "?path=totp").assertEvent();
-
- Assert.assertTrue(totpPage.isCurrent());
-
- Assert.assertFalse(driver.getPageSource().contains("Remove Google"));
-
- 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"));
-
- List users = adminClient.realms().realm("test").users().search("test-user@localhost", null, null, null, 0, 1);
- String userId = users.get(0).getId();
- testingClient.testing().clearAdminEventQueue();
- CredentialRepresentation totpCredential = adminClient.realms().realm("test").users().get(userId).credentials()
- .stream().filter(c -> OTPCredentialModel.TYPE.equals(c.getType())).findFirst().get();
- adminClient.realms().realm("test").users().get(userId).removeCredential(totpCredential.getId());
-
- totpPage.open();
- Assert.assertFalse(driver.getPageSource().contains("pficon-delete"));
-
- AdminEventRepresentation event = testingClient.testing().pollAdminEvent();
- Assert.assertNotNull(event);
- Assert.assertEquals(OperationType.ACTION.name(), event.getOperationType());
- Assert.assertEquals("users/" + userId + "/credentials/" + totpCredential.getId(), event.getResourcePath());
- }
-}
diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/federation/storage/BackwardsCompatibilityUserStorageTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/federation/storage/BackwardsCompatibilityUserStorageTest.java
index 76598f67e2..9e68fd61c2 100644
--- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/federation/storage/BackwardsCompatibilityUserStorageTest.java
+++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/federation/storage/BackwardsCompatibilityUserStorageTest.java
@@ -18,53 +18,50 @@
package org.keycloak.testsuite.federation.storage;
+import org.jboss.arquillian.graphene.page.Page;
+import org.junit.Before;
+import org.junit.BeforeClass;
+import org.junit.Test;
+import org.keycloak.admin.client.resource.UserResource;
+import org.keycloak.common.Profile.Feature;
+import org.keycloak.common.util.MultivaluedHashMap;
+import org.keycloak.credential.CredentialModel;
+import org.keycloak.models.RealmModel;
+import org.keycloak.models.UserModel;
+import org.keycloak.models.credential.OTPCredentialModel;
+import org.keycloak.models.utils.TimeBasedOTP;
+import org.keycloak.representations.idm.ComponentRepresentation;
+import org.keycloak.representations.idm.CredentialRepresentation;
+import org.keycloak.representations.idm.RealmRepresentation;
+import org.keycloak.representations.idm.UserRepresentation;
+import org.keycloak.storage.StorageId;
+import org.keycloak.storage.UserStorageProvider;
+import org.keycloak.testsuite.AbstractTestRealmKeycloakTest;
+import org.keycloak.testsuite.Assert;
+import org.keycloak.testsuite.ProfileAssume;
+import org.keycloak.testsuite.admin.ApiUtil;
+import org.keycloak.testsuite.federation.BackwardsCompatibilityUserStorageFactory;
+import org.keycloak.testsuite.pages.AppPage;
+import org.keycloak.testsuite.pages.LoginConfigTotpPage;
+import org.keycloak.testsuite.pages.LoginPage;
+import org.keycloak.testsuite.pages.LoginTotpPage;
+import org.keycloak.testsuite.util.TestAppHelper;
+
+import javax.ws.rs.core.Response;
import java.io.IOException;
import java.net.URISyntaxException;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
-import javax.ws.rs.core.Response;
-
-import org.jboss.arquillian.graphene.page.Page;
-import org.junit.Before;
-import org.junit.Test;
-import org.keycloak.admin.client.resource.UserResource;
-import org.keycloak.common.Profile;
-import org.keycloak.common.Profile.Feature;
-import org.keycloak.common.util.MultivaluedHashMap;
-import org.keycloak.credential.CredentialModel;
-import org.keycloak.models.RealmModel;
-import org.keycloak.models.UserModel;
-import org.keycloak.models.utils.TimeBasedOTP;
-import org.keycloak.representations.idm.ComponentRepresentation;
-import org.keycloak.representations.idm.CredentialRepresentation;
-import org.keycloak.representations.idm.UserRepresentation;
-import org.keycloak.storage.StorageId;
-import org.keycloak.storage.UserStorageProvider;
-import org.keycloak.testsuite.AbstractAuthTest;
-import org.keycloak.testsuite.Assert;
-import org.keycloak.testsuite.ProfileAssume;
-import org.keycloak.testsuite.admin.ApiUtil;
-import org.keycloak.testsuite.arquillian.annotation.DisableFeature;
-import org.keycloak.testsuite.federation.BackwardsCompatibilityUserStorageFactory;
-import org.keycloak.testsuite.pages.AccountTotpPage;
-import org.keycloak.testsuite.pages.AppPage;
-import org.keycloak.testsuite.pages.LoginConfigTotpPage;
-import org.keycloak.testsuite.pages.LoginPage;
-import org.keycloak.testsuite.pages.LoginTotpPage;
-
-import org.junit.BeforeClass;
-import static org.keycloak.testsuite.util.URLAssert.assertCurrentUrlDoesntStartWith;
-import static org.keycloak.testsuite.util.URLAssert.assertCurrentUrlStartsWith;
+import static org.wildfly.common.Assert.assertTrue;
/**
* Test that userStorage implementation created in previous version is still compatible with latest Keycloak version
*
* @author Marek Posolda
*/
-@DisableFeature(value = Profile.Feature.ACCOUNT2, skipRestart = true) // TODO remove this (KEYCLOAK-16228)
-public class BackwardsCompatibilityUserStorageTest extends AbstractAuthTest {
+public class BackwardsCompatibilityUserStorageTest extends AbstractTestRealmKeycloakTest {
private String backwardsCompProviderId;
@@ -77,15 +74,14 @@ public class BackwardsCompatibilityUserStorageTest extends AbstractAuthTest {
@Page
protected LoginTotpPage loginTotpPage;
- @Page
- protected AccountTotpPage accountTotpSetupPage;
-
@Page
protected LoginConfigTotpPage configureTotpRequiredActionPage;
private TimeBasedOTP totp = new TimeBasedOTP();
+
+
@BeforeClass
public static void checkNotMapStorage() {
ProfileAssume.assumeFeatureDisabled(Feature.MAP_STORAGE);
@@ -105,27 +101,29 @@ public class BackwardsCompatibilityUserStorageTest extends AbstractAuthTest {
}
protected String addComponent(ComponentRepresentation component) {
- Response resp = testRealmResource().components().add(component);
+ Response resp = testRealm().components().add(component);
String id = ApiUtil.getCreatedId(resp);
getCleanup().addComponentId(id);
return id;
}
- private void loginSuccessAndLogout(String username, String password) {
- testRealmAccountPage.navigateTo();
- loginPage.login(username, password);
- assertCurrentUrlStartsWith(testRealmAccountPage);
- testRealmAccountPage.logOut();
+ private void loginSuccessAndLogout(String username, String password) throws URISyntaxException, IOException {
+ TestAppHelper testAppHelper = new TestAppHelper(oauth, loginPage, appPage);
+
+ testAppHelper.login(username, password);
+ appPage.assertCurrent();
+
+ assertTrue(testAppHelper.logout());
}
public void loginBadPassword(String username) {
- testRealmAccountPage.navigateTo();
- testRealmLoginPage.form().login(username, "badpassword");
- assertCurrentUrlDoesntStartWith(testRealmAccountPage);
+ loginPage.open();
+ loginPage.login(username, "badpassword");
+ loginPage.assertCurrent();
}
@Test
- public void testLoginSuccess() {
+ public void testLoginSuccess() throws URISyntaxException, IOException {
addUserAndResetPassword("tbrady", "goat");
addUserAndResetPassword("tbrady2", "goat2");
@@ -139,7 +137,7 @@ public class BackwardsCompatibilityUserStorageTest extends AbstractAuthTest {
UserRepresentation user = new UserRepresentation();
user.setEnabled(true);
user.setUsername(username);
- Response response = testRealmResource().users().create(user);
+ Response response = testRealm().users().create(user);
String userId = ApiUtil.getCreatedId(response);
Assert.assertEquals(backwardsCompProviderId, new StorageId(userId).getProviderId());
@@ -150,14 +148,14 @@ public class BackwardsCompatibilityUserStorageTest extends AbstractAuthTest {
passwordRep.setValue(password);
passwordRep.setTemporary(false);
- testRealmResource().users().get(userId).resetPassword(passwordRep);
+ testRealm().users().get(userId).resetPassword(passwordRep);
return userId;
}
@Test
- public void testOTPUpdateAndLogin() {
+ public void testOTPUpdateAndLogin() throws URISyntaxException, IOException {
String userId = addUserAndResetPassword("otp1", "pass");
getCleanup().addUserId(userId);
@@ -171,58 +169,55 @@ public class BackwardsCompatibilityUserStorageTest extends AbstractAuthTest {
assertUserDontHaveDBCredentials();
assertUserHasOTPCredentialInUserStorage(true);
- // Authenticate as the user with the hardcoded OTP. Should be supported
- loginPage.login("otp1", "pass");
- loginTotpPage.assertCurrent();
- loginTotpPage.login("123456");
+ TestAppHelper testAppHelper = new TestAppHelper(oauth, loginPage, appPage);
- assertCurrentUrlStartsWith(testRealmAccountPage);
- testRealmAccountPage.logOut();
+ // Authenticate as the user with the hardcoded OTP. Should be supported
+ testAppHelper.startLogin("otp1", "pass");
+ loginTotpPage.login("123456");
+ testAppHelper.completeLogin();
+
+ appPage.assertCurrent();
+
+ testAppHelper.logout();
// Authenticate as the user with bad OTP
- loginPage.login("otp1", "pass");
+ testAppHelper.startLogin("otp1", "pass");
loginTotpPage.assertCurrent();
loginTotpPage.login("7123456");
- assertCurrentUrlDoesntStartWith(testRealmAccountPage);
+ loginTotpPage.assertCurrent();
Assert.assertNotNull(loginTotpPage.getInputError());
// Authenticate as the user with correct OTP
loginTotpPage.login(totp.generateTOTP(totpSecret));
- assertCurrentUrlStartsWith(testRealmAccountPage);
- testRealmAccountPage.logOut();
+ testAppHelper.completeLogin();
+ appPage.assertCurrent();
+
+ assertTrue(testAppHelper.logout());
}
@Test
- public void testOTPSetupThroughAccountMgmtAndLogin() {
+ public void testOTPSetupThroughAccountMgmtAndLogin() throws URISyntaxException, IOException {
String userId = addUserAndResetPassword("otp1", "pass");
getCleanup().addUserId(userId);
- // Login as user to account mgmt
- accountTotpSetupPage.open();
- loginPage.login("otp1", "pass");
-
// Setup OTP
- String totpSecret = accountTotpSetupPage.getTotpSecret();
- accountTotpSetupPage.configure(totp.generateTOTP(totpSecret));
+ String totpSecret = setupOTPForUserWithRequiredAction(userId);
assertUserDontHaveDBCredentials();
assertUserHasOTPCredentialInUserStorage(true);
- // Logout and assert user can login with hardcoded OTP
- accountTotpSetupPage.logout();
- loginPage.login("otp1", "pass");
- loginTotpPage.login("123456");
- assertCurrentUrlStartsWith(testRealmAccountPage);
+ TestAppHelper testAppHelper = new TestAppHelper(oauth, loginPage, loginTotpPage, appPage);
+
+ // Login as user to account mgmt
+ assertTrue(testAppHelper.login("otp1", "pass", "123456"));
// Logout and assert user can login with valid credential
- accountTotpSetupPage.logout();
- loginPage.login("otp1", "pass");
- loginTotpPage.login(totp.generateTOTP(totpSecret));
- assertCurrentUrlStartsWith(testRealmAccountPage);
+ testAppHelper.logout();
+ assertTrue(testAppHelper.login("otp1", "pass", totp.generateTOTP(totpSecret)));
+ testAppHelper.logout();
- // Delete OTP credential in account console
- accountTotpSetupPage.removeTotp();
- accountTotpSetupPage.logout();
+ // Disable OTP credential in account console
+ testRealm().users().get(userId).disableCredentialType(Collections.singletonList(OTPCredentialModel.TYPE));
assertUserDontHaveDBCredentials();
assertUserHasOTPCredentialInUserStorage(false);
@@ -232,7 +227,7 @@ public class BackwardsCompatibilityUserStorageTest extends AbstractAuthTest {
}
@Test
- public void testDisableCredentialsInUserStorage() {
+ public void testDisableCredentialsInUserStorage() throws URISyntaxException, IOException {
String userId = addUserAndResetPassword("otp1", "pass");
getCleanup().addUserId(userId);
@@ -243,13 +238,13 @@ public class BackwardsCompatibilityUserStorageTest extends AbstractAuthTest {
assertUserDontHaveDBCredentials();
assertUserHasOTPCredentialInUserStorage(true);
- UserResource user = testRealmResource().users().get(userId);
+ UserResource user = testRealm().users().get(userId);
// Disable OTP credential for the user through REST endpoint
UserRepresentation userRep = user.toRepresentation();
- Assert.assertNames(userRep.getDisableableCredentialTypes(), CredentialModel.OTP);
+ Assert.assertNames(userRep.getDisableableCredentialTypes(), OTPCredentialModel.TYPE);
- user.disableCredentialType(Collections.singletonList(CredentialModel.OTP));
+ user.disableCredentialType(Collections.singletonList(OTPCredentialModel.TYPE));
// User don't have OTP credential in userStorage anymore
assertUserDontHaveDBCredentials();
@@ -266,29 +261,32 @@ public class BackwardsCompatibilityUserStorageTest extends AbstractAuthTest {
getCleanup().addUserId(userId);
// Uses same parameters as admin console when searching users
- List users = testRealmResource().users().search("searching", 0, 20, true);
+ List users = testRealm().users().search("searching", 0, 20, true);
Assert.assertNames(users, "searching");
}
// return created totpSecret
- private String setupOTPForUserWithRequiredAction(String userId) {
+ private String setupOTPForUserWithRequiredAction(String userId) throws URISyntaxException, IOException {
// Add required action to the user to reset OTP
- UserResource user = testRealmResource().users().get(userId);
+ UserResource user = testRealm().users().get(userId);
UserRepresentation userRep = user.toRepresentation();
userRep.setRequiredActions(Arrays.asList(UserModel.RequiredAction.CONFIGURE_TOTP.toString()));
user.update(userRep);
+ TestAppHelper testAppHelper = new TestAppHelper(oauth, loginPage, appPage);
+
// Login as the user and setup OTP
- testRealmAccountPage.navigateTo();
- loginPage.login("otp1", "pass");
+ testAppHelper.startLogin("otp1", "pass");
configureTotpRequiredActionPage.assertCurrent();
String totpSecret = configureTotpRequiredActionPage.getTotpSecret();
configureTotpRequiredActionPage.configure(totp.generateTOTP(totpSecret));
- assertCurrentUrlStartsWith(testRealmAccountPage);
+ appPage.assertCurrent();
+
+ testAppHelper.completeLogin();
// Logout
- testRealmAccountPage.logOut();
+ assertTrue(testAppHelper.logout());
return totpSecret;
}
@@ -310,4 +308,9 @@ public class BackwardsCompatibilityUserStorageTest extends AbstractAuthTest {
}, Boolean.class);
Assert.assertEquals(expectedUserHasOTP, hasUserOTP);
}
+
+ @Override
+ public void configureTestRealm(RealmRepresentation testRealm) {
+
+ }
}
diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/forms/ResetCredentialsAlternativeFlowsTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/forms/ResetCredentialsAlternativeFlowsTest.java
index a1e0859c9a..bb29150dce 100644
--- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/forms/ResetCredentialsAlternativeFlowsTest.java
+++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/forms/ResetCredentialsAlternativeFlowsTest.java
@@ -18,14 +18,12 @@
package org.keycloak.testsuite.forms;
-import org.hamcrest.Matchers;
import org.jboss.arquillian.graphene.page.Page;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.keycloak.OAuth2Constants;
-import org.keycloak.common.Profile;
import org.keycloak.models.UserManager;
import org.keycloak.models.UserModel;
import org.keycloak.models.utils.DefaultAuthenticationFlows;
@@ -34,11 +32,9 @@ import org.keycloak.representations.idm.AuthenticationFlowRepresentation;
import org.keycloak.representations.idm.RealmRepresentation;
import org.keycloak.representations.idm.RequiredActionProviderRepresentation;
import org.keycloak.representations.idm.UserRepresentation;
-import org.keycloak.testsuite.AbstractTestRealmKeycloakTest;
+import org.keycloak.testsuite.actions.AbstractAppInitiatedActionTest;
import org.keycloak.testsuite.admin.ApiUtil;
import org.keycloak.testsuite.admin.authentication.AbstractAuthenticationTest;
-import org.keycloak.testsuite.arquillian.annotation.DisableFeature;
-import org.keycloak.testsuite.pages.AccountTotpPage;
import org.keycloak.testsuite.pages.AppPage;
import org.keycloak.testsuite.pages.ErrorPage;
import org.keycloak.testsuite.pages.LoginConfigTotpPage;
@@ -50,23 +46,13 @@ import org.keycloak.testsuite.pages.LoginUsernameOnlyPage;
import org.keycloak.testsuite.pages.LogoutConfirmPage;
import org.keycloak.testsuite.pages.PasswordPage;
import org.keycloak.testsuite.pages.RegisterPage;
-import org.keycloak.testsuite.util.FlowUtil;
-import org.keycloak.testsuite.util.GreenMailRule;
-import org.keycloak.testsuite.util.MailUtils;
-import org.keycloak.testsuite.util.OAuthClient;
-import org.keycloak.testsuite.util.URLUtils;
-import org.keycloak.testsuite.util.UserBuilder;
-import org.openqa.selenium.By;
-import org.openqa.selenium.WebElement;
+import org.keycloak.testsuite.util.*;
import javax.mail.internet.MimeMessage;
import java.util.Arrays;
import java.util.List;
-import java.util.regex.Pattern;
-import java.util.stream.Collectors;
import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertThat;
/**
* Test for the various alternatives of reset-credentials flow or browser flow (non-default setup of the flows)
@@ -74,7 +60,7 @@ import static org.junit.Assert.assertThat;
* @author Marek Posolda
* @author Jan Lieskovsky
*/
-public class ResetCredentialsAlternativeFlowsTest extends AbstractTestRealmKeycloakTest {
+public class ResetCredentialsAlternativeFlowsTest extends AbstractAppInitiatedActionTest {
private String userId;
@@ -99,9 +85,6 @@ public class ResetCredentialsAlternativeFlowsTest extends AbstractTestRealmKeycl
@Page
protected LoginPasswordUpdatePage updatePasswordPage;
- @Page
- protected AccountTotpPage accountTotpPage;
-
@Page
protected LoginConfigTotpPage totpPage;
@@ -136,6 +119,11 @@ public class ResetCredentialsAlternativeFlowsTest extends AbstractTestRealmKeycl
getCleanup().addUserId(userId);
}
+ @Override
+ public String getAiaAction() {
+ return UserModel.RequiredAction.CONFIGURE_TOTP.name();
+ }
+
// Test with default reset-credentials flow and alternative browser flow with separate username and password screen.
//
@@ -236,7 +224,7 @@ public class ResetCredentialsAlternativeFlowsTest extends AbstractTestRealmKeycl
loginUsernameOnlyPage.open();
loginUsernameOnlyPage.login("login-test");
- Assert.assertTrue(passwordPage.isCurrent());
+ passwordPage.assertCurrent();
// Click "Forget password"
passwordPage.clickResetPassword();
@@ -272,7 +260,7 @@ public class ResetCredentialsAlternativeFlowsTest extends AbstractTestRealmKeycl
loginUsernameOnlyPage.open();
loginUsernameOnlyPage.login(username);
- Assert.assertTrue(passwordPage.isCurrent());
+ passwordPage.assertCurrent();
// Click "Forget password"
passwordPage.clickResetPassword();
@@ -344,7 +332,6 @@ public class ResetCredentialsAlternativeFlowsTest extends AbstractTestRealmKeycl
@Test
- @DisableFeature(value = Profile.Feature.ACCOUNT2, skipRestart = true) // TODO remove this (KEYCLOAK-16228)
public void resetCredentialsVerifyCustomOtpLabelSetProperly() {
try {
// Make a copy of the default Reset Credentials flow, but:
@@ -358,14 +345,17 @@ public class ResetCredentialsAlternativeFlowsTest extends AbstractTestRealmKeycl
// Login & set up the initial OTP code for the user
loginPage.open();
- loginPage.login("login@test.com", "password");
+ loginPage.login("login-test", "password");
String code = new OAuthClient.AuthorizationEndpointResponse(oauth).getCode();
OAuthClient.AccessTokenResponse response = oauth.doAccessTokenRequest(code, "password");
- accountTotpPage.open();
- Assert.assertTrue(accountTotpPage.isCurrent());
String customOtpLabel = "my-original-otp-label";
- accountTotpPage.configure(totp.generateTOTP(accountTotpPage.getTotpSecret()), customOtpLabel);
+
+ // Setup OTP
+ doAIA();
+ totpPage.assertCurrent();
+ totpPage.configure(totp.generateTOTP(totpPage.getTotpSecret()), customOtpLabel);
+ assertKcActionStatus(SUCCESS);
// Logout
oauth.idTokenHint(response.getIdToken()).openLogout();
@@ -375,26 +365,18 @@ public class ResetCredentialsAlternativeFlowsTest extends AbstractTestRealmKeycl
loginPage.resetPassword();
// Should be on reset password page now. Provide email of the user & click Submit button
- Assert.assertTrue(resetPasswordPage.isCurrent());
- resetPasswordPage.changePassword("login@test.com");
-
- // Since 'Send Reset Email' & 'Reset Password' authenticators got removed above,
- // the next action should be 'Reset OTP' -- verify that
- Assert.assertTrue(totpPage.isCurrent());
+ resetPasswordPage.assertCurrent();
+ resetPasswordPage.changePassword("login-test");
// Provide updated form of the OTP label, to be used within 'Reset OTP' (next) step
customOtpLabel = "my-reset-otp-label";
// Reset OTP label to a custom value as part of Reset Credentials flow
- totpPage.configure(totp.generateTOTP(totpPage.getTotpSecret()), customOtpLabel);
+ AccountHelper.updateTotpUserLabel(testRealm(), "login-test", customOtpLabel);
// Open OTP Authenticator account page
- accountTotpPage.open();
- Assert.assertTrue(accountTotpPage.isCurrent());
-
- // Verify OTP authenticator with requested label was created
- String pageSource = driver.getPageSource();
- Assert.assertTrue(pageSource.contains(customOtpLabel));
+ // Check if OTP credential is present
+ Assert.assertTrue(AccountHelper.totpUserLabelComparator(testRealm(), "login-test", customOtpLabel));
// Undo setup changes performed within the test
} finally {
@@ -406,7 +388,6 @@ public class ResetCredentialsAlternativeFlowsTest extends AbstractTestRealmKeycl
// KEYCLOAK-12168 Verify the 'Device Name' label is optional for the first OTP credential created
// (either via Account page or by registering new user), but required for each next created OTP credential
@Test
- @DisableFeature(value = Profile.Feature.ACCOUNT2, skipRestart = true) // TODO remove this (KEYCLOAK-16228)
public void deviceNameOptionalForFirstOTPCredentialButRequiredForEachNextOne() {
// Enable 'Default Action' on 'Configure OTP' RA for the 'test' realm
RequiredActionProviderRepresentation otpRequiredAction = testRealm().flows().getRequiredAction("CONFIGURE_TOTP");
@@ -428,29 +409,17 @@ public class ResetCredentialsAlternativeFlowsTest extends AbstractTestRealmKeycl
// Login & set up the initial OTP code for the user
loginPage.open();
loginPage.login("login@test.com", "password");
- accountTotpPage.open();
- Assert.assertTrue(accountTotpPage.isCurrent());
-
- String pageSource = driver.getPageSource();
- // Check the One-time code label is followed by asterisk character (since always required)
- final String oneTimeCodeLabelFollowedByAsterisk = "(?s)