Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Updating adp-pilot from Int #1272

Merged
merged 29 commits into from
Aug 26, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
29 commits
Select commit Hold shift + click to select a range
664aea5
1258 first draft, one test failing
Jul 24, 2024
a85cbb9
all tests passing, more tests to write
Jul 26, 2024
f967daa
#1258 all tests passing
Jul 29, 2024
f98b83d
#1258 all tests passing
Jul 29, 2024
a660d97
#1258 small changes to negative tests
Jul 29, 2024
b94e2c2
#1258 fixes for pr pipeline
Jul 31, 2024
53c9fb1
quieting bad eslint error
Jul 31, 2024
403b3bf
#1258 now rejects non-sec requests with params
Jul 31, 2024
03cc618
#1258 updated swagger documentation
Aug 2, 2024
c082fb5
test to see if my username shows up
jack-flores Aug 2, 2024
cfb8911
#1258 added schema for am-i-alive
jack-flores Aug 5, 2024
fcc7fc4
Updated github actions to use docker compose instead of docker-compose
jdaigneau5 Aug 5, 2024
45db2a8
More docker-compose fixes
jdaigneau5 Aug 5, 2024
8fc52ad
Merge pull request #1265 from CVEProject/jd-dc-fix
david-rocca Aug 5, 2024
afa5db0
Merge branch 'dev' into jf-1258
jack-flores Aug 5, 2024
a45d63a
#1258 more unit tests
jack-flores Aug 8, 2024
278065c
#1258 secretariat update to another org no longer updates last_active
jack-flores Aug 15, 2024
20c1596
Update swagger.js to reflect changes from https://github.com/CVEProje…
M-nj Aug 16, 2024
0efc8aa
#1258 addressing comments from team
jack-flores Aug 19, 2024
9d1e931
#1258 update openapi.json
jack-flores Aug 19, 2024
13cc2b2
reverting openapi.json to most recent correct ver
jack-flores Aug 20, 2024
85a4076
#1258 addressing comments from team
jack-flores Aug 20, 2024
3300b06
Merge pull request #1262 from CVEProject/jf-1258
jdaigneau5 Aug 21, 2024
59e72b7
Merge branch 'dev' into api-docs-redirect-correction
jdaigneau5 Aug 26, 2024
d6acf27
Merge pull request #1263 from M-nj/api-docs-redirect-correction
jdaigneau5 Aug 26, 2024
f4a125b
updated version number to 2.4.0
jdaigneau5 Aug 26, 2024
17f8d7b
Merge pull request #1268 from CVEProject/jd-2.4.0
athu-tran Aug 26, 2024
416d2ab
Merge branch 'int' into dev
jdaigneau5 Aug 26, 2024
e89a368
Merge pull request #1269 from CVEProject/dev
athu-tran Aug 26, 2024
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
16 changes: 8 additions & 8 deletions .github/workflows/test-http.yml
Original file line number Diff line number Diff line change
Expand Up @@ -14,30 +14,30 @@ jobs:
- name: Build and Run Services and Mongo Containers
run: |
cp docker/.docker-env.example docker/.docker-env
docker-compose --file docker/docker-compose.yml build
docker-compose --file docker/docker-compose.yml up -d
docker compose --file docker/docker-compose.yml build
docker compose --file docker/docker-compose.yml up -d
- name: Build Test Container
run: |
cp test-http/docker/.docker-env.example test-http/docker/.docker-env
docker-compose --file test-http/docker/docker-compose.yml build
docker compose --file test-http/docker/docker-compose.yml build
- name: Run Test Container
run: |
docker-compose --file test-http/docker/docker-compose.yml up -d
docker compose --file test-http/docker/docker-compose.yml up -d
- name: Sleep
run: bash -c "while ! docker-compose --file docker/docker-compose.yml logs --tail=10 cveawg | grep -q 'Serving on port'; do sleep 1; done"
run: bash -c "while ! docker compose --file docker/docker-compose.yml logs --tail=10 cveawg | grep -q 'Serving on port'; do sleep 1; done"
- name: Load Data into MongoDb
run: docker-compose -f docker/docker-compose.yml exec -T cveawg npm run populate:dev y
run: docker compose -f docker/docker-compose.yml exec -T cveawg npm run populate:dev y
- name: Run Black Box Tests
run: |
docker-compose --file test-http/docker/docker-compose.yml exec -T demon pytest src/ | tee test-http/src/testOutput.txt
docker compose --file test-http/docker/docker-compose.yml exec -T demon pytest src/ | tee test-http/src/testOutput.txt
- name: Archive Test Results
uses: actions/upload-artifact@v2
with:
name: test-results
path: test-http/src/testOutput.txt
retention-days: 1
- name: Extract Tests Results
run: docker-compose --file test-http/docker/docker-compose.yml exec -T demon /bin/bash src/parse_tests_output.sh | (read foo; echo "##[set-output name=result;]$(echo $foo)")
run: docker compose --file test-http/docker/docker-compose.yml exec -T demon /bin/bash src/parse_tests_output.sh | (read foo; echo "##[set-output name=result;]$(echo $foo)")
id: tests_result
- name: Evaluate Tests Results
if: ${{ steps.tests_result.outputs.result == 'Tests failed' }}
Expand Down
8 changes: 4 additions & 4 deletions .github/workflows/test-integration.yml
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,10 @@ jobs:
- name: Build and Run Services and Mongo Containers
run: |
cp docker/.docker-env.test-example docker/.docker-env
docker-compose --file docker/docker-compose.yml build
docker-compose --file docker/docker-compose.yml up -d
docker compose --file docker/docker-compose.yml build
docker compose --file docker/docker-compose.yml up -d
- name: Sleep
run: bash -c "while ! docker-compose --file docker/docker-compose.yml logs --tail=10 cveawg | grep -q 'Serving on port'; do sleep 1; done"
run: bash -c "while ! docker compose --file docker/docker-compose.yml logs --tail=10 cveawg | grep -q 'Serving on port'; do sleep 1; done"
- name: Run Tests
run: docker-compose -f docker/docker-compose.yml exec -T cveawg npm run test:integration
run: docker compose -f docker/docker-compose.yml exec -T cveawg npm run test:integration
continue-on-error: false
15 changes: 11 additions & 4 deletions api-docs/openapi.json
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
{
"openapi": "3.0.2",
"info": {
"version": "2.3.3",
"version": "2.4.0",
"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/5.1.0/schema/v5.0' target='_blank'>here</a>.</p> <a href='https://cveform.mitre.org/' class='link' target='_blank'>Contact the CVE Services team</a>",
"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/5.1.0/schema' target='_blank'>here</a>.</p> <a href='https://cveform.mitre.org/' class='link' target='_blank'>Contact the CVE Services team</a>",
"contact": {
"name": "CVE Services Overview",
"url": "https://cveproject.github.io/automation-cve-services#services-overview"
Expand Down Expand Up @@ -2099,7 +2099,7 @@
"Organization"
],
"summary": "Updates information about the organization specified by short name (accessible to Secretariat)",
"description": " <h2>Access Control</h2> <p>User must belong to an organization with the <b>Secretariat</b> role</p> <h2>Expected Behavior</h2> <p><b>Secretariat:</b> Updates any organization's information</p>",
"description": " <h2>Access Control</h2> <p>User must belong to an organization with the <b>Secretariat</b> role, or user must belong to the organization specified by short name</p> <h2>Expected Behavior</h2> <p><b>Secretariat:</b> Updates any organization's information</p> <p><b>Non-secretariat:</b> Updates 'last_active' timestamp to show that an org is still active</p>",
"operationId": "orgUpdateSingle",
"parameters": [
{
Expand Down Expand Up @@ -2142,7 +2142,14 @@
"content": {
"application/json": {
"schema": {
"$ref": "../schemas/org/update-org-response.json"
"oneOf": [
{
"$ref": "../schemas/org/update-org-response.json"
},
{
"$ref": "../schemas/org/am-i-alive-response.json"
}
]
}
}
}
Expand Down
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.

20 changes: 20 additions & 0 deletions schemas/org/am-i-alive-response.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
{
"$schema": "http://json-schema.org/draft-04/schema",
"type": "object",
"properties": {
"message": {
"type": "string",
"description": "Success description"
},
"updated": {
"type": "object",
"properties": {
"last_active": {
"type": "string",
"format": "date-time",
"description": "The time the organization was last active."
}
}
}
}
}
16 changes: 11 additions & 5 deletions src/controller/org.controller/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -245,9 +245,10 @@ router.put('/org/:shortname',
#swagger.summary = "Updates information about the organization specified by short name (accessible to Secretariat)"
#swagger.description = "
<h2>Access Control</h2>
<p>User must belong to an organization with the <b>Secretariat</b> role</p>
<p>User must belong to an organization with the <b>Secretariat</b> role, or user must belong to the organization specified by short name</p>
<h2>Expected Behavior</h2>
<p><b>Secretariat:</b> Updates any organization's information</p>"
<p><b>Secretariat:</b> Updates any organization's information</p>
<p><b>Non-secretariat:</b> Updates 'last_active' timestamp to show that an org is still active</p>"
#swagger.parameters['shortname'] = { description: 'The shortname of the organization' }
#swagger.parameters['$ref'] = [
'#/components/parameters/id_quota',
Expand All @@ -263,7 +264,12 @@ router.put('/org/:shortname',
description: 'Returns information about the organization updated',
content: {
"application/json": {
schema: { $ref: '../schemas/org/update-org-response.json' }
schema: {
oneOf: [
{ $ref: '../schemas/org/update-org-response.json' },
{ $ref: '../schemas/org/am-i-alive-response.json' }
]
}
}
}
}
Expand Down Expand Up @@ -309,10 +315,10 @@ router.put('/org/:shortname',
}
*/
mw.validateUser,
mw.onlySecretariat,
param(['shortname']).isString().trim().isLength({ min: CONSTANTS.MIN_SHORTNAME_LENGTH, max: CONSTANTS.MAX_SHORTNAME_LENGTH }),
mw.validateOrg,
query().custom((query) => { return mw.validateQueryParameterNames(query, ['new_short_name', 'id_quota', 'name', 'active_roles.add', 'active_roles.remove']) }),
query(['new_short_name', 'id_quota', 'name', 'active_roles.add', 'active_roles.remove']).custom((val) => { return mw.containsNoInvalidCharacters(val) }),
param(['shortname']).isString().trim().isLength({ min: CONSTANTS.MIN_SHORTNAME_LENGTH, max: CONSTANTS.MAX_SHORTNAME_LENGTH }),
query(['new_short_name']).optional().isString().trim().notEmpty().isLength({ min: CONSTANTS.MIN_SHORTNAME_LENGTH, max: CONSTANTS.MAX_SHORTNAME_LENGTH }),
query(['id_quota']).optional().not().isArray().isInt({ min: CONSTANTS.MONGOOSE_VALIDATION.Org_policies_id_quota_min, max: CONSTANTS.MONGOOSE_VALIDATION.Org_policies_id_quota_max }).withMessage(errorMsgs.ID_QUOTA),
query(['name']).optional().isString().trim().notEmpty(),
Expand Down
65 changes: 41 additions & 24 deletions src/controller/org.controller/org.controller.js
Original file line number Diff line number Diff line change
Expand Up @@ -329,6 +329,7 @@ async function updateOrg (req, res, next) {
const addRoles = []
const orgRepo = req.ctx.repositories.getOrgRepository()
const org = await orgRepo.findOneByShortName(shortName)
const orgMakingChanges = req.ctx.org
let agt = setAggregateOrgObj({ short_name: shortName })

// org doesn't exist
Expand All @@ -337,30 +338,38 @@ async function updateOrg (req, res, next) {
return res.status(404).json(error.orgDnePathParam(shortName))
}

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

if (key === 'new_short_name') {
newOrg.short_name = req.ctx.query.new_short_name
agt = setAggregateOrgObj({ short_name: newOrg.short_name })
} else if (key === 'name') {
newOrg.name = req.ctx.query.name
} else if (key === 'id_quota') {
newOrg.policies.id_quota = req.ctx.query.id_quota
} else if (key === 'active_roles.add') {
if (Array.isArray(req.ctx.query['active_roles.add'])) {
req.ctx.query['active_roles.add'].forEach(r => {
addRoles.push(r)
})
}
} else if (key === 'active_roles.remove') {
if (Array.isArray(req.ctx.query['active_roles.remove'])) {
req.ctx.query['active_roles.remove'].forEach(r => {
removeRoles.push(r)
})
const isSec = await orgRepo.isSecretariat(orgMakingChanges)

if (isSec) {
Object.keys(req.ctx.query).forEach(k => {
const key = k.toLowerCase()

if (key === 'new_short_name') {
newOrg.short_name = req.ctx.query.new_short_name
agt = setAggregateOrgObj({ short_name: newOrg.short_name })
} else if (key === 'name') {
newOrg.name = req.ctx.query.name
} else if (key === 'id_quota') {
newOrg.policies.id_quota = req.ctx.query.id_quota
} else if (key === 'active_roles.add') {
if (Array.isArray(req.ctx.query['active_roles.add'])) {
req.ctx.query['active_roles.add'].forEach(r => {
addRoles.push(r)
})
}
} else if (key === 'active_roles.remove') {
if (Array.isArray(req.ctx.query['active_roles.remove'])) {
req.ctx.query['active_roles.remove'].forEach(r => {
removeRoles.push(r)
})
}
}
}
})
})
}

if (shortName === orgMakingChanges) {
newOrg.last_active = Date.now()
}

// updating the org's roles
if (org) {
Expand Down Expand Up @@ -403,6 +412,13 @@ async function updateOrg (req, res, next) {
result = await orgRepo.aggregate(agt)
result = result.length > 0 ? result[0] : null

if (!isSec) {
if (!result || !result.last_active) {
return res.status(500).json(error.serverError())
}
result = { last_active: result.last_active }
}

const responseMessage = {
message: shortName + ' organization was successfully updated.',
updated: result
Expand Down Expand Up @@ -819,7 +835,8 @@ function setAggregateOrgObj (query) {
name: true,
'authority.active_roles': true,
'policies.id_quota': true,
time: true
time: true,
last_active: true
}
}
]
Expand Down
27 changes: 27 additions & 0 deletions src/middleware/middleware.js
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,32 @@ async function validateUser (req, res, next) {
}
}

async function validateOrg (req, res, next) {
const org = req.ctx.org
const reqOrg = req.params.shortname
const orgRepo = req.ctx.repositories.getOrgRepository()
const CONSTANTS = getConstants()

try {
logger.info({ uuid: req.ctx.uuid, message: 'Authenticating org: ' + org })

const isSec = await orgRepo.isSecretariat(org)
if (!isSec) {
if (org !== reqOrg) {
logger.info({ uuid: req.ctx.uuid, message: org + ' is not a ' + CONSTANTS.AUTH_ROLE_ENUM.SECRETARIAT + ' or the same as ' + reqOrg + ' and is not allowed to make these changes.' })
return res.status(403).json(error.secretariatOnly())
} else if (Object.keys(req.query).length > 0) {
return res.status(403).json(error.secretariatOnly())
}
}

logger.info({ uuid: req.ctx.uuid, message: 'Confirmed ' + org + ' has the authority to make changes to ' + reqOrg })
next()
} catch (err) {
next(err)
}
}

// Checks that the requester belongs to an org that has the 'BULK_DOWNLOAD' role
async function onlySecretariatOrBulkDownload (req, res, next) {
const org = req.ctx.org
Expand Down Expand Up @@ -483,6 +509,7 @@ module.exports = {
setCacheControl,
optionallyValidateUser,
validateUser,
validateOrg,
onlySecretariat,
onlySecretariatOrBulkDownload,
onlySecretariatOrAdmin,
Expand Down
3 changes: 2 additions & 1 deletion src/model/org.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,8 @@ const schema = {
created: Date,
modified: Date
},
inUse: Boolean
inUse: Boolean,
last_active: Date
}

const OrgSchema = new mongoose.Schema(schema, { collection: 'Org', timestamps: { createdAt: 'time.created', updatedAt: 'time.modified' } })
Expand Down
4 changes: 2 additions & 2 deletions 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.3.3',
version: '2.4.0',
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 All @@ -34,7 +34,7 @@ const doc = {
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/5.1.0/schema/v5.0' target='_blank'>here</a>.</p>\
located <a href='https://github.com/CVEProject/cve-schema/tree/5.1.0/schema' target='_blank'>here</a>.</p>\
<a href='https://cveform.mitre.org/' class='link' target='_blank'>Contact the CVE Services team</a>",
contact: {
name: 'CVE Services Overview',
Expand Down
Loading
Loading