diff --git a/monkey/monkey_island/cc/ui/src/components/report-components/zerotrust/scoutsuite/RuleDisplay.js b/monkey/monkey_island/cc/ui/src/components/report-components/zerotrust/scoutsuite/RuleDisplay.js index 7b4e8f3bd..ac267e193 100644 --- a/monkey/monkey_island/cc/ui/src/components/report-components/zerotrust/scoutsuite/RuleDisplay.js +++ b/monkey/monkey_island/cc/ui/src/components/report-components/zerotrust/scoutsuite/RuleDisplay.js @@ -17,8 +17,8 @@ export default function RuleDisplay(props) {

Resources checked:

{props.rule.checked_items}

- {props.rule.references.length !== 0 ? getReferences() : ''} - {props.rule.items.length !== 0 ? getResources() : ''} + {getReferences()} + {getResources()} ); function getReferences() { @@ -30,11 +30,13 @@ export default function RuleDisplay(props) { rel="noopener noreferrer" key={reference}>{reference}) }) - return ( -
-

References:

- {references} -
) + if (references.length) { + return ( +
+

References:

+ {references} +
) + } } function getResources() { @@ -46,13 +48,15 @@ export default function RuleDisplay(props) { resources.push() + key={template_path + i}/>) + } + if (resources.length) { + return ( +
+

Flagged resources ({props.rule.flagged_items}):

+ {resources} +
) } - return ( -
-

Flagged resources ({props.rule.flagged_items}):

- {resources} -
) } } diff --git a/monkey/monkey_island/cc/ui/src/components/report-components/zerotrust/scoutsuite/ScoutSuiteDataParser.js b/monkey/monkey_island/cc/ui/src/components/report-components/zerotrust/scoutsuite/ScoutSuiteDataParser.js index 452a9e321..729499dec 100644 --- a/monkey/monkey_island/cc/ui/src/components/report-components/zerotrust/scoutsuite/ScoutSuiteDataParser.js +++ b/monkey/monkey_island/cc/ui/src/components/report-components/zerotrust/scoutsuite/ScoutSuiteDataParser.js @@ -3,72 +3,104 @@ export default class ScoutSuiteDataParser { this.runResults = runResults } - /* - itemPath contains path to a specific value e.g. s3.buckets.da1e7081077ce92.secure_transport_enabled" - templatePath contains a template path for resource we would want to display e.g. s3.buckets.id + /** + * + * @param itemPath contains path to a specific value e.g. s3.buckets.da1e7081077ce92.secure_transport_enabled + * @param templatePath contains a template path for resource we would want to display e.g. s3.buckets.id + * @returns {*[]|*} */ getResourceValue(itemPath, templatePath) { let resourcePath = this.fillTemplatePath(itemPath, templatePath); - return this.getValueAt(resourcePath); + return this.getObjectValueByPath(resourcePath, this.runResults); } fillTemplatePath(itemPath, templatePath) { let itemPathArray = itemPath.split('.'); let templatePathArray = templatePath.split('.'); - let resourcePathArray = templatePathArray.map((val, i) => {return val === 'id' ? itemPathArray[i] : val}) + let resourcePathArray = templatePathArray.map((val, i) => { + return val === 'id' ? itemPathArray[i] : val + }) return resourcePathArray.join('.'); } - getValueAt(path) { - return this.getValueAtRecursive(path, this.runResults) + /** + * Retrieves value from ScoutSuite data object based on path, provided in the rule + * @param path E.g. a.id.c.id.e + * @param source E.g. {a: {b: {c: {d: {e: [{result1: 'result1'}, {result2: 'result2'}]}}}}} + * @returns {*[]|*} E.g. ['result1', 'result2'] + */ + getObjectValueByPath(path, source) { + let key; + + while (path) { + key = this.getNextKeyInPath(path); + source = this.getValueForKey(key, path, source); + path = this.trimFirstKey(path); + } + + return source; } - getValueAtRecursive(path, source) { - let value = source; - let current_path = path; - let key; - // iterate over each path elements - while (current_path) { - // check if there are more elements to the path - if (current_path.indexOf('.') != -1) { - key = current_path.substr(0, current_path.indexOf('.')); - } - // last element - else { - key = current_path; - } + getNextKeyInPath(path) { + if (path.indexOf('.') !== -1) { + return path.substr(0, path.indexOf('.')); + } else { + return path; + } + } - try { - // path containing an ".id" - if (key == 'id') { - let v = []; - let w; - for (let k in value) { - // process recursively - w = this.getValueAtRecursive(k + current_path.substr(current_path.indexOf('.'), current_path.length), value); - v = v.concat( - Object.values(w) // get values from array, otherwise it will be an array of key/values - ); - } - return v; - } - // simple path, just return element in value - else { - value = value[key]; - } - } catch (err) { - console.log('Error: ' + err) - } + /** + * Returns value from object, based on path and current key + * @param key E.g. "a" + * @param path E.g. "a.b.c" + * @param source E.g. {a: {b: {c: 'result'}}} + * @returns {[]|*} E.g. {b: {c: 'result'}} + */ + getValueForKey(key, path, source) { + if (key === 'id') { + return this.getValueByReplacingUnknownKey(path, source); + } else { + return source[key]; + } + } - // check if there are more elements to process - if (current_path.indexOf('.') != -1) { - current_path = current_path.substr(current_path.indexOf('.') + 1, current_path.length); - } - // otherwise we're done - else { - current_path = false; - } + /** + * Gets value from object if first key in path doesn't match source object + * @param path unknown.b.c + * @param source {a: {b: {c: [{result:'result'}]}}} + * @returns {[]} 'result' + */ + getValueByReplacingUnknownKey(path, source) { + let value = []; + for (let key in source) { + value = this.getObjectValueByPath(this.replaceFirstKey(path, key), source); + value = value.concat(Object.values(value)); } return value; } + + /** + * Replaces first key in path + * @param path E.g. "one.two.three" + * @param replacement E.g. "four" + * @returns string E.g. "four.two.three" + */ + replaceFirstKey(path, replacement) { + return replacement + path.substr(path.indexOf('.'), path.length); + } + + /** + * Trims the first key from dot separated path. + * @param path E.g. "one.two.three" + * @returns {string|boolean} E.g. "two.three" + */ + trimFirstKey(path) { + if (path.indexOf('.') !== -1) { + return path.substr(path.indexOf('.') + 1, path.length); + } else { + return false; + } + } + + }