diff --git a/app/api/definitions/openapi.yml b/app/api/definitions/openapi.yml index 9c7ed766..f122fe48 100644 --- a/app/api/definitions/openapi.yml +++ b/app/api/definitions/openapi.yml @@ -60,6 +60,8 @@ tags: description: 'Operations for authenticating with the REST API' - name: 'User Accounts' description: 'Operations on user accounts' + - name: 'Health Check' + description: 'Operations on system status' paths: # ATT&CK Objects @@ -315,3 +317,10 @@ paths: # Recent Activity /api/recent-activity: $ref: 'paths/recent-activity-paths.yml#/paths/~1api~1recent-activity' + + # Health Checks + /api/health/ping: + $ref: 'paths/health-paths.yml#/paths/~1api~1health~1ping' + + /api/health/status: + $ref: 'paths/health-paths.yml#/paths/~1api~1health~1status' diff --git a/app/api/definitions/paths/health-paths.yml b/app/api/definitions/paths/health-paths.yml new file mode 100644 index 00000000..4837b44d --- /dev/null +++ b/app/api/definitions/paths/health-paths.yml @@ -0,0 +1,25 @@ +paths: + /api/health/ping: + get: + summary: 'Test whether the REST API is responding to requests' + operationId: 'health-ping' + description: | + This endpoint tests whether the REST API is responding to requests. + It doesn't test any other aspect of system health. + tags: + - 'Health Check' + responses: + '204': + description: 'Indicates that the REST API is responding to requests' + + /api/health/status: + get: + summary: 'Returns a summary of the system status' + operationId: 'health-status' + description: | + This endpoint returns a summary of the system status, including system uptime and database connection state. + tags: + - 'Health Check' + responses: + '200': + description: 'Summary of the system status' diff --git a/app/controllers/health-controller.js b/app/controllers/health-controller.js new file mode 100644 index 00000000..8b573cde --- /dev/null +++ b/app/controllers/health-controller.js @@ -0,0 +1,23 @@ +'use strict'; + +// const mongoose = require('mongoose'); +const logger = require('../lib/logger'); + +exports.getPing = function(req, res) { + return res.status(204).send(); +}; + +exports.getStatus = function(req, res) { + try { + const status = { + // TBD: check database connection without waiting 30 seconds for timeout when not connected + // dbState: mongoose.STATES[mongoose.connection.readyState], + uptime: process.uptime() + }; + return res.status(200).send(status); + } + catch(err) { + logger.error("Unable to retrieve system status, failed with error: " + err); + return res.status(500).send("Unable to retrieve system status. Server error."); + } +}; diff --git a/app/routes/health-routes.js b/app/routes/health-routes.js new file mode 100644 index 00000000..e32e4a14 --- /dev/null +++ b/app/routes/health-routes.js @@ -0,0 +1,24 @@ +'use strict'; + +const express = require('express'); + +const healthController = require('../controllers/health-controller'); +const authn = require('../lib/authn-middleware'); +const authz = require('../lib/authz-middleware'); + +const router = express.Router(); + +router.route('/health/ping') + .get( + // No authentication or authorization required + healthController.getPing + ); + +router.route('/health/status') + .get( + authn.authenticate, + authz.requireRole(authz.visitorOrHigher, authz.readOnlyService), + healthController.getStatus + ); + +module.exports = router; diff --git a/app/services/stix-bundles-service.js b/app/services/stix-bundles-service.js index 43f5faca..ca154694 100644 --- a/app/services/stix-bundles-service.js +++ b/app/services/stix-bundles-service.js @@ -67,6 +67,8 @@ const stixOptionalArrayProperties = [ 'x_mitre_domains', 'x_mitre_effective_permissions', 'x_mitre_impact_type', + 'x_mitre_related_assets', + 'x_mitre_sectors', 'x_mitre_system_requirements', 'x_mitre_permissions_required', 'x_mitre_platforms',