@mitre/inspec-objects 0.0.15 → 0.0.16
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/objects/control.d.ts +4 -4
- package/lib/objects/control.js +1 -1
- package/lib/parsers/json.js +12 -2
- package/lib/parsers/xccdf.js +1 -5
- package/lib/resources/automatticUpdateTemplate.json +1 -1
- package/lib/utilities/diff.d.ts +4 -3
- package/lib/utilities/diff.js +52 -22
- package/lib/utilities/diffMarkdown.d.ts +1 -1
- package/lib/utilities/diffMarkdown.js +73 -12
- package/lib/utilities/update.d.ts +3 -2
- package/lib/utilities/update.js +34 -12
- package/lib/utilities/xccdf.js +0 -14
- package/package-lock.json +2 -2
- package/package.json +1 -1
package/lib/objects/control.d.ts
CHANGED
|
@@ -3,16 +3,16 @@ export declare function objectifyDescriptions(descs: ExecJSON.ControlDescription
|
|
|
3
3
|
[key: string]: string | undefined;
|
|
4
4
|
} | null | undefined): {
|
|
5
5
|
[key: string]: string | undefined;
|
|
6
|
-
}
|
|
6
|
+
};
|
|
7
7
|
export default class Control {
|
|
8
|
-
id
|
|
8
|
+
id: string;
|
|
9
9
|
title?: string | null;
|
|
10
10
|
code?: string | null;
|
|
11
11
|
describe?: string | null;
|
|
12
12
|
desc?: string | null;
|
|
13
|
-
descs
|
|
13
|
+
descs: {
|
|
14
14
|
[key: string]: string | undefined;
|
|
15
|
-
}
|
|
15
|
+
};
|
|
16
16
|
impact?: number;
|
|
17
17
|
ref?: string;
|
|
18
18
|
refs?: (string | {
|
package/lib/objects/control.js
CHANGED
package/lib/parsers/json.js
CHANGED
|
@@ -45,7 +45,7 @@ function processProfileJSON(profileInput) {
|
|
|
45
45
|
version: profileInput.data.version,
|
|
46
46
|
});
|
|
47
47
|
profileInput.data.controls.forEach((control) => {
|
|
48
|
-
|
|
48
|
+
const newControl = new control_1.default({
|
|
49
49
|
id: control.id,
|
|
50
50
|
title: control.title,
|
|
51
51
|
desc: control.desc,
|
|
@@ -53,7 +53,17 @@ function processProfileJSON(profileInput) {
|
|
|
53
53
|
code: control.code,
|
|
54
54
|
tags: control.tags,
|
|
55
55
|
descs: (0, control_1.objectifyDescriptions)(control.descriptions),
|
|
56
|
-
})
|
|
56
|
+
});
|
|
57
|
+
// Migrate check and fix text from tags to descriptions
|
|
58
|
+
if (newControl.tags.check && !newControl.descs.check) {
|
|
59
|
+
lodash_1.default.set(newControl.descs, 'check', control.tags.check);
|
|
60
|
+
lodash_1.default.set(newControl.tags, 'check', undefined);
|
|
61
|
+
}
|
|
62
|
+
if (newControl.tags.fix && !newControl.descs.fix) {
|
|
63
|
+
lodash_1.default.set(newControl.descs, 'fix', control.tags.fix);
|
|
64
|
+
lodash_1.default.set(newControl.tags, 'fix', undefined);
|
|
65
|
+
}
|
|
66
|
+
profile.controls.push(newControl);
|
|
57
67
|
});
|
|
58
68
|
return profile;
|
|
59
69
|
}
|
package/lib/parsers/xccdf.js
CHANGED
|
@@ -77,6 +77,7 @@ function processXCCDF(xml, removeNewlines = false, useRuleId, ovalDefinitions) {
|
|
|
77
77
|
if (rule.check) {
|
|
78
78
|
if (rule.check.some((ruleValue) => 'check-content' in ruleValue)) {
|
|
79
79
|
control.descs.check = (0, xccdf_1.removeXMLSpecialCharacters)(rule.check ? rule.check[0]['check-content'] : 'Missing description');
|
|
80
|
+
control.tags.check_id = rule.check[0]['@_system'];
|
|
80
81
|
}
|
|
81
82
|
else if (rule.check.some((ruleValue) => 'check-content-ref' in ruleValue) && ovalDefinitions) {
|
|
82
83
|
let referenceID = null;
|
|
@@ -161,11 +162,6 @@ function processXCCDF(xml, removeNewlines = false, useRuleId, ovalDefinitions) {
|
|
|
161
162
|
}
|
|
162
163
|
(_c = control.tags.nist) === null || _c === void 0 ? void 0 : _c.push(identifier['#text']);
|
|
163
164
|
}
|
|
164
|
-
else {
|
|
165
|
-
// console.log('Alert')
|
|
166
|
-
// console.log(identifier['@_system'])
|
|
167
|
-
// console.log(identifier['#text'])
|
|
168
|
-
}
|
|
169
165
|
});
|
|
170
166
|
}
|
|
171
167
|
(_c = rule.reference) === null || _c === void 0 ? void 0 : _c.forEach((reference) => {
|
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
{
|
|
2
|
-
"data": "##
|
|
2
|
+
"data": "## Automatic Update: {{fromVersion}} -> {{toVersion}}\n\n### New Controls:\n{{#addedControls}}\n+ {{id}} - {{title}}\n{{/addedControls}}\n\n{{#hasRenamedControls}}\n### Updated Control IDs:\n<details>\n <summary>Click to expand.</summary>\n \n {{#renamedControls}}\n - {{oldId}} -> {{newId}}\n {{/renamedControls}} \n</details>\n{{/hasRenamedControls}}\n\n### Updated Check/Fixes:\n#### Checks:\n<details open>\n <summary>Click to expand.</summary>\n{{#updatedChecks}}\n{{id}}:\nOld: \n```\n{{{old}}}\n\n```\n\nUpdated:\n```\n{{{new}}}\n\n```\n---\n{{/updatedChecks}}\n</details>\n\n#### Fixes:\n<details open>\n <summary>Click to expand.</summary>\n{{#updatedFixes}}\n{{id}}:\nOld: \n```\n{{{old}}}\n\n```\nNew:\n```\n{{{new}}}\n\n```\n---\n{{/updatedFixes}}\n</details>\n\n### Updated Impacts\n<details open>\n <summary>Click to expand.</summary>\n{{#updatedImpacts}}\n{{id}}:\nOld: {{old}}\nNew: {{new}}\n---\n{{/updatedImpacts}}\n</details>\n\n### Updated Titles\n<details>\n <summary>Click to expand.</summary>\n{{#updatedTitles}}\n{{id}}:\nOld: {{old}}\nNew: {{new}}\n---\n{{/updatedTitles}}\n</details>\n\n### Updated Descriptions\n<details>\n <summary>Click to expand.</summary>\n{{#updatedDescriptions}}\n{{id}}:\nOld:\n```\n{{{old}}}\n\n```\nNew:\n```\n{{{new}}}\n\n```\n---\n{{/updatedDescriptions}}\n</details>"
|
|
3
3
|
}
|
package/lib/utilities/diff.d.ts
CHANGED
|
@@ -1,8 +1,9 @@
|
|
|
1
|
-
import Profile from
|
|
2
|
-
import { ProfileDiff } from
|
|
1
|
+
import Profile from "../objects/profile";
|
|
2
|
+
import { ProfileDiff } from "../types/diff";
|
|
3
|
+
import winston from "winston";
|
|
3
4
|
export declare function removeNewlines(control?: Record<string, unknown>): Record<string, unknown>;
|
|
4
5
|
export declare function simplifyDiff(diffData: Record<string, unknown>): Record<string, unknown>;
|
|
5
|
-
export declare function diffProfile(fromProfile: Profile, toProfile: Profile): {
|
|
6
|
+
export declare function diffProfile(fromProfile: Profile, toProfile: Profile, logger: winston.Logger): {
|
|
6
7
|
simplified: ProfileDiff;
|
|
7
8
|
originalDiff: Record<string, unknown>;
|
|
8
9
|
};
|
package/lib/utilities/diff.js
CHANGED
|
@@ -4,15 +4,16 @@ exports.diffProfile = exports.simplifyDiff = exports.removeNewlines = void 0;
|
|
|
4
4
|
const tslib_1 = require("tslib");
|
|
5
5
|
const json_diff_1 = require("json-diff");
|
|
6
6
|
const lodash_1 = tslib_1.__importDefault(require("lodash"));
|
|
7
|
+
const update_1 = require("./update");
|
|
7
8
|
function removeNewlines(control) {
|
|
8
9
|
if (!control) {
|
|
9
10
|
return {};
|
|
10
11
|
}
|
|
11
12
|
return lodash_1.default.mapValues(control, (value) => {
|
|
12
|
-
if (typeof value ===
|
|
13
|
-
return value.replace(/\n/g,
|
|
13
|
+
if (typeof value === "string") {
|
|
14
|
+
return value.replace(/\n/g, "{{{{newlineHERE}}}}").trim();
|
|
14
15
|
}
|
|
15
|
-
else if (typeof value ===
|
|
16
|
+
else if (typeof value === "object" && value !== null) {
|
|
16
17
|
return removeNewlines(value);
|
|
17
18
|
}
|
|
18
19
|
return value;
|
|
@@ -21,24 +22,28 @@ function removeNewlines(control) {
|
|
|
21
22
|
exports.removeNewlines = removeNewlines;
|
|
22
23
|
function simplifyDiff(diffData) {
|
|
23
24
|
return lodash_1.default.transform(diffData, (result, diffValue, key) => {
|
|
24
|
-
if (lodash_1.default.has(diffValue,
|
|
25
|
+
if (lodash_1.default.has(diffValue, "__new")) {
|
|
25
26
|
// Remove any trailing space
|
|
26
|
-
if (typeof lodash_1.default.get(diffValue,
|
|
27
|
-
|
|
28
|
-
|
|
27
|
+
if (typeof lodash_1.default.get(diffValue, "__new") === "string" &&
|
|
28
|
+
typeof lodash_1.default.get(diffValue, "__old") === "string") {
|
|
29
|
+
if (lodash_1.default.get(diffValue, "__new").trim() !==
|
|
30
|
+
lodash_1.default.get(diffValue, "__old").trim()) {
|
|
31
|
+
lodash_1.default.set(result, key, lodash_1.default.get(diffValue, "__new"));
|
|
29
32
|
}
|
|
30
33
|
}
|
|
31
34
|
else {
|
|
32
|
-
result[key] = lodash_1.default.get(diffValue,
|
|
35
|
+
result[key] = lodash_1.default.get(diffValue, "__new");
|
|
33
36
|
}
|
|
34
37
|
}
|
|
35
38
|
else if (Array.isArray(diffValue)) {
|
|
36
|
-
result[key] = diffValue
|
|
39
|
+
result[key] = diffValue
|
|
40
|
+
.map((value) => value[0] === "+" && value[1])
|
|
41
|
+
.filter((value) => value);
|
|
37
42
|
}
|
|
38
|
-
else if (typeof diffValue ===
|
|
43
|
+
else if (typeof diffValue === "object") {
|
|
39
44
|
result[key] = simplifyDiff(diffValue);
|
|
40
45
|
}
|
|
41
|
-
else if (key.endsWith(
|
|
46
|
+
else if (key.endsWith("__deleted")) {
|
|
42
47
|
return undefined;
|
|
43
48
|
}
|
|
44
49
|
else {
|
|
@@ -47,37 +52,62 @@ function simplifyDiff(diffData) {
|
|
|
47
52
|
});
|
|
48
53
|
}
|
|
49
54
|
exports.simplifyDiff = simplifyDiff;
|
|
50
|
-
function diffProfile(fromProfile, toProfile) {
|
|
55
|
+
function diffProfile(fromProfile, toProfile, logger) {
|
|
51
56
|
const profileDiff = {
|
|
52
57
|
addedControlIDs: [],
|
|
53
58
|
removedControlIDs: [],
|
|
59
|
+
renamedControlIds: {},
|
|
54
60
|
addedControls: {},
|
|
55
|
-
changedControls: {}
|
|
61
|
+
changedControls: {},
|
|
56
62
|
};
|
|
57
63
|
const originalDiff = {
|
|
58
64
|
addedControlIDs: [],
|
|
59
65
|
removedControlIDs: [],
|
|
66
|
+
renamedControlIds: {},
|
|
60
67
|
addedControls: {},
|
|
61
|
-
changedControls: {}
|
|
68
|
+
changedControls: {},
|
|
62
69
|
};
|
|
63
|
-
const fromControlIDs = fromProfile.controls
|
|
70
|
+
const fromControlIDs = fromProfile.controls
|
|
71
|
+
.map((control) => control.id)
|
|
72
|
+
.sort();
|
|
64
73
|
const toControlIDs = toProfile.controls.map((control) => control.id).sort();
|
|
65
74
|
// Find new controls
|
|
66
75
|
const controlIDDiff = (0, json_diff_1.diff)(fromControlIDs, toControlIDs);
|
|
76
|
+
// Contains the new IDs
|
|
77
|
+
const changedControlIds = [];
|
|
67
78
|
controlIDDiff === null || controlIDDiff === void 0 ? void 0 : controlIDDiff.forEach((diffValue) => {
|
|
68
|
-
if (diffValue[0] ===
|
|
69
|
-
|
|
70
|
-
|
|
79
|
+
if (diffValue[0] === "-") {
|
|
80
|
+
const existingControl = fromProfile.controls.find((control) => control.id === diffValue[1]);
|
|
81
|
+
// Check if the control has been given a new ID
|
|
82
|
+
if (existingControl) {
|
|
83
|
+
const newControl = (0, update_1.findUpdatedControlByAllIdentifiers)(existingControl, toProfile.controls);
|
|
84
|
+
if (newControl && newControl.id !== existingControl.id) {
|
|
85
|
+
profileDiff.renamedControlIds[existingControl.id] = newControl.id;
|
|
86
|
+
originalDiff.renamedControlIds[existingControl.id] = newControl.id;
|
|
87
|
+
changedControlIds.push(newControl.id.toLowerCase());
|
|
88
|
+
const controlDiff = lodash_1.default.omit((0, json_diff_1.diff)(existingControl, newControl), "code__deleted");
|
|
89
|
+
profileDiff.changedControls[newControl.id] = simplifyDiff(controlDiff);
|
|
90
|
+
originalDiff.changedControls[newControl.id] = controlDiff;
|
|
91
|
+
logger.verbose(`Control ${existingControl.id} has been upgraded to ${newControl.id}`);
|
|
92
|
+
}
|
|
93
|
+
else {
|
|
94
|
+
profileDiff.removedControlIDs.push(diffValue[1]);
|
|
95
|
+
originalDiff.removedControlIDs.push(diffValue[1]);
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
else {
|
|
99
|
+
logger.error(`Unable to find existing control ${diffValue[1]}`);
|
|
100
|
+
}
|
|
71
101
|
}
|
|
72
|
-
else if (diffValue[0] ===
|
|
102
|
+
else if (diffValue[0] === "+" && !changedControlIds.includes(diffValue[1].toLowerCase())) {
|
|
73
103
|
profileDiff.addedControlIDs.push(diffValue[1]);
|
|
74
104
|
originalDiff.addedControlIDs.push(diffValue[1]);
|
|
75
105
|
}
|
|
76
106
|
});
|
|
77
|
-
// Add new controls to
|
|
107
|
+
// Add new controls to addedControls
|
|
78
108
|
profileDiff.addedControlIDs.forEach((addedControl) => {
|
|
79
109
|
const newControl = toProfile.controls.find((control) => addedControl === control.id);
|
|
80
|
-
if (newControl) {
|
|
110
|
+
if (newControl && !profileDiff.changedControls[newControl.id]) {
|
|
81
111
|
profileDiff.addedControls[addedControl] = newControl;
|
|
82
112
|
originalDiff.addedControls[addedControl] = newControl;
|
|
83
113
|
}
|
|
@@ -86,7 +116,7 @@ function diffProfile(fromProfile, toProfile) {
|
|
|
86
116
|
for (const fromControl of fromProfile.controls) {
|
|
87
117
|
const toControl = toProfile.controls.find((control) => control.id === fromControl.id);
|
|
88
118
|
if (toControl) {
|
|
89
|
-
const controlDiff = lodash_1.default.omit((0, json_diff_1.diff)(fromControl, toControl),
|
|
119
|
+
const controlDiff = lodash_1.default.omit((0, json_diff_1.diff)(fromControl, toControl), "code__deleted");
|
|
90
120
|
if (controlDiff) {
|
|
91
121
|
profileDiff.changedControls[toControl.id] = simplifyDiff(controlDiff);
|
|
92
122
|
originalDiff.changedControls[toControl.id] = controlDiff;
|
|
@@ -4,26 +4,87 @@ exports.createDiffMarkdown = void 0;
|
|
|
4
4
|
const tslib_1 = require("tslib");
|
|
5
5
|
const mustache_1 = tslib_1.__importDefault(require("mustache"));
|
|
6
6
|
const lodash_1 = tslib_1.__importDefault(require("lodash"));
|
|
7
|
-
const global_1 = require("./global");
|
|
8
|
-
const xccdf_1 = require("./xccdf");
|
|
9
7
|
const automatticUpdateTemplate_json_1 = tslib_1.__importDefault(require("../resources/automatticUpdateTemplate.json"));
|
|
10
8
|
function getUpdatedCheckForId(id, profile) {
|
|
11
9
|
const foundControl = profile.controls.find((control) => control.id === id);
|
|
12
|
-
return lodash_1.default.get(foundControl === null || foundControl === void 0 ? void 0 : foundControl.descs,
|
|
10
|
+
return lodash_1.default.get(foundControl === null || foundControl === void 0 ? void 0 : foundControl.descs, "check") || "Missing check";
|
|
13
11
|
}
|
|
14
12
|
function createDiffMarkdown(diff, updatedProfile) {
|
|
15
13
|
const renderableDiffData = {
|
|
16
14
|
addedControls: Object.values(diff.simplified.addedControls),
|
|
17
|
-
|
|
18
|
-
|
|
15
|
+
hasRenamedControls: false,
|
|
16
|
+
renamedControls: [],
|
|
17
|
+
updatedChecks: [],
|
|
18
|
+
updatedFixes: [],
|
|
19
|
+
updatedImpacts: [],
|
|
20
|
+
updatedTitles: [],
|
|
21
|
+
updatedDescriptions: [],
|
|
19
22
|
};
|
|
20
|
-
Object.entries(diff.simplified.
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
23
|
+
Object.entries(diff.simplified.renamedControlIds).forEach(([oldId, newId]) => {
|
|
24
|
+
renderableDiffData.hasRenamedControls = true;
|
|
25
|
+
renderableDiffData.renamedControls.push({
|
|
26
|
+
oldId: oldId,
|
|
27
|
+
newId: newId,
|
|
28
|
+
});
|
|
29
|
+
});
|
|
30
|
+
Object.entries(diff.originalDiff.changedControls).forEach(([id, controlDiff]) => {
|
|
31
|
+
var _a, _b;
|
|
32
|
+
if ((_a = controlDiff.descs) === null || _a === void 0 ? void 0 : _a.check) {
|
|
33
|
+
const oldCheck = lodash_1.default.get(controlDiff.descs.check, "__old");
|
|
34
|
+
const newCheck = lodash_1.default.get(controlDiff.descs.check, "__new");
|
|
35
|
+
if (oldCheck.replace(/\n/g, "").replace(/\W/g, "") !==
|
|
36
|
+
newCheck.replace(/\n/g, "").replace(/\W/g, "")) {
|
|
37
|
+
renderableDiffData.updatedChecks.push({
|
|
38
|
+
id: id,
|
|
39
|
+
old: oldCheck,
|
|
40
|
+
new: newCheck,
|
|
41
|
+
});
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
if ((_b = controlDiff.descs) === null || _b === void 0 ? void 0 : _b.fix) {
|
|
45
|
+
const oldFix = lodash_1.default.get(controlDiff.descs.fix, "__old");
|
|
46
|
+
const newFix = lodash_1.default.get(controlDiff.descs.fix, "__new");
|
|
47
|
+
if (oldFix.replace(/\n/g, "").replace(/\W/g, "") !==
|
|
48
|
+
newFix.replace(/\n/g, "").replace(/\W/g, "")) {
|
|
49
|
+
renderableDiffData.updatedFixes.push({
|
|
50
|
+
id: id,
|
|
51
|
+
old: oldFix,
|
|
52
|
+
new: newFix,
|
|
53
|
+
});
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
if (controlDiff.impact) {
|
|
57
|
+
const oldImpact = lodash_1.default.get(controlDiff.impact, "__old");
|
|
58
|
+
const newImpact = lodash_1.default.get(controlDiff.impact, "__new");
|
|
59
|
+
if (oldImpact !== newImpact) {
|
|
60
|
+
renderableDiffData.updatedImpacts.push({
|
|
61
|
+
id: id,
|
|
62
|
+
old: oldImpact,
|
|
63
|
+
new: newImpact,
|
|
64
|
+
});
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
if (controlDiff.title) {
|
|
68
|
+
const oldTitle = lodash_1.default.get(controlDiff.title, "__old");
|
|
69
|
+
const newTitle = lodash_1.default.get(controlDiff.title, "__new");
|
|
70
|
+
if (oldTitle !== newTitle) {
|
|
71
|
+
renderableDiffData.updatedTitles.push({
|
|
72
|
+
id: id,
|
|
73
|
+
old: oldTitle,
|
|
74
|
+
new: newTitle,
|
|
75
|
+
});
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
if (controlDiff.desc) {
|
|
79
|
+
const oldDesc = lodash_1.default.get(controlDiff.desc, "__old");
|
|
80
|
+
const newDesc = lodash_1.default.get(controlDiff.desc, "__new");
|
|
81
|
+
if (oldDesc !== newDesc) {
|
|
82
|
+
renderableDiffData.updatedDescriptions.push({
|
|
83
|
+
id: id,
|
|
84
|
+
old: oldDesc,
|
|
85
|
+
new: newDesc,
|
|
86
|
+
});
|
|
87
|
+
}
|
|
27
88
|
}
|
|
28
89
|
});
|
|
29
90
|
// Render output
|
|
@@ -11,6 +11,7 @@ export declare type UpdatedProfileReturn = {
|
|
|
11
11
|
};
|
|
12
12
|
markdown: string;
|
|
13
13
|
};
|
|
14
|
-
export declare function
|
|
15
|
-
export declare function
|
|
14
|
+
export declare function findUpdatedControlByAllIdentifiers(existingControl: Control, updatedControls: Control[]): Control | undefined;
|
|
15
|
+
export declare function updateControl(from: Control, update: Partial<Control>, logger: winston.Logger): Control;
|
|
16
|
+
export declare function updateProfile(from: Profile, using: Profile, logger: winston.Logger): Omit<UpdatedProfileReturn, 'markdown'>;
|
|
16
17
|
export declare function updateProfileUsingXCCDF(from: Profile, using: string, id: 'group' | 'rule' | 'version', logger: winston.Logger, ovalDefinitions?: Record<string, OvalDefinitionValue>): UpdatedProfileReturn;
|
package/lib/utilities/update.js
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
// Utilities to update a profile or control with new metadata
|
|
3
3
|
// The ultimate goal is to preserve all the metadata that is already there and only add what is new
|
|
4
4
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
5
|
-
exports.updateProfileUsingXCCDF = exports.updateProfile = exports.updateControl = void 0;
|
|
5
|
+
exports.updateProfileUsingXCCDF = exports.updateProfile = exports.updateControl = exports.findUpdatedControlByAllIdentifiers = void 0;
|
|
6
6
|
const tslib_1 = require("tslib");
|
|
7
7
|
const lodash_1 = tslib_1.__importDefault(require("lodash"));
|
|
8
8
|
const profile_1 = tslib_1.__importDefault(require("../objects/profile"));
|
|
@@ -65,43 +65,64 @@ function getExistingDescribeFromControl(control) {
|
|
|
65
65
|
return '';
|
|
66
66
|
}
|
|
67
67
|
}
|
|
68
|
-
function
|
|
68
|
+
function findUpdatedControlByAllIdentifiers(existingControl, updatedControls) {
|
|
69
|
+
// Try to match based on IDs
|
|
70
|
+
let updatedControl = updatedControls.find((updatedControl) => {
|
|
71
|
+
return updatedControl.id.toLowerCase() === existingControl.id.toLowerCase();
|
|
72
|
+
});
|
|
73
|
+
if (updatedControl) {
|
|
74
|
+
return updatedControl;
|
|
75
|
+
}
|
|
76
|
+
// Try to match based on legacy identifiers
|
|
77
|
+
updatedControl = updatedControls.find((updatedControl) => {
|
|
78
|
+
var _a;
|
|
79
|
+
return (_a = updatedControl.tags.legacy) === null || _a === void 0 ? void 0 : _a.some((legacyTag) => {
|
|
80
|
+
var _a;
|
|
81
|
+
return legacyTag.toLowerCase() === ((_a = existingControl.id) === null || _a === void 0 ? void 0 : _a.toLowerCase());
|
|
82
|
+
});
|
|
83
|
+
});
|
|
84
|
+
if (updatedControl) {
|
|
85
|
+
return updatedControl;
|
|
86
|
+
}
|
|
87
|
+
return undefined;
|
|
88
|
+
}
|
|
89
|
+
exports.findUpdatedControlByAllIdentifiers = findUpdatedControlByAllIdentifiers;
|
|
90
|
+
function updateControl(from, update, logger) {
|
|
69
91
|
const existingDescribeBlock = getExistingDescribeFromControl(from);
|
|
92
|
+
logger.debug(`Existing describe block for control ${from.id}: ${JSON.stringify(existingDescribeBlock)}`);
|
|
70
93
|
const projectedControl = projectValuesOntoExistingObj(from, update);
|
|
71
94
|
projectedControl.describe = existingDescribeBlock;
|
|
72
95
|
return projectedControl;
|
|
73
96
|
}
|
|
74
97
|
exports.updateControl = updateControl;
|
|
75
|
-
function updateProfile(from, using) {
|
|
98
|
+
function updateProfile(from, using, logger) {
|
|
76
99
|
// Update the profile with the new metadata
|
|
77
100
|
const to = new profile_1.default(lodash_1.default.omit(from, 'controls'));
|
|
78
101
|
// Find the diff
|
|
79
|
-
const diff = (0, diff_1.diffProfile)(from, using);
|
|
102
|
+
const diff = (0, diff_1.diffProfile)(from, using, logger);
|
|
80
103
|
// Add the new controls
|
|
81
104
|
diff.simplified.addedControlIDs.forEach(id => {
|
|
82
105
|
const addedControl = diff.simplified.addedControls[id];
|
|
83
106
|
if (addedControl) {
|
|
107
|
+
logger.debug(`New Control: ${addedControl.id} - ${addedControl.title}`);
|
|
84
108
|
to.controls.push(addedControl);
|
|
85
109
|
}
|
|
86
110
|
else {
|
|
87
|
-
throw new Error(
|
|
111
|
+
throw new Error(`New control ${id} added but don't have the control data`);
|
|
88
112
|
}
|
|
89
113
|
});
|
|
90
114
|
// Update the existing controls
|
|
91
115
|
for (const existingControl of from.controls) {
|
|
92
|
-
const updatedControl = using.controls
|
|
116
|
+
const updatedControl = findUpdatedControlByAllIdentifiers(existingControl, using.controls);
|
|
93
117
|
if (updatedControl) {
|
|
94
|
-
const controlDiff = diff.simplified.changedControls[
|
|
118
|
+
const controlDiff = diff.simplified.changedControls[updatedControl.id];
|
|
95
119
|
if (controlDiff) {
|
|
96
|
-
to.controls.push(updateControl(existingControl, controlDiff));
|
|
120
|
+
to.controls.push(updateControl(existingControl, controlDiff, logger));
|
|
97
121
|
}
|
|
98
122
|
else {
|
|
99
123
|
to.controls.push(existingControl);
|
|
100
124
|
}
|
|
101
125
|
}
|
|
102
|
-
else {
|
|
103
|
-
console.log("Control not updated: " + existingControl.id);
|
|
104
|
-
}
|
|
105
126
|
}
|
|
106
127
|
return {
|
|
107
128
|
profile: to,
|
|
@@ -110,6 +131,7 @@ function updateProfile(from, using) {
|
|
|
110
131
|
}
|
|
111
132
|
exports.updateProfile = updateProfile;
|
|
112
133
|
function updateProfileUsingXCCDF(from, using, id, logger, ovalDefinitions) {
|
|
134
|
+
logger.debug(`Updating profile ${from.name} with control IDs: ${id}`);
|
|
113
135
|
// Parse the XCCDF benchmark and convert it into a Profile
|
|
114
136
|
logger.debug('Loading XCCDF File');
|
|
115
137
|
const xccdfProfile = (0, xccdf_1.processXCCDF)(using, false, id);
|
|
@@ -119,7 +141,7 @@ function updateProfileUsingXCCDF(from, using, id, logger, ovalDefinitions) {
|
|
|
119
141
|
logger.debug('Loaded XCCDF File with newline replacements');
|
|
120
142
|
// Update the profile and return
|
|
121
143
|
logger.debug('Creating updated profile');
|
|
122
|
-
const updatedProfile = updateProfile(from, xccdfProfile);
|
|
144
|
+
const updatedProfile = updateProfile(from, xccdfProfile, logger);
|
|
123
145
|
logger.debug('Creating diff markdown');
|
|
124
146
|
// Create the markdown
|
|
125
147
|
const markdown = (0, diffMarkdown_1.createDiffMarkdown)(updatedProfile.diff, xccdfProfileWithNLReplacement);
|
package/lib/utilities/xccdf.js
CHANGED
|
@@ -6,20 +6,6 @@ const fast_xml_parser_1 = tslib_1.__importDefault(require("fast-xml-parser"));
|
|
|
6
6
|
const htmlparser = tslib_1.__importStar(require("htmlparser2"));
|
|
7
7
|
const lodash_1 = tslib_1.__importDefault(require("lodash"));
|
|
8
8
|
const he_1 = tslib_1.__importDefault(require("he"));
|
|
9
|
-
var htmlEntities = {
|
|
10
|
-
nbsp: ' ',
|
|
11
|
-
cent: '¢',
|
|
12
|
-
pound: '£',
|
|
13
|
-
yen: '¥',
|
|
14
|
-
euro: '€',
|
|
15
|
-
copy: '©',
|
|
16
|
-
reg: '®',
|
|
17
|
-
lt: '<',
|
|
18
|
-
gt: '>',
|
|
19
|
-
quot: '"',
|
|
20
|
-
amp: '&',
|
|
21
|
-
apos: '\''
|
|
22
|
-
};
|
|
23
9
|
function convertEncodedXmlIntoJson(encodedXml) {
|
|
24
10
|
return fast_xml_parser_1.default.parse(encodedXml, {
|
|
25
11
|
ignoreAttributes: false,
|
package/package-lock.json
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@mitre/inspec-objects",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.16",
|
|
4
4
|
"lockfileVersion": 2,
|
|
5
5
|
"requires": true,
|
|
6
6
|
"packages": {
|
|
7
7
|
"": {
|
|
8
8
|
"name": "@mitre/inspec-objects",
|
|
9
|
-
"version": "0.0.
|
|
9
|
+
"version": "0.0.16",
|
|
10
10
|
"license": "Apache-2.0",
|
|
11
11
|
"dependencies": {
|
|
12
12
|
"@types/flat": "^5.0.2",
|