forked from p34709852/monkey
Moved rule parsing methods into a separate component, added more details about rules in rule overview: added how many failed/passed/uncheck rules there are for a finding.
This commit is contained in:
parent
5027dd4d2c
commit
7e07489807
|
@ -2,9 +2,10 @@ import React, {useState} from 'react';
|
||||||
import {Modal} from 'react-bootstrap';
|
import {Modal} from 'react-bootstrap';
|
||||||
import * as PropTypes from 'prop-types';
|
import * as PropTypes from 'prop-types';
|
||||||
import Pluralize from 'pluralize';
|
import Pluralize from 'pluralize';
|
||||||
import ScoutSuiteSingleRuleDropdown, {getRuleStatus} from './ScoutSuiteSingleRuleDropdown';
|
import ScoutSuiteSingleRuleDropdown from './ScoutSuiteSingleRuleDropdown';
|
||||||
import '../../../../styles/components/scoutsuite/RuleModal.scss';
|
import '../../../../styles/components/scoutsuite/RuleModal.scss';
|
||||||
import STATUSES from '../../common/consts/StatusConsts';
|
import STATUSES from '../../common/consts/StatusConsts';
|
||||||
|
import {getRuleCountByStatus, sortRules} from './rule-parsing/ParsingUtils';
|
||||||
|
|
||||||
|
|
||||||
export default function ScoutSuiteRuleModal(props) {
|
export default function ScoutSuiteRuleModal(props) {
|
||||||
|
@ -18,46 +19,54 @@ export default function ScoutSuiteRuleModal(props) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function compareRules(firstRule, secondRule) {
|
|
||||||
let firstStatus = getRuleStatus(firstRule);
|
|
||||||
let secondStatus = getRuleStatus(secondRule);
|
|
||||||
return compareRuleStatuses(firstStatus, secondStatus);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
function compareRuleStatuses(ruleStatusOne, ruleStatusTwo) {
|
|
||||||
if (ruleStatusOne === ruleStatusTwo) {
|
|
||||||
return 0;
|
|
||||||
} else if (ruleStatusOne === STATUSES.STATUS_FAILED) {
|
|
||||||
return -1;
|
|
||||||
} else if (ruleStatusTwo === STATUSES.STATUS_FAILED) {
|
|
||||||
return 1;
|
|
||||||
} else if (ruleStatusOne === STATUSES.STATUS_VERIFY) {
|
|
||||||
return -1;
|
|
||||||
} else if (ruleStatusTwo === STATUSES.STATUS_VERIFY) {
|
|
||||||
return 1;
|
|
||||||
} else if (ruleStatusOne === STATUSES.STATUS_PASSED) {
|
|
||||||
return -1;
|
|
||||||
} else if (ruleStatusTwo === STATUSES.STATUS_PASSED) {
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function renderRuleDropdowns() {
|
function renderRuleDropdowns() {
|
||||||
let dropdowns = [];
|
let dropdowns = [];
|
||||||
let rules = props.scoutsuite_rules;
|
let rules = sortRules(props.scoutsuite_rules);
|
||||||
rules.sort(compareRules);
|
|
||||||
rules.forEach(rule => {
|
rules.forEach(rule => {
|
||||||
let dropdown = (<ScoutSuiteSingleRuleDropdown isCollapseOpen={openRuleId === rule.description}
|
let dropdown = (<ScoutSuiteSingleRuleDropdown isCollapseOpen={openRuleId === rule.description}
|
||||||
toggleCallback={() => toggleRuleDropdown(rule.description)}
|
toggleCallback={() => toggleRuleDropdown(rule.description)}
|
||||||
rule={rule}
|
rule={rule}
|
||||||
scoutsuite_data={props.scoutsuite_data}
|
scoutsuite_data={props.scoutsuite_data}
|
||||||
key={rule.description+rule.path}/>)
|
key={rule.description + rule.path}/>)
|
||||||
dropdowns.push(dropdown)
|
dropdowns.push(dropdown)
|
||||||
});
|
});
|
||||||
return dropdowns;
|
return dropdowns;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function getGeneralRuleOverview() {
|
||||||
|
return <>
|
||||||
|
There {Pluralize('is', props.scoutsuite_rules.length)}
|
||||||
|
<span className={'badge badge-primary'}>{props.scoutsuite_rules.length}</span>
|
||||||
|
ScoutSuite {Pluralize('rule', props.scoutsuite_rules.length)} associated with this finding.
|
||||||
|
</>
|
||||||
|
}
|
||||||
|
|
||||||
|
function getFailedRuleOverview() {
|
||||||
|
let failedRuleCnt = getRuleCountByStatus(props.scoutsuite_rules, STATUSES.STATUS_FAILED) +
|
||||||
|
+ getRuleCountByStatus(props.scoutsuite_rules, STATUSES.STATUS_VERIFY);
|
||||||
|
return <>
|
||||||
|
<span className={'badge badge-danger'}>{failedRuleCnt}</span>
|
||||||
|
failed security {Pluralize('rule', failedRuleCnt)}.
|
||||||
|
</>
|
||||||
|
}
|
||||||
|
|
||||||
|
function getPassedRuleOverview() {
|
||||||
|
let passedRuleCnt = getRuleCountByStatus(props.scoutsuite_rules, STATUSES.STATUS_PASSED);
|
||||||
|
return <>
|
||||||
|
<span className={'badge badge-success'}>{passedRuleCnt}</span>
|
||||||
|
passed security {Pluralize('rule', passedRuleCnt)}.
|
||||||
|
</>
|
||||||
|
}
|
||||||
|
|
||||||
|
function getUnexecutedRuleOverview() {
|
||||||
|
let unexecutedRuleCnt = getRuleCountByStatus(props.scoutsuite_rules, STATUSES.STATUS_UNEXECUTED);
|
||||||
|
return <>
|
||||||
|
<span className={'badge badge-default'}>{unexecutedRuleCnt}</span>
|
||||||
|
{Pluralize('rule', unexecutedRuleCnt)} {Pluralize('was', unexecutedRuleCnt)} not
|
||||||
|
checked (no relevant resources for the rule).
|
||||||
|
</>
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
<Modal show={props.isModalOpen} onHide={() => props.hideCallback()} className={'scoutsuite-rule-modal'}>
|
<Modal show={props.isModalOpen} onHide={() => props.hideCallback()} className={'scoutsuite-rule-modal'}>
|
||||||
|
@ -67,9 +76,10 @@ export default function ScoutSuiteRuleModal(props) {
|
||||||
</h3>
|
</h3>
|
||||||
<hr/>
|
<hr/>
|
||||||
<p>
|
<p>
|
||||||
There {Pluralize('is', props.scoutsuite_rules.length)} {
|
{getGeneralRuleOverview()}
|
||||||
<span className={'badge badge-primary'}>{props.scoutsuite_rules.length}</span>
|
{getFailedRuleOverview()}
|
||||||
} ScoutSuite {Pluralize('rule', props.scoutsuite_rules.length)} associated with this finding.
|
{getPassedRuleOverview()}
|
||||||
|
{getUnexecutedRuleOverview()}
|
||||||
</p>
|
</p>
|
||||||
{renderRuleDropdowns()}
|
{renderRuleDropdowns()}
|
||||||
</Modal.Body>
|
</Modal.Body>
|
||||||
|
|
|
@ -6,10 +6,10 @@ import {faChevronDown} from '@fortawesome/free-solid-svg-icons/faChevronDown'
|
||||||
|
|
||||||
import classNames from 'classnames';
|
import classNames from 'classnames';
|
||||||
import * as PropTypes from 'prop-types';
|
import * as PropTypes from 'prop-types';
|
||||||
import RULE_LEVELS from '../../common/consts/ScoutSuiteConsts/RuleLevels';
|
|
||||||
import STATUSES from '../../common/consts/StatusConsts';
|
import STATUSES from '../../common/consts/StatusConsts';
|
||||||
import {faCheckCircle, faCircle, faExclamationCircle} from '@fortawesome/free-solid-svg-icons';
|
import {faCheckCircle, faCircle, faExclamationCircle} from '@fortawesome/free-solid-svg-icons';
|
||||||
import RuleDisplay from './RuleDisplay';
|
import RuleDisplay from './RuleDisplay';
|
||||||
|
import {getRuleStatus} from './rule-parsing/ParsingUtils';
|
||||||
|
|
||||||
export default function ScoutSuiteSingleRuleDropdown(props) {
|
export default function ScoutSuiteSingleRuleDropdown(props) {
|
||||||
|
|
||||||
|
@ -70,18 +70,6 @@ export default function ScoutSuiteSingleRuleDropdown(props) {
|
||||||
return getRuleCollapse();
|
return getRuleCollapse();
|
||||||
}
|
}
|
||||||
|
|
||||||
export function getRuleStatus(rule) {
|
|
||||||
if (rule.checked_items === 0) {
|
|
||||||
return STATUSES.STATUS_UNEXECUTED
|
|
||||||
} else if (rule.items.length === 0) {
|
|
||||||
return STATUSES.STATUS_PASSED
|
|
||||||
} else if (rule.level === RULE_LEVELS.LEVEL_WARNING) {
|
|
||||||
return STATUSES.STATUS_VERIFY
|
|
||||||
} else {
|
|
||||||
return STATUSES.STATUS_FAILED
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
ScoutSuiteSingleRuleDropdown.propTypes = {
|
ScoutSuiteSingleRuleDropdown.propTypes = {
|
||||||
isCollapseOpen: PropTypes.bool,
|
isCollapseOpen: PropTypes.bool,
|
||||||
|
|
|
@ -0,0 +1,47 @@
|
||||||
|
import STATUSES from '../../../common/consts/StatusConsts';
|
||||||
|
import RULE_LEVELS from '../../../common/consts/ScoutSuiteConsts/RuleLevels';
|
||||||
|
|
||||||
|
export function getRuleStatus(rule) {
|
||||||
|
if (rule.checked_items === 0) {
|
||||||
|
return STATUSES.STATUS_UNEXECUTED
|
||||||
|
} else if (rule.items.length === 0) {
|
||||||
|
return STATUSES.STATUS_PASSED
|
||||||
|
} else if (rule.level === RULE_LEVELS.LEVEL_WARNING) {
|
||||||
|
return STATUSES.STATUS_VERIFY
|
||||||
|
} else {
|
||||||
|
return STATUSES.STATUS_FAILED
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export function getRuleCountByStatus(rules, status) {
|
||||||
|
return rules.filter(rule => getRuleStatus(rule) === status).length;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function sortRules(rules) {
|
||||||
|
rules.sort(compareRules);
|
||||||
|
return rules;
|
||||||
|
}
|
||||||
|
|
||||||
|
function compareRules(firstRule, secondRule) {
|
||||||
|
let firstStatus = getRuleStatus(firstRule);
|
||||||
|
let secondStatus = getRuleStatus(secondRule);
|
||||||
|
return compareRuleStatuses(firstStatus, secondStatus);
|
||||||
|
}
|
||||||
|
|
||||||
|
function compareRuleStatuses(ruleStatusOne, ruleStatusTwo) {
|
||||||
|
if (ruleStatusOne === ruleStatusTwo) {
|
||||||
|
return 0;
|
||||||
|
} else if (ruleStatusOne === STATUSES.STATUS_FAILED) {
|
||||||
|
return -1;
|
||||||
|
} else if (ruleStatusTwo === STATUSES.STATUS_FAILED) {
|
||||||
|
return 1;
|
||||||
|
} else if (ruleStatusOne === STATUSES.STATUS_VERIFY) {
|
||||||
|
return -1;
|
||||||
|
} else if (ruleStatusTwo === STATUSES.STATUS_VERIFY) {
|
||||||
|
return 1;
|
||||||
|
} else if (ruleStatusOne === STATUSES.STATUS_PASSED) {
|
||||||
|
return -1;
|
||||||
|
} else if (ruleStatusTwo === STATUSES.STATUS_PASSED) {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue