2018-07-25 05:30:33 -04:00
|
|
|
# frozen_string_literal: true
|
|
|
|
|
2019-03-28 09:17:42 -04:00
|
|
|
class ApplicationSetting < ApplicationRecord
|
2018-05-04 13:23:50 -04:00
|
|
|
include CacheableAttributes
|
2016-10-06 17:17:11 -04:00
|
|
|
include CacheMarkdownField
|
2015-12-10 04:48:37 -05:00
|
|
|
include TokenAuthenticatable
|
2018-10-09 01:59:42 -04:00
|
|
|
include IgnorableColumn
|
2018-10-23 06:58:41 -04:00
|
|
|
include ChronicDurationAttribute
|
2016-10-06 17:17:11 -04:00
|
|
|
|
2019-03-15 10:32:15 -04:00
|
|
|
add_authentication_token_field :runners_registration_token, encrypted: -> { Feature.enabled?(:application_settings_tokens_optional_encryption, default_enabled: true) ? :optional : :required }
|
2016-05-09 19:21:22 -04:00
|
|
|
add_authentication_token_field :health_check_access_token
|
2015-12-10 04:48:37 -05:00
|
|
|
|
2019-03-08 10:28:59 -05:00
|
|
|
# Include here so it can override methods from
|
|
|
|
# `add_authentication_token_field`
|
|
|
|
# We don't prepend for now because otherwise we'll need to
|
|
|
|
# fix a lot of tests using allow_any_instance_of
|
|
|
|
include ApplicationSettingImplementation
|
|
|
|
|
2017-07-03 10:01:41 -04:00
|
|
|
serialize :restricted_visibility_levels # rubocop:disable Cop/ActiveRecordSerialize
|
|
|
|
serialize :import_sources # rubocop:disable Cop/ActiveRecordSerialize
|
|
|
|
serialize :disabled_oauth_sign_in_sources, Array # rubocop:disable Cop/ActiveRecordSerialize
|
|
|
|
serialize :domain_whitelist, Array # rubocop:disable Cop/ActiveRecordSerialize
|
|
|
|
serialize :domain_blacklist, Array # rubocop:disable Cop/ActiveRecordSerialize
|
|
|
|
serialize :repository_storages # rubocop:disable Cop/ActiveRecordSerialize
|
2016-07-14 14:19:40 -04:00
|
|
|
|
2018-10-09 01:59:42 -04:00
|
|
|
ignore_column :circuitbreaker_failure_count_threshold
|
|
|
|
ignore_column :circuitbreaker_failure_reset_time
|
|
|
|
ignore_column :circuitbreaker_storage_timeout
|
|
|
|
ignore_column :circuitbreaker_access_retries
|
|
|
|
ignore_column :circuitbreaker_check_interval
|
2018-10-12 20:54:08 -04:00
|
|
|
ignore_column :koding_url
|
|
|
|
ignore_column :koding_enabled
|
2018-10-09 01:59:42 -04:00
|
|
|
|
2016-10-06 17:17:11 -04:00
|
|
|
cache_markdown_field :sign_in_text
|
|
|
|
cache_markdown_field :help_page_text
|
|
|
|
cache_markdown_field :shared_runners_text, pipeline: :plain_markdown
|
|
|
|
cache_markdown_field :after_sign_up_text
|
|
|
|
|
2017-10-05 15:56:23 -04:00
|
|
|
default_value_for :id, 1
|
|
|
|
|
2018-10-23 06:58:41 -04:00
|
|
|
chronic_duration_attr_writer :archive_builds_in_human_readable, :archive_builds_in_seconds
|
|
|
|
|
2017-04-24 15:12:05 -04:00
|
|
|
validates :uuid, presence: true
|
|
|
|
|
2015-06-13 00:22:55 -04:00
|
|
|
validates :session_expire_delay,
|
2015-12-28 15:21:34 -05:00
|
|
|
presence: true,
|
|
|
|
numericality: { only_integer: true, greater_than_or_equal_to: 0 }
|
2015-03-01 10:06:46 -05:00
|
|
|
|
2015-02-03 00:15:44 -05:00
|
|
|
validates :home_page_url,
|
2015-12-28 15:21:34 -05:00
|
|
|
allow_blank: true,
|
2019-04-11 02:29:07 -04:00
|
|
|
addressable_url: true,
|
2017-06-13 12:46:02 -04:00
|
|
|
if: :home_page_url_column_exists?
|
|
|
|
|
|
|
|
validates :help_page_support_url,
|
|
|
|
allow_blank: true,
|
2019-04-11 02:29:07 -04:00
|
|
|
addressable_url: true,
|
2017-06-13 12:46:02 -04:00
|
|
|
if: :help_page_support_url_column_exists?
|
2015-01-16 19:01:15 -05:00
|
|
|
|
2015-05-29 11:42:27 -04:00
|
|
|
validates :after_sign_out_path,
|
2015-12-28 15:21:34 -05:00
|
|
|
allow_blank: true,
|
2019-04-11 02:29:07 -04:00
|
|
|
addressable_url: true
|
2015-05-29 11:42:27 -04:00
|
|
|
|
2015-10-18 05:58:59 -04:00
|
|
|
validates :admin_notification_email,
|
2018-10-26 18:39:00 -04:00
|
|
|
devise_email: true,
|
2016-02-09 09:51:06 -05:00
|
|
|
allow_blank: true
|
2015-10-18 05:58:59 -04:00
|
|
|
|
2015-12-18 15:29:13 -05:00
|
|
|
validates :two_factor_grace_period,
|
2015-12-28 15:21:34 -05:00
|
|
|
numericality: { greater_than_or_equal_to: 0 }
|
|
|
|
|
|
|
|
validates :recaptcha_site_key,
|
|
|
|
presence: true,
|
|
|
|
if: :recaptcha_enabled
|
|
|
|
|
|
|
|
validates :recaptcha_private_key,
|
|
|
|
presence: true,
|
|
|
|
if: :recaptcha_enabled
|
2015-12-18 15:29:13 -05:00
|
|
|
|
2016-01-18 11:15:10 -05:00
|
|
|
validates :sentry_dsn,
|
|
|
|
presence: true,
|
|
|
|
if: :sentry_enabled
|
|
|
|
|
2017-04-28 08:23:34 -04:00
|
|
|
validates :clientside_sentry_dsn,
|
|
|
|
presence: true,
|
|
|
|
if: :clientside_sentry_enabled
|
|
|
|
|
2016-01-09 14:30:34 -05:00
|
|
|
validates :akismet_api_key,
|
|
|
|
presence: true,
|
|
|
|
if: :akismet_enabled
|
|
|
|
|
2017-02-17 08:04:10 -05:00
|
|
|
validates :unique_ips_limit_per_user,
|
|
|
|
numericality: { greater_than_or_equal_to: 1 },
|
|
|
|
presence: true,
|
|
|
|
if: :unique_ips_limit_enabled
|
|
|
|
|
|
|
|
validates :unique_ips_limit_time_window,
|
|
|
|
numericality: { greater_than_or_equal_to: 0 },
|
|
|
|
presence: true,
|
|
|
|
if: :unique_ips_limit_enabled
|
|
|
|
|
2016-11-28 12:41:29 -05:00
|
|
|
validates :plantuml_url,
|
|
|
|
presence: true,
|
|
|
|
if: :plantuml_enabled
|
|
|
|
|
2016-02-05 04:12:36 -05:00
|
|
|
validates :max_attachment_size,
|
|
|
|
presence: true,
|
|
|
|
numericality: { only_integer: true, greater_than: 0 }
|
|
|
|
|
2017-02-14 05:00:37 -05:00
|
|
|
validates :max_artifacts_size,
|
|
|
|
presence: true,
|
|
|
|
numericality: { only_integer: true, greater_than: 0 }
|
|
|
|
|
2017-02-24 04:28:24 -05:00
|
|
|
validates :default_artifacts_expire_in, presence: true, duration: true
|
2017-02-14 05:00:37 -05:00
|
|
|
|
2016-05-30 11:12:50 -04:00
|
|
|
validates :container_registry_token_expire_delay,
|
|
|
|
presence: true,
|
|
|
|
numericality: { only_integer: true, greater_than: 0 }
|
|
|
|
|
2016-11-03 10:12:20 -04:00
|
|
|
validates :repository_storages, presence: true
|
|
|
|
validate :check_repository_storages
|
2016-06-29 23:35:00 -04:00
|
|
|
|
2018-01-22 13:29:15 -05:00
|
|
|
validates :auto_devops_domain,
|
|
|
|
allow_blank: true,
|
|
|
|
hostname: { allow_numeric_hostname: true, require_valid_tld: true },
|
|
|
|
if: :auto_devops_enabled?
|
|
|
|
|
2016-06-29 15:30:27 -04:00
|
|
|
validates :enabled_git_access_protocol,
|
2016-06-20 21:40:56 -04:00
|
|
|
inclusion: { in: %w(ssh http), allow_blank: true, allow_nil: true }
|
2016-06-15 18:30:55 -04:00
|
|
|
|
2016-07-14 14:19:40 -04:00
|
|
|
validates :domain_blacklist,
|
2016-07-18 18:49:33 -04:00
|
|
|
presence: { message: 'Domain blacklist cannot be empty if Blacklist is enabled.' },
|
2016-07-14 14:19:40 -04:00
|
|
|
if: :domain_blacklist_enabled?
|
|
|
|
|
2016-10-27 08:59:52 -04:00
|
|
|
validates :housekeeping_incremental_repack_period,
|
|
|
|
presence: true,
|
|
|
|
numericality: { only_integer: true, greater_than: 0 }
|
|
|
|
|
|
|
|
validates :housekeeping_full_repack_period,
|
|
|
|
presence: true,
|
2017-08-21 05:51:45 -04:00
|
|
|
numericality: { only_integer: true, greater_than_or_equal_to: :housekeeping_incremental_repack_period }
|
2016-10-27 08:59:52 -04:00
|
|
|
|
|
|
|
validates :housekeeping_gc_period,
|
|
|
|
presence: true,
|
2017-08-21 05:51:45 -04:00
|
|
|
numericality: { only_integer: true, greater_than_or_equal_to: :housekeeping_full_repack_period }
|
2016-10-27 08:59:52 -04:00
|
|
|
|
2017-01-26 13:16:50 -05:00
|
|
|
validates :terminal_max_session_time,
|
|
|
|
presence: true,
|
|
|
|
numericality: { only_integer: true, greater_than_or_equal_to: 0 }
|
|
|
|
|
2017-04-03 09:17:04 -04:00
|
|
|
validates :polling_interval_multiplier,
|
|
|
|
presence: true,
|
|
|
|
numericality: { greater_than_or_equal_to: 0 }
|
|
|
|
|
2017-11-29 04:12:12 -05:00
|
|
|
validates :gitaly_timeout_default,
|
|
|
|
presence: true,
|
|
|
|
numericality: { only_integer: true, greater_than_or_equal_to: 0 }
|
|
|
|
|
|
|
|
validates :gitaly_timeout_medium,
|
|
|
|
presence: true,
|
|
|
|
numericality: { only_integer: true, greater_than_or_equal_to: 0 }
|
|
|
|
validates :gitaly_timeout_medium,
|
|
|
|
numericality: { less_than_or_equal_to: :gitaly_timeout_default },
|
|
|
|
if: :gitaly_timeout_default
|
|
|
|
validates :gitaly_timeout_medium,
|
|
|
|
numericality: { greater_than_or_equal_to: :gitaly_timeout_fast },
|
|
|
|
if: :gitaly_timeout_fast
|
|
|
|
|
|
|
|
validates :gitaly_timeout_fast,
|
|
|
|
presence: true,
|
|
|
|
numericality: { only_integer: true, greater_than_or_equal_to: 0 }
|
|
|
|
validates :gitaly_timeout_fast,
|
|
|
|
numericality: { less_than_or_equal_to: :gitaly_timeout_default },
|
|
|
|
if: :gitaly_timeout_default
|
|
|
|
|
2018-09-24 11:30:49 -04:00
|
|
|
validates :diff_max_patch_bytes,
|
|
|
|
presence: true,
|
|
|
|
numericality: { only_integer: true,
|
|
|
|
greater_than_or_equal_to: Gitlab::Git::Diff::DEFAULT_MAX_PATCH_BYTES,
|
|
|
|
less_than_or_equal_to: Gitlab::Git::Diff::MAX_PATCH_BYTES_UPPER_BOUND }
|
|
|
|
|
2018-08-30 08:53:06 -04:00
|
|
|
validates :user_default_internal_regex, js_regex: true, allow_nil: true
|
|
|
|
|
2018-11-07 06:00:21 -05:00
|
|
|
validates :commit_email_hostname, format: { with: /\A[^@]+\z/ }
|
|
|
|
|
2018-10-23 06:58:41 -04:00
|
|
|
validates :archive_builds_in_seconds,
|
|
|
|
allow_nil: true,
|
|
|
|
numericality: { only_integer: true, greater_than_or_equal_to: 1.day.seconds }
|
|
|
|
|
2019-01-31 06:28:31 -05:00
|
|
|
validates :local_markdown_version,
|
|
|
|
allow_nil: true,
|
|
|
|
numericality: { only_integer: true, greater_than_or_equal_to: 0, less_than: 65536 }
|
|
|
|
|
2017-08-25 09:08:48 -04:00
|
|
|
SUPPORTED_KEY_TYPES.each do |type|
|
2017-08-28 16:58:36 -04:00
|
|
|
validates :"#{type}_key_restriction", presence: true, key_restriction: { type: type }
|
2017-08-25 09:08:48 -04:00
|
|
|
end
|
2017-08-21 06:30:03 -04:00
|
|
|
|
2017-08-30 16:20:00 -04:00
|
|
|
validates :allowed_key_types, presence: true
|
|
|
|
|
2015-03-01 10:06:46 -05:00
|
|
|
validates_each :restricted_visibility_levels do |record, attr, value|
|
2017-02-07 09:16:46 -05:00
|
|
|
value&.each do |level|
|
2017-06-02 13:11:26 -04:00
|
|
|
unless Gitlab::VisibilityLevel.options.value?(level)
|
2019-04-12 08:28:07 -04:00
|
|
|
record.errors.add(attr, _("'%{level}' is not a valid visibility level") % { level: level })
|
2015-03-01 10:06:46 -05:00
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2015-08-12 02:13:20 -04:00
|
|
|
validates_each :import_sources do |record, attr, value|
|
2017-02-07 09:16:46 -05:00
|
|
|
value&.each do |source|
|
2017-06-02 13:11:26 -04:00
|
|
|
unless Gitlab::ImportSources.options.value?(source)
|
2019-04-12 08:28:07 -04:00
|
|
|
record.errors.add(attr, _("'%{source}' is not a import source") % { source: source })
|
2015-08-12 02:13:20 -04:00
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2018-04-24 12:28:04 -04:00
|
|
|
validate :terms_exist, if: :enforce_terms?
|
|
|
|
|
2019-04-09 11:38:58 -04:00
|
|
|
validates :external_authorization_service_default_label,
|
|
|
|
presence: true,
|
|
|
|
if: :external_authorization_service_enabled
|
|
|
|
|
|
|
|
validates :external_authorization_service_url,
|
2019-04-11 02:29:07 -04:00
|
|
|
addressable_url: true, allow_blank: true,
|
2019-04-09 11:38:58 -04:00
|
|
|
if: :external_authorization_service_enabled
|
|
|
|
|
|
|
|
validates :external_authorization_service_timeout,
|
|
|
|
numericality: { greater_than: 0, less_than_or_equal_to: 10 },
|
|
|
|
if: :external_authorization_service_enabled
|
|
|
|
|
|
|
|
validates :external_auth_client_key,
|
|
|
|
presence: true,
|
|
|
|
if: -> (setting) { setting.external_auth_client_cert.present? }
|
|
|
|
|
|
|
|
validates_with X509CertificateCredentialsValidator,
|
|
|
|
certificate: :external_auth_client_cert,
|
|
|
|
pkey: :external_auth_client_key,
|
|
|
|
pass: :external_auth_client_key_pass,
|
|
|
|
if: -> (setting) { setting.external_auth_client_cert.present? }
|
|
|
|
|
|
|
|
attr_encrypted :external_auth_client_key,
|
|
|
|
mode: :per_attribute_iv,
|
|
|
|
key: Settings.attr_encrypted_db_key_base_truncated,
|
|
|
|
algorithm: 'aes-256-gcm',
|
|
|
|
encode: true
|
|
|
|
|
|
|
|
attr_encrypted :external_auth_client_key_pass,
|
|
|
|
mode: :per_attribute_iv,
|
|
|
|
key: Settings.attr_encrypted_db_key_base_truncated,
|
|
|
|
algorithm: 'aes-256-gcm',
|
|
|
|
encode: true
|
|
|
|
|
2017-04-24 15:12:05 -04:00
|
|
|
before_validation :ensure_uuid!
|
2018-09-12 08:55:29 -04:00
|
|
|
before_validation :strip_sentry_values
|
2017-08-21 06:30:03 -04:00
|
|
|
|
2015-12-10 07:05:59 -05:00
|
|
|
before_save :ensure_runners_registration_token
|
2016-05-09 19:21:22 -04:00
|
|
|
before_save :ensure_health_check_access_token
|
2015-12-10 07:05:59 -05:00
|
|
|
|
2015-11-12 04:19:03 -05:00
|
|
|
after_commit do
|
2018-04-24 12:28:04 -04:00
|
|
|
reset_memoized_terms
|
2017-03-18 05:29:25 -04:00
|
|
|
end
|
2018-05-25 12:44:15 -04:00
|
|
|
after_commit :expire_performance_bar_allowed_user_ids_cache, if: -> { previous_changes.key?('performance_bar_allowed_group_id') }
|
2019-03-18 09:32:26 -04:00
|
|
|
|
|
|
|
def self.create_from_defaults
|
2019-04-10 06:03:37 -04:00
|
|
|
transaction(requires_new: true) do
|
|
|
|
super
|
|
|
|
end
|
2019-03-18 09:32:26 -04:00
|
|
|
rescue ActiveRecord::RecordNotUnique
|
|
|
|
# We already have an ApplicationSetting record, so just return it.
|
|
|
|
current_without_cache
|
|
|
|
end
|
2015-01-08 03:22:50 -05:00
|
|
|
end
|