Commit 610e8da0 authored by Olivier Gonzalez's avatar Olivier Gonzalez

Display dimissal author and associated pipeline. refs #5953

parent dd83d193
...@@ -20,6 +20,11 @@ export default { ...@@ -20,6 +20,11 @@ export default {
? s__('ciReport|Revert dismissal') ? s__('ciReport|Revert dismissal')
: s__('ciReport|Dismiss vulnerability'); : s__('ciReport|Dismiss vulnerability');
}, },
hasDismissedBy() {
return this.modal.vulnerability.dismissalFeedback &&
this.modal.vulnerability.dismissalFeedback.pipeline &&
this.modal.vulnerability.dismissalFeedback.author;
},
}, },
methods: { methods: {
...mapActions(['dismissIssue', 'revertDismissIssue', 'createNewIssue']), ...mapActions(['dismissIssue', 'revertDismissIssue', 'createNewIssue']),
...@@ -112,6 +117,20 @@ export default { ...@@ -112,6 +117,20 @@ export default {
<div class="row prepend-top-20 append-bottom-10"> <div class="row prepend-top-20 append-bottom-10">
<div class="col-sm-10 col-sm-offset-2 text-secondary"> <div class="col-sm-10 col-sm-offset-2 text-secondary">
<template v-if="hasDismissedBy">
{{ s__('ciReport|Dismissed by') }}
<a
:href="modal.vulnerability.dismissalFeedback.author.web_url"
class="pipeline-id"
>
@{{ modal.vulnerability.dismissalFeedback.author.username }}
</a>
{{ s__('ciReport|on pipeline') }}
<a
:href="modal.vulnerability.dismissalFeedback.pipeline.path"
class="pipeline-id"
>#{{ modal.vulnerability.dismissalFeedback.pipeline.id }}</a>.
</template>
<a <a
class="js-link-vulnerabilityFeedbackHelpPath" class="js-link-vulnerabilityFeedbackHelpPath"
:href="vulnerabilityFeedbackHelpPath" :href="vulnerabilityFeedbackHelpPath"
......
...@@ -17,5 +17,5 @@ class VulnerabilityFeedback < ActiveRecord::Base ...@@ -17,5 +17,5 @@ class VulnerabilityFeedback < ActiveRecord::Base
validates :category, presence: true validates :category, presence: true
validates :project_fingerprint, presence: true, uniqueness: { scope: [:project_id, :category, :feedback_type] } validates :project_fingerprint, presence: true, uniqueness: { scope: [:project_id, :category, :feedback_type] }
scope :with_associations, -> { includes(:pipeline, :issue) } scope :with_associations, -> { includes(:pipeline, :issue, :author) }
end end
...@@ -4,9 +4,17 @@ class VulnerabilityFeedbackEntity < Grape::Entity ...@@ -4,9 +4,17 @@ class VulnerabilityFeedbackEntity < Grape::Entity
expose :id expose :id
expose :project_id expose :project_id
expose :author_id expose :author, using: UserEntity
expose :issue_id expose :issue_id
expose :pipeline_id expose :pipeline, if: -> (feedback, _) { feedback.pipeline.present? } do
expose :id do |feedback|
feedback.pipeline.id
end
expose :path do |feedback|
project_pipeline_path(feedback.pipeline.project, feedback.pipeline)
end
end
expose :issue_url, if: -> (feedback, _) { feedback.issue? } do |feedback| expose :issue_url, if: -> (feedback, _) { feedback.issue? } do |feedback|
project_issue_url(feedback.project, feedback.issue) project_issue_url(feedback.project, feedback.issue)
......
...@@ -3,7 +3,7 @@ ...@@ -3,7 +3,7 @@
"required" : [ "required" : [
"id", "id",
"project_id", "project_id",
"author_id", "author",
"feedback_type", "feedback_type",
"category", "category",
"project_fingerprint" "project_fingerprint"
...@@ -11,8 +11,11 @@ ...@@ -11,8 +11,11 @@
"properties" : { "properties" : {
"id": { "type": "integer" }, "id": { "type": "integer" },
"project_id": { "type": "integer" }, "project_id": { "type": "integer" },
"author_id": { "type": "integer" }, "author": { "$ref": "../../../../../spec/fixtures/api/schemas/entities/user.json" },
"pipeline_id": { "type": ["integer", "null"] }, "pipeline": {
"id": { "type": ["integer", "null"] },
"path": { "type": ["string", "null"] }
},
"issue_id": { "type": ["integer", "null"] }, "issue_id": { "type": ["integer", "null"] },
"issue_url": { "type": ["string", "null"] }, "issue_url": { "type": ["string", "null"] },
"feedback_type": { "feedback_type": {
......
...@@ -8,8 +8,8 @@ msgid "" ...@@ -8,8 +8,8 @@ msgid ""
msgstr "" msgstr ""
"Project-Id-Version: gitlab 1.0.0\n" "Project-Id-Version: gitlab 1.0.0\n"
"Report-Msgid-Bugs-To: \n" "Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2018-05-29 11:32+0200\n" "POT-Creation-Date: 2018-05-30 10:16-0400\n"
"PO-Revision-Date: 2018-05-29 11:32+0200\n" "PO-Revision-Date: 2018-05-30 10:16-0400\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n" "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n" "Language-Team: LANGUAGE <LL@li.org>\n"
"Language: \n" "Language: \n"
...@@ -5889,6 +5889,9 @@ msgstr "" ...@@ -5889,6 +5889,9 @@ msgstr ""
msgid "ciReport|Dismiss vulnerability" msgid "ciReport|Dismiss vulnerability"
msgstr "" msgstr ""
msgid "ciReport|Dismissed by"
msgstr ""
msgid "ciReport|Dynamic Application Security Testing (DAST) detects known vulnerabilities in your web application." msgid "ciReport|Dynamic Application Security Testing (DAST) detects known vulnerabilities in your web application."
msgstr "" msgstr ""
...@@ -5982,6 +5985,9 @@ msgstr "" ...@@ -5982,6 +5985,9 @@ msgstr ""
msgid "ciReport|no vulnerabilities" msgid "ciReport|no vulnerabilities"
msgstr "" msgstr ""
msgid "ciReport|on pipeline"
msgstr ""
msgid "command line instructions" msgid "command line instructions"
msgstr "" msgstr ""
......
...@@ -31,14 +31,19 @@ describe('Security Reports modal', () => { ...@@ -31,14 +31,19 @@ describe('Security Reports modal', () => {
path: 'Gemfile.lock', path: 'Gemfile.lock',
urlPath: 'path/Gemfile.lock', urlPath: 'path/Gemfile.lock',
isDismissed: true, isDismissed: true,
vulnerability_feedback: { dismissalFeedback: {
vulnerability_data: { id: 1,
tool: 'bundler_audit', category: 'sast',
message: 'Arbitrary file existence disclosure in Action Pack', feedback_type: 'dismissal',
url: 'https://groups.google.com/forum/#!topic/rubyonrails-security/rMTQy4oRCGk', issue_id: null,
cve: 'CVE-2016-9999', author: {
file: 'Gemfile.lock', name: 'John Smith',
solution: 'upgrade to ~> 3.2.21, ~> 4.0.11.1, ~> 4.0.12, ~> 4.1.7.1, >= 4.1.8', username: 'jsmith',
web_url: 'https;//gitlab.com/user1',
},
pipeline: {
id: 123,
path: '/jsmith/awesome-project/pipelines/123',
}, },
}, },
}); });
...@@ -48,6 +53,11 @@ describe('Security Reports modal', () => { ...@@ -48,6 +53,11 @@ describe('Security Reports modal', () => {
}); });
}); });
it('renders dismissal author and associated pipeline', () => {
expect(vm.$el.textContent.trim()).toContain('@jsmith');
expect(vm.$el.textContent.trim()).toContain('#123');
});
it('renders button to revert dismissal', () => { it('renders button to revert dismissal', () => {
expect(vm.$el.querySelector('.js-dismiss-btn').textContent.trim()).toEqual( expect(vm.$el.querySelector('.js-dismiss-btn').textContent.trim()).toEqual(
'Revert dismissal', 'Revert dismissal',
......
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