diff --git a/src/authorization/permissions/MethodModesExtractor.ts b/src/authorization/permissions/MethodModesExtractor.ts index 0d995ad35..5a581ca14 100644 --- a/src/authorization/permissions/MethodModesExtractor.ts +++ b/src/authorization/permissions/MethodModesExtractor.ts @@ -39,11 +39,13 @@ export class MethodModesExtractor extends ModesExtractor { if (READ_METHODS.has(method)) { requiredModes.add(target, AccessMode.read); } - // Setting a resource's representation requires Write permissions if (method === 'PUT') { - requiredModes.add(target, AccessMode.write); - // …and, if the resource does not exist yet, Create permissions are required as well - if (!await this.resourceSet.hasResource(target)) { + if (await this.resourceSet.hasResource(target)) { + // Replacing a resource's representation with PUT requires Write permissions + requiredModes.add(target, AccessMode.write); + } else { + // ... while creating a new resource with PUT requires Append and Create permissions. + requiredModes.add(target, AccessMode.append); requiredModes.add(target, AccessMode.create); } } diff --git a/test/integration/PermissionTable.test.ts b/test/integration/PermissionTable.test.ts index 0d1f93ea2..c81c85a41 100644 --- a/test/integration/PermissionTable.test.ts +++ b/test/integration/PermissionTable.test.ts @@ -83,7 +83,7 @@ const table: [string, string, AM[], AM[] | undefined, string, string, number, nu [ 'PUT', 'C/R', [], [ AM.append ], '', TXT, 401, 401 ], [ 'PUT', 'C/R', [], [ AM.write ], '', TXT, 205, 401 ], [ 'PUT', 'C/R', [ AM.read ], undefined, '', TXT, 401, 401 ], - [ 'PUT', 'C/R', [ AM.append ], undefined, '', TXT, 401, 401 ], + [ 'PUT', 'C/R', [ AM.append ], undefined, '', TXT, 401, 201 ], [ 'PUT', 'C/R', [ AM.write ], undefined, '', TXT, 205, 201 ], [ 'PUT', 'C/R', [ AM.append ], [ AM.write ], '', TXT, 205, 201 ], diff --git a/test/unit/authorization/permissions/MethodModesExtractor.test.ts b/test/unit/authorization/permissions/MethodModesExtractor.test.ts index 37ab0c6be..ad1e06acb 100644 --- a/test/unit/authorization/permissions/MethodModesExtractor.test.ts +++ b/test/unit/authorization/permissions/MethodModesExtractor.test.ts @@ -58,11 +58,11 @@ describe('A MethodModesExtractor', (): void => { compareMaps(await extractor.handle({ ...operation, method: 'PUT' }), getMap([ AccessMode.write ])); }); - it('requires create for PUT operations if the target does not exist.', async(): Promise => { + it('requires append/create for PUT operations if the target does not exist.', async(): Promise => { resourceSet.hasResource.mockResolvedValueOnce(false); compareMaps( await extractor.handle({ ...operation, method: 'PUT' }), - getMap([ AccessMode.write, AccessMode.create ]), + getMap([ AccessMode.append, AccessMode.create ]), ); });