Skip to content

Commit 12e5717

Browse files
feat: initial authz API impl
This adds a new API for authorization, defined in `src/middleware/authz.js`, which is centered around two key functions: `authz` and `authzLevel`. Each returns a middleware function which applies the requested authorization checks. For `authz`, if the authorization checks fail, then the request fails. For `authzLevel`, if the authorization checks fail, then the request continues but without an authorization level being set on the request context. In addition to these top-level APIs, this introduces a set of pre-defined checks, plus two check combinators, which collectively will enable CVE Services endpoints to define the authorization checks they require, all in one place. This is intended to replace the combination of existing authorization middleware functions and ad-hoc authorization checks performed throughout a number of endpoints. This commit *does not* include any replacement of existing authorization checks, only the introduction of the new API. For test, note the following: Mocha doesn't isolate tests in their own process, which means when the tests are running they're actually all sharing a singleton instance of the Express app. This is a problem for the authz testing specifically, because it modifies a piece of global state (`useNewAuthzApi`) to select at runtime whether to use the old or new versions of the authorization API. To deal with this, this commit also ensures that authz tests are isolated in their own, separate run of Mocha. We also shim the method Set.prototype.intersection. The Set.prototype.intersection method was added to the Set type in Node.js version 22. Currently, CVE Services uses an older version of Node and so we need this shim to ensure the API runs. We are planning to upgrade to Node 24 soon, in which case this shim will become unecessary. Signed-off-by: Andrew Lilley Brinker <abrinker@mitre.org>
1 parent 51e1e0f commit 12e5717

10 files changed

Lines changed: 1512 additions & 305 deletions

File tree

package-lock.json

Lines changed: 391 additions & 234 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@
5555
"prompt-sync": "^4.2.0",
5656
"replace-in-file": "6.3.5",
5757
"replace-json-property": "^1.8.0",
58+
"set.prototype.intersection": "^1.1.8",
5859
"swagger-autogen": "^2.19.0",
5960
"swagger-ui-express": "^4.3.0",
6061
"uuid": "^8.3.2",
@@ -105,8 +106,8 @@
105106
"start:prd": "node src/swagger.js && NODE_ENV=production node src/scripts/updateOpenapiHost.js && NODE_ENV=production node src/index.js",
106107
"swagger-autogen": "node src/swagger.js",
107108
"test": "NODE_ENV=test mocha --recursive --exit || true",
108-
"test:integration": "NODE_ENV=test node-dev src/scripts/populate.mjs y; NODE_ENV=test MONGO_CONN_STRING=mongodb://docdb:27017 MONGO_DB_NAME=cve_test node-dev src/scripts/migrate.js; NODE_ENV=test mocha test/integration-tests --recursive --exit",
109-
"test:integration-local": "NODE_ENV=test node-dev src/scripts/populate.mjs y; NODE_ENV=test MONGO_CONN_STRING=mongodb://localhost:27017 MONGO_DB_NAME=cve_test node-dev src/scripts/migrate.js; NODE_ENV=test mocha test/integration-tests --recursive --exit",
109+
"test:integration": "NODE_ENV=test node-dev src/scripts/populate.mjs y; NODE_ENV=test MONGO_CONN_STRING=mongodb://docdb:27017 MONGO_DB_NAME=cve_test node-dev src/scripts/migrate.js; NODE_ENV=test mocha test/integration-tests --exclude test/integration-tests/cve/authzValidation.js --recursive --exit && NODE_ENV=test mocha test/integration-tests/cve/authzValidation.js --recursive --exit",
110+
"test:integration-local": "NODE_ENV=test node-dev src/scripts/populate.mjs y; NODE_ENV=test MONGO_CONN_STRING=mongodb://localhost:27017 MONGO_DB_NAME=cve_test node-dev src/scripts/migrate.js; NODE_ENV=test mocha test/integration-tests --exclude test/integration-tests/cve/authzValidation.js --recursive --exit && NODE_ENV=test mocha test/integration-tests/cve/authzValidation.js --recursive --exit",
110111
"test:unit-tests": "NODE_ENV=test mocha test/unit-tests --recursive --exit || true",
111112
"test:coverage": "NODE_ENV=test nyc --reporter=text mocha src/* --recursive --exit || true",
112113
"test:coverage-html": "NODE_ENV=test nyc --reporter=html mocha src/* --recursive --exit || true",

src/controller/cve.controller/index.js

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ const errorMsgs = require('../../middleware/errorMessages')
99
const controller = require('./cve.controller')
1010
const { body, param, query } = require('express-validator')
1111
const { parseGetParams, parsePostParams, parseError, validateCveCnaContainerJsonSchema, validateCveAdpContainerJsonSchema, validateRejectBody, validateUniqueEnglishEntry, validateDescription, validateDatePublic, validatePURL } = require('./cve.middleware')
12+
const { authz, orgHasRole, OrgRoles } = require('../../middleware/authz')
1213
const getConstants = require('../../constants').getConstants
1314
const CONSTANTS = getConstants()
1415
const CHOICES = [CONSTANTS.CVE_STATES.REJECTED, CONSTANTS.CVE_STATES.PUBLISHED]
@@ -583,6 +584,10 @@ router.put('/cve/:id',
583584
}
584585
*/
585586
mw.validateUser,
587+
mw.authzApiSelector({
588+
oldAuthz: mw.onlySecretariat,
589+
newAuthz: authz(orgHasRole(OrgRoles.SECRETARIAT))
590+
}),
586591
mw.onlySecretariat,
587592
mw.trimJSONWhitespace,
588593
mw.validateCveJsonSchema,

src/index.js

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,9 @@ app.use((req, res, next) => {
4646
res.status(404).json(error.notFound())
4747
})
4848

49+
// TODO(alilleybrinker): Remove this when done testing the new Authz API.
50+
app.set('useNewAuthzApi', false)
51+
4952
// Connect to MongoDB database
5053
const dbConnectionStr = dbUtils.getMongoConnectionString()
5154
const dbConnectionOptions = dbUtils.getMongoConnectionOptions()

0 commit comments

Comments
 (0)