Commit 1165591c authored by Kushal Pandya's avatar Kushal Pandya

Merge branch 'djadmin-markdown-pipeline-vuln-desc' into 'master'

Pipeline Security: Render markdown content for Vulnerability description

See merge request gitlab-org/gitlab!76382
parents 005e6b2b e2f971cd
<script>
import { GlFriendlyWrap, GlLink, GlBadge } from '@gitlab/ui';
import { GlFriendlyWrap, GlLink, GlBadge, GlSafeHtmlDirective } from '@gitlab/ui';
import { REPORT_TYPES } from 'ee/security_dashboard/store/constants';
import FalsePositiveAlert from 'ee/vulnerabilities/components/false_positive_alert.vue';
import GenericReportSection from 'ee/vulnerabilities/components/generic_report/report_section.vue';
......@@ -24,6 +24,9 @@ export default {
GlBadge,
FalsePositiveAlert,
},
directives: {
SafeHtml: GlSafeHtmlDirective,
},
props: { vulnerability: { type: Object, required: true } },
computed: {
url() {
......@@ -126,6 +129,9 @@ export default {
falsePositive() {
return this.vulnerability.false_positive;
},
hasDescription() {
return this.vulnerability.description_html || this.vulnerability.description;
},
hasRequest() {
return Boolean(this.constructedRequest);
},
......@@ -178,11 +184,13 @@ export default {
<vulnerability-detail v-if="vulnerability.state" :label="s__('Vulnerability|Status')">
<gl-badge variant="warning" class="text-capitalize">{{ vulnerability.state }}</gl-badge>
</vulnerability-detail>
<vulnerability-detail
v-if="vulnerability.description"
:label="s__('Vulnerability|Description')"
>
<gl-friendly-wrap :text="vulnerability.description" />
<vulnerability-detail v-if="hasDescription" :label="s__('Vulnerability|Description')">
<p
v-if="vulnerability.description_html"
v-safe-html="vulnerability.description_html"
data-testid="description"
></p>
<p v-else data-testid="description">{{ vulnerability.description }}</p>
</vulnerability-detail>
<vulnerability-detail v-if="vulnerability.project" :label="s__('Vulnerability|Project')">
<gl-link ref="projectLink" :href="vulnerability.project.full_path" target="_blank">
......
......@@ -3,6 +3,7 @@
class Vulnerabilities::FindingEntity < Grape::Entity
include RequestAwareEntity
include VulnerabilitiesHelper
include MarkupHelper
expose :id, :report_type, :name, :severity, :confidence
expose :scanner, using: Vulnerabilities::ScannerEntity
......@@ -32,6 +33,9 @@ class Vulnerabilities::FindingEntity < Grape::Entity
expose :metadata, merge: true, if: ->(occurrence, _) { occurrence.raw_metadata } do
expose :description
expose :description_html do |model|
markdown(model.description)
end
expose :links
expose :location
expose :remediations
......
......@@ -21,10 +21,11 @@ exports[`VulnerabilityDetails component pin test renders correctly 1`] = `
<vulnerability-detail-stub
label="Description"
>
<gl-friendly-wrap-stub
symbols="/"
text="The serialize-javascript npm package is vulnerable to Cross-site Scripting (XSS). It does not properly mitigate against unsafe characters in serialized regular expressions. If serialized data of regular expression objects are used in an environment other than Node.js, it is affected by this vulnerability."
/>
<p
data-testid="description"
>
The serialize-javascript npm package is vulnerable to Cross-site Scripting (XSS). It does not properly mitigate against unsafe characters in serialized regular expressions. If serialized data of regular expression objects are used in an environment other than Node.js, it is affected by this vulnerability.
</p>
</vulnerability-detail-stub>
<vulnerability-detail-stub
......
import { GlLink, GlBadge } from '@gitlab/ui';
import { mount, shallowMount } from '@vue/test-utils';
import { shallowMount } from '@vue/test-utils';
import { cloneDeep } from 'lodash';
import { EMPTY_BODY_MESSAGE } from 'ee/vue_shared/security_reports/components/constants';
import SeverityBadge from 'ee/vue_shared/security_reports/components/severity_badge.vue';
......@@ -7,6 +7,7 @@ import VulnerabilityDetails from 'ee/vue_shared/security_reports/components/vuln
import FalsePositiveAlert from 'ee/vulnerabilities/components/false_positive_alert.vue';
import GenericReportSection from 'ee/vulnerabilities/components/generic_report/report_section.vue';
import { SUPPORTING_MESSAGE_TYPES } from 'ee/vulnerabilities/constants';
import { mountExtended } from 'helpers/vue_test_utils_helper';
import { TEST_HOST } from 'helpers/test_constants';
import { mockFindings } from '../mock_data';
......@@ -19,7 +20,7 @@ describe('VulnerabilityDetails component', () => {
let wrapper;
const componentFactory = (vulnerability, provide = {}) => {
wrapper = mount(VulnerabilityDetails, {
wrapper = mountExtended(VulnerabilityDetails, {
propsData: { vulnerability },
provide,
});
......@@ -44,6 +45,7 @@ describe('VulnerabilityDetails component', () => {
const findStacktraceSnippet = () => wrapper.find({ ref: 'stacktraceSnippet' });
const findGenericReportSection = () => wrapper.findComponent(GenericReportSection);
const findAlert = () => wrapper.findComponent(FalsePositiveAlert);
const findDescription = () => wrapper.findByTestId('description');
const USER_NOT_FOUND_MESSAGE = '{"message":"User not found."}';
......@@ -61,6 +63,22 @@ describe('VulnerabilityDetails component', () => {
expect(findAlert().exists()).toBe(true);
});
it('renders description text when markdown is not present', () => {
const vulnerability = makeVulnerability();
componentFactory(vulnerability);
const section = findDescription();
expect(section.text()).toBe(vulnerability.description);
});
it('renders description html when markdown is present', () => {
const vulnerability = makeVulnerability({ description_html: '<code>test</code>' });
componentFactory(vulnerability);
const section = findDescription();
expect(section.html()).toContain(vulnerability.description_html);
});
it('renders severity with a badge', () => {
const vulnerability = makeVulnerability({ severity: 'critical' });
componentFactory(vulnerability);
......
......@@ -306,7 +306,7 @@ RSpec.describe VulnerabilitiesHelper do
it 'returns finding information' do
expect(subject.to_h).to match(
description: finding.description,
description_html: anything,
description_html: match(%r<p data-sourcepos.*?\<\/p>),
identifiers: kind_of(Array),
issue_feedback: anything,
links: finding.links,
......
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