Skip to content

Commit

Permalink
fix: introduce security related linter and fix warnings (#106)
Browse files Browse the repository at this point in the history
  • Loading branch information
magicmatatjahu authored Jul 9, 2020
1 parent 5ef22a3 commit 9c5f891
Show file tree
Hide file tree
Showing 17 changed files with 272 additions and 327 deletions.
6 changes: 5 additions & 1 deletion .eslintrc
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,12 @@ env:
plugins:
- sonarjs
- mocha
- security

extends:
- plugin:sonarjs/recommended
- plugin:mocha/recommended
- plugin:security/recommended

parserOptions:
ecmaVersion: 2018
Expand Down Expand Up @@ -102,4 +104,6 @@ overrides:
- files: "test/**"
rules:
prefer-arrow-callback: 0
sonarjs/no-duplicate-string: 0
sonarjs/no-duplicate-string: 0
security/detect-object-injection: 0
security/detect-non-literal-fs-filename: 0
2 changes: 1 addition & 1 deletion lib/customValidators.js
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,7 @@ function validateOperationId(parsedJSON, asyncapiYAMLorJSON, initialFormat, oper

chnlsMap.forEach((chnlObj,chnlName) => {
operations.forEach(opName => {
const op = chnlObj[opName];
const op = chnlObj[String(opName)];
if (op) addDuplicateToMap(op, chnlName, opName);
});
});
Expand Down
17 changes: 9 additions & 8 deletions lib/models/asyncapi.js
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
const { createMapOfType, getMapKeyOfType, addExtensions } = require('../utils');
const { createMapOfType, getMapValueOfType, addExtensions } = require('../utils');
const Base = require('./base');
const Info = require('./info');
const Server = require('./server');
const Channel = require('./channel');
const Components = require('./components');
const Tag = require('./tag');

const xParserMessageName = 'x-parser-message-name';
const xParserSchemaId = 'x-parser-schema-id';

Expand Down Expand Up @@ -66,7 +67,7 @@ class AsyncAPIDocument extends Base {
* @returns {Server}
*/
server(name) {
return getMapKeyOfType(this._json.servers, name, Server);
return getMapValueOfType(this._json.servers, name, Server);
}

/**
Expand Down Expand Up @@ -96,7 +97,7 @@ class AsyncAPIDocument extends Base {
* @returns {Channel}
*/
channel(name) {
return getMapKeyOfType(this._json.channels, name, Channel, this);
return getMapValueOfType(this._json.channels, name, Channel, this);
}

/**
Expand Down Expand Up @@ -199,7 +200,7 @@ function assignNameToComponentMessages(doc) {
if (doc.hasComponents()) {
for (const [key, m] of Object.entries(doc.components().messages())) {
if (m.name() === undefined) {
m.json()[xParserMessageName] = key;
m.json()[String(xParserMessageName)] = key;
}
}
}
Expand All @@ -214,7 +215,7 @@ function assignUidToParameterSchemas(doc) {
doc.channelNames().forEach(channelName => {
const channel = doc.channel(channelName);
for (const [parameterKey, parameterSchema] of Object.entries(channel.parameters())) {
parameterSchema.json()[xParserSchemaId] = parameterKey;
parameterSchema.json()[String(xParserSchemaId)] = parameterKey;
}
});
}
Expand All @@ -227,7 +228,7 @@ function assignUidToParameterSchemas(doc) {
function assignUidToComponentSchemas(doc) {
if (doc.hasComponents()) {
for (const [key, s] of Object.entries(doc.components().schemas())) {
s.json()[xParserSchemaId] = key;
s.json()[String(xParserSchemaId)] = key;
}
}
}
Expand Down Expand Up @@ -257,7 +258,7 @@ function assignNameToAnonymousMessages(doc) {
function addNameToKey(messages, number) {
messages.forEach(m => {
if (m.name() === undefined) {
m.json()[xParserMessageName] = `<anonymous-message-${number}>`;
m.json()[String(xParserMessageName)] = `<anonymous-message-${number}>`;
}
});
}
Expand Down Expand Up @@ -362,7 +363,7 @@ function assignIdToAnonymousSchemas(doc) {
let anonymousSchemaCounter = 0;
const callback = (schema) => {
if (!schema.uid()) {
schema.json()[xParserSchemaId] = `<anonymous-schema-${++anonymousSchemaCounter}>`;
schema.json()[String(xParserSchemaId)] = `<anonymous-schema-${++anonymousSchemaCounter}>`;
}
};
schemaDocument(doc, callback);
Expand Down
2 changes: 1 addition & 1 deletion lib/models/base.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ class Base {
json(key) {
if (key === undefined) return this._json;
if (!this._json) return;
return this._json[key];
return this._json[String(key)];
}
}

Expand Down
6 changes: 3 additions & 3 deletions lib/models/channel.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
const { createMapOfType, getMapKeyOfType, addExtensions } = require('../utils');
const { createMapOfType, getMapValueOfType, getMapValueByKey, addExtensions } = require('../utils');
const Base = require('./base');
const ChannelParameter = require('./channel-parameter');
const PublishOperation = require('./publish-operation');
Expand Down Expand Up @@ -30,7 +30,7 @@ class Channel extends Base {
* @returns {ChannelParameter}
*/
parameter(name) {
return getMapKeyOfType(this._json.parameters, name, ChannelParameter);
return getMapValueOfType(this._json.parameters, name, ChannelParameter);
}

/**
Expand Down Expand Up @@ -82,7 +82,7 @@ class Channel extends Base {
* @returns {Object}
*/
binding(name) {
return this._json.bindings ? this._json.bindings[name] : null;
return getMapValueByKey(this._json.bindings, name);
}
}

Expand Down
16 changes: 8 additions & 8 deletions lib/models/components.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
const { getMapKeyOfType, createMapOfType, addExtensions } = require('../utils');
const { createMapOfType, getMapValueOfType, addExtensions } = require('../utils');
const Base = require('./base');
const Message = require('./message');
const Schema = require('./schema');
Expand Down Expand Up @@ -26,7 +26,7 @@ class Components extends Base {
* @returns {Message}
*/
message(name) {
return getMapKeyOfType(this._json.messages, name, Message);
return getMapValueOfType(this._json.messages, name, Message);
}

/**
Expand All @@ -40,7 +40,7 @@ class Components extends Base {
* @returns {Schema}
*/
schema(name) {
return getMapKeyOfType(this._json.schemas, name, Schema);
return getMapValueOfType(this._json.schemas, name, Schema);
}

/**
Expand All @@ -54,7 +54,7 @@ class Components extends Base {
* @returns {SecurityScheme}
*/
securityScheme(name) {
return getMapKeyOfType(this._json.securitySchemes, name, SecurityScheme);
return getMapValueOfType(this._json.securitySchemes, name, SecurityScheme);
}

/**
Expand All @@ -68,7 +68,7 @@ class Components extends Base {
* @returns {ChannelParameter}
*/
parameter(name) {
return getMapKeyOfType(this._json.parameters, name, ChannelParameter);
return getMapValueOfType(this._json.parameters, name, ChannelParameter);
}

/**
Expand All @@ -82,7 +82,7 @@ class Components extends Base {
* @returns {CorrelationId}
*/
correlationId(name) {
return getMapKeyOfType(this._json.correlationIds, name, CorrelationId);
return getMapValueOfType(this._json.correlationIds, name, CorrelationId);
}

/**
Expand All @@ -96,7 +96,7 @@ class Components extends Base {
* @returns {OperationTrait}
*/
operationTrait(name) {
return getMapKeyOfType(this._json.operationTraits, name, OperationTrait);
return getMapValueOfType(this._json.operationTraits, name, OperationTrait);
}

/**
Expand All @@ -110,7 +110,7 @@ class Components extends Base {
* @returns {MessageTrait}
*/
messageTrait(name) {
return getMapKeyOfType(this._json.messageTraits, name, MessageTrait);
return getMapValueOfType(this._json.messageTraits, name, MessageTrait);
}
}

Expand Down
6 changes: 3 additions & 3 deletions lib/models/message-traitable.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
const { getMapKeyOfType, addExtensions } = require('../utils');
const { getMapValueOfType, getMapValueByKey, addExtensions } = require('../utils');
const Base = require('./base');
const Tag = require('./tag');
const ExternalDocs = require('./external-docs');
Expand Down Expand Up @@ -26,7 +26,7 @@ class MessageTraitable extends Base {
*/
header(name) {
if (!this._json.headers) return null;
return getMapKeyOfType(this._json.headers.properties, name, Schema);
return getMapValueOfType(this._json.headers.properties, name, Schema);
}

/**
Expand Down Expand Up @@ -114,7 +114,7 @@ class MessageTraitable extends Base {
* @returns {Object}
*/
binding(name) {
return this._json.bindings ? this._json.bindings[name] : null;
return getMapValueByKey(this._json.bindings, name);
}

/**
Expand Down
4 changes: 2 additions & 2 deletions lib/models/operation-traitable.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
const { addExtensions } = require('../utils');
const { getMapValueByKey, addExtensions } = require('../utils');
const Base = require('./base');
const Tag = require('./tag');
const ExternalDocs = require('./external-docs');
Expand Down Expand Up @@ -66,7 +66,7 @@ class OperationTraitable extends Base {
* @returns {Object}
*/
binding(name) {
return this._json.bindings ? this._json.bindings[name] : null;
return getMapValueByKey(this._json.bindings, name);
}
}

Expand Down
4 changes: 2 additions & 2 deletions lib/models/operation.js
Original file line number Diff line number Diff line change
Expand Up @@ -30,10 +30,10 @@ class Operation extends OperationTraitable {
* @returns {Message}
*/
message(index) {
if (!this._json.message) return null;
if (typeof index !== 'number' || !this._json.message) return null;
if (!this._json.message.oneOf) return new Message(this._json.message);
if (index > this._json.message.oneOf.length - 1) return null;
return new Message(this._json.message.oneOf[index]);
return new Message(this._json.message.oneOf[+index]);
}
}

Expand Down
8 changes: 2 additions & 6 deletions lib/models/schema.js
Original file line number Diff line number Diff line change
Expand Up @@ -232,12 +232,8 @@ class Schema extends Base {
dependencies() {
if (!this._json.dependencies) return null;
const result = {};
Object.keys(this._json.dependencies).forEach(k => {
if (!Array.isArray(this._json.dependencies[k])) {
result[k] = new Schema(this._json.dependencies[k]);
} else {
result[k] = this._json.dependencies[k];
}
Object.entries(this._json.dependencies).forEach(([key, value]) => {
result[String(key)] = !Array.isArray(value) ? new Schema(value) : value;
});
return result;
}
Expand Down
6 changes: 3 additions & 3 deletions lib/models/server.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
const { createMapOfType, getMapKeyOfType, addExtensions } = require('../utils');
const { createMapOfType, getMapValueOfType, getMapValueByKey, addExtensions } = require('../utils');
const Base = require('./base');
const ServerVariable = require('./server-variable');
const ServerSecurityRequirement = require('./server-security-requirement');
Expand Down Expand Up @@ -50,7 +50,7 @@ class Server extends Base {
* @returns {ServerVariable}
*/
variable(name) {
return getMapKeyOfType(this._json.variables, name, ServerVariable);
return getMapValueOfType(this._json.variables, name, ServerVariable);
}

/**
Expand Down Expand Up @@ -80,7 +80,7 @@ class Server extends Base {
* @returns {Object}
*/
binding(name) {
return this._json.bindings ? this._json.bindings[name] : null;
return getMapValueByKey(this._json.bindings, name);
}
}

Expand Down
22 changes: 11 additions & 11 deletions lib/parser.js
Original file line number Diff line number Diff line change
Expand Up @@ -155,30 +155,30 @@ async function customDocumentOperations(js, asyncapiYAMLorJSON, initialFormat, o
validateChannelParams(js, asyncapiYAMLorJSON, initialFormat);
validateOperationId(js, asyncapiYAMLorJSON, initialFormat, OPERATIONS);

for (const channelName in js.channels) {
const channel = js.channels[channelName];
const convert = OPERATIONS.map(async (opName) => {
const op = channel[opName];
const promisesArray = [];
Object.entries(js.channels).forEach(([channelName, channel]) => {
promisesArray.push(...OPERATIONS.map(async (opName) => {
const op = channel[String(opName)];
if (op) {
const messages = op.message ? (op.message.oneOf || [op.message]) : [];
const pathToPayload = `/channels/${ channelName }/${ opName }/message/payload`;
if (options.applyTraits) {
applyTraits(op);
messages.forEach(m => applyTraits(m));
}
const pathToPayload = `/channels/${channelName}/${opName}/message/payload`;
for (const m of messages) {
await validateAndConvertMessage(m, asyncapiYAMLorJSON, initialFormat, js, pathToPayload);
}
}
});
await Promise.all(convert);
}
}));
});
await Promise.all(promisesArray);
}

async function validateAndConvertMessage(msg, originalAsyncAPIDocument, fileFormat, parsedAsyncAPIDocument, pathToPayload) {
const schemaFormat = msg.schemaFormat || DEFAULT_SCHEMA_FORMAT;

await PARSERS[schemaFormat]({
await PARSERS[String(schemaFormat)]({
schemaFormat,
message: msg,
defaultSchemaFormat: DEFAULT_SCHEMA_FORMAT,
Expand Down Expand Up @@ -208,15 +208,15 @@ function registerSchemaParser(parserModule) {
});

parserModule.getMimeTypes().forEach((schemaFormat) => {
PARSERS[schemaFormat] = parserModule.parse;
PARSERS[String(schemaFormat)] = parserModule.parse;
});
}

function applyTraits(js) {
if (Array.isArray(js.traits)) {
for (const trait of js.traits) {
for (const key in trait) {
js[key] = mergePatch(js[key], trait[key]);
js[String(key)] = mergePatch(js[String(key)], trait[String(key)]);
}
}

Expand Down
Loading

0 comments on commit 9c5f891

Please sign in to comment.