fix: ensure loose validation for isEvent and toEvent (#394)
The `HTTP.isEvent()` and `HTTP.toEvent()` functions both had some validation code that violated the principle of loose validation when receiving an event over HTTP. As discussed, the validation should be managed by the receiver in this case with `event.validate()` Signed-off-by: Lance Ball <lball@redhat.com>
This commit is contained in:
parent
93f02130f6
commit
efe466ac7d
|
@ -1,7 +1,14 @@
|
|||
import { CloudEvent, CloudEventV03, CloudEventV1, CONSTANTS, Mode, Version } from "../..";
|
||||
import { Message, Headers } from "..";
|
||||
|
||||
import { headersFor, sanitize, v03structuredParsers, v1binaryParsers, v1structuredParsers } from "./headers";
|
||||
import {
|
||||
headersFor,
|
||||
sanitize,
|
||||
v03binaryParsers,
|
||||
v03structuredParsers,
|
||||
v1binaryParsers,
|
||||
v1structuredParsers,
|
||||
} from "./headers";
|
||||
import { isStringOrObjectOrThrow, ValidationError } from "../../event/validation";
|
||||
import { JSONParser, MappedParser, Parser, parserByContentType } from "../../parsers";
|
||||
|
||||
|
@ -122,23 +129,12 @@ function parseBinary(message: Message, version: Version): CloudEvent {
|
|||
let body = message.body;
|
||||
|
||||
if (!headers) throw new ValidationError("headers is null or undefined");
|
||||
if (body) {
|
||||
isStringOrObjectOrThrow(body, new ValidationError("payload must be an object or a string"));
|
||||
}
|
||||
|
||||
if (
|
||||
headers[CONSTANTS.CE_HEADERS.SPEC_VERSION] &&
|
||||
headers[CONSTANTS.CE_HEADERS.SPEC_VERSION] !== Version.V03 &&
|
||||
headers[CONSTANTS.CE_HEADERS.SPEC_VERSION] !== Version.V1
|
||||
) {
|
||||
throw new ValidationError(`invalid spec version ${headers[CONSTANTS.CE_HEADERS.SPEC_VERSION]}`);
|
||||
}
|
||||
|
||||
// Clone and low case all headers names
|
||||
const sanitizedHeaders = sanitize(headers);
|
||||
|
||||
const eventObj: { [key: string]: unknown | string | Record<string, unknown> } = {};
|
||||
const parserMap: Record<string, MappedParser> = version === Version.V1 ? v1binaryParsers : v1binaryParsers;
|
||||
const parserMap: Record<string, MappedParser> = version === Version.V1 ? v1binaryParsers : v03binaryParsers;
|
||||
|
||||
for (const header in parserMap) {
|
||||
if (sanitizedHeaders[header]) {
|
||||
|
@ -186,14 +182,6 @@ function parseStructured(message: Message, version: Version): CloudEvent {
|
|||
if (!headers) throw new ValidationError("headers is null or undefined");
|
||||
isStringOrObjectOrThrow(payload, new ValidationError("payload must be an object or a string"));
|
||||
|
||||
if (
|
||||
headers[CONSTANTS.CE_HEADERS.SPEC_VERSION] &&
|
||||
headers[CONSTANTS.CE_HEADERS.SPEC_VERSION] != Version.V03 &&
|
||||
headers[CONSTANTS.CE_HEADERS.SPEC_VERSION] != Version.V1
|
||||
) {
|
||||
throw new ValidationError(`invalid spec version ${headers[CONSTANTS.CE_HEADERS.SPEC_VERSION]}`);
|
||||
}
|
||||
|
||||
// Clone and low case all headers names
|
||||
const sanitizedHeaders = sanitize(headers);
|
||||
|
||||
|
|
|
@ -59,6 +59,32 @@ describe("HTTP transport", () => {
|
|||
expect(HTTP.isEvent(message)).to.be.true;
|
||||
});
|
||||
|
||||
it("Can detect CloudEvent binary Messages with weird versions", () => {
|
||||
// Now create a message that is an event
|
||||
const message = {
|
||||
body: `{ "greeting": "hello" }`,
|
||||
headers: {
|
||||
[CONSTANTS.CE_HEADERS.ID]: "1234",
|
||||
[CONSTANTS.CE_HEADERS.SOURCE]: "test",
|
||||
[CONSTANTS.CE_HEADERS.TYPE]: "test.event",
|
||||
[CONSTANTS.CE_HEADERS.SPEC_VERSION]: "11.8",
|
||||
},
|
||||
};
|
||||
expect(HTTP.isEvent(message)).to.be.true;
|
||||
expect(HTTP.toEvent(message)).not.to.throw;
|
||||
});
|
||||
|
||||
it("Can detect CloudEvent structured Messages with weird versions", () => {
|
||||
// Now create a message that is an event
|
||||
const message = {
|
||||
body: `{ "source": "test", "type": "test.event", "specversion": "11.8"}`,
|
||||
headers: {
|
||||
[CONSTANTS.CE_HEADERS.ID]: "1234",
|
||||
},
|
||||
};
|
||||
expect(HTTP.isEvent(message)).to.be.true;
|
||||
expect(HTTP.toEvent(message)).not.to.throw;
|
||||
});
|
||||
// Allow for external systems to send bad events - do what we can
|
||||
// to accept them
|
||||
it("Does not throw an exception when converting an invalid Message to a CloudEvent", () => {
|
||||
|
|
Loading…
Reference in New Issue