keycloak-aplcache

Details

diff --git a/services/src/main/java/org/keycloak/authentication/requiredactions/UpdateProfile.java b/services/src/main/java/org/keycloak/authentication/requiredactions/UpdateProfile.java
index ac7862b..9630f3b 100755
--- a/services/src/main/java/org/keycloak/authentication/requiredactions/UpdateProfile.java
+++ b/services/src/main/java/org/keycloak/authentication/requiredactions/UpdateProfile.java
@@ -63,7 +63,25 @@ public class UpdateProfile implements RequiredActionProvider, RequiredActionFact
         }
 
         if (realm.isEditUsernameAllowed()) {
-            user.setUsername(formData.getFirst("username"));
+            String username = formData.getFirst("username");
+            String oldUsername = user.getUsername();
+
+            boolean usernameChanged = oldUsername != null ? !oldUsername.equals(username) : username != null;
+
+            if (usernameChanged) {
+
+                if (session.users().getUserByUsername(username, realm) != null) {
+                    Response challenge = context.form()
+                            .setError(Messages.USERNAME_EXISTS)
+                            .setFormData(formData)
+                            .createResponse(UserModel.RequiredAction.UPDATE_PROFILE);
+                    context.challenge(challenge);
+                    return;
+                }
+
+                user.setUsername(username);
+            }
+
         }
 
         user.setFirstName(formData.getFirst("firstName"));
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 531ee8a..545ce0c 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
@@ -248,6 +248,29 @@ public class RequiredActionUpdateProfileTest {
     }
 
     @Test
+    public void updateProfileDuplicateUsername() {
+        loginPage.open();
+
+        loginPage.login("john-doh@localhost", "password");
+
+        updateProfilePage.assertCurrent();
+
+        updateProfilePage.update("New first", "New last", "new@email.com", "test-user@localhost");
+
+        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("new@email.com", updateProfilePage.getEmail());
+        Assert.assertEquals("", updateProfilePage.getUsername());
+
+        Assert.assertEquals("Username already exists.", updateProfilePage.getError());
+
+        events.assertEmpty();
+    }
+
+    @Test
     public void updateProfileDuplicatedEmail() {
         loginPage.open();