Skip to content

Commit

Permalink
Merge pull request DependencyTrack#715 from setchy/feature/dashboard-…
Browse files Browse the repository at this point in the history
…auditing-progress

feat(dashboard): auditing progress for findings and policy violations
  • Loading branch information
setchy committed Jan 30, 2024
2 parents 362896c + 2d71d49 commit d4d622c
Show file tree
Hide file tree
Showing 11 changed files with 301 additions and 63 deletions.
2 changes: 1 addition & 1 deletion docker/Dockerfile.alpine
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
FROM nginxinc/nginx-unprivileged:1.25.3-alpine@sha256:939d113c899dbe01d5eea7724f42e9744d57205681ab530b5dc1e14377ffff2f
FROM nginxinc/nginx-unprivileged:1.25.3-alpine@sha256:69bd3c1d739c28af7e123b69fa4f0e12e679034e71920fdcc402fae39e2af47b

# Arguments that can be passed at build time
ARG COMMIT_SHA=unknown
Expand Down
4 changes: 4 additions & 0 deletions src/assets/scss/_variables.scss
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,8 @@ $severity-label-bg: $grey-900 !default;
$notification-fail: $red;
$notification-warn: $yellow;
$notification-info: $blue;
$notification-pass: $green;
$notification-note: #777777;

// Components
//
Expand Down Expand Up @@ -231,6 +233,8 @@ $recessed: $grey-850;
--notification-fail: #{$notification-fail};
--notification-warn: #{$notification-warn};
--notification-info: #{$notification-info};
--notification-pass: #{$notification-pass};
--notification-note: #{$notification-note};

--component-active-color: #{$component-active-color};

Expand Down
4 changes: 4 additions & 0 deletions src/i18n/locales/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -42,8 +42,10 @@
"inherited_risk_score": "Inherited Risk Score",
"risk_score": "Risk Score",
"vulnerable_projects": "Vulnerable Projects",
"findings": "Findings",
"total_findings": "Total Findings",
"findings_audited": "Findings Audited",
"findings_unaudited": "Findings Unaudited",
"auditing_progress": "Auditing Progress",
"show_suppressed_findings": "Show suppressed findings",
"show_suppressed_violations": "Show suppressed violations",
Expand All @@ -69,6 +71,7 @@
"fsf_libre": "FSF Libre",
"total": "Total",
"vulnerable": "Vulnerable",
"non_vulnerable": "Non Vulnerable",
"portfolio_statistics": "Portfolio Statistics",
"suppress": "Suppress",
"suppressed": "Suppressed",
Expand All @@ -84,6 +87,7 @@
"license_risk": "License Risk",
"operational_risk": "Operational Risk",
"violations_audited": "Violations Audited",
"violations_unaudited": "Violations Unaudited",
"attributed_on": "Attributed On",
"view_details": "View Details",
"project_details": "Project Details",
Expand Down
188 changes: 162 additions & 26 deletions src/views/Dashboard.vue

Large diffs are not rendered by default.

100 changes: 100 additions & 0 deletions src/views/dashboard/ChartAuditingViolationsProgress.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
<script>
import common from "../../shared/common"
import { Line } from 'vue-chartjs'
import { getStyle, hexToRgba } from '@coreui/coreui/dist/js/coreui-utilities'
import { CustomTooltips } from '@coreui/coreui-plugin-chartjs-custom-tooltips'
export default {
extends: Line,
props: {
height: Number
},
methods: {
render: function(metrics) {
const totalStyle = getStyle('--severity-unassigned');
const auditedStyle = getStyle('--severity-low');
let labels = [];
let totalData = [];
let auditedData = [];
for (let i = 0; i < metrics.length; i++) {
labels.push(common.formatTimestamp(metrics[i].firstOccurrence));
totalData.push(metrics[i].policyViolationsTotal);
auditedData.push(metrics[i].policyViolationsAudited);
if (i === metrics.length - 1) {
labels.push(common.formatTimestamp(metrics[i].lastOccurrence));
totalData.push(metrics[i].policyViolationsTotal);
auditedData.push(metrics[i].policyViolationsAudited);
}
}
this.renderChart({
labels: labels,
datasets: [
{
label: this.$t('message.policy_violations'),
backgroundColor: 'transparent',
borderColor: totalStyle,
pointHoverBackgroundColor: '#fff',
data: totalData
},
{
label: this.$t('message.violations_audited'),
backgroundColor: hexToRgba(auditedStyle, 10),
borderColor: auditedStyle,
pointHoverBackgroundColor: '#fff',
data: auditedData
}
]
}, {
tooltips: {
enabled: false,
custom: CustomTooltips,
intersect: true,
mode: 'index',
position: 'nearest',
callbacks: {
labelColor: function (tooltipItem, chart) {
return { backgroundColor: chart.data.datasets[tooltipItem.datasetIndex].borderColor }
}
}
},
maintainAspectRatio: false,
legend: {
display: false
},
scales: {
xAxes: [{
gridLines: {
drawOnChartArea: false
}
}],
yAxes: [{
ticks: {
beginAtZero: true,
maxTicksLimit: 1
},
gridLines: {
display: true
}
}]
},
elements: {
line: {
tension: 0.1,
borderWidth: 2
},
point: {
radius: 0,
hitRadius: 20,
hoverRadius: 4,
hoverBorderWidth: 3
}
}
})
}
}
}
</script>
15 changes: 13 additions & 2 deletions src/views/dashboard/ChartComponentVulnerabilities.vue
Original file line number Diff line number Diff line change
Expand Up @@ -11,22 +11,26 @@
},
methods: {
render: function(metrics) {
const totalStyle = getStyle('--severity-unassigned');
const affectedStyle = getStyle('--severity-info');
const totalStyle = getStyle('--notification-note');
const affectedStyle = getStyle('--notification-warn');
const nonAffectedStyle = getStyle('--notification-pass');
let labels = [];
let totalData = [];
let affectedData = [];
let nonAffectedData = [];
for (let i = 0; i < metrics.length; i++) {
labels.push(common.formatTimestamp(metrics[i].firstOccurrence));
totalData.push(metrics[i].components);
affectedData.push(metrics[i].vulnerableComponents);
nonAffectedData.push(metrics[i].components - metrics[i].vulnerableComponents)
if (i === metrics.length - 1) {
labels.push(common.formatTimestamp(metrics[i].lastOccurrence));
totalData.push(metrics[i].components);
affectedData.push(metrics[i].vulnerableComponents);
nonAffectedData.push(metrics[i].components - metrics[i].vulnerableComponents)
}
}
Expand All @@ -40,6 +44,13 @@
pointHoverBackgroundColor: '#fff',
data: totalData
},
{
label: this.$t('message.non_vulnerable'),
backgroundColor: hexToRgba(nonAffectedStyle, 10),
borderColor: nonAffectedStyle,
pointHoverBackgroundColor: '#fff',
data: nonAffectedData
},
{
label: this.$t('message.vulnerable'),
backgroundColor: hexToRgba(affectedStyle, 10),
Expand Down
15 changes: 13 additions & 2 deletions src/views/dashboard/ChartProjectVulnerabilities.vue
Original file line number Diff line number Diff line change
Expand Up @@ -11,22 +11,26 @@
},
methods: {
render: function(metrics) {
const totalStyle = getStyle('--severity-unassigned');
const affectedStyle = getStyle('--severity-info');
const totalStyle = getStyle('--notification-note');
const affectedStyle = getStyle('--notification-warn');
const nonAffectedStyle = getStyle('--notification-pass');
let labels = [];
let totalData = [];
let affectedData = [];
let nonAffectedData = [];
for (let i = 0; i < metrics.length; i++) {
labels.push(common.formatTimestamp(metrics[i].firstOccurrence));
totalData.push(metrics[i].projects);
affectedData.push(metrics[i].vulnerableProjects);
nonAffectedData.push(metrics[i].projects - metrics[i].vulnerableProjects)
if (i === metrics.length - 1) {
labels.push(common.formatTimestamp(metrics[i].lastOccurrence));
totalData.push(metrics[i].projects);
affectedData.push(metrics[i].vulnerableProjects);
nonAffectedData.push(metrics[i].projects - metrics[i].vulnerableProjects)
}
}
Expand All @@ -40,6 +44,13 @@
pointHoverBackgroundColor: '#fff',
data: totalData
},
{
label: this.$t('message.non_vulnerable'),
backgroundColor: hexToRgba(nonAffectedStyle, 10),
borderColor: nonAffectedStyle,
pointHoverBackgroundColor: '#fff',
data: nonAffectedData
},
{
label: this.$t('message.vulnerable'),
backgroundColor: hexToRgba(affectedStyle, 10),
Expand Down
10 changes: 0 additions & 10 deletions src/views/portfolio/projects/ComponentDashboard.vue
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,6 @@
<script>
import common from "../../../shared/common"
import { Callout } from '@coreui/vue'
import ChartAuditingProgress from "../../dashboard/ChartAuditingProgress";
import ChartComponentVulnerabilities from "../../dashboard/ChartComponentVulnerabilities";
import ChartPortfolioVulnerabilities from '../../dashboard/ChartPortfolioVulnerabilities';
import ChartPolicyViolationsState from "@/views/dashboard/ChartPolicyViolationsState";
Expand All @@ -112,7 +111,6 @@
export default {
name: 'ComponentDashboard',
components: {
ChartAuditingProgress,
ChartComponentVulnerabilities,
ChartPortfolioVulnerabilities,
ChartPolicyViolationsState,
Expand All @@ -133,10 +131,6 @@
vulnerableComponents: 0,
vulnerableComponentPercent: 0,
totalFindings: 0,
auditedFindings: 0,
auditedFindingPercent: 0,
vulnerabilities: 0,
suppressed: 0,
lastMeasurement: ""
Expand All @@ -159,10 +153,6 @@
this.vulnerableComponents = common.valueWithDefault(metric.vulnerableComponents, "0");
this.vulnerableComponentPercent = common.calcProgressPercent(this.totalComponents, this.vulnerableComponents);
this.totalFindings = common.valueWithDefault(metric.findingsTotal, "0");
this.auditedFindings = common.valueWithDefault(metric.findingsAudited, "0");
this.auditedFindingPercent = common.calcProgressPercent(this.findingsTotal, this.findingsAudited);
this.vulnerabilities = common.valueWithDefault(metric.vulnerabilities, "0");
this.suppressed = common.valueWithDefault(metric.suppressed, "0");
this.lastMeasurement = common.formatTimestamp(metric.lastOccurrence, true);
Expand Down
16 changes: 4 additions & 12 deletions src/views/portfolio/projects/ProjectDashboard.vue
Original file line number Diff line number Diff line change
Expand Up @@ -131,7 +131,7 @@
<b-col sm="7" class="d-none d-md-block">
</b-col>
</b-row>
<chart-auditing-progress ref="chartAuditedProgress" chartId="chartAuditedProgress" class="chart-wrapper" style="height:200px;margin-top:40px;" :height="200"></chart-auditing-progress>
<chart-auditing-findings-progress ref="chartAuditingFindingsProgress" chartId="chartAuditingFindingsProgress" class="chart-wrapper" style="height:200px;margin-top:40px;" :height="200"></chart-auditing-findings-progress>
</b-card>
</b-col>
</b-row>
Expand All @@ -141,7 +141,7 @@
<script>
import common from "../../../shared/common"
import { Callout } from '@coreui/vue'
import ChartAuditingProgress from "../../dashboard/ChartAuditingProgress";
import ChartAuditingFindingsProgress from "../../dashboard/ChartAuditingFindingsProgress";
import ChartComponentVulnerabilities from "../../dashboard/ChartComponentVulnerabilities";
import ChartPortfolioVulnerabilities from '../../dashboard/ChartPortfolioVulnerabilities'
import ChartPolicyViolationsState from "@/views/dashboard/ChartPolicyViolationsState";
Expand All @@ -152,7 +152,7 @@
components: {
ChartPolicyViolationsState,
ChartPolicyViolationBreakdown,
ChartAuditingProgress,
ChartAuditingFindingsProgress,
ChartComponentVulnerabilities,
ChartPortfolioVulnerabilities,
Callout
Expand All @@ -174,10 +174,6 @@
vulnerableComponents: 0,
vulnerableComponentPercent: 0,
totalFindings: 0,
auditedFindings: 0,
auditedFindingPercent: 0,
vulnerabilities: 0,
suppressed: 0,
lastMeasurement: "n/a",
Expand All @@ -201,10 +197,6 @@
this.vulnerableComponents = common.valueWithDefault(metric.vulnerableComponents, "0");
this.vulnerableComponentPercent = common.calcProgressPercent(this.totalComponents, this.vulnerableComponents);
this.totalFindings = common.valueWithDefault(metric.findingsTotal, "0");
this.auditedFindings = common.valueWithDefault(metric.findingsAudited, "0");
this.auditedFindingPercent = common.calcProgressPercent(this.findingsTotal, this.findingsAudited);
this.vulnerabilities = common.valueWithDefault(metric.vulnerabilities, "0");
this.suppressed = common.valueWithDefault(metric.suppressed, "0");
this.lastMeasurement = common.formatTimestamp(metric.lastOccurrence, true);
Expand All @@ -223,7 +215,7 @@
this.$refs.chartProjectVulnerabilities.render(response.data);
this.$refs.chartPolicyViolationsState.render(response.data);
this.$refs.chartPolicyViolationBreakdown.render(response.data);
this.$refs.chartAuditedProgress.render(response.data);
this.$refs.chartAuditingFindingsProgress.render(response.data);
this.$refs.chartComponentVulnerabilities.render(response.data);
this.extractStats(response.data);
});
Expand Down
10 changes: 0 additions & 10 deletions src/views/portfolio/projects/ServiceDashboard.vue
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,6 @@
<script>
import common from "../../../shared/common"
import { Callout } from '@coreui/vue'
import ChartAuditingProgress from "../../dashboard/ChartAuditingProgress";
import ChartComponentVulnerabilities from "../../dashboard/ChartComponentVulnerabilities";
import ChartPortfolioVulnerabilities from '../../dashboard/ChartPortfolioVulnerabilities';
import ChartPolicyViolationsState from "@/views/dashboard/ChartPolicyViolationsState";
Expand All @@ -112,7 +111,6 @@ import ChartPolicyViolationBreakdown from '@/views/dashboard/ChartPolicyViolatio
export default {
name: 'ServiceDashboard',
components: {
ChartAuditingProgress,
ChartComponentVulnerabilities,
ChartPortfolioVulnerabilities,
ChartPolicyViolationsState,
Expand All @@ -133,10 +131,6 @@ export default {
vulnerableComponents: 0,
vulnerableComponentPercent: 0,
totalFindings: 0,
auditedFindings: 0,
auditedFindingPercent: 0,
vulnerabilities: 0,
suppressed: 0,
lastMeasurement: ""
Expand All @@ -159,10 +153,6 @@ export default {
this.vulnerableComponents = common.valueWithDefault(metric.vulnerableComponents, "0");
this.vulnerableComponentPercent = common.calcProgressPercent(this.totalComponents, this.vulnerableComponents);
this.totalFindings = common.valueWithDefault(metric.findingsTotal, "0");
this.auditedFindings = common.valueWithDefault(metric.findingsAudited, "0");
this.auditedFindingPercent = common.calcProgressPercent(this.findingsTotal, this.findingsAudited);
this.vulnerabilities = common.valueWithDefault(metric.vulnerabilities, "0");
this.suppressed = common.valueWithDefault(metric.suppressed, "0");
this.lastMeasurement = common.formatTimestamp(metric.lastOccurrence, true);
Expand Down

0 comments on commit d4d622c

Please sign in to comment.