mirror of
https://github.com/CommunitySolidServer/CommunitySolidServer.git
synced 2024-10-03 14:55:10 +00:00
fix: Support empty PATCH requests
This commit is contained in:
parent
a6371b0735
commit
ded263a81d
109
package-lock.json
generated
109
package-lock.json
generated
@ -1432,6 +1432,29 @@
|
|||||||
"asynciterator": "^3.1.0",
|
"asynciterator": "^3.1.0",
|
||||||
"immutable": "^3.8.2",
|
"immutable": "^3.8.2",
|
||||||
"sparqlalgebrajs": "^2.4.0"
|
"sparqlalgebrajs": "^2.4.0"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"sparqlalgebrajs": {
|
||||||
|
"version": "2.5.5",
|
||||||
|
"resolved": "https://registry.npmjs.org/sparqlalgebrajs/-/sparqlalgebrajs-2.5.5.tgz",
|
||||||
|
"integrity": "sha512-sG9XI5311mS+JPDaeZUwtwYaYDRiTZDzxtHVS1GSrnfcZ2aiK1fa1PX9z16l7dtS35X3z1j1qyHEElzZO5OM3A==",
|
||||||
|
"requires": {
|
||||||
|
"fast-deep-equal": "^3.1.3",
|
||||||
|
"minimist": "^1.2.5",
|
||||||
|
"rdf-data-factory": "^1.0.4",
|
||||||
|
"rdf-isomorphic": "^1.2.0",
|
||||||
|
"rdf-string": "^1.5.0",
|
||||||
|
"sparqljs": "^3.3.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"sparqljs": {
|
||||||
|
"version": "3.4.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/sparqljs/-/sparqljs-3.4.2.tgz",
|
||||||
|
"integrity": "sha512-MmmZ6cMuvhf4Eh2FXX21dalgADUiZ9WN8XKMedwhTFg0r7W09/o8wvoZ8C4yA6FptnjjAjm+mGnxAEpkSRY3QQ==",
|
||||||
|
"requires": {
|
||||||
|
"rdf-data-factory": "^1.0.4"
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"@dabh/diagnostics": {
|
"@dabh/diagnostics": {
|
||||||
@ -2368,6 +2391,14 @@
|
|||||||
"resolved": "https://registry.npmjs.org/@rdfjs/to-ntriples/-/to-ntriples-1.0.2.tgz",
|
"resolved": "https://registry.npmjs.org/@rdfjs/to-ntriples/-/to-ntriples-1.0.2.tgz",
|
||||||
"integrity": "sha512-ngw5XAaGHjgGiwWWBPGlfdCclHftonmbje5lMys4G2j4NvfExraPIuRZgjSnd5lg4dnulRVUll8tRbgKO+7EDA=="
|
"integrity": "sha512-ngw5XAaGHjgGiwWWBPGlfdCclHftonmbje5lMys4G2j4NvfExraPIuRZgjSnd5lg4dnulRVUll8tRbgKO+7EDA=="
|
||||||
},
|
},
|
||||||
|
"@rdfjs/types": {
|
||||||
|
"version": "1.0.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/@rdfjs/types/-/types-1.0.1.tgz",
|
||||||
|
"integrity": "sha512-YxVkH0XrCNG3MWeZxfg596GFe+oorTVusmNxRP6ZHTsGczZ8AGvG3UchRNkg3Fy4MyysI7vBAA5YZbESL+VmHQ==",
|
||||||
|
"requires": {
|
||||||
|
"@types/node": "*"
|
||||||
|
}
|
||||||
|
},
|
||||||
"@sindresorhus/is": {
|
"@sindresorhus/is": {
|
||||||
"version": "0.14.0",
|
"version": "0.14.0",
|
||||||
"resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-0.14.0.tgz",
|
"resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-0.14.0.tgz",
|
||||||
@ -6569,6 +6600,15 @@
|
|||||||
"integrity": "sha512-UqBRqi4ju7T+TqGNdqAO0PaSVGsDGJUBQvk9eUWNGRY1CFGDzYhLWoM7JQEemnlvVcv/YEmc2wNW8BC24EnUsw==",
|
"integrity": "sha512-UqBRqi4ju7T+TqGNdqAO0PaSVGsDGJUBQvk9eUWNGRY1CFGDzYhLWoM7JQEemnlvVcv/YEmc2wNW8BC24EnUsw==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
|
"hash.js": {
|
||||||
|
"version": "1.1.7",
|
||||||
|
"resolved": "https://registry.npmjs.org/hash.js/-/hash.js-1.1.7.tgz",
|
||||||
|
"integrity": "sha512-taOaskGt4z4SOANNseOviYDvjEJinIkRgmp7LbKP2YTTmVxWBl87s/uzK9r+44BclBSp2X7K1hqeNfz9JbBeXA==",
|
||||||
|
"requires": {
|
||||||
|
"inherits": "^2.0.3",
|
||||||
|
"minimalistic-assert": "^1.0.1"
|
||||||
|
}
|
||||||
|
},
|
||||||
"hosted-git-info": {
|
"hosted-git-info": {
|
||||||
"version": "2.8.8",
|
"version": "2.8.8",
|
||||||
"resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.8.tgz",
|
"resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.8.tgz",
|
||||||
@ -9628,6 +9668,11 @@
|
|||||||
"integrity": "sha512-I9jwMn07Sy/IwOj3zVkVik2JTvgpaykDZEigL6Rx6N9LbMywwUSMtxET+7lVoDLLd3O3IXwJwvuuns8UB/HeAg==",
|
"integrity": "sha512-I9jwMn07Sy/IwOj3zVkVik2JTvgpaykDZEigL6Rx6N9LbMywwUSMtxET+7lVoDLLd3O3IXwJwvuuns8UB/HeAg==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
|
"minimalistic-assert": {
|
||||||
|
"version": "1.0.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz",
|
||||||
|
"integrity": "sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A=="
|
||||||
|
},
|
||||||
"minimatch": {
|
"minimatch": {
|
||||||
"version": "3.0.4",
|
"version": "3.0.4",
|
||||||
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz",
|
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz",
|
||||||
@ -10769,6 +10814,14 @@
|
|||||||
"rdf-terms": "^1.6.2"
|
"rdf-terms": "^1.6.2"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"rdf-js": {
|
||||||
|
"version": "4.0.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/rdf-js/-/rdf-js-4.0.2.tgz",
|
||||||
|
"integrity": "sha512-ApvlFa/WsQh8LpPK/6hctQwG06Z9ztQQGWVtrcrf9L6+sejHNXLPOqL+w7q3hF+iL0C4sv3AX1PUtGkLNzyZ0Q==",
|
||||||
|
"requires": {
|
||||||
|
"@rdfjs/types": "*"
|
||||||
|
}
|
||||||
|
},
|
||||||
"rdf-literal": {
|
"rdf-literal": {
|
||||||
"version": "1.2.0",
|
"version": "1.2.0",
|
||||||
"resolved": "https://registry.npmjs.org/rdf-literal/-/rdf-literal-1.2.0.tgz",
|
"resolved": "https://registry.npmjs.org/rdf-literal/-/rdf-literal-1.2.0.tgz",
|
||||||
@ -11505,22 +11558,62 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"sparqlalgebrajs": {
|
"sparqlalgebrajs": {
|
||||||
"version": "2.5.1",
|
"version": "3.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/sparqlalgebrajs/-/sparqlalgebrajs-2.5.1.tgz",
|
"resolved": "https://registry.npmjs.org/sparqlalgebrajs/-/sparqlalgebrajs-3.0.0.tgz",
|
||||||
"integrity": "sha512-J682nUANGeaaJexN5gcjw7fS507Vxoiz78wIRgFZ2Zv0nu4ObPZQDPgzYK01V0/FXd7sboXkWiHyG8BUeXnimQ==",
|
"integrity": "sha512-3QbDE78l170TiyzzTNkW4ug0p9rCRpNHK5vTN67O9LO2yrwnqI3v3Hp+8RW7ZQZAswZCPQ3T3o8TFDR6s3AZYA==",
|
||||||
"requires": {
|
"requires": {
|
||||||
|
"@types/minimist": "^1.2.1",
|
||||||
|
"@types/node": "^15.12.2",
|
||||||
|
"@types/rdf-js": "^4.0.2",
|
||||||
|
"@types/sparqljs": "^3.1.2",
|
||||||
"fast-deep-equal": "^3.1.3",
|
"fast-deep-equal": "^3.1.3",
|
||||||
"minimist": "^1.2.5",
|
"minimist": "^1.2.5",
|
||||||
"rdf-data-factory": "^1.0.4",
|
"rdf-data-factory": "^1.0.4",
|
||||||
"rdf-isomorphic": "^1.2.0",
|
"rdf-isomorphic": "^1.2.1",
|
||||||
"rdf-string": "^1.5.0",
|
"rdf-string": "^1.5.0",
|
||||||
"sparqljs": "^3.3.0"
|
"sparqljs": "^3.4.2"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
"@types/minimist": {
|
||||||
|
"version": "1.2.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/@types/minimist/-/minimist-1.2.1.tgz",
|
||||||
|
"integrity": "sha512-fZQQafSREFyuZcdWFAExYjBiCL7AUCdgsk80iO0q4yihYYdcIiH28CcuPTGFgLOCC8RlW49GSQxdHwZP+I7CNg=="
|
||||||
|
},
|
||||||
|
"@types/node": {
|
||||||
|
"version": "15.12.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/@types/node/-/node-15.12.2.tgz",
|
||||||
|
"integrity": "sha512-zjQ69G564OCIWIOHSXyQEEDpdpGl+G348RAKY0XXy9Z5kU9Vzv1GMNnkar/ZJ8dzXB3COzD9Mo9NtRZ4xfgUww=="
|
||||||
|
},
|
||||||
|
"@types/rdf-js": {
|
||||||
|
"version": "4.0.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/@types/rdf-js/-/rdf-js-4.0.2.tgz",
|
||||||
|
"integrity": "sha512-soR/+RMogGiDU1lrpuQl5ZL55/L1eq/JlR2dWx052Uh/RYs9okh3XZHFlIJXHZqjqyjEn4WdbOMfBj7vvc2WVQ==",
|
||||||
|
"requires": {
|
||||||
|
"rdf-js": "*"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"@types/sparqljs": {
|
||||||
|
"version": "3.1.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/@types/sparqljs/-/sparqljs-3.1.2.tgz",
|
||||||
|
"integrity": "sha512-tLfrnBuK37P2Bn8Fo7Qik95sBXYHw5D+gq3MMq1HVyoTpCWivwPnP0Mmd7Apamdc9eH3mLJwIZIETHCQ6HxMUw==",
|
||||||
|
"requires": {
|
||||||
|
"rdf-js": "^4.0.2"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"rdf-isomorphic": {
|
||||||
|
"version": "1.2.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/rdf-isomorphic/-/rdf-isomorphic-1.2.1.tgz",
|
||||||
|
"integrity": "sha512-kIKlQYoizNqp8zhbca1zV3mYngisoD/KNt/xBRjagp7R3F8niI3b1vxvqcWlSkNXgPD6MsXpP2E/uXZ8oGTIcA==",
|
||||||
|
"requires": {
|
||||||
|
"hash.js": "^1.1.7",
|
||||||
|
"rdf-string": "^1.5.0",
|
||||||
|
"rdf-terms": "^1.6.2"
|
||||||
|
}
|
||||||
|
},
|
||||||
"sparqljs": {
|
"sparqljs": {
|
||||||
"version": "3.3.0",
|
"version": "3.4.2",
|
||||||
"resolved": "https://registry.npmjs.org/sparqljs/-/sparqljs-3.3.0.tgz",
|
"resolved": "https://registry.npmjs.org/sparqljs/-/sparqljs-3.4.2.tgz",
|
||||||
"integrity": "sha512-2WnOX1b72pmf8yHyhoaPKnqqCBMn22qa59H/aiIruQ4lkv9ngaSYGOos5ZqW3o6AcUvCj/ObLQw4RnfQKXRdww==",
|
"integrity": "sha512-MmmZ6cMuvhf4Eh2FXX21dalgADUiZ9WN8XKMedwhTFg0r7W09/o8wvoZ8C4yA6FptnjjAjm+mGnxAEpkSRY3QQ==",
|
||||||
"requires": {
|
"requires": {
|
||||||
"rdf-data-factory": "^1.0.4"
|
"rdf-data-factory": "^1.0.4"
|
||||||
}
|
}
|
||||||
|
@ -122,7 +122,7 @@
|
|||||||
"rdf-terms": "^1.5.1",
|
"rdf-terms": "^1.5.1",
|
||||||
"redis": "^3.0.2",
|
"redis": "^3.0.2",
|
||||||
"redlock": "^4.2.0",
|
"redlock": "^4.2.0",
|
||||||
"sparqlalgebrajs": "^2.5.1",
|
"sparqlalgebrajs": "^3.0.0",
|
||||||
"sparqljs": "^3.1.2",
|
"sparqljs": "^3.1.2",
|
||||||
"streamify-array": "^1.0.1",
|
"streamify-array": "^1.0.1",
|
||||||
"url-join": "^4.0.1",
|
"url-join": "^4.0.1",
|
||||||
|
@ -44,7 +44,7 @@ export class SparqlPatchPermissionsExtractor extends PermissionsExtractor {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private isSupported(op: Algebra.Operation): boolean {
|
private isSupported(op: Algebra.Operation): boolean {
|
||||||
if (op.type === Algebra.types.DELETE_INSERT) {
|
if (this.isDeleteInsert(op) || this.isNop(op)) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
if (op.type === Algebra.types.COMPOSITE_UPDATE) {
|
if (op.type === Algebra.types.COMPOSITE_UPDATE) {
|
||||||
@ -57,7 +57,14 @@ export class SparqlPatchPermissionsExtractor extends PermissionsExtractor {
|
|||||||
return op.type === Algebra.types.DELETE_INSERT;
|
return op.type === Algebra.types.DELETE_INSERT;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private isNop(op: Algebra.Operation): op is Algebra.Nop {
|
||||||
|
return op.type === Algebra.types.NOP;
|
||||||
|
}
|
||||||
|
|
||||||
private needsAppend(update: Algebra.Operation): boolean {
|
private needsAppend(update: Algebra.Operation): boolean {
|
||||||
|
if (this.isNop(update)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
if (this.isDeleteInsert(update)) {
|
if (this.isDeleteInsert(update)) {
|
||||||
return Boolean(update.insert && update.insert.length > 0);
|
return Boolean(update.insert && update.insert.length > 0);
|
||||||
}
|
}
|
||||||
@ -66,6 +73,9 @@ export class SparqlPatchPermissionsExtractor extends PermissionsExtractor {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private needsWrite(update: Algebra.Operation): boolean {
|
private needsWrite(update: Algebra.Operation): boolean {
|
||||||
|
if (this.isNop(update)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
if (this.isDeleteInsert(update)) {
|
if (this.isDeleteInsert(update)) {
|
||||||
return Boolean(update.delete && update.delete.length > 0);
|
return Boolean(update.delete && update.delete.length > 0);
|
||||||
}
|
}
|
||||||
|
@ -47,6 +47,12 @@ export class SparqlUpdatePatchHandler extends PatchHandler {
|
|||||||
// Verify the patch
|
// Verify the patch
|
||||||
const { source, identifier, patch } = input;
|
const { source, identifier, patch } = input;
|
||||||
const op = (patch as SparqlUpdatePatch).algebra;
|
const op = (patch as SparqlUpdatePatch).algebra;
|
||||||
|
|
||||||
|
// In case of a NOP we can skip everything
|
||||||
|
if (op.type === Algebra.types.NOP) {
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
|
||||||
this.validateUpdate(op);
|
this.validateUpdate(op);
|
||||||
|
|
||||||
return this.applyPatch(source, identifier, op);
|
return this.applyPatch(source, identifier, op);
|
||||||
|
@ -32,6 +32,19 @@ describe('A SparqlPatchPermissionsExtractor', (): void => {
|
|||||||
await expect(result).rejects.toThrow('Can only determine permissions of a PATCH with DELETE/INSERT operations.');
|
await expect(result).rejects.toThrow('Can only determine permissions of a PATCH with DELETE/INSERT operations.');
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('requires nothing for NOP operations.', async(): Promise<void> => {
|
||||||
|
const operation = {
|
||||||
|
method: 'PATCH',
|
||||||
|
body: { algebra: factory.createNop() },
|
||||||
|
} as unknown as Operation;
|
||||||
|
await expect(extractor.handle(operation)).resolves.toEqual({
|
||||||
|
read: false,
|
||||||
|
append: false,
|
||||||
|
write: false,
|
||||||
|
control: false,
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
it('requires append for INSERT operations.', async(): Promise<void> => {
|
it('requires append for INSERT operations.', async(): Promise<void> => {
|
||||||
const operation = {
|
const operation = {
|
||||||
method: 'PATCH',
|
method: 'PATCH',
|
||||||
|
@ -93,6 +93,13 @@ describe('A SparqlUpdatePatchHandler', (): void => {
|
|||||||
await expect(handler.canHandle(input)).rejects.toThrow(NotImplementedHttpError);
|
await expect(handler.canHandle(input)).rejects.toThrow(NotImplementedHttpError);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('handles NOP operations by not doing anything.', async(): Promise<void> => {
|
||||||
|
await handle('');
|
||||||
|
expect(source.getRepresentation).toHaveBeenCalledTimes(0);
|
||||||
|
expect(converter.handleSafe).toHaveBeenCalledTimes(0);
|
||||||
|
expect(source.setRepresentation).toHaveBeenCalledTimes(0);
|
||||||
|
});
|
||||||
|
|
||||||
it('handles INSERT DATA updates.', async(): Promise<void> => {
|
it('handles INSERT DATA updates.', async(): Promise<void> => {
|
||||||
await handle(fullfilledDataInsert);
|
await handle(fullfilledDataInsert);
|
||||||
expect(await basicChecks(startQuads.concat(
|
expect(await basicChecks(startQuads.concat(
|
||||||
|
Loading…
x
Reference in New Issue
Block a user