Commit 79c3b03a authored by Alan Paruszewski's avatar Alan Paruszewski

Remove first class vulnerabilities feature flag

Standalone Vulnerabilities are available now without feature flag. This
commit enables them by default.
parent 6576dcec
......@@ -2,14 +2,6 @@
> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/10242) in [GitLab Ultimate](https://about.gitlab.com/pricing/) 12.6.
CAUTION: **Caution:**
This API is currently in development and is protected by a **disabled**
[feature flag](../development/feature_flags/index.md).
On a self-managed GitLab instance, an administrator can enable it by starting the Rails console
(`sudo gitlab-rails console`) and then running the following command: `Feature.enable(:first_class_vulnerabilities)`.
To test if the Vulnerabilities API was successfully enabled, run the following command:
`Feature.enabled?(:first_class_vulnerabilities)`.
CAUTION: **Caution:**
This API is in an alpha stage and considered unstable.
The response payload may be subject to change or breakage
......
......@@ -8,14 +8,6 @@ and its documentation was moved to [a different location](vulnerability_findings
This document now describes the new Vulnerabilities API that provides access to
[Standalone Vulnerabilities](https://gitlab.com/groups/gitlab-org/-/epics/634).
CAUTION: **Caution:**
This API is currently in development and is protected by a **disabled**
[feature flag](../development/feature_flags/index.md).
On a self-managed GitLab instance, an administrator can enable it by starting the Rails console
(`sudo gitlab-rails console`) and then running the following command: `Feature.enable(:first_class_vulnerabilities)`.
To test if the Vulnerabilities API was successfully enabled, run the following command:
`Feature.enabled?(:first_class_vulnerabilities)`.
CAUTION: **Caution:**
This API is in an alpha stage and considered unstable.
The response payload may be subject to change or breakage
......
......@@ -2,14 +2,6 @@
> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/197494) in [GitLab Ultimate](https://about.gitlab.com/pricing/) 12.10. [Updated](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/30397) in [GitLab Ultimate](https://about.gitlab.com/pricing/) 13.0.
CAUTION: **Caution:**
This API is currently in development and is protected by a **disabled**
[feature flag](../development/feature_flags/index.md).
On a self-managed GitLab instance, an administrator can enable it by starting the Rails console
(`sudo gitlab-rails console`) and then running the following command: `Feature.enable(:first_class_vulnerabilities)`.
To test if the Vulnerability Exports API was successfully enabled, run the following command:
`Feature.enabled?(:first_class_vulnerabilities)`.
CAUTION: **Caution:**
This API is in an alpha stage and considered unstable.
The response payload may be subject to change or breakage
......
import initGroupSecurityDashboard from 'ee/security_dashboard/group_init';
import initFirstClassSecurityDashboard from 'ee/security_dashboard/first_class_init';
import { DASHBOARD_TYPES } from 'ee/security_dashboard/store/constants';
document.addEventListener('DOMContentLoaded', () => {
if (gon.features?.firstClassVulnerabilities) {
initFirstClassSecurityDashboard(
document.getElementById('js-group-security-dashboard'),
DASHBOARD_TYPES.GROUP,
);
} else {
initGroupSecurityDashboard();
}
});
import initProjectSecurityDashboard from 'ee/security_dashboard/project_init';
import initFirstClassSecurityDashboard from 'ee/security_dashboard/first_class_init';
import { DASHBOARD_TYPES } from 'ee/security_dashboard/store/constants';
document.addEventListener('DOMContentLoaded', () => {
if (gon.features?.firstClassVulnerabilities) {
initFirstClassSecurityDashboard(
document.getElementById('js-security-report-app'),
DASHBOARD_TYPES.PROJECT,
);
} else {
initProjectSecurityDashboard();
}
});
import initInstanceSecurityDashboard from 'ee/security_dashboard/instance_init';
import initFirstClassSecurityDashboard from 'ee/security_dashboard/first_class_init';
import { DASHBOARD_TYPES } from 'ee/security_dashboard/store/constants';
document.addEventListener('DOMContentLoaded', () => {
if (gon.features?.firstClassVulnerabilities) {
initFirstClassSecurityDashboard(
document.getElementById('js-security'),
DASHBOARD_TYPES.INSTANCE,
);
} else if (gon.features?.instanceSecurityDashboard) {
initInstanceSecurityDashboard();
}
initFirstClassSecurityDashboard(document.getElementById('js-security'), DASHBOARD_TYPES.INSTANCE);
});
......@@ -2,10 +2,6 @@
class Groups::Security::DashboardController < Groups::ApplicationController
layout 'group'
before_action only: [:show] do
push_frontend_feature_flag(:first_class_vulnerabilities, group, default_enabled: true)
end
def show
render :unavailable unless dashboard_available?
end
......
......@@ -9,7 +9,6 @@ module Projects
before_action only: [:index] do
push_frontend_feature_flag(:hide_dismissed_vulnerabilities)
push_frontend_feature_flag(:first_class_vulnerabilities, @project, default_enabled: true)
end
def index
......
......@@ -11,7 +11,6 @@ module Projects
include NotesHelper
include ToggleAwardEmoji
before_action :not_found, unless: -> { project.first_class_vulnerabilities_enabled? }
before_action :authorize_create_note!, only: [:create]
private
......
......@@ -7,8 +7,7 @@ module Projects
include IssuableActions
include RendersNotes
before_action :not_found, unless: -> { project.first_class_vulnerabilities_enabled? }
before_action :vulnerability
before_action :vulnerability, except: :index
alias_method :vulnerable, :project
......
......@@ -2,8 +2,5 @@
module Security
class DashboardController < ::Security::ApplicationController
before_action only: [:show] do
push_frontend_feature_flag(:first_class_vulnerabilities, default_enabled: true)
end
end
end
......@@ -130,10 +130,6 @@ module EE
::License.feature_available?(:ci_cd_projects) && import_sources_enabled?
end
def first_class_vulnerabilities_available?(project)
::Feature.enabled?(:first_class_vulnerabilities, project, default_enabled: true)
end
def merge_pipelines_available?
return false unless @project.builds_enabled?
......@@ -190,6 +186,7 @@ module EE
project_full_path: project.full_path,
vulnerabilities_endpoint: project_security_vulnerability_findings_path(project),
vulnerabilities_summary_endpoint: summary_project_security_vulnerability_findings_path(project),
vulnerabilities_export_endpoint: api_v4_security_projects_vulnerability_exports_path(id: project.id),
vulnerability_feedback_help_path: help_page_path("user/application_security/index", anchor: "interacting-with-the-vulnerabilities"),
empty_state_svg_path: image_path('illustrations/security-dashboard-empty-state.svg'),
dashboard_documentation: help_page_path('user/application_security/security_dashboard/index'),
......@@ -225,8 +222,6 @@ module EE
end
def project_vulnerabilities_config(project)
return {} unless first_class_vulnerabilities_available?(project)
{ vulnerabilities_export_endpoint: api_v4_security_projects_vulnerability_exports_path(id: project.id) }
end
......
......@@ -303,10 +303,6 @@ module EE
::Feature.enabled?(:repository_push_audit_event, self)
end
def first_class_vulnerabilities_enabled?
::Feature.enabled?(:first_class_vulnerabilities, self, default_enabled: true)
end
def feature_available?(feature, user = nil)
if ::ProjectFeature::FEATURES.include?(feature)
super
......
......@@ -139,7 +139,6 @@ module Vulnerabilities
def state
return 'dismissed' if dismissal_feedback.present?
return 'detected' unless Feature.enabled?(:first_class_vulnerabilities, project, default_enabled: true)
if vulnerability.nil?
'detected'
......
---
title: Improve Vulnerability Management with Standalone Vulnerabilities
merge_request: 28212
author:
type: added
......@@ -34,8 +34,6 @@ module API
end
get ':id' do
vulnerability = find_and_authorize_vulnerability!(:read_vulnerability)
not_found! unless Feature.enabled?(:first_class_vulnerabilities, vulnerability.project, default_enabled: true)
render_vulnerability(vulnerability)
end
......@@ -44,8 +42,6 @@ module API
end
post ':id/resolve' do
vulnerability = find_and_authorize_vulnerability!(:admin_vulnerability)
not_found! unless Feature.enabled?(:first_class_vulnerabilities, vulnerability.project, default_enabled: true)
not_modified! if vulnerability.resolved?
vulnerability = ::Vulnerabilities::ResolveService.new(current_user, vulnerability).execute
......@@ -57,8 +53,6 @@ module API
end
post ':id/dismiss' do
vulnerability = find_and_authorize_vulnerability!(:admin_vulnerability)
not_found! unless Feature.enabled?(:first_class_vulnerabilities, vulnerability.project, default_enabled: true)
not_modified! if vulnerability.dismissed?
vulnerability = ::Vulnerabilities::DismissService.new(current_user, vulnerability).execute
......@@ -70,8 +64,6 @@ module API
end
post ':id/confirm' do
vulnerability = find_and_authorize_vulnerability!(:admin_vulnerability)
not_found! unless Feature.enabled?(:first_class_vulnerabilities, vulnerability.project, default_enabled: true)
not_modified! if vulnerability.confirmed?
vulnerability = ::Vulnerabilities::ConfirmService.new(current_user, vulnerability).execute
......@@ -86,9 +78,6 @@ module API
desc 'Get a list of project vulnerabilities' do
success EE::API::Entities::Vulnerability
end
before do
not_found! unless Feature.enabled?(:first_class_vulnerabilities, user_project, default_enabled: true)
end
params do
use :pagination
end
......
......@@ -42,10 +42,6 @@ module API
success EE::API::Entities::VulnerabilityExport
end
before do
not_found! unless Feature.enabled?(:first_class_vulnerabilities, user_project, default_enabled: true)
end
post ':id/vulnerability_exports' do
authorize! :create_vulnerability_export, user_project
......@@ -64,10 +60,6 @@ module API
success EE::API::Entities::VulnerabilityExport
end
before do
not_found! unless Feature.enabled?(:first_class_vulnerabilities, user_group, default_enabled: true)
end
post ':id/vulnerability_exports' do
authorize! :create_vulnerability_export, user_group
......@@ -76,10 +68,6 @@ module API
end
namespace do
before do
not_found! unless Feature.enabled?(:first_class_vulnerabilities, default_enabled: true)
end
params do
optional :export_format, type: String, desc: 'The format of export to be generated',
default: ::Vulnerabilities::Export.formats.each_key.first,
......
......@@ -33,8 +33,6 @@ module API
end
get ':id/issue_links' do
vulnerability = find_and_authorize_vulnerability!(:read_vulnerability)
not_found! unless Feature.enabled?(:first_class_vulnerabilities, vulnerability.project, default_enabled: true)
present vulnerability
.related_issues
.with_api_entity_associations
......@@ -51,8 +49,6 @@ module API
end
post ':id/issue_links' do
vulnerability = find_and_authorize_vulnerability!(:admin_vulnerability_issue_link)
not_found! unless Feature.enabled?(:first_class_vulnerabilities, vulnerability.project, default_enabled: true)
issue = find_project_issue(params[:target_issue_iid], vulnerability.project_id)
response = ::VulnerabilityIssueLinks::CreateService.new(
......@@ -68,9 +64,7 @@ module API
requires :issue_link_id, type: Integer, desc: 'The ID of a vulnerability-issue-link to delete'
end
delete ':id/issue_links/:issue_link_id' do
vulnerability = find_and_authorize_vulnerability!(:admin_vulnerability_issue_link)
not_found! unless Feature.enabled?(:first_class_vulnerabilities, vulnerability.project, default_enabled: true)
find_and_authorize_vulnerability!(:admin_vulnerability_issue_link)
issue_link = find_issue_link!
service_response = ::VulnerabilityIssueLinks::DeleteService.new(current_user, issue_link).execute
......
......@@ -40,18 +40,6 @@ RSpec.describe Projects::Security::Vulnerabilities::NotesController do
expect(json_response['notes']).to be_an Array
expect(json_response['notes'].pluck('id')).to eq([note.id.to_s])
end
context 'when the feature flag is disabled' do
before do
stub_feature_flags(first_class_vulnerabilities: false)
end
it 'renders the 404 page' do
view_all_notes
expect(response).to have_gitlab_http_status(:not_found)
end
end
end
describe 'POST create' do
......
......@@ -52,18 +52,6 @@ RSpec.describe Projects::Security::VulnerabilitiesController do
expect(response.body).to have_text(vulnerability.title)
end
end
context 'when the feature flag is disabled' do
before do
stub_feature_flags(first_class_vulnerabilities: false)
end
it 'renders the 404 page' do
show_vulnerability
expect(response).to have_gitlab_http_status(:not_found)
end
end
end
describe 'GET #discussions' do
......@@ -85,17 +73,5 @@ RSpec.describe Projects::Security::VulnerabilitiesController do
expect(json_response.pluck('id')).to eq([discussion_note.discussion_id])
end
context 'when the feature flag is disabled' do
before do
stub_feature_flags(first_class_vulnerabilities: false)
end
it 'renders the 404 page' do
show_vulnerability_discussion_list
expect(response).to have_gitlab_http_status(:not_found)
end
end
end
end
......@@ -10,7 +10,6 @@ RSpec.describe 'Group overview', :js, :aggregate_failures do
subject(:visit_page) { visit group_path(group) }
before do
stub_feature_flags(first_class_vulnerabilities: false)
group.add_owner(user)
sign_in(user)
end
......@@ -35,51 +34,6 @@ RSpec.describe 'Group overview', :js, :aggregate_failures do
let(:user) { create(:user, group_view: :security_dashboard) }
context 'and Security Dashboard feature is available for a group' do
let(:group) { create(:group_with_plan, plan: :gold_plan) }
let(:project) { create(:project, :public, namespace: group) }
before do
create(:vulnerability, :with_findings, project: project)
end
context 'when the "first_class_vulnerabilities" feature flag is not enabled' do
it 'displays the Security Dashboard view' do
visit_page
expect(page).to have_selector('.js-security-dashboard-table')
page.within(find('aside')) do
expect(page).to have_content _('Vulnerabilities over time')
expect(page).to have_selector('.js-vulnerabilities-chart-time-info')
expect(page).to have_selector('.js-vulnerabilities-chart-severity-level-breakdown')
expect(page).to have_content _('Project security status')
expect(page).to have_selector('.js-projects-security-status')
end
page.within(all('div.row')[1]) do
expect(page).not_to have_content s_('VulnerabilityStatusTypes|Detected')
end
end
end
context 'when the "first_class_vulnerabilities" feature flag is enabled' do
before do
stub_feature_flags(first_class_vulnerabilities: true)
end
it 'loads the first class group security dashboard' do
visit_page
page.within(all('div.row')[1]) do
expect(page).to have_content s_('VulnerabilityStatusTypes|Detected')
expect(page).to have_content s_('Vulnerability|Severity')
end
end
end
end
context 'and Security Dashboard feature is not available for a group' do
let(:group) { create(:group_with_plan, plan: :bronze_plan) }
......
......@@ -135,25 +135,6 @@ RSpec.describe ProjectsHelper do
it { is_expected.to match(expected_core_values) }
context 'when the first_class_vulnerabilities available' do
let(:export_endpoint) { "/api/v4/security/projects/#{project.id}/vulnerability_exports" }
let(:expected_sub_hash) { hash_including(vulnerabilities_export_endpoint: export_endpoint) }
before do
allow(::Feature).to receive(:enabled?).with(:first_class_vulnerabilities, project, default_enabled: true).and_return(true)
end
it { is_expected.to match(expected_sub_hash) }
end
context 'when the first_class_vulnerabilities is not available' do
before do
allow(::Feature).to receive(:enabled?).with(:first_class_vulnerabilities, project, default_enabled: true).and_return(false)
end
it { is_expected.not_to have_key(:vulnerabilities_export_endpoint) }
end
context 'project without pipeline' do
let(:expected_sub_hash) do
hash_including(
......@@ -187,7 +168,8 @@ RSpec.describe ProjectsHelper do
ref_path: "#{project_path}/-/commits/#{project.default_branch}",
pipeline_path: "#{project_path}/-/pipelines/#{pipeline.id}",
pipeline_created: pipeline.created_at.to_s(:iso8601),
has_pipeline_data: 'true'
has_pipeline_data: 'true',
vulnerabilities_export_endpoint: "/api/v4/security/projects/#{project.id}/vulnerability_exports"
)
end
......
......@@ -4,10 +4,6 @@ require 'spec_helper'
RSpec.describe SecurityHelper do
describe '#instance_security_dashboard_data' do
before do
stub_feature_flags(first_class_vulnerabilities: true)
end
subject { instance_security_dashboard_data }
it 'returns vulnerability, project, feedback, asset, and docs paths for the instance security dashboard' do
......
# frozen_string_literal: true
RSpec.shared_examples 'forbids access to vulnerability API endpoint in case of disabled features' do
context 'when "first-class vulnerabilities" feature is disabled' do
before do
stub_feature_flags(first_class_vulnerabilities: false)
end
it 'responds with "not found"' do
subject
expect(response).to have_gitlab_http_status(:not_found)
end
end
context 'when security dashboard feature is not available' do
before do
stub_licensed_features(security_dashboard: false)
......
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