Commit a4e7abc8 authored by Mark Florian's avatar Mark Florian

Merge branch '199145-add-severity-badge-to-MR-report' into 'master'

Add severity badge to security reports

See merge request gitlab-org/gitlab!26715
parents e47889f9 651851a0
......@@ -23,7 +23,7 @@ GitLab checks the Container Scanning report, compares the found vulnerabilities
between the source and target branches, and shows the information right on the
merge request.
![Container Scanning Widget](img/container_scanning.png)
![Container Scanning Widget](img/container_scanning_v12_9.png)
## Use cases
......
......@@ -35,12 +35,12 @@ NOTE: **Note:**
This comparison logic uses only the latest pipeline executed for the target branch's base commit.
Running the pipeline on any other commit has no effect on the merge request.
![DAST Widget](img/dast_all.png)
![DAST Widget](img/dast_all_v12_9.png)
By clicking on one of the detected linked vulnerabilities, you will be able to
see the details and the URL(s) affected.
![DAST Widget Clicked](img/dast_single.png)
![DAST Widget Clicked](img/dast_single_v12_9.png)
[Dynamic Application Security Testing (DAST)](https://en.wikipedia.org/wiki/Dynamic_Application_Security_Testing)
is using the popular open source tool [OWASP ZAProxy](https://github.com/zaproxy/zaproxy)
......
......@@ -25,7 +25,7 @@ that is provided by [Auto DevOps](../../../topics/autodevops/index.md).
GitLab checks the SAST report, compares the found vulnerabilities between the
source and target branches, and shows the information right on the merge request.
![SAST Widget](img/sast.png)
![SAST Widget](img/sast_v12_9.png)
The results are sorted by the priority of the vulnerability:
......
<script>
/**
* Renders CONTAINER SCANNING body text
* [priority]: [name] in [link]:[line]
* [severity-badge] [name] in [link]:[line]
*/
import ModalOpenName from '~/reports/components/modal_open_name.vue';
import { humanize } from '~/lib/utils/text_utility';
import SeverityBadge from './severity_badge.vue';
export default {
name: 'ContainerScanningIssueBody',
components: {
ModalOpenName,
SeverityBadge,
},
props: {
issue: {
......@@ -22,20 +23,12 @@ export default {
required: true,
},
},
computed: {
severity() {
return this.issue.severity ? humanize(this.issue.severity) : null;
},
},
};
</script>
<template>
<div class="report-block-list-issue-description prepend-top-5 append-bottom-5">
<div class="report-block-list-issue-description-text">
<template v-if="severity">
{{ severity }}:
</template>
<severity-badge v-if="issue.severity" class="d-inline-block" :severity="issue.severity" />
<modal-open-name :issue="issue" :status="status" />
</div>
</div>
......
<script>
/**
* Renders DAST body text
* [severity]: [name]
* [severity-badge] [name] in [link]:[line]
*/
import ModalOpenName from '~/reports/components/modal_open_name.vue';
import SeverityBadge from './severity_badge.vue';
export default {
name: 'DastIssueBody',
components: {
ModalOpenName,
SeverityBadge,
},
props: {
issue: {
......@@ -27,8 +28,7 @@ export default {
<template>
<div class="report-block-list-issue-description prepend-top-5 append-bottom-5">
<div class="report-block-list-issue-description-text">
{{ issue.severity }}:
<severity-badge v-if="issue.severity" class="d-inline-block" :severity="issue.severity" />
<modal-open-name :issue="issue" :status="status" class="js-modal-dast" />
</div>
</div>
......
<script>
/**
* Renders SAST body text
* [severity]: [name] in [link] : [line]
* [severity-badge] [name] in [link]:[line]
*/
import ReportLink from '~/reports/components/report_link.vue';
import ModalOpenName from '~/reports/components/modal_open_name.vue';
import { humanize } from '~/lib/utils/text_utility';
import SeverityBadge from './severity_badge.vue';
export default {
name: 'SastIssueBody',
components: {
ReportLink,
ModalOpenName,
SeverityBadge,
},
props: {
issue: {
type: Object,
......@@ -26,25 +25,14 @@ export default {
required: true,
},
},
computed: {
title() {
const { severity, priority } = this.issue;
if (severity) {
return humanize(severity);
}
return priority;
},
},
};
</script>
<template>
<div class="report-block-list-issue-description prepend-top-5 append-bottom-5">
<div class="report-block-list-issue-description-text">
{{ title }}:
<severity-badge v-if="issue.severity" class="d-inline-block" :severity="issue.severity" />
<modal-open-name :issue="issue" :status="status" />
</div>
<report-link v-if="issue.path" :issue="issue" />
</div>
</template>
---
title: Add severity badge to security reports
merge_request: 26715
author:
type: changed
......@@ -7,8 +7,10 @@ exports[`Container Scanning Issue Body matches snapshot 1`] = `
<div
class="report-block-list-issue-description-text"
>
Low:
<severity-badge-stub
class="d-inline-block"
severity="Low"
/>
<modal-open-name-stub
issue="[object Object]"
......
......@@ -7,10 +7,11 @@ exports[`Dast Issue Body matches the snaphot 1`] = `
<div
class="report-block-list-issue-description-text"
>
Low:
<severity-badge-stub
class="d-inline-block"
severity="Low"
/>
<modal-open-name-stub
class="js-modal-dast"
issue="[object Object]"
......
......@@ -7,9 +7,11 @@ exports[`Sast Issue Body matches snapshot 1`] = `
<div
class="report-block-list-issue-description-text"
>
Medium:
<severity-badge-stub
class="d-inline-block"
severity="Medium"
/>
<modal-open-name-stub
issue="[object Object]"
status="failed"
......
import { shallowMount } from '@vue/test-utils';
import ContainerScanningIssueBody from 'ee/vue_shared/security_reports/components/container_scanning_issue_body.vue';
import SeverityBadge from 'ee/vue_shared/security_reports/components/severity_badge.vue';
describe('Container Scanning Issue Body', () => {
let wrapper;
const createComponent = severity => {
const createComponent = (severity = undefined) => {
wrapper = shallowMount(ContainerScanningIssueBody, {
propsData: {
issue: {
......@@ -30,13 +31,13 @@ describe('Container Scanning Issue Body', () => {
expect(wrapper.element).toMatchSnapshot();
});
it('renders severity if present on issue', () => {
it('does show SeverityBadge if severity is present', () => {
createComponent('Low');
expect(wrapper.find('.report-block-list-issue-description-text').text()).toBe('Low:');
expect(wrapper.find(SeverityBadge).props('severity')).toBe('Low');
});
it('does not render severity if not present on issue', () => {
it('does not show SeverityBadge if severity is not present', () => {
createComponent();
expect(wrapper.find('.report-block-list-issue-description-text').text()).toBe('');
expect(wrapper.contains(SeverityBadge)).toBe(false);
});
});
import { shallowMount } from '@vue/test-utils';
import { STATUS_FAILED } from '~/reports/constants';
import SastIssueBody from 'ee/vue_shared/security_reports/components/sast_issue_body.vue';
import SeverityBadge from 'ee/vue_shared/security_reports/components/severity_badge.vue';
import ReportLink from '~/reports/components/report_link.vue';
describe('Sast Issue Body', () => {
let wrapper;
const findDescriptionText = () => wrapper.find('.report-block-list-issue-description-text');
const findReportLink = () => wrapper.find(ReportLink);
const createComponent = issue => {
......@@ -25,27 +25,23 @@ describe('Sast Issue Body', () => {
it('matches snapshot', () => {
createComponent({
severity: 'medium',
priority: 'high',
severity: 'Medium',
});
expect(wrapper.element).toMatchSnapshot();
});
it('renders priority if no security are passed', () => {
it('does show SeverityBadge if severity is present', () => {
createComponent({
priority: 'high',
severity: 'Medium',
});
expect(findDescriptionText().text()).toBe('high:');
expect(wrapper.find(SeverityBadge).props('severity')).toBe('Medium');
});
it('renders severity', () => {
createComponent({
severity: 'medium',
});
expect(findDescriptionText().text()).toBe('Medium:');
it('does not show SeverityBadge if severity is not present', () => {
createComponent({});
expect(wrapper.contains(SeverityBadge)).toBe(false);
});
it('does not render report link if no path is passed', () => {
......
......@@ -5,7 +5,7 @@ export const sastParsedIssues = [
title: 'Arbitrary file existence disclosure in Action Pack',
path: 'Gemfile.lock',
line: 12,
priority: 'High',
severity: 'High',
urlPath: 'foo/Gemfile.lock',
},
];
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment