KEYCLOAK-15841 Upgrade rest of the minor forms to PF4

This commit is contained in:
Martin Bartos 2020-07-23 19:23:36 +02:00 committed by Marek Posolda
parent db026e5566
commit 7522d5ac74
29 changed files with 390 additions and 182 deletions

View file

@ -84,6 +84,10 @@ public abstract class AbstractUsernameFormAuthenticator extends AbstractFormAuth
return Messages.INVALID_USER;
}
protected String tempDisabledFieldError(){
return FIELD_USERNAME;
}
protected Response setDuplicateUserChallenge(AuthenticationFlowContext context, String eventError, String loginFormError, AuthenticationFlowError authenticatorError) {
context.getEvent().error(eventError);
Response challengeResponse = context.form()
@ -240,7 +244,7 @@ public abstract class AbstractUsernameFormAuthenticator extends AbstractFormAuth
if (context.getProtector().isTemporarilyDisabled(context.getSession(), context.getRealm(), user)) {
context.getEvent().user(user);
context.getEvent().error(Errors.USER_TEMPORARILY_DISABLED);
Response challengeResponse = challenge(context, tempDisabledError(), FIELD_USERNAME);
Response challengeResponse = challenge(context, tempDisabledError(), tempDisabledFieldError());
context.forceChallenge(challengeResponse);
return true;
}

View file

@ -36,6 +36,7 @@ import org.keycloak.models.UserCredentialModel;
import org.keycloak.models.UserModel;
import org.keycloak.models.credential.OTPCredentialModel;
import org.keycloak.services.messages.Messages;
import org.keycloak.services.validation.Validation;
import org.keycloak.sessions.AuthenticationSessionModel;
import javax.ws.rs.core.MultivaluedMap;
@ -101,7 +102,7 @@ public class OTPFormAuthenticator extends AbstractUsernameFormAuthenticator impl
if (!valid) {
context.getEvent().user(userModel)
.error(Errors.INVALID_USER_CREDENTIALS);
Response challengeResponse = challenge(context, Messages.INVALID_TOTP);
Response challengeResponse = challenge(context, Messages.INVALID_TOTP, Validation.FIELD_OTP_CODE);
context.failureChallenge(AuthenticationFlowError.INVALID_CREDENTIALS, challengeResponse);
return;
}
@ -118,6 +119,11 @@ public class OTPFormAuthenticator extends AbstractUsernameFormAuthenticator impl
return Messages.INVALID_TOTP;
}
@Override
protected String tempDisabledFieldError() {
return Validation.FIELD_OTP_CODE;
}
@Override
protected Response createLoginForm(LoginFormsProvider form) {
return form.createLoginTotp();

View file

@ -30,6 +30,7 @@ import org.keycloak.models.UserCredentialModel;
import org.keycloak.models.UserModel;
import org.keycloak.models.credential.OTPCredentialModel;
import org.keycloak.services.messages.Messages;
import org.keycloak.services.validation.Validation;
import javax.ws.rs.core.Response;
@ -72,7 +73,7 @@ public class BasicAuthOTPAuthenticator extends BasicAuthAuthenticator implements
if (!valid) {
context.getEvent().user(context.getUser()).error(Errors.INVALID_USER_CREDENTIALS);
if (context.getExecution().isRequired()){
Response challengeResponse = challenge(context, Messages.INVALID_TOTP);
Response challengeResponse = challenge(context, Messages.INVALID_TOTP, Validation.FIELD_OTP_CODE);
context.failureChallenge(AuthenticationFlowError.INVALID_CREDENTIALS, challengeResponse);
} else {
context.attempted();

View file

@ -38,6 +38,7 @@ import org.keycloak.models.RealmModel;
import org.keycloak.models.UserCredentialModel;
import org.keycloak.models.UserModel;
import org.keycloak.models.UserSessionModel;
import org.keycloak.models.utils.FormMessage;
import org.keycloak.services.managers.AuthenticationManager;
import org.keycloak.services.messages.Messages;
import org.keycloak.services.validation.Validation;
@ -110,7 +111,7 @@ public class UpdatePassword implements RequiredActionProvider, RequiredActionFac
if (Validation.isBlank(passwordNew)) {
Response challenge = context.form()
.setAttribute("username", authSession.getAuthenticatedUser().getUsername())
.setError(Messages.MISSING_PASSWORD)
.addError(new FormMessage(Validation.FIELD_PASSWORD, Messages.MISSING_PASSWORD))
.createResponse(UserModel.RequiredAction.UPDATE_PASSWORD);
context.challenge(challenge);
errorEvent.error(Errors.PASSWORD_MISSING);
@ -118,7 +119,7 @@ public class UpdatePassword implements RequiredActionProvider, RequiredActionFac
} else if (!passwordNew.equals(passwordConfirm)) {
Response challenge = context.form()
.setAttribute("username", authSession.getAuthenticatedUser().getUsername())
.setError(Messages.NOTMATCH_PASSWORD)
.addError(new FormMessage(Validation.FIELD_PASSWORD_CONFIRM, Messages.NOTMATCH_PASSWORD))
.createResponse(UserModel.RequiredAction.UPDATE_PASSWORD);
context.challenge(challenge);
errorEvent.error(Errors.PASSWORD_CONFIRM_ERROR);

View file

@ -19,7 +19,12 @@ package org.keycloak.authentication.requiredactions;
import org.keycloak.Config;
import org.keycloak.OAuth2Constants;
import org.keycloak.authentication.*;
import org.keycloak.authentication.CredentialRegistrator;
import org.keycloak.authentication.DisplayTypeRequiredActionFactory;
import org.keycloak.authentication.InitiatedActionSupport;
import org.keycloak.authentication.RequiredActionContext;
import org.keycloak.authentication.RequiredActionFactory;
import org.keycloak.authentication.RequiredActionProvider;
import org.keycloak.credential.CredentialModel;
import org.keycloak.credential.CredentialProvider;
import org.keycloak.credential.OTPCredentialProvider;
@ -28,17 +33,16 @@ import org.keycloak.events.EventType;
import org.keycloak.models.KeycloakSession;
import org.keycloak.models.KeycloakSessionFactory;
import org.keycloak.models.OTPPolicy;
import org.keycloak.models.UserCredentialModel;
import org.keycloak.models.UserModel;
import org.keycloak.models.credential.OTPCredentialModel;
import org.keycloak.models.utils.CredentialValidation;
import org.keycloak.models.utils.FormMessage;
import org.keycloak.services.messages.Messages;
import org.keycloak.services.validation.Validation;
import org.keycloak.utils.CredentialHelper;
import javax.ws.rs.core.MultivaluedMap;
import javax.ws.rs.core.Response;
import java.util.Collections;
import java.util.List;
@ -79,14 +83,14 @@ public class UpdateTotp implements RequiredActionProvider, RequiredActionFactory
if (Validation.isBlank(challengeResponse)) {
Response challenge = context.form()
.setAttribute("mode", mode)
.setError(Messages.MISSING_TOTP)
.addError(new FormMessage(Validation.FIELD_OTP_CODE, Messages.MISSING_TOTP))
.createResponse(UserModel.RequiredAction.CONFIGURE_TOTP);
context.challenge(challenge);
return;
} else if (!validateOTPCredential(context, challengeResponse, credentialModel, policy)) {
Response challenge = context.form()
.setAttribute("mode", mode)
.setError(Messages.INVALID_TOTP)
.addError(new FormMessage(Validation.FIELD_OTP_CODE, Messages.INVALID_TOTP))
.createResponse(UserModel.RequiredAction.CONFIGURE_TOTP);
context.challenge(challenge);
return;
@ -98,7 +102,7 @@ public class UpdateTotp implements RequiredActionProvider, RequiredActionFactory
if (otpCredentials.size() >= 1 && Validation.isBlank(userLabel)) {
Response challenge = context.form()
.setAttribute("mode", mode)
.setError(Messages.MISSING_TOTP_DEVICE_NAME)
.addError(new FormMessage(Validation.FIELD_OTP_LABEL, Messages.MISSING_TOTP_DEVICE_NAME))
.createResponse(UserModel.RequiredAction.CONFIGURE_TOTP);
context.challenge(challenge);
return;
@ -107,7 +111,7 @@ public class UpdateTotp implements RequiredActionProvider, RequiredActionFactory
if (!CredentialHelper.createOTPCredential(context.getSession(), context.getRealm(), context.getUser(), challengeResponse, credentialModel)) {
Response challenge = context.form()
.setAttribute("mode", mode)
.setError(Messages.INVALID_TOTP)
.addError(new FormMessage(Validation.FIELD_OTP_CODE, Messages.INVALID_TOTP))
.createResponse(UserModel.RequiredAction.CONFIGURE_TOTP);
context.challenge(challenge);
return;

View file

@ -43,7 +43,9 @@ public class Validation {
public static final String FIELD_FIRST_NAME = "firstName";
public static final String FIELD_PASSWORD = "password";
public static final String FIELD_USERNAME = "username";
public static final String FIELD_OTP_CODE = "totp";
public static final String FIELD_OTP_LABEL = "userLabel";
// Actually allow same emails like angular. See ValidationTest.testEmailValidation()
private static final Pattern EMAIL_PATTERN = Pattern.compile("[a-zA-Z0-9!#$%&'*+/=?^_`{|}~.-]+@[a-zA-Z0-9-]+(\\.[a-zA-Z0-9-]+)*");

View file

@ -38,6 +38,9 @@ public class OneTimeCode extends Authenticate {
@FindBy(className = "alert-error")
private WebElement loginErrorMessage;
@FindBy(id = "input-error-otp-code")
private WebElement totpInputCodeError;
public String getOtpLabel() {
return getTextFromElement(otpInputLabel);
}
@ -55,8 +58,20 @@ public class OneTimeCode extends Authenticate {
submit();
}
public String getError() {
return loginErrorMessage != null ? loginErrorMessage.getText() : null;
public String getAlertError() {
try {
return UIUtils.getTextFromElement(loginErrorMessage);
} catch (NoSuchElementException e) {
return null;
}
}
public String getInputError() {
try {
return UIUtils.getTextFromElement(totpInputCodeError);
} catch (NoSuchElementException e) {
return null;
}
}
@Override

View file

@ -16,6 +16,7 @@
*/
package org.keycloak.testsuite.pages;
import org.keycloak.testsuite.util.UIUtils;
import org.openqa.selenium.By;
import org.openqa.selenium.NoSuchElementException;
import org.openqa.selenium.WebElement;
@ -48,7 +49,13 @@ public class LoginConfigTotpPage extends AbstractPage {
private WebElement manualLink;
@FindBy(className = "alert-error")
private WebElement loginErrorMessage;
private WebElement loginAlertErrorMessage;
@FindBy(id = "input-error-otp-code")
private WebElement totpInputCodeError;
@FindBy(id = "input-error-otp-label")
private WebElement totpInputLabelError;
public void configure(String totp) {
totpInput.sendKeys(totp);
@ -94,8 +101,28 @@ public class LoginConfigTotpPage extends AbstractPage {
barcodeLink.click();
}
public String getError() {
return loginErrorMessage.getText();
public String getInputCodeError() {
try {
return UIUtils.getTextFromElement(totpInputCodeError);
} catch (NoSuchElementException e) {
return null;
}
}
public String getInputLabelError() {
try {
return UIUtils.getTextFromElement(totpInputLabelError);
} catch (NoSuchElementException e) {
return null;
}
}
public String getAlertError() {
try {
return UIUtils.getTextFromElement(loginAlertErrorMessage);
} catch (NoSuchElementException e) {
return null;
}
}
public boolean isCancelDisplayed() {

View file

@ -45,6 +45,9 @@ public class LoginTotpPage extends LanguageComboboxAwarePage {
@FindBy(className = "alert-error")
private WebElement loginErrorMessage;
@FindBy(id = "input-error-otp-code")
private WebElement totpInputCodeError;
public void login(String totp) {
otpInput.clear();
if (totp != null) otpInput.sendKeys(totp);
@ -52,8 +55,20 @@ public class LoginTotpPage extends LanguageComboboxAwarePage {
submitButton.click();
}
public String getError() {
return loginErrorMessage != null ? loginErrorMessage.getText() : null;
public String getAlertError() {
try {
return UIUtils.getTextFromElement(loginErrorMessage);
} catch (NoSuchElementException e) {
return null;
}
}
public String getInputError(){
try {
return UIUtils.getTextFromElement(totpInputCodeError);
} catch (NoSuchElementException e) {
return null;
}
}
public boolean isCurrent() {

View file

@ -17,17 +17,23 @@
package org.keycloak.testsuite.pages;
import org.jboss.arquillian.graphene.page.Page;
import org.keycloak.testsuite.util.UIUtils;
import org.openqa.selenium.NoSuchElementException;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.support.FindBy;
import static org.keycloak.testsuite.util.UIUtils.clickLink;
import static org.keycloak.testsuite.util.UIUtils.getTextFromElement;
/**
* @author <a href="mailto:sthorger@redhat.com">Stian Thorgersen</a>
*/
public class LoginUpdateProfilePage extends AbstractPage {
@Page
private UpdateProfileErrors errorsPage;
@FindBy(id = "firstName")
private WebElement firstNameInput;
@ -44,7 +50,7 @@ public class LoginUpdateProfilePage extends AbstractPage {
private WebElement cancelAIAButton;
@FindBy(className = "alert-error")
private WebElement loginErrorMessage;
private WebElement loginAlertErrorMessage;
public void update(String firstName, String lastName, String email) {
if (firstName != null) {
@ -62,13 +68,17 @@ public class LoginUpdateProfilePage extends AbstractPage {
clickLink(submitButton);
}
public void cancel() {
cancelAIAButton.click();
}
public String getError() {
return loginErrorMessage != null ? loginErrorMessage.getText() : null;
public String getAlertError() {
try {
return UIUtils.getTextFromElement(loginAlertErrorMessage);
} catch (NoSuchElementException e) {
return null;
}
}
public String getFirstName() {
@ -87,6 +97,10 @@ public class LoginUpdateProfilePage extends AbstractPage {
return PageUtils.getPageTitle(driver).equals("Update Account Information");
}
public UpdateProfileErrors getInputErrors() {
return errorsPage;
}
@Override
public void open() {
throw new UnsupportedOperationException();
@ -100,4 +114,51 @@ public class LoginUpdateProfilePage extends AbstractPage {
}
}
// For managing input errors
public static class UpdateProfileErrors {
@FindBy(id = "input-error-firstname")
private WebElement inputErrorFirstName;
@FindBy(id = "input-error-lastname")
private WebElement inputErrorLastName;
@FindBy(id = "input-error-email")
private WebElement inputErrorEmail;
@FindBy(id = "input-error-username")
private WebElement inputErrorUsername;
public String getFirstNameError() {
try {
return getTextFromElement(inputErrorFirstName);
} catch (NoSuchElementException e) {
return null;
}
}
public String getLastNameError() {
try {
return getTextFromElement(inputErrorLastName);
} catch (NoSuchElementException e) {
return null;
}
}
public String getEmailError() {
try {
return getTextFromElement(inputErrorEmail);
} catch (NoSuchElementException e) {
return null;
}
}
public String getUsernameError() {
try {
return getTextFromElement(inputErrorUsername);
} catch (NoSuchElementException e) {
return null;
}
}
}
}

View file

@ -27,12 +27,10 @@ import org.keycloak.admin.client.resource.RealmResource;
import org.keycloak.events.Details;
import org.keycloak.events.EventType;
import org.keycloak.models.AuthenticationExecutionModel;
import org.keycloak.models.UserCredentialModel;
import org.keycloak.models.UserModel;
import org.keycloak.models.credential.OTPCredentialModel;
import org.keycloak.models.utils.HmacOTP;
import org.keycloak.models.utils.TimeBasedOTP;
import org.keycloak.representations.idm.AuthenticationExecutionInfoRepresentation;
import org.keycloak.representations.idm.EventRepresentation;
import org.keycloak.representations.idm.RealmRepresentation;
import org.keycloak.representations.idm.UserRepresentation;
@ -269,7 +267,7 @@ public class AppInitiatedActionTotpSetupTest extends AbstractAppInitiatedActionT
assertFalse(pageSource.contains("Unable to scan?"));
assertTrue(pageSource.contains("Scan barcode?"));
assertEquals("Please specify authenticator code.", totpPage.getError());
assertEquals("Please specify authenticator code.", totpPage.getInputCodeError());
}
// KEYCLOAK-7081
@ -293,7 +291,7 @@ public class AppInitiatedActionTotpSetupTest extends AbstractAppInitiatedActionT
assertTrue(pageSource.contains("Unable to scan?"));
assertFalse(pageSource.contains("Scan barcode?"));
assertEquals("Please specify authenticator code.", totpPage.getError());
assertEquals("Please specify authenticator code.", totpPage.getInputCodeError());
totpPage.clickManual();

View file

@ -195,7 +195,7 @@ public class AppInitiatedActionUpdateProfileTest extends AbstractAppInitiatedAct
Assert.assertEquals("New last", updateProfilePage.getLastName());
Assert.assertEquals("new@email.com", updateProfilePage.getEmail());
Assert.assertEquals("Please specify first name.", updateProfilePage.getError());
Assert.assertEquals("Please specify first name.", updateProfilePage.getInputErrors().getFirstNameError());
events.assertEmpty();
}
@ -217,7 +217,7 @@ public class AppInitiatedActionUpdateProfileTest extends AbstractAppInitiatedAct
Assert.assertEquals("", updateProfilePage.getLastName());
Assert.assertEquals("new@email.com", updateProfilePage.getEmail());
Assert.assertEquals("Please specify last name.", updateProfilePage.getError());
Assert.assertEquals("Please specify last name.", updateProfilePage.getInputErrors().getLastNameError());
events.assertEmpty();
}
@ -239,7 +239,7 @@ public class AppInitiatedActionUpdateProfileTest extends AbstractAppInitiatedAct
Assert.assertEquals("New last", updateProfilePage.getLastName());
Assert.assertEquals("", updateProfilePage.getEmail());
Assert.assertEquals("Please specify email.", updateProfilePage.getError());
Assert.assertEquals("Please specify email.", updateProfilePage.getInputErrors().getEmailError());
events.assertEmpty();
}
@ -261,7 +261,7 @@ public class AppInitiatedActionUpdateProfileTest extends AbstractAppInitiatedAct
Assert.assertEquals("New last", updateProfilePage.getLastName());
Assert.assertEquals("invalidemail", updateProfilePage.getEmail());
Assert.assertEquals("Invalid email address.", updateProfilePage.getError());
Assert.assertEquals("Invalid email address.", updateProfilePage.getInputErrors().getEmailError());
events.assertEmpty();
}
@ -284,7 +284,7 @@ public class AppInitiatedActionUpdateProfileTest extends AbstractAppInitiatedAct
Assert.assertEquals("new@email.com", updateProfilePage.getEmail());
Assert.assertEquals("", updateProfilePage.getUsername());
Assert.assertEquals("Please specify username.", updateProfilePage.getError());
Assert.assertEquals("Please specify username.", updateProfilePage.getInputErrors().getUsernameError());
events.assertEmpty();
}
@ -307,7 +307,7 @@ public class AppInitiatedActionUpdateProfileTest extends AbstractAppInitiatedAct
Assert.assertEquals("new@email.com", updateProfilePage.getEmail());
Assert.assertEquals("test-user@localhost", updateProfilePage.getUsername());
Assert.assertEquals("Username already exists.", updateProfilePage.getError());
Assert.assertEquals("Username already exists.", updateProfilePage.getInputErrors().getUsernameError());
events.assertEmpty();
}
@ -329,7 +329,7 @@ public class AppInitiatedActionUpdateProfileTest extends AbstractAppInitiatedAct
Assert.assertEquals("New last", updateProfilePage.getLastName());
Assert.assertEquals("keycloak-user@localhost", updateProfilePage.getEmail());
Assert.assertEquals("Email already exists.", updateProfilePage.getError());
Assert.assertEquals("Email already exists.", updateProfilePage.getInputErrors().getEmailError());
events.assertEmpty();
}

View file

@ -17,7 +17,6 @@
package org.keycloak.testsuite.actions;
import org.jboss.arquillian.graphene.page.Page;
import org.jboss.arquillian.junit.InSequence;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Rule;
@ -27,13 +26,10 @@ import org.keycloak.admin.client.resource.UserResource;
import org.keycloak.events.Details;
import org.keycloak.events.EventType;
import org.keycloak.models.AuthenticationExecutionModel;
import org.keycloak.models.UserCredentialModel;
import org.keycloak.models.UserModel;
import org.keycloak.models.credential.OTPCredentialModel;
import org.keycloak.models.utils.HmacOTP;
import org.keycloak.models.utils.TimeBasedOTP;
import org.keycloak.representations.idm.AuthenticationExecutionInfoRepresentation;
import org.keycloak.representations.idm.AuthenticationFlowRepresentation;
import org.keycloak.representations.idm.EventRepresentation;
import org.keycloak.representations.idm.RealmRepresentation;
import org.keycloak.representations.idm.RequiredActionProviderRepresentation;
@ -52,16 +48,12 @@ import org.keycloak.testsuite.pages.RegisterPage;
import org.keycloak.testsuite.util.RealmBuilder;
import org.keycloak.testsuite.util.UserBuilder;
import org.openqa.selenium.By;
import org.openqa.selenium.WebElement;
import java.util.Collections;
import java.util.LinkedList;
import java.util.List;
import static org.hamcrest.Matchers.is;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertThat;
import static org.junit.Assert.assertTrue;
/**
@ -237,7 +229,7 @@ public class RequiredActionTotpSetupTest extends AbstractTestRealmKeycloakTest {
assertFalse(pageSource.contains("Unable to scan?"));
assertTrue(pageSource.contains("Scan barcode?"));
assertEquals("Please specify authenticator code.", totpPage.getError());
assertEquals("Please specify authenticator code.", totpPage.getInputCodeError());
}
// KEYCLOAK-7081
@ -259,7 +251,7 @@ public class RequiredActionTotpSetupTest extends AbstractTestRealmKeycloakTest {
assertTrue(pageSource.contains("Unable to scan?"));
assertFalse(pageSource.contains("Scan barcode?"));
assertEquals("Please specify authenticator code.", totpPage.getError());
assertEquals("Please specify authenticator code.", totpPage.getInputCodeError());
totpPage.clickManual();

View file

@ -163,7 +163,7 @@ public class RequiredActionUpdateProfileTest extends AbstractTestRealmKeycloakTe
Assert.assertEquals("New last", updateProfilePage.getLastName());
Assert.assertEquals("new@email.com", updateProfilePage.getEmail());
Assert.assertEquals("Please specify first name.", updateProfilePage.getError());
Assert.assertEquals("Please specify first name.", updateProfilePage.getInputErrors().getFirstNameError());
events.assertEmpty();
}
@ -185,7 +185,7 @@ public class RequiredActionUpdateProfileTest extends AbstractTestRealmKeycloakTe
Assert.assertEquals("", updateProfilePage.getLastName());
Assert.assertEquals("new@email.com", updateProfilePage.getEmail());
Assert.assertEquals("Please specify last name.", updateProfilePage.getError());
Assert.assertEquals("Please specify last name.", updateProfilePage.getInputErrors().getLastNameError());
events.assertEmpty();
}
@ -207,7 +207,7 @@ public class RequiredActionUpdateProfileTest extends AbstractTestRealmKeycloakTe
Assert.assertEquals("New last", updateProfilePage.getLastName());
Assert.assertEquals("", updateProfilePage.getEmail());
Assert.assertEquals("Please specify email.", updateProfilePage.getError());
Assert.assertEquals("Please specify email.", updateProfilePage.getInputErrors().getEmailError());
events.assertEmpty();
}
@ -229,7 +229,7 @@ public class RequiredActionUpdateProfileTest extends AbstractTestRealmKeycloakTe
Assert.assertEquals("New last", updateProfilePage.getLastName());
Assert.assertEquals("invalidemail", updateProfilePage.getEmail());
Assert.assertEquals("Invalid email address.", updateProfilePage.getError());
Assert.assertEquals("Invalid email address.", updateProfilePage.getInputErrors().getEmailError());
events.assertEmpty();
}
@ -252,7 +252,7 @@ public class RequiredActionUpdateProfileTest extends AbstractTestRealmKeycloakTe
Assert.assertEquals("new@email.com", updateProfilePage.getEmail());
Assert.assertEquals("", updateProfilePage.getUsername());
Assert.assertEquals("Please specify username.", updateProfilePage.getError());
Assert.assertEquals("Please specify username.", updateProfilePage.getInputErrors().getUsernameError());
events.assertEmpty();
}
@ -275,7 +275,7 @@ public class RequiredActionUpdateProfileTest extends AbstractTestRealmKeycloakTe
Assert.assertEquals("new@email.com", updateProfilePage.getEmail());
Assert.assertEquals("test-user@localhost", updateProfilePage.getUsername());
Assert.assertEquals("Username already exists.", updateProfilePage.getError());
Assert.assertEquals("Username already exists.", updateProfilePage.getInputErrors().getUsernameError());
events.assertEmpty();
}
@ -297,7 +297,7 @@ public class RequiredActionUpdateProfileTest extends AbstractTestRealmKeycloakTe
Assert.assertEquals("New last", updateProfilePage.getLastName());
Assert.assertEquals("keycloak-user@localhost", updateProfilePage.getEmail());
Assert.assertEquals("Email already exists.", updateProfilePage.getError());
Assert.assertEquals("Email already exists.", updateProfilePage.getInputErrors().getEmailError());
events.assertEmpty();
}

View file

@ -516,14 +516,14 @@ public abstract class AbstractAdvancedBrokerTest extends AbstractBrokerTest {
// Login for 2 times with incorrect TOTP. This should temporarily disable the user
loginTotpPage.login("bad-totp");
Assert.assertEquals("Invalid authenticator code.", loginTotpPage.getError());
Assert.assertEquals("Invalid authenticator code.", loginTotpPage.getInputError());
loginTotpPage.login("bad-totp");
Assert.assertEquals("Invalid authenticator code.", loginTotpPage.getError());
Assert.assertEquals("Invalid authenticator code.", loginTotpPage.getInputError());
// Login with valid TOTP. I should not be able to login
loginTotpPage.login(totp.generateTOTP(totpSecret));
Assert.assertEquals("Invalid authenticator code.", loginTotpPage.getError());
Assert.assertEquals("Invalid authenticator code.", loginTotpPage.getInputError());
// Clear login failures
String userId = ApiUtil.findUserByUsername(realm, bc.getUserLogin()).getId();

View file

@ -1,10 +1,12 @@
package org.keycloak.testsuite.broker;
import org.jboss.arquillian.graphene.page.Page;
import org.junit.Test;
import org.keycloak.admin.client.resource.RealmResource;
import org.keycloak.representations.idm.ClientRepresentation;
import org.keycloak.representations.idm.IdentityProviderRepresentation;
import org.keycloak.testsuite.Assert;
import org.keycloak.testsuite.pages.LoginUpdateProfilePage;
import org.openqa.selenium.NoSuchElementException;
import static org.junit.Assert.assertEquals;
@ -18,6 +20,9 @@ import static org.keycloak.testsuite.broker.BrokerTestTools.getConsumerRoot;
*/
public class KcOidcFirstBrokerLoginTest extends AbstractFirstBrokerLoginTest {
@Page
protected LoginUpdateProfilePage loginUpdateProfilePage;
@Override
protected BrokerConfiguration getBrokerConfiguration() {
return KcOidcBrokerConfiguration.INSTANCE;
@ -260,6 +265,7 @@ public class KcOidcFirstBrokerLoginTest extends AbstractFirstBrokerLoginTest {
updateAccountInformationPage.assertCurrent();
updateAccountInformationPage.updateAccountInformation("", "no-first-name@localhost.com", "FirstName", "LastName");
updateAccountInformationPage.assertCurrent();
assertEquals("Please specify username.", accountUpdateProfilePage.getError());
assertEquals("Please specify username.", loginUpdateProfilePage.getInputErrors().getUsernameError());
}
}

View file

@ -175,7 +175,7 @@ public class BackwardsCompatibilityUserStorageTest extends AbstractAuthTest {
loginTotpPage.assertCurrent();
loginTotpPage.login("7123456");
assertCurrentUrlDoesntStartWith(testRealmAccountPage);
Assert.assertNotNull(loginTotpPage.getError());
Assert.assertNotNull(loginTotpPage.getInputError());
// Authenticate as the user with correct OTP
loginTotpPage.login(totp.generateTOTP(totpSecret));

View file

@ -124,7 +124,7 @@ public class UserStorageOTPTest extends AbstractTestRealmKeycloakTest {
loginTotpPage.login("654321");
loginTotpPage.assertCurrent();
Assert.assertEquals("Invalid authenticator code.", loginPage.getError());
Assert.assertEquals("Invalid authenticator code.", loginTotpPage.getInputError());
loginTotpPage.login(DummyUserFederationProvider.HARDCODED_OTP);
@ -153,7 +153,7 @@ public class UserStorageOTPTest extends AbstractTestRealmKeycloakTest {
// Dummy OTP code won't work when configure new OTP
loginConfigTotpPage.configure(DummyUserFederationProvider.HARDCODED_OTP);
Assert.assertEquals("Invalid authenticator code.", loginConfigTotpPage.getError());
Assert.assertEquals("Invalid authenticator code.", loginConfigTotpPage.getInputCodeError());
// This will save the credential to the local DB
String totpSecret = loginConfigTotpPage.getTotpSecret();

View file

@ -153,7 +153,7 @@ public class BrowserFlowTest extends AbstractTestRealmKeycloakTest {
// Use 7 digits instead 6 to have 100% probability of failure
oneTimeCodePage.sendCode("1234567");
Assert.assertEquals(INVALID_AUTH_CODE, oneTimeCodePage.getError());
Assert.assertEquals(INVALID_AUTH_CODE, oneTimeCodePage.getInputError());
Assert.assertTrue(oneTimeCodePage.isOtpLabelPresent());
}
@ -183,12 +183,12 @@ public class BrowserFlowTest extends AbstractTestRealmKeycloakTest {
// Select "second" factor (which is unnamed as it doesn't have userLabel) but try to connect with the OTP code from the "first" one
loginTotpPage.selectOtpCredential(OTPFormAuthenticator.UNNAMED);
loginTotpPage.login(getOtpCode(USER_WITH_TWO_OTPS_OTP1_SECRET));
Assert.assertEquals(INVALID_AUTH_CODE, oneTimeCodePage.getError());
Assert.assertEquals(INVALID_AUTH_CODE, oneTimeCodePage.getInputError());
// Select "first" factor but try to connect with the OTP code from the "second" one
loginTotpPage.selectOtpCredential("first");
loginTotpPage.login(getOtpCode(USER_WITH_TWO_OTPS_OTP2_SECRET));
Assert.assertEquals(INVALID_AUTH_CODE, oneTimeCodePage.getError());
Assert.assertEquals(INVALID_AUTH_CODE, oneTimeCodePage.getInputError());
// Select "second" factor and try to connect with its OTP code
loginTotpPage.selectOtpCredential(OTPFormAuthenticator.UNNAMED);

View file

@ -606,7 +606,7 @@ public class BruteForceTest extends AbstractTestRealmKeycloakTest {
loginTotpPage.login("123456");
loginTotpPage.assertCurrent();
Assert.assertEquals("Invalid authenticator code.", loginPage.getError());
Assert.assertEquals("Invalid authenticator code.", loginTotpPage.getInputError());
events.clear();
}
@ -630,7 +630,7 @@ public class BruteForceTest extends AbstractTestRealmKeycloakTest {
loginTotpPage.login(totpSecret);
loginTotpPage.assertCurrent();
Assert.assertEquals("Invalid authenticator code.", loginTotpPage.getError());
Assert.assertEquals("Invalid authenticator code.", loginTotpPage.getInputError());
events.clear();
}
@ -641,7 +641,7 @@ public class BruteForceTest extends AbstractTestRealmKeycloakTest {
loginTotpPage.login("123456");
loginTotpPage.assertCurrent();
Assert.assertEquals("Invalid authenticator code.", loginTotpPage.getError());
Assert.assertEquals("Invalid authenticator code.", loginTotpPage.getInputError());
events.clear();
}
@ -651,7 +651,7 @@ public class BruteForceTest extends AbstractTestRealmKeycloakTest {
loginTotpPage.login(null);
loginTotpPage.assertCurrent();
Assert.assertEquals("Invalid authenticator code.", loginTotpPage.getError());
Assert.assertEquals("Invalid authenticator code.", loginTotpPage.getInputError());
events.clear();
}
@ -663,7 +663,7 @@ public class BruteForceTest extends AbstractTestRealmKeycloakTest {
loginTotpPage.login(null);
loginTotpPage.assertCurrent();
Assert.assertEquals("Invalid authenticator code.", loginPage.getError());
Assert.assertEquals("Invalid authenticator code.", loginTotpPage.getInputError());
events.clear();
}

View file

@ -105,7 +105,7 @@ public class LoginHotpTest extends AbstractTestRealmKeycloakTest {
loginTotpPage.login("123456");
loginTotpPage.assertCurrent();
Assert.assertEquals("Invalid authenticator code.", loginPage.getError());
Assert.assertEquals("Invalid authenticator code.", loginTotpPage.getInputError());
//loginPage.assertCurrent(); // Invalid authenticator code.
//Assert.assertEquals("Invalid username or password.", loginPage.getError());
@ -124,7 +124,7 @@ public class LoginHotpTest extends AbstractTestRealmKeycloakTest {
loginTotpPage.login(null);
loginTotpPage.assertCurrent();
Assert.assertEquals("Invalid authenticator code.", loginPage.getError());
Assert.assertEquals("Invalid authenticator code.", loginTotpPage.getInputError());
//loginPage.assertCurrent(); // Invalid authenticator code.
//Assert.assertEquals("Invalid username or password.", loginPage.getError());

View file

@ -96,7 +96,7 @@ public class LoginTotpTest extends AbstractTestRealmKeycloakTest {
loginTotpPage.login("123456");
loginTotpPage.assertCurrent();
Assert.assertEquals("Invalid authenticator code.", loginPage.getError());
Assert.assertEquals("Invalid authenticator code.", loginTotpPage.getInputError());
//loginPage.assertCurrent(); // Invalid authenticator code.
//Assert.assertEquals("Invalid username or password.", loginPage.getError());
@ -115,7 +115,7 @@ public class LoginTotpTest extends AbstractTestRealmKeycloakTest {
loginTotpPage.login(null);
loginTotpPage.assertCurrent();
Assert.assertEquals("Invalid authenticator code.", loginPage.getError());
Assert.assertEquals("Invalid authenticator code.", loginTotpPage.getInputError());
//loginPage.assertCurrent(); // Invalid authenticator code.
//Assert.assertEquals("Invalid username or password.", loginPage.getError());

View file

@ -464,11 +464,10 @@ public class ResetCredentialsAlternativeFlowsTest extends AbstractTestRealmKeycl
// Create OTP credential with empty label
totpPage.configure(totp.generateTOTP(accountTotpPage.getTotpSecret()), emptyOtpLabel);
try {
Assert.assertTrue(totpPage.getError().isEmpty());
} catch (org.openqa.selenium.NoSuchElementException nsee) {
// OK to ignore if 'alert-error' element wasn't found
}
Assert.assertNull(totpPage.getAlertError());
Assert.assertNull(totpPage.getInputCodeError());
Assert.assertNull(totpPage.getInputLabelError());
// Assert user authenticated
appPage.assertCurrent();
@ -508,16 +507,15 @@ public class ResetCredentialsAlternativeFlowsTest extends AbstractTestRealmKeycl
// should fail with error since OTP label is required in this case already
final String deviceNameLabelRequiredErrorMessage = "Please specify device name.";
totpPage.configure(totp.generateTOTP(accountTotpPage.getTotpSecret()), emptyOtpLabel);
Assert.assertTrue(totpPage.getError().equals(deviceNameLabelRequiredErrorMessage));
Assert.assertTrue(totpPage.getInputLabelError().equals(deviceNameLabelRequiredErrorMessage));
// Create 2nd OTP credential with valid (non-empty) Device Name label. This should pass
final String secondOtpLabel = "My 2nd OTP device";
totpPage.configure(totp.generateTOTP(accountTotpPage.getTotpSecret()), secondOtpLabel);
try {
Assert.assertTrue(totpPage.getError().isEmpty());
} catch (org.openqa.selenium.NoSuchElementException nsee) {
// OK to ignore if 'alert-error' element wasn't found
}
Assert.assertNull(totpPage.getAlertError());
Assert.assertNull(totpPage.getInputCodeError());
Assert.assertNull(totpPage.getInputLabelError());
// Assert user authenticated
appPage.assertCurrent();

View file

@ -1,6 +1,5 @@
package org.keycloak.testsuite.sssd;
import java.io.IOException;
import java.io.InputStream;
import java.util.Arrays;
import java.util.List;
@ -16,7 +15,6 @@ import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Rule;
import org.junit.Test;
import org.keycloak.common.constants.GenericConstants;
import org.keycloak.common.util.MultivaluedHashMap;
import org.keycloak.representations.idm.ComponentRepresentation;
import org.keycloak.representations.idm.GroupRepresentation;
@ -30,7 +28,6 @@ import org.keycloak.testsuite.admin.ApiUtil;
import org.keycloak.testsuite.pages.AccountPasswordPage;
import org.keycloak.testsuite.pages.AccountUpdateProfilePage;
import org.keycloak.testsuite.pages.LoginPage;
import org.keycloak.testsuite.util.LDAPTestConfiguration;
public class SSSDTest extends AbstractKeycloakTest {

View file

@ -1,30 +1,29 @@
<#import "template.ftl" as layout>
<@layout.registrationLayout displayRequiredFields=false; section>
<@layout.registrationLayout displayRequiredFields=false displayMessage=!messagesPerField.existsError('totp','userLabel'); section>
<#if section = "header">
${msg("loginTotpTitle")}
<#elseif section = "form">
<ol id="kc-totp-settings">
<li>
<p>${msg("loginTotpStep1")}</p>
<ul id="kc-totp-supported-apps">
<#list totp.policy.supportedApplications as app>
<li>${app}</li>
</#list>
</ul>
</li>
<#if mode?? && mode = "manual">
<ol id="kc-totp-settings">
<li>
<p>${msg("loginTotpManualStep2")}</p>
<p><span id="kc-totp-secret-key">${totp.totpSecretEncoded}</span></p>
<p><a href="${totp.qrUrl}" id="mode-barcode">${msg("loginTotpScanBarcode")}</a></p>
<p>${msg("loginTotpStep1")}</p>
<ul id="kc-totp-supported-apps">
<#list totp.policy.supportedApplications as app>
<li>${app}</li>
</#list>
</ul>
</li>
<li>
<p>${msg("loginTotpManualStep3")}</p>
<p>
<#if mode?? && mode = "manual">
<li>
<p>${msg("loginTotpManualStep2")}</p>
<p><span id="kc-totp-secret-key">${totp.totpSecretEncoded}</span></p>
<p><a href="${totp.qrUrl}" id="mode-barcode">${msg("loginTotpScanBarcode")}</a></p>
</li>
<li>
<p>${msg("loginTotpManualStep3")}</p>
<p>
<ul>
<li id="kc-totp-type">${msg("loginTotpType")}: ${msg("loginTotp." + totp.policy.type)}</li>
<li id="kc-totp-algorithm">${msg("loginTotpAlgorithm")}: ${totp.policy.getAlgorithmKey()}</li>
@ -35,58 +34,75 @@
<li id="kc-totp-counter">${msg("loginTotpCounter")}: ${totp.policy.initialCounter}</li>
</#if>
</ul>
</p>
</li>
<#else>
</p>
</li>
<#else>
<li>
<p>${msg("loginTotpStep2")}</p>
<img id="kc-totp-secret-qr-code" src="data:image/png;base64, ${totp.totpSecretQrCode}" alt="Figure: Barcode"><br/>
<p><a href="${totp.manualUrl}" id="mode-manual">${msg("loginTotpUnableToScan")}</a></p>
</li>
</#if>
<li>
<p>${msg("loginTotpStep2")}</p>
<img id="kc-totp-secret-qr-code" src="data:image/png;base64, ${totp.totpSecretQrCode}" alt="Figure: Barcode"><br/>
<p><a href="${totp.manualUrl}" id="mode-manual">${msg("loginTotpUnableToScan")}</a></p>
<p>${msg("loginTotpStep3")}</p>
<p>${msg("loginTotpStep3DeviceName")}</p>
</li>
</#if>
<li>
<p>${msg("loginTotpStep3")}</p>
<p>${msg("loginTotpStep3DeviceName")}</p>
</li>
</ol>
</ol>
<form action="${url.loginAction}" class="${properties.kcFormClass!}" id="kc-totp-settings-form" method="post">
<div class="${properties.kcFormGroupClass!}">
<div class="${properties.kcInputWrapperClass!}">
<label for="totp" class="control-label">${msg("authenticatorCode")}</label> <span class="required">*</span>
</div>
<div class="${properties.kcInputWrapperClass!}">
<input type="text" id="totp" name="totp" autocomplete="off" class="${properties.kcInputClass!}" />
</div>
<input type="hidden" id="totpSecret" name="totpSecret" value="${totp.totpSecret}" />
<#if mode??><input type="hidden" id="mode" name="mode" value="${mode}"/></#if>
</div>
<form action="${url.loginAction}" class="${properties.kcFormClass!}" id="kc-totp-settings-form" method="post">
<div class="${properties.kcFormGroupClass!}">
<div class="${properties.kcInputWrapperClass!}">
<label for="totp" class="control-label">${msg("authenticatorCode")}</label> <span class="required">*</span>
</div>
<div class="${properties.kcInputWrapperClass!}">
<input type="text" id="totp" name="totp" autocomplete="off" class="${properties.kcInputClass!}"
aria-invalid="<#if messagesPerField.existsError('totp')>true</#if>"
/>
<div class="${properties.kcFormGroupClass!}" ${messagesPerField.printIfExists('userLabel',properties.kcFormGroupErrorClass!)}">
<div class="${properties.kcInputWrapperClass!}">
<label for="userLabel" class="control-label">${msg("loginTotpDeviceName")}</label> <#if totp.otpCredentials?size gte 1><span class="required">*</span></#if>
<#if messagesPerField.existsError('totp')>
<span id="input-error-otp-code" class="${properties.kcInputErrorMessageClass!}" aria-live="polite">
${kcSanitize(messagesPerField.get('totp'))?no_esc}
</span>
</#if>
</div>
<input type="hidden" id="totpSecret" name="totpSecret" value="${totp.totpSecret}" />
<#if mode??><input type="hidden" id="mode" name="mode" value="${mode}"/></#if>
</div>
<div class="${properties.kcInputWrapperClass!}">
<input type="text" class="${properties.kcInputClass!}" id="userLabel" name="userLabel" autocomplete="off">
</div>
</div>
<div class="${properties.kcFormGroupClass!}">
<div class="${properties.kcInputWrapperClass!}">
<label for="userLabel" class="control-label">${msg("loginTotpDeviceName")}</label> <#if totp.otpCredentials?size gte 1><span class="required">*</span></#if>
</div>
<#if isAppInitiatedAction??>
<input type="submit"
class="${properties.kcButtonClass!} ${properties.kcButtonPrimaryClass!} ${properties.kcButtonLargeClass!}"
id="saveTOTPBtn" value="${msg("doSubmit")}"
/>
<button type="submit"
class="${properties.kcButtonClass!} ${properties.kcButtonDefaultClass!} ${properties.kcButtonLargeClass!} ${properties.kcButtonLargeClass!}"
id="cancelTOTPBtn" name="cancel-aia" value="true" />${msg("doCancel")}
</button>
<#else>
<input type="submit"
class="${properties.kcButtonClass!} ${properties.kcButtonPrimaryClass!} ${properties.kcButtonBlockClass!} ${properties.kcButtonLargeClass!}"
id="saveTOTPBtn" value="${msg("doSubmit")}"
/>
</#if>
</form>
<div class="${properties.kcInputWrapperClass!}">
<input type="text" class="${properties.kcInputClass!}" id="userLabel" name="userLabel" autocomplete="off"
aria-invalid="<#if messagesPerField.existsError('userLabel')>true</#if>"
/>
<#if messagesPerField.existsError('userLabel')>
<span id="input-error-otp-label" class="${properties.kcInputErrorMessageClass!}" aria-live="polite">
${kcSanitize(messagesPerField.get('userLabel'))?no_esc}
</span>
</#if>
</div>
</div>
<#if isAppInitiatedAction??>
<input type="submit"
class="${properties.kcButtonClass!} ${properties.kcButtonPrimaryClass!} ${properties.kcButtonLargeClass!}"
id="saveTOTPBtn" value="${msg("doSubmit")}"
/>
<button type="submit"
class="${properties.kcButtonClass!} ${properties.kcButtonDefaultClass!} ${properties.kcButtonLargeClass!} ${properties.kcButtonLargeClass!}"
id="cancelTOTPBtn" name="cancel-aia" value="true" />${msg("doCancel")}
</button>
<#else>
<input type="submit"
class="${properties.kcButtonClass!} ${properties.kcButtonPrimaryClass!} ${properties.kcButtonBlockClass!} ${properties.kcButtonLargeClass!}"
id="saveTOTPBtn" value="${msg("doSubmit")}"
/>
</#if>
</form>
</#if>
</@layout.registrationLayout>
</@layout.registrationLayout>

View file

@ -1,5 +1,5 @@
<#import "template.ftl" as layout>
<@layout.registrationLayout; section>
<@layout.registrationLayout displayMessage=!messagesPerField.existsError('totp'); section>
<#if section="header">
${msg("doLogIn")}
<#elseif section="form">
@ -28,11 +28,18 @@
<label for="otp" class="${properties.kcLabelClass!}">${msg("loginOtpOneTime")}</label>
</div>
<div class="${properties.kcInputWrapperClass!}">
<input id="otp" name="otp" autocomplete="off" type="text" class="${properties.kcInputClass!}"
autofocus/>
</div>
<div class="${properties.kcInputWrapperClass!}">
<input id="otp" name="otp" autocomplete="off" type="text" class="${properties.kcInputClass!}"
autofocus aria-invalid="<#if messagesPerField.existsError('totp')>true</#if>"/>
<#if messagesPerField.existsError('totp')>
<span id="input-error-otp-code" class="${properties.kcInputErrorMessageClass!}"
aria-live="polite">
${kcSanitize(messagesPerField.get('totp'))?no_esc}
</span>
</#if>
</div>
</div>
<div class="${properties.kcFormGroupClass!}">
<div id="kc-form-options" class="${properties.kcFormOptionsClass!}">

View file

@ -1,10 +1,11 @@
<#import "template.ftl" as layout>
<@layout.registrationLayout ; section>
<@layout.registrationLayout displayMessage=!messagesPerField.existsError('password','password-confirm'); section>
<#if section = "header">
${msg("updatePasswordTitle")}
<#elseif section = "form">
<form id="kc-passwd-update-form" class="${properties.kcFormClass!}" action="${url.loginAction}" method="post">
<input type="text" id="username" name="username" value="${username}" autocomplete="username" readonly="readonly" style="display:none;"/>
<input type="text" id="username" name="username" value="${username}" autocomplete="username"
readonly="readonly" style="display:none;"/>
<input type="password" id="password" name="password" autocomplete="current-password" style="display:none;"/>
<div class="${properties.kcFormGroupClass!}">
@ -12,7 +13,16 @@
<label for="password-new" class="${properties.kcLabelClass!}">${msg("passwordNew")}</label>
</div>
<div class="${properties.kcInputWrapperClass!}">
<input type="password" id="password-new" name="password-new" class="${properties.kcInputClass!}" autofocus autocomplete="new-password" />
<input type="password" id="password-new" name="password-new" class="${properties.kcInputClass!}"
autofocus autocomplete="new-password"
aria-invalid="<#if messagesPerField.existsError('password','password-confirm')>true</#if>"
/>
<#if messagesPerField.existsError('password')>
<span id="input-error-password" class="${properties.kcInputErrorMessageClass!}" aria-live="polite">
${kcSanitize(messagesPerField.get('password'))?no_esc}
</span>
</#if>
</div>
</div>
@ -21,7 +31,18 @@
<label for="password-confirm" class="${properties.kcLabelClass!}">${msg("passwordConfirm")}</label>
</div>
<div class="${properties.kcInputWrapperClass!}">
<input type="password" id="password-confirm" name="password-confirm" class="${properties.kcInputClass!}" autocomplete="new-password" />
<input type="password" id="password-confirm" name="password-confirm"
class="${properties.kcInputClass!}"
autocomplete="new-password"
aria-invalid="<#if messagesPerField.existsError('password-confirm')>true</#if>"
/>
<#if messagesPerField.existsError('password-confirm')>
<span id="input-error-password-confirm" class="${properties.kcInputErrorMessageClass!}" aria-live="polite">
${kcSanitize(messagesPerField.get('password-confirm'))?no_esc}
</span>
</#if>
</div>
</div>
@ -29,22 +50,22 @@
<div id="kc-form-options" class="${properties.kcFormOptionsClass!}">
<div class="${properties.kcFormOptionsWrapperClass!}">
<#if isAppInitiatedAction??>
<div class="checkbox">
<label><input type="checkbox" id="logout-sessions" name="logout-sessions" value="on" checked> ${msg("logoutOtherSessions")}</label>
</div>
<div class="checkbox">
<label><input type="checkbox" id="logout-sessions" name="logout-sessions" value="on" checked> ${msg("logoutOtherSessions")}</label>
</div>
</#if>
</div>
</div>
<div id="kc-form-buttons" class="${properties.kcFormButtonsClass!}">
<#if isAppInitiatedAction??>
<input class="${properties.kcButtonClass!} ${properties.kcButtonPrimaryClass!} ${properties.kcButtonLargeClass!}" type="submit" value="${msg("doSubmit")}" />
<button class="${properties.kcButtonClass!} ${properties.kcButtonDefaultClass!} ${properties.kcButtonLargeClass!}" type="submit" name="cancel-aia" value="true" />${msg("doCancel")}</button>
<input class="${properties.kcButtonClass!} ${properties.kcButtonPrimaryClass!} ${properties.kcButtonLargeClass!}" type="submit" value="${msg("doSubmit")}" />
<button class="${properties.kcButtonClass!} ${properties.kcButtonDefaultClass!} ${properties.kcButtonLargeClass!}" type="submit" name="cancel-aia" value="true" />${msg("doCancel")}</button>
<#else>
<input class="${properties.kcButtonClass!} ${properties.kcButtonPrimaryClass!} ${properties.kcButtonBlockClass!} ${properties.kcButtonLargeClass!}" type="submit" value="${msg("doSubmit")}" />
<input class="${properties.kcButtonClass!} ${properties.kcButtonPrimaryClass!} ${properties.kcButtonBlockClass!} ${properties.kcButtonLargeClass!}" type="submit" value="${msg("doSubmit")}" />
</#if>
</div>
</div>
</form>
</#if>
</@layout.registrationLayout>
</@layout.registrationLayout>

View file

@ -1,43 +1,79 @@
<#import "template.ftl" as layout>
<@layout.registrationLayout; section>
<@layout.registrationLayout displayMessage=!messagesPerField.existsError('username','email','firstName','lastName'); section>
<#if section = "header">
${msg("loginProfileTitle")}
<#elseif section = "form">
<form id="kc-update-profile-form" class="${properties.kcFormClass!}" action="${url.loginAction}" method="post">
<#if user.editUsernameAllowed>
<div class="${properties.kcFormGroupClass!} ${messagesPerField.printIfExists('username',properties.kcFormGroupErrorClass!)}">
<div class="${properties.kcFormGroupClass!}">
<div class="${properties.kcLabelWrapperClass!}">
<label for="username" class="${properties.kcLabelClass!}">${msg("username")}</label>
</div>
<div class="${properties.kcInputWrapperClass!}">
<input type="text" id="username" name="username" value="${(user.username!'')}" class="${properties.kcInputClass!}"/>
<input type="text" id="username" name="username" value="${(user.username!'')}"
class="${properties.kcInputClass!}"
aria-invalid="<#if messagesPerField.existsError('username')>true</#if>"
/>
<#if messagesPerField.existsError('username')>
<span id="input-error-username" class="${properties.kcInputErrorMessageClass!}" aria-live="polite">
${kcSanitize(messagesPerField.get('username'))?no_esc}
</span>
</#if>
</div>
</div>
</#if>
<div class="${properties.kcFormGroupClass!} ${messagesPerField.printIfExists('email',properties.kcFormGroupErrorClass!)}">
<div class="${properties.kcFormGroupClass!}">
<div class="${properties.kcLabelWrapperClass!}">
<label for="email" class="${properties.kcLabelClass!}">${msg("email")}</label>
</div>
<div class="${properties.kcInputWrapperClass!}">
<input type="text" id="email" name="email" value="${(user.email!'')}" class="${properties.kcInputClass!}" />
<input type="text" id="email" name="email" value="${(user.email!'')}"
class="${properties.kcInputClass!}"
aria-invalid="<#if messagesPerField.existsError('email')>true</#if>"
/>
<#if messagesPerField.existsError('email')>
<span id="input-error-email" class="${properties.kcInputErrorMessageClass!}" aria-live="polite">
${kcSanitize(messagesPerField.get('email'))?no_esc}
</span>
</#if>
</div>
</div>
<div class="${properties.kcFormGroupClass!} ${messagesPerField.printIfExists('firstName',properties.kcFormGroupErrorClass!)}">
<div class="${properties.kcFormGroupClass!}">
<div class="${properties.kcLabelWrapperClass!}">
<label for="firstName" class="${properties.kcLabelClass!}">${msg("firstName")}</label>
</div>
<div class="${properties.kcInputWrapperClass!}">
<input type="text" id="firstName" name="firstName" value="${(user.firstName!'')}" class="${properties.kcInputClass!}" />
<input type="text" id="firstName" name="firstName" value="${(user.firstName!'')}"
class="${properties.kcInputClass!}"
aria-invalid="<#if messagesPerField.existsError('firstName')>true</#if>"
/>
<#if messagesPerField.existsError('firstName')>
<span id="input-error-firstname" class="${properties.kcInputErrorMessageClass!}" aria-live="polite">
${kcSanitize(messagesPerField.get('firstName'))?no_esc}
</span>
</#if>
</div>
</div>
<div class="${properties.kcFormGroupClass!} ${messagesPerField.printIfExists('lastName',properties.kcFormGroupErrorClass!)}">
<div class="${properties.kcFormGroupClass!}">
<div class="${properties.kcLabelWrapperClass!}">
<label for="lastName" class="${properties.kcLabelClass!}">${msg("lastName")}</label>
</div>
<div class="${properties.kcInputWrapperClass!}">
<input type="text" id="lastName" name="lastName" value="${(user.lastName!'')}" class="${properties.kcInputClass!}" />
<input type="text" id="lastName" name="lastName" value="${(user.lastName!'')}"
class="${properties.kcInputClass!}"
aria-invalid="<#if messagesPerField.existsError('lastName')>true</#if>"
/>
<#if messagesPerField.existsError('lastName')>
<span id="input-error-lastname" class="${properties.kcInputErrorMessageClass!}" aria-live="polite">
${kcSanitize(messagesPerField.get('lastName'))?no_esc}
</span>
</#if>
</div>
</div>

View file

@ -1,13 +1,14 @@
<#import "template.ftl" as layout>
<@layout.registrationLayout; section>
<@layout.registrationLayout displayInfo=true; section>
<#if section = "header">
${msg("emailVerifyTitle")}
<#elseif section = "form">
<p class="instruction">${msg("emailVerifyInstruction1")}</p>
<#elseif section = "info">
<p class="instruction">
${msg("emailVerifyInstruction1")}
</p>
<p class="instruction">
${msg("emailVerifyInstruction2")} <a href="${url.loginAction}">${msg("doClickHere")}</a> ${msg("emailVerifyInstruction3")}
${msg("emailVerifyInstruction2")}
<br/>
<a href="${url.loginAction}">${msg("doClickHere")}</a> ${msg("emailVerifyInstruction3")}
</p>
</#if>
</@layout.registrationLayout>