KEYCLOAK-15841 Upgrade rest of the minor forms to PF4
This commit is contained in:
parent
db026e5566
commit
7522d5ac74
29 changed files with 390 additions and 182 deletions
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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-]+)*");
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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() {
|
||||
|
|
|
@ -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() {
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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));
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
|
|
@ -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());
|
||||
|
|
|
@ -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());
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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 {
|
||||
|
||||
|
|
|
@ -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>
|
|
@ -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!}">
|
||||
|
|
|
@ -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>
|
|
@ -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>
|
||||
|
||||
|
|
|
@ -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>
|
Loading…
Reference in a new issue