[KEYCLOAK-17206] - Avoid removing attributes when updating user and profile

This commit is contained in:
Pedro Igor 2021-02-22 15:45:54 -03:00 committed by Marek Posolda
parent 6255ebe6b5
commit dbc6514bfc
4 changed files with 52 additions and 4 deletions

View file

@ -214,7 +214,7 @@ public class UserResource {
public static void updateUserFromRep(UserModel user, UserRepresentation rep, KeycloakSession session, boolean isUpdateExistingUser) {
boolean removeMissingRequiredActions = isUpdateExistingUser;
UserUpdateHelper.updateUserResource(session, user, rep, isUpdateExistingUser);
UserUpdateHelper.updateUserResource(session, user, rep, rep.getAttributes() != null);
if (rep.isEnabled() != null) user.setEnabled(rep.isEnabled());
if (rep.isEmailVerified() != null) user.setEmailVerified(rep.isEmailVerified());

View file

@ -51,11 +51,11 @@ public class UserUpdateHelper {
}
public static void updateIdpReview(RealmModel realm, UserModel userModelDelegate, UserProfile updatedProfile) {
update(UserUpdateEvent.IdpReview, realm, userModelDelegate, updatedProfile);
update(UserUpdateEvent.IdpReview, realm, userModelDelegate, updatedProfile.getAttributes(), false);
}
public static void updateUserProfile(RealmModel realm, UserModel user, UserProfile updatedProfile) {
update(UserUpdateEvent.UpdateProfile, realm, user, updatedProfile);
update(UserUpdateEvent.UpdateProfile, realm, user, updatedProfile.getAttributes(), false);
}
public static void updateAccount(RealmModel realm, UserModel user, UserProfile updatedProfile) {

View file

@ -22,6 +22,7 @@ import org.junit.Assert;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.keycloak.admin.client.resource.UserResource;
import org.keycloak.events.Details;
import org.keycloak.events.EventType;
import org.keycloak.models.UserModel;
@ -40,6 +41,9 @@ import org.keycloak.testsuite.util.UserBuilder;
import static org.junit.Assert.assertFalse;
import java.util.Arrays;
import java.util.HashMap;
/**
* @author <a href="mailto:sthorger@redhat.com">Stian Thorgersen</a>
*/
@ -321,4 +325,40 @@ public class RequiredActionUpdateProfileTest extends AbstractTestRealmKeycloakTe
Assert.assertEquals(backToAppLink, client.getBaseUrl());
}
@Test
public void updateProfileWithoutRemoveCustomAttributes() {
UserRepresentation userRep = ActionUtil.findUserWithAdminClient(adminClient, "test-user@localhost");
UserResource user = adminClient.realm("test").users().get(userRep.getId());
userRep.setAttributes(new HashMap<>());
userRep.getAttributes().put("custom", Arrays.asList("custom"));
user.update(userRep);
loginPage.open();
loginPage.login("test-user@localhost", "password");
updateProfilePage.assertCurrent();
assertFalse(updateProfilePage.isCancelDisplayed());
updateProfilePage.update("New first", "New last", "new@email.com", "test-user@localhost");
events.expectRequiredAction(EventType.UPDATE_EMAIL).detail(Details.PREVIOUS_EMAIL, "test-user@localhost").detail(Details.UPDATED_EMAIL, "new@email.com").assertEvent();
events.expectRequiredAction(EventType.UPDATE_PROFILE).assertEvent();
Assert.assertEquals(RequestType.AUTH_RESPONSE, appPage.getRequestType());
events.expectLogin().assertEvent();
// assert user is really updated in persistent store
userRep = ActionUtil.findUserWithAdminClient(adminClient, "test-user@localhost");
Assert.assertEquals("New first", userRep.getFirstName());
Assert.assertEquals("New last", userRep.getLastName());
Assert.assertEquals("new@email.com", userRep.getEmail());
Assert.assertEquals("test-user@localhost", userRep.getUsername());
Assert.assertNotNull(userRep.getAttributes());
Assert.assertTrue(userRep.getAttributes().containsKey("custom"));
}
}

View file

@ -1088,7 +1088,15 @@ public class UserTest extends AbstractAdminTest {
assertAttributeValue("value2user1", user1.getAttributes().get("attr2"));
assertAttributeValue("value4user1", user1.getAttributes().get("attr3"));
user1.getAttributes().clear();
// null attributes should not remove attributes
user1.setAttributes(null);
updateUser(realm.users().get(user1Id), user1);
user1 = realm.users().get(user1Id).toRepresentation();
assertNotNull(user1.getAttributes());
assertEquals(2, user1.getAttributes().size());
// empty attributes should remove attributes
user1.setAttributes(Collections.emptyMap());
updateUser(realm.users().get(user1Id), user1);
user1 = realm.users().get(user1Id).toRepresentation();