From b299bb7468e525c0dd2c656d577c1d6d255d886b Mon Sep 17 00:00:00 2001 From: Sebastian Beltran Date: Thu, 9 Jan 2025 16:02:15 -0500 Subject: [PATCH] add complianceChecks for owaspTop10Training --- __tests__/checks/owaspTop10Training.test.js | 139 ++++++++++++++++++ .../complianceChecks/owaspTop10Training.js | 31 ++++ 2 files changed, 170 insertions(+) create mode 100644 __tests__/checks/owaspTop10Training.test.js create mode 100644 src/checks/complianceChecks/owaspTop10Training.js diff --git a/__tests__/checks/owaspTop10Training.test.js b/__tests__/checks/owaspTop10Training.test.js new file mode 100644 index 0000000..aecf86a --- /dev/null +++ b/__tests__/checks/owaspTop10Training.test.js @@ -0,0 +1,139 @@ +const knexInit = require('knex') +const { getConfig } = require('../../src/config') +const owaspTop10Training = require('../../src/checks/complianceChecks/owaspTop10Training') +const { + resetDatabase, initializeStore +} = require('../../__utils__') + +const { dbSettings } = getConfig('test') + +let knex +let project +let check + +let addProject, + addOwaspTraining, + getAllResults, + getAllTasks, + getAllAlerts, + addAlert, + addTask, + addResult, + getCheckByCodeName, + getAllOwaspTrainings + +beforeAll(async () => { + knex = knexInit(dbSettings); + ({ + addProject, + addOwaspTraining, + getAllOwaspTrainings, + getAllResults, + getAllTasks, + getAllAlerts, + addAlert, + addTask, + addResult, + getCheckByCodeName + } = initializeStore(knex)) + check = await getCheckByCodeName('owaspTop10Training') +}) + +beforeEach(async () => { + await resetDatabase(knex) + project = await addProject({ name: 'project' }) +}) + +afterAll(async () => { + await knex.destroy() +}) + +describe('Integration: owaspTop10Training', () => { + test('Should add results without alerts or tasks', async () => { + // Add a passed check scenario + await addOwaspTraining({ project_id: project.id, description: 'learning accomplished', training_date: new Date().toISOString() }) + let trainings = await getAllOwaspTrainings() + expect(trainings.length).toBe(1) + // Check that the database is empty + let results = await getAllResults() + expect(results.length).toBe(0) + let alerts = await getAllAlerts() + expect(alerts.length).toBe(0) + let tasks = await getAllTasks() + expect(tasks.length).toBe(0) + // Run the check + await expect(owaspTop10Training(knex)).resolves.toBeUndefined() + // Check that the database has the expected results + trainings = await getAllOwaspTrainings() + expect(trainings.length).toBe(1) + results = await getAllResults() + expect(results.length).toBe(1) + expect(results[0].status).toBe('passed') + expect(results[0].compliance_check_id).toBe(check.id) + alerts = await getAllAlerts() + expect(alerts.length).toBe(0) + tasks = await getAllTasks() + expect(tasks.length).toBe(0) + }) + + test('Should delete (previous alerts and tasks) and add results', async () => { + // Add a passed check scenario + await addOwaspTraining({ project_id: project.id, description: 'learning accomplished', training_date: new Date().toISOString() }) + // Add previous alerts and tasks + await addAlert({ compliance_check_id: check.id, project_id: project.id, title: 'existing', description: 'existing', severity: 'critical' }) + await addTask({ compliance_check_id: check.id, project_id: project.id, title: 'existing', description: 'existing', severity: 'critical' }) + // Check that the database has the expected results + const trainings = await getAllOwaspTrainings() + expect(trainings.length).toBe(1) + let results = await getAllResults() + expect(results.length).toBe(0) + let alerts = await getAllAlerts() + expect(alerts.length).toBe(1) + expect(alerts[0].compliance_check_id).toBe(check.id) + let tasks = await getAllTasks() + expect(tasks.length).toBe(1) + expect(tasks[0].compliance_check_id).toBe(check.id) + // Run the check + await expect(owaspTop10Training(knex)).resolves.toBeUndefined() + // Check that the database has the expected results + results = await getAllResults() + expect(results.length).toBe(1) + expect(results[0].status).toBe('passed') + expect(results[0].compliance_check_id).toBe(check.id) + alerts = await getAllAlerts() + expect(alerts.length).toBe(0) + tasks = await getAllTasks() + expect(tasks.length).toBe(0) + }) + + test('Should add (alerts and tasks) and update results', async () => { + await addResult({ compliance_check_id: check.id, project_id: project.id, status: 'failed', rationale: 'failed previously', severity: 'critical' }) + // Check that the database is empty + let results = await getAllResults() + expect(results.length).toBe(1) + expect(results[0].compliance_check_id).toBe(check.id) + let trainings = await getAllOwaspTrainings() + expect(trainings.length).toBe(0) + let alerts = await getAllAlerts() + expect(alerts.length).toBe(0) + let tasks = await getAllTasks() + expect(tasks.length).toBe(0) + // Run the check + await expect(owaspTop10Training(knex)).resolves.toBeUndefined() + // Check that the database has the expected results + results = await getAllResults() + expect(results.length).toBe(1) + expect(results[0].status).toBe('failed') + expect(results[0].rationale).not.toBe('failed previously') + expect(results[0].compliance_check_id).toBe(check.id) + + trainings = await getAllOwaspTrainings() + expect(trainings.length).toBe(0) + alerts = await getAllAlerts() + expect(alerts.length).toBe(1) + expect(alerts[0].compliance_check_id).toBe(check.id) + tasks = await getAllTasks() + expect(tasks.length).toBe(1) + expect(tasks[0].compliance_check_id).toBe(check.id) + }) +}) diff --git a/src/checks/complianceChecks/owaspTop10Training.js b/src/checks/complianceChecks/owaspTop10Training.js new file mode 100644 index 0000000..96b68dc --- /dev/null +++ b/src/checks/complianceChecks/owaspTop10Training.js @@ -0,0 +1,31 @@ +const validators = require('../validators') +const { initializeStore } = require('../../store') +const debug = require('debug')('checks:softwareDesignTraining') + +module.exports = async (knex, { projects } = {}) => { + const { + getAllOwaspTrainingsByProjectIds, getCheckByCodeName, + getAllProjects, addAlert, addTask, upsertComplianceCheckResult, + deleteAlertsByComplianceCheckId, deleteTasksByComplianceCheckId + } = initializeStore(knex) + debug('Collecting relevant data...') + const check = await getCheckByCodeName('owaspTop10Training') + + if (!projects || (Array.isArray(projects) && projects.length === 0)) { + projects = await getAllProjects() + } + const trainings = await getAllOwaspTrainingsByProjectIds(projects.map(project => project.id)) + + debug('Extracting the validation results...') + const analysis = validators.owaspTraining({ trainings, check, projects }) + debug('Deleting previous alerts and tasks to avoid orphaned records...') + await deleteAlertsByComplianceCheckId(check.id) + await deleteTasksByComplianceCheckId(check.id) + + debug('Upserting the new results...') + await Promise.all(analysis.results.map(result => upsertComplianceCheckResult(result))) + + debug('Inserting the new Alerts and Tasks...') + await Promise.all(analysis.alerts.map(alert => addAlert(alert))) + await Promise.all(analysis.tasks.map(task => addTask(task))) +}