fix: Only require append permissions on POST requests

This commit is contained in:
Joachim Van Herwegen 2021-01-27 10:20:44 +01:00
parent 13409bd91e
commit 93e53b3d24
3 changed files with 27 additions and 5 deletions

View File

@ -4,8 +4,9 @@ import type { PermissionSet } from './PermissionSet';
import { PermissionsExtractor } from './PermissionsExtractor'; import { PermissionsExtractor } from './PermissionsExtractor';
const READ_METHODS = new Set([ 'GET', 'HEAD' ]); const READ_METHODS = new Set([ 'GET', 'HEAD' ]);
const WRITE_METHODS = new Set([ 'POST', 'PUT', 'DELETE' ]); const WRITE_METHODS = new Set([ 'PUT', 'DELETE' ]);
const SUPPORTED_METHODS = new Set([ ...READ_METHODS, ...WRITE_METHODS ]); const APPEND_METHODS = new Set([ 'POST' ]);
const SUPPORTED_METHODS = new Set([ ...READ_METHODS, ...WRITE_METHODS, ...APPEND_METHODS ]);
/** /**
* Generates permissions for the base set of methods that always require the same permissions. * Generates permissions for the base set of methods that always require the same permissions.
@ -21,6 +22,7 @@ export class MethodPermissionsExtractor extends PermissionsExtractor {
public async handle({ method }: Operation): Promise<PermissionSet> { public async handle({ method }: Operation): Promise<PermissionSet> {
const read = READ_METHODS.has(method); const read = READ_METHODS.has(method);
const write = WRITE_METHODS.has(method); const write = WRITE_METHODS.has(method);
return { read, write, append: write }; const append = write || APPEND_METHODS.has(method);
return { read, write, append };
} }
} }

View File

@ -117,4 +117,24 @@ describe.each(stores)('An LDP handler with auth using %s', (name, { storeUrn, se
response = await resourceHelper.deleteResource('http://test.com/permanent.txt', true); response = await resourceHelper.deleteResource('http://test.com/permanent.txt', true);
expect(response.statusCode).toBe(401); expect(response.statusCode).toBe(401);
}); });
it('can add files but not write to them if append is allowed.', async(): Promise<void> => {
// Set acl
await aclHelper.setSimpleAcl({ read: true, write: false, append: true }, 'agent');
// Add a file
let response = await resourceHelper.createResource(
'../assets/testfile2.txt', 'testfile2.txt', 'text/plain', true,
);
expect(response.statusCode).toBe(201);
const id = response._getHeaders().location;
response = await resourceHelper.performRequestWithBody(
new URL(id),
'PUT',
{ 'content-type': 'text/plain', 'transfer-encoding': 'chunked' },
Buffer.from('data'),
);
expect(response.statusCode).toBe(401);
});
}); });

View File

@ -30,11 +30,11 @@ describe('A MethodPermissionsExtractor', (): void => {
}); });
}); });
it('requires write for POST operations.', async(): Promise<void> => { it('requires append for POST operations.', async(): Promise<void> => {
await expect(extractor.handle({ method: 'POST' } as Operation)).resolves.toEqual({ await expect(extractor.handle({ method: 'POST' } as Operation)).resolves.toEqual({
read: false, read: false,
append: true, append: true,
write: true, write: false,
}); });
}); });