Skip to content

Commit

Permalink
Reference pull request for full details.
Browse files Browse the repository at this point in the history
  • Loading branch information
crodriguez6497 committed Mar 6, 2024
1 parent 22a9ccc commit e1c1a17
Show file tree
Hide file tree
Showing 35 changed files with 1,486 additions and 372 deletions.
99 changes: 70 additions & 29 deletions Api/Controllers/Import.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,8 @@ const express = require('express');
const db = require('../utils/sequelize');
const router = express.Router();
const ExcelJS = require('exceljs');
const { poamAsset, Poam } = require('../utils/sequelize.js');
const { Poam } = require('../utils/sequelize.js');
const { parse, format } = require('date-fns');

const excelColumnToDbColumnMapping = {
"POA&M Item ID": "poamitemid",
Expand All @@ -24,6 +25,7 @@ const excelColumnToDbColumnMapping = {
"Resources Required": "requiredResources",
"Scheduled Completion Date": "scheduledCompletionDate",
"Milestone with Completion Dates": "milestones",
"Milestone Changes": "milestoneChanges",
"Source Identifying Vulnerability ": "vulnerabilitySource",
"Status": "emassStatus",
"Comments": "notes",
Expand All @@ -42,22 +44,30 @@ const excelColumnToDbColumnMapping = {
"Resulting Residual Risk after Proposed Mitigations": "adjSeverity"
};

function convertToMySQLDate(excelDate) {
if (!excelDate || typeof excelDate !== 'string' || !/^\d{2}\/\d{2}\/\d{4}$/.test(excelDate)) {
console.log(`Invalid date format: ${excelDate}`);
return null;
}
async function processMilestones(poamId, milestone) {
const dateRegex = /(\d{2}\/\d{2}\/\d{4})$/;
const match = milestone.match(dateRegex);

const [month, day, year] = excelDate.split('/');
const convertedDate = `${year}-${month.padStart(2, '0')}-${day.padStart(2, '0')}`;
const date = new Date(convertedDate);
if (match) {
const milestoneDateStr = match[1];
const milestoneText = milestone.replace(dateRegex, '').trim();

if (isNaN(date.getTime())) {
console.log(`Invalid date conversion: ${excelDate} to ${convertedDate}`);
return null;
}
const milestoneDate = parse(milestoneDateStr, "MM/dd/yyyy", new Date());

return convertedDate;
const formattedMilestoneDate = format(milestoneDate, "yyyy-MM-dd");

await db.poamMilestone.create({
poamId: poamId,
milestoneDate: formattedMilestoneDate,
milestoneComments: milestoneText
});
} else {
console.warn(`No date found in milestone: adding milestone.`);
await db.poamMilestone.create({
poamId: poamId,
milestoneComments: milestone
});
}
}

module.exports.uploadPoamFile = exports.uploadPoamFile = async (req, res) => {
Expand Down Expand Up @@ -97,22 +107,25 @@ module.exports.uploadPoamFile = exports.uploadPoamFile = async (req, res) => {

if (dbColumn) {
let cellValue = cell.text && cell.text.trim();
if (dbColumn === 'scheduledCompletionDate' && cellValue) {
poamEntry[dbColumn] = convertToMySQLDate(cellValue);
} else if (dbColumn === 'rawSeverity') {
switch (cellValue) {
case 'I':
poamEntry[dbColumn] = "Cat I - Critical/High";
break;
case 'II':
poamEntry[dbColumn] = "CAT II - Medium";
break;
case 'III':
poamEntry[dbColumn] = "CAT III - Low";
break;
default:
poamEntry[dbColumn] = cellValue;
if (dbColumn === 'vulnerabilitySource') {
if (cellValue.includes("Security Technical Implementation Guide")) {
poamEntry.stigTitle = cellValue;
poamEntry.vulnerabilitySource = "STIG";
} else {
poamEntry[dbColumn] = cellValue;
}
} else if (dbColumn === 'scheduledCompletionDate' && cellValue) {
if (cell.value instanceof Date) {
poamEntry[dbColumn] = format(cell.value, "yyyy-MM-dd");
} else if (typeof cellValue === 'string' && cellValue.match(/^\d{2}\/\d{2}\/\d{4}$/)) {
const dateParts = cellValue.split('/').map(part => parseInt(part, 10));
const dateObject = new Date(dateParts[2], dateParts[0] - 1, dateParts[1]);
poamEntry[dbColumn] = format(dateObject, "yyyy-MM-dd");
} else {
console.log(`Unhandled date format: ${cellValue}`);
}
} else if (dbColumn === 'rawSeverity' || dbColumn === 'adjSeverity') {
poamEntry[dbColumn] = mapValueToCategory(cellValue, dbColumn);
} else {
poamEntry[dbColumn] = cellValue;
}
Expand Down Expand Up @@ -144,6 +157,15 @@ module.exports.uploadPoamFile = exports.uploadPoamFile = async (req, res) => {
}

const poamId = poamEntry.poamId;

if (poamEntry.milestones) {
await processMilestones(poamId, poamEntry.milestones);
}

if (poamEntry.milestoneChanges) {
await processMilestones(poamId, poamEntry.milestoneChanges);
}

const devicesString = poamEntry.devicesAffected && poamEntry.devicesAffected.toString();
const devices = devicesString ? devicesString.split('\n') : [];

Expand Down Expand Up @@ -185,6 +207,25 @@ module.exports.uploadPoamFile = exports.uploadPoamFile = async (req, res) => {
}
};

function mapValueToCategory(cellValue, dbColumn) {
const severityMapping = {
rawSeverity: {
'I': "Cat I - Critical/High",
'II': "CAT II - Medium",
'III': "CAT III - Low"
},
adjSeverity: {
'Very High': "Cat I - Critical/High",
'High': "Cat I - Critical/High",
'Moderate': "CAT II - Medium",
'Low': "CAT III - Low",
'Very Low': "CAT III - Low"
}
};

return severityMapping[dbColumn][cellValue] || cellValue;
}

module.exports.importAssets = async function importAssets(req, res) {
try {
const { assets } = req.body;
Expand Down
39 changes: 39 additions & 0 deletions Api/Controllers/PoamMilestones.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
/*
!#######################################################################
! C-PATTM SOFTWARE
! CRANE C-PATTM plan of action and milestones software. Use is governed by the Open Source Academic Research License Agreement contained in the file
! crane_C_PAT.1_license.txt, which is part of this software package. BY
! USING OR MODIFYING THIS SOFTWARE, YOU ARE AGREEING TO THE TERMS AND
! CONDITIONS OF THE LICENSE.
!########################################################################
*/

const poamMilestoneService = require('../Services/mysql/poamMilestoneService')

module.exports.getPoamMilestones = async function getPoamMilestones(req, res, next){
//res.status(201).json({message: "getPoamMilestones Method called successfully"})
var poamMilestones = await poamMilestoneService.getPoamMilestones(req,res,next);
//console.log("returning poamMilestones: ", poamMilestones)
res.status(200).json(poamMilestones)
}

module.exports.postPoamMilestones = async function postPoamMilestones(req, res, next){
//res.status(201).json({message: "postPoamMilestone Method called successfully"});
var poamMilestone = await poamMilestoneService.postPoamMilestone(req,res,next);
//console.log("returning poamMilestone: ", poamMilestone)
res.status(201).json(poamMilestone)
}

module.exports.putPoamMilestones = async function putPoamMilestones(req, res, next){
// res.status(201).json({message: "putPoamMilestone Method called successfully"});
var poamMilestone = await poamMilestoneService.putPoamMilestone(req,res,next);
//console.log("returning poamMilestone: ", poamMilestone)
res.status(200).json(poamMilestone)
}

module.exports.deletePoamMilestones = async function deletePoamMilestones(req, res, next){
// res.status(201).json({message: "deletePoamMilestone Method called successfully"});
var poamMilestone = await poamMilestoneService.deletePoamMilestone(req,res,next);
// console.log("returning poamMilestone: ", poamMilestone);
res.status(204).json(poamMilestone)
}
13 changes: 7 additions & 6 deletions Api/Models/poam.model.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@

module.exports = (sequelize, DataTypes) => {
const Poam = sequelize.define("poam", {
poamId: {
Expand All @@ -6,6 +7,12 @@ module.exports = (sequelize, DataTypes) => {
primaryKey: true,
autoIncrement: true
},
milestones: {
type: DataTypes.VIRTUAL,
},
"milestoneChanges": {
type: DataTypes.VIRTUAL,
},
collectionId: {
type: DataTypes.INTEGER,
defaultValue: 0
Expand Down Expand Up @@ -57,9 +64,6 @@ module.exports = (sequelize, DataTypes) => {
requiredResources: {
type: DataTypes.TEXT
},
milestones: {
type: DataTypes.TEXT
},
residualRisk: {
type: DataTypes.TEXT
},
Expand Down Expand Up @@ -147,9 +151,6 @@ module.exports = (sequelize, DataTypes) => {
extensionJustification: {
type: DataTypes.TEXT
},
extensionMilestones: {
type: DataTypes.TEXT
},
}, {
freezeTableName: true,
timestamps: false,
Expand Down
33 changes: 33 additions & 0 deletions Api/Models/poamMilestone.model.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
module.exports = (sequelize, DataTypes) => {
const poamMilestone = sequelize.define("poammilestones", {
milestoneId: {
type: DataTypes.INTEGER,
allowNull: false,
primaryKey: true,
autoIncrement: true
},
poamId: {
type: DataTypes.INTEGER,
allowNull: false
},
milestoneTitle: {
type: DataTypes.STRING(255),
allowNull: true,
defaultValue: ''
},
milestoneDate: {
type: DataTypes.DATEONLY,
allowNull: true,
},
milestoneComments: {
type: DataTypes.STRING(2000),
allowNull: true,
defaultValue: ''
},
}, {
freezeTableName: true,
timestamps: false,
});

return poamMilestone;
};
6 changes: 2 additions & 4 deletions Api/Services/mysql/permissionsService.js
Original file line number Diff line number Diff line change
Expand Up @@ -164,10 +164,8 @@ exports.postPermission = async function postPermission(req, res, next) {
let connection
connection = await dbUtils.pool.getConnection()

let sql_query = "UPDATE poamtracking.collectionpermissions SET canOwn= ?, canMaintain= ?, " +
"canApprove= ?, canView= ? WHERE userId = " + req.body.userId + " AND collectionId = " + req.body.collectionId + ";"

await connection.query(sql_query, [req.body.canOwn, req.body.canMaintain, req.body.canApprove, req.body.canView])
let sql_query = "INSERT INTO poamtracking.collectionpermissions (canOwn, canMaintain, canApprove, canView, userId, collectionId) VALUES (?, ?, ?, ?, ?, ?);";
await connection.query(sql_query, [req.body.canOwn, req.body.canMaintain, req.body.canApprove, req.body.canView, req.body.userId, req.body.collectionId]);
await connection.release()

const message = new Object()
Expand Down
8 changes: 4 additions & 4 deletions Api/Services/mysql/poamExtensionService.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ exports.getPoamExtension = async function (poamId) {
let connection;
try {
connection = await dbUtils.pool.getConnection();
let sql = "SELECT poamId, extensionTimeAllowed, extensionJustification, extensionMilestones, scheduledCompletionDate FROM poamtracking.poam WHERE poamId = ?";
let sql = "SELECT poamId, extensionTimeAllowed, extensionJustification, scheduledCompletionDate FROM poamtracking.poam WHERE poamId = ?";
let [poamExtensions] = await connection.query(sql, [poamId]);

return poamExtensions;
Expand All @@ -30,15 +30,15 @@ exports.getPoamExtension = async function (poamId) {

exports.putPoamExtension = async function (extensionData) {
let connection = await dbUtils.pool.getConnection();
let sql = "UPDATE poamtracking.poam SET extensionTimeAllowed = ?, extensionJustification = ?, extensionMilestones = ? WHERE poamId = ?";
await connection.query(sql, [extensionData.extensionTimeAllowed, extensionData.extensionJustification, extensionData.extensionMilestones, extensionData.poamId]);
let sql = "UPDATE poamtracking.poam SET extensionTimeAllowed = ?, extensionJustification = ? WHERE poamId = ?";
await connection.query(sql, [extensionData.extensionTimeAllowed, extensionData.extensionJustification, extensionData.poamId]);
await connection.release();
return extensionData;
};

exports.deletePoamExtension = async function ({ poamId }) {
let connection = await dbUtils.pool.getConnection();
let sql = "UPDATE poamtracking.poam SET extensionTimeAllowed = '', extensionJustification = '', extensionMilestones = '' WHERE poamId = ?";
let sql = "UPDATE poamtracking.poam SET extensionTimeAllowed = '', extensionJustification = '' WHERE poamId = ?";
await connection.query(sql, [poamId]);
await connection.release();
};
Loading

0 comments on commit e1c1a17

Please sign in to comment.