Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
63 commits
Select commit Hold shift + click to select a range
94e650d
Merge pull request #966 from CVEProject/int
brettp Dec 19, 2022
97453ff
Merge pull request #967 from CVEProject/prod-staging
brettp Dec 19, 2022
5d3bcac
Merge pull request #1024 from CVEProject/int
slubar Feb 13, 2023
400f853
Merge branch 'master' into prod-staging
jdaigneau5 Feb 13, 2023
b810e60
Merge pull request #1025 from CVEProject/prod-staging
slubar Feb 13, 2023
67a3af4
Merge pull request #1046 from CVEProject/int
jdaigneau5 Mar 15, 2023
a21eb54
Merge branch 'master' into prod-staging
jdaigneau5 Mar 15, 2023
12d439c
Merge pull request #1047 from CVEProject/prod-staging
slubar Mar 15, 2023
14f1103
Merge pull request #1069 from CVEProject/int
jdaigneau5 May 1, 2023
b53f7a7
Merge branch 'master' into prod-staging
jdaigneau5 May 1, 2023
e53e207
Merge pull request #1070 from CVEProject/prod-staging
jdaigneau5 May 1, 2023
6501352
Merge pull request #1174 from CVEProject/int
david-rocca Jan 17, 2024
3577f5f
Merge branch 'master' into prod-staging
jdaigneau5 Jan 17, 2024
5a9522a
Merge pull request #1175 from CVEProject/prod-staging
david-rocca Jan 17, 2024
5a94e25
Merge pull request #1188 from CVEProject/int
david-rocca Feb 21, 2024
16712ea
Merge branch 'master' into prod-staging
jdaigneau5 Feb 21, 2024
d92c78f
Merge pull request #1189 from CVEProject/prod-staging
david-rocca Feb 21, 2024
e02e4e2
Merge pull request #1193 from CVEProject/int
david-rocca Mar 8, 2024
8c196ee
Merge pull request #1196 from CVEProject/int
david-rocca Mar 13, 2024
5257a3f
Merge pull request #1202 from CVEProject/int
david-rocca Mar 13, 2024
26591ea
Merge pull request #1213 from CVEProject/int
david-rocca Mar 19, 2024
5e5fb7d
Merge branch 'master' into prod-staging
jdaigneau5 May 8, 2024
5c1303b
Merge pull request #1225 from CVEProject/prod-staging
david-rocca May 8, 2024
0d221a5
Merge pull request #1228 from CVEProject/int
david-rocca May 15, 2024
d9667f9
Merge branch 'master' into prod-staging
jdaigneau5 May 15, 2024
30b2115
Merge pull request #1229 from CVEProject/prod-staging
david-rocca May 15, 2024
7e94708
Merge pull request #1234 from CVEProject/int
david-rocca May 16, 2024
d7588c7
Merge branch 'master' into prod-staging
jdaigneau5 May 16, 2024
aab47b8
Merge pull request #1235 from CVEProject/prod-staging
david-rocca May 16, 2024
0140e90
Merge pull request #1260 from CVEProject/int
david-rocca Jul 24, 2024
ad4cf9a
Merge branch 'master' into prod-staging
jdaigneau5 Jul 24, 2024
89aac9d
Merge pull request #1261 from CVEProject/prod-staging
david-rocca Jul 24, 2024
407589b
Merge pull request #1271 from CVEProject/int
ann-linh-mitre Aug 26, 2024
4112d47
Merge pull request #1292 from CVEProject/int
david-rocca Nov 8, 2024
be7432a
Merge pull request #1298 from CVEProject/int
jdaigneau5 Nov 26, 2024
b6de292
Merge branch 'master' into prod-staging
david-rocca Dec 4, 2024
3684a0e
Merge pull request #1302 from CVEProject/prod-staging
jdaigneau5 Dec 4, 2024
4aa8529
updating version to 2.5.0
david-rocca Dec 4, 2024
385a4b4
Merge pull request #1303 from CVEProject/2.5.0_version_number_update
jdaigneau5 Dec 4, 2024
e2ca551
Merge pull request #1319 from CVEProject/int
jdaigneau5 Jan 8, 2025
0d96104
Merge pull request #1325 from CVEProject/int
jdaigneau5 Jan 15, 2025
2e31733
Version Number merge conflict
david-rocca Jan 22, 2025
db48f78
Merge pull request #1331 from CVEProject/prod-staging
jdaigneau5 Jan 22, 2025
5ad33bd
Merge pull request #1337 from CVEProject/int
jdaigneau5 Feb 10, 2025
c380f0c
Merge pull request #1346 from CVEProject/int
jdaigneau5 Feb 19, 2025
2829736
Merge branch 'master' into prod-staging
david-rocca Feb 19, 2025
287f00c
Merge pull request #1348 from CVEProject/prod-staging
jdaigneau5 Feb 19, 2025
18c1366
add new api endpoint accessible to all users for getting cve record c…
emathew5 Mar 21, 2025
595bb33
remove required count_only param
emathew5 Mar 31, 2025
c03099a
Merge branch 'master' into int
david-rocca Apr 2, 2025
1f5248e
add integration test and update swagger docs
emathew5 Apr 3, 2025
462a90a
lint-src
emathew5 Apr 3, 2025
f24fb2e
lint test
emathew5 Apr 3, 2025
3af87be
Merge branch 'dev' into emathew/unprivileged-get-cve-count
emathew5 Apr 3, 2025
b75d942
remove count_only as a parameter
emathew5 Apr 7, 2025
fa472d2
Merge pull request #1379 from CVEProject/emathew/unprivileged-get-cve…
david-rocca Apr 9, 2025
e3993da
re-wrote the for loop to correctly terminate on the return
david-rocca May 12, 2025
33f53e9
Update mongoose usage to no longer use n
david-rocca May 12, 2025
6a8840e
Merge pull request #1384 from CVEProject/dr_incorrect_return
jdaigneau5 May 13, 2025
b557e8a
version number updates
david-rocca May 14, 2025
0004e1d
Merge pull request #1386 from CVEProject/dr_v2.5.4_version_number
jdaigneau5 May 14, 2025
10ca105
Merge branch 'int' into dev
david-rocca May 14, 2025
f0a8638
Merge pull request #1387 from CVEProject/dev
jdaigneau5 May 14, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
61 changes: 59 additions & 2 deletions api-docs/openapi.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"openapi": "3.0.2",
"info": {
"version": "2.5.3",
"version": "2.5.4",
"title": "CVE Services API",
"description": "The CVE Services API supports automation tooling for the CVE Program. Credentials are required for most service endpoints. Representatives of <a href='https://www.cve.org/ProgramOrganization/CNAs'>CVE Numbering Authorities (CNAs)</a> should use one of the methods below to obtain credentials: <ul><li>If your organization already has an Organizational Administrator (OA) account for the CVE Services, ask your admin for credentials</li> <li>Contact your Root (<a href='https://www.cve.org/PartnerInformation/ListofPartners/partner/Google'>Google</a>, <a href='https://www.cve.org/PartnerInformation/ListofPartners/partner/INCIBE'>INCIBE</a>, <a href='https://www.cve.org/PartnerInformation/ListofPartners/partner/jpcert'>JPCERT/CC</a>, or <a href='https://www.cve.org/PartnerInformation/ListofPartners/partner/redhat'>Red Hat</a>) or Top-Level Root (<a href='https://www.cve.org/PartnerInformation/ListofPartners/partner/icscert'>CISA ICS</a> or <a href='https://www.cve.org/PartnerInformation/ListofPartners/partner/mitre'>MITRE</a>) to request credentials </ul> <p>CVE data is to be in the JSON 5.1 CVE Record format. Details of the JSON 5.1 schema are located <a href='https://github.com/CVEProject/cve-schema/tree/v5.1.1-rc2/schema' target='_blank'>here</a>.</p> <a href='https://cveform.mitre.org/' class='link' target='_blank'>Contact the CVE Services team</a>",
"contact": {
Expand Down Expand Up @@ -1190,6 +1190,63 @@
}
}
},
"/cve_count": {
"get": {
"tags": [
"CVE Record"
],
"summary": "Retrieves the count of all the CVE Records after applying the query parameters as filters (accessible to all users)",
"description": " <h2>Access Control</h2> <p>Endpoint is accessible to all</p> <h2>Expected Behavior</h2> <p>Retrieves the count of all CVE records for all organizations</p>",
"operationId": "cveGetFilteredCount",
"parameters": [
{
"$ref": "#/components/parameters/cveState"
}
],
"responses": {
"200": {
"description": "A count of the total number of filtered CVE records",
"content": {
"application/json": {
"schema": {
"$ref": "../schemas/cve/get-cve-record-count.json"
}
}
}
},
"400": {
"description": "Bad Request",
"content": {
"application/json": {
"schema": {
"$ref": "../schemas/errors/bad-request.json"
}
}
}
},
"404": {
"description": "Not Found",
"content": {
"application/json": {
"schema": {
"$ref": "../schemas/errors/generic.json"
}
}
}
},
"500": {
"description": "Internal Server Error",
"content": {
"application/json": {
"schema": {
"$ref": "../schemas/errors/generic.json"
}
}
}
}
}
}
},
"/cve_cursor": {
"get": {
"tags": [
Expand Down Expand Up @@ -4991,4 +5048,4 @@
}
}
}
}
}
4 changes: 2 additions & 2 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "cve-services",
"author": "Automation Working Group",
"version": "2.5.3",
"version": "2.5.4",
"license": "(CC0)",
"devDependencies": {
"@faker-js/faker": "^7.6.0",
Expand Down
10 changes: 10 additions & 0 deletions schemas/cve/get-cve-record-count.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
{
"$schema": "http://json-schema.org/draft-04/schema",
"type": "object",
"properties": {
"totalCount": {
"type": "integer",
"format": "int32"
}
}
}
12 changes: 12 additions & 0 deletions src/controller/cve.controller/cve.controller.js
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,17 @@ async function getCve (req, res, next) {
}
}

// Called by GET /cve
async function getFilteredCveCount (req, res, next) {
try {
req.ctx.query.count_only = '1'
const result = await getFilteredCves(req, res, next)
return result
} catch (err) {
next(err)
}
}

// Called by GET /cve
async function getFilteredCves (req, res, next) {
const CONSTANTS = getConstants()
Expand Down Expand Up @@ -916,6 +927,7 @@ module.exports = {
CVE_GET_SINGLE: getCve,
CVE_GET_FILTERED: getFilteredCves,
CVE_GET_FILTERED_CURSOR: getFilteredCvesCursor,
CVE_GET_FILTERED_COUNT: getFilteredCveCount,
CVE_SUBMIT: submitCve,
CVE_UPDATE_SINGLE: updateCve,
CVE_SUBMIT_CNA: submitCna,
Expand Down
52 changes: 52 additions & 0 deletions src/controller/cve.controller/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -274,6 +274,58 @@ router.get('/cve',
parseGetParams,
controller.CVE_GET_FILTERED)

router.get('/cve_count',
/*
#swagger.tags = ['CVE Record']
#swagger.operationId = 'cveGetFilteredCount'
#swagger.summary = "Retrieves the count of all the CVE Records after applying the query parameters as filters (accessible to all users)"
#swagger.description = "
<h2>Access Control</h2>
<p>Endpoint is accessible to all</p>
<h2>Expected Behavior</h2>
<p>Retrieves the count of all CVE records for all organizations</p>"
#swagger.parameters['$ref'] = [
'#/components/parameters/cveState',
]
#swagger.responses[200] = {
description: 'A count of the total number of filtered CVE records',
content: {
"application/json": {
schema: { $ref: '../schemas/cve/get-cve-record-count.json' }
}
}
}
#swagger.responses[400] = {
description: 'Bad Request',
content: {
"application/json": {
schema: { $ref: '../schemas/errors/bad-request.json' }
}
}
}
#swagger.responses[404] = {
description: 'Not Found',
content: {
"application/json": {
schema: { $ref: '../schemas/errors/generic.json' }
}
}
}
#swagger.responses[500] = {
description: 'Internal Server Error',
content: {
"application/json": {
schema: { $ref: '../schemas/errors/generic.json' }
}
}
}
*/
query().custom((query) => { return mw.validateQueryParameterNames(query, ['state']) }),
query(['state']).optional().isString().trim().customSanitizer(val => { return val.toUpperCase() }).isIn(CHOICES).withMessage(errorMsgs.CVE_FILTERED_STATES),
parseError,
parseGetParams,
controller.CVE_GET_FILTERED_COUNT)

router.get('/cve_cursor',
/*
#swagger.tags = ['CVE Record']
Expand Down
64 changes: 36 additions & 28 deletions src/controller/org.controller/org.controller.js
Original file line number Diff line number Diff line change
Expand Up @@ -395,7 +395,7 @@ async function updateOrg (req, res, next) {

// update org
let result = await orgRepo.updateByOrgUUID(org.UUID, newOrg)
if (result.n === 0) {
if (result.matchedCount === 0) {
logger.info({ uuid: req.ctx.uuid, message: shortName + ' organization could not be updated in MongoDB because it does not exist.' })
return res.status(404).json(error.orgDnePathParam(shortName))
}
Expand Down Expand Up @@ -450,34 +450,42 @@ async function createUser (req, res, next) {
return res.status(400).json(error.userLimitReached())
}

Object.keys(req.ctx.body).forEach(k => {
const key = k.toLowerCase()
const body = req.ctx.body
const keys = Object.keys(body)

if (key === 'username') {
newUser.username = req.ctx.body.username
} else if (key === 'authority') {
if (req.ctx.body.authority.active_roles) {
newUser.authority.active_roles = [...new Set(req.ctx.body.authority.active_roles)] // Removes any duplicate strings from array
}
} else if (key === 'name') {
if (req.ctx.body.name.first) {
newUser.name.first = req.ctx.body.name.first
}
if (req.ctx.body.name.last) {
newUser.name.last = req.ctx.body.name.last
}
if (req.ctx.body.name.middle) {
newUser.name.middle = req.ctx.body.name.middle
}
if (req.ctx.body.name.suffix) {
newUser.name.suffix = req.ctx.body.name.suffix
}
} else if (key === 'org_uuid') {
return res.status(400).json(error.uuidProvided('org'))
} else if (key === 'uuid') {
for (const keyRaw of keys) {
const key = keyRaw.toLowerCase()

if (key === 'uuid') {
return res.status(400).json(error.uuidProvided('user'))
}
})

if (key === 'org_uuid') {
return res.status(400).json(error.uuidProvided('org'))
}

const handlers = {
username: () => {
newUser.username = body.username
},
authority: () => {
if (body.authority?.active_roles) {
newUser.authority.active_roles = [...new Set(body.authority.active_roles)]
}
},
name: () => {
const name = body.name || {}
if (name.first) newUser.name.first = name.first
if (name.last) newUser.name.last = name.last
if (name.middle) newUser.name.middle = name.middle
if (name.suffix) newUser.name.suffix = name.suffix
}
}

if (handlers[key]) {
handlers[key]() // execute the appropriate handler
}
}

const requesterOrgUUID = await orgRepo.getOrgUUID(requesterShortName)
const isSecretariat = await orgRepo.isSecretariatUUID(requesterOrgUUID)
Expand Down Expand Up @@ -711,7 +719,7 @@ async function updateUser (req, res, next) {
newUser.authority.active_roles = duplicateCheckedRoles

let result = await userRepo.updateByUserNameAndOrgUUID(username, orgUUID, newUser)
if (result.n === 0) {
if (result.matchedCount === 0) {
logger.info({ uuid: req.ctx.uuid, message: 'The user could not be updated because ' + username + ' does not exist for ' + shortName + ' organization.' })
return res.status(404).json(error.userDne(username))
}
Expand Down Expand Up @@ -786,7 +794,7 @@ async function resetSecret (req, res, next) {
const randomKey = cryptoRandomString({ length: getConstants().CRYPTO_RANDOM_STRING_LENGTH })
oldUser.secret = await argon2.hash(randomKey) // store in db
const user = await userRepo.updateByUserNameAndOrgUUID(oldUser.username, orgUUID, oldUser)
if (user.n === 0) {
if (user.matchedCount === 0) {
logger.info({ uuid: req.ctx.uuid, message: 'The user could not be updated because ' + username + ' does not exist for ' + orgShortName + ' organization.' })
return res.status(404).json(error.userDne(username))
}
Expand Down
1 change: 1 addition & 0 deletions src/controller/schemas.controller/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ router.get('/cve/create-cve-record-cna-request.json', controller.getCnaFullSchem
router.get('/cve/create-adp-record-adp-request.json', controller.getAdpFullSchema)
router.get('/cve/create-cve-record-secretariat-request.json', controller.getCnaSecretariatFullSchema)
router.get('/cve/cna-minimum-request.json', controller.getCnaMinSchema)
router.get('/cve/get-cve-record-count.json', controller.getCveCountResponseSchema)

// Schemas relating to CVE IDs
router.get('/cve-id/create-cve-ids-response.json', controller.getCreateCveIdsResponseSchema)
Expand Down
9 changes: 8 additions & 1 deletion src/controller/schemas.controller/schemas.controller.js
Original file line number Diff line number Diff line change
Expand Up @@ -222,6 +222,12 @@ async function getUpdateUserResponseSchema (req, res) {
res.status(200)
}

async function getCveCountResponseSchema (req, res) {
const cveCountResponseSchema = require('../../../schemas/cve/get-cve-record-count.json')
res.json(cveCountResponseSchema)
res.status(200)
}

module.exports = {
getBadRequestSchema: getBadRequestSchema,
getCreateCveRecordResponseSchema: getCreateCveRecordResponseSchema,
Expand Down Expand Up @@ -258,5 +264,6 @@ module.exports = {
getCnaFullSchema: getCnaFullSchema,
getAdpFullSchema: getAdpFullSchema,
getCnaSecretariatFullSchema: getCnaSecretariatFullSchema,
getCnaMinSchema: getCnaMinSchema
getCnaMinSchema: getCnaMinSchema,
getCveCountResponseSchema: getCveCountResponseSchema
}
2 changes: 1 addition & 1 deletion src/swagger.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ const fullCnaContainerRequest = require('../schemas/cve/create-cve-record-cna-re
/* eslint-disable no-multi-str */
const doc = {
info: {
version: '2.5.3',
version: '2.5.4',
title: 'CVE Services API',
description: "The CVE Services API supports automation tooling for the CVE Program. Credentials are \
required for most service endpoints. Representatives of \
Expand Down
9 changes: 7 additions & 2 deletions test/README.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@


# CVE-API-Unit-Tests
In order to Run Tests, make sure you configure a DB connection in the config/config.json under the `test` environment.
In order to Run Tests, make sure you configure a DB connection in the config/default.json under the `test` environment.

## Dependencies

Expand All @@ -14,11 +14,16 @@ This project uses or depends on software from
- Mocha https://mochajs.org/
- Chai https://www.chaijs.com/

In order to pre-populate a new database for testing, run the following command:

```sh
npm run populate:test
```

In order to run unit tests, use the following command:

```sh
npm run start:test
npm run test
```

## Notes
Expand Down
Loading
Loading