Commit 4337dce3 authored by Gabriel Mazetto's avatar Gabriel Mazetto

Merge branch '276893-add-fields-to-jira-tracker-to-configure-vulnerabilities' into 'master'

Add new fields for creating issues from vulnerabilities in Jira

See merge request gitlab-org/gitlab!46982
parents 7c211396 bfb73335
...@@ -13,6 +13,8 @@ class Projects::ServicesController < Projects::ApplicationController ...@@ -13,6 +13,8 @@ class Projects::ServicesController < Projects::ApplicationController
before_action :redirect_deprecated_prometheus_service, only: [:update] before_action :redirect_deprecated_prometheus_service, only: [:update]
before_action only: :edit do before_action only: :edit do
push_frontend_feature_flag(:jira_issues_integration, @project, type: :licensed, default_enabled: true) push_frontend_feature_flag(:jira_issues_integration, @project, type: :licensed, default_enabled: true)
push_frontend_feature_flag(:jira_vulnerabilities_integration, @project, type: :licensed, default_enabled: true)
push_frontend_feature_flag(:jira_for_vulnerabilities, @project, type: :development, default_enabled: false)
end end
respond_to :html respond_to :html
......
...@@ -30,7 +30,7 @@ class JiraService < IssueTrackerService ...@@ -30,7 +30,7 @@ class JiraService < IssueTrackerService
# TODO: we can probably just delegate as part of # TODO: we can probably just delegate as part of
# https://gitlab.com/gitlab-org/gitlab/issues/29404 # https://gitlab.com/gitlab-org/gitlab/issues/29404
data_field :username, :password, :url, :api_url, :jira_issue_transition_id, :project_key, :issues_enabled data_field :username, :password, :url, :api_url, :jira_issue_transition_id, :project_key, :issues_enabled, :vulnerabilities_enabled, :vulnerabilities_issuetype
before_update :reset_password before_update :reset_password
after_commit :update_deployment_type, on: [:create, :update], if: :update_deployment_type? after_commit :update_deployment_type, on: [:create, :update], if: :update_deployment_type?
......
---
name: jira_for_vulnerabilities
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/46982
rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/276893
type: development
group: group::threat insights
default_enabled: false
# frozen_string_literal: true
class AddVulnerabilitiesEnabledAndIssuetypeToJiraTrackerData < ActiveRecord::Migration[6.0]
DOWNTIME = false
# rubocop:disable Migration/AddLimitToTextColumns
# limit is added in 20201105143312_add_text_limit_to_jira_tracker_data_issuetype.rb
def change
add_column :jira_tracker_data, :vulnerabilities_issuetype, :text
add_column :jira_tracker_data, :vulnerabilities_enabled, :boolean, default: false, null: false
end
# rubocop:enable Migration/AddLimitToTextColumns
end
# frozen_string_literal: true
class AddTextLimitToJiraTrackerDataIssuetype < ActiveRecord::Migration[6.0]
include Gitlab::Database::MigrationHelpers
DOWNTIME = false
disable_ddl_transaction!
def up
add_text_limit :jira_tracker_data, :vulnerabilities_issuetype, 255
end
def down
remove_text_limit :jira_tracker_data, :vulnerabilities_issuetype
end
end
b614435cdb654ebbd11bcc5ac0ed69352219e51b368d8f10c0b2998c5258caf9
\ No newline at end of file
decdc314dbcf6b8ac2ce140f81f9d342efca0d98bbeff10c7a041568a67b63f3
\ No newline at end of file
...@@ -13192,6 +13192,9 @@ CREATE TABLE jira_tracker_data ( ...@@ -13192,6 +13192,9 @@ CREATE TABLE jira_tracker_data (
project_key text, project_key text,
issues_enabled boolean DEFAULT false NOT NULL, issues_enabled boolean DEFAULT false NOT NULL,
deployment_type smallint DEFAULT 0 NOT NULL, deployment_type smallint DEFAULT 0 NOT NULL,
vulnerabilities_issuetype text,
vulnerabilities_enabled boolean DEFAULT false NOT NULL,
CONSTRAINT check_0bf84b76e9 CHECK ((char_length(vulnerabilities_issuetype) <= 255)),
CONSTRAINT check_214cf6a48b CHECK ((char_length(project_key) <= 255)) CONSTRAINT check_214cf6a48b CHECK ((char_length(project_key) <= 255))
); );
......
...@@ -13,7 +13,9 @@ module EE ...@@ -13,7 +13,9 @@ module EE
:opsgenie_mvc_enabled, :opsgenie_mvc_enabled,
:opsgenie_mvc_target_url, :opsgenie_mvc_target_url,
:repository_url, :repository_url,
:static_context :static_context,
:vulnerabilities_enabled,
:vulnerabilities_issuetype
].freeze ].freeze
override :allowed_service_params override :allowed_service_params
......
...@@ -16,8 +16,11 @@ module EE ...@@ -16,8 +16,11 @@ module EE
if integration.is_a?(JiraService) if integration.is_a?(JiraService)
form_data.merge!( form_data.merge!(
show_jira_issues_integration: @project&.feature_available?(:jira_issues_integration).to_s, show_jira_issues_integration: @project&.feature_available?(:jira_issues_integration).to_s,
show_jira_vulnerabilities_integration: @project&.jira_vulnerabilities_integration_available?.to_s,
enable_jira_issues: integration.issues_enabled.to_s, enable_jira_issues: integration.issues_enabled.to_s,
enable_jira_vulnerabilities: integration.jira_vulnerabilities_integration_enabled?.to_s,
project_key: integration.project_key, project_key: integration.project_key,
vulnerabilities_issuetype: integration.vulnerabilities_issuetype,
gitlab_issues_enabled: @project&.issues_enabled?.to_s, gitlab_issues_enabled: @project&.issues_enabled?.to_s,
upgrade_plan_path: @project && ::Gitlab::CurrentSettings.should_check_namespace_plan? ? upgrade_plan_path(@project.group) : nil, upgrade_plan_path: @project && ::Gitlab::CurrentSettings.should_check_namespace_plan? ? upgrade_plan_path(@project.group) : nil,
edit_project_path: @project ? edit_project_path(@project, anchor: 'js-shared-permissions') : nil edit_project_path: @project ? edit_project_path(@project, anchor: 'js-shared-permissions') : nil
......
...@@ -189,6 +189,7 @@ module EE ...@@ -189,6 +189,7 @@ module EE
delegate :merge_trains_enabled?, to: :ci_cd_settings delegate :merge_trains_enabled?, to: :ci_cd_settings
delegate :auto_rollback_enabled, :auto_rollback_enabled=, :auto_rollback_enabled?, to: :ci_cd_settings delegate :auto_rollback_enabled, :auto_rollback_enabled=, :auto_rollback_enabled?, to: :ci_cd_settings
delegate :closest_gitlab_subscription, to: :namespace delegate :closest_gitlab_subscription, to: :namespace
delegate :jira_vulnerabilities_integration_enabled?, to: :jira_service, allow_nil: true
delegate :requirements_access_level, to: :project_feature, allow_nil: true delegate :requirements_access_level, to: :project_feature, allow_nil: true
...@@ -349,6 +350,10 @@ module EE ...@@ -349,6 +350,10 @@ module EE
feature_available?(:jira_issues_integration) feature_available?(:jira_issues_integration)
end end
def jira_vulnerabilities_integration_available?
::Feature.enabled?(:jira_for_vulnerabilities, self, default_enabled: false) && feature_available?(:jira_vulnerabilities_integration)
end
def multiple_approval_rules_available? def multiple_approval_rules_available?
feature_available?(:multiple_approval_rules) feature_available?(:multiple_approval_rules)
end end
......
...@@ -97,6 +97,7 @@ class License < ApplicationRecord ...@@ -97,6 +97,7 @@ class License < ApplicationRecord
ide_schema_config ide_schema_config
issues_analytics issues_analytics
jira_issues_integration jira_issues_integration
jira_vulnerabilities_integration
ldap_group_sync_filter ldap_group_sync_filter
merge_pipelines merge_pipelines
merge_request_performance_metrics merge_request_performance_metrics
......
...@@ -5,7 +5,16 @@ module EE ...@@ -5,7 +5,16 @@ module EE
extend ActiveSupport::Concern extend ActiveSupport::Concern
prepended do prepended do
validates :project_key, presence: true, if: :issues_enabled validates :project_key, presence: true, if: :project_key_required?
validates :vulnerabilities_issuetype, presence: true, if: :vulnerabilities_enabled
end
def jira_vulnerabilities_integration_enabled?
project.jira_vulnerabilities_integration_available? && vulnerabilities_enabled
end
def project_key_required?
issues_enabled || vulnerabilities_enabled
end end
def issue_types def issue_types
......
---
title: Add new fields for creating issues from vulnerabilities in Jira
merge_request: 46982
author:
type: added
...@@ -13,7 +13,7 @@ RSpec.describe EE::ServicesHelper do ...@@ -13,7 +13,7 @@ RSpec.describe EE::ServicesHelper do
end end
end end
let_it_be(:project) { create(:project) } let_it_be_with_refind(:project) { create(:project) }
subject { controller_class.new } subject { controller_class.new }
...@@ -28,26 +28,55 @@ RSpec.describe EE::ServicesHelper do ...@@ -28,26 +28,55 @@ RSpec.describe EE::ServicesHelper do
let(:integration) { build(:slack_service) } let(:integration) { build(:slack_service) }
it 'does not include Jira specific fields' do it 'does not include Jira specific fields' do
is_expected.not_to include(:show_jira_issues_integration, :enable_jira_issues, :project_key, :gitlab_issues_enabled, :edit_project_path) is_expected.not_to include(:show_jira_issues_integration, :show_jira_vulnerabilities_integration, :enable_jira_issues, :project_key, :gitlab_issues_enabled, :edit_project_path)
end end
end end
context 'Jira service' do context 'Jira service' do
let(:integration) { create(:jira_service, project: project, issues_enabled: true, project_key: 'FE') } let_it_be_with_refind(:integration) { create(:jira_service, project: project, issues_enabled: true, project_key: 'FE', vulnerabilities_enabled: true, vulnerabilities_issuetype: '10001') }
context 'when there is no license for jira_vulnerabilities_integration' do
before do
stub_feature_flags(jira_for_vulnerabilities: true)
end
it 'includes Jira specific fields' do it 'includes Jira specific fields' do
stub_licensed_features(jira_issues_integration: true) is_expected.to include(show_jira_vulnerabilities_integration: 'false')
end
end
context 'when flag is disabled for jira_for_vulnerabilities' do
before do
stub_licensed_features(jira_issues_integration: true, jira_vulnerabilities_integration: true)
stub_feature_flags(jira_for_vulnerabilities: false)
end
it 'includes Jira specific fields' do
is_expected.to include(show_jira_vulnerabilities_integration: 'false')
end
end
context 'when all flags are enabled' do
before do
stub_licensed_features(jira_issues_integration: true, jira_vulnerabilities_integration: true)
stub_feature_flags(jira_for_vulnerabilities: true)
end
it 'includes Jira specific fields' do
is_expected.to include( is_expected.to include(
show_jira_issues_integration: 'true', show_jira_issues_integration: 'true',
show_jira_vulnerabilities_integration: 'true',
enable_jira_issues: 'true', enable_jira_issues: 'true',
enable_jira_vulnerabilities: 'true',
project_key: 'FE', project_key: 'FE',
vulnerabilities_issuetype: '10001',
gitlab_issues_enabled: 'true', gitlab_issues_enabled: 'true',
edit_project_path: edit_project_path(project, anchor: 'js-shared-permissions') edit_project_path: edit_project_path(project, anchor: 'js-shared-permissions')
) )
end end
end end
end end
end
describe '#add_to_slack_link' do describe '#add_to_slack_link' do
it 'encodes a masked CSRF token' do it 'encodes a masked CSRF token' do
......
...@@ -12,6 +12,68 @@ RSpec.describe JiraService do ...@@ -12,6 +12,68 @@ RSpec.describe JiraService do
expect(jira_service).to be_invalid expect(jira_service).to be_invalid
end end
it 'validates presence of project_key if vulnerabilities_enabled' do
jira_service.project_key = ''
jira_service.vulnerabilities_enabled = true
expect(jira_service).to be_invalid
end
it 'validates presence of vulnerabilities_issuetype if vulnerabilities_enabled' do
jira_service.vulnerabilities_issuetype = ''
jira_service.vulnerabilities_enabled = true
expect(jira_service).to be_invalid
end
end
describe 'jira_vulnerabilities_integration_enabled?' do
subject(:jira_vulnerabilities_integration_enabled) { jira_service.jira_vulnerabilities_integration_enabled? }
context 'when jira integration is not available for the project' do
before do
allow(jira_service.project).to receive(:jira_vulnerabilities_integration_available?).and_return(false)
end
context 'when vulnerabilities_enabled is set to false' do
before do
allow(jira_service).to receive(:vulnerabilities_enabled).and_return(false)
end
it { is_expected.to eq(false) }
end
context 'when vulnerabilities_enabled is set to true' do
before do
allow(jira_service).to receive(:vulnerabilities_enabled).and_return(true)
end
it { is_expected.to eq(false) }
end
end
context 'when jira integration is available for the project' do
before do
allow(jira_service.project).to receive(:jira_vulnerabilities_integration_available?).and_return(true)
end
context 'when vulnerabilities_enabled is set to false' do
before do
allow(jira_service).to receive(:vulnerabilities_enabled).and_return(false)
end
it { is_expected.to eq(false) }
end
context 'when vulnerabilities_enabled is set to true' do
before do
allow(jira_service).to receive(:vulnerabilities_enabled).and_return(true)
end
it { is_expected.to eq(true) }
end
end
end end
describe '#issue_types' do describe '#issue_types' do
......
...@@ -83,6 +83,8 @@ FactoryBot.define do ...@@ -83,6 +83,8 @@ FactoryBot.define do
jira_issue_transition_id { '56-1' } jira_issue_transition_id { '56-1' }
issues_enabled { false } issues_enabled { false }
project_key { nil } project_key { nil }
vulnerabilities_enabled { false }
vulnerabilities_issuetype { nil }
end end
before(:create) do |service, evaluator| before(:create) do |service, evaluator|
...@@ -90,7 +92,8 @@ FactoryBot.define do ...@@ -90,7 +92,8 @@ FactoryBot.define do
create(:jira_tracker_data, service: service, create(:jira_tracker_data, service: service,
url: evaluator.url, api_url: evaluator.api_url, jira_issue_transition_id: evaluator.jira_issue_transition_id, url: evaluator.url, api_url: evaluator.api_url, jira_issue_transition_id: evaluator.jira_issue_transition_id,
username: evaluator.username, password: evaluator.password, issues_enabled: evaluator.issues_enabled, username: evaluator.username, password: evaluator.password, issues_enabled: evaluator.issues_enabled,
project_key: evaluator.project_key project_key: evaluator.project_key, vulnerabilities_enabled: evaluator.vulnerabilities_enabled,
vulnerabilities_issuetype: evaluator.vulnerabilities_issuetype
) )
end end
end 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