diff options
-rw-r--r-- | app/models/concerns/has_user_type.rb | 5 | ||||
-rw-r--r-- | app/models/user.rb | 10 | ||||
-rw-r--r-- | app/policies/base_policy.rb | 4 | ||||
-rw-r--r-- | app/policies/concerns/policy_actor.rb | 4 | ||||
-rw-r--r-- | doc/user/application_security/policies/scan-execution-policies.md | 2 | ||||
-rw-r--r-- | lib/gitlab/ci/pipeline/chain/validate/abilities.rb | 6 | ||||
-rw-r--r-- | spec/lib/gitlab/ci/pipeline/chain/validate/abilities_spec.rb | 34 | ||||
-rw-r--r-- | spec/models/concerns/has_user_type_spec.rb | 2 | ||||
-rw-r--r-- | spec/models/user_spec.rb | 16 |
9 files changed, 71 insertions, 12 deletions
diff --git a/app/models/concerns/has_user_type.rb b/app/models/concerns/has_user_type.rb index ad070090dd5..ccb5bebcc39 100644 --- a/app/models/concerns/has_user_type.rb +++ b/app/models/concerns/has_user_type.rb @@ -13,10 +13,11 @@ module HasUserType project_bot: 6, migration_bot: 7, security_bot: 8, - automation_bot: 9 + automation_bot: 9, + security_policy_bot: 10 }.with_indifferent_access.freeze - BOT_USER_TYPES = %w[alert_bot project_bot support_bot visual_review_bot migration_bot security_bot automation_bot].freeze + BOT_USER_TYPES = %w[alert_bot project_bot support_bot visual_review_bot migration_bot security_bot automation_bot security_policy_bot].freeze NON_INTERNAL_USER_TYPES = %w[human project_bot service_user].freeze INTERNAL_USER_TYPES = (USER_TYPES.keys - NON_INTERNAL_USER_TYPES).freeze diff --git a/app/models/user.rb b/app/models/user.rb index 24f947183a2..b2235bff456 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -896,6 +896,16 @@ class User < ApplicationRecord end end + def security_policy_bot + email_pattern = "security-policy-bot%s@#{Settings.gitlab.host}" + + unique_internal(where(user_type: :security_policy_bot), 'security-policy-bot', email_pattern) do |u| + u.bio = 'System bot that creates pipelines for security orchestration policies' + u.name = 'GitLab Security Policy Bot' + u.avatar = bot_avatar(image: 'security-bot.png') + end + end + # Return true if there is only single non-internal user in the deployment, # ghost user is ignored. def single_user? diff --git a/app/policies/base_policy.rb b/app/policies/base_policy.rb index f8e7a912896..2f0073c00e4 100644 --- a/app/policies/base_policy.rb +++ b/app/policies/base_policy.rb @@ -27,6 +27,10 @@ class BasePolicy < DeclarativePolicy::Base with_options scope: :user, score: 0 condition(:security_bot) { @user&.security_bot? } + desc "User is security policy bot" + with_options scope: :user, score: 0 + condition(:security_policy_bot) { @user&.security_policy_bot? } + desc "User is automation bot" with_options scope: :user, score: 0 condition(:automation_bot) { @user&.automation_bot? } diff --git a/app/policies/concerns/policy_actor.rb b/app/policies/concerns/policy_actor.rb index 8fa09683b06..e000f1514e5 100644 --- a/app/policies/concerns/policy_actor.rb +++ b/app/policies/concerns/policy_actor.rb @@ -53,6 +53,10 @@ module PolicyActor false end + def security_policy_bot? + false + end + def automation_bot? false end diff --git a/doc/user/application_security/policies/scan-execution-policies.md b/doc/user/application_security/policies/scan-execution-policies.md index f950d5116b1..40e9469515a 100644 --- a/doc/user/application_security/policies/scan-execution-policies.md +++ b/doc/user/application_security/policies/scan-execution-policies.md @@ -97,6 +97,8 @@ GitLab supports the following types of CRON syntax for the `cadence` field: Other elements of the CRON syntax may work in the cadence field, however, GitLab does not officially test or support them. The CRON expression is evaluated in UTC by default. If you have a self-managed GitLab instance and have [changed the server timezone](../../../administration/timezone.md), the CRON expression is evaluated with the new timezone. +The scan execution policy for the `schedule` rule type triggers the `GitLab Security Policy Bot` user to create a new pipeline. This user does not count toward the license limit count. + ### `agent` schema Use this schema to define `agents` objects in the [`schedule` rule type](#schedule-rule-type). diff --git a/lib/gitlab/ci/pipeline/chain/validate/abilities.rb b/lib/gitlab/ci/pipeline/chain/validate/abilities.rb index 035167f1a74..bdd45687760 100644 --- a/lib/gitlab/ci/pipeline/chain/validate/abilities.rb +++ b/lib/gitlab/ci/pipeline/chain/validate/abilities.rb @@ -14,7 +14,7 @@ module Gitlab return error('Project is deleted!') end - unless project.builds_enabled? + unless builds_enabled? return error('Pipelines are disabled!') end @@ -37,6 +37,10 @@ module Gitlab can?(current_user, :create_pipeline, project) end + def builds_enabled? + project.builds_enabled? + end + def allowed_to_write_ref? access = Gitlab::UserAccess.new(current_user, container: project) diff --git a/spec/lib/gitlab/ci/pipeline/chain/validate/abilities_spec.rb b/spec/lib/gitlab/ci/pipeline/chain/validate/abilities_spec.rb index 7aaeee32f49..b0c6cc6990f 100644 --- a/spec/lib/gitlab/ci/pipeline/chain/validate/abilities_spec.rb +++ b/spec/lib/gitlab/ci/pipeline/chain/validate/abilities_spec.rb @@ -84,6 +84,36 @@ RSpec.describe Gitlab::Ci::Pipeline::Chain::Validate::Abilities do end end + context 'when CI/CD disabled' do + before do + project.project_feature.update_attribute(:builds_access_level, ProjectFeature::DISABLED) + + step.perform! + end + + it 'adds an error about disabled pipeline' do + expect(pipeline.errors.to_a).to include('Pipelines are disabled!') + end + + it 'breaks the pipeline builder chain' do + expect(step.break?).to eq true + end + end + + describe '#builds_enabled?' do + subject { step.send(:builds_enabled?) } + + it { is_expected.to be_truthy } + + context 'when CI/CD disabled' do + before do + project.project_feature.update_attribute(:builds_access_level, ProjectFeature::DISABLED) + end + + it { is_expected.to be_falsey } + end + end + describe '#allowed_to_write_ref?' do subject { step.send(:allowed_to_write_ref?) } @@ -100,7 +130,7 @@ RSpec.describe Gitlab::Ci::Pipeline::Chain::Validate::Abilities do it { is_expected.to be_truthy } end - context 'when the branch is protected' do + context 'when the branch is protected', :use_clean_rails_redis_caching do let!(:protected_branch) do create(:protected_branch, project: project, name: ref) end @@ -160,7 +190,7 @@ RSpec.describe Gitlab::Ci::Pipeline::Chain::Validate::Abilities do it { is_expected.to be_truthy } - context 'when the branch is protected' do + context 'when the branch is protected', :use_clean_rails_redis_caching do let!(:protected_branch) do create(:protected_branch, project: project, name: ref) end diff --git a/spec/models/concerns/has_user_type_spec.rb b/spec/models/concerns/has_user_type_spec.rb index b2ea7b22dea..3938257708e 100644 --- a/spec/models/concerns/has_user_type_spec.rb +++ b/spec/models/concerns/has_user_type_spec.rb @@ -5,7 +5,7 @@ require 'spec_helper' RSpec.describe User do specify 'types consistency checks', :aggregate_failures do expect(described_class::USER_TYPES.keys) - .to match_array(%w[human ghost alert_bot project_bot support_bot service_user security_bot visual_review_bot migration_bot automation_bot]) + .to match_array(%w[human ghost alert_bot project_bot support_bot service_user security_bot visual_review_bot migration_bot automation_bot security_policy_bot]) expect(described_class::USER_TYPES).to include(*described_class::BOT_USER_TYPES) expect(described_class::USER_TYPES).to include(*described_class::NON_INTERNAL_USER_TYPES) expect(described_class::USER_TYPES).to include(*described_class::INTERNAL_USER_TYPES) diff --git a/spec/models/user_spec.rb b/spec/models/user_spec.rb index 7207ee0b172..fdeb98f52ae 100644 --- a/spec/models/user_spec.rb +++ b/spec/models/user_spec.rb @@ -6799,7 +6799,8 @@ RSpec.describe User do { user_type: :alert_bot }, { user_type: :support_bot }, { user_type: :security_bot }, - { user_type: :automation_bot } + { user_type: :automation_bot }, + { user_type: :security_policy_bot } ] end @@ -6881,11 +6882,12 @@ RSpec.describe User do using RSpec::Parameterized::TableSyntax where(:user_type, :expected_result) do - 'human' | true - 'alert_bot' | false - 'support_bot' | false - 'security_bot' | false - 'automation_bot' | false + 'human' | true + 'alert_bot' | false + 'support_bot' | false + 'security_bot' | false + 'automation_bot' | false + 'security_policy_bot' | false end with_them do @@ -7034,10 +7036,12 @@ RSpec.describe User do it_behaves_like 'bot users', :security_bot it_behaves_like 'bot users', :ghost it_behaves_like 'bot users', :automation_bot + it_behaves_like 'bot users', :security_policy_bot it_behaves_like 'bot user avatars', :alert_bot, 'alert-bot.png' it_behaves_like 'bot user avatars', :support_bot, 'support-bot.png' it_behaves_like 'bot user avatars', :security_bot, 'security-bot.png' + it_behaves_like 'bot user avatars', :security_policy_bot, 'security-bot.png' it_behaves_like 'bot user avatars', :automation_bot, 'support-bot.png' context 'when bot is the support_bot' do |