Skip to content

Commit

Permalink
Allow ADD on multivalued path queries. (#188)
Browse files Browse the repository at this point in the history
  • Loading branch information
thomaspoignant authored Jan 24, 2022
1 parent f7ed1f2 commit 162cab7
Show file tree
Hide file tree
Showing 2 changed files with 20 additions and 6 deletions.
14 changes: 8 additions & 6 deletions src/scimPatch.ts
Original file line number Diff line number Diff line change
Expand Up @@ -121,7 +121,7 @@ function validatePatchOperation(operation: ScimPatchOperation): void {
if (operation.op === 'remove' && !operation.path)
throw new NoPathInScimPatchOp();

if (operation.op === 'add' && !('value' in operation))
if (operation.op.toLowerCase() === 'add' && !('value' in operation))
throw new InvalidScimPatchRequest(`The operation ${operation.op} MUST contain a "value" member whose content specifies the value to be added`);

if (operation.path && typeof operation.path !== 'string')
Expand Down Expand Up @@ -216,7 +216,7 @@ function applyAddOrReplaceOperation<T extends ScimResource>(scimResource: T, pat
) {
const result: any = {};
result[parsedPath.attrPath] = parsedPath.compValue;
result[lastSubPath] = addOrReplaceAttribute(resource, patch);
result[lastSubPath] = addOrReplaceAttribute(resource, patch, true);
resource[e.attrName] = [...(resource[e.attrName] ?? []), result];
return scimResource;
}
Expand Down Expand Up @@ -315,9 +315,10 @@ function navigate(inputSchema: any, paths: string[]): any {
* Add or Replace a property in the ScimResource
* @param property The property we want to replace
* @param patch The patch operation
* @param multiValuedPathFilter True if thi is a multivalued path filter query
* @return the patched property
*/
function addOrReplaceAttribute(property: any, patch: ScimPatchAddReplaceOperation): any {
function addOrReplaceAttribute(property: any, patch: ScimPatchAddReplaceOperation, multiValuedPathFilter?: boolean): any {
if (Array.isArray(property)) {
if (Array.isArray(patch.value)) {
// if we're adding an array, we need to remove duplicated values from existing array
Expand All @@ -336,7 +337,7 @@ function addOrReplaceAttribute(property: any, patch: ScimPatchAddReplaceOperatio
}

if (property !== null && typeof property === 'object') {
return addOrReplaceObjectAttribute(property, patch);
return addOrReplaceObjectAttribute(property, patch, multiValuedPathFilter);
}

// If the target location specifies a single-valued attribute, the existing value is replaced.
Expand All @@ -347,10 +348,11 @@ function addOrReplaceAttribute(property: any, patch: ScimPatchAddReplaceOperatio
* addOrReplaceObjectAttribute will add an attribute if it is an object
* @param property The property we want to replace
* @param patch The patch operation
* @param multiValuedPathFilter True if thi is a multivalued path filter query
*/
function addOrReplaceObjectAttribute(property: any, patch: ScimPatchAddReplaceOperation): any {
function addOrReplaceObjectAttribute(property: any, patch: ScimPatchAddReplaceOperation, multiValuedPathFilter?: boolean): any {
if (typeof patch.value !== 'object') {
if (patch.op === 'add')
if (patch.op.toLowerCase() === 'add' && !multiValuedPathFilter)
throw new InvalidScimPatchOp('Invalid patch query.');

return patch.value;
Expand Down
12 changes: 12 additions & 0 deletions test/scimPatch.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -576,6 +576,18 @@ describe('SCIM PATCH', () => {
return done();
});

it("ADD: existing array add filter type + field (Azure AD) with lower case add", (done) => {
const patch: ScimPatchAddReplaceOperation = { op: "add",value: "1122 Street Rd", path: "addresses[type eq \"work\"].formatted" };
const afterPatch = scimPatch(scimUser, [patch]);
expect(afterPatch.addresses?.length).to.be.eq(1);
if (afterPatch.addresses !== undefined){
const newAddress = afterPatch.addresses[0];
expect(newAddress.type).to.be.eq("work");
expect(newAddress.formatted).to.be.eq("1122 Street Rd");
}
return done();
});

it("ADD: empty array multiple filter should throw an error", (done) => {
const patch: ScimPatchAddReplaceOperation = {
op: "Add",
Expand Down

0 comments on commit 162cab7

Please sign in to comment.