Skip to content

Commit

Permalink
Merging develop back in to project-orion
Browse files Browse the repository at this point in the history
  • Loading branch information
elucchesileon committed Nov 26, 2024
1 parent d9b1136 commit df2f44f
Show file tree
Hide file tree
Showing 34 changed files with 1,569 additions and 1,001 deletions.
6 changes: 3 additions & 3 deletions .github/workflows/ci-workflow.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,16 +11,16 @@ jobs:
name: static-checks
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: actions/setup-node@v3
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: '18.x'
- run: npm install
- run: npm run lint
- run: npm run snyk
- run: npm run coverage:cobertura
- name: Upload Coverage to CodeCov
uses: codecov/codecov-action@v3
uses: codecov/codecov-action@v4
with:
token: ${{ secrets.CODECOV_SECRET }}
files: coverage/cobertura-coverage.xml
Expand Down
2 changes: 1 addition & 1 deletion NOTICE.txt
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
Copyright 2020-2023 MITRE Engenuity. Approved for public release. Document number CT0020 and public release case number 22-3206.
Copyright 2020-2024 MITRE Engenuity. Approved for public release. Document number CT0020 and public release case number 22-3206.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -194,7 +194,7 @@ The workflow is defined in `.github/workflows/ci-workflow.yml`

## Notice

Copyright 2020-2023 MITRE Engenuity. Approved for public release. Document number CT0020
Copyright 2020-2024 MITRE Engenuity. Approved for public release. Document number CT0020

Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at

Expand Down
9 changes: 9 additions & 0 deletions app/api/definitions/openapi.yml
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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'
2 changes: 1 addition & 1 deletion app/api/definitions/paths/assets-paths.yml
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ paths:
- name: search
in: query
description: |
Only return objects where the provided search text occurs in the `name` or `description`.
Only return objects where the provided search text occurs in the `attack_id`, `name`, or `description`.
The search is case-insensitive.
schema:
type: string
Expand Down
2 changes: 1 addition & 1 deletion app/api/definitions/paths/attack-objects-paths.yml
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ paths:
- name: search
in: query
description: |
Only return ATT&CK objects where the provided search text occurs in the `name` or `description`.
Only return ATT&CK objects where the provided search text occurs in the `attack_id`, `name`, or `description`.
The search is case-insensitive.
schema:
type: string
Expand Down
6 changes: 6 additions & 0 deletions app/api/definitions/paths/authn-paths.yml
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,12 @@ paths:
required: true
schema:
type: string
- name: iss
in: query
description: |
iss provided by the identity server.
schema:
type: string
- name: state
in: query
description: |
Expand Down
2 changes: 1 addition & 1 deletion app/api/definitions/paths/campaigns-paths.yml
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ paths:
- name: search
in: query
description: |
Only return objects where the provided search text occurs in the `name` or `description`.
Only return objects where the provided search text occurs in the `attack_id`, `name`, or `description`.
The search is case-insensitive.
schema:
type: string
Expand Down
2 changes: 1 addition & 1 deletion app/api/definitions/paths/data-sources-paths.yml
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ paths:
- name: search
in: query
description: |
Only return objects where the provided search text occurs in the `name` or `description`.
Only return objects where the provided search text occurs in the `attack_id`, `name`, or `description`.
The search is case-insensitive.
schema:
type: string
Expand Down
2 changes: 1 addition & 1 deletion app/api/definitions/paths/groups-paths.yml
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ paths:
- name: search
in: query
description: |
Only return objects where the provided search text occurs in the `name` or `description`.
Only return objects where the provided search text occurs in the `attack_id`, `name`, or `description`.
The search is case-insensitive.
schema:
type: string
Expand Down
25 changes: 25 additions & 0 deletions app/api/definitions/paths/health-paths.yml
Original file line number Diff line number Diff line change
@@ -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'
2 changes: 1 addition & 1 deletion app/api/definitions/paths/mitigations-paths.yml
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ paths:
- name: search
in: query
description: |
Only return objects where the provided search text occurs in the `name` or `description`.
Only return objects where the provided search text occurs in the `attack_id`, `name`, or `description`.
The search is case-insensitive.
schema:
type: string
Expand Down
2 changes: 1 addition & 1 deletion app/api/definitions/paths/software-paths.yml
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ paths:
- name: search
in: query
description: |
Only return objects where the provided search text occurs in the `name` or `description`.
Only return objects where the provided search text occurs in the `attack_id`, `name`, or `description`.
The search is case-insensitive.
schema:
type: string
Expand Down
2 changes: 1 addition & 1 deletion app/api/definitions/paths/tactics-paths.yml
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ paths:
- name: search
in: query
description: |
Only return objects where the provided search text occurs in the `name` or `description`.
Only return objects where the provided search text occurs in the `attack_id`, `name`, or `description`.
The search is case-insensitive.
schema:
type: string
Expand Down
2 changes: 1 addition & 1 deletion app/api/definitions/paths/techniques-paths.yml
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ paths:
- name: search
in: query
description: |
Only return objects where the provided search text occurs in the `name` or `description`.
Only return objects where the provided search text occurs in the `attack_id`, `name`, or `description`.
The search is case-insensitive.
schema:
type: string
Expand Down
24 changes: 10 additions & 14 deletions app/config/allowed-values.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,12 +13,11 @@
"macOS",
"Windows",
"Network",
"Office 365",
"Azure AD",
"SaaS",
"IaaS",
"Google Workspace",
"Containers"
"Containers",
"Identity Provider",
"Office Suite"
]
},
{
Expand Down Expand Up @@ -159,13 +158,11 @@
"macOS",
"Windows",
"Network",
"AWS",
"GCP",
"Azure",
"Office 365",
"Azure AD",
"IaaS",
"SaaS",
"Containers"
"Containers",
"Identity Provider",
"Office Suite"
]
},
{
Expand Down Expand Up @@ -233,14 +230,13 @@
"allowedValues": [
"Containers",
"Windows",
"Azure AD",
"Linux",
"macOS",
"IaaS",
"SaaS",
"Office 365",
"Google Workspace",
"Network"
"Network",
"Identity Provider",
"Office Suite"
]
},
{
Expand Down
23 changes: 23 additions & 0 deletions app/controllers/health-controller.js
Original file line number Diff line number Diff line change
@@ -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.");
}
};
3 changes: 2 additions & 1 deletion app/lib/authn-bearer.js
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,8 @@ function verifyClientCredentialsToken(token, decodedHeader, done) {
// Make sure the client is allowed to access the REST API
// Okta returns the client id in payload.cid
// Keycloak returns the client id in payload.clientId
clientId = payload.cid || payload.clientId;
// Newer versions of keycloak appear to return the client id in payload.client_id
clientId = payload.cid || payload.clientId || payload.client_id;
const clients = config.serviceAuthn.oidcClientCredentials.clients;
const client = clients.find(c => c.clientId === clientId);
if (!client) {
Expand Down
87 changes: 86 additions & 1 deletion app/repository/assets-repository.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,91 @@
const BaseRepository = require('./_base.repository');
const Asset = require('../models/asset-model');

class AssetsRepository extends BaseRepository { }
class AssetsRepository extends BaseRepository {

async retrieveAll(options) {
try {
// Build the query
const query = {};
if (!options.includeRevoked) {
query['stix.revoked'] = { $in: [null, false] };
}
if (!options.includeDeprecated) {
query['stix.x_mitre_deprecated'] = { $in: [null, false] };
}
if (typeof options.state !== 'undefined') {
if (Array.isArray(options.state)) {
query['workspace.workflow.state'] = { $in: options.state };
}
else {
query['workspace.workflow.state'] = options.state;
}
}
if (typeof options.domain !== 'undefined') {
if (Array.isArray(options.domain)) {
query['stix.x_mitre_domains'] = { $in: options.domain };
}
else {
query['stix.x_mitre_domains'] = options.domain;
}
}
if (typeof options.platform !== 'undefined') {
if (Array.isArray(options.platform)) {
query['stix.x_mitre_platforms'] = { $in: options.platform };
}
else {
query['stix.x_mitre_platforms'] = options.platform;
}
}
if (typeof options.lastUpdatedBy !== 'undefined') {
query['workspace.workflow.created_by_user_account'] = lastUpdatedByQueryHelper(options.lastUpdatedBy);

Check failure on line 43 in app/repository/assets-repository.js

View workflow job for this annotation

GitHub Actions / static-checks

'lastUpdatedByQueryHelper' is not defined
}

// Build the aggregation
// - Group the documents by stix.id, sorted by stix.modified
// - Use the last document in each group (according to the value of stix.modified)
// - Then apply query, skip and limit options
const aggregation = [
{ $sort: { 'stix.id': 1, 'stix.modified': 1 } },
{ $group: { _id: '$stix.id', document: { $last: '$$ROOT' }}},
{ $replaceRoot: { newRoot: '$document' }},
{ $sort: { 'stix.id': 1 }},
{ $match: query }
];

if (typeof options.search !== 'undefined') {
options.search = regexValidator.sanitizeRegex(options.search);

Check failure on line 59 in app/repository/assets-repository.js

View workflow job for this annotation

GitHub Actions / static-checks

'regexValidator' is not defined
const match = { $match: { $or: [
{ 'stix.name': { '$regex': options.search, '$options': 'i' }},
{ 'stix.description': { '$regex': options.search, '$options': 'i' }},
{ 'workspace.attack_id': { '$regex': options.search, '$options': 'i' }}
]}};
aggregation.push(match);
}

const facet = {
$facet: {
totalCount: [ { $count: 'totalCount' }],
documents: [ ]
}
};
if (options.offset) {
facet.$facet.documents.push({ $skip: options.offset });
}
else {
facet.$facet.documents.push({ $skip: 0 });
}
if (options.limit) {
facet.$facet.documents.push({ $limit: options.limit });
}
aggregation.push(facet);

// Retrieve the documents
return await this.model.aggregate(aggregation).exec();
} catch (err) {
throw new DatabaseError(err);

Check failure on line 88 in app/repository/assets-repository.js

View workflow job for this annotation

GitHub Actions / static-checks

'DatabaseError' is not defined
}
}
}

module.exports = new AssetsRepository(Asset);
Loading

0 comments on commit df2f44f

Please sign in to comment.