mirror of
https://github.com/CommunitySolidServer/CommunitySolidServer.git
synced 2024-10-03 14:55:10 +00:00
fix: Return WAC-Allow header in 304 responses
This commit is contained in:
parent
baa64987c6
commit
43e8ef99b0
@ -8,6 +8,7 @@ import { AccessMode } from '../authorization/permissions/Permissions';
|
||||
import type { ResponseDescription } from '../http/output/response/ResponseDescription';
|
||||
import type { RepresentationMetadata } from '../http/representation/RepresentationMetadata';
|
||||
import { getLoggerFor } from '../logging/LogUtil';
|
||||
import { NotModifiedHttpError } from '../util/errors/NotModifiedHttpError';
|
||||
import { ACL, AUTH } from '../util/Vocabularies';
|
||||
import type { OperationHttpHandlerInput } from './OperationHttpHandler';
|
||||
import { OperationHttpHandler } from './OperationHttpHandler';
|
||||
@ -47,7 +48,18 @@ export class WacAllowHttpHandler extends OperationHttpHandler {
|
||||
|
||||
public async handle(input: OperationHttpHandlerInput): Promise<ResponseDescription> {
|
||||
const { request, operation } = input;
|
||||
const response = await this.operationHandler.handleSafe(input);
|
||||
let response: ResponseDescription | NotModifiedHttpError;
|
||||
try {
|
||||
response = await this.operationHandler.handleSafe(input);
|
||||
} catch (error: unknown) {
|
||||
// WAC-Allow headers need to be added to 304 responses
|
||||
// as the value can differ even if the representation is the same.
|
||||
if (NotModifiedHttpError.isInstance(error)) {
|
||||
response = error;
|
||||
} else {
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
const { metadata } = response;
|
||||
|
||||
// WAC-Allow is only needed for HEAD/GET requests
|
||||
@ -81,6 +93,10 @@ export class WacAllowHttpHandler extends OperationHttpHandler {
|
||||
this.addWacAllowMetadata(metadata, everyone, user);
|
||||
}
|
||||
|
||||
if (NotModifiedHttpError.isInstance(response)) {
|
||||
throw response;
|
||||
}
|
||||
|
||||
return response;
|
||||
}
|
||||
|
||||
|
@ -11,6 +11,7 @@ import type { HttpRequest } from '../../../src/server/HttpRequest';
|
||||
import type { HttpResponse } from '../../../src/server/HttpResponse';
|
||||
import type { OperationHttpHandler } from '../../../src/server/OperationHttpHandler';
|
||||
import { WacAllowHttpHandler } from '../../../src/server/WacAllowHttpHandler';
|
||||
import { NotModifiedHttpError } from '../../../src/util/errors/NotModifiedHttpError';
|
||||
import { IdentifierMap, IdentifierSetMultiMap } from '../../../src/util/map/IdentifierMap';
|
||||
import { ACL, AUTH } from '../../../src/util/Vocabularies';
|
||||
|
||||
@ -77,6 +78,43 @@ describe('A WacAllowHttpHandler', (): void => {
|
||||
});
|
||||
});
|
||||
|
||||
it('adds permission metadata for 304 responses.', async(): Promise<void> => {
|
||||
permissionReader.handleSafe.mockResolvedValueOnce(new IdentifierMap(
|
||||
[[ target, { read: true, write: true, append: false }]],
|
||||
));
|
||||
|
||||
source.handleSafe.mockRejectedValueOnce(new NotModifiedHttpError());
|
||||
let error: unknown;
|
||||
try {
|
||||
await handler.handle({ operation, request, response });
|
||||
} catch (err: unknown) {
|
||||
error = err;
|
||||
}
|
||||
expect(NotModifiedHttpError.isInstance(error)).toBe(true);
|
||||
expect((error as NotModifiedHttpError).metadata.getAll(AUTH.terms.userMode))
|
||||
.toEqualRdfTermArray([ ACL.terms.Read, ACL.terms.Write ]);
|
||||
expect((error as NotModifiedHttpError).metadata.getAll(AUTH.terms.publicMode))
|
||||
.toEqualRdfTermArray([ ACL.terms.Read, ACL.terms.Write ]);
|
||||
|
||||
expect(source.handleSafe).toHaveBeenCalledTimes(1);
|
||||
expect(source.handleSafe).toHaveBeenLastCalledWith({ operation, request, response });
|
||||
expect(credentialsExtractor.handleSafe).toHaveBeenCalledTimes(1);
|
||||
expect(credentialsExtractor.handleSafe).toHaveBeenLastCalledWith(request);
|
||||
expect(modesExtractor.handleSafe).toHaveBeenCalledTimes(1);
|
||||
expect(modesExtractor.handleSafe).toHaveBeenLastCalledWith(operation);
|
||||
expect(permissionReader.handleSafe).toHaveBeenCalledTimes(1);
|
||||
expect(permissionReader.handleSafe).toHaveBeenLastCalledWith({
|
||||
credentials: await credentialsExtractor.handleSafe.mock.results[0].value,
|
||||
requestedModes: await modesExtractor.handleSafe.mock.results[0].value,
|
||||
});
|
||||
});
|
||||
|
||||
it('rethrows errors.', async(): Promise<void> => {
|
||||
const error = new Error('bad data');
|
||||
source.handleSafe.mockRejectedValueOnce(error);
|
||||
await expect(handler.handle({ operation, request, response })).rejects.toThrow(error);
|
||||
});
|
||||
|
||||
it('determines public permissions separately in case of an authenticated request.', async(): Promise<void> => {
|
||||
credentialsExtractor.handleSafe.mockResolvedValue({ agent: { webId: 'http://example.com/#me' }});
|
||||
permissionReader.handleSafe.mockResolvedValueOnce(new IdentifierMap(
|
||||
|
Loading…
x
Reference in New Issue
Block a user