mirror of
https://github.com/keycloak/keycloak.git
synced 2026-02-18 18:37:54 -05:00
Allow setting locale when edit mode is READ_ONLY
Closes #38981 Signed-off-by: Pedro Igor <pigor.craveiro@gmail.com>
This commit is contained in:
parent
b9d38d0fe9
commit
ab41366757
3 changed files with 37 additions and 5 deletions
|
|
@ -120,6 +120,7 @@ public class LDAPStorageProvider implements UserStorageProvider,
|
|||
UserProfileDecorator {
|
||||
private static final Logger logger = Logger.getLogger(LDAPStorageProvider.class);
|
||||
private static final int DEFAULT_MAX_RESULTS = Integer.MAX_VALUE >> 1;
|
||||
public static final List<String> INTERNAL_ATTRIBUTES = List.of(UserModel.LOCALE);
|
||||
|
||||
protected LDAPStorageProviderFactory factory;
|
||||
protected KeycloakSession session;
|
||||
|
|
@ -1201,6 +1202,7 @@ public class LDAPStorageProvider implements UserStorageProvider,
|
|||
// 3 - make all attributes read-only for LDAP users in case that LDAP itself is read-only
|
||||
if (getEditMode() == EditMode.READ_ONLY) {
|
||||
Stream.concat(metadata.getAttributes().stream(), metadatas.stream())
|
||||
.filter((m) -> !INTERNAL_ATTRIBUTES.contains(m.getName()))
|
||||
.forEach(attrMetadata -> attrMetadata.addWriteCondition(AttributeMetadata.ALWAYS_FALSE));
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -17,7 +17,8 @@
|
|||
|
||||
package org.keycloak.storage.ldap;
|
||||
|
||||
import java.util.Collections;
|
||||
import static org.keycloak.storage.ldap.LDAPStorageProvider.INTERNAL_ATTRIBUTES;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import java.util.stream.Collectors;
|
||||
|
|
@ -69,13 +70,15 @@ public class ReadonlyLDAPUserModelDelegate extends UserModelDelegate {
|
|||
|
||||
@Override
|
||||
public void setSingleAttribute(String name, String value) {
|
||||
if (!Objects.equals(getAttributeStream(name).collect(Collectors.toList()), Collections.singletonList(value))) {
|
||||
throw new ReadOnlyException("Federated storage is not writable");
|
||||
}
|
||||
setAttribute(name, List.of(value));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setAttribute(String name, List<String> values) {
|
||||
if (INTERNAL_ATTRIBUTES.contains(name)) {
|
||||
super.setAttribute(name, values);
|
||||
return;
|
||||
}
|
||||
if (!Objects.equals(getAttributeStream(name).collect(Collectors.toList()), values)) {
|
||||
throw new ReadOnlyException("Federated storage is not writable");
|
||||
}
|
||||
|
|
@ -83,6 +86,10 @@ public class ReadonlyLDAPUserModelDelegate extends UserModelDelegate {
|
|||
|
||||
@Override
|
||||
public void removeAttribute(String name) {
|
||||
if (INTERNAL_ATTRIBUTES.contains(name)) {
|
||||
super.removeAttribute(name);
|
||||
return;
|
||||
}
|
||||
if (getAttributeStream(name).count() > 0) {
|
||||
throw new ReadOnlyException("Federated storage is not writable");
|
||||
}
|
||||
|
|
|
|||
|
|
@ -18,6 +18,7 @@
|
|||
|
||||
package org.keycloak.testsuite.federation.ldap;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import org.hamcrest.MatcherAssert;
|
||||
import org.jboss.arquillian.graphene.page.Page;
|
||||
|
|
@ -26,7 +27,6 @@ import org.junit.ClassRule;
|
|||
import org.junit.FixMethodOrder;
|
||||
import org.junit.Test;
|
||||
import org.junit.runners.MethodSorters;
|
||||
import org.keycloak.OAuth2Constants;
|
||||
import org.keycloak.admin.client.resource.UserResource;
|
||||
import org.keycloak.component.ComponentModel;
|
||||
import org.keycloak.models.AuthenticationExecutionModel;
|
||||
|
|
@ -56,7 +56,10 @@ import jakarta.ws.rs.ClientErrorException;
|
|||
import java.util.Collections;
|
||||
|
||||
import static org.hamcrest.CoreMatchers.is;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
import static org.junit.Assert.assertNull;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
/**
|
||||
|
|
@ -164,6 +167,26 @@ public class LDAPReadOnlyTest extends AbstractLDAPTest {
|
|||
user.update(userRepresentation);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testUpdateLocale() {
|
||||
RealmRepresentation realm = testRealm().toRepresentation();
|
||||
realm.setInternationalizationEnabled(true);
|
||||
testRealm().update(realm);
|
||||
UserResource user = ApiUtil.findUserByUsernameId(testRealm(), "johnkeycloak");
|
||||
|
||||
UserRepresentation userRepresentation = user.toRepresentation();
|
||||
String language = "pt_BR";
|
||||
userRepresentation.setAttributes(Map.of(UserModel.LOCALE, List.of(language)));
|
||||
user.update(userRepresentation);
|
||||
|
||||
userRepresentation = user.toRepresentation();
|
||||
assertEquals(language, userRepresentation.getAttributes().get(UserModel.LOCALE).get(0));
|
||||
|
||||
userRepresentation.getAttributes().remove(UserModel.LOCALE);
|
||||
user.update(userRepresentation);
|
||||
assertNull(userRepresentation.getAttributes().get(UserModel.LOCALE));
|
||||
}
|
||||
|
||||
// KEYCLOAK-3365
|
||||
@Test(expected = ClientErrorException.class)
|
||||
public void testReadOnlyUserThrowsIfChanged() {
|
||||
|
|
|
|||
Loading…
Reference in a new issue