diff options
Diffstat (limited to 'app/models')
-rw-r--r-- | app/models/ci/deleted_object.rb | 37 | ||||
-rw-r--r-- | app/models/ci/job_artifact.rb | 9 | ||||
-rw-r--r-- | app/models/ci/pipeline.rb | 19 | ||||
-rw-r--r-- | app/models/commit_status.rb | 1 | ||||
-rw-r--r-- | app/models/group.rb | 11 | ||||
-rw-r--r-- | app/models/namespace_setting.rb | 7 | ||||
-rw-r--r-- | app/models/project.rb | 4 | ||||
-rw-r--r-- | app/models/project_services/confluence_service.rb | 2 | ||||
-rw-r--r-- | app/models/project_services/packagist_service.rb | 2 |
9 files changed, 88 insertions, 4 deletions
diff --git a/app/models/ci/deleted_object.rb b/app/models/ci/deleted_object.rb new file mode 100644 index 00000000000..e74946eda16 --- /dev/null +++ b/app/models/ci/deleted_object.rb @@ -0,0 +1,37 @@ +# frozen_string_literal: true + +module Ci + class DeletedObject < ApplicationRecord + extend Gitlab::Ci::Model + + mount_uploader :file, DeletedObjectUploader + + scope :ready_for_destruction, ->(limit) do + where('pick_up_at < ?', Time.current).limit(limit) + end + + scope :lock_for_destruction, ->(limit) do + ready_for_destruction(limit) + .select(:id) + .order(:pick_up_at) + .lock('FOR UPDATE SKIP LOCKED') + end + + def self.bulk_import(artifacts) + attributes = artifacts.each.with_object([]) do |artifact, accumulator| + record = artifact.to_deleted_object_attrs + accumulator << record if record[:store_dir] && record[:file] + end + + self.insert_all(attributes) if attributes.any? + end + + def delete_file_from_storage + file.remove! + true + rescue => exception + Gitlab::ErrorTracking.track_exception(exception) + false + end + end +end diff --git a/app/models/ci/job_artifact.rb b/app/models/ci/job_artifact.rb index 42c0185c366..02e17afdab0 100644 --- a/app/models/ci/job_artifact.rb +++ b/app/models/ci/job_artifact.rb @@ -290,6 +290,15 @@ module Ci max_size&.megabytes.to_i end + def to_deleted_object_attrs + { + file_store: file_store, + store_dir: file.store_dir.to_s, + file: file_identifier, + pick_up_at: expire_at || Time.current + } + end + private def set_size diff --git a/app/models/ci/pipeline.rb b/app/models/ci/pipeline.rb index c9e05b45dbd..b29451315e8 100644 --- a/app/models/ci/pipeline.rb +++ b/app/models/ci/pipeline.rb @@ -841,6 +841,25 @@ module Ci end end + def build_with_artifacts_in_self_and_descendants(name) + builds_in_self_and_descendants + .ordered_by_pipeline # find job in hierarchical order + .with_downloadable_artifacts + .find_by_name(name) + end + + def builds_in_self_and_descendants + Ci::Build.latest.where(pipeline: self_and_descendants) + end + + # Without using `unscoped`, caller scope is also included into the query. + # Using `unscoped` here will be redundant after Rails 6.1 + def self_and_descendants + ::Gitlab::Ci::PipelineObjectHierarchy + .new(self.class.unscoped.where(id: id), options: { same_project: true }) + .base_and_descendants + end + def bridge_triggered? source_bridge.present? end diff --git a/app/models/commit_status.rb b/app/models/commit_status.rb index b0169d6290a..4498e08d754 100644 --- a/app/models/commit_status.rb +++ b/app/models/commit_status.rb @@ -48,6 +48,7 @@ class CommitStatus < ApplicationRecord scope :ordered_by_stage, -> { order(stage_idx: :asc) } scope :latest_ordered, -> { latest.ordered.includes(project: :namespace) } scope :retried_ordered, -> { retried.ordered.includes(project: :namespace) } + scope :ordered_by_pipeline, -> { order(pipeline_id: :asc) } scope :before_stage, -> (index) { where('stage_idx < ?', index) } scope :for_stage, -> (index) { where(stage_idx: index) } scope :after_stage, -> (index) { where('stage_idx > ?', index) } diff --git a/app/models/group.rb b/app/models/group.rb index 1dec831606b..5a18441e0ad 100644 --- a/app/models/group.rb +++ b/app/models/group.rb @@ -76,6 +76,7 @@ class Group < Namespace validate :visibility_level_allowed_by_projects validate :visibility_level_allowed_by_sub_groups validate :visibility_level_allowed_by_parent + validate :two_factor_authentication_allowed validates :variables, variable_duplicates: true validates :two_factor_grace_period, presence: true, numericality: { greater_than_or_equal_to: 0 } @@ -589,6 +590,16 @@ class Group < Namespace errors.add(:visibility_level, "#{visibility} is not allowed since there are sub-groups with higher visibility.") end + def two_factor_authentication_allowed + return unless has_parent? + return unless require_two_factor_authentication + + ancestor_settings = ancestors.find_by(parent_id: nil).namespace_settings + return if ancestor_settings.allow_mfa_for_subgroups + + errors.add(:require_two_factor_authentication, _('is forbidden by a top-level group')) + end + def members_from_self_and_ancestor_group_shares group_group_link_table = GroupGroupLink.arel_table group_member_table = GroupMember.arel_table diff --git a/app/models/namespace_setting.rb b/app/models/namespace_setting.rb index 40c46fa6e3d..6f31208f28b 100644 --- a/app/models/namespace_setting.rb +++ b/app/models/namespace_setting.rb @@ -4,6 +4,7 @@ class NamespaceSetting < ApplicationRecord belongs_to :namespace, inverse_of: :namespace_settings validate :default_branch_name_content + validate :allow_mfa_for_group NAMESPACE_SETTINGS_PARAMS = [:default_branch_name].freeze @@ -16,6 +17,12 @@ class NamespaceSetting < ApplicationRecord errors.add(:default_branch_name, "can not be an empty string") end end + + def allow_mfa_for_group + if namespace&.subgroup? && allow_mfa_for_subgroups == false + errors.add(:allow_mfa_for_subgroups, _('is not allowed since the group is not top-level group.')) + end + end end NamespaceSetting.prepend_if_ee('EE::NamespaceSetting') diff --git a/app/models/project.rb b/app/models/project.rb index 9fa93d9b4e4..d7f5254a6e3 100644 --- a/app/models/project.rb +++ b/app/models/project.rb @@ -951,7 +951,7 @@ class Project < ApplicationRecord latest_pipeline = ci_pipelines.latest_successful_for_ref(ref) return unless latest_pipeline - latest_pipeline.builds.latest.with_downloadable_artifacts.find_by(name: job_name) + latest_pipeline.build_with_artifacts_in_self_and_descendants(job_name) end def latest_successful_build_for_sha(job_name, sha) @@ -960,7 +960,7 @@ class Project < ApplicationRecord latest_pipeline = ci_pipelines.latest_successful_for_sha(sha) return unless latest_pipeline - latest_pipeline.builds.latest.with_downloadable_artifacts.find_by(name: job_name) + latest_pipeline.build_with_artifacts_in_self_and_descendants(job_name) end def latest_successful_build_for_ref!(job_name, ref = default_branch) diff --git a/app/models/project_services/confluence_service.rb b/app/models/project_services/confluence_service.rb index dd44a0d1d56..6db446fc04c 100644 --- a/app/models/project_services/confluence_service.rb +++ b/app/models/project_services/confluence_service.rb @@ -27,7 +27,7 @@ class ConfluenceService < Service end def description - s_('ConfluenceService|Connect a Confluence Cloud Workspace to your GitLab project') + s_('ConfluenceService|Connect a Confluence Cloud Workspace to GitLab') end def detailed_description diff --git a/app/models/project_services/packagist_service.rb b/app/models/project_services/packagist_service.rb index 35dbedd1341..21f0a2b2463 100644 --- a/app/models/project_services/packagist_service.rb +++ b/app/models/project_services/packagist_service.rb @@ -16,7 +16,7 @@ class PackagistService < Service end def description - 'Update your project on Packagist, the main Composer repository' + s_('Integrations|Update your projects on Packagist, the main Composer repository') end def self.to_param |