keycloak-uncached
Changes
forms/account-freemarker/src/main/java/org/keycloak/account/freemarker/FreeMarkerAccountProvider.java 119(+84 -35)
forms/account-freemarker/src/main/java/org/keycloak/account/freemarker/model/MessageBean.java 60(+0 -60)
forms/common-freemarker/src/main/java/org/keycloak/freemarker/beans/MessagesPerFieldBean.java 7(+2 -5)
Details
diff --git a/forms/account-api/src/main/java/org/keycloak/account/AccountProvider.java b/forms/account-api/src/main/java/org/keycloak/account/AccountProvider.java
index bc6920b..f5bcbb2 100755
--- a/forms/account-api/src/main/java/org/keycloak/account/AccountProvider.java
+++ b/forms/account-api/src/main/java/org/keycloak/account/AccountProvider.java
@@ -1,52 +1,55 @@
package org.keycloak.account;
-import org.apache.http.client.methods.HttpHead;
-import org.keycloak.events.Event;
-import org.keycloak.models.RealmModel;
-import org.keycloak.models.UserModel;
-import org.keycloak.models.UserSessionModel;
-import org.keycloak.provider.Provider;
+import java.util.List;
import javax.ws.rs.core.HttpHeaders;
import javax.ws.rs.core.MultivaluedMap;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.UriInfo;
-import java.util.List;
+
+import org.keycloak.events.Event;
+import org.keycloak.models.RealmModel;
+import org.keycloak.models.UserModel;
+import org.keycloak.models.UserSessionModel;
+import org.keycloak.models.utils.FormMessage;
+import org.keycloak.provider.Provider;
/**
* @author <a href="mailto:sthorger@redhat.com">Stian Thorgersen</a>
*/
public interface AccountProvider extends Provider {
- AccountProvider setUriInfo(UriInfo uriInfo);
+ AccountProvider setUriInfo(UriInfo uriInfo);
+
+ AccountProvider setHttpHeaders(HttpHeaders httpHeaders);
- AccountProvider setHttpHeaders(HttpHeaders httpHeaders);
+ Response createResponse(AccountPages page);
- Response createResponse(AccountPages page);
+ AccountProvider setError(String message, Object... parameters);
- AccountProvider setError(String message, Object ... parameters);
+ AccountProvider setErrors(List<FormMessage> messages);
- AccountProvider setSuccess(String message, Object ... parameters);
+ AccountProvider setSuccess(String message, Object... parameters);
- AccountProvider setWarning(String message, Object ... parameters);
+ AccountProvider setWarning(String message, Object... parameters);
- AccountProvider setUser(UserModel user);
+ AccountProvider setUser(UserModel user);
- AccountProvider setProfileFormData(MultivaluedMap<String, String> formData);
+ AccountProvider setProfileFormData(MultivaluedMap<String, String> formData);
- AccountProvider setStatus(Response.Status status);
+ AccountProvider setStatus(Response.Status status);
- AccountProvider setRealm(RealmModel realm);
+ AccountProvider setRealm(RealmModel realm);
- AccountProvider setReferrer(String[] referrer);
+ AccountProvider setReferrer(String[] referrer);
- AccountProvider setEvents(List<Event> events);
+ AccountProvider setEvents(List<Event> events);
- AccountProvider setSessions(List<UserSessionModel> sessions);
+ AccountProvider setSessions(List<UserSessionModel> sessions);
- AccountProvider setPasswordSet(boolean passwordSet);
+ AccountProvider setPasswordSet(boolean passwordSet);
- AccountProvider setStateChecker(String stateChecker);
+ AccountProvider setStateChecker(String stateChecker);
- AccountProvider setFeatures(boolean social, boolean events, boolean passwordUpdateSupported);
+ AccountProvider setFeatures(boolean social, boolean events, boolean passwordUpdateSupported);
}
diff --git a/forms/account-freemarker/src/main/java/org/keycloak/account/freemarker/FreeMarkerAccountProvider.java b/forms/account-freemarker/src/main/java/org/keycloak/account/freemarker/FreeMarkerAccountProvider.java
index 4e0c007..2828531 100755
--- a/forms/account-freemarker/src/main/java/org/keycloak/account/freemarker/FreeMarkerAccountProvider.java
+++ b/forms/account-freemarker/src/main/java/org/keycloak/account/freemarker/FreeMarkerAccountProvider.java
@@ -1,25 +1,54 @@
package org.keycloak.account.freemarker;
+import java.io.IOException;
+import java.net.URI;
+import java.text.MessageFormat;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Locale;
+import java.util.Map;
+import java.util.Properties;
+
+import javax.ws.rs.core.HttpHeaders;
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.MultivaluedMap;
+import javax.ws.rs.core.Response;
+import javax.ws.rs.core.UriBuilder;
+import javax.ws.rs.core.UriInfo;
+
import org.jboss.logging.Logger;
import org.keycloak.account.AccountPages;
import org.keycloak.account.AccountProvider;
-import org.keycloak.account.freemarker.model.*;
+import org.keycloak.account.freemarker.model.AccountBean;
+import org.keycloak.account.freemarker.model.AccountFederatedIdentityBean;
+import org.keycloak.account.freemarker.model.FeaturesBean;
+import org.keycloak.account.freemarker.model.LogBean;
+import org.keycloak.account.freemarker.model.PasswordBean;
+import org.keycloak.account.freemarker.model.RealmBean;
+import org.keycloak.account.freemarker.model.ReferrerBean;
+import org.keycloak.account.freemarker.model.SessionsBean;
+import org.keycloak.account.freemarker.model.TotpBean;
+import org.keycloak.account.freemarker.model.UrlBean;
import org.keycloak.events.Event;
-import org.keycloak.freemarker.*;
+import org.keycloak.freemarker.BrowserSecurityHeaderSetup;
+import org.keycloak.freemarker.FreeMarkerException;
+import org.keycloak.freemarker.FreeMarkerUtil;
+import org.keycloak.freemarker.LocaleHelper;
+import org.keycloak.freemarker.Theme;
+import org.keycloak.freemarker.ThemeProvider;
+import org.keycloak.freemarker.beans.LocaleBean;
+import org.keycloak.freemarker.beans.MessageBean;
import org.keycloak.freemarker.beans.MessageFormatterMethod;
+import org.keycloak.freemarker.beans.MessageType;
+import org.keycloak.freemarker.beans.MessagesPerFieldBean;
import org.keycloak.models.KeycloakSession;
import org.keycloak.models.RealmModel;
import org.keycloak.models.UserModel;
import org.keycloak.models.UserSessionModel;
+import org.keycloak.models.utils.FormMessage;
import org.keycloak.services.resources.flows.Urls;
-import javax.ws.rs.core.*;
-import java.io.IOException;
-import java.net.URI;
-import java.text.MessageFormat;
-import java.util.*;
-import org.keycloak.freemarker.beans.LocaleBean;
-
/**
* @author <a href="mailto:sthorger@redhat.com">Stian Thorgersen</a>
*/
@@ -43,13 +72,10 @@ public class FreeMarkerAccountProvider implements AccountProvider {
private FreeMarkerUtil freeMarker;
private HttpHeaders headers;
- public static enum MessageType {SUCCESS, WARNING, ERROR}
-
private UriInfo uriInfo;
- private String message;
- private Object[] parameters;
- private MessageType messageType;
+ private List<FormMessage> messages = null;
+ private MessageType messageType = MessageType.ERROR;
public FreeMarkerAccountProvider(KeycloakSession session, FreeMarkerUtil freeMarker) {
this.session = session;
@@ -87,13 +113,13 @@ public class FreeMarkerAccountProvider implements AccountProvider {
}
Locale locale = LocaleHelper.getLocale(realm, user, uriInfo, headers);
- Properties messages;
+ Properties messagesBundle;
try {
- messages = theme.getMessages(locale);
- attributes.put("msg", new MessageFormatterMethod(locale, messages));
+ messagesBundle = theme.getMessages(locale);
+ attributes.put("msg", new MessageFormatterMethod(locale, messagesBundle));
} catch (IOException e) {
logger.warn("Failed to load messages", e);
- messages = new Properties();
+ messagesBundle = new Properties();
}
URI baseUri = uriInfo.getBaseUri();
@@ -107,15 +133,19 @@ public class FreeMarkerAccountProvider implements AccountProvider {
attributes.put("stateChecker", stateChecker);
}
- if (message != null) {
- String formattedMessage;
- if(messages.containsKey(message)){
- formattedMessage = new MessageFormat(messages.getProperty(message),locale).format(parameters);
- }else{
- formattedMessage = message;
+ MessagesPerFieldBean messagesPerField = new MessagesPerFieldBean();
+ if (messages != null) {
+ MessageBean wholeMessage = new MessageBean(null, messageType);
+ for (FormMessage message : this.messages) {
+ String formattedMessageText = formatMessage(message, messagesBundle, locale);
+ if (formattedMessageText != null) {
+ wholeMessage.appendSummaryLine(formattedMessageText);
+ messagesPerField.addMessage(message.getField(), formattedMessageText, messageType);
+ }
}
- attributes.put("message", new MessageBean(formattedMessage, messageType));
+ attributes.put("message", wholeMessage);
}
+ attributes.put("messagesPerField", messagesPerField);
if (referrer != null) {
attributes.put("referrer", new ReferrerBean(referrer));
@@ -134,7 +164,7 @@ public class FreeMarkerAccountProvider implements AccountProvider {
b = UriBuilder.fromUri(baseQueryUri).path(uriInfo.getPath());
break;
}
- attributes.put("locale", new LocaleBean(realm, locale, b, messages));
+ attributes.put("locale", new LocaleBean(realm, locale, b, messagesBundle));
}
attributes.put("features", new FeaturesBean(identityProviderEnabled, eventsEnabled, passwordUpdateSupported));
@@ -173,28 +203,47 @@ public class FreeMarkerAccountProvider implements AccountProvider {
this.passwordSet = passwordSet;
return this;
}
+
+ protected void setMessage(MessageType type, String message, Object... parameters) {
+ messageType = type;
+ messages = new ArrayList<>();
+ messages.add(new FormMessage(null, message, parameters));
+ }
+
+ protected String formatMessage(FormMessage message, Properties messagesBundle, Locale locale) {
+ if (message == null)
+ return null;
+ if (messagesBundle.containsKey(message.getMessage())) {
+ return new MessageFormat(messagesBundle.getProperty(message.getMessage()), locale)
+ .format(message.getParameters());
+ } else {
+ return message.getMessage();
+ }
+ }
+
+ @Override
+ public AccountProvider setErrors(List<FormMessage> messages) {
+ this.messageType = MessageType.ERROR;
+ this.messages = new ArrayList<>(messages);
+ return this;
+ }
+
@Override
public AccountProvider setError(String message, Object ... parameters) {
- this.message = message;
- this.parameters = parameters;
- this.messageType = MessageType.ERROR;
+ setMessage(MessageType.ERROR, message, parameters);
return this;
}
@Override
public AccountProvider setSuccess(String message, Object ... parameters) {
- this.message = message;
- this.parameters = parameters;
- this.messageType = MessageType.SUCCESS;
+ setMessage(MessageType.SUCCESS, message, parameters);
return this;
}
@Override
public AccountProvider setWarning(String message, Object ... parameters) {
- this.message = message;
- this.parameters = parameters;
- this.messageType = MessageType.WARNING;
+ setMessage(MessageType.WARNING, message, parameters);
return this;
}
diff --git a/forms/common-freemarker/src/main/java/org/keycloak/freemarker/beans/MessageType.java b/forms/common-freemarker/src/main/java/org/keycloak/freemarker/beans/MessageType.java
new file mode 100644
index 0000000..a404c7e
--- /dev/null
+++ b/forms/common-freemarker/src/main/java/org/keycloak/freemarker/beans/MessageType.java
@@ -0,0 +1,17 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2015 Red Hat Inc. and/or its affiliates and other contributors
+ * as indicated by the @authors tag. All rights reserved.
+ */
+package org.keycloak.freemarker.beans;
+
+/**
+ * Enum with types of messages.
+ *
+ * @author Vlastimil Elias (velias at redhat dot com)
+ */
+public enum MessageType {
+
+ SUCCESS, WARNING, ERROR
+
+}
diff --git a/forms/common-themes/src/main/resources/theme/base/account/account.ftl b/forms/common-themes/src/main/resources/theme/base/account/account.ftl
index a41d769..7c349df 100755
--- a/forms/common-themes/src/main/resources/theme/base/account/account.ftl
+++ b/forms/common-themes/src/main/resources/theme/base/account/account.ftl
@@ -14,7 +14,7 @@
<input type="hidden" id="stateChecker" name="stateChecker" value="${stateChecker}">
- <div class="form-group">
+ <div class="form-group ${messagesPerField.printIfExists('username','has-error')}">
<div class="col-sm-2 col-md-2">
<label for="username" class="control-label">${msg("username")}</label>
</div>
@@ -24,7 +24,7 @@
</div>
</div>
- <div class="form-group">
+ <div class="form-group ${messagesPerField.printIfExists('email','has-error')}">
<div class="col-sm-2 col-md-2">
<label for="email" class="control-label">${msg("email")}</label> <span class="required">*</span>
</div>
@@ -34,7 +34,7 @@
</div>
</div>
- <div class="form-group">
+ <div class="form-group ${messagesPerField.printIfExists('firstName','has-error')}">
<div class="col-sm-2 col-md-2">
<label for="firstName" class="control-label">${msg("firstName")}</label> <span class="required">*</span>
</div>
@@ -44,7 +44,7 @@
</div>
</div>
- <div class="form-group">
+ <div class="form-group ${messagesPerField.printIfExists('lastName','has-error')}">
<div class="col-sm-2 col-md-2">
<label for="lastName" class="control-label">${msg("lastName")}</label> <span class="required">*</span>
</div>
diff --git a/forms/common-themes/src/main/resources/theme/base/login/login-update-profile.ftl b/forms/common-themes/src/main/resources/theme/base/login/login-update-profile.ftl
index 56b5cbe..a534073 100755
--- a/forms/common-themes/src/main/resources/theme/base/login/login-update-profile.ftl
+++ b/forms/common-themes/src/main/resources/theme/base/login/login-update-profile.ftl
@@ -6,7 +6,7 @@
${msg("loginProfileTitle")}
<#elseif section = "form">
<form id="kc-update-profile-form" class="${properties.kcFormClass!}" action="${url.loginUpdateProfileUrl}" method="post">
- <div class="${properties.kcFormGroupClass!}">
+ <div class="${properties.kcFormGroupClass!} ${messagesPerField.printIfExists('email',properties.kcFormGroupErrorClass!)}">
<div class="${properties.kcLabelWrapperClass!}">
<label for="email" class="${properties.kcLabelClass!}">${msg("email")}</label>
</div>
@@ -15,7 +15,7 @@
</div>
</div>
- <div class="${properties.kcFormGroupClass!}">
+ <div class="${properties.kcFormGroupClass!} ${messagesPerField.printIfExists('firstName',properties.kcFormGroupErrorClass!)}">
<div class="${properties.kcLabelWrapperClass!}">
<label for="firstName" class="${properties.kcLabelClass!}">${msg("firstName")}</label>
</div>
@@ -24,7 +24,7 @@
</div>
</div>
- <div class="${properties.kcFormGroupClass!}">
+ <div class="${properties.kcFormGroupClass!} ${messagesPerField.printIfExists('lastName',properties.kcFormGroupErrorClass!)}">
<div class="${properties.kcLabelWrapperClass!}">
<label for="lastName" class="${properties.kcLabelClass!}">${msg("lastName")}</label>
</div>
diff --git a/forms/login-api/src/main/java/org/keycloak/login/LoginFormsProvider.java b/forms/login-api/src/main/java/org/keycloak/login/LoginFormsProvider.java
index ac73087..c3a71d9 100755
--- a/forms/login-api/src/main/java/org/keycloak/login/LoginFormsProvider.java
+++ b/forms/login-api/src/main/java/org/keycloak/login/LoginFormsProvider.java
@@ -13,6 +13,7 @@ import org.keycloak.models.ClientSessionModel;
import org.keycloak.models.RealmModel;
import org.keycloak.models.RoleModel;
import org.keycloak.models.UserModel;
+import org.keycloak.models.utils.FormMessage;
import org.keycloak.provider.Provider;
/**
diff --git a/forms/login-freemarker/src/main/java/org/keycloak/login/freemarker/FreeMarkerLoginFormsProvider.java b/forms/login-freemarker/src/main/java/org/keycloak/login/freemarker/FreeMarkerLoginFormsProvider.java
index 22fa3f7..0dd6342 100755
--- a/forms/login-freemarker/src/main/java/org/keycloak/login/freemarker/FreeMarkerLoginFormsProvider.java
+++ b/forms/login-freemarker/src/main/java/org/keycloak/login/freemarker/FreeMarkerLoginFormsProvider.java
@@ -1,27 +1,50 @@
package org.keycloak.login.freemarker;
+import java.io.IOException;
+import java.net.URI;
+import java.text.MessageFormat;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Locale;
+import java.util.Map;
+import java.util.Properties;
+import java.util.concurrent.TimeUnit;
+
+import javax.ws.rs.core.HttpHeaders;
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.MultivaluedMap;
+import javax.ws.rs.core.Response;
+import javax.ws.rs.core.UriBuilder;
+import javax.ws.rs.core.UriInfo;
+
import org.jboss.logging.Logger;
import org.jboss.resteasy.specimpl.MultivaluedMapImpl;
import org.keycloak.OAuth2Constants;
import org.keycloak.email.EmailException;
import org.keycloak.email.EmailProvider;
-import org.keycloak.freemarker.*;
+import org.keycloak.freemarker.BrowserSecurityHeaderSetup;
+import org.keycloak.freemarker.FreeMarkerException;
+import org.keycloak.freemarker.FreeMarkerUtil;
+import org.keycloak.freemarker.LocaleHelper;
+import org.keycloak.freemarker.Theme;
+import org.keycloak.freemarker.ThemeProvider;
import org.keycloak.freemarker.beans.AdvancedMessageFormatterMethod;
+import org.keycloak.freemarker.beans.LocaleBean;
+import org.keycloak.freemarker.beans.MessageBean;
import org.keycloak.freemarker.beans.MessageFormatterMethod;
-import org.keycloak.login.FormMessage;
+import org.keycloak.freemarker.beans.MessageType;
+import org.keycloak.freemarker.beans.MessagesPerFieldBean;
import org.keycloak.login.LoginFormsPages;
import org.keycloak.login.LoginFormsProvider;
import org.keycloak.login.freemarker.model.ClientBean;
import org.keycloak.login.freemarker.model.CodeBean;
-import org.keycloak.freemarker.beans.LocaleBean;
+import org.keycloak.login.freemarker.model.IdentityProviderBean;
import org.keycloak.login.freemarker.model.LoginBean;
-import org.keycloak.login.freemarker.model.MessageBean;
-import org.keycloak.login.freemarker.model.MessagesPerFieldBean;
import org.keycloak.login.freemarker.model.OAuthGrantBean;
import org.keycloak.login.freemarker.model.ProfileBean;
import org.keycloak.login.freemarker.model.RealmBean;
import org.keycloak.login.freemarker.model.RegisterBean;
-import org.keycloak.login.freemarker.model.IdentityProviderBean;
import org.keycloak.login.freemarker.model.TotpBean;
import org.keycloak.login.freemarker.model.UrlBean;
import org.keycloak.models.ClientModel;
@@ -30,17 +53,10 @@ import org.keycloak.models.KeycloakSession;
import org.keycloak.models.RealmModel;
import org.keycloak.models.RoleModel;
import org.keycloak.models.UserModel;
+import org.keycloak.models.utils.FormMessage;
import org.keycloak.services.messages.Messages;
import org.keycloak.services.resources.flows.Urls;
-import javax.ws.rs.core.*;
-
-import java.io.IOException;
-import java.net.URI;
-import java.text.MessageFormat;
-import java.util.*;
-import java.util.concurrent.TimeUnit;
-
/**
* @author <a href="mailto:sthorger@redhat.com">Stian Thorgersen</a>
*/
@@ -48,8 +64,6 @@ import java.util.concurrent.TimeUnit;
private static final Logger logger = Logger.getLogger(FreeMarkerLoginFormsProvider.class);
- public static enum MessageType {SUCCESS, WARNING, ERROR}
-
private String accessCode;
private Response.Status status;
private List<RoleModel> realmRolesRequested;
@@ -191,7 +205,7 @@ import java.util.concurrent.TimeUnit;
if (messages != null) {
MessageBean wholeMessage = new MessageBean(null, messageType);
for (FormMessage message : this.messages) {
- String formattedMessageText = formatMessageMessage(message, messagesBundle, locale);
+ String formattedMessageText = formatMessage(message, messagesBundle, locale);
if (formattedMessageText != null) {
wholeMessage.appendSummaryLine(formattedMessageText);
messagesPerField.addMessage(message.getField(), formattedMessageText, messageType);
@@ -323,7 +337,7 @@ import java.util.concurrent.TimeUnit;
return null;
}
- protected String formatMessageMessage(FormMessage message, Properties messagesBundle, Locale locale) {
+ protected String formatMessage(FormMessage message, Properties messagesBundle, Locale locale) {
if (message == null)
return null;
if (messagesBundle.containsKey(message.getMessage())) {
@@ -332,22 +346,27 @@ import java.util.concurrent.TimeUnit;
return message.getMessage();
}
}
+
+ @Override
public FreeMarkerLoginFormsProvider setError(String message, Object... parameters) {
setMessage(MessageType.ERROR, message, parameters);
return this;
}
+ @Override
public LoginFormsProvider setErrors(List<FormMessage> messages) {
this.messageType = MessageType.ERROR;
this.messages = new ArrayList<>(messages);
return this;
}
+ @Override
public FreeMarkerLoginFormsProvider setSuccess(String message, Object ... parameters) {
setMessage(MessageType.SUCCESS, message, parameters);
return this;
}
+ @Override
public FreeMarkerLoginFormsProvider setWarning(String message, Object ... parameters) {
setMessage(MessageType.WARNING, message, parameters);
return this;
diff --git a/services/src/main/java/org/keycloak/services/resources/AccountService.java b/services/src/main/java/org/keycloak/services/resources/AccountService.java
index f694661..fd50eda 100755
--- a/services/src/main/java/org/keycloak/services/resources/AccountService.java
+++ b/services/src/main/java/org/keycloak/services/resources/AccountService.java
@@ -34,6 +34,7 @@ import org.keycloak.events.EventBuilder;
import org.keycloak.events.EventStoreProvider;
import org.keycloak.events.EventType;
import org.keycloak.models.*;
+import org.keycloak.models.utils.FormMessage;
import org.keycloak.models.utils.ModelToRepresentation;
import org.keycloak.models.utils.TimeBasedOTP;
import org.keycloak.protocol.oidc.OIDCLoginProtocol;
@@ -71,6 +72,7 @@ import javax.ws.rs.core.Response;
import javax.ws.rs.core.UriBuilder;
import javax.ws.rs.core.UriInfo;
import javax.ws.rs.core.Variant;
+
import java.lang.reflect.Method;
import java.net.URI;
import java.util.HashSet;
@@ -405,10 +407,10 @@ public class AccountService {
UserModel user = auth.getUser();
- String error = Validation.validateUpdateProfileForm(formData);
- if (error != null) {
+ List<FormMessage> errors = Validation.validateUpdateProfileForm(formData);
+ if (errors != null && !errors.isEmpty()) {
setReferrerOnPage();
- return account.setError(error).setProfileFormData(formData).createResponse(AccountPages.ACCOUNT);
+ return account.setErrors(errors).setProfileFormData(formData).createResponse(AccountPages.ACCOUNT);
}
try {
diff --git a/services/src/main/java/org/keycloak/services/resources/LoginActionsService.java b/services/src/main/java/org/keycloak/services/resources/LoginActionsService.java
index 0a7e8b1..c941cc4 100755
--- a/services/src/main/java/org/keycloak/services/resources/LoginActionsService.java
+++ b/services/src/main/java/org/keycloak/services/resources/LoginActionsService.java
@@ -31,10 +31,10 @@ import org.keycloak.events.Errors;
import org.keycloak.events.EventBuilder;
import org.keycloak.events.EventType;
import org.keycloak.jose.jws.JWSBuilder;
-import org.keycloak.login.FormMessage;
import org.keycloak.login.LoginFormsProvider;
import org.keycloak.models.*;
import org.keycloak.models.UserModel.RequiredAction;
+import org.keycloak.models.utils.FormMessage;
import org.keycloak.models.utils.KeycloakModelUtils;
import org.keycloak.models.utils.TimeBasedOTP;
import org.keycloak.protocol.LoginProtocol;
@@ -618,9 +618,9 @@ public class LoginActionsService {
initEvent(clientSession);
- String error = Validation.validateUpdateProfileForm(formData);
- if (error != null) {
- return Flows.forms(session, realm, null, uriInfo, headers).setUser(user).setError(error)
+ List<FormMessage> errors = Validation.validateUpdateProfileForm(formData);
+ if (errors != null && !errors.isEmpty()) {
+ return Flows.forms(session, realm, null, uriInfo, headers).setUser(user).setErrors(errors)
.setClientSessionCode(accessCode.getCode())
.createResponse(RequiredAction.UPDATE_PROFILE);
}
diff --git a/services/src/main/java/org/keycloak/services/validation/Validation.java b/services/src/main/java/org/keycloak/services/validation/Validation.java
index 5fb98f9..1a4392b 100755
--- a/services/src/main/java/org/keycloak/services/validation/Validation.java
+++ b/services/src/main/java/org/keycloak/services/validation/Validation.java
@@ -6,9 +6,9 @@ import java.util.regex.Pattern;
import javax.ws.rs.core.MultivaluedMap;
-import org.keycloak.login.FormMessage;
import org.keycloak.models.PasswordPolicy;
import org.keycloak.models.RealmModel;
+import org.keycloak.models.utils.FormMessage;
import org.keycloak.representations.idm.CredentialRepresentation;
import org.keycloak.services.messages.Messages;
@@ -67,24 +67,24 @@ public class Validation {
}
- public static String validateUpdateProfileForm(MultivaluedMap<String, String> formData) {
+ public static List<FormMessage> validateUpdateProfileForm(MultivaluedMap<String, String> formData) {
+ List<FormMessage> errors = new ArrayList<>();
+
if (isEmpty(formData.getFirst(FIELD_FIRST_NAME))) {
- return Messages.MISSING_FIRST_NAME;
+ addError(errors, FIELD_FIRST_NAME, Messages.MISSING_FIRST_NAME);
}
if (isEmpty(formData.getFirst(FIELD_LAST_NAME))) {
- return Messages.MISSING_LAST_NAME;
+ addError(errors, FIELD_LAST_NAME, Messages.MISSING_LAST_NAME);
}
if (isEmpty(formData.getFirst(FIELD_EMAIL))) {
- return Messages.MISSING_EMAIL;
- }
-
- if (!isEmailValid(formData.getFirst(FIELD_EMAIL))) {
- return Messages.INVALID_EMAIL;
+ addError(errors, FIELD_EMAIL, Messages.MISSING_EMAIL);
+ } else if (!isEmailValid(formData.getFirst(FIELD_EMAIL))) {
+ addError(errors, FIELD_EMAIL, Messages.INVALID_EMAIL);
}
- return null;
+ return errors;
}
public static boolean isEmpty(String s) {