keycloak-uncached

Changes

Details

diff --git a/forms/src/main/java/org/keycloak/service/FormServiceImpl.java b/forms/src/main/java/org/keycloak/service/FormServiceImpl.java
index 9489448..64624e4 100644
--- a/forms/src/main/java/org/keycloak/service/FormServiceImpl.java
+++ b/forms/src/main/java/org/keycloak/service/FormServiceImpl.java
@@ -32,7 +32,7 @@ import freemarker.template.Configuration;
 import freemarker.template.Template;
 import freemarker.template.TemplateException;
 import org.jboss.resteasy.logging.Logger;
-import org.keycloak.forms.ErrorBean;
+import org.keycloak.forms.MessageBean;
 import org.keycloak.forms.LoginBean;
 import org.keycloak.forms.OAuthGrantBean;
 import org.keycloak.forms.RealmBean;
@@ -69,8 +69,7 @@ public class FormServiceImpl implements FormService {
         commandMap.put(Pages.TOTP, new CommandTotp());
         commandMap.put(Pages.LOGIN_CONFIG_TOTP, new CommandTotp());
         commandMap.put(Pages.LOGIN_TOTP, new CommandLoginTotp());
-        commandMap.put(Pages.LOGIN_VERIFY_EMAIL, new CommandLoginTotp());
-        commandMap.put(Pages.ERROR, new CommandError());
+        commandMap.put(Pages.LOGIN_VERIFY_EMAIL, new CommandVerifyEmail());
         commandMap.put(Pages.OAUTH_GRANT, new CommandOAuthGrant());
     }
 
@@ -82,8 +81,8 @@ public class FormServiceImpl implements FormService {
 
         Map<String, Object> attributes = new HashMap<String, Object>();
 
-        if (dataBean.getError() != null){
-            attributes.put("message", new ErrorBean(dataBean.getError(), dataBean.getErrorType()));
+        if (dataBean.getMessage() != null){
+            attributes.put("message", new MessageBean(dataBean.getMessage(), dataBean.getMessageType()));
         }
 
         RealmBean realm = new RealmBean(dataBean.getRealm());
@@ -161,9 +160,6 @@ public class FormServiceImpl implements FormService {
 
     private class CommandLoginTotp implements Command {
         public void exec(Map<String, Object> attributes, FormServiceDataBean dataBean) {
-            if (dataBean.getError() != null){
-                attributes.put("error", new ErrorBean(dataBean.getError()));
-            }
 
             RealmBean realm = new RealmBean(dataBean.getRealm());
 
@@ -206,10 +202,6 @@ public class FormServiceImpl implements FormService {
 
     private class CommandLogin implements Command {
         public void exec(Map<String, Object> attributes, FormServiceDataBean dataBean) {
-            if (dataBean.getError() != null){
-                attributes.put("error", new ErrorBean(dataBean.getError()));
-            }
-
             RealmBean realm = new RealmBean(dataBean.getRealm());
 
             attributes.put("realm", realm);
@@ -230,9 +222,6 @@ public class FormServiceImpl implements FormService {
 
     private class CommandRegister implements Command {
         public void exec(Map<String, Object> attributes, FormServiceDataBean dataBean) {
-            if (dataBean.getError() != null){
-                attributes.put("error", new ErrorBean(dataBean.getError()));
-            }
 
             RealmBean realm = new RealmBean(dataBean.getRealm());
 
@@ -252,14 +241,6 @@ public class FormServiceImpl implements FormService {
         }
     }
 
-    private class CommandError implements Command {
-        public void exec(Map<String, Object> attributes, FormServiceDataBean dataBean) {
-            if (dataBean.getError() != null){
-                attributes.put("error", new ErrorBean(dataBean.getError()));
-            }
-        }
-    }
-
     private class CommandOAuthGrant implements Command {
         public void exec(Map<String, Object> attributes, FormServiceDataBean dataBean) {
 
@@ -274,6 +255,20 @@ public class FormServiceImpl implements FormService {
         }
     }
 
+    private class CommandVerifyEmail implements Command {
+        public void exec(Map<String, Object> attributes, FormServiceDataBean dataBean) {
+
+            RealmBean realm = new RealmBean(dataBean.getRealm());
+
+            attributes.put("realm", realm);
+
+            UrlBean url = new UrlBean(realm, dataBean.getBaseURI());
+            url.setSocialRegistration(dataBean.getSocialRegistration());
+
+            attributes.put("url", url);
+        }
+    }
+
     private interface Command {
         public void exec(Map<String, Object> attributes, FormServiceDataBean dataBean);
     }
diff --git a/forms/src/main/resources/META-INF/resources/forms/theme/default/css/login-register.css b/forms/src/main/resources/META-INF/resources/forms/theme/default/css/login-register.css
index 8eacd72..eca69a2 100644
--- a/forms/src/main/resources/META-INF/resources/forms/theme/default/css/login-register.css
+++ b/forms/src/main/resources/META-INF/resources/forms/theme/default/css/login-register.css
@@ -291,9 +291,6 @@ a.zocial:before {
 .rcue-login-register.reset .background-area .section.app-form {
   width: 43.2em;
 }
-.rcue-login-register.reset .feedback {
-  left: 35.7em;
-}
 
 .rcue-login-register.oauth .form-actions {
     margin-bottom: 0;
diff --git a/forms/src/main/resources/META-INF/resources/forms/theme/default/error.ftl b/forms/src/main/resources/META-INF/resources/forms/theme/default/error.ftl
index 659fce1..fd3fc1e 100755
--- a/forms/src/main/resources/META-INF/resources/forms/theme/default/error.ftl
+++ b/forms/src/main/resources/META-INF/resources/forms/theme/default/error.ftl
@@ -12,7 +12,7 @@
     <#elseif section = "form">
 
         <p class="instruction">Something happened and we could not process your request.</p>
-        <p id="error-summary" class="instruction second">${error.summary}</p>
+        <p id="error-summary" class="instruction second">${message.summary}</p>
 
     <#elseif section = "info" >
 
diff --git a/forms/src/main/resources/META-INF/resources/forms/theme/default/login-config-totp.ftl b/forms/src/main/resources/META-INF/resources/forms/theme/default/login-config-totp.ftl
index 2b1c1c5..97ff4ad 100755
--- a/forms/src/main/resources/META-INF/resources/forms/theme/default/login-config-totp.ftl
+++ b/forms/src/main/resources/META-INF/resources/forms/theme/default/login-config-totp.ftl
@@ -8,11 +8,6 @@
 
     Google Authenticator Setup
 
-    <#elseif section = "feedback">
-    <div class="feedback warning show">
-        <p><strong>Your account is not enabled because you need to set up the Google Authenticator.</strong><br>Please follow the steps below.</p>
-    </div>
-
     <#elseif section = "form">
 
     <div id="form">
diff --git a/forms/src/main/resources/META-INF/resources/forms/theme/default/login-reset-password.ftl b/forms/src/main/resources/META-INF/resources/forms/theme/default/login-reset-password.ftl
index ad80199..af308ac 100755
--- a/forms/src/main/resources/META-INF/resources/forms/theme/default/login-reset-password.ftl
+++ b/forms/src/main/resources/META-INF/resources/forms/theme/default/login-reset-password.ftl
@@ -11,15 +11,6 @@
     <#elseif section = "form">
 
     <div id="form">
-        <#if message?has_content>
-            <#if message.success>
-                <div class="feedback success bottom-left show"><p><strong>${rb.getString('successHeader')}</strong> ${rb.getString(message.summary)}</p></div>
-            </#if>
-            <#if message.error>
-                <div class="feedback error bottom-left show"><p><strong>${rb.getString('errorHeader')}</strong><br/>${rb.getString(message.summary)}</p></div>
-            </#if>
-        </#if>
-
         <p class="instruction">${rb.getString('emailInstruction')}</p>
         <form action="${url.loginPasswordResetUrl}" method="post">
             <div>
diff --git a/forms/src/main/resources/META-INF/resources/forms/theme/default/login-verify-email.ftl b/forms/src/main/resources/META-INF/resources/forms/theme/default/login-verify-email.ftl
index cff75f1..0832666 100755
--- a/forms/src/main/resources/META-INF/resources/forms/theme/default/login-verify-email.ftl
+++ b/forms/src/main/resources/META-INF/resources/forms/theme/default/login-verify-email.ftl
@@ -8,11 +8,6 @@
 
     Email verification
 
-    <#elseif section = "feedback">
-    <div class="feedback warning show">
-        <p><strong>Your account is not enabled because you need to verify your email.</strong><br>Please follow the steps below.</p>
-    </div>
-
     <#elseif section = "form">
 
     <div class="app-form">
diff --git a/forms/src/main/resources/META-INF/resources/forms/theme/default/template-login.ftl b/forms/src/main/resources/META-INF/resources/forms/theme/default/template-login.ftl
index de023e1..d64a3c6 100644
--- a/forms/src/main/resources/META-INF/resources/forms/theme/default/template-login.ftl
+++ b/forms/src/main/resources/META-INF/resources/forms/theme/default/template-login.ftl
@@ -31,10 +31,10 @@
             <div class="form-area ${(realm.social)?string('social','')} clearfix">
                 <div class="section app-form">
                     <h3>Application login area</h3>
-                    <#if error?has_content>
+                    <#if message?has_content && message.error>
                         <div class="feedback error bottom-left show">
                             <p>
-                                <strong id="loginError">${rb.getString(error.summary)}</strong><br/>${rb.getString('emailErrorInfo')}
+                                <strong id="loginError">${rb.getString(message.summary)}</strong><br/>${rb.getString('emailErrorInfo')}
                             </p>
                         </div>
                     </#if>
diff --git a/forms/src/main/resources/META-INF/resources/forms/theme/default/template-login-action.ftl b/forms/src/main/resources/META-INF/resources/forms/theme/default/template-login-action.ftl
index c2920cf..303aeeb 100644
--- a/forms/src/main/resources/META-INF/resources/forms/theme/default/template-login-action.ftl
+++ b/forms/src/main/resources/META-INF/resources/forms/theme/default/template-login-action.ftl
@@ -17,7 +17,11 @@
 
 <body class="rcue-login-register ${bodyClass}">
     <div class="feedback-aligner">
-        <#nested "feedback">
+        <#if message?has_content && message.warning>
+        <div class="feedback warning show">
+            <p><strong>${rb.getString('actionWarningHeader')} ${rb.getString(message.summary)}</strong><br/>${rb.getString('actionFollow')}</p>
+        </div>
+        </#if>
     </div>
     <#if (template.themeConfig.logo)?has_content>
         <h1>
@@ -33,18 +37,26 @@
         <div class="background-area">
             <div class="form-area clearfix">
                 <div class="section app-form">
+                    <#if !isErrorPage && message?has_content>
+                        <#if message.error>
+                            <div class="feedback error bottom-left show">
+                                <p>
+                                    <strong id="loginError">${rb.getString(message.summary)}</strong><br/>${rb.getString('emailErrorInfo')}
+                                </p>
+                            </div>
+                        <#elseif message.success>
+                            <div class="feedback success bottom-left show">
+                                <p>
+                                    <strong>${rb.getString('successHeader')}</strong> ${rb.getString(message.summary)}
+                                </p>
+                            </div>
+                        </#if>
+                    </#if>
+
                     <h3>Application login area</h3>
                     <#nested "form">
                 </div>
 
-                <#if !isErrorPage && error?has_content>
-                    <div class="feedback error bottom-left show">
-                        <p>
-                            <strong id="loginError">${rb.getString(error.summary)}</strong>
-                        </p>
-                    </div>
-                </#if>
-
                 <div class="section info-area">
                     <h3>Info area</h3>
                     <#nested "info">
diff --git a/forms/src/main/resources/org/keycloak/forms/messages.properties b/forms/src/main/resources/org/keycloak/forms/messages.properties
index 03943dc..8fb4f12 100644
--- a/forms/src/main/resources/org/keycloak/forms/messages.properties
+++ b/forms/src/main/resources/org/keycloak/forms/messages.properties
@@ -31,6 +31,7 @@ missingLastName=Please specify last name
 missingEmail=Please specify email
 missingUsername=Please specify username
 missingPassword=Please specify password
+notMatchPassword=Passwords don't match
 missingTotp=Please specify authenticator code
 
 invalidPasswordExisting=Invalid existing password
@@ -43,6 +44,12 @@ successTotpRemoved=Google authenticator removed.
 usernameExists=Username already exists
 
 error=A system error has occured, contact admin
+actionWarningHeader=Your account is not enabled.
+actionTotpWarning=You need to set up the Google Authenticator to activate your account.
+actionProfileWarning=You need to update your user profile to activate your account.
+actionPasswordWarning=You need to change your password to activate your account.
+actionEmailWarning=You need to verify your email address to activate your account.
+actionFollow=Please follow the steps below.
 
 successHeader=Success!
 errorHeader=Error!
diff --git a/services/src/main/java/org/keycloak/services/FormService.java b/services/src/main/java/org/keycloak/services/FormService.java
index 6e58138..70e4c0f 100755
--- a/services/src/main/java/org/keycloak/services/FormService.java
+++ b/services/src/main/java/org/keycloak/services/FormService.java
@@ -44,9 +44,9 @@ public interface FormService {
 
         private RealmModel realm;
         private UserModel userModel;
-        private String error;
+        private String message;
 
-        private FormFlows.ErrorType errorType;
+        private FormFlows.MessageType messageType;
 
         private MultivaluedMap<String, String> formData;
         private URI baseURI;
@@ -81,11 +81,11 @@ public interface FormService {
 
         private String contextPath;
 
-        public FormServiceDataBean(RealmModel realm, UserModel userModel, MultivaluedMap<String, String> formData, String error){
+        public FormServiceDataBean(RealmModel realm, UserModel userModel, MultivaluedMap<String, String> formData, String message){
             this.realm = realm;
             this.userModel = userModel;
             this.formData = formData;
-            this.error = error;
+            this.message = message;
         }
 
         public URI getBaseURI() {
@@ -96,12 +96,12 @@ public interface FormService {
             this.baseURI = baseURI;
         }
 
-        public String getError() {
-            return error;
+        public String getMessage() {
+            return message;
         }
 
-        public void setError(String error) {
-            this.error = error;
+        public void setMessage(String message) {
+            this.message = message;
         }
 
         public MultivaluedMap<String, String> getFormData() {
@@ -128,12 +128,12 @@ public interface FormService {
             this.userModel = userModel;
         }
 
-        public FormFlows.ErrorType getErrorType() {
-            return errorType;
+        public FormFlows.MessageType getMessageType() {
+            return messageType;
         }
 
-        public void setErrorType(FormFlows.ErrorType errorType) {
-            this.errorType = errorType;
+        public void setMessageType(FormFlows.MessageType messageType) {
+            this.messageType = messageType;
         }
 
         /* OAuth Part */
diff --git a/services/src/main/java/org/keycloak/services/messages/Messages.java b/services/src/main/java/org/keycloak/services/messages/Messages.java
index 3b7a760..2c659fb 100644
--- a/services/src/main/java/org/keycloak/services/messages/Messages.java
+++ b/services/src/main/java/org/keycloak/services/messages/Messages.java
@@ -44,6 +44,8 @@ public class Messages {
 
     public static final String MISSING_PASSWORD = "missingPassword";
 
+    public static final String NOTMATCH_PASSWORD = "notMatchPassword";
+
     public static final String MISSING_USERNAME = "missingUsername";
 
     public static final String MISSING_TOTP = "missingTotp";
@@ -52,6 +54,14 @@ public class Messages {
 
     public static final String USERNAME_EXISTS = "usernameExists";
 
+    public static final String ACTION_WARN_TOTP = "actionTotpWarning";
+
+    public static final String ACTION_WARN_PROFILE = "actionProfileWarning";
+
+    public static final String ACTION_WARN_PASSWD = "actionPasswordWarning";
+
+    public static final String ACTION_WARN_EMAIL = "actionEmailWarning";
+
     public static final String ERROR = "error";
 
 }
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 7f54e52..7205d6f 100755
--- a/services/src/main/java/org/keycloak/services/resources/AccountService.java
+++ b/services/src/main/java/org/keycloak/services/resources/AccountService.java
@@ -115,7 +115,7 @@ public class AccountService {
     public Response processTotpRemove() {
         UserModel user = getUserFromAuthManager();
         user.setTotp(false);
-        return Flows.forms(realm, request, uriInfo).setError("successTotpRemoved").setErrorType(FormFlows.ErrorType.SUCCESS)
+        return Flows.forms(realm, request, uriInfo).setError("successTotpRemoved").setErrorType(FormFlows.MessageType.SUCCESS)
                 .setUser(user).forwardToTotp();
     }
 
@@ -152,7 +152,7 @@ public class AccountService {
 
         user.setTotp(true);
 
-        return Flows.forms(realm, request, uriInfo).setError("successTotp").setErrorType(FormFlows.ErrorType.SUCCESS)
+        return Flows.forms(realm, request, uriInfo).setError("successTotp").setErrorType(FormFlows.MessageType.SUCCESS)
                 .setUser(user).forwardToTotp();
     }
 
diff --git a/services/src/main/java/org/keycloak/services/resources/flows/FormFlows.java b/services/src/main/java/org/keycloak/services/resources/flows/FormFlows.java
index c4fe4a6..2aebb4e 100755
--- a/services/src/main/java/org/keycloak/services/resources/flows/FormFlows.java
+++ b/services/src/main/java/org/keycloak/services/resources/flows/FormFlows.java
@@ -34,6 +34,7 @@ import org.keycloak.services.managers.AccessCodeEntry;
 import org.keycloak.models.RealmModel;
 import org.keycloak.models.UserModel;
 import org.keycloak.models.UserModel.RequiredAction;
+import org.keycloak.services.messages.Messages;
 import org.picketlink.idm.model.sample.Realm;
 
 import javax.imageio.spi.ServiceRegistry;
@@ -58,8 +59,8 @@ public class FormFlows {
     // TODO refactor/rename "error" to "message" everywhere where it makes sense
     private String error;
 
-    public static enum ErrorType {SUCCESS, WARNING, ERROR};
-    private ErrorType errorType;
+    public static enum MessageType {SUCCESS, WARNING, ERROR};
+    private MessageType messageType = MessageType.ERROR;
 
     private MultivaluedMap<String, String> formData;
 
@@ -79,16 +80,17 @@ public class FormFlows {
     }
 
     public Response forwardToAction(RequiredAction action) {
+
         switch (action) {
             case CONFIGURE_TOTP:
-                return forwardToForm(Pages.LOGIN_CONFIG_TOTP);
+                return forwardToActionForm(Pages.LOGIN_CONFIG_TOTP, Messages.ACTION_WARN_TOTP);
             case UPDATE_PROFILE:
-                return forwardToForm(Pages.LOGIN_UPDATE_PROFILE);
+                return forwardToActionForm(Pages.LOGIN_UPDATE_PROFILE, Messages.ACTION_WARN_PROFILE);
             case UPDATE_PASSWORD:
-                return forwardToForm(Pages.LOGIN_UPDATE_PASSWORD);
+                return forwardToActionForm(Pages.LOGIN_UPDATE_PASSWORD, Messages.ACTION_WARN_PASSWD);
             case VERIFY_EMAIL:
                 new EmailSender().sendEmailVerification(userModel, realm, accessCode, uriInfo);
-                return forwardToForm(Pages.LOGIN_VERIFY_EMAIL);
+                return forwardToActionForm(Pages.LOGIN_VERIFY_EMAIL, Messages.ACTION_WARN_EMAIL);
             default:
                 return Response.serverError().build();
         }
@@ -103,7 +105,6 @@ public class FormFlows {
     }
 
     private Response forwardToForm(String template, FormService.FormServiceDataBean formDataBean) {
-        formDataBean.setErrorType(errorType == null ? ErrorType.ERROR : errorType);
 
         // Getting URI needed by form processing service
         ResteasyUriInfo uriInfo = request.getUri();
@@ -143,8 +144,21 @@ public class FormFlows {
     private Response forwardToForm(String template) {
 
         FormService.FormServiceDataBean formDataBean = new FormService.FormServiceDataBean(realm, userModel, formData, error);
+        formDataBean.setMessageType(messageType);
+
         return forwardToForm(template, formDataBean);
+    }
+
+    private Response forwardToActionForm(String template, String warningSummary) {
+
+        // If no other message is set, notify user about required action in the warning window
+        // so it's clear that this is a req. action form not a login form
+        if (error == null){
+            messageType = MessageType.WARNING;
+            error = warningSummary;
+        }
 
+        return forwardToForm(template);
     }
 
     public Response forwardToLogin() {
@@ -202,8 +216,8 @@ public class FormFlows {
         return this;
     }
 
-    public FormFlows setErrorType(ErrorType errorType) {
-        this.errorType = errorType;
+    public FormFlows setErrorType(MessageType errorType) {
+        this.messageType = errorType;
         return this;
     }
 
diff --git a/services/src/main/java/org/keycloak/services/resources/RequiredActionsService.java b/services/src/main/java/org/keycloak/services/resources/RequiredActionsService.java
index 1517b79..67a241e 100755
--- a/services/src/main/java/org/keycloak/services/resources/RequiredActionsService.java
+++ b/services/src/main/java/org/keycloak/services/resources/RequiredActionsService.java
@@ -88,6 +88,12 @@ public class RequiredActionsService {
         }
 
         UserModel user = getUser(accessCode);
+
+        String error = Validation.validateUpdateProfileForm(formData);
+        if (error != null) {
+            return Flows.forms(realm, request, uriInfo).setError(error).forwardToAction(RequiredAction.UPDATE_PROFILE);
+        }
+
         user.setFirstName(formData.getFirst("firstName"));
         user.setLastName(formData.getFirst("lastName"));
         user.setEmail(formData.getFirst("email"));
@@ -146,15 +152,14 @@ public class RequiredActionsService {
 
         UserModel user = getUser(accessCode);
 
-        String password = formData.getFirst("password");
         String passwordNew = formData.getFirst("password-new");
         String passwordConfirm = formData.getFirst("password-confirm");
 
         FormFlows forms = Flows.forms(realm, request, uriInfo).setUser(user);
         if (Validation.isEmpty(passwordNew)) {
-            forms.setError(Messages.MISSING_PASSWORD).forwardToAction(RequiredAction.UPDATE_PASSWORD);
+            return forms.setError(Messages.MISSING_PASSWORD).forwardToAction(RequiredAction.UPDATE_PASSWORD);
         } else if (!passwordNew.equals(passwordConfirm)) {
-            forms.setError(Messages.MISSING_PASSWORD).forwardToAction(RequiredAction.UPDATE_PASSWORD);
+            return forms.setError(Messages.NOTMATCH_PASSWORD).forwardToAction(RequiredAction.UPDATE_PASSWORD);
         }
 
         UserCredentialModel credentials = new UserCredentialModel();
@@ -257,7 +262,7 @@ public class RequiredActionsService {
 
         new EmailSender().sendPasswordReset(user, realm, accessCode, uriInfo);
 
-        return Flows.forms(realm, request, uriInfo).setError("emailSent").setErrorType(FormFlows.ErrorType.SUCCESS)
+        return Flows.forms(realm, request, uriInfo).setError("emailSent").setErrorType(FormFlows.MessageType.SUCCESS)
                 .forwardToPasswordReset();
     }
 
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 5a71f0d..c652849 100755
--- a/services/src/main/java/org/keycloak/services/validation/Validation.java
+++ b/services/src/main/java/org/keycloak/services/validation/Validation.java
@@ -38,6 +38,22 @@ public class Validation {
         return null;
     }
 
+    public static String validateUpdateProfileForm(MultivaluedMap<String, String> formData) {
+        if (isEmpty(formData.getFirst("firstName"))) {
+            return Messages.MISSING_FIRST_NAME;
+        }
+
+        if (isEmpty(formData.getFirst("lastName"))) {
+            return Messages.MISSING_LAST_NAME;
+        }
+
+        if (isEmpty(formData.getFirst("email"))) {
+            return Messages.MISSING_EMAIL;
+        }
+
+        return null;
+    }
+
     public static boolean isEmpty(String s) {
         return s == null || s.length() == 0;
     }
diff --git a/testsuite/integration/src/test/java/org/keycloak/testsuite/actions/RequiredActionUpdateProfileTest.java b/testsuite/integration/src/test/java/org/keycloak/testsuite/actions/RequiredActionUpdateProfileTest.java
index 08a2bfa..c567e99 100755
--- a/testsuite/integration/src/test/java/org/keycloak/testsuite/actions/RequiredActionUpdateProfileTest.java
+++ b/testsuite/integration/src/test/java/org/keycloak/testsuite/actions/RequiredActionUpdateProfileTest.java
@@ -44,8 +44,8 @@ import org.openqa.selenium.WebDriver;
  */
 public class RequiredActionUpdateProfileTest {
 
-    @ClassRule
-    public static KeycloakRule keycloakRule = new KeycloakRule(new KeycloakSetup() {
+    @Rule
+    public KeycloakRule keycloakRule = new KeycloakRule(new KeycloakSetup() {
 
         @Override
         public void config(RealmManager manager, RealmModel defaultRealm, RealmModel appRealm) {
@@ -83,4 +83,50 @@ public class RequiredActionUpdateProfileTest {
         Assert.assertEquals(RequestType.AUTH_RESPONSE, appPage.getRequestType());
     }
 
+    @Test
+    public void updateProfileMissingFirstName() {
+        loginPage.open();
+
+        loginPage.login("test-user@localhost", "password");
+
+        updateProfilePage.assertCurrent();
+
+        updateProfilePage.update("", "New last", "new@email.com");
+
+        updateProfilePage.assertCurrent();
+
+        Assert.assertEquals("Please specify first name", updateProfilePage.getError());
+    }
+
+    @Test
+    public void updateProfileMissingLastName() {
+        loginPage.open();
+
+        loginPage.login("test-user@localhost", "password");
+
+        updateProfilePage.assertCurrent();
+
+        updateProfilePage.update("New first", "", "new@email.com");
+
+        updateProfilePage.assertCurrent();
+
+        Assert.assertEquals("Please specify last name", updateProfilePage.getError());
+    }
+
+    @Test
+    public void updateProfileMissingEmail() {
+        loginPage.open();
+
+        loginPage.login("test-user@localhost", "password");
+
+        updateProfilePage.assertCurrent();
+
+        updateProfilePage.update("New first", "New last", "");
+
+        updateProfilePage.assertCurrent();
+
+        Assert.assertEquals("Please specify email", updateProfilePage.getError());
+    }
+
+
 }
diff --git a/testsuite/integration/src/test/java/org/keycloak/testsuite/forms/ResetPasswordTest.java b/testsuite/integration/src/test/java/org/keycloak/testsuite/forms/ResetPasswordTest.java
index 9b5ca0f..396f3d9 100644
--- a/testsuite/integration/src/test/java/org/keycloak/testsuite/forms/ResetPasswordTest.java
+++ b/testsuite/integration/src/test/java/org/keycloak/testsuite/forms/ResetPasswordTest.java
@@ -123,7 +123,7 @@ public class ResetPasswordTest {
         resetPasswordPage.assertCurrent();
 
         Assert.assertNotEquals("Success!", resetPasswordPage.getMessage());
-        Assert.assertEquals("Error!", resetPasswordPage.getMessage());
+        Assert.assertEquals("Invalid username or email.", resetPasswordPage.getMessage());
     }
 
     @Test
@@ -138,7 +138,7 @@ public class ResetPasswordTest {
         resetPasswordPage.assertCurrent();
 
         Assert.assertNotEquals("Success!", resetPasswordPage.getMessage());
-        Assert.assertEquals("Error!", resetPasswordPage.getMessage());
+        Assert.assertEquals("Invalid username or email.", resetPasswordPage.getMessage());
     }
 
 }