mirror of
https://github.com/keycloak/keycloak.git
synced 2026-05-28 04:13:22 -04:00
Fix ReadOnlyAttributeUnchangedValidator to handle omitted read-only attributes
When a read-only attribute exists on a user but is not provided in an update request (value == null), the isUnchanged() method incorrectly returned false, causing a 400 error with 'updateReadOnlyAttributesRejectedMessage'. This adds a symmetric null check: if an attribute exists on the user but was omitted from the request, treat it as unchanged. The existing logic only handled the reverse case (existingValue == null && isBlank(value)). Closes keycloak/keycloak#49272 Signed-off-by: Bruce Arctor <5032356+brucearctor@users.noreply.github.com>
This commit is contained in:
parent
94dcc24a8d
commit
8857c1b665
2 changed files with 77 additions and 1 deletions
|
|
@ -90,12 +90,18 @@ public class ReadOnlyAttributeUnchangedValidator implements SimpleValidator {
|
|||
return context;
|
||||
}
|
||||
|
||||
private boolean isUnchanged(String existingValue, String value) {
|
||||
// package-private for testing
|
||||
boolean isUnchanged(String existingValue, String value) {
|
||||
if (existingValue == null && isBlank(value)) {
|
||||
// if attribute not set to the user and value is blank/null, then pass validation
|
||||
return true;
|
||||
}
|
||||
|
||||
if (existingValue != null && value == null) {
|
||||
// if attribute exists on the user but was not provided in the request, treat as unchanged
|
||||
return true;
|
||||
}
|
||||
|
||||
return ObjectUtil.isEqualOrBothNull(existingValue, value);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,70 @@
|
|||
/*
|
||||
* Copyright 2024 Red Hat, Inc. and/or its affiliates
|
||||
* and other contributors as indicated by the @author tags.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.keycloak.userprofile.validator;
|
||||
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
|
||||
/**
|
||||
* Tests for {@link ReadOnlyAttributeUnchangedValidator#isUnchanged(String, String)}.
|
||||
*/
|
||||
public class ReadOnlyAttributeUnchangedValidatorTest {
|
||||
|
||||
private final ReadOnlyAttributeUnchangedValidator validator = new ReadOnlyAttributeUnchangedValidator();
|
||||
|
||||
@Test
|
||||
public void bothNull() {
|
||||
Assert.assertTrue("both null should be unchanged", validator.isUnchanged(null, null));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void existingNullValueBlank() {
|
||||
Assert.assertTrue("existing null and blank value should be unchanged", validator.isUnchanged(null, ""));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void existingNullValueWhitespace() {
|
||||
Assert.assertTrue("existing null and whitespace value should be unchanged", validator.isUnchanged(null, " "));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void existingNullValueNonBlank() {
|
||||
Assert.assertFalse("existing null and non-blank value should be changed", validator.isUnchanged(null, "newValue"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void existingValueAndValueNull_omittedAttribute() {
|
||||
// This is the bug fix: attribute exists on user but was omitted from the update request
|
||||
Assert.assertTrue("existing value with null (omitted) value should be unchanged",
|
||||
validator.isUnchanged("existingValue", null));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void bothEqual() {
|
||||
Assert.assertTrue("equal values should be unchanged", validator.isUnchanged("same", "same"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void bothDifferent() {
|
||||
Assert.assertFalse("different values should be changed", validator.isUnchanged("old", "new"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void existingValueAndValueBlank() {
|
||||
Assert.assertFalse("existing value with blank value should be changed", validator.isUnchanged("existingValue", ""));
|
||||
}
|
||||
}
|
||||
Loading…
Reference in a new issue