module.exports = function (app) { var Response = require('../lib/httpResponse.js'); var acl = require('../lib/auth').acl; var Vulnerability = require('mongoose').model('Vulnerability'); var VulnerabilityType = require('mongoose').model('VulnerabilityType'); var VulnerabilityCategory = require('mongoose').model( 'VulnerabilityCategory', ); var VulnerabilityUpdate = require('mongoose').model('VulnerabilityUpdate'); // Get vulnerabilities list app.get( '/api/vulnerabilities', acl.hasPermission('vulnerabilities:read'), function (req, res) { Vulnerability.getAll() .then(msg => Response.Ok(res, msg)) .catch(err => Response.Internal(res, err)); }, ); // Get vulnerabilities for export app.get( '/api/vulnerabilities/export', acl.hasPermission('vulnerabilities:read'), function (req, res) { Vulnerability.export() .then(msg => Response.Ok(res, msg)) .catch(err => Response.Internal(res, err)); }, ); // Create vulnerabilities (array of vulnerabilities) app.post( '/api/vulnerabilities', acl.hasPermission('vulnerabilities:create'), function (req, res) { for (var i = 0; i < req.body.length; i++) { var vuln = req.body[i]; if (!vuln.details) { Response.BadParameters( res, 'Required parameters: details.locale, details.title', ); return; } var index = vuln.details.findIndex( obj => obj.locale && obj.locale !== '' && obj.title && obj.title !== '', ); if (index < 0) { Response.BadParameters( res, 'Required parameters: details.locale, details.title', ); return; } } var vulnerabilities = []; for (var i = 0; i < req.body.length; i++) { var vuln = {}; vuln.cvssv3 = req.body[i].cvssv3 || null; if (req.body[i].priority) vuln.priority = req.body[i].priority; if (req.body[i].remediationComplexity) vuln.remediationComplexity = req.body[i].remediationComplexity; if (req.body[i].category) { vuln.category = req.body[i].category; VulnerabilityCategory.create({ name: vuln.category }).catch(e => {}); } vuln.details = []; req.body[i].details.forEach(d => { if (!d.title || !d.locale) // Array of details may contain entries without title or locale but we don't want to save them return; var details = {}; if (d.locale) details.locale = d.locale; if (d.title) details.title = d.title; if (d.vulnType) { details.vulnType = d.vulnType; VulnerabilityType.create({ locale: d.locale, name: d.vulnType, }).catch(e => {}); } if (d.description) details.description = d.description; if (d.observation) details.observation = d.observation; if (d.remediation) details.remediation = d.remediation; if (d.references) details.references = d.references; if (d.cwes) details.cwes = d.cwes; if (d.customFields) details.customFields = d.customFields; vuln.details.push(details); }); vuln.status = 0; vulnerabilities.push(vuln); } Vulnerability.create(vulnerabilities) .then(msg => Response.Created(res, msg)) .catch(err => Response.Internal(res, err)); }, ); // Update vulnerability app.put( '/api/vulnerabilities/:vulnerabilityId', acl.hasPermission('vulnerabilities:update'), function (req, res) { if (!req.body.details) { Response.BadParameters( res, 'Required parameters: details.locale, details.title', ); return; } var index = req.body.details.findIndex( obj => obj.locale && obj.locale !== '' && obj.title && obj.title !== '', ); if (index < 0) { Response.BadParameters( res, 'Required parameters: details.locale, details.title', ); return; } var vuln = {}; if (req.body.cvssv3) vuln.cvssv3 = req.body.cvssv3; if (req.body.priority) vuln.priority = req.body.priority; if (req.body.remediationComplexity) vuln.remediationComplexity = req.body.remediationComplexity; vuln.category = req.body.category || null; vuln.details = []; req.body.details.forEach(d => { if (!d.title || !d.locale) return; var details = {}; if (d.locale) details.locale = d.locale; if (d.title) details.title = d.title; if (d.vulnType) details.vulnType = d.vulnType; if (d.description) details.description = d.description; if (d.observation) details.observation = d.observation; if (d.remediation) details.remediation = d.remediation; if (d.cwes) details.cwes = d.cwes; if (d.references) details.references = d.references; if (d.customFields) details.customFields = d.customFields; vuln.details.push(details); }); vuln.status = 0; Vulnerability.update(req.params.vulnerabilityId, vuln) .then(msg => { if (req.body.status === 2) VulnerabilityUpdate.deleteAllByVuln(req.params.vulnerabilityId); Response.Ok(res, msg); }) .catch(err => Response.Internal(res, err)); }, ); // Delete vulnerability app.delete( '/api/vulnerabilities/:vulnerabilityId', acl.hasPermission('vulnerabilities:delete'), function (req, res) { Vulnerability.delete(req.params.vulnerabilityId) .then(msg => Response.Ok(res, msg)) .catch(err => Response.Internal(res, err)); }, ); // Delete all vulnerabilities app.delete( '/api/vulnerabilities', acl.hasPermission('vulnerabilities:delete-all'), function (req, res) { Vulnerability.deleteAll() .then(msg => Response.Ok(res, msg)) .catch(err => Response.Internal(res, err)); }, ); // Get vulnerabilities list by language app.get( '/api/vulnerabilities/:locale', acl.hasPermission('vulnerabilities:read'), function (req, res) { Vulnerability.getAllByLanguage(req.params.locale) .then(msg => Response.Ok(res, msg)) .catch(err => Response.Internal(res, err)); }, ); // Create or Update vulnerability from finding for validation app.post( '/api/vulnerabilities/finding/:locale', acl.hasPermission('vulnerability-updates:create'), function (req, res) { if (!req.body.title) { Response.BadParameters(res, 'Required parameters: title'); return; } var vuln = {}; // Required params vuln.title = req.body.title; vuln.locale = req.params.locale; // Optional params vuln.cvssv3 = req.body.cvssv3 || ''; vuln.priority = req.body.priority || null; vuln.remediationComplexity = req.body.remediationComplexity || null; vuln.references = req.body.references || []; vuln.cwes = req.body.cwes || []; vuln.vulnType = req.body.vulnType || null; vuln.description = req.body.description || null; vuln.observation = req.body.observation || null; vuln.remediation = req.body.remediation || null; vuln.category = req.body.category || null; vuln.customFields = req.body.customFields || []; VulnerabilityUpdate.create(req.decodedToken.username, vuln) .then(msg => { if (msg === 'Finding created as new Vulnerability') Response.Created(res, msg); else Response.Ok(res, msg); }) .catch(err => Response.Internal(res, err)); }, ); // Get vulnerability updates form vuln id app.get( '/api/vulnerabilities/updates/:vulnId', acl.hasPermission('vulnerabilities:update'), function (req, res) { VulnerabilityUpdate.getAllByVuln(req.params.vulnId) .then(msg => Response.Ok(res, msg)) .catch(err => Response.Internal(res, err)); }, ); // Merge vulnerability with locale part of another one app.put( '/api/vulnerabilities/merge/:vulnId', acl.hasPermission('vulnerabilities:update'), function (req, res) { if (!req.body.vulnId || !req.body.locale) { Response.BadParameters(res, 'Required parameters: vulnId, locale'); return; } Vulnerability.Merge(req.params.vulnId, req.body.vulnId, req.body.locale) .then(() => Response.Ok(res, 'Vulnerability merge successfully')) .catch(err => Response.Internal(res, err)); }, ); };