Commit a4379bae authored by Alan (Maciej) Paruszewski's avatar Alan (Maciej) Paruszewski Committed by Dmytro Zaporozhets (DZ)

Add method to create issue in Jira from vulnerability finding

This change adds link to finding to create issue in Jira.
parent eb544aac
# frozen_string_literal: true
module VulnerabilitiesHelper
FINDING_FIELDS = %i[metadata identifiers name issue_feedback merge_request_feedback project project_fingerprint scanner].freeze
def vulnerability_details_json(vulnerability, pipeline)
vulnerability_details(vulnerability, pipeline).to_json
end
......@@ -36,9 +38,10 @@ module VulnerabilitiesHelper
def create_jira_issue_url_for(vulnerability)
return unless vulnerability.project.jira_vulnerabilities_integration_enabled?
summary = _('Investigate vulnerability: %{title}') % { title: vulnerability.title }
decorated_vulnerability = vulnerability.present
summary = _('Investigate vulnerability: %{title}') % { title: decorated_vulnerability.title }
description = ApplicationController.render(template: 'vulnerabilities/jira_issue_description.md.erb',
locals: { vulnerability: vulnerability.present })
locals: { vulnerability: decorated_vulnerability })
vulnerability.project.jira_service.new_issue_url_with_predefined_fields(summary, description)
end
......@@ -59,28 +62,7 @@ module VulnerabilitiesHelper
end
def vulnerability_finding_data(vulnerability)
finding = Vulnerabilities::FindingSerializer.new(current_user: current_user).represent(vulnerability.finding)
data = finding.slice(
:description,
:identifiers,
:links,
:location,
:name,
:issue_feedback,
:merge_request_feedback,
:project,
:project_fingerprint,
:remediations,
:evidence,
:scanner,
:solution,
:request,
:response,
:evidence_source,
:supporting_messages,
:assets
)
data = Vulnerabilities::FindingSerializer.new(current_user: current_user).represent(vulnerability.finding, only: FINDING_FIELDS)
if data[:location]['file']
branch = vulnerability.finding.pipelines&.last&.sha || vulnerability.project.default_branch
......
......@@ -4,6 +4,10 @@ module Vulnerabilities
class FindingPresenter < Gitlab::View::Presenter::Delegated
presents :finding
def title
name
end
def blob_path
return '' unless sha.present?
return '' unless location.present? && location['file'].present?
......
......@@ -2,11 +2,15 @@
class Vulnerabilities::FindingEntity < Grape::Entity
include RequestAwareEntity
include VulnerabilitiesHelper
expose :id, :report_type, :name, :severity, :confidence
expose :scanner, using: Vulnerabilities::ScannerEntity
expose :identifiers, using: Vulnerabilities::IdentifierEntity
expose :project_fingerprint
expose :create_jira_issue_url do |occurrence|
create_jira_issue_url_for(occurrence)
end
expose :create_vulnerability_feedback_issue_path do |occurrence|
create_vulnerability_feedback_issue_path(occurrence.project)
end
......
......@@ -12,11 +12,11 @@ h3. <%= _("Description") %>:
<% if vulnerability.confidence.present? %>
* <%= _("Confidence") %>: <%= vulnerability.confidence %>
<% end %>
<% if vulnerability.try(:file) %>
* <%= _("Location") %>: [<%= vulnerability.location_text %>|<%= vulnerability.location_link %>]
<% if vulnerability.try(:location_text) && vulnerability.try(:location_link) %>
* <%= _("Location") %>: [<%= vulnerability.try(:location_text) %>|<%= vulnerability.try(:location_link) %>]
<% end %>
<% if vulnerability.solution.present? %>
<% if vulnerability.solution.present? && vulnerability.is_a?(Vulnerability) %>
### <%= _("Solution") %>:
<%= _("See vulnerability %{vulnerability_link} for any Solution details.".html_safe) % { vulnerability_link: "[#{vulnerability.id}|#{vulnerability_url(vulnerability)}]" } %>
......@@ -59,17 +59,17 @@ h3. <%= _("Scanner") %>:
* <%= _("Name") %>: <%= vulnerability.scanner[:name] %>
<% end %>
<% if vulnerability.scan.present? %>
<% if vulnerability.scan[:type].present? %>
* <%= _("Type") %>: <%= vulnerability.scan[:type] %>
<% if vulnerability.scan.type.present? %>
* <%= _("Type") %>: <%= vulnerability.scan.type %>
<% end %>
<% if vulnerability.scan[:status].present? %>
* <%= _("Status") %>: <%= vulnerability.scan[:status] %>
<% if vulnerability.scan.status.present? %>
* <%= _("Status") %>: <%= vulnerability.scan.status %>
<% end %>
<% if vulnerability.scan[:start_time].present? %>
* <%= _("Start Time") %>: <%= vulnerability.scan[:start_time] %>
<% if vulnerability.scan.start_time.present? %>
* <%= _("Start Time") %>: <%= vulnerability.scan.start_time %>
<% end %>
<% if vulnerability.scan[:end_time].present? %>
* <%= _("End Time") %>: <%= vulnerability.scan[:end_time] %>
<% if vulnerability.scan.end_time.present? %>
* <%= _("End Time") %>: <%= vulnerability.scan.end_time %>
<% end %>
<% end %>
<% end %>
......@@ -41,6 +41,8 @@ RSpec.describe VulnerabilitiesHelper do
:solution)
end
let(:desired_serializer_fields) { %i[metadata identifiers name issue_feedback merge_request_feedback project project_fingerprint scanner] }
before do
vulnerability_serializer_stub = instance_double("VulnerabilitySerializer")
expect(VulnerabilitySerializer).to receive(:new).and_return(vulnerability_serializer_stub)
......@@ -48,7 +50,7 @@ RSpec.describe VulnerabilitiesHelper do
finding_serializer_stub = instance_double("Vulnerabilities::FindingSerializer")
expect(Vulnerabilities::FindingSerializer).to receive(:new).and_return(finding_serializer_stub)
expect(finding_serializer_stub).to receive(:represent).with(finding).and_return(finding_serializer_hash)
expect(finding_serializer_stub).to receive(:represent).with(finding, only: desired_serializer_fields).and_return(finding_serializer_hash)
end
around do |example|
......@@ -227,7 +229,7 @@ RSpec.describe VulnerabilitiesHelper do
subject { helper.vulnerability_finding_data(vulnerability) }
it 'returns finding information' do
expect(subject).to match(
expect(subject.to_h).to match(
description: finding.description,
identifiers: kind_of(Array),
issue_feedback: anything,
......
......@@ -6,6 +6,12 @@ RSpec.describe Vulnerabilities::FindingPresenter do
let(:presenter) { described_class.new(occurrence) }
let(:occurrence) { build_stubbed(:vulnerabilities_finding) }
describe '#title' do
subject { presenter.title }
it { is_expected.to eq occurrence.name }
end
describe '#blob_path' do
subject { presenter.blob_path }
......
......@@ -4,7 +4,7 @@ require 'spec_helper'
RSpec.describe Vulnerabilities::FindingEntity do
let_it_be(:user) { build(:user) }
let_it_be(:project) { build(:project) }
let_it_be_with_refind(:project) { create(:project) }
let(:scanner) { build(:vulnerabilities_scanner, project: project) }
......@@ -67,6 +67,7 @@ RSpec.describe Vulnerabilities::FindingEntity do
end
it 'does not contain vulnerability feedback paths' do
expect(subject[:create_jira_issue_url]).to be_falsey
expect(subject[:create_vulnerability_feedback_issue_path]).to be_falsey
expect(subject[:create_vulnerability_feedback_merge_request_path]).to be_falsey
expect(subject[:create_vulnerability_feedback_dismissal_path]).to be_falsey
......@@ -78,6 +79,10 @@ RSpec.describe Vulnerabilities::FindingEntity do
project.add_developer(user)
end
it 'does not contain create jira issue path' do
expect(subject[:create_jira_issue_url]).to be_falsey
end
it 'contains vulnerability feedback dismissal path' do
expect(subject).to include(:create_vulnerability_feedback_dismissal_path)
end
......@@ -90,9 +95,28 @@ RSpec.describe Vulnerabilities::FindingEntity do
expect(subject).to include(:create_vulnerability_feedback_merge_request_path)
end
context 'when jira service is configured' do
let_it_be(:jira_service) { create(:jira_service, project: project, issues_enabled: true, project_key: 'FE', vulnerabilities_enabled: true, vulnerabilities_issuetype: '10001') }
before do
stub_licensed_features(jira_vulnerabilities_integration: true)
allow_next_found_instance_of(JiraService) do |jira|
allow(jira).to receive(:jira_project_id).and_return('11223')
end
end
it 'does contains create jira issue path' do
expect(subject[:create_jira_issue_url]).to be_present
end
end
context 'when disallowed to create issue' do
let(:project) { create(:project, issues_access_level: ProjectFeature::DISABLED) }
it 'does not contain create jira issue path' do
expect(subject[:create_jira_issue_url]).to be_falsey
end
it 'does not contain vulnerability feedback issue path' do
expect(subject[:create_vulnerability_feedback_issue_path]).to be_falsey
end
......@@ -109,6 +133,10 @@ RSpec.describe Vulnerabilities::FindingEntity do
context 'when disallowed to create merge_request' do
let(:project) { create(:project, merge_requests_access_level: ProjectFeature::DISABLED) }
it 'does not contain create jira issue path' do
expect(subject[:create_jira_issue_url]).to be_falsey
end
it 'does not contain vulnerability feedback merge_request path' do
expect(subject[:create_vulnerability_feedback_merge_request_path]).to be_falsey
end
......
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