keycloak-memoizeit

Changes

Details

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 f80909e..8be620d 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
@@ -32,6 +32,53 @@
                     <input type="text" id="lastName" name="lastName" value="${(user.lastName!'')?html}" class="${properties.kcInputClass!}" />
                 </div>
             </div>
+            
+            <div class="form-group">
+                <div class="${properties.kcLabelWrapperClass!}">
+                    <label for="user.attributes.street" class="${properties.kcLabelClass!}">${msg("street")}</label>
+                </div>
+
+                <div class="${properties.kcInputWrapperClass!}">
+                    <input type="text" class="${properties.kcInputClass!}"  id="user.attributes.street" name="user.attributes.street" value="${(user.attributes.street!'')?html}"/>
+                </div>
+            </div>
+            <div class="form-group">
+                <div class="${properties.kcLabelWrapperClass!}">
+                    <label for="user.attributes.locality" class="${properties.kcLabelClass!}">${msg("locality")}</label>
+                </div>
+
+                <div class="${properties.kcInputWrapperClass!}">
+                    <input type="text" class="${properties.kcInputClass!}"  id="user.attributes.locality" name="user.attributes.locality" value="${(user.attributes.locality!'')?html}"/>
+                </div>
+            </div>
+            <div class="form-group">
+                <div class="${properties.kcLabelWrapperClass!}">
+                    <label for="user.attributes.region" class="${properties.kcLabelClass!}">${msg("region")}</label>
+                </div>
+
+                <div class="${properties.kcInputWrapperClass!}">
+                    <input type="text" class="${properties.kcInputClass!}"  id="user.attributes.region" name="user.attributes.region" value="${(user.attributes.region!'')?html}"/>
+                </div>
+            </div>
+            <div class="form-group">
+                <div class="${properties.kcLabelWrapperClass!}">
+                    <label for="user.attributes.postal_code" class="${properties.kcLabelClass!}">${msg("postal_code")}</label>
+                </div>
+
+                <div class="${properties.kcInputWrapperClass!}">
+                    <input type="text" class="${properties.kcInputClass!}"  id="user.attributes.postal_code" name="user.attributes.postal_code" value="${(user.attributes.postal_code!'')?html}"/>
+                </div>
+            </div>
+            <div class="form-group">
+                <div class="${properties.kcLabelWrapperClass!}">
+                    <label for="user.attributes.country" class="${properties.kcLabelClass!}">${msg("country")}</label>
+                </div>
+
+                <div class="${properties.kcInputWrapperClass!}">
+                    <input type="text" class="${properties.kcInputClass!}"  id="user.attributes.country" name="user.attributes.country" value="${(user.attributes.country!'')?html}"/>
+                </div>
+            </div>
+            
 
             <div class="${properties.kcFormGroupClass!}">
                 <div id="kc-form-options" class="${properties.kcFormOptionsClass!}">
diff --git a/forms/common-themes/src/main/resources/theme/base/login/register.ftl b/forms/common-themes/src/main/resources/theme/base/login/register.ftl
index 4ccd0bc..3247305 100755
--- a/forms/common-themes/src/main/resources/theme/base/login/register.ftl
+++ b/forms/common-themes/src/main/resources/theme/base/login/register.ftl
@@ -68,7 +68,7 @@
                 </div>
 
                 <div class="${properties.kcInputWrapperClass!}">
-                    <input type="text" class="${properties.kcInputClass!}"  id="user.attributes.street" name="user.attributes.street"/>
+                    <input type="text" class="${properties.kcInputClass!}"  id="user.attributes.street" name="user.attributes.street" value="${(register.formData['user.attributes.street']!'')?html}"/>
                 </div>
             </div>
             <div class="form-group">
@@ -77,7 +77,7 @@
                 </div>
 
                 <div class="${properties.kcInputWrapperClass!}">
-                    <input type="text" class="${properties.kcInputClass!}"  id="user.attributes.locality" name="user.attributes.locality"/>
+                    <input type="text" class="${properties.kcInputClass!}"  id="user.attributes.locality" name="user.attributes.locality" value="${(register.formData['user.attributes.locality']!'')?html}"/>
                 </div>
             </div>
             <div class="form-group">
@@ -86,7 +86,7 @@
                 </div>
 
                 <div class="${properties.kcInputWrapperClass!}">
-                    <input type="text" class="${properties.kcInputClass!}"  id="user.attributes.region" name="user.attributes.region"/>
+                    <input type="text" class="${properties.kcInputClass!}"  id="user.attributes.region" name="user.attributes.region" value="${(register.formData['user.attributes.region']!'')?html}"/>
                 </div>
             </div>
             <div class="form-group">
@@ -95,7 +95,7 @@
                 </div>
 
                 <div class="${properties.kcInputWrapperClass!}">
-                    <input type="text" class="${properties.kcInputClass!}"  id="user.attributes.postal_code" name="user.attributes.postal_code"/>
+                    <input type="text" class="${properties.kcInputClass!}"  id="user.attributes.postal_code" name="user.attributes.postal_code" value="${(register.formData['user.attributes.postal_code']!'')?html}"/>
                 </div>
             </div>
             <div class="form-group">
@@ -104,7 +104,7 @@
                 </div>
 
                 <div class="${properties.kcInputWrapperClass!}">
-                    <input type="text" class="${properties.kcInputClass!}"  id="user.attributes.country" name="user.attributes.country"/>
+                    <input type="text" class="${properties.kcInputClass!}"  id="user.attributes.country" name="user.attributes.country" value="${(register.formData['user.attributes.country']!'')?html}"/>
                 </div>
             </div>
             <#if recaptchaRequired??>
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 0b74d1e..fc8d9b0 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
@@ -251,7 +251,7 @@ public class FreeMarkerLoginFormsProvider implements LoginFormsProvider {
                 attributes.put("totp", new TotpBean(realm, user, baseUri));
                 break;
             case LOGIN_UPDATE_PROFILE:
-                attributes.put("user", new ProfileBean(user));
+                attributes.put("user", new ProfileBean(user, formData));
                 break;
             case REGISTER:
                 attributes.put("register", new RegisterBean(formData));
diff --git a/forms/login-freemarker/src/main/java/org/keycloak/login/freemarker/model/ProfileBean.java b/forms/login-freemarker/src/main/java/org/keycloak/login/freemarker/model/ProfileBean.java
index bb34c46..6f73cc5 100755
--- a/forms/login-freemarker/src/main/java/org/keycloak/login/freemarker/model/ProfileBean.java
+++ b/forms/login-freemarker/src/main/java/org/keycloak/login/freemarker/model/ProfileBean.java
@@ -21,29 +21,68 @@
  */
 package org.keycloak.login.freemarker.model;
 
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import javax.ws.rs.core.MultivaluedMap;
+
+import org.jboss.logging.Logger;
 import org.keycloak.models.UserModel;
 
 /**
  * @author <a href="mailto:sthorger@redhat.com">Stian Thorgersen</a>
+ * @author Vlastimil Elias (velias at redhat dot com)
  */
 public class ProfileBean {
 
+    private static final Logger logger = Logger.getLogger(ProfileBean.class);
+
     private UserModel user;
+    private MultivaluedMap<String, String> formData;
+
+    private final Map<String, String> attributes = new HashMap<>();
 
-    public ProfileBean(UserModel user){
+    public ProfileBean(UserModel user, MultivaluedMap<String, String> formData) {
         this.user = user;
+        this.formData = formData;
+
+        if (user.getAttributes() != null) {
+            for (Map.Entry<String, List<String>> attr : user.getAttributes().entrySet()) {
+                List<String> attrValue = attr.getValue();
+                if (attrValue != null && attrValue.size() > 0) {
+                    attributes.put(attr.getKey(), attrValue.get(0));
+                }
+
+                if (attrValue != null && attrValue.size() > 1) {
+                    logger.warnf("There are more values for attribute '%s' of user '%s' . Will display just first value", attr.getKey(), user.getUsername());
+                }
+            }
+        }
+        if (formData != null) {
+            for (String key : formData.keySet()) {
+                if (key.startsWith("user.attributes.")) {
+                    String attribute = key.substring("user.attributes.".length());
+                    attributes.put(attribute, formData.getFirst(key));
+                }
+            }
+        }
+
     }
 
     public String getFirstName() {
-        return user.getFirstName();
+        return formData != null ? formData.getFirst("firstName") : user.getFirstName();
     }
 
     public String getLastName() {
-        return user.getLastName();
+        return formData != null ? formData.getFirst("lastName") : user.getLastName();
     }
 
     public String getEmail() {
-        return user.getEmail();
+        return formData != null ? formData.getFirst("email") : user.getEmail();
     }
 
+    public Map<String, String> getAttributes() {
+        return attributes;
+    }
 }
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 d87ad68..f097a3d 100755
--- a/services/src/main/java/org/keycloak/services/resources/LoginActionsService.java
+++ b/services/src/main/java/org/keycloak/services/resources/LoginActionsService.java
@@ -535,6 +535,7 @@ public class LoginActionsService {
                     .setClientSessionCode(accessCode.getCode())
                     .setUser(user)
                     .setErrors(errors)
+                    .setFormData(formData)
                     .createResponse(RequiredAction.UPDATE_PROFILE);
         }
 
@@ -555,6 +556,7 @@ public class LoginActionsService {
                         .setUser(user)
                         .setError(Messages.EMAIL_EXISTS)
                         .setClientSessionCode(accessCode.getCode())
+                        .setFormData(formData)
                         .createResponse(RequiredAction.UPDATE_PROFILE);
             }
 
diff --git a/testsuite/integration/src/test/java/org/keycloak/testsuite/account/AccountTest.java b/testsuite/integration/src/test/java/org/keycloak/testsuite/account/AccountTest.java
index 95d644e..12ec029 100755
--- a/testsuite/integration/src/test/java/org/keycloak/testsuite/account/AccountTest.java
+++ b/testsuite/integration/src/test/java/org/keycloak/testsuite/account/AccountTest.java
@@ -562,7 +562,7 @@ public class AccountTest {
             loginPage.open();
             loginPage.clickRegister();
 
-            registerPage.register("view", "log", "view-log@localhost", "view-log", "password", "password");
+            registerPage.register("view", "log", "view-log@localhost", "view-log", "password", "password", null);
 
             expectedEvents.add(events.poll());
             expectedEvents.add(events.poll());
@@ -609,7 +609,7 @@ public class AccountTest {
         loginPage.open();
         loginPage.clickRegister();
 
-        registerPage.register("view", "sessions", "view-sessions@localhost", "view-sessions", "password", "password");
+        registerPage.register("view", "sessions", "view-sessions@localhost", "view-sessions", "password", "password", null);
 
         Event registerEvent = events.expectRegister("view-sessions", "view-sessions@localhost").assertEvent();
         String userId = registerEvent.getUserId();
diff --git a/testsuite/integration/src/test/java/org/keycloak/testsuite/actions/RequiredActionEmailVerificationTest.java b/testsuite/integration/src/test/java/org/keycloak/testsuite/actions/RequiredActionEmailVerificationTest.java
index a9c0c58..38760b9 100755
--- a/testsuite/integration/src/test/java/org/keycloak/testsuite/actions/RequiredActionEmailVerificationTest.java
+++ b/testsuite/integration/src/test/java/org/keycloak/testsuite/actions/RequiredActionEmailVerificationTest.java
@@ -145,7 +145,7 @@ public class RequiredActionEmailVerificationTest {
     public void verifyEmailRegister() throws IOException, MessagingException {
         loginPage.open();
         loginPage.clickRegister();
-        registerPage.register("firstName", "lastName", "email@mail.com", "verifyEmail", "password", "password");
+        registerPage.register("firstName", "lastName", "email@mail.com", "verifyEmail", "password", "password", null);
 
         String userId = events.expectRegister("verifyEmail", "email@mail.com").assertEvent().getUserId();
 
diff --git a/testsuite/integration/src/test/java/org/keycloak/testsuite/actions/RequiredActionMultipleActionsTest.java b/testsuite/integration/src/test/java/org/keycloak/testsuite/actions/RequiredActionMultipleActionsTest.java
index 4d16a1b..341a440 100755
--- a/testsuite/integration/src/test/java/org/keycloak/testsuite/actions/RequiredActionMultipleActionsTest.java
+++ b/testsuite/integration/src/test/java/org/keycloak/testsuite/actions/RequiredActionMultipleActionsTest.java
@@ -121,7 +121,7 @@ public class RequiredActionMultipleActionsTest {
     }
 
     public String updateProfile(String sessionId) {
-        updateProfilePage.update("New first", "New last", "new@email.com");
+        updateProfilePage.update("New first", "New last", "new@email.com", null);
 
         AssertEvents.ExpectedEvent expectedEvent = events.expectRequiredAction(EventType.UPDATE_PROFILE);
         if (sessionId != null) {
diff --git a/testsuite/integration/src/test/java/org/keycloak/testsuite/actions/RequiredActionTotpSetupTest.java b/testsuite/integration/src/test/java/org/keycloak/testsuite/actions/RequiredActionTotpSetupTest.java
index c904918..a4206aa 100755
--- a/testsuite/integration/src/test/java/org/keycloak/testsuite/actions/RequiredActionTotpSetupTest.java
+++ b/testsuite/integration/src/test/java/org/keycloak/testsuite/actions/RequiredActionTotpSetupTest.java
@@ -117,7 +117,7 @@ public class RequiredActionTotpSetupTest {
     public void setupTotpRegister() {
         loginPage.open();
         loginPage.clickRegister();
-        registerPage.register("firstName", "lastName", "email@mail.com", "setupTotp", "password", "password");
+        registerPage.register("firstName", "lastName", "email@mail.com", "setupTotp", "password", "password", null);
 
         String userId = events.expectRegister("setupTotp", "email@mail.com").assertEvent().getUserId();
 
@@ -170,7 +170,7 @@ public class RequiredActionTotpSetupTest {
         // Register new user
         loginPage.open();
         loginPage.clickRegister();
-        registerPage.register("firstName2", "lastName2", "email2@mail.com", "setupTotp2", "password2", "password2");
+        registerPage.register("firstName2", "lastName2", "email2@mail.com", "setupTotp2", "password2", "password2", null);
 
         String userId = events.expectRegister("setupTotp2", "email2@mail.com").assertEvent().getUserId();
 
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 e5e4c3c..b61ee17 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
@@ -30,6 +30,7 @@ import org.keycloak.events.Details;
 import org.keycloak.events.EventType;
 import org.keycloak.models.RealmModel;
 import org.keycloak.models.UserModel;
+import org.keycloak.representations.idm.UserRepresentation;
 import org.keycloak.services.managers.RealmManager;
 import org.keycloak.testsuite.AssertEvents;
 import org.keycloak.testsuite.pages.AppPage;
@@ -86,7 +87,7 @@ public class RequiredActionUpdateProfileTest {
 
         updateProfilePage.assertCurrent();
 
-        updateProfilePage.update("New first", "New last", "new@email.com");
+        updateProfilePage.update("New first", "New last", "new@email.com", "mystreet");
 
         String sessionId = events.expectRequiredAction(EventType.UPDATE_PROFILE).assertEvent().getSessionId();
         events.expectRequiredAction(EventType.UPDATE_EMAIL).session(sessionId).detail(Details.PREVIOUS_EMAIL, "test-user@localhost").detail(Details.UPDATED_EMAIL, "new@email.com").assertEvent();
@@ -94,6 +95,13 @@ public class RequiredActionUpdateProfileTest {
         Assert.assertEquals(RequestType.AUTH_RESPONSE, appPage.getRequestType());
 
         events.expectLogin().session(sessionId).assertEvent();
+
+        // assert user is really updated in persistent store
+        UserRepresentation user = keycloakRule.getUser("test", "test-user@localhost");
+        Assert.assertEquals("New first", user.getFirstName());
+        Assert.assertEquals("New last", user.getLastName());
+        Assert.assertEquals("new@email.com", user.getEmail());
+        Assert.assertEquals("mystreet", user.getAttributesAsListValues().get("street").get(0));
     }
 
     @Test
@@ -104,10 +112,16 @@ public class RequiredActionUpdateProfileTest {
 
         updateProfilePage.assertCurrent();
 
-        updateProfilePage.update("", "New last", "new@email.com");
+        updateProfilePage.update("", "New last", "new@email.com", "mystreet");
 
         updateProfilePage.assertCurrent();
 
+        // assert that form holds submitted values during validation error
+        Assert.assertEquals("", updateProfilePage.getFirstName());
+        Assert.assertEquals("New last", updateProfilePage.getLastName());
+        Assert.assertEquals("new@email.com", updateProfilePage.getEmail());
+        Assert.assertEquals("mystreet", updateProfilePage.getAttributeStreet());
+
         Assert.assertEquals("Please specify first name.", updateProfilePage.getError());
 
         events.assertEmpty();
@@ -121,10 +135,16 @@ public class RequiredActionUpdateProfileTest {
 
         updateProfilePage.assertCurrent();
 
-        updateProfilePage.update("New first", "", "new@email.com");
+        updateProfilePage.update("New first", "", "new@email.com", null);
 
         updateProfilePage.assertCurrent();
 
+        // assert that form holds submitted values during validation error
+        Assert.assertEquals("New first", updateProfilePage.getFirstName());
+        Assert.assertEquals("", updateProfilePage.getLastName());
+        Assert.assertEquals("new@email.com", updateProfilePage.getEmail());
+        Assert.assertEquals("", updateProfilePage.getAttributeStreet());
+
         Assert.assertEquals("Please specify last name.", updateProfilePage.getError());
 
         events.assertEmpty();
@@ -138,16 +158,45 @@ public class RequiredActionUpdateProfileTest {
 
         updateProfilePage.assertCurrent();
 
-        updateProfilePage.update("New first", "New last", "");
+        updateProfilePage.update("New first", "New last", "", "mystreet");
 
         updateProfilePage.assertCurrent();
 
+        // assert that form holds submitted values during validation error
+        Assert.assertEquals("New first", updateProfilePage.getFirstName());
+        Assert.assertEquals("New last", updateProfilePage.getLastName());
+        Assert.assertEquals("", updateProfilePage.getEmail());
+        Assert.assertEquals("mystreet", updateProfilePage.getAttributeStreet());
+
         Assert.assertEquals("Please specify email.", updateProfilePage.getError());
 
         events.assertEmpty();
     }
 
     @Test
+    public void updateProfileInvalidEmail() {
+        loginPage.open();
+
+        loginPage.login("test-user@localhost", "password");
+
+        updateProfilePage.assertCurrent();
+
+        updateProfilePage.update("New first", "New last", "invalidemail", null);
+
+        updateProfilePage.assertCurrent();
+
+        // assert that form holds submitted values during validation error
+        Assert.assertEquals("New first", updateProfilePage.getFirstName());
+        Assert.assertEquals("New last", updateProfilePage.getLastName());
+        Assert.assertEquals("invalidemail", updateProfilePage.getEmail());
+        Assert.assertEquals("", updateProfilePage.getAttributeStreet());
+
+        Assert.assertEquals("Invalid email address.", updateProfilePage.getError());
+
+        events.assertEmpty();
+    }
+
+    @Test
     public void updateProfileDuplicatedEmail() {
         loginPage.open();
 
@@ -155,10 +204,15 @@ public class RequiredActionUpdateProfileTest {
 
         updateProfilePage.assertCurrent();
 
-        updateProfilePage.update("New first", "New last", "keycloak-user@localhost");
+        updateProfilePage.update("New first", "New last", "keycloak-user@localhost", null);
 
         updateProfilePage.assertCurrent();
 
+        // assert that form holds submitted values during validation error
+        Assert.assertEquals("New first", updateProfilePage.getFirstName());
+        Assert.assertEquals("New last", updateProfilePage.getLastName());
+        Assert.assertEquals("keycloak-user@localhost", updateProfilePage.getEmail());
+
         Assert.assertEquals("Email already exists.", updateProfilePage.getError());
 
         events.assertEmpty();
diff --git a/testsuite/integration/src/test/java/org/keycloak/testsuite/broker/AbstractIdentityProviderTest.java b/testsuite/integration/src/test/java/org/keycloak/testsuite/broker/AbstractIdentityProviderTest.java
index 8ce5c7c..e3dabc8 100755
--- a/testsuite/integration/src/test/java/org/keycloak/testsuite/broker/AbstractIdentityProviderTest.java
+++ b/testsuite/integration/src/test/java/org/keycloak/testsuite/broker/AbstractIdentityProviderTest.java
@@ -451,7 +451,7 @@ public abstract class AbstractIdentityProviderTest {
         doAfterProviderAuthentication();
 
         this.updateProfilePage.assertCurrent();
-        this.updateProfilePage.update("Test", "User", "psilva@redhat.com");
+        this.updateProfilePage.update("Test", "User", "psilva@redhat.com", null);
 
         WebElement element = this.driver.findElement(By.className("kc-feedback-text"));
 
@@ -460,7 +460,7 @@ public abstract class AbstractIdentityProviderTest {
         assertEquals("Email already exists.", element.getText());
 
         this.updateProfilePage.assertCurrent();
-        this.updateProfilePage.update("Test", "User", "test-user@redhat.com");
+        this.updateProfilePage.update("Test", "User", "test-user@redhat.com", null);
 
         assertTrue(this.driver.getCurrentUrl().startsWith("http://localhost:8081/test-app"));
 
@@ -724,7 +724,7 @@ public abstract class AbstractIdentityProviderTest {
 
             // update profile
             this.updateProfilePage.assertCurrent();
-            this.updateProfilePage.update(userFirstName, userLastName, userEmail);
+            this.updateProfilePage.update(userFirstName, userLastName, userEmail, null);
         }
 
     }
diff --git a/testsuite/integration/src/test/java/org/keycloak/testsuite/federation/FederationProvidersIntegrationTest.java b/testsuite/integration/src/test/java/org/keycloak/testsuite/federation/FederationProvidersIntegrationTest.java
index 8c33f9f..943adaf 100755
--- a/testsuite/integration/src/test/java/org/keycloak/testsuite/federation/FederationProvidersIntegrationTest.java
+++ b/testsuite/integration/src/test/java/org/keycloak/testsuite/federation/FederationProvidersIntegrationTest.java
@@ -296,12 +296,12 @@ public class FederationProvidersIntegrationTest {
         registerPage.assertCurrent();
 
         // check existing username
-        registerPage.register("firstName", "lastName", "email@mail.cz", "existing", "Password1", "Password1");
+        registerPage.register("firstName", "lastName", "email@mail.cz", "existing", "Password1", "Password1", null);
         registerPage.assertCurrent();
         Assert.assertEquals("Username already exists.", registerPage.getError());
 
         // Check existing email
-        registerPage.register("firstName", "lastName", "existing@email.org", "nonExisting", "Password1", "Password1");
+        registerPage.register("firstName", "lastName", "existing@email.org", "nonExisting", "Password1", "Password1", null);
         registerPage.assertCurrent();
         Assert.assertEquals("Email already exists.", registerPage.getError());
     }
@@ -312,7 +312,7 @@ public class FederationProvidersIntegrationTest {
         loginPage.clickRegister();
         registerPage.assertCurrent();
 
-        registerPage.register("firstName", "lastName", "email2@check.cz", "registerUserSuccess2", "Password1", "Password1");
+        registerPage.register("firstName", "lastName", "email2@check.cz", "registerUserSuccess2", "Password1", "Password1", null);
         Assert.assertEquals(AppPage.RequestType.AUTH_RESPONSE, appPage.getRequestType());
 
         KeycloakSession session = keycloakRule.startSession();
diff --git a/testsuite/integration/src/test/java/org/keycloak/testsuite/forms/RegisterTest.java b/testsuite/integration/src/test/java/org/keycloak/testsuite/forms/RegisterTest.java
index d134378..63a754e 100755
--- a/testsuite/integration/src/test/java/org/keycloak/testsuite/forms/RegisterTest.java
+++ b/testsuite/integration/src/test/java/org/keycloak/testsuite/forms/RegisterTest.java
@@ -30,11 +30,9 @@ import org.keycloak.models.KeycloakSession;
 import org.keycloak.models.PasswordPolicy;
 import org.keycloak.models.RealmModel;
 import org.keycloak.models.UserModel;
-import org.keycloak.representations.IDToken;
 import org.keycloak.services.managers.RealmManager;
 import org.keycloak.testsuite.AssertEvents;
 import org.keycloak.testsuite.OAuthClient;
-import org.keycloak.testsuite.broker.util.UserSessionStatusServlet.UserSessionStatus;
 import org.keycloak.testsuite.pages.AppPage;
 import org.keycloak.testsuite.pages.AppPage.RequestType;
 import org.keycloak.testsuite.pages.LoginPage;
@@ -79,11 +77,20 @@ public class RegisterTest {
         loginPage.clickRegister();
         registerPage.assertCurrent();
 
-        registerPage.register("firstName", "lastName", "registerExistingUser@email", "test-user@localhost", "password", "password");
+        registerPage.register("firstName", "lastName", "registerExistingUser@email", "test-user@localhost", "password", "password", "mystreet");
 
         registerPage.assertCurrent();
         Assert.assertEquals("Username already exists.", registerPage.getError());
 
+        // assert form keeps form fields on error
+        Assert.assertEquals("firstName", registerPage.getFirstName());
+        Assert.assertEquals("lastName", registerPage.getLastName());
+        Assert.assertEquals("", registerPage.getEmail());
+        Assert.assertEquals("", registerPage.getUsername());
+        Assert.assertEquals("", registerPage.getPassword());
+        Assert.assertEquals("", registerPage.getPasswordConfirm());
+        Assert.assertEquals("mystreet", registerPage.getAttributeStreet());
+
         events.expectRegister("test-user@localhost", "registerExistingUser@email")
                 .removeDetail(Details.EMAIL)
                 .user((String) null).error("username_in_use").assertEvent();
@@ -95,11 +102,20 @@ public class RegisterTest {
         loginPage.clickRegister();
         registerPage.assertCurrent();
 
-        registerPage.register("firstName", "lastName", "registerUserInvalidPasswordConfirm@email", "registerUserInvalidPasswordConfirm", "password", "invalid");
+        registerPage.register("firstName", "lastName", "registerUserInvalidPasswordConfirm@email", "registerUserInvalidPasswordConfirm", "password", "invalid", null);
 
         registerPage.assertCurrent();
         Assert.assertEquals("Password confirmation doesn't match.", registerPage.getError());
 
+        // assert form keeps form fields on error
+        Assert.assertEquals("firstName", registerPage.getFirstName());
+        Assert.assertEquals("lastName", registerPage.getLastName());
+        Assert.assertEquals("registerUserInvalidPasswordConfirm@email", registerPage.getEmail());
+        Assert.assertEquals("registerUserInvalidPasswordConfirm", registerPage.getUsername());
+        Assert.assertEquals("", registerPage.getPassword());
+        Assert.assertEquals("", registerPage.getPasswordConfirm());
+        Assert.assertEquals("", registerPage.getAttributeStreet());
+
         events.expectRegister("registerUserInvalidPasswordConfirm", "registerUserInvalidPasswordConfirm@email")
                 .removeDetail(Details.USERNAME)
                 .removeDetail(Details.EMAIL)
@@ -112,7 +128,7 @@ public class RegisterTest {
         loginPage.clickRegister();
         registerPage.assertCurrent();
 
-        registerPage.register("firstName", "lastName", "registerUserMissingPassword@email", "registerUserMissingPassword", null, null);
+        registerPage.register("firstName", "lastName", "registerUserMissingPassword@email", "registerUserMissingPassword", null, null, null);
 
         registerPage.assertCurrent();
         Assert.assertEquals("Please specify password.", registerPage.getError());
@@ -137,7 +153,7 @@ public class RegisterTest {
             loginPage.clickRegister();
             registerPage.assertCurrent();
 
-            registerPage.register("firstName", "lastName", "registerPasswordPolicy@email", "registerPasswordPolicy", "pass", "pass");
+            registerPage.register("firstName", "lastName", "registerPasswordPolicy@email", "registerPasswordPolicy", "pass", "pass", null);
 
             registerPage.assertCurrent();
             Assert.assertEquals("Invalid password: minimum length 8.", registerPage.getError());
@@ -147,7 +163,7 @@ public class RegisterTest {
                     .removeDetail(Details.EMAIL)
                     .user((String) null).error("invalid_registration").assertEvent();
 
-            registerPage.register("firstName", "lastName", "registerPasswordPolicy@email", "registerPasswordPolicy", "password", "password");
+            registerPage.register("firstName", "lastName", "registerPasswordPolicy@email", "registerPasswordPolicy", "password", "password", null);
             Assert.assertEquals(RequestType.AUTH_RESPONSE, appPage.getRequestType());
 
             String userId = events.expectRegister("registerPasswordPolicy", "registerPasswordPolicy@email").assertEvent().getUserId();
@@ -169,7 +185,7 @@ public class RegisterTest {
         loginPage.clickRegister();
         registerPage.assertCurrent();
 
-        registerPage.register("firstName", "lastName", "registerUserMissingUsername@email", null, "password", "password");
+        registerPage.register("firstName", "lastName", "registerUserMissingUsername@email", null, "password", "password", null);
 
         registerPage.assertCurrent();
         Assert.assertEquals("Please specify username.", registerPage.getError());
@@ -186,14 +202,14 @@ public class RegisterTest {
         loginPage.clickRegister();
         registerPage.assertCurrent();
 
-        registerPage.register("firstName", "lastName", null, "registerUserMissingEmail", "password", "password");
+        registerPage.register("firstName", "lastName", null, "registerUserMissingEmail", "password", "password", null);
         registerPage.assertCurrent();
         Assert.assertEquals("Please specify email.", registerPage.getError());
         events.expectRegister("registerUserMissingEmail", null)
                 .removeDetail("email")
                 .error("invalid_registration").assertEvent();
 
-        registerPage.register("firstName", "lastName", "registerUserInvalidEmailemail", "registerUserInvalidEmail", "password", "password");
+        registerPage.register("firstName", "lastName", "registerUserInvalidEmailemail", "registerUserInvalidEmail", "password", "password", null);
         registerPage.assertCurrent();
         Assert.assertEquals("Invalid email address.", registerPage.getError());
         events.expectRegister("registerUserInvalidEmail", "registerUserInvalidEmailemail")
@@ -206,7 +222,7 @@ public class RegisterTest {
         loginPage.clickRegister();
         registerPage.assertCurrent();
 
-        registerPage.register("firstName", "lastName", "registerUserSuccess@email", "registerUserSuccess", "password", "password");
+        registerPage.register("firstName", "lastName", "registerUserSuccess@email", "registerUserSuccess", "password", "password", "myStreet");
 
         Assert.assertEquals(RequestType.AUTH_RESPONSE, appPage.getRequestType());
 
@@ -218,6 +234,12 @@ public class RegisterTest {
         Assert.assertNotNull(user.getCreatedTimestamp());
         // test that timestamp is current with 10s tollerance
         Assert.assertTrue((System.currentTimeMillis() - user.getCreatedTimestamp()) < 10000);
+        // test user info is set from form
+        Assert.assertEquals("registerusersuccess", user.getUsername());
+        Assert.assertEquals("registerusersuccess@email", user.getEmail());
+        Assert.assertEquals("firstName", user.getFirstName());
+        Assert.assertEquals("lastName", user.getLastName());
+        Assert.assertEquals("myStreet", user.getAttribute("street").get(0));
     }
 
     protected UserModel getUser(String userId) {
diff --git a/testsuite/integration/src/test/java/org/keycloak/testsuite/pages/LoginUpdateProfilePage.java b/testsuite/integration/src/test/java/org/keycloak/testsuite/pages/LoginUpdateProfilePage.java
index 4445202..809150f 100644
--- a/testsuite/integration/src/test/java/org/keycloak/testsuite/pages/LoginUpdateProfilePage.java
+++ b/testsuite/integration/src/test/java/org/keycloak/testsuite/pages/LoginUpdateProfilePage.java
@@ -38,20 +38,25 @@ public class LoginUpdateProfilePage extends AbstractPage {
     @FindBy(id = "email")
     private WebElement emailInput;
 
+    @FindBy(id = "user.attributes.street")
+    private WebElement attributeStreetInput;
+
     @FindBy(css = "input[type=\"submit\"]")
     private WebElement submitButton;
 
     @FindBy(className = "feedback-error")
     private WebElement loginErrorMessage;
 
-    public void update(String firstName, String lastName, String email) {
+    public void update(String firstName, String lastName, String email, String attributeStreet) {
         firstNameInput.clear();
         firstNameInput.sendKeys(firstName);
         lastNameInput.clear();
         lastNameInput.sendKeys(lastName);
         emailInput.clear();
         emailInput.sendKeys(email);
-
+        attributeStreetInput.clear();
+        if (attributeStreet != null)
+            attributeStreetInput.sendKeys(attributeStreet);
         submitButton.click();
     }
 
@@ -71,6 +76,10 @@ public class LoginUpdateProfilePage extends AbstractPage {
         return emailInput.getAttribute("value");
     }
 
+    public String getAttributeStreet() {
+        return attributeStreetInput.getAttribute("value");
+    }
+
     public boolean isCurrent() {
         return driver.getTitle().equals("Update Account Information");
     }
diff --git a/testsuite/integration/src/test/java/org/keycloak/testsuite/pages/RegisterPage.java b/testsuite/integration/src/test/java/org/keycloak/testsuite/pages/RegisterPage.java
index 5904da1..0892b0f 100644
--- a/testsuite/integration/src/test/java/org/keycloak/testsuite/pages/RegisterPage.java
+++ b/testsuite/integration/src/test/java/org/keycloak/testsuite/pages/RegisterPage.java
@@ -50,6 +50,9 @@ public class RegisterPage extends AbstractPage {
 
     @FindBy(id = "password-confirm")
     private WebElement passwordConfirmInput;
+    
+    @FindBy(id = "user.attributes.street")
+    private WebElement attributeStreetInput;
 
     @FindBy(css = "input[type=\"submit\"]")
     private WebElement submitButton;
@@ -57,7 +60,7 @@ public class RegisterPage extends AbstractPage {
     @FindBy(className = "feedback-error")
     private WebElement loginErrorMessage;
 
-    public void register(String firstName, String lastName, String email, String username, String password, String passwordConfirm) {
+    public void register(String firstName, String lastName, String email, String username, String password, String passwordConfirm, String attributeStreet) {
         firstNameInput.clear();
         if (firstName != null) {
             firstNameInput.sendKeys(firstName);
@@ -88,6 +91,11 @@ public class RegisterPage extends AbstractPage {
             passwordConfirmInput.sendKeys(passwordConfirm);
         }
 
+        attributeStreetInput.clear();
+        if (attributeStreet != null) {
+            attributeStreetInput.sendKeys(attributeStreet);
+        }
+
         submitButton.click();
     }
 
@@ -147,6 +155,18 @@ public class RegisterPage extends AbstractPage {
         return usernameInput.getAttribute("value");
     }
 
+    public String getPassword() {
+        return passwordInput.getAttribute("value");
+    }
+
+    public String getPasswordConfirm() {
+        return passwordConfirmInput.getAttribute("value");
+    }
+
+    public String getAttributeStreet() {
+        return attributeStreetInput.getAttribute("value");
+    }
+
     public boolean isCurrent() {
         return driver.getTitle().equals("Register with test");
     }