Welcome to mirror list, hosted at ThFree Co, Russian Federation.

gitlab.com/gitlab-org/gitlab-foss.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/app
diff options
context:
space:
mode:
authorGitLab Bot <gitlab-bot@gitlab.com>2023-06-03 00:59:19 +0300
committerGitLab Bot <gitlab-bot@gitlab.com>2023-06-03 00:59:19 +0300
commit1385478346704d03ab9d3a9bf8ae3812cea0b6b5 (patch)
treec2b68728119200c48fbfe09bb09397d4e31659b7 /app
parent361d9dae8bafae8c830d68d16ea0f76482ba9343 (diff)
Add latest changes from gitlab-org/security/gitlab@16-0-stable-ee
Diffstat (limited to 'app')
-rw-r--r--app/assets/javascripts/single_file_diff.js4
-rw-r--r--app/controllers/abuse_reports_controller.rb9
-rw-r--r--app/helpers/merge_requests_helper.rb4
-rw-r--r--app/models/concerns/ci/artifactable.rb4
-rw-r--r--app/models/concerns/exportable.rb69
-rw-r--r--app/models/concerns/issuable.rb5
-rw-r--r--app/models/issue.rb1
-rw-r--r--app/models/label.rb15
-rw-r--r--app/models/project_team.rb6
-rw-r--r--app/models/user.rb4
10 files changed, 92 insertions, 29 deletions
diff --git a/app/assets/javascripts/single_file_diff.js b/app/assets/javascripts/single_file_diff.js
index bab167bb7e4..11896a75798 100644
--- a/app/assets/javascripts/single_file_diff.js
+++ b/app/assets/javascripts/single_file_diff.js
@@ -24,7 +24,9 @@ export default class SingleFileDiff {
this.content = $('.diff-content', this.file);
this.$chevronRightIcon = $('.diff-toggle-caret .chevron-right', this.file);
this.$chevronDownIcon = $('.diff-toggle-caret .chevron-down', this.file);
- this.diffForPath = this.content.find('[data-diff-for-path]').data('diffForPath');
+ this.diffForPath = this.content
+ .find('div:not(.note-text)[data-diff-for-path]')
+ .data('diffForPath');
this.isOpen = !this.diffForPath;
if (this.diffForPath) {
this.collapsedContent = this.content;
diff --git a/app/controllers/abuse_reports_controller.rb b/app/controllers/abuse_reports_controller.rb
index edeac57bc42..5a4f80fcb32 100644
--- a/app/controllers/abuse_reports_controller.rb
+++ b/app/controllers/abuse_reports_controller.rb
@@ -1,17 +1,10 @@
# frozen_string_literal: true
class AbuseReportsController < ApplicationController
- before_action :set_user, only: [:new, :add_category]
+ before_action :set_user, only: [:add_category]
feature_category :insider_threat
- def new
- @abuse_report = AbuseReport.new(
- user_id: @user.id,
- reported_from_url: params.fetch(:ref_url, '')
- )
- end
-
def add_category
@abuse_report = AbuseReport.new(
user_id: @user.id,
diff --git a/app/helpers/merge_requests_helper.rb b/app/helpers/merge_requests_helper.rb
index 15901e13c1a..af1c85532c3 100644
--- a/app/helpers/merge_requests_helper.rb
+++ b/app/helpers/merge_requests_helper.rb
@@ -247,13 +247,13 @@ module MergeRequestsHelper
end
branch = if merge_request.for_fork?
- _('%{fork_icon} %{source_project_path}:%{source_branch}').html_safe % { fork_icon: fork_icon.html_safe, source_project_path: merge_request.source_project_path.html_safe, source_branch: merge_request.source_branch.html_safe }
+ html_escape(_('%{fork_icon} %{source_project_path}:%{source_branch}')) % { fork_icon: fork_icon.html_safe, source_project_path: merge_request.source_project_path, source_branch: merge_request.source_branch }
else
merge_request.source_branch
end
branch_title = if merge_request.for_fork?
- _('%{source_project_path}:%{source_branch}').html_safe % { source_project_path: merge_request.source_project_path.html_safe, source_branch: merge_request.source_branch.html_safe }
+ html_escape(_('%{source_project_path}:%{source_branch}')) % { source_project_path: merge_request.source_project_path, source_branch: merge_request.source_branch }
else
merge_request.source_branch
end
diff --git a/app/models/concerns/ci/artifactable.rb b/app/models/concerns/ci/artifactable.rb
index 3fdbd6a8789..974f8213a29 100644
--- a/app/models/concerns/ci/artifactable.rb
+++ b/app/models/concerns/ci/artifactable.rb
@@ -9,6 +9,7 @@ module Ci
STORE_COLUMN = :file_store
NotSupportedAdapterError = Class.new(StandardError)
+
FILE_FORMAT_ADAPTERS = {
# While zip is a streamable file format, performing streaming
# reads requires that each entry in the zip has certain headers
@@ -41,6 +42,9 @@ module Ci
raise NotSupportedAdapterError, 'This file format requires a dedicated adapter'
end
+ ::Gitlab::Ci::Artifacts::DecompressedArtifactSizeValidator
+ .new(file: file, file_format: file_format.to_sym).validate!
+
log_artifacts_filesize(file.model)
file.open do |stream|
diff --git a/app/models/concerns/exportable.rb b/app/models/concerns/exportable.rb
index 066a44912be..c305d272a14 100644
--- a/app/models/concerns/exportable.rb
+++ b/app/models/concerns/exportable.rb
@@ -3,19 +3,6 @@
module Exportable
extend ActiveSupport::Concern
- def readable_records(association, current_user: nil)
- association_records = try(association)
- return unless association_records.present?
-
- if has_many_association?(association)
- DeclarativePolicy.user_scope do
- association_records.select { |record| readable_record?(record, current_user) }
- end
- else
- readable_record?(association_records, current_user) ? association_records : nil
- end
- end
-
def exportable_association?(association, current_user: nil)
return false unless respond_to?(association)
return true if has_many_association?(association)
@@ -30,8 +17,17 @@ module Exportable
exportable_restricted_associations & keys
end
- def has_many_association?(association_name)
- self.class.reflect_on_association(association_name)&.macro == :has_many
+ def to_authorized_json(keys_to_authorize, current_user, options)
+ modified_options = filtered_associations_opts(options, keys_to_authorize)
+ record_hash = as_json(modified_options).with_indifferent_access
+
+ keys_to_authorize.each do |key|
+ next unless record_hash.key?(key)
+
+ record_hash[key] = authorized_association_records(key, current_user, options)
+ end
+
+ record_hash.to_json
end
private
@@ -47,4 +43,47 @@ module Exportable
record.readable_by?(user)
end
end
+
+ def has_many_association?(association_name)
+ self.class.reflect_on_association(association_name)&.macro == :has_many
+ end
+
+ def readable_records(association, current_user: nil)
+ association_records = try(association)
+ return unless association_records.present?
+
+ if has_many_association?(association)
+ DeclarativePolicy.user_scope do
+ association_records.select { |record| readable_record?(record, current_user) }
+ end
+ else
+ readable_record?(association_records, current_user) ? association_records : nil
+ end
+ end
+
+ def authorized_association_records(key, current_user, options)
+ records = readable_records(key, current_user: current_user)
+ empty_assoc = has_many_association?(key) ? [] : nil
+ return empty_assoc unless records.present?
+
+ assoc_opts = association_options(key, options)&.dig(key)
+ records.as_json(assoc_opts)
+ end
+
+ def filtered_associations_opts(options, associations)
+ options_copy = options.deep_dup
+
+ associations.each do |key|
+ assoc_opts = association_options(key, options_copy)
+ next unless assoc_opts
+
+ assoc_opts[key] = { only: [:id] }
+ end
+
+ options_copy
+ end
+
+ def association_options(key, options)
+ options[:include].find { |assoc| assoc.key?(key) }
+ end
end
diff --git a/app/models/concerns/issuable.rb b/app/models/concerns/issuable.rb
index b1ec6b8ba32..8926e805d8d 100644
--- a/app/models/concerns/issuable.rb
+++ b/app/models/concerns/issuable.rb
@@ -27,6 +27,7 @@ module Issuable
include ClosedAtFilterable
include VersionedDescription
include SortableTitle
+ include Exportable
TITLE_LENGTH_MAX = 255
TITLE_HTML_LENGTH_MAX = 800
@@ -230,6 +231,10 @@ module Issuable
issuable_severity&.severity || IssuableSeverity::DEFAULT
end
+ def exportable_restricted_associations
+ super + [:notes]
+ end
+
private
def validate_description_length?
diff --git a/app/models/issue.rb b/app/models/issue.rb
index b7125617034..f214bc0f1af 100644
--- a/app/models/issue.rb
+++ b/app/models/issue.rb
@@ -25,7 +25,6 @@ class Issue < ApplicationRecord
include FromUnion
include EachBatch
include PgFullTextSearchable
- include Exportable
extend ::Gitlab::Utils::Override
diff --git a/app/models/label.rb b/app/models/label.rb
index 32b399ac461..0831ba40536 100644
--- a/app/models/label.rb
+++ b/app/models/label.rb
@@ -14,6 +14,7 @@ class Label < ApplicationRecord
cache_markdown_field :description, pipeline: :single_line
DEFAULT_COLOR = ::Gitlab::Color.of('#6699cc')
+ DESCRIPTION_LENGTH_MAX = 512.kilobytes
attribute :color, ::Gitlab::Database::Type::Color.new, default: DEFAULT_COLOR
@@ -32,6 +33,10 @@ class Label < ApplicationRecord
validates :title, uniqueness: { scope: [:group_id, :project_id] }
validates :title, length: { maximum: 255 }
+ # we validate the description against DESCRIPTION_LENGTH_MAX only for labels being created and on updates if
+ # the description changes to avoid breaking the existing labels which may have their descriptions longer
+ validates :description, bytesize: { maximum: -> { DESCRIPTION_LENGTH_MAX } }, if: :validate_description_length?
+
default_scope { order(title: :asc) } # rubocop:disable Cop/DefaultScope
scope :templates, -> { where(template: true, type: [Label.name, nil]) }
@@ -282,6 +287,16 @@ class Label < ApplicationRecord
private
+ def validate_description_length?
+ return false unless description_changed?
+
+ previous_description = changes['description'].first
+ # previous_description will be nil for new records
+ return true if previous_description.blank?
+
+ previous_description.bytesize <= DESCRIPTION_LENGTH_MAX || description.bytesize > previous_description.bytesize
+ end
+
def issues_count(user, params = {})
params.merge!(subject_foreign_key => subject.id, label_name: title, scope: 'all')
IssuesFinder.new(user, params.with_indifferent_access).execute.count
diff --git a/app/models/project_team.rb b/app/models/project_team.rb
index dd200aec807..ca1064997af 100644
--- a/app/models/project_team.rb
+++ b/app/models/project_team.rb
@@ -117,12 +117,14 @@ class ProjectTeam
owners.include?(user)
end
- def import(source_project, current_user = nil)
+ def import(source_project, current_user)
target_project = project
source_members = source_project.project_members.to_a
target_user_ids = target_project.project_members.pluck_user_ids
+ importer_access_level = max_member_access(current_user.id)
+
source_members.reject! do |member|
# Skip if user already present in team
!member.invite? && target_user_ids.include?(member.user_id)
@@ -132,6 +134,8 @@ class ProjectTeam
new_member = member.dup
new_member.id = nil
new_member.source = target_project
+ # So that a maintainer cannot import a member with owner access
+ new_member.access_level = [new_member.access_level, importer_access_level].min
new_member.created_by = current_user
new_member
end
diff --git a/app/models/user.rb b/app/models/user.rb
index dc70ff2e232..50da6f9e491 100644
--- a/app/models/user.rb
+++ b/app/models/user.rb
@@ -1549,7 +1549,9 @@ class User < ApplicationRecord
# rubocop: enable CodeReuse/ServiceClass
def primary_email_verified?
- confirmed? && !temp_oauth_email?
+ return false unless confirmed? && !temp_oauth_email?
+
+ !email_changed? || new_record?
end
def accept_pending_invitations!