Skip to content

Commit

Permalink
Reduce code complexity in CCI List XML to JSON converter
Browse files Browse the repository at this point in the history
Signed-off-by: Joyce Quach <[email protected]>
  • Loading branch information
jtquach1 committed Nov 15, 2024
1 parent 635b270 commit 4e5c4c4
Showing 1 changed file with 47 additions and 36 deletions.
83 changes: 47 additions & 36 deletions libs/hdf-converters/data/converters/cciListXml2json.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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<string, string[]> = {};
const definitions: Record<string, string> = {};
const ccis: Record<string, string[]> = {};
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)
Expand All @@ -128,3 +96,46 @@ if (scriptIsCalled) {
});
}
}

function produceConversions(cciList: ICCIList): {
nists: Record<string, string[]>;
definitions: Record<string, string>;
ccis: Record<string, string[]>;
} {
const nists: Record<string, string[]> = {};
const definitions: Record<string, string> = {};
const ccis: Record<string, string[]> = {};

// 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};
}

0 comments on commit 4e5c4c4

Please sign in to comment.