[KEYCLOAK-16886] - Updating user account removes attributes

This commit is contained in:
Pedro Igor 2021-02-12 10:21:00 -03:00
parent bea3410357
commit ca2a761d4b
3 changed files with 64 additions and 1 deletions

View file

@ -390,7 +390,8 @@ public class AccountFormService extends AbstractSecuredLocalService {
}
try {
UserUpdateHelper.updateAccount(realm, user, updatedProfile);
// backward compatibility with old account console where attributes are not removed if missing
UserUpdateHelper.updateAccountOldConsole(realm, user, updatedProfile);
} catch (ReadOnlyException e) {
setReferrerOnPage();
return account.setError(Response.Status.BAD_REQUEST, Messages.READ_ONLY_USER).setProfileFormData(formData).createResponse(AccountPages.ACCOUNT);

View file

@ -57,6 +57,20 @@ public class UserUpdateHelper {
update(UserUpdateEvent.Account, realm, user, updatedProfile);
}
/**
* <p>This method should be used when account is updated through the old console where the behavior is different
* than when using the new Account REST API and console in regards to how user attributes are managed.
*
* @deprecated Remove this method as soon as the old console is no longer part of the distribution
* @param realm
* @param user
* @param updatedProfile
*/
@Deprecated
public static void updateAccountOldConsole(RealmModel realm, UserModel user, UserProfile updatedProfile) {
update(UserUpdateEvent.Account, realm, user, updatedProfile.getAttributes(), false);
}
public static void updateUserResource(RealmModel realm, UserModel user, UserProfile userRepresentationUserProfile, boolean removeExistingAttributes) {
update(UserUpdateEvent.UserResource, realm, user, userRepresentationUserProfile.getAttributes(), removeExistingAttributes);
}

View file

@ -76,6 +76,7 @@ import org.openqa.selenium.NoSuchElementException;
import org.openqa.selenium.WebDriver;
import java.util.Arrays;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
@ -92,6 +93,7 @@ import static org.hamcrest.Matchers.hasItems;
import static org.hamcrest.Matchers.hasSize;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertThat;
import static org.junit.Assert.assertTrue;
import static org.keycloak.testsuite.util.ServerURLs.AUTH_SERVER_SSL_REQUIRED;
@ -722,6 +724,52 @@ public class AccountFormServiceTest extends AbstractTestRealmKeycloakTest {
setEditUsernameAllowed(true);
}
@Test
public void changeProfileWithoutRemoveCustomAttributes() throws Exception {
setEditUsernameAllowed(false);
setRegistrationEmailAsUsername(false);
UserResource userResource = testRealm().users().get(userId);
UserRepresentation user = userResource.toRepresentation();
user.setAttributes(new HashMap<>());
user.getAttributes().put("custom", Arrays.asList("custom-value"));
userResource.update(user);
profilePage.open();
loginPage.login("test-user@localhost", "password");
events.expectLogin().client("account").detail(Details.REDIRECT_URI, getAccountRedirectUrl()).assertEvent();
Assert.assertEquals("test-user@localhost", profilePage.getUsername());
Assert.assertEquals("Tom", profilePage.getFirstName());
Assert.assertEquals("Brady", profilePage.getLastName());
Assert.assertEquals("test-user@localhost", profilePage.getEmail());
profilePage.updateProfile("New first", "New last", "new@email.com");
Assert.assertEquals("Your account has been updated.", profilePage.getSuccess());
Assert.assertEquals("test-user@localhost", profilePage.getUsername());
Assert.assertEquals("New first", profilePage.getFirstName());
Assert.assertEquals("New last", profilePage.getLastName());
Assert.assertEquals("new@email.com", profilePage.getEmail());
events.expectAccount(EventType.UPDATE_EMAIL).detail(Details.PREVIOUS_EMAIL, "test-user@localhost").detail(Details.UPDATED_EMAIL, "new@email.com").assertEvent();
events.expectAccount(EventType.UPDATE_PROFILE).assertEvent();
user = userResource.toRepresentation();
assertNotNull(user.getAttributes());
assertTrue(user.getAttributes().containsKey("custom"));
// reset user for other tests
profilePage.updateProfile("Tom", "Brady", "test-user@localhost");
events.clear();
// Revert
setEditUsernameAllowed(true);
}
@Test
public void changeProfileEmailAsUsernameEnabled() throws Exception {
setRegistrationEmailAsUsername(true);