From 4e5c4c41836fbb68b54b0aa936843844d6af7759 Mon Sep 17 00:00:00 2001 From: Joyce Quach Date: Fri, 15 Nov 2024 15:47:37 -0500 Subject: [PATCH] Reduce code complexity in CCI List XML to JSON converter Signed-off-by: Joyce Quach --- .../data/converters/cciListXml2json.ts | 83 +++++++++++-------- 1 file changed, 47 insertions(+), 36 deletions(-) diff --git a/libs/hdf-converters/data/converters/cciListXml2json.ts b/libs/hdf-converters/data/converters/cciListXml2json.ts index f69dedb8a..118b7360a 100644 --- a/libs/hdf-converters/data/converters/cciListXml2json.ts +++ b/libs/hdf-converters/data/converters/cciListXml2json.ts @@ -69,55 +69,23 @@ if (scriptIsCalled) { console.error(`Failed to read ${pathToInfile}: ${readFileError}`); } else { // Parse XML to JS Object - parser.parseString(data, (parseFileError: any, converted: ICCIList) => { + parser.parseString(data, (parseFileError: any, cciList: ICCIList) => { if (parseFileError) { console.error(`Failed to parse ${pathToInfile}: ${parseFileError}`); } else { // These store our CCI->NIST names, CCI->definitions, and NIST->CCI mappings - const nists: Record = {}; - const definitions: Record = {}; - const ccis: Record = {}; + const {nists, definitions, ccis} = produceConversions(cciList); - // For all CCI items - for (const cciItem of converted.cci_list.cci_items[0].cci_item) { - // Get the latest reference - const newestReference = _.maxBy( - cciItem.references?.[0].reference, - (item) => _.get(item, '$.version') - ); - const cciId = cciItem.$.id; - - if (newestReference) { - /* There's 1 out of the 2000+ CCI controls where this index string is composed of at - least 2 comma-and-space-separated controls found in the latest revision. */ - const nistIds = newestReference.$.index - .split(/,\s*/) - .map(parse_nist) - .filter(is_control) - .map((n) => n.canonize()); - - _.set(nists, cciId, nistIds); - _.set(definitions, cciId, cciItem.definition[0]); - - for (const nistId of nistIds) { - if (ccis[nistId] === undefined) { - ccis[nistId] = [cciId]; - } else { - ccis[nistId].push(cciId); - } - } - } else { - console.error(`No NIST Controls found for ${cciId}`); - } - } fs.writeFileSync( pathToCci2NistOutfile, JSON.stringify(nists, null, 2) ); + fs.writeFileSync( pathToCci2DefinitionsOutfile, JSON.stringify(definitions, null, 2) ); + fs.writeFileSync( pathToNist2CciOutfile, JSON.stringify(ccis, null, 2) @@ -128,3 +96,46 @@ if (scriptIsCalled) { }); } } + +function produceConversions(cciList: ICCIList): { + nists: Record; + definitions: Record; + ccis: Record; +} { + const nists: Record = {}; + const definitions: Record = {}; + const ccis: Record = {}; + + // For all CCI items + for (const cciItem of cciList.cci_list.cci_items[0].cci_item) { + // Get the latest reference + const newestReference = _.maxBy(cciItem.references?.[0].reference, (item) => + _.get(item, '$.version') + ); + const cciId = cciItem.$.id; + + if (newestReference) { + /* There's 1 out of the 2000+ CCI controls where this index string is composed of at + least 2 comma-and-space-separated controls found in the latest revision. */ + const nistIds = newestReference.$.index + .split(/,\s*/) + .map(parse_nist) + .filter(is_control) + .map((n) => n.canonize()); + + _.set(nists, cciId, nistIds); + _.set(definitions, cciId, cciItem.definition[0]); + + for (const nistId of nistIds) { + if (ccis[nistId] === undefined) { + ccis[nistId] = [cciId]; + } else { + ccis[nistId].push(cciId); + } + } + } else { + console.error(`No NIST Controls found for ${cciId}`); + } + } + return {nists, definitions, ccis}; +}