summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
Diffstat (limited to 'lib')
-rw-r--r--lib/api/helpers/members_helpers.rb2
-rw-r--r--lib/api/helpers/rate_limiter.rb5
-rw-r--r--lib/api/users.rb6
-rw-r--r--lib/gitlab.rb50
-rw-r--r--lib/gitlab/application_rate_limiter.rb1
-rw-r--r--lib/gitlab/experimentation.rb8
-rw-r--r--lib/gitlab/metrics/samplers/action_cable_sampler.rb4
-rw-r--r--lib/gitlab/metrics/samplers/base_sampler.rb14
-rw-r--r--lib/gitlab/metrics/samplers/ruby_sampler.rb4
-rw-r--r--lib/gitlab_edition.rb50
10 files changed, 84 insertions, 60 deletions
diff --git a/lib/api/helpers/members_helpers.rb b/lib/api/helpers/members_helpers.rb
index c2710be6c03..6c20993431d 100644
--- a/lib/api/helpers/members_helpers.rb
+++ b/lib/api/helpers/members_helpers.rb
@@ -50,7 +50,7 @@ module API
end
def find_all_members_for_group(group)
- GroupMembersFinder.new(group).execute
+ GroupMembersFinder.new(group, current_user).execute(include_relations: [:inherited, :direct, :shared_from_groups])
end
def present_members(members)
diff --git a/lib/api/helpers/rate_limiter.rb b/lib/api/helpers/rate_limiter.rb
index 7d87c74097d..0ad4f089907 100644
--- a/lib/api/helpers/rate_limiter.rb
+++ b/lib/api/helpers/rate_limiter.rb
@@ -10,6 +10,7 @@ module API
# See app/controllers/concerns/check_rate_limit.rb for Rails controllers version
module RateLimiter
def check_rate_limit!(key, scope:, **options)
+ return if bypass_header_set?
return unless rate_limiter.throttled?(key, scope: scope, **options)
rate_limiter.log_request(request, "#{key}_request_limit".to_sym, current_user)
@@ -24,6 +25,10 @@ module API
def rate_limiter
::Gitlab::ApplicationRateLimiter
end
+
+ def bypass_header_set?
+ ::Gitlab::Throttle.bypass_header.present? && request.get_header(Gitlab::Throttle.bypass_header) == '1'
+ end
end
end
end
diff --git a/lib/api/users.rb b/lib/api/users.rb
index ce0a0e9b502..efecc7593d0 100644
--- a/lib/api/users.rb
+++ b/lib/api/users.rb
@@ -142,11 +142,15 @@ module API
get ":id", feature_category: :users do
forbidden!('Not authorized!') unless current_user
+ if Feature.enabled?(:rate_limit_user_by_id_endpoint, type: :development)
+ check_rate_limit! :users_get_by_id, scope: current_user unless current_user.admin?
+ end
+
user = User.find_by(id: params[:id])
not_found!('User') unless user && can?(current_user, :read_user, user)
- opts = { with: current_user&.admin? ? Entities::UserDetailsWithAdmin : Entities::User, current_user: current_user }
+ opts = { with: current_user.admin? ? Entities::UserDetailsWithAdmin : Entities::User, current_user: current_user }
user, opts = with_custom_attributes(user, opts)
present user, opts
diff --git a/lib/gitlab.rb b/lib/gitlab.rb
index d93d7acbaad..2449554d3c0 100644
--- a/lib/gitlab.rb
+++ b/lib/gitlab.rb
@@ -1,10 +1,15 @@
# frozen_string_literal: true
require 'pathname'
+require 'forwardable'
+
+require_relative 'gitlab_edition'
module Gitlab
- def self.root
- Pathname.new(File.expand_path('..', __dir__))
+ class << self
+ extend Forwardable
+
+ def_delegators :GitlabEdition, :root, :extensions, :ee?, :ee, :jh?, :jh
end
def self.version_info
@@ -89,47 +94,6 @@ module Gitlab
Rails.env.development? || Rails.env.test?
end
- def self.extensions
- if jh?
- %w[ee jh]
- elsif ee?
- %w[ee]
- else
- %w[]
- end
- end
-
- def self.ee?
- @is_ee ||=
- # We use this method when the Rails environment is not loaded. This
- # means that checking the presence of the License class could result in
- # this method returning `false`, even for an EE installation.
- #
- # The `FOSS_ONLY` is always `string` or `nil`
- # Thus the nil or empty string will result
- # in using default value: false
- #
- # The behavior needs to be synchronised with
- # config/helpers/is_ee_env.js
- root.join('ee/app/models/license.rb').exist? &&
- !%w[true 1].include?(ENV['FOSS_ONLY'].to_s)
- end
-
- def self.jh?
- @is_jh ||=
- ee? &&
- root.join('jh').exist? &&
- !%w[true 1].include?(ENV['EE_ONLY'].to_s)
- end
-
- def self.ee
- yield if ee?
- end
-
- def self.jh
- yield if jh?
- end
-
def self.http_proxy_env?
HTTP_PROXY_ENV_VARS.any? { |name| ENV[name] }
end
diff --git a/lib/gitlab/application_rate_limiter.rb b/lib/gitlab/application_rate_limiter.rb
index fb90ad9e275..5125d566524 100644
--- a/lib/gitlab/application_rate_limiter.rb
+++ b/lib/gitlab/application_rate_limiter.rb
@@ -49,6 +49,7 @@ module Gitlab
group_testing_hook: { threshold: 5, interval: 1.minute },
profile_add_new_email: { threshold: 5, interval: 1.minute },
web_hook_calls: { interval: 1.minute },
+ users_get_by_id: { threshold: 10, interval: 1.minute },
profile_resend_email_confirmation: { threshold: 5, interval: 1.minute },
update_environment_canary_ingress: { threshold: 1, interval: 1.minute },
auto_rollback_deployment: { threshold: 1, interval: 3.minutes }
diff --git a/lib/gitlab/experimentation.rb b/lib/gitlab/experimentation.rb
index 4cc653bec43..7edda290204 100644
--- a/lib/gitlab/experimentation.rb
+++ b/lib/gitlab/experimentation.rb
@@ -30,14 +30,6 @@
module Gitlab
module Experimentation
EXPERIMENTS = {
- remove_known_trial_form_fields_welcoming: {
- tracking_category: 'Growth::Conversion::Experiment::RemoveKnownTrialFormFieldsWelcoming',
- rollout_strategy: :user
- },
- remove_known_trial_form_fields_noneditable: {
- tracking_category: 'Growth::Conversion::Experiment::RemoveKnownTrialFormFieldsNoneditable',
- rollout_strategy: :user
- }
}.freeze
class << self
diff --git a/lib/gitlab/metrics/samplers/action_cable_sampler.rb b/lib/gitlab/metrics/samplers/action_cable_sampler.rb
index adce3030d0d..1f50371cae9 100644
--- a/lib/gitlab/metrics/samplers/action_cable_sampler.rb
+++ b/lib/gitlab/metrics/samplers/action_cable_sampler.rb
@@ -6,8 +6,8 @@ module Gitlab
class ActionCableSampler < BaseSampler
DEFAULT_SAMPLING_INTERVAL_SECONDS = 5
- def initialize(interval = nil, action_cable: ::ActionCable.server)
- super(interval)
+ def initialize(action_cable: ::ActionCable.server, **options)
+ super(**options)
@action_cable = action_cable
end
diff --git a/lib/gitlab/metrics/samplers/base_sampler.rb b/lib/gitlab/metrics/samplers/base_sampler.rb
index 52d80c3c27e..b2a9de21145 100644
--- a/lib/gitlab/metrics/samplers/base_sampler.rb
+++ b/lib/gitlab/metrics/samplers/base_sampler.rb
@@ -9,7 +9,10 @@ module Gitlab
attr_reader :interval
# interval - The sampling interval in seconds.
- def initialize(interval = nil)
+ # warmup - When true, takes a single sample eagerly before entering the sampling loop.
+ # This can be useful to ensure that all metrics files exist after `start` returns,
+ # since prometheus-client-mmap creates them lazily upon first access.
+ def initialize(interval: nil, logger: Logger.new($stdout), warmup: false, **options)
interval ||= ENV[interval_env_key]&.to_i
interval ||= self.class::DEFAULT_SAMPLING_INTERVAL_SECONDS
interval_half = interval.to_f / 2
@@ -17,13 +20,16 @@ module Gitlab
@interval = interval
@interval_steps = (-interval_half..interval_half).step(0.1).to_a
- super()
+ @logger = logger
+ @warmup = warmup
+
+ super(**options)
end
def safe_sample
sample
rescue StandardError => e
- ::Gitlab::AppLogger.warn("#{self.class}: #{e}, stopping")
+ @logger.warn("#{self.class}: #{e}, stopping")
stop
end
@@ -63,6 +69,8 @@ module Gitlab
def start_working
@running = true
+ safe_sample if @warmup
+
true
end
diff --git a/lib/gitlab/metrics/samplers/ruby_sampler.rb b/lib/gitlab/metrics/samplers/ruby_sampler.rb
index b1c5e9800da..d71ee671b8d 100644
--- a/lib/gitlab/metrics/samplers/ruby_sampler.rb
+++ b/lib/gitlab/metrics/samplers/ruby_sampler.rb
@@ -7,12 +7,12 @@ module Gitlab
DEFAULT_SAMPLING_INTERVAL_SECONDS = 60
GC_REPORT_BUCKETS = [0.01, 0.05, 0.1, 0.2, 0.3, 0.5, 1].freeze
- def initialize(*)
+ def initialize(...)
GC::Profiler.clear
metrics[:process_start_time_seconds].set(labels, Time.now.to_i)
- super
+ super(...)
end
def metrics
diff --git a/lib/gitlab_edition.rb b/lib/gitlab_edition.rb
new file mode 100644
index 00000000000..6eb6b52c357
--- /dev/null
+++ b/lib/gitlab_edition.rb
@@ -0,0 +1,50 @@
+# frozen_string_literal: true
+
+require 'pathname'
+
+module GitlabEdition
+ def self.root
+ Pathname.new(File.expand_path('..', __dir__))
+ end
+
+ def self.extensions
+ if jh?
+ %w[ee jh]
+ elsif ee?
+ %w[ee]
+ else
+ %w[]
+ end
+ end
+
+ def self.ee?
+ @is_ee ||=
+ # We use this method when the Rails environment is not loaded. This
+ # means that checking the presence of the License class could result in
+ # this method returning `false`, even for an EE installation.
+ #
+ # The `FOSS_ONLY` is always `string` or `nil`
+ # Thus the nil or empty string will result
+ # in using default value: false
+ #
+ # The behavior needs to be synchronised with
+ # config/helpers/is_ee_env.js
+ root.join('ee/app/models/license.rb').exist? &&
+ !%w[true 1].include?(ENV['FOSS_ONLY'].to_s)
+ end
+
+ def self.jh?
+ @is_jh ||=
+ ee? &&
+ root.join('jh').exist? &&
+ !%w[true 1].include?(ENV['EE_ONLY'].to_s)
+ end
+
+ def self.ee
+ yield if ee?
+ end
+
+ def self.jh
+ yield if jh?
+ end
+end