Skip to content

Commit

Permalink
Merge pull request #1087 from CVEProject/dr-1076
Browse files Browse the repository at this point in the history
Resolves #1076 - ADP short name parameter
  • Loading branch information
jdaigneau5 committed Jun 23, 2023
2 parents 596c0ce + c419729 commit 4573236
Show file tree
Hide file tree
Showing 7 changed files with 192 additions and 16 deletions.
24 changes: 24 additions & 0 deletions api-docs/openapi.json
Original file line number Diff line number Diff line change
Expand Up @@ -832,6 +832,12 @@
},
{
"$ref": "#/components/parameters/pageQuery"
},
{
"$ref": "#/components/parameters/cnaModified"
},
{
"$ref": "#/components/parameters/adpShortName"
}
],
"responses": {
Expand Down Expand Up @@ -2644,6 +2650,24 @@
"type": "boolean"
}
},
"cnaModified": {
"in": "query",
"name": "cna_modified",
"description": "Only get CVE records with cnaContainers that have been modified/created within the set time_modified range. Requires at least one time_modified parameter set",
"required": false,
"schema": {
"type": "boolean"
}
},
"adpShortName": {
"in": "query",
"name": "adp_short_name",
"description": "Only get CVE records that have an adpContainer owned by this org and that has been modified/created within the set time_modified range. Requires at least one time_modified parameter set",
"required": false,
"schema": {
"type": "string"
}
},
"cveState": {
"in": "query",
"name": "state",
Expand Down
62 changes: 50 additions & 12 deletions src/controller/cve.controller/cve.controller.js
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ async function getFilteredCves (req, res, next) {
let cnaModified = false
let timeModifiedGtDateObject = null
let timeModifiedLtDateObject = null
let adpShortName = null
const timeModified = {
timeStamp: [],
dateOperator: []
Expand Down Expand Up @@ -81,6 +82,8 @@ async function getFilteredCves (req, res, next) {
assigner = req.ctx.query.assigner
} else if (key === 'cna_modified') {
cnaModified = req.ctx.query.cna_modified
} else if (key === 'adp_short_name') {
adpShortName = req.ctx.query.adp_short_name
}
})

Expand Down Expand Up @@ -144,25 +147,60 @@ async function getFilteredCves (req, res, next) {
const pg = await cveRepo.aggregatePaginate(agt, options)
const payload = {
cveRecords: pg.itemsList.map(val => { return val.cve }).filter((val) => {
// If cnaModified is false, return all values.
if (!cnaModified) {
// If cnaModified AND adpShortName are false, return all values, no filtering to be done.
if (!cnaModified && !adpShortName) {
return true
}
// Check that the CNA has a date updated
if ((val.containers.cna.providerMetadata?.dateUpdated)) {
// If the time modified gt flag is set, and the dateUpdated date is less than the flag
if ((timeModifiedGtDateObject && timeModifiedGtDateObject > toDate(val.containers.cna.providerMetadata?.dateUpdated))) {

// cnaModified and adpShortName are treated as an AND if they are both set
if (cnaModified) {
if (val.containers.cna.providerMetadata?.dateUpdated) {
// If the time modified gt flag is set, and the dateUpdated date is less than the flag
if ((timeModifiedGtDateObject && timeModifiedGtDateObject > toDate(val.containers.cna.providerMetadata?.dateUpdated))) {
return false
}
// if the time modified lt flag is set, and the dateUpdated date is greater than the flag
if ((timeModifiedLtDateObject && timeModifiedLtDateObject < toDate(val.containers.cna.providerMetadata?.dateUpdated))) {
return false
}
} else {
// if cnaModified was set, but there is no value
return false
}
// if the time modified lt flag is set, and the dateUpdated date is greater than the flag
if ((timeModifiedLtDateObject && timeModifiedLtDateObject < toDate(val.containers.cna.providerMetadata?.dateUpdated))) {
}
if (adpShortName) {
// Check to make sure we want to filter ADPs and that the CVE has an ADP container
if (val.containers?.adp && val.containers?.adp?.length) {
// Check all adp containers and if ANY of them have what we are searching for, return them
let adpMatchFound = false
for (const element of val.containers.adp) {
// If shortname is defined AND no dates are set, only check for the short name
if (element.providerMetadata.shortName === adpShortName) {
if (!timeModifiedGtDateObject && !timeModifiedLtDateObject) {
adpMatchFound = true
break
} else {
// otherwise we need to check the dates for a match
if ((timeModifiedGtDateObject && timeModifiedGtDateObject < toDate(element.providerMetadata?.dateUpdated))) {
adpMatchFound = true
break
}
if (timeModifiedLtDateObject && timeModifiedLtDateObject > toDate(element.providerMetadata?.dateUpdated)) {
adpMatchFound = true
break
}
}
}
}
if (!adpMatchFound) {
return false
}
} else {
// if adpShortName was set, BUT we didn't find anything
return false
}
// If the code gets to this point, all checks have passed.
return true
}
// Base fall through case
return false
return true
})
}

Expand Down
2 changes: 1 addition & 1 deletion src/controller/cve.controller/cve.middleware.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ function parsePostParams (req, res, next) {
}

function parseGetParams (req, res, next) {
utils.reqCtxMapping(req, 'query', ['page', 'time_modified.lt', 'time_modified.gt', 'state', 'count_only', 'assigner_short_name', 'assigner', 'cna_modified'])
utils.reqCtxMapping(req, 'query', ['page', 'time_modified.lt', 'time_modified.gt', 'state', 'count_only', 'assigner_short_name', 'assigner', 'cna_modified', 'adp_short_name'])
utils.reqCtxMapping(req, 'params', ['id'])
next()
}
Expand Down
7 changes: 5 additions & 2 deletions src/controller/cve.controller/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,9 @@ router.get('/cve',
'#/components/parameters/countOnly',
'#/components/parameters/assignerShortName',
'#/components/parameters/assigner',
'#/components/parameters/pageQuery'
'#/components/parameters/pageQuery',
'#/components/parameters/cnaModified',
'#/components/parameters/adpShortName'
]
#swagger.responses[200] = {
description: 'A filtered list of CVE Records, along with pagination fields if results span multiple pages of data',
Expand Down Expand Up @@ -154,7 +156,7 @@ router.get('/cve',
*/
mw.validateUser,
mw.onlySecretariatOrBulkDownload,
query().custom((query) => { return mw.validateQueryParameterNames(query, ['page', 'time_modified.lt', 'time_modified.gt', 'state', 'count_only', 'assigner_short_name', 'assigner', 'cna_modified']) }),
query().custom((query) => { return mw.validateQueryParameterNames(query, ['page', 'time_modified.lt', 'time_modified.gt', 'state', 'count_only', 'assigner_short_name', 'assigner', 'cna_modified', 'adp_short_name']) }),
query(['page']).optional().isInt({ min: CONSTANTS.PAGINATOR_PAGE }),
query(['time_modified.lt']).optional().isString().trim().escape().customSanitizer(val => { return toDate(val) }).not().isEmpty().withMessage(errorMsgs.TIMESTAMP_FORMAT),
query(['time_modified.gt']).optional().isString().trim().escape().customSanitizer(val => { return toDate(val) }).not().isEmpty().withMessage(errorMsgs.TIMESTAMP_FORMAT),
Expand All @@ -163,6 +165,7 @@ router.get('/cve',
query(['assigner_short_name']).optional().isString().trim().escape().notEmpty().isLength({ min: CONSTANTS.MIN_SHORTNAME_LENGTH, max: CONSTANTS.MAX_SHORTNAME_LENGTH }),
query(['assigner']).optional().isString().trim().escape().notEmpty(),
query(['cna_modified']).optional().isBoolean({ loose: true }).withMessage(errorMsgs.CNA_MODIFIED),
query(['adp_short_name']).optional().isString().trim().escape().notEmpty().isLength({ min: CONSTANTS.MIN_SHORTNAME_LENGTH, max: CONSTANTS.MAX_SHORTNAME_LENGTH }),
parseError,
parseGetParams,
controller.CVE_GET_FILTERED)
Expand Down
18 changes: 18 additions & 0 deletions src/swagger.js
Original file line number Diff line number Diff line change
Expand Up @@ -187,6 +187,24 @@ const doc = {
type: 'boolean'
}
},
cnaModified: {
in: 'query',
name: 'cna_modified',
description: 'Only get CVE records with cnaContainers that have been modified/created within the set time_modified range. Requires at least one time_modified parameter set',
required: false,
schema: {
type: 'boolean'
}
},
adpShortName: {
in: 'query',
name: 'adp_short_name',
description: 'Only get CVE records that have an adpContainer owned by this org and that has been modified/created within the set time_modified range. Requires at least one time_modified parameter set',
required: false,
schema: {
type: 'string'
}
},
cveState: {
in: 'query',
name: 'state',
Expand Down
83 changes: 83 additions & 0 deletions test/integration-tests/cve/getCveAdpShortNameTest.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
/* eslint-disable no-unused-expressions */
const chai = require('chai')
chai.use(require('chai-http'))
const expect = chai.expect

const constants = require('../constants.js')
const app = require('../../../src/index.js')
const helpers = require('../helpers.js')
const _ = require('lodash')

const shortName = 'win_5'

describe('Test cna_modified parameter for get CVE', () => {
let cveId
before(async () => {
cveId = await helpers.cveIdReserveHelper(1, '2023', shortName, 'non-sequential')
await helpers.cveRequestAsCnaHelper(cveId)
await helpers.cveUpdateAsCnaHelperWithAdpContainer(cveId, constants.testAdp)
})
context('Positive Test', () => {
it('CVE should not be returned with adp_short_name set to fake_org as it does not exist', async () => {
await chai.request(app)
.get('/api/cve/?adp_short_name=fake_org')
.set(constants.headers)
.then((res, err) => {
expect(err).to.be.undefined
expect(res).to.have.status(200)
expect(_.some(res.body.cveRecords, { cveMetadata: { cveId: cveId } })).to.be.false
})
})
it(`CVE should be returned with adp_short_name set to ${shortName} as it has been created`, async () => {
await chai.request(app)
.get(`/api/cve/?adp_short_name=${shortName}`)
.set(constants.headers)
.then((res, err) => {
expect(err).to.be.undefined
expect(res).to.have.status(200)
expect(_.some(res.body.cveRecords, { cveMetadata: { cveId: cveId } })).to.be.true
})
})
it(`Get CVE with adp_short_name set to ${shortName} AND date.gt should return when searched with a known earlier than date`, async () => {
await chai.request(app)
.get(`/api/cve/?time_modified.gt=2022-01-01T00:00:00&adp_short_name=${shortName}`)
.set(constants.headers)
.then((res, err) => {
expect(err).to.be.undefined
expect(res).to.have.status(200)
expect(_.some(res.body.cveRecords, { cveMetadata: { cveId: cveId } })).to.be.true
})
})
it(`Get CVE with with adp_short_name set to ${shortName} AND date.gt should return and empty list when searched with a known bad earlier than date`, async () => {
await chai.request(app)
.get(`/api/cve/?time_modified.gt=2100-01-01T00:00:00&adp_short_name=${shortName}`)
.set(constants.headers)
.then((res, err) => {
expect(err).to.be.undefined
expect(res).to.have.status(200)
expect(_.some(res.body.cveRecords, { cveMetadata: { cveId: cveId } })).to.be.false
})
})

it(`Get CVE with adp_short_name set to ${shortName} AND date.lt should return when searched with a known later than date`, async () => {
await chai.request(app)
.get(`/api/cve/?time_modified.lt=2100-01-01T00:00:00&adp_short_name=${shortName}`)
.set(constants.headers)
.then((res, err) => {
expect(err).to.be.undefined
expect(res).to.have.status(200)
expect(_.some(res.body.cveRecords, { cveMetadata: { cveId: cveId } })).to.be.true
})
})
it(`Get CVE with adp_short_name set to ${shortName} AND date.lt should return and empty list when searched with a known bad later than date`, async () => {
await chai.request(app)
.get(`/api/cve/?time_modified.lt=2022-01-01T00:00:00&adp_short_name=${shortName}`)
.set(constants.headers)
.then((res, err) => {
expect(err).to.be.undefined
expect(res).to.have.status(200)
expect(_.some(res.body.cveRecords, { cveMetadata: { cveId: cveId } })).to.be.false
})
})
})
})
12 changes: 11 additions & 1 deletion test/integration-tests/helpers.js
Original file line number Diff line number Diff line change
Expand Up @@ -51,4 +51,14 @@ async function cveUpdatetAsCnaHelperWithCnaContainer (cveId, cnaContainer) {
})
}

module.exports = { cveIdReserveHelper, cveRequestAsCnaHelper, cveRequestAsCnaHelperWithCnaContainer, cveUpdatetAsCnaHelperWithCnaContainer }
async function cveUpdateAsCnaHelperWithAdpContainer (cveId, adpContainer) {
await chai.request(app)
.put(`/api/cve/${cveId}/adp`)
.set(constants.nonSecretariatUserHeaders)
.send(adpContainer)
.then((res, err) => {
expect(res).to.have.status(200)
})
}

module.exports = { cveIdReserveHelper, cveRequestAsCnaHelper, cveRequestAsCnaHelperWithCnaContainer, cveUpdatetAsCnaHelperWithCnaContainer, cveUpdateAsCnaHelperWithAdpContainer }

0 comments on commit 4573236

Please sign in to comment.