KEYCLOAK-14904 Fix AccountRestService
- custom attributes in UserModel are removed during update - this can break caching (doesn't break if user is written to database) - also ensure that we don't accidentally change username and/or firstName/lastName through attributes
This commit is contained in:
parent
bf411d7567
commit
330a3d8ff5
2 changed files with 41 additions and 1 deletions
|
@ -214,12 +214,26 @@ public class AccountRestService {
|
|||
user.setLastName(userRep.getLastName());
|
||||
|
||||
if (userRep.getAttributes() != null) {
|
||||
for (String k : user.getAttributes().keySet()) {
|
||||
Set<String> attributeKeys = new HashSet<>(user.getAttributes().keySet());
|
||||
// We store username and other attributes as attributes (for future UserProfile)
|
||||
// but don't propagate them to the UserRepresentation, so userRep will never contain them
|
||||
// if the user did not explicitly add them
|
||||
attributeKeys.remove(UserModel.FIRST_NAME);
|
||||
attributeKeys.remove(UserModel.LAST_NAME);
|
||||
attributeKeys.remove(UserModel.EMAIL);
|
||||
attributeKeys.remove(UserModel.USERNAME);
|
||||
for (String k : attributeKeys) {
|
||||
if (!userRep.getAttributes().containsKey(k)) {
|
||||
user.removeAttribute(k);
|
||||
}
|
||||
}
|
||||
|
||||
Map<String, List<String>> attributes = userRep.getAttributes();
|
||||
// Make sure we don't accidentally update any of the fields through attributes
|
||||
attributes.remove(UserModel.FIRST_NAME);
|
||||
attributes.remove(UserModel.LAST_NAME);
|
||||
attributes.remove(UserModel.EMAIL);
|
||||
attributes.remove(UserModel.USERNAME);
|
||||
for (Map.Entry<String, List<String>> e : userRep.getAttributes().entrySet()) {
|
||||
user.setAttribute(e.getKey(), e.getValue());
|
||||
}
|
||||
|
|
|
@ -180,6 +180,32 @@ public class AccountRestServiceTest extends AbstractRestServiceTest {
|
|||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testUpdateProfileCannotChangeThroughAttributes() throws IOException {
|
||||
UserRepresentation user = SimpleHttp.doGet(getAccountUrl(null), httpClient).auth(tokenUtil.getToken()).asJson(UserRepresentation.class);
|
||||
String originalUsername = user.getUsername();
|
||||
Map<String, List<String>> originalAttributes = new HashMap<>(user.getAttributes());
|
||||
|
||||
try {
|
||||
user.getAttributes().put("username", Collections.singletonList("Username"));
|
||||
user.getAttributes().put("attr2", Collections.singletonList("val2"));
|
||||
|
||||
user = updateAndGet(user);
|
||||
|
||||
assertEquals(user.getUsername(), originalUsername);
|
||||
} finally {
|
||||
RealmRepresentation realmRep = adminClient.realm("test").toRepresentation();
|
||||
realmRep.setEditUsernameAllowed(true);
|
||||
adminClient.realm("test").update(realmRep);
|
||||
|
||||
user.setUsername(originalUsername);
|
||||
user.setAttributes(originalAttributes);
|
||||
SimpleHttp.Response response = SimpleHttp.doPost(getAccountUrl(null), httpClient).auth(tokenUtil.getToken()).json(user).asResponse();
|
||||
System.out.println(response.asString());
|
||||
assertEquals(204, response.getStatus());
|
||||
}
|
||||
}
|
||||
|
||||
// KEYCLOAK-7572
|
||||
@Test
|
||||
public void testUpdateProfileWithRegistrationEmailAsUsername() throws IOException {
|
||||
|
|
Loading…
Reference in a new issue