diff options
Diffstat (limited to 'lib')
-rw-r--r-- | lib/api/api_guard.rb | 4 | ||||
-rw-r--r-- | lib/api/internal/base.rb | 10 | ||||
-rw-r--r-- | lib/api/settings.rb | 1 | ||||
-rw-r--r-- | lib/constraints/admin_constrainer.rb | 2 | ||||
-rw-r--r-- | lib/gitlab/diff/highlight.rb | 70 | ||||
-rw-r--r-- | lib/gitlab/diff/highlight_cache.rb | 3 | ||||
-rw-r--r-- | lib/gitlab/diff/inline_diff.rb | 1 | ||||
-rw-r--r-- | lib/gitlab/diff/line.rb | 8 | ||||
-rw-r--r-- | lib/gitlab/sidekiq_middleware/admin_mode/client.rb | 3 | ||||
-rw-r--r-- | lib/gitlab/sidekiq_middleware/admin_mode/server.rb | 3 |
10 files changed, 77 insertions, 28 deletions
diff --git a/lib/api/api_guard.rb b/lib/api/api_guard.rb index 8641271f2df..8822a30d4a1 100644 --- a/lib/api/api_guard.rb +++ b/lib/api/api_guard.rb @@ -55,7 +55,7 @@ module API user = find_user_from_sources return unless user - if user.is_a?(User) && Feature.enabled?(:user_mode_in_session) + if user.is_a?(User) && Gitlab::CurrentSettings.admin_mode # Sessions are enforced to be unavailable for API calls, so ignore them for admin mode Gitlab::Auth::CurrentUserMode.bypass_session!(user.id) end @@ -236,7 +236,7 @@ module API def after # Use a Grape middleware since the Grape `after` blocks might run # before we are finished rendering the `Grape::Entity` classes - Gitlab::Auth::CurrentUserMode.reset_bypass_session! if Feature.enabled?(:user_mode_in_session) + Gitlab::Auth::CurrentUserMode.reset_bypass_session! if Gitlab::CurrentSettings.admin_mode # Explicit nil is needed or the api call return value will be overwritten nil diff --git a/lib/api/internal/base.rb b/lib/api/internal/base.rb index 3dd01b96e39..664b05ea010 100644 --- a/lib/api/internal/base.rb +++ b/lib/api/internal/base.rb @@ -52,7 +52,7 @@ module API actor.update_last_used_at! check_result = begin - Gitlab::Auth::CurrentUserMode.bypass_session!(actor.user&.id) do + with_admin_mode_bypass!(actor.user&.id) do access_check!(actor, params) end rescue Gitlab::GitAccess::ForbiddenError => e @@ -120,6 +120,14 @@ module API def two_factor_otp_check { success: false, message: 'Feature is not available' } end + + def with_admin_mode_bypass!(actor_id) + return yield unless Gitlab::CurrentSettings.admin_mode + + Gitlab::Auth::CurrentUserMode.bypass_session!(actor_id) do + yield + end + end end namespace 'internal' do diff --git a/lib/api/settings.rb b/lib/api/settings.rb index 64a72b4cb7f..95d0c525ced 100644 --- a/lib/api/settings.rb +++ b/lib/api/settings.rb @@ -30,6 +30,7 @@ module API success Entities::ApplicationSetting end params do + optional :admin_mode, type: Boolean, desc: 'Require admin users to re-authenticate for administrative (i.e. potentially dangerous) operations' optional :admin_notification_email, type: String, desc: 'Deprecated: Use :abuse_notification_email instead. Abuse reports will be sent to this address if it is set. Abuse reports are always available in the admin area.' optional :abuse_notification_email, type: String, desc: 'Abuse reports will be sent to this address if it is set. Abuse reports are always available in the admin area.' optional :after_sign_up_text, type: String, desc: 'Text shown after sign up' diff --git a/lib/constraints/admin_constrainer.rb b/lib/constraints/admin_constrainer.rb index 59c855a1b73..2f32cc7ad91 100644 --- a/lib/constraints/admin_constrainer.rb +++ b/lib/constraints/admin_constrainer.rb @@ -3,7 +3,7 @@ module Constraints class AdminConstrainer def matches?(request) - if Feature.enabled?(:user_mode_in_session) + if Gitlab::CurrentSettings.admin_mode admin_mode_enabled?(request) else user_is_admin?(request) diff --git a/lib/gitlab/diff/highlight.rb b/lib/gitlab/diff/highlight.rb index baa46e7e306..23859e2573e 100644 --- a/lib/gitlab/diff/highlight.rb +++ b/lib/gitlab/diff/highlight.rb @@ -3,7 +3,7 @@ module Gitlab module Diff class Highlight - attr_reader :diff_file, :diff_lines, :raw_lines, :repository, :project + attr_reader :diff_file, :diff_lines, :repository, :project delegate :old_path, :new_path, :old_sha, :new_sha, to: :diff_file, prefix: :diff @@ -22,29 +22,15 @@ module Gitlab end def highlight - @diff_lines.map.with_index do |diff_line, i| + populate_marker_ranges if Feature.enabled?(:use_marker_ranges, project, default_enabled: :yaml) + + @diff_lines.map.with_index do |diff_line, index| diff_line = diff_line.dup # ignore highlighting for "match" lines next diff_line if diff_line.meta? - rich_line = highlight_line(diff_line) || ERB::Util.html_escape(diff_line.text) - - if line_inline_diffs = inline_diffs[i] - begin - # MarkerRange objects are converted to Ranges to keep the previous behavior - # Issue: https://gitlab.com/gitlab-org/gitlab/-/issues/324068 - if Feature.disabled?(:introduce_marker_ranges, project, default_enabled: :yaml) - line_inline_diffs = line_inline_diffs.map { |marker_range| marker_range.to_range } - end - - rich_line = InlineDiffMarker.new(diff_line.text, rich_line).mark(line_inline_diffs) - # This should only happen when the encoding of the diff doesn't - # match the blob, which is a bug. But we shouldn't fail to render - # completely in that case, even though we want to report the error. - rescue RangeError => e - Gitlab::ErrorTracking.track_and_raise_for_dev_exception(e, issue_url: 'https://gitlab.com/gitlab-org/gitlab-foss/issues/45441') - end - end + rich_line = apply_syntax_highlight(diff_line) + rich_line = apply_marker_ranges_highlight(diff_line, rich_line, index) diff_line.rich_text = rich_line @@ -54,6 +40,49 @@ module Gitlab private + def populate_marker_ranges + pair_selector = Gitlab::Diff::PairSelector.new(@raw_lines) + + pair_selector.each do |old_index, new_index| + old_line = diff_lines[old_index] + new_line = diff_lines[new_index] + + old_diffs, new_diffs = Gitlab::Diff::InlineDiff.new(old_line.text, new_line.text, offset: 1).inline_diffs + + old_line.set_marker_ranges(old_diffs) + new_line.set_marker_ranges(new_diffs) + end + end + + def apply_syntax_highlight(diff_line) + highlight_line(diff_line) || ERB::Util.html_escape(diff_line.text) + end + + def apply_marker_ranges_highlight(diff_line, rich_line, index) + marker_ranges = if Feature.enabled?(:use_marker_ranges, project, default_enabled: :yaml) + diff_line.marker_ranges + else + inline_diffs[index] + end + + return rich_line if marker_ranges.blank? + + begin + # MarkerRange objects are converted to Ranges to keep the previous behavior + # Issue: https://gitlab.com/gitlab-org/gitlab/-/issues/324068 + if Feature.disabled?(:introduce_marker_ranges, project, default_enabled: :yaml) + marker_ranges = marker_ranges.map { |marker_range| marker_range.to_range } + end + + InlineDiffMarker.new(diff_line.text, rich_line).mark(marker_ranges) + # This should only happen when the encoding of the diff doesn't + # match the blob, which is a bug. But we shouldn't fail to render + # completely in that case, even though we want to report the error. + rescue RangeError => e + Gitlab::ErrorTracking.track_and_raise_for_dev_exception(e, issue_url: 'https://gitlab.com/gitlab-org/gitlab-foss/issues/45441') + end + end + def highlight_line(diff_line) return unless diff_file && diff_file.diff_refs @@ -72,6 +101,7 @@ module Gitlab end end + # Deprecated: https://gitlab.com/gitlab-org/gitlab/-/issues/324638 def inline_diffs @inline_diffs ||= InlineDiff.for_lines(@raw_lines) end diff --git a/lib/gitlab/diff/highlight_cache.rb b/lib/gitlab/diff/highlight_cache.rb index c5e9bfdc321..2192582348c 100644 --- a/lib/gitlab/diff/highlight_cache.rb +++ b/lib/gitlab/diff/highlight_cache.rb @@ -73,7 +73,8 @@ module Gitlab 'highlighted-diff-files', diffable.cache_key, VERSION, diff_options, - Feature.enabled?(:introduce_marker_ranges, diffable.project, default_enabled: :yaml) + Feature.enabled?(:introduce_marker_ranges, diffable.project, default_enabled: :yaml), + Feature.enabled?(:use_marker_ranges, diffable.project, default_enabled: :yaml) ].join(":") end end diff --git a/lib/gitlab/diff/inline_diff.rb b/lib/gitlab/diff/inline_diff.rb index dd73e4d6c15..f70618195d0 100644 --- a/lib/gitlab/diff/inline_diff.rb +++ b/lib/gitlab/diff/inline_diff.rb @@ -18,6 +18,7 @@ module Gitlab CharDiff.new(old_line, new_line).changed_ranges(offset: offset) end + # Deprecated: https://gitlab.com/gitlab-org/gitlab/-/issues/324638 class << self def for_lines(lines) pair_selector = Gitlab::Diff::PairSelector.new(lines) diff --git a/lib/gitlab/diff/line.rb b/lib/gitlab/diff/line.rb index 98ed2400d82..444928b4310 100644 --- a/lib/gitlab/diff/line.rb +++ b/lib/gitlab/diff/line.rb @@ -8,7 +8,7 @@ module Gitlab # SERIALIZE_KEYS = %i(line_code rich_text text type index old_pos new_pos).freeze - attr_reader :line_code + attr_reader :line_code, :marker_ranges attr_writer :rich_text attr_accessor :text, :index, :type, :old_pos, :new_pos @@ -21,6 +21,8 @@ module Gitlab # When line code is not provided from cache store we build it # using the parent_file(Diff::File or Conflict::File). @line_code = line_code || calculate_line_code + + @marker_ranges = [] end def self.init_from_hash(hash) @@ -48,6 +50,10 @@ module Gitlab hash end + def set_marker_ranges(marker_ranges) + @marker_ranges = marker_ranges + end + def old_line old_pos unless added? || meta? end diff --git a/lib/gitlab/sidekiq_middleware/admin_mode/client.rb b/lib/gitlab/sidekiq_middleware/admin_mode/client.rb index 36204e1bee0..1b33743a0e9 100644 --- a/lib/gitlab/sidekiq_middleware/admin_mode/client.rb +++ b/lib/gitlab/sidekiq_middleware/admin_mode/client.rb @@ -8,7 +8,8 @@ module Gitlab # If enabled then it injects a job field that persists through the job execution class Client def call(_worker_class, job, _queue, _redis_pool) - return yield unless ::Feature.enabled?(:user_mode_in_session) + # Not calling Gitlab::CurrentSettings.admin_mode on purpose on sidekiq middleware + # Only when admin mode application setting is enabled might the admin_mode_user_id be non-nil here # Admin mode enabled in the original request or in a nested sidekiq job admin_mode_user_id = find_admin_user_id diff --git a/lib/gitlab/sidekiq_middleware/admin_mode/server.rb b/lib/gitlab/sidekiq_middleware/admin_mode/server.rb index 6366867a0fa..c4e64705d6e 100644 --- a/lib/gitlab/sidekiq_middleware/admin_mode/server.rb +++ b/lib/gitlab/sidekiq_middleware/admin_mode/server.rb @@ -5,7 +5,8 @@ module Gitlab module AdminMode class Server def call(_worker, job, _queue) - return yield unless Feature.enabled?(:user_mode_in_session) + # Not calling Gitlab::CurrentSettings.admin_mode on purpose on sidekiq middleware + # Only when admin_mode setting is enabled can it be true here admin_mode_user_id = job['admin_mode_user_id'] |