Add latest changes from gitlab-org/gitlab@master
This commit is contained in:
parent
963c6277b2
commit
aa64fed495
17 changed files with 90 additions and 225 deletions
|
@ -84,11 +84,6 @@ export default {
|
|||
required: false,
|
||||
default: false,
|
||||
},
|
||||
securityAndComplianceAvailable: {
|
||||
type: Boolean,
|
||||
required: false,
|
||||
default: false,
|
||||
},
|
||||
visibilityHelpPath: {
|
||||
type: String,
|
||||
required: false,
|
||||
|
@ -595,7 +590,6 @@ export default {
|
|||
/>
|
||||
</project-setting-row>
|
||||
<project-setting-row
|
||||
v-if="securityAndComplianceAvailable"
|
||||
:label="s__('ProjectSettings|Security & Compliance')"
|
||||
:help-text="s__('ProjectSettings|Security & Compliance for this project')"
|
||||
>
|
||||
|
|
|
@ -8,16 +8,8 @@ module Projects
|
|||
feature_category :static_application_security_testing
|
||||
|
||||
def show
|
||||
return render_404 unless feature_enabled?
|
||||
|
||||
render_403 unless can?(current_user, :read_security_configuration, project)
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def feature_enabled?
|
||||
::Feature.enabled?(:secure_security_and_compliance_configuration_page_on_ce, @project, default_enabled: :yaml)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -35,40 +35,13 @@ class ApplicationExperiment < Gitlab::Experiment # rubocop:disable Gitlab/Namesp
|
|||
@excluded = true
|
||||
end
|
||||
|
||||
def rollout_strategy
|
||||
# no-op override in inherited class as desired
|
||||
end
|
||||
|
||||
def variants
|
||||
# override as desired in inherited class with all variants + control
|
||||
# %i[variant1 variant2 control]
|
||||
#
|
||||
# this will make sure we supply variants as these go together - rollout_strategy of :round_robin must have variants
|
||||
raise NotImplementedError, "Inheriting class must supply variants as an array if :round_robin strategy is used" if rollout_strategy == :round_robin
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def feature_flag_name
|
||||
name.tr('/', '_')
|
||||
end
|
||||
|
||||
def resolve_variant_name
|
||||
case rollout_strategy
|
||||
when :round_robin
|
||||
round_robin_rollout
|
||||
else
|
||||
percentage_rollout
|
||||
end
|
||||
end
|
||||
|
||||
def round_robin_rollout
|
||||
Strategy::RoundRobin.new(feature_flag_name, variants).execute
|
||||
end
|
||||
|
||||
def percentage_rollout
|
||||
return variant_names.first if Feature.enabled?(feature_flag_name, self, type: :experiment, default_enabled: :yaml)
|
||||
|
||||
nil # Returning nil vs. :control is important for not caching and rollouts.
|
||||
def experiment_group?
|
||||
Feature.enabled?(feature_flag_name, self, type: :experiment, default_enabled: :yaml)
|
||||
end
|
||||
end
|
||||
|
|
|
@ -7,12 +7,8 @@ module Members
|
|||
|
||||
INVITE_TYPE = 'initial_email'
|
||||
|
||||
def rollout_strategy
|
||||
:round_robin
|
||||
end
|
||||
|
||||
def variants
|
||||
%i[avatar permission_info control]
|
||||
def resolve_variant_name
|
||||
Strategy::RoundRobin.new(feature_flag_name, %i[avatar permission_info control]).execute
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -379,13 +379,8 @@ module ProjectsHelper
|
|||
private
|
||||
|
||||
def can_read_security_configuration?(project, current_user)
|
||||
show_security_and_compliance_config? &&
|
||||
can?(current_user, :access_security_and_compliance, project) &&
|
||||
can?(current_user, :read_security_configuration, project)
|
||||
end
|
||||
|
||||
def show_security_and_compliance_config?
|
||||
::Feature.enabled?(:secure_security_and_compliance_configuration_page_on_ce, @subject, default_enabled: :yaml)
|
||||
can?(current_user, :access_security_and_compliance, project) &&
|
||||
can?(current_user, :read_security_configuration, project)
|
||||
end
|
||||
|
||||
def get_project_security_nav_tabs(project, current_user)
|
||||
|
@ -674,13 +669,10 @@ module ProjectsHelper
|
|||
pagesAvailable: Gitlab.config.pages.enabled,
|
||||
pagesAccessControlEnabled: Gitlab.config.pages.access_control,
|
||||
pagesAccessControlForced: ::Gitlab::Pages.access_control_is_forced?,
|
||||
pagesHelpPath: help_page_path('user/project/pages/introduction', anchor: 'gitlab-pages-access-control'),
|
||||
securityAndComplianceAvailable: show_security_and_compliance_toggle?
|
||||
pagesHelpPath: help_page_path('user/project/pages/introduction', anchor: 'gitlab-pages-access-control')
|
||||
}
|
||||
end
|
||||
|
||||
alias_method :show_security_and_compliance_toggle?, :show_security_and_compliance_config?
|
||||
|
||||
def project_permissions_panel_data_json(project)
|
||||
project_permissions_panel_data(project).to_json.html_safe
|
||||
end
|
||||
|
|
|
@ -0,0 +1,5 @@
|
|||
---
|
||||
title: Add more settings to group MR approval settings
|
||||
merge_request: 56215
|
||||
author:
|
||||
type: added
|
|
@ -0,0 +1,5 @@
|
|||
---
|
||||
title: Remove security & compliance config page feature flag
|
||||
merge_request: 56219
|
||||
author:
|
||||
type: changed
|
|
@ -1,8 +0,0 @@
|
|||
---
|
||||
name: secure_security_and_compliance_configuration_page_on_ce
|
||||
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/50282
|
||||
rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/294076
|
||||
milestone: '13.9'
|
||||
type: development
|
||||
group: group::static analysis
|
||||
default_enabled: false
|
|
@ -0,0 +1,14 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class AddSettingsToGroupMergeRequestApprovalSettings < ActiveRecord::Migration[6.0]
|
||||
DOWNTIME = false
|
||||
|
||||
def change
|
||||
change_table(:group_merge_request_approval_settings, bulk: true) do |t|
|
||||
t.column :allow_committer_approval, :boolean, null: false, default: false
|
||||
t.column :allow_overrides_to_approver_list_per_merge_request, :boolean, null: false, default: false
|
||||
t.column :retain_approvals_on_push, :boolean, null: false, default: false
|
||||
t.column :require_password_to_approve, :boolean, null: false, default: false
|
||||
end
|
||||
end
|
||||
end
|
1
db/schema_migrations/20210310111009
Normal file
1
db/schema_migrations/20210310111009
Normal file
|
@ -0,0 +1 @@
|
|||
8b5a69947c44c9c1050f4989e3b373d3eb87832111d0202992c7dd992032c9d1
|
|
@ -13270,7 +13270,11 @@ CREATE TABLE group_merge_request_approval_settings (
|
|||
created_at timestamp with time zone NOT NULL,
|
||||
updated_at timestamp with time zone NOT NULL,
|
||||
group_id bigint NOT NULL,
|
||||
allow_author_approval boolean DEFAULT false NOT NULL
|
||||
allow_author_approval boolean DEFAULT false NOT NULL,
|
||||
allow_committer_approval boolean DEFAULT false NOT NULL,
|
||||
allow_overrides_to_approver_list_per_merge_request boolean DEFAULT false NOT NULL,
|
||||
retain_approvals_on_push boolean DEFAULT false NOT NULL,
|
||||
require_password_to_approve boolean DEFAULT false NOT NULL
|
||||
);
|
||||
|
||||
CREATE TABLE group_repository_storage_moves (
|
||||
|
|
|
@ -6,6 +6,8 @@ info: To determine the technical writer assigned to the Stage/Group associated w
|
|||
|
||||
# Audit Events API
|
||||
|
||||
> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/121) in GitLab 12.4.
|
||||
|
||||
## Instance Audit Events **(PREMIUM SELF)**
|
||||
|
||||
The Audit Events API allows you to retrieve [instance audit events](../administration/audit_events.md#instance-events).
|
||||
|
|
|
@ -10,12 +10,7 @@ info: To determine the technical writer assigned to the Stage/Group associated w
|
|||
> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/20711) in [GitLab Ultimate](https://about.gitlab.com/pricing/) 12.6. **(ULTIMATE)**
|
||||
> - SAST configuration was [enabled](https://gitlab.com/groups/gitlab-org/-/epics/3659) in 13.3 and [improved](https://gitlab.com/gitlab-org/gitlab/-/issues/232862) in 13.4. **(ULTIMATE)**
|
||||
> - DAST Profiles feature was [introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/40474) in 13.4. **(ULTIMATE)**
|
||||
> - A simplified version was made [available in all tiers](https://gitlab.com/gitlab-org/gitlab/-/issues/294076) in GitLab 13.9. **(FREE)**
|
||||
> - It's [deployed behind a feature flag](../../feature_flags.md), disabled by default.
|
||||
> - It's enabled on GitLab.com.
|
||||
> - It's recommended for production use.
|
||||
> - For GitLab self-managed instances, GitLab administrators can opt to [enable it](#enable-or-disable-security-configuration). **(FREE SELF)**
|
||||
> - It can be enabled or disabled for a single project.
|
||||
> - A simplified version was made [available in all tiers](https://gitlab.com/gitlab-org/gitlab/-/issues/294076) in GitLab 13.9.
|
||||
|
||||
WARNING:
|
||||
This feature might not be available to you. Check the **version history** note above for details.
|
||||
|
@ -54,25 +49,3 @@ You can configure the following security controls:
|
|||
- Click either **Enable** or **Configure** to use SAST for the current project. For more details, see [Configure SAST in the UI](../sast/index.md#configure-sast-in-the-ui).
|
||||
- DAST Profiles
|
||||
- Click **Manage** to manage the available DAST profiles used for on-demand scans. For more details, see [DAST on-demand scans](../dast/index.md#on-demand-scans).
|
||||
|
||||
### Enable or disable Security Configuration **(FREE SELF)**
|
||||
|
||||
Security Configuration is under development but ready for production use.
|
||||
It is deployed behind a feature flag that is **disabled by default**.
|
||||
[GitLab administrators with access to the GitLab Rails console](../../../administration/feature_flags.md)
|
||||
can opt to enable it.
|
||||
|
||||
NOTE:
|
||||
This does not apply to GitLab Ultimate.
|
||||
|
||||
To enable it:
|
||||
|
||||
```ruby
|
||||
Feature.enable(:secure_security_and_compliance_configuration_page_on_ce)
|
||||
```
|
||||
|
||||
To disable it:
|
||||
|
||||
```ruby
|
||||
Feature.disable(:secure_security_and_compliance_configuration_page_on_ce)
|
||||
```
|
||||
|
|
|
@ -13,42 +13,28 @@ RSpec.describe Projects::Security::ConfigurationController do
|
|||
end
|
||||
|
||||
describe 'GET show' do
|
||||
context 'when feature flag is disabled' do
|
||||
context 'when user has guest access' do
|
||||
before do
|
||||
stub_feature_flags(secure_security_and_compliance_configuration_page_on_ce: false)
|
||||
project.add_guest(user)
|
||||
end
|
||||
|
||||
it 'renders not found' do
|
||||
it 'denies access' do
|
||||
get :show, params: { namespace_id: project.namespace, project_id: project }
|
||||
|
||||
expect(response).to have_gitlab_http_status(:not_found)
|
||||
expect(response).to have_gitlab_http_status(:forbidden)
|
||||
end
|
||||
end
|
||||
|
||||
context 'when feature flag is enabled' do
|
||||
context 'when user has guest access' do
|
||||
before do
|
||||
project.add_guest(user)
|
||||
end
|
||||
|
||||
it 'denies access' do
|
||||
get :show, params: { namespace_id: project.namespace, project_id: project }
|
||||
|
||||
expect(response).to have_gitlab_http_status(:forbidden)
|
||||
end
|
||||
context 'when user has developer access' do
|
||||
before do
|
||||
project.add_developer(user)
|
||||
end
|
||||
|
||||
context 'when user has developer access' do
|
||||
before do
|
||||
project.add_developer(user)
|
||||
end
|
||||
it 'grants access' do
|
||||
get :show, params: { namespace_id: project.namespace, project_id: project }
|
||||
|
||||
it 'grants access' do
|
||||
get :show, params: { namespace_id: project.namespace, project_id: project }
|
||||
|
||||
expect(response).to have_gitlab_http_status(:ok)
|
||||
expect(response).to render_template(:show)
|
||||
end
|
||||
expect(response).to have_gitlab_http_status(:ok)
|
||||
expect(response).to render_template(:show)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -114,77 +114,22 @@ RSpec.describe ApplicationExperiment, :experiment do
|
|||
end
|
||||
|
||||
describe "variant resolution" do
|
||||
context "when using the default feature flag percentage rollout" do
|
||||
it "uses the default value as specified in the yaml" do
|
||||
expect(Feature).to receive(:enabled?).with('namespaced_stub', subject, type: :experiment, default_enabled: :yaml)
|
||||
it "uses the default value as specified in the yaml" do
|
||||
expect(Feature).to receive(:enabled?).with('namespaced_stub', subject, type: :experiment, default_enabled: :yaml)
|
||||
|
||||
expect(subject.variant.name).to eq('control')
|
||||
end
|
||||
|
||||
it "returns nil when not rolled out" do
|
||||
stub_feature_flags(namespaced_stub: false)
|
||||
|
||||
expect(subject.variant.name).to eq('control')
|
||||
end
|
||||
|
||||
context "when rolled out to 100%" do
|
||||
it "returns the first variant name" do
|
||||
subject.try(:variant1) {}
|
||||
subject.try(:variant2) {}
|
||||
|
||||
expect(subject.variant.name).to eq('variant1')
|
||||
end
|
||||
end
|
||||
expect(subject.variant.name).to eq('control')
|
||||
end
|
||||
|
||||
context "when using the round_robin strategy", :clean_gitlab_redis_shared_state do
|
||||
context "when variants aren't supplied" do
|
||||
subject :inheriting_class do
|
||||
Class.new(described_class) do
|
||||
def rollout_strategy
|
||||
:round_robin
|
||||
end
|
||||
end.new('namespaced/stub')
|
||||
end
|
||||
|
||||
it "raises an error" do
|
||||
expect { inheriting_class.variants }.to raise_error(NotImplementedError)
|
||||
end
|
||||
context "when rolled out to 100%" do
|
||||
before do
|
||||
stub_feature_flags(namespaced_stub: true)
|
||||
end
|
||||
|
||||
context "when variants are supplied" do
|
||||
let(:inheriting_class) do
|
||||
Class.new(described_class) do
|
||||
def rollout_strategy
|
||||
:round_robin
|
||||
end
|
||||
it "returns the first variant name" do
|
||||
subject.try(:variant1) {}
|
||||
subject.try(:variant2) {}
|
||||
|
||||
def variants
|
||||
%i[variant1 variant2 control]
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
it "proves out round robin in variant selection", :aggregate_failures do
|
||||
instance_1 = inheriting_class.new('namespaced/stub')
|
||||
allow(instance_1).to receive(:enabled?).and_return(true)
|
||||
instance_2 = inheriting_class.new('namespaced/stub')
|
||||
allow(instance_2).to receive(:enabled?).and_return(true)
|
||||
instance_3 = inheriting_class.new('namespaced/stub')
|
||||
allow(instance_3).to receive(:enabled?).and_return(true)
|
||||
|
||||
instance_1.try {}
|
||||
|
||||
expect(instance_1.variant.name).to eq('variant2')
|
||||
|
||||
instance_2.try {}
|
||||
|
||||
expect(instance_2.variant.name).to eq('control')
|
||||
|
||||
instance_3.try {}
|
||||
|
||||
expect(instance_3.variant.name).to eq('variant1')
|
||||
end
|
||||
expect(subject.variant.name).to eq('variant1')
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -3,26 +3,14 @@
|
|||
require 'spec_helper'
|
||||
|
||||
RSpec.describe Members::InviteEmailExperiment do
|
||||
subject :invite_email do
|
||||
experiment('members/invite_email', actor: double('Member', created_by: double('User', avatar_url: '_avatar_url_')))
|
||||
end
|
||||
subject(:invite_email) { experiment('members/invite_email', **context) }
|
||||
|
||||
let(:context) { { actor: double('Member', created_by: double('User', avatar_url: '_avatar_url_')) } }
|
||||
|
||||
before do
|
||||
allow(invite_email).to receive(:enabled?).and_return(true)
|
||||
end
|
||||
|
||||
describe "#rollout_strategy" do
|
||||
it "resolves to round_robin" do
|
||||
expect(invite_email.rollout_strategy).to eq(:round_robin)
|
||||
end
|
||||
end
|
||||
|
||||
describe "#variants" do
|
||||
it "has all the expected variants" do
|
||||
expect(invite_email.variants).to match(%i[avatar permission_info control])
|
||||
end
|
||||
end
|
||||
|
||||
describe "exclusions", :experiment do
|
||||
it "excludes when created by is nil" do
|
||||
expect(experiment('members/invite_email')).to exclude(actor: double(created_by: nil))
|
||||
|
@ -34,4 +22,27 @@ RSpec.describe Members::InviteEmailExperiment do
|
|||
expect(experiment('members/invite_email')).to exclude(actor: member_without_avatar_url)
|
||||
end
|
||||
end
|
||||
|
||||
describe "variant resolution", :clean_gitlab_redis_shared_state do
|
||||
it "proves out round robin in variant selection", :aggregate_failures do
|
||||
instance_1 = described_class.new('members/invite_email', **context)
|
||||
allow(instance_1).to receive(:enabled?).and_return(true)
|
||||
instance_2 = described_class.new('members/invite_email', **context)
|
||||
allow(instance_2).to receive(:enabled?).and_return(true)
|
||||
instance_3 = described_class.new('members/invite_email', **context)
|
||||
allow(instance_3).to receive(:enabled?).and_return(true)
|
||||
|
||||
instance_1.try { }
|
||||
|
||||
expect(instance_1.variant.name).to eq('permission_info')
|
||||
|
||||
instance_2.try { }
|
||||
|
||||
expect(instance_2.variant.name).to eq('control')
|
||||
|
||||
instance_3.try { }
|
||||
|
||||
expect(instance_3.variant.name).to eq('avatar')
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -401,40 +401,20 @@ RSpec.describe ProjectsHelper do
|
|||
|
||||
context 'Security & Compliance tabs' do
|
||||
before do
|
||||
stub_feature_flags(secure_security_and_compliance_configuration_page_on_ce: feature_flag_enabled)
|
||||
allow(helper).to receive(:can?).with(user, :read_security_configuration, project).and_return(can_read_security_configuration)
|
||||
end
|
||||
|
||||
context 'when user cannot read security configuration' do
|
||||
let(:can_read_security_configuration) { false }
|
||||
|
||||
context 'when feature flag is disabled' do
|
||||
let(:feature_flag_enabled) { false }
|
||||
|
||||
it { is_expected.not_to include(:security_configuration) }
|
||||
end
|
||||
|
||||
context 'when feature flag is enabled' do
|
||||
let(:feature_flag_enabled) { true }
|
||||
|
||||
it { is_expected.not_to include(:security_configuration) }
|
||||
end
|
||||
it { is_expected.not_to include(:security_configuration) }
|
||||
end
|
||||
|
||||
context 'when user can read security configuration' do
|
||||
let(:can_read_security_configuration) { true }
|
||||
let(:feature_flag_enabled) { true }
|
||||
|
||||
context 'when feature flag is disabled' do
|
||||
let(:feature_flag_enabled) { false }
|
||||
|
||||
it { is_expected.not_to include(:security_configuration) }
|
||||
end
|
||||
|
||||
context 'when feature flag is enabled' do
|
||||
let(:feature_flag_enabled) { true }
|
||||
|
||||
it { is_expected.to include(:security_configuration) }
|
||||
end
|
||||
it { is_expected.to include(:security_configuration) }
|
||||
end
|
||||
end
|
||||
|
||||
|
|
Loading…
Reference in a new issue