Skip to content

Commit

Permalink
Fixed issue with PATCH incorrectly replacing entire complex attr
Browse files Browse the repository at this point in the history
  • Loading branch information
jasonfagerberg-toast committed Jan 17, 2025
1 parent a639001 commit c016f37
Show file tree
Hide file tree
Showing 2 changed files with 31 additions and 2 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@
import java.util.Map;
import java.util.Optional;
import java.util.function.Predicate;
import org.apache.directory.scim.spec.schema.Schema.Attribute.Type;

import static java.util.stream.Collectors.toList;

Expand Down Expand Up @@ -337,8 +338,16 @@ public void applySingleValue(Map<String, Object> sourceAsMap, Attribute attribut
checkMutability(attribute.getAttribute(subAttributeName), parentValue.get(subAttributeName));
parentValue.put(subAttributeName, value);
} else {
checkMutability(attribute, sourceAsMap.get(attribute.getName()));
sourceAsMap.put(attribute.getName(), value);
Object currentValue = sourceAsMap.get(attribute.getName());
checkMutability(attribute, currentValue);
// PATCH on complex attributes should only replace the values given, leaving any not provided in the request untouched
if (attribute.getType() == Type.COMPLEX) {
Map<String, Object> newValue = ((Map<String, Object>) currentValue);
newValue.putAll((Map<String, Object>) value);
sourceAsMap.put(attribute.getName(), newValue);
} else {
sourceAsMap.put(attribute.getName(), value);
}
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,26 @@ public PatchHandlerTest() {
this.patchHandler = new DefaultPatchHandler(schemaRegistry);
}

@Test
public void applyReplaceComplexAttribute() {
// setup existing user
Name existingName = new Name();
existingName.setFamilyName("Family Name");
existingName.setGivenName("Given Name");
ScimUser user = user();
user.setName(existingName);

// setup patch ops
Map<String, String> newName = Map.of("familyName", "New Family Name");
PatchOperation op = patchOperation(REPLACE, "name", newName);

//execute
ScimUser updatedUser = patchHandler.apply(user, List.of(op));
assertThat(updatedUser.getName().getFamilyName()).isEqualTo("New Family Name");
// assert that PATCH did not update fields not provided in PatchOperation
assertThat(updatedUser.getName().getGivenName()).isNotNull();
}

@Test
public void applyReplaceUserName() {
String newUserName = "[email protected]";
Expand Down

0 comments on commit c016f37

Please sign in to comment.