BE: Create security policy schema to add approval_settings to scan result policies
&9705 (closed) describes adding a new section to security scan result policies that allows to override project settings. The first setting we want to add is to prevent deletion of protected branches.
To archive this we need to:
- Update the security policy schema
Add a new column toscan_result_policies
to store the valueUpdate the policy in the DB when the policy yml gets updated.
Note: Steps 2. and 3. are already done with !130630 (merged)
Implementation plan
Diff
diff --git a/app/validators/json_schemas/scan_result_policy_project_approval_settings.json b/app/validators/json_schemas/scan_result_policy_project_approval_settings.json
new file mode 100644
index 000000000000..a386865e910e
--- /dev/null
+++ b/app/validators/json_schemas/scan_result_policy_project_approval_settings.json
@@ -0,0 +1,18 @@
+{
+ "$schema": "http://json-schema.org/draft-07/schema#",
+ "description": "Scan result policy project_approval_settings",
+ "type": "object",
+ "properties": {
+ "block_unprotecting_branches": {
+ "type": "object",
+ "properties": {
+ "enabled": {
+ "type": "boolean"
+ }
+ },
+ "required": [
+ "enabled"
+ ]
+ }
+ }
+}
diff --git a/db/migrate/20230823151904_add_project_approval_settings_to_scan_result_policies.rb b/db/migrate/20230823151904_add_project_approval_settings_to_scan_result_policies.rb
new file mode 100644
index 000000000000..e9cd79ab7ae5
--- /dev/null
+++ b/db/migrate/20230823151904_add_project_approval_settings_to_scan_result_policies.rb
@@ -0,0 +1,7 @@
+# frozen_string_literal: true
+
+class AddProjectApprovalSettingsToScanResultPolicies < Gitlab::Database::Migration[2.1]
+ def change
+ add_column :scan_result_policies, :project_approval_settings, :jsonb, default: {}
+ end
+end
diff --git a/db/schema_migrations/20230823151904 b/db/schema_migrations/20230823151904
new file mode 100644
index 000000000000..a44f15ade9ad
--- /dev/null
+++ b/db/schema_migrations/20230823151904
@@ -0,0 +1 @@
+1ab2df97d67f3d17951f7b934f8738516de0d1f8066f1c8764ce5002258ad1c2
\ No newline at end of file
diff --git a/db/structure.sql b/db/structure.sql
index 01f6c7741039..23caa62bbe84 100644
--- a/db/structure.sql
+++ b/db/structure.sql
@@ -22696,6 +22696,7 @@ CREATE TABLE scan_result_policies (
vulnerability_attributes jsonb DEFAULT '{}'::jsonb,
project_id bigint,
rule_idx smallint,
+ project_approval_settings jsonb DEFAULT '{}'::jsonb,
CONSTRAINT age_value_null_or_positive CHECK (((age_value IS NULL) OR (age_value >= 0))),
CONSTRAINT check_scan_result_policies_rule_idx_positive CHECK (((rule_idx IS NULL) OR (rule_idx >= 0)))
);
diff --git a/ee/app/models/security/scan_result_policy_read.rb b/ee/app/models/security/scan_result_policy_read.rb
index 7be63a51646e..683f38371fe6 100644
--- a/ee/app/models/security/scan_result_policy_read.rb
+++ b/ee/app/models/security/scan_result_policy_read.rb
@@ -21,6 +21,8 @@ class ScanResultPolicyRead < ApplicationRecord
validates :rule_idx,
uniqueness: { scope: %i[security_orchestration_policy_configuration_id project_id orchestration_policy_idx] },
numericality: { only_integer: true, greater_than_or_equal_to: 0 }, allow_nil: true
+ validates :project_approval_settings, json_schema: { filename: 'scan_result_policy_project_approval_settings' },
+ allow_blank: true
def newly_detected?
license_states.include?(ApprovalProjectRule::NEWLY_DETECTED)
diff --git a/ee/app/services/security/security_orchestration_policies/process_scan_result_policy_service.rb b/ee/app/services/security/security_orchestration_policies/process_scan_result_policy_service.rb
index e843c53c6104..b4b630316701 100644
--- a/ee/app/services/security/security_orchestration_policies/process_scan_result_policy_service.rb
+++ b/ee/app/services/security/security_orchestration_policies/process_scan_result_policy_service.rb
@@ -21,12 +21,13 @@ def execute
def create_new_approval_rules
action_info = policy[:actions]&.find { |action| action[:type] == Security::ScanResultPolicy::REQUIRE_APPROVAL }
+ project_approval_settings = policy[:approval_settings]
return if action_info.blank? || policy[:rules].blank?
policy[:rules].first(Security::ScanResultPolicy::LIMIT).each_with_index do |rule, rule_index|
next unless rule_type_allowed?(rule[:type])
- scan_result_policy_read = create_scan_result_policy(rule, action_info, project, rule_index)
+ scan_result_policy_read = create_scan_result_policy(rule, action_info, project, project_approval_settings, rule_index)
create_software_license_policies(rule, rule_index, scan_result_policy_read) if license_finding?(rule)
@@ -54,7 +55,7 @@ def create_software_license_policies(rule, _rule_index, scan_result_policy_read)
end
end
- def create_scan_result_policy(rule, action_info, project, rule_index)
+ def create_scan_result_policy(rule, action_info, project, project_approval_settings, rule_index)
policy_configuration.scan_result_policy_reads.create!(
orchestration_policy_idx: policy_index,
rule_idx: rule_index,
@@ -65,7 +66,8 @@ def create_scan_result_policy(rule, action_info, project, rule_index)
project_id: project.id,
age_operator: rule.dig(:vulnerability_age, :operator),
age_interval: rule.dig(:vulnerability_age, :interval),
- age_value: rule.dig(:vulnerability_age, :value)
+ age_value: rule.dig(:vulnerability_age, :value),
+ project_approval_settings: project_approval_settings
)
end
diff --git a/ee/app/validators/json_schemas/security_orchestration_policy.json b/ee/app/validators/json_schemas/security_orchestration_policy.json
index ad0ccacd30d7..89a1449bb7e6 100644
--- a/ee/app/validators/json_schemas/security_orchestration_policy.json
+++ b/ee/app/validators/json_schemas/security_orchestration_policy.json
@@ -682,6 +682,22 @@
}
}
}
+ },
+ "approval_settings": {
+ "type": "object",
+ "properties": {
+ "block_unprotecting_branches": {
+ "type": "object",
+ "properties": {
+ "enabled": {
+ "type": "boolean"
+ }
+ },
+ "required": [
+ "enabled"
+ ]
+ }
+ }
}
},
"additionalProperties": false
Edited by Andy Schoenen