diff options
Diffstat (limited to 'app/models/concerns')
19 files changed, 120 insertions, 98 deletions
diff --git a/app/models/concerns/commit_signature.rb b/app/models/concerns/commit_signature.rb index 5dac3c7833a..5bdf6bb31bf 100644 --- a/app/models/concerns/commit_signature.rb +++ b/app/models/concerns/commit_signature.rb @@ -16,7 +16,8 @@ module CommitSignature unverified_key: 4, unknown_key: 5, multiple_signatures: 6, - revoked_key: 7 + revoked_key: 7, + verified_system: 8 } belongs_to :project, class_name: 'Project', foreign_key: 'project_id', optional: false diff --git a/app/models/concerns/database_event_tracking.rb b/app/models/concerns/database_event_tracking.rb index 26e184c202f..7e2f445189e 100644 --- a/app/models/concerns/database_event_tracking.rb +++ b/app/models/concerns/database_event_tracking.rb @@ -3,8 +3,6 @@ module DatabaseEventTracking extend ActiveSupport::Concern - FEATURE_FLAG_BATCH2_CLASSES = %w[Vulnerability MergeRequest::Metrics].freeze - included do after_create_commit :publish_database_create_event after_destroy_commit :publish_database_destroy_event @@ -24,9 +22,6 @@ module DatabaseEventTracking end def publish_database_event(name) - return unless database_events_for_class_enabled? - return unless database_events_feature_flag_enabled? - # Gitlab::Tracking#event is triggering Snowplow event # Snowplow events are sent with usage of # https://snowplow.github.io/snowplow-ruby-tracker/SnowplowTracker/AsyncEmitter.html @@ -54,14 +49,4 @@ module DatabaseEventTracking .with_indifferent_access .slice(*self.class::SNOWPLOW_ATTRIBUTES) end - - def database_events_for_class_enabled? - is_batch2 = FEATURE_FLAG_BATCH2_CLASSES.include?(self.class.to_s) - - !is_batch2 || Feature.enabled?(:product_intelligence_database_event_tracking_batch2) - end - - def database_events_feature_flag_enabled? - Feature.enabled?(:product_intelligence_database_event_tracking) - end end diff --git a/app/models/concerns/enums/ci/pipeline.rb b/app/models/concerns/enums/ci/pipeline.rb index d798a13741f..f5ffeb8c425 100644 --- a/app/models/concerns/enums/ci/pipeline.rb +++ b/app/models/concerns/enums/ci/pipeline.rb @@ -85,7 +85,8 @@ module Enums external_project_source: 5, bridge_source: 6, parameter_source: 7, - compliance_source: 8 + compliance_source: 8, + security_policies_default_source: 9 } end end diff --git a/app/models/concerns/enums/vulnerability.rb b/app/models/concerns/enums/vulnerability.rb index 4b325de61bc..dbf05dbc428 100644 --- a/app/models/concerns/enums/vulnerability.rb +++ b/app/models/concerns/enums/vulnerability.rb @@ -50,6 +50,10 @@ module Enums CONFIDENCE_LEVELS end + def self.parse_confidence_level(input) + input&.downcase.then { |value| confidence_levels.key?(value) ? value : 'unknown' } + end + def self.report_types REPORT_TYPES end @@ -58,6 +62,10 @@ module Enums SEVERITY_LEVELS end + def self.parse_severity_level(input) + input&.downcase.then { |value| severity_levels.key?(value) ? value : 'unknown' } + end + def self.detection_methods DETECTION_METHODS end diff --git a/app/models/concerns/expirable.rb b/app/models/concerns/expirable.rb index cc55315d6d7..af139e735af 100644 --- a/app/models/concerns/expirable.rb +++ b/app/models/concerns/expirable.rb @@ -6,10 +6,8 @@ module Expirable DAYS_TO_EXPIRE = 7 included do - scope :not, ->(scope) { where(scope.arel.constraints.reduce(:and).not) } - - scope :expired, -> { where.not(expires_at: nil).where(arel_table[:expires_at].lteq(Time.current)) } - scope :not_expired, -> { self.not(expired) } + scope :expired, -> { where(arel_table[:expires_at].lteq(Time.current)) } + scope :not_expired, -> { where(arel_table[:expires_at].gt(Time.current)).or(where(expires_at: nil)) } end def expired? diff --git a/app/models/concerns/has_user_type.rb b/app/models/concerns/has_user_type.rb index 9d4b8328e8d..2d0ff82e624 100644 --- a/app/models/concerns/has_user_type.rb +++ b/app/models/concerns/has_user_type.rb @@ -14,7 +14,7 @@ module HasUserType migration_bot: 7, security_bot: 8, automation_bot: 9, - security_policy_bot: 10, # Currently not in use. See https://gitlab.com/gitlab-org/gitlab/-/issues/384174 + security_policy_bot: 10, admin_bot: 11, suggested_reviewers_bot: 12, service_account: 13, diff --git a/app/models/concerns/ignorable_columns.rb b/app/models/concerns/ignorable_columns.rb index 4cbcb25406d..249d0b99494 100644 --- a/app/models/concerns/ignorable_columns.rb +++ b/app/models/concerns/ignorable_columns.rb @@ -18,7 +18,7 @@ module IgnorableColumns # # Indicate the earliest date and release we can stop ignoring the column with +remove_after+ (a date string) and +remove_with+ (a release) def ignore_columns(*columns, remove_after:, remove_with:) - raise ArgumentError, 'Please indicate when we can stop ignoring columns with remove_after (date string YYYY-MM-DD), example: ignore_columns(:name, remove_after: \'2019-12-01\', remove_with: \'12.6\')' unless remove_after =~ Gitlab::Regex.utc_date_regex + raise ArgumentError, 'Please indicate when we can stop ignoring columns with remove_after (date string YYYY-MM-DD), example: ignore_columns(:name, remove_after: \'2019-12-01\', remove_with: \'12.6\')' unless Gitlab::Regex.utc_date_regex.match?(remove_after) raise ArgumentError, 'Please indicate in which release we can stop ignoring columns with remove_with, example: ignore_columns(:name, remove_after: \'2019-12-01\', remove_with: \'12.6\')' unless remove_with self.ignored_columns += columns.flatten # rubocop:disable Cop/IgnoredColumns diff --git a/app/models/concerns/issue_available_features.rb b/app/models/concerns/issue_available_features.rb index 209456f8b67..3f65e701da7 100644 --- a/app/models/concerns/issue_available_features.rb +++ b/app/models/concerns/issue_available_features.rb @@ -19,7 +19,7 @@ module IssueAvailableFeatures end included do - scope :with_feature, ->(feature) { where(issue_type: available_features_for_issue_types[feature]) } + scope :with_feature, ->(feature) { with_issue_type(available_features_for_issue_types[feature]) } end def issue_type_supports?(feature) diff --git a/app/models/concerns/issues/forbid_issue_type_column_usage.rb b/app/models/concerns/issues/forbid_issue_type_column_usage.rb deleted file mode 100644 index 46a8a0278d9..00000000000 --- a/app/models/concerns/issues/forbid_issue_type_column_usage.rb +++ /dev/null @@ -1,59 +0,0 @@ -# frozen_string_literal: true - -# TODO: Remove with https://gitlab.com/gitlab-org/gitlab/-/issues/402699 -module Issues - module ForbidIssueTypeColumnUsage - extend ActiveSupport::Concern - - ForbiddenColumnUsed = Class.new(StandardError) - - included do - WorkItems::Type.base_types.each do |base_type, _value| - define_method "#{base_type}?".to_sym do - error_message = <<~ERROR - `#{model_name.element}.#{base_type}?` uses the `issue_type` column underneath. As we want to remove the column, - its usage is forbidden. You should use the `work_item_types` table instead. - - # Before - - #{model_name.element}.#{base_type}? => true - - # After - - #{model_name.element}.work_item_type.#{base_type}? => true - - More details in https://gitlab.com/groups/gitlab-org/-/epics/10529 - ERROR - - raise ForbiddenColumnUsed, error_message - end - - define_singleton_method base_type.to_sym do - error = ForbiddenColumnUsed.new( - <<~ERROR - `#{name}.#{base_type}` uses the `issue_type` column underneath. As we want to remove the column, - its usage is forbidden. You should use the `work_item_types` table instead. - - # Before - - #{name}.#{base_type} - - # After - - #{name}.with_issue_type(:#{base_type}) - - More details in https://gitlab.com/groups/gitlab-org/-/epics/10529 - ERROR - ) - - Gitlab::ErrorTracking.track_and_raise_for_dev_exception( - error, - method_name: "#{name}.#{base_type}" - ) - - with_issue_type(base_type.to_sym) - end - end - end - end -end diff --git a/app/models/concerns/milestoneish.rb b/app/models/concerns/milestoneish.rb index 4f2ea58f36d..3d9e09acf44 100644 --- a/app/models/concerns/milestoneish.rb +++ b/app/models/concerns/milestoneish.rb @@ -51,6 +51,7 @@ module Milestoneish def issue_participants_visible_by_user(user) User.joins(:issue_assignees) .where('issue_assignees.issue_id' => issues_visible_to_user(user).select(:id)) + .allow_cross_joins_across_databases(url: "https://gitlab.com/gitlab-org/gitlab/-/issues/417457") .distinct end @@ -90,9 +91,9 @@ module Milestoneish def expires_at if due_date if due_date.past? - "expired on #{due_date.to_s(:medium)}" + "expired on #{due_date.to_fs(:medium)}" else - "expires on #{due_date.to_s(:medium)}" + "expires on #{due_date.to_fs(:medium)}" end end end diff --git a/app/models/concerns/packages/debian/component_file.rb b/app/models/concerns/packages/debian/component_file.rb index cc7279d05f8..90d3abddbf1 100644 --- a/app/models/concerns/packages/debian/component_file.rb +++ b/app/models/concerns/packages/debian/component_file.rb @@ -10,8 +10,6 @@ module Packages include FileStoreMounter include IgnorableColumns - ignore_column :file_md5, remove_with: '16.2', remove_after: '2023-06-22' - def self.container_foreign_key "#{container_type}_id".to_sym end diff --git a/app/models/concerns/project_features_compatibility.rb b/app/models/concerns/project_features_compatibility.rb index 76c733b1c0b..c70100c03c8 100644 --- a/app/models/concerns/project_features_compatibility.rb +++ b/app/models/concerns/project_features_compatibility.rb @@ -4,7 +4,7 @@ # # After migrating issues_enabled merge_requests_enabled builds_enabled snippets_enabled and wiki_enabled # fields to a new table "project_features", support for the old fields is still needed in the API. -require 'gitlab/utils' +require 'gitlab/utils/all' module ProjectFeaturesCompatibility extend ActiveSupport::Concern diff --git a/app/models/concerns/protected_ref.rb b/app/models/concerns/protected_ref.rb index 7e1ebd1eba3..a87eadb9332 100644 --- a/app/models/concerns/protected_ref.rb +++ b/app/models/concerns/protected_ref.rb @@ -32,7 +32,12 @@ module ProtectedRef # to fail. has_many :"#{type}_access_levels", inverse_of: self.model_name.singular - validates :"#{type}_access_levels", length: { is: 1, message: "are restricted to a single instance per #{self.model_name.human}." }, unless: -> { allow_multiple?(type) } + validates :"#{type}_access_levels", + length: { + is: 1, + message: "are restricted to a single instance per #{self.model_name.human}." + }, + unless: -> { allow_multiple?(type) } accepts_nested_attributes_for :"#{type}_access_levels", allow_destroy: true end diff --git a/app/models/concerns/protected_ref_access.rb b/app/models/concerns/protected_ref_access.rb index c1c670db543..f0bb1cc359b 100644 --- a/app/models/concerns/protected_ref_access.rb +++ b/app/models/concerns/protected_ref_access.rb @@ -29,14 +29,30 @@ module ProtectedRefAccess def humanize(access_level) human_access_levels[access_level] end + + def non_role_types + [] + end end included do scope :maintainer, -> { where(access_level: Gitlab::Access::MAINTAINER) } scope :developer, -> { where(access_level: Gitlab::Access::DEVELOPER) } - scope :for_role, -> { where(user_id: nil, group_id: nil) } - - validates :access_level, presence: true, if: :role?, inclusion: { in: allowed_access_levels } + scope :for_role, -> { + if non_role_types.present? + where.missing(*non_role_types) + .allow_cross_joins_across_databases(url: "https://gitlab.com/gitlab-org/gitlab/-/issues/417457") + else + all + end + } + + protected_ref_fk = "#{module_parent.model_name.singular}_id" + validates :access_level, + presence: true, + inclusion: { in: allowed_access_levels }, + uniqueness: { scope: protected_ref_fk, conditions: -> { for_role } }, + if: :role? end def humanize diff --git a/app/models/concerns/protected_ref_deploy_key_access.rb b/app/models/concerns/protected_ref_deploy_key_access.rb new file mode 100644 index 00000000000..4275476a1ff --- /dev/null +++ b/app/models/concerns/protected_ref_deploy_key_access.rb @@ -0,0 +1,61 @@ +# frozen_string_literal: true + +module ProtectedRefDeployKeyAccess + extend ActiveSupport::Concern + + included do + belongs_to :deploy_key + + protected_ref_fk = "#{module_parent.model_name.singular}_id" + validates :deploy_key_id, uniqueness: { scope: protected_ref_fk, allow_nil: true } + validate :validate_deploy_key_membership + end + + class_methods do + def non_role_types + super << :deploy_key + end + end + + def type + return :deploy_key if deploy_key.present? + + super + end + + def humanize + return deploy_key.title if deploy_key? + + super + end + + def check_access(current_user) + super do + break enabled_deploy_key_for_user?(current_user) if deploy_key? + + yield if block_given? + end + end + + private + + def deploy_key? + type == :deploy_key + end + + def validate_deploy_key_membership + return if deploy_key.nil? || deploy_key_has_write_access_to_project? + + errors.add(:deploy_key, 'is not enabled for this project') + end + + def enabled_deploy_key_for_user?(current_user) + current_user.can?(:read_project, project) && + deploy_key.user_id == current_user.id && + deploy_key_has_write_access_to_project? + end + + def deploy_key_has_write_access_to_project? + DeployKey.with_write_access_for_project(project, deploy_key: deploy_key).exists? + end +end diff --git a/app/models/concerns/spammable.rb b/app/models/concerns/spammable.rb index 6550c5a94a0..5986f8f5b5f 100644 --- a/app/models/concerns/spammable.rb +++ b/app/models/concerns/spammable.rb @@ -138,7 +138,7 @@ module Spammable result.reject(&:blank?).join("\n") end - # Override in Spammable if further checks are necessary + # Override in included class if further checks are necessary def check_for_spam?(*) spammable_attribute_changed? end @@ -153,8 +153,8 @@ module Spammable end end - # Override in Spammable if differs - def allow_possible_spam? + # Override in included class if you want to allow possible spam under specific circumstances + def allow_possible_spam?(*) Gitlab::CurrentSettings.allow_possible_spam end end diff --git a/app/models/concerns/triggerable_hooks.rb b/app/models/concerns/triggerable_hooks.rb index e3800caa43f..0e72bd30a37 100644 --- a/app/models/concerns/triggerable_hooks.rb +++ b/app/models/concerns/triggerable_hooks.rb @@ -17,7 +17,8 @@ module TriggerableHooks feature_flag_hooks: :feature_flag_events, release_hooks: :releases_events, member_hooks: :member_events, - subgroup_hooks: :subgroup_events + subgroup_hooks: :subgroup_events, + emoji_hooks: :emoji_events }.freeze extend ActiveSupport::Concern diff --git a/app/models/concerns/vulnerability_finding_helpers.rb b/app/models/concerns/vulnerability_finding_helpers.rb index a5b69997900..e8a50497b20 100644 --- a/app/models/concerns/vulnerability_finding_helpers.rb +++ b/app/models/concerns/vulnerability_finding_helpers.rb @@ -59,6 +59,7 @@ module VulnerabilityFindingHelpers evidence = Vulnerabilities::Finding::Evidence.new(data: report_finding.evidence.data) if report_finding.evidence Vulnerabilities::Finding.new(finding_data).tap do |finding| + finding.uuid = security_finding.uuid finding.location_fingerprint = report_finding.location.fingerprint finding.vulnerability = vulnerability_for(security_finding.uuid) finding.project = project diff --git a/app/models/concerns/vulnerability_finding_signature_helpers.rb b/app/models/concerns/vulnerability_finding_signature_helpers.rb index 71a12b4077b..a225625815b 100644 --- a/app/models/concerns/vulnerability_finding_signature_helpers.rb +++ b/app/models/concerns/vulnerability_finding_signature_helpers.rb @@ -2,12 +2,17 @@ module VulnerabilityFindingSignatureHelpers extend ActiveSupport::Concern + # If the location object describes a physical location within a file # (filename + line numbers), the 'location' algorithm_type should be used # If the location object describes arbitrary data, then the 'hash' # algorithm_type should be used. - - ALGORITHM_TYPES = { hash: 1, location: 2, scope_offset: 3 }.with_indifferent_access.freeze + ALGORITHM_TYPES = { + hash: 1, + location: 2, + scope_offset: 3, + scope_offset_compressed: 4 + }.with_indifferent_access.freeze class_methods do def priority(algorithm_type) |