Optimize update of user attributes (#32907)
Closes #32906 Signed-off-by: Alexander Schwartz <aschwart@redhat.com>
This commit is contained in:
parent
021a2af2fd
commit
5bb23eb0fc
2 changed files with 44 additions and 2 deletions
|
@ -17,6 +17,7 @@
|
|||
|
||||
package org.keycloak.models.cache.infinispan;
|
||||
|
||||
import org.keycloak.common.util.CollectionUtil;
|
||||
import org.keycloak.credential.CredentialModel;
|
||||
import org.keycloak.models.ClientModel;
|
||||
import org.keycloak.models.GroupModel;
|
||||
|
@ -40,6 +41,7 @@ import java.util.Objects;
|
|||
import java.util.Set;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.function.Supplier;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
/**
|
||||
|
@ -174,20 +176,39 @@ public class UserAdapter implements CachedUserModel {
|
|||
|
||||
@Override
|
||||
public void setSingleAttribute(String name, String value) {
|
||||
getDelegateForUpdate();
|
||||
if (UserModel.USERNAME.equals(name) || UserModel.EMAIL.equals(name)) {
|
||||
value = KeycloakModelUtils.toLowerCaseSafe(value);
|
||||
}
|
||||
if (updated == null) {
|
||||
Set<String> oldEntries = getAttributeStream(name).collect(Collectors.toSet());
|
||||
Set<String> newEntries = value != null ? Set.of(value) : Collections.emptySet();
|
||||
if (CollectionUtil.collectionEquals(oldEntries, newEntries)) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
getDelegateForUpdate();
|
||||
updated.setSingleAttribute(name, value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setAttribute(String name, List<String> values) {
|
||||
getDelegateForUpdate();
|
||||
if (UserModel.USERNAME.equals(name) || UserModel.EMAIL.equals(name)) {
|
||||
String lowerCasedFirstValue = KeycloakModelUtils.toLowerCaseSafe((values != null && values.size() > 0) ? values.get(0) : null);
|
||||
if (lowerCasedFirstValue != null) values = Collections.singletonList(lowerCasedFirstValue);
|
||||
}
|
||||
if (updated == null) {
|
||||
Set<String> oldEntries = getAttributeStream(name).collect(Collectors.toSet());
|
||||
Set<String> newEntries;
|
||||
if (values == null) {
|
||||
newEntries = new HashSet<>();
|
||||
} else {
|
||||
newEntries = new HashSet<>(values);
|
||||
}
|
||||
if (CollectionUtil.collectionEquals(oldEntries, newEntries)) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
getDelegateForUpdate();
|
||||
updated.setAttribute(name, values);
|
||||
}
|
||||
|
||||
|
|
|
@ -19,6 +19,7 @@ package org.keycloak.models.jpa;
|
|||
|
||||
import org.keycloak.common.Profile;
|
||||
import org.keycloak.common.Profile.Feature;
|
||||
import org.keycloak.common.util.CollectionUtil;
|
||||
import org.keycloak.common.util.MultivaluedHashMap;
|
||||
import org.keycloak.common.util.ObjectUtil;
|
||||
import org.keycloak.credential.UserCredentialManager;
|
||||
|
@ -51,10 +52,13 @@ import jakarta.persistence.criteria.Root;
|
|||
import org.keycloak.organization.OrganizationProvider;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashSet;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
import org.keycloak.representations.idm.MembershipType;
|
||||
|
||||
|
@ -138,6 +142,11 @@ public class UserAdapter implements UserModel, JpaModel<UserEntity> {
|
|||
if (value == null) {
|
||||
user.getAttributes().removeIf(a -> a.getName().equals(name));
|
||||
} else {
|
||||
Set<String> oldEntries = getAttributeStream(name).collect(Collectors.toSet());
|
||||
Set<String> newEntries = Set.of(value);
|
||||
if (CollectionUtil.collectionEquals(oldEntries, newEntries)) {
|
||||
return;
|
||||
}
|
||||
String firstExistingAttrId = null;
|
||||
List<UserAttributeEntity> toRemove = new ArrayList<>();
|
||||
for (UserAttributeEntity attr : user.getAttributes()) {
|
||||
|
@ -183,6 +192,18 @@ public class UserAdapter implements UserModel, JpaModel<UserEntity> {
|
|||
setUsername(valueToSet);
|
||||
return;
|
||||
}
|
||||
|
||||
Set<String> oldEntries = getAttributeStream(name).collect(Collectors.toSet());
|
||||
Set<String> newEntries;
|
||||
if (values == null) {
|
||||
newEntries = new HashSet<>();
|
||||
} else {
|
||||
newEntries = new HashSet<>(values);
|
||||
}
|
||||
if (CollectionUtil.collectionEquals(oldEntries, newEntries)) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Remove all existing
|
||||
removeAttribute(name);
|
||||
if (values != null) {
|
||||
|
|
Loading…
Reference in a new issue