summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorStan Hu <stanhu@gmail.com>2019-03-19 06:37:36 +0000
committerStan Hu <stanhu@gmail.com>2019-03-19 06:37:36 +0000
commit68aacd65ae3c53f3c1d2cf081adc89e3758c52de (patch)
treef581cb1d079a56b2dda90a4774c27af0b54d0b82
parent909161dd49514db5292ca551d6e288560c29f7b2 (diff)
parent7ce990b16181d05f57df4e89300c5db65b129747 (diff)
downloadgitlab-ce-68aacd65ae3c53f3c1d2cf081adc89e3758c52de.tar.gz
Merge branch '47491-gitlab-fakeapplicationsettings-doesn-t-respond-to-all-the-methods-applicationsetting-responds-to-itself' into 'master'
Introduce ApplicationSettingImplementation Closes #47491 See merge request gitlab-org/gitlab-ce!25803
-rw-r--r--app/models/application_setting.rb280
-rw-r--r--app/models/application_setting_implementation.rb281
-rw-r--r--app/models/concerns/token_authenticatable.rb19
-rw-r--r--lib/gitlab/fake_application_settings.rb19
-rw-r--r--spec/controllers/registrations_controller_spec.rb6
-rw-r--r--spec/lib/gitlab/fake_application_settings_spec.rb31
-rw-r--r--spec/models/application_setting_spec.rb232
-rw-r--r--spec/support/shared_examples/application_setting_examples.rb252
8 files changed, 575 insertions, 545 deletions
diff --git a/app/models/application_setting.rb b/app/models/application_setting.rb
index cd36c963ee5..56cc7c3784f 100644
--- a/app/models/application_setting.rb
+++ b/app/models/application_setting.rb
@@ -10,17 +10,11 @@ class ApplicationSetting < ActiveRecord::Base
add_authentication_token_field :runners_registration_token, encrypted: -> { Feature.enabled?(:application_settings_tokens_optional_encryption) ? :optional : :required }
add_authentication_token_field :health_check_access_token
- DOMAIN_LIST_SEPARATOR = %r{\s*[,;]\s* # comma or semicolon, optionally surrounded by whitespace
- | # or
- \s # any whitespace character
- | # or
- [\r\n] # any number of newline characters
- }x
-
- # Setting a key restriction to `-1` means that all keys of this type are
- # forbidden.
- FORBIDDEN_KEY_VALUE = KeyRestrictionValidator::FORBIDDEN
- SUPPORTED_KEY_TYPES = %i[rsa dsa ecdsa ed25519].freeze
+ # 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
serialize :restricted_visibility_levels # rubocop:disable Cop/ActiveRecordSerialize
serialize :import_sources # rubocop:disable Cop/ActiveRecordSerialize
@@ -42,8 +36,6 @@ class ApplicationSetting < ActiveRecord::Base
cache_markdown_field :shared_runners_text, pipeline: :plain_markdown
cache_markdown_field :after_sign_up_text
- attr_accessor :domain_whitelist_raw, :domain_blacklist_raw
-
default_value_for :id, 1
chronic_duration_attr_writer :archive_builds_in_human_readable, :archive_builds_in_seconds
@@ -231,266 +223,4 @@ class ApplicationSetting < ActiveRecord::Base
reset_memoized_terms
end
after_commit :expire_performance_bar_allowed_user_ids_cache, if: -> { previous_changes.key?('performance_bar_allowed_group_id') }
-
- def self.defaults
- {
- after_sign_up_text: nil,
- akismet_enabled: false,
- allow_local_requests_from_hooks_and_services: false,
- authorized_keys_enabled: true, # TODO default to false if the instance is configured to use AuthorizedKeysCommand
- container_registry_token_expire_delay: 5,
- default_artifacts_expire_in: '30 days',
- default_branch_protection: Settings.gitlab['default_branch_protection'],
- default_group_visibility: Settings.gitlab.default_projects_features['visibility_level'],
- default_project_visibility: Settings.gitlab.default_projects_features['visibility_level'],
- default_projects_limit: Settings.gitlab['default_projects_limit'],
- default_snippet_visibility: Settings.gitlab.default_projects_features['visibility_level'],
- disabled_oauth_sign_in_sources: [],
- domain_whitelist: Settings.gitlab['domain_whitelist'],
- dsa_key_restriction: 0,
- ecdsa_key_restriction: 0,
- ed25519_key_restriction: 0,
- first_day_of_week: 0,
- gitaly_timeout_default: 55,
- gitaly_timeout_fast: 10,
- gitaly_timeout_medium: 30,
- gravatar_enabled: Settings.gravatar['enabled'],
- help_page_hide_commercial_content: false,
- help_page_text: nil,
- hide_third_party_offers: false,
- housekeeping_bitmaps_enabled: true,
- housekeeping_enabled: true,
- housekeeping_full_repack_period: 50,
- housekeeping_gc_period: 200,
- housekeeping_incremental_repack_period: 10,
- import_sources: Settings.gitlab['import_sources'],
- max_artifacts_size: Settings.artifacts['max_size'],
- max_attachment_size: Settings.gitlab['max_attachment_size'],
- mirror_available: true,
- password_authentication_enabled_for_git: true,
- password_authentication_enabled_for_web: Settings.gitlab['signin_enabled'],
- performance_bar_allowed_group_id: nil,
- rsa_key_restriction: 0,
- plantuml_enabled: false,
- plantuml_url: nil,
- polling_interval_multiplier: 1,
- project_export_enabled: true,
- recaptcha_enabled: false,
- repository_checks_enabled: true,
- repository_storages: ['default'],
- require_two_factor_authentication: false,
- restricted_visibility_levels: Settings.gitlab['restricted_visibility_levels'],
- session_expire_delay: Settings.gitlab['session_expire_delay'],
- send_user_confirmation_email: false,
- shared_runners_enabled: Settings.gitlab_ci['shared_runners_enabled'],
- shared_runners_text: nil,
- sign_in_text: nil,
- signup_enabled: Settings.gitlab['signup_enabled'],
- terminal_max_session_time: 0,
- throttle_authenticated_api_enabled: false,
- throttle_authenticated_api_period_in_seconds: 3600,
- throttle_authenticated_api_requests_per_period: 7200,
- throttle_authenticated_web_enabled: false,
- throttle_authenticated_web_period_in_seconds: 3600,
- throttle_authenticated_web_requests_per_period: 7200,
- throttle_unauthenticated_enabled: false,
- throttle_unauthenticated_period_in_seconds: 3600,
- throttle_unauthenticated_requests_per_period: 3600,
- two_factor_grace_period: 48,
- unique_ips_limit_enabled: false,
- unique_ips_limit_per_user: 10,
- unique_ips_limit_time_window: 3600,
- usage_ping_enabled: Settings.gitlab['usage_ping_enabled'],
- instance_statistics_visibility_private: false,
- user_default_external: false,
- user_default_internal_regex: nil,
- user_show_add_ssh_key_message: true,
- usage_stats_set_by_user_id: nil,
- diff_max_patch_bytes: Gitlab::Git::Diff::DEFAULT_MAX_PATCH_BYTES,
- commit_email_hostname: default_commit_email_hostname,
- protected_ci_variables: false,
- local_markdown_version: 0
- }
- end
-
- def self.default_commit_email_hostname
- "users.noreply.#{Gitlab.config.gitlab.host}"
- end
-
- def self.create_from_defaults
- build_from_defaults.tap(&:save)
- end
-
- def self.human_attribute_name(attr, _options = {})
- if attr == :default_artifacts_expire_in
- 'Default artifacts expiration'
- else
- super
- end
- end
-
- def home_page_url_column_exists?
- ::Gitlab::Database.cached_column_exists?(:application_settings, :home_page_url)
- end
-
- def help_page_support_url_column_exists?
- ::Gitlab::Database.cached_column_exists?(:application_settings, :help_page_support_url)
- end
-
- def disabled_oauth_sign_in_sources=(sources)
- sources = (sources || []).map(&:to_s) & Devise.omniauth_providers.map(&:to_s)
- super(sources)
- end
-
- def domain_whitelist_raw
- self.domain_whitelist&.join("\n")
- end
-
- def domain_blacklist_raw
- self.domain_blacklist&.join("\n")
- end
-
- def domain_whitelist_raw=(values)
- self.domain_whitelist = []
- self.domain_whitelist = values.split(DOMAIN_LIST_SEPARATOR)
- self.domain_whitelist.reject! { |d| d.empty? }
- self.domain_whitelist
- end
-
- def domain_blacklist_raw=(values)
- self.domain_blacklist = []
- self.domain_blacklist = values.split(DOMAIN_LIST_SEPARATOR)
- self.domain_blacklist.reject! { |d| d.empty? }
- self.domain_blacklist
- end
-
- def domain_blacklist_file=(file)
- self.domain_blacklist_raw = file.read
- end
-
- def repository_storages
- Array(read_attribute(:repository_storages))
- end
-
- def commit_email_hostname
- super.presence || self.class.default_commit_email_hostname
- end
-
- def default_project_visibility=(level)
- super(Gitlab::VisibilityLevel.level_value(level))
- end
-
- def default_snippet_visibility=(level)
- super(Gitlab::VisibilityLevel.level_value(level))
- end
-
- def default_group_visibility=(level)
- super(Gitlab::VisibilityLevel.level_value(level))
- end
-
- def restricted_visibility_levels=(levels)
- super(levels&.map { |level| Gitlab::VisibilityLevel.level_value(level) })
- end
-
- def strip_sentry_values
- sentry_dsn.strip! if sentry_dsn.present?
- clientside_sentry_dsn.strip! if clientside_sentry_dsn.present?
- end
-
- def performance_bar_allowed_group
- Group.find_by_id(performance_bar_allowed_group_id)
- end
-
- # Return true if the Performance Bar is enabled for a given group
- def performance_bar_enabled
- performance_bar_allowed_group_id.present?
- end
-
- # Choose one of the available repository storage options. Currently all have
- # equal weighting.
- def pick_repository_storage
- repository_storages.sample
- end
-
- def runners_registration_token
- ensure_runners_registration_token!
- end
-
- def health_check_access_token
- ensure_health_check_access_token!
- end
-
- def usage_ping_can_be_configured?
- Settings.gitlab.usage_ping_enabled
- end
-
- def usage_ping_enabled
- usage_ping_can_be_configured? && super
- end
-
- def allowed_key_types
- SUPPORTED_KEY_TYPES.select do |type|
- key_restriction_for(type) != FORBIDDEN_KEY_VALUE
- end
- end
-
- def key_restriction_for(type)
- attr_name = "#{type}_key_restriction"
-
- has_attribute?(attr_name) ? public_send(attr_name) : FORBIDDEN_KEY_VALUE # rubocop:disable GitlabSecurity/PublicSend
- end
-
- def allow_signup?
- signup_enabled? && password_authentication_enabled_for_web?
- end
-
- def password_authentication_enabled?
- password_authentication_enabled_for_web? || password_authentication_enabled_for_git?
- end
-
- def user_default_internal_regex_enabled?
- user_default_external? && user_default_internal_regex.present?
- end
-
- def user_default_internal_regex_instance
- Regexp.new(user_default_internal_regex, Regexp::IGNORECASE)
- end
-
- delegate :terms, to: :latest_terms, allow_nil: true
- def latest_terms
- @latest_terms ||= Term.latest
- end
-
- def reset_memoized_terms
- @latest_terms = nil
- latest_terms
- end
-
- def archive_builds_older_than
- archive_builds_in_seconds.seconds.ago if archive_builds_in_seconds
- end
-
- private
-
- def ensure_uuid!
- return if uuid?
-
- self.uuid = SecureRandom.uuid
- end
-
- def check_repository_storages
- invalid = repository_storages - Gitlab.config.repositories.storages.keys
- errors.add(:repository_storages, "can't include: #{invalid.join(", ")}") unless
- invalid.empty?
- end
-
- def terms_exist
- return unless enforce_terms?
-
- errors.add(:terms, "You need to set terms to be enforced") unless terms.present?
- end
-
- def expire_performance_bar_allowed_user_ids_cache
- Gitlab::PerformanceBar.expire_allowed_user_ids_cache
- end
end
diff --git a/app/models/application_setting_implementation.rb b/app/models/application_setting_implementation.rb
new file mode 100644
index 00000000000..265aa1d4965
--- /dev/null
+++ b/app/models/application_setting_implementation.rb
@@ -0,0 +1,281 @@
+# frozen_string_literal: true
+
+module ApplicationSettingImplementation
+ extend ActiveSupport::Concern
+
+ DOMAIN_LIST_SEPARATOR = %r{\s*[,;]\s* # comma or semicolon, optionally surrounded by whitespace
+ | # or
+ \s # any whitespace character
+ | # or
+ [\r\n] # any number of newline characters
+ }x
+
+ # Setting a key restriction to `-1` means that all keys of this type are
+ # forbidden.
+ FORBIDDEN_KEY_VALUE = KeyRestrictionValidator::FORBIDDEN
+ SUPPORTED_KEY_TYPES = %i[rsa dsa ecdsa ed25519].freeze
+
+ class_methods do
+ def defaults
+ {
+ after_sign_up_text: nil,
+ akismet_enabled: false,
+ allow_local_requests_from_hooks_and_services: false,
+ authorized_keys_enabled: true, # TODO default to false if the instance is configured to use AuthorizedKeysCommand
+ container_registry_token_expire_delay: 5,
+ default_artifacts_expire_in: '30 days',
+ default_branch_protection: Settings.gitlab['default_branch_protection'],
+ default_group_visibility: Settings.gitlab.default_projects_features['visibility_level'],
+ default_project_visibility: Settings.gitlab.default_projects_features['visibility_level'],
+ default_projects_limit: Settings.gitlab['default_projects_limit'],
+ default_snippet_visibility: Settings.gitlab.default_projects_features['visibility_level'],
+ disabled_oauth_sign_in_sources: [],
+ domain_whitelist: Settings.gitlab['domain_whitelist'],
+ dsa_key_restriction: 0,
+ ecdsa_key_restriction: 0,
+ ed25519_key_restriction: 0,
+ first_day_of_week: 0,
+ gitaly_timeout_default: 55,
+ gitaly_timeout_fast: 10,
+ gitaly_timeout_medium: 30,
+ gravatar_enabled: Settings.gravatar['enabled'],
+ help_page_hide_commercial_content: false,
+ help_page_text: nil,
+ hide_third_party_offers: false,
+ housekeeping_bitmaps_enabled: true,
+ housekeeping_enabled: true,
+ housekeeping_full_repack_period: 50,
+ housekeeping_gc_period: 200,
+ housekeeping_incremental_repack_period: 10,
+ import_sources: Settings.gitlab['import_sources'],
+ max_artifacts_size: Settings.artifacts['max_size'],
+ max_attachment_size: Settings.gitlab['max_attachment_size'],
+ mirror_available: true,
+ password_authentication_enabled_for_git: true,
+ password_authentication_enabled_for_web: Settings.gitlab['signin_enabled'],
+ performance_bar_allowed_group_id: nil,
+ rsa_key_restriction: 0,
+ plantuml_enabled: false,
+ plantuml_url: nil,
+ polling_interval_multiplier: 1,
+ project_export_enabled: true,
+ recaptcha_enabled: false,
+ repository_checks_enabled: true,
+ repository_storages: ['default'],
+ require_two_factor_authentication: false,
+ restricted_visibility_levels: Settings.gitlab['restricted_visibility_levels'],
+ session_expire_delay: Settings.gitlab['session_expire_delay'],
+ send_user_confirmation_email: false,
+ shared_runners_enabled: Settings.gitlab_ci['shared_runners_enabled'],
+ shared_runners_text: nil,
+ sign_in_text: nil,
+ signup_enabled: Settings.gitlab['signup_enabled'],
+ terminal_max_session_time: 0,
+ throttle_authenticated_api_enabled: false,
+ throttle_authenticated_api_period_in_seconds: 3600,
+ throttle_authenticated_api_requests_per_period: 7200,
+ throttle_authenticated_web_enabled: false,
+ throttle_authenticated_web_period_in_seconds: 3600,
+ throttle_authenticated_web_requests_per_period: 7200,
+ throttle_unauthenticated_enabled: false,
+ throttle_unauthenticated_period_in_seconds: 3600,
+ throttle_unauthenticated_requests_per_period: 3600,
+ two_factor_grace_period: 48,
+ unique_ips_limit_enabled: false,
+ unique_ips_limit_per_user: 10,
+ unique_ips_limit_time_window: 3600,
+ usage_ping_enabled: Settings.gitlab['usage_ping_enabled'],
+ instance_statistics_visibility_private: false,
+ user_default_external: false,
+ user_default_internal_regex: nil,
+ user_show_add_ssh_key_message: true,
+ usage_stats_set_by_user_id: nil,
+ diff_max_patch_bytes: Gitlab::Git::Diff::DEFAULT_MAX_PATCH_BYTES,
+ commit_email_hostname: default_commit_email_hostname,
+ protected_ci_variables: false,
+ local_markdown_version: 0
+ }
+ end
+
+ def default_commit_email_hostname
+ "users.noreply.#{Gitlab.config.gitlab.host}"
+ end
+
+ def create_from_defaults
+ build_from_defaults.tap(&:save)
+ end
+
+ def human_attribute_name(attr, _options = {})
+ if attr == :default_artifacts_expire_in
+ 'Default artifacts expiration'
+ else
+ super
+ end
+ end
+ end
+
+ def home_page_url_column_exists?
+ ::Gitlab::Database.cached_column_exists?(:application_settings, :home_page_url)
+ end
+
+ def help_page_support_url_column_exists?
+ ::Gitlab::Database.cached_column_exists?(:application_settings, :help_page_support_url)
+ end
+
+ def disabled_oauth_sign_in_sources=(sources)
+ sources = (sources || []).map(&:to_s) & Devise.omniauth_providers.map(&:to_s)
+ super(sources)
+ end
+
+ def domain_whitelist_raw
+ self.domain_whitelist&.join("\n")
+ end
+
+ def domain_blacklist_raw
+ self.domain_blacklist&.join("\n")
+ end
+
+ def domain_whitelist_raw=(values)
+ self.domain_whitelist = []
+ self.domain_whitelist = values.split(DOMAIN_LIST_SEPARATOR)
+ self.domain_whitelist.reject! { |d| d.empty? }
+ self.domain_whitelist
+ end
+
+ def domain_blacklist_raw=(values)
+ self.domain_blacklist = []
+ self.domain_blacklist = values.split(DOMAIN_LIST_SEPARATOR)
+ self.domain_blacklist.reject! { |d| d.empty? }
+ self.domain_blacklist
+ end
+
+ def domain_blacklist_file=(file)
+ self.domain_blacklist_raw = file.read
+ end
+
+ def repository_storages
+ Array(read_attribute(:repository_storages))
+ end
+
+ def commit_email_hostname
+ super.presence || self.class.default_commit_email_hostname
+ end
+
+ def default_project_visibility=(level)
+ super(Gitlab::VisibilityLevel.level_value(level))
+ end
+
+ def default_snippet_visibility=(level)
+ super(Gitlab::VisibilityLevel.level_value(level))
+ end
+
+ def default_group_visibility=(level)
+ super(Gitlab::VisibilityLevel.level_value(level))
+ end
+
+ def restricted_visibility_levels=(levels)
+ super(levels&.map { |level| Gitlab::VisibilityLevel.level_value(level) })
+ end
+
+ def strip_sentry_values
+ sentry_dsn.strip! if sentry_dsn.present?
+ clientside_sentry_dsn.strip! if clientside_sentry_dsn.present?
+ end
+
+ def performance_bar_allowed_group
+ Group.find_by_id(performance_bar_allowed_group_id)
+ end
+
+ # Return true if the Performance Bar is enabled for a given group
+ def performance_bar_enabled
+ performance_bar_allowed_group_id.present?
+ end
+
+ # Choose one of the available repository storage options. Currently all have
+ # equal weighting.
+ def pick_repository_storage
+ repository_storages.sample
+ end
+
+ def runners_registration_token
+ ensure_runners_registration_token!
+ end
+
+ def health_check_access_token
+ ensure_health_check_access_token!
+ end
+
+ def usage_ping_can_be_configured?
+ Settings.gitlab.usage_ping_enabled
+ end
+
+ def usage_ping_enabled
+ usage_ping_can_be_configured? && super
+ end
+
+ def allowed_key_types
+ SUPPORTED_KEY_TYPES.select do |type|
+ key_restriction_for(type) != FORBIDDEN_KEY_VALUE
+ end
+ end
+
+ def key_restriction_for(type)
+ attr_name = "#{type}_key_restriction"
+
+ has_attribute?(attr_name) ? public_send(attr_name) : FORBIDDEN_KEY_VALUE # rubocop:disable GitlabSecurity/PublicSend
+ end
+
+ def allow_signup?
+ signup_enabled? && password_authentication_enabled_for_web?
+ end
+
+ def password_authentication_enabled?
+ password_authentication_enabled_for_web? || password_authentication_enabled_for_git?
+ end
+
+ def user_default_internal_regex_enabled?
+ user_default_external? && user_default_internal_regex.present?
+ end
+
+ def user_default_internal_regex_instance
+ Regexp.new(user_default_internal_regex, Regexp::IGNORECASE)
+ end
+
+ delegate :terms, to: :latest_terms, allow_nil: true
+ def latest_terms
+ @latest_terms ||= ApplicationSetting::Term.latest
+ end
+
+ def reset_memoized_terms
+ @latest_terms = nil # rubocop:disable Gitlab/ModuleWithInstanceVariables
+ latest_terms
+ end
+
+ def archive_builds_older_than
+ archive_builds_in_seconds.seconds.ago if archive_builds_in_seconds
+ end
+
+ private
+
+ def ensure_uuid!
+ return if uuid?
+
+ self.uuid = SecureRandom.uuid
+ end
+
+ def check_repository_storages
+ invalid = repository_storages - Gitlab.config.repositories.storages.keys
+ errors.add(:repository_storages, "can't include: #{invalid.join(", ")}") unless
+ invalid.empty?
+ end
+
+ def terms_exist
+ return unless enforce_terms?
+
+ errors.add(:terms, "You need to set terms to be enforced") unless terms.present?
+ end
+
+ def expire_performance_bar_allowed_user_ids_cache
+ Gitlab::PerformanceBar.expire_allowed_user_ids_cache
+ end
+end
diff --git a/app/models/concerns/token_authenticatable.rb b/app/models/concerns/token_authenticatable.rb
index f5bb559ceda..8c769be0489 100644
--- a/app/models/concerns/token_authenticatable.rb
+++ b/app/models/concerns/token_authenticatable.rb
@@ -26,34 +26,41 @@ module TokenAuthenticatable
end
end
- define_method(token_field) do
+ mod = token_authenticatable_module
+
+ mod.define_method(token_field) do
strategy.get_token(self)
end
- define_method("set_#{token_field}") do |token|
+ mod.define_method("set_#{token_field}") do |token|
strategy.set_token(self, token)
end
- define_method("ensure_#{token_field}") do
+ mod.define_method("ensure_#{token_field}") do
strategy.ensure_token(self)
end
# Returns a token, but only saves when the database is in read & write mode
- define_method("ensure_#{token_field}!") do
+ mod.define_method("ensure_#{token_field}!") do
strategy.ensure_token!(self)
end
# Resets the token, but only saves when the database is in read & write mode
- define_method("reset_#{token_field}!") do
+ mod.define_method("reset_#{token_field}!") do
strategy.reset_token!(self)
end
- define_method("#{token_field}_matches?") do |other_token|
+ mod.define_method("#{token_field}_matches?") do |other_token|
token = read_attribute(token_field)
token.present? && ActiveSupport::SecurityUtils.variable_size_secure_compare(other_token, token)
end
end
+ def token_authenticatable_module
+ @token_authenticatable_module ||=
+ const_set(:TokenAuthenticatable, Module.new).tap(&method(:include))
+ end
+
def token_authenticatable_fields
@token_authenticatable_fields ||= []
end
diff --git a/lib/gitlab/fake_application_settings.rb b/lib/gitlab/fake_application_settings.rb
index bd806269bf0..77f7d9490f3 100644
--- a/lib/gitlab/fake_application_settings.rb
+++ b/lib/gitlab/fake_application_settings.rb
@@ -7,6 +7,8 @@
# column type without parsing db/schema.rb.
module Gitlab
class FakeApplicationSettings < OpenStruct
+ include ApplicationSettingImplementation
+
# Mimic ActiveRecord predicate methods for boolean values
def self.define_predicate_methods(options)
options.each do |key, value|
@@ -26,20 +28,7 @@ module Gitlab
FakeApplicationSettings.define_predicate_methods(options)
end
- def key_restriction_for(type)
- 0
- end
-
- def allowed_key_types
- ApplicationSetting::SUPPORTED_KEY_TYPES
- end
-
- def pick_repository_storage
- repository_storages.sample
- end
-
- def commit_email_hostname
- super.presence || ApplicationSetting.default_commit_email_hostname
- end
+ alias_method :read_attribute, :[]
+ alias_method :has_attribute?, :[]
end
end
diff --git a/spec/controllers/registrations_controller_spec.rb b/spec/controllers/registrations_controller_spec.rb
index fd151e8a298..c1baf88778d 100644
--- a/spec/controllers/registrations_controller_spec.rb
+++ b/spec/controllers/registrations_controller_spec.rb
@@ -15,7 +15,7 @@ describe RegistrationsController do
context 'when send_user_confirmation_email is false' do
it 'signs the user in' do
- allow_any_instance_of(ApplicationSetting).to receive(:send_user_confirmation_email).and_return(false)
+ stub_application_setting(send_user_confirmation_email: false)
expect { post(:create, params: user_params) }.not_to change { ActionMailer::Base.deliveries.size }
expect(subject.current_user).not_to be_nil
@@ -24,7 +24,7 @@ describe RegistrationsController do
context 'when send_user_confirmation_email is true' do
it 'does not authenticate user and sends confirmation email' do
- allow_any_instance_of(ApplicationSetting).to receive(:send_user_confirmation_email).and_return(true)
+ stub_application_setting(send_user_confirmation_email: true)
post(:create, params: user_params)
@@ -35,7 +35,7 @@ describe RegistrationsController do
context 'when signup_enabled? is false' do
it 'redirects to sign_in' do
- allow_any_instance_of(ApplicationSetting).to receive(:signup_enabled?).and_return(false)
+ stub_application_setting(signup_enabled: false)
expect { post(:create, params: user_params) }.not_to change(User, :count)
expect(response).to redirect_to(new_user_session_path)
diff --git a/spec/lib/gitlab/fake_application_settings_spec.rb b/spec/lib/gitlab/fake_application_settings_spec.rb
index af12e13d36d..c81cb83d9f4 100644
--- a/spec/lib/gitlab/fake_application_settings_spec.rb
+++ b/spec/lib/gitlab/fake_application_settings_spec.rb
@@ -1,32 +1,33 @@
require 'spec_helper'
describe Gitlab::FakeApplicationSettings do
- let(:defaults) { { password_authentication_enabled_for_web: false, foobar: 'asdf', signup_enabled: true, 'test?' => 123 } }
+ let(:defaults) do
+ described_class.defaults.merge(
+ foobar: 'asdf',
+ 'test?' => 123
+ )
+ end
- subject { described_class.new(defaults) }
+ let(:setting) { described_class.new(defaults) }
it 'wraps OpenStruct variables properly' do
- expect(subject.password_authentication_enabled_for_web).to be_falsey
- expect(subject.signup_enabled).to be_truthy
- expect(subject.foobar).to eq('asdf')
+ expect(setting.password_authentication_enabled_for_web).to be_truthy
+ expect(setting.signup_enabled).to be_truthy
+ expect(setting.foobar).to eq('asdf')
end
it 'defines predicate methods' do
- expect(subject.password_authentication_enabled_for_web?).to be_falsey
- expect(subject.signup_enabled?).to be_truthy
- end
-
- it 'predicate method changes when value is updated' do
- subject.password_authentication_enabled_for_web = true
-
- expect(subject.password_authentication_enabled_for_web?).to be_truthy
+ expect(setting.password_authentication_enabled_for_web?).to be_truthy
+ expect(setting.signup_enabled?).to be_truthy
end
it 'does not define a predicate method' do
- expect(subject.foobar?).to be_nil
+ expect(setting.foobar?).to be_nil
end
it 'does not override an existing predicate method' do
- expect(subject.test?).to eq(123)
+ expect(setting.test?).to eq(123)
end
+
+ it_behaves_like 'application settings examples'
end
diff --git a/spec/models/application_setting_spec.rb b/spec/models/application_setting_spec.rb
index 789e14e8a20..314f0728b8e 100644
--- a/spec/models/application_setting_spec.rb
+++ b/spec/models/application_setting_spec.rb
@@ -117,14 +117,6 @@ describe ApplicationSetting do
it { expect(setting.repository_storages).to eq(['default']) }
end
- context '#commit_email_hostname' do
- it 'returns configured gitlab hostname if commit_email_hostname is not defined' do
- setting.update(commit_email_hostname: nil)
-
- expect(setting.commit_email_hostname).to eq("users.noreply.#{Gitlab.config.gitlab.host}")
- end
- end
-
context 'auto_devops_domain setting' do
context 'when auto_devops_enabled? is true' do
before do
@@ -182,15 +174,6 @@ describe ApplicationSetting do
it { is_expected.not_to allow_value("").for(:repository_storages) }
it { is_expected.not_to allow_value(nil).for(:repository_storages) }
end
-
- describe '.pick_repository_storage' do
- it 'uses Array#sample to pick a random storage' do
- array = double('array', sample: 'random')
- expect(setting).to receive(:repository_storages).and_return(array)
-
- expect(setting.pick_repository_storage).to eq('random')
- end
- end
end
context 'housekeeping settings' do
@@ -367,65 +350,6 @@ describe ApplicationSetting do
end
end
- context 'restricted signup domains' do
- it 'sets single domain' do
- setting.domain_whitelist_raw = 'example.com'
- expect(setting.domain_whitelist).to eq(['example.com'])
- end
-
- it 'sets multiple domains with spaces' do
- setting.domain_whitelist_raw = 'example.com *.example.com'
- expect(setting.domain_whitelist).to eq(['example.com', '*.example.com'])
- end
-
- it 'sets multiple domains with newlines and a space' do
- setting.domain_whitelist_raw = "example.com\n *.example.com"
- expect(setting.domain_whitelist).to eq(['example.com', '*.example.com'])
- end
-
- it 'sets multiple domains with commas' do
- setting.domain_whitelist_raw = "example.com, *.example.com"
- expect(setting.domain_whitelist).to eq(['example.com', '*.example.com'])
- end
- end
-
- context 'blacklisted signup domains' do
- it 'sets single domain' do
- setting.domain_blacklist_raw = 'example.com'
- expect(setting.domain_blacklist).to contain_exactly('example.com')
- end
-
- it 'sets multiple domains with spaces' do
- setting.domain_blacklist_raw = 'example.com *.example.com'
- expect(setting.domain_blacklist).to contain_exactly('example.com', '*.example.com')
- end
-
- it 'sets multiple domains with newlines and a space' do
- setting.domain_blacklist_raw = "example.com\n *.example.com"
- expect(setting.domain_blacklist).to contain_exactly('example.com', '*.example.com')
- end
-
- it 'sets multiple domains with commas' do
- setting.domain_blacklist_raw = "example.com, *.example.com"
- expect(setting.domain_blacklist).to contain_exactly('example.com', '*.example.com')
- end
-
- it 'sets multiple domains with semicolon' do
- setting.domain_blacklist_raw = "example.com; *.example.com"
- expect(setting.domain_blacklist).to contain_exactly('example.com', '*.example.com')
- end
-
- it 'sets multiple domains with mixture of everything' do
- setting.domain_blacklist_raw = "example.com; *.example.com\n test.com\sblock.com yes.com"
- expect(setting.domain_blacklist).to contain_exactly('example.com', '*.example.com', 'test.com', 'block.com', 'yes.com')
- end
-
- it 'sets multiple domain with file' do
- setting.domain_blacklist_file = File.open(Rails.root.join('spec/fixtures/', 'domain_blacklist.txt'))
- expect(setting.domain_blacklist).to contain_exactly('example.com', 'test.com', 'foo.bar')
- end
- end
-
describe 'performance bar settings' do
describe 'performance_bar_allowed_group' do
context 'with no performance_bar_allowed_group_id saved' do
@@ -462,142 +386,6 @@ describe ApplicationSetting do
end
end
- describe 'usage ping settings' do
- context 'when the usage ping is disabled in gitlab.yml' do
- before do
- allow(Settings.gitlab).to receive(:usage_ping_enabled).and_return(false)
- end
-
- it 'does not allow the usage ping to be configured' do
- expect(setting.usage_ping_can_be_configured?).to be_falsey
- end
-
- context 'when the usage ping is disabled in the DB' do
- before do
- setting.usage_ping_enabled = false
- end
-
- it 'returns false for usage_ping_enabled' do
- expect(setting.usage_ping_enabled).to be_falsey
- end
- end
-
- context 'when the usage ping is enabled in the DB' do
- before do
- setting.usage_ping_enabled = true
- end
-
- it 'returns false for usage_ping_enabled' do
- expect(setting.usage_ping_enabled).to be_falsey
- end
- end
- end
-
- context 'when the usage ping is enabled in gitlab.yml' do
- before do
- allow(Settings.gitlab).to receive(:usage_ping_enabled).and_return(true)
- end
-
- it 'allows the usage ping to be configured' do
- expect(setting.usage_ping_can_be_configured?).to be_truthy
- end
-
- context 'when the usage ping is disabled in the DB' do
- before do
- setting.usage_ping_enabled = false
- end
-
- it 'returns false for usage_ping_enabled' do
- expect(setting.usage_ping_enabled).to be_falsey
- end
- end
-
- context 'when the usage ping is enabled in the DB' do
- before do
- setting.usage_ping_enabled = true
- end
-
- it 'returns true for usage_ping_enabled' do
- expect(setting.usage_ping_enabled).to be_truthy
- end
- end
- end
- end
-
- describe '#allowed_key_types' do
- it 'includes all key types by default' do
- expect(setting.allowed_key_types).to contain_exactly(*described_class::SUPPORTED_KEY_TYPES)
- end
-
- it 'excludes disabled key types' do
- expect(setting.allowed_key_types).to include(:ed25519)
-
- setting.ed25519_key_restriction = described_class::FORBIDDEN_KEY_VALUE
-
- expect(setting.allowed_key_types).not_to include(:ed25519)
- end
- end
-
- describe '#key_restriction_for' do
- it 'returns the restriction value for recognised types' do
- setting.rsa_key_restriction = 1024
-
- expect(setting.key_restriction_for(:rsa)).to eq(1024)
- end
-
- it 'allows types to be passed as a string' do
- setting.rsa_key_restriction = 1024
-
- expect(setting.key_restriction_for('rsa')).to eq(1024)
- end
-
- it 'returns forbidden for unrecognised type' do
- expect(setting.key_restriction_for(:foo)).to eq(described_class::FORBIDDEN_KEY_VALUE)
- end
- end
-
- describe '#allow_signup?' do
- it 'returns true' do
- expect(setting.allow_signup?).to be_truthy
- end
-
- it 'returns false if signup is disabled' do
- allow(setting).to receive(:signup_enabled?).and_return(false)
-
- expect(setting.allow_signup?).to be_falsey
- end
-
- it 'returns false if password authentication is disabled for the web interface' do
- allow(setting).to receive(:password_authentication_enabled_for_web?).and_return(false)
-
- expect(setting.allow_signup?).to be_falsey
- end
- end
-
- describe '#user_default_internal_regex_enabled?' do
- using RSpec::Parameterized::TableSyntax
-
- where(:user_default_external, :user_default_internal_regex, :result) do
- false | nil | false
- false | '' | false
- false | '^(?:(?!\.ext@).)*$\r?\n?' | false
- true | '' | false
- true | nil | false
- true | '^(?:(?!\.ext@).)*$\r?\n?' | true
- end
-
- with_them do
- before do
- setting.update(user_default_external: user_default_external)
- setting.update(user_default_internal_regex: user_default_internal_regex)
- end
-
- subject { setting.user_default_internal_regex_enabled? }
-
- it { is_expected.to eq(result) }
- end
- end
-
context 'diff limit settings' do
describe '#diff_max_patch_bytes' do
context 'validations' do
@@ -613,23 +401,5 @@ describe ApplicationSetting do
end
end
- describe '#archive_builds_older_than' do
- subject { setting.archive_builds_older_than }
-
- context 'when the archive_builds_in_seconds is set' do
- before do
- setting.archive_builds_in_seconds = 3600
- end
-
- it { is_expected.to be_within(1.minute).of(1.hour.ago) }
- end
-
- context 'when the archive_builds_in_seconds is set' do
- before do
- setting.archive_builds_in_seconds = nil
- end
-
- it { is_expected.to be_nil }
- end
- end
+ it_behaves_like 'application settings examples'
end
diff --git a/spec/support/shared_examples/application_setting_examples.rb b/spec/support/shared_examples/application_setting_examples.rb
new file mode 100644
index 00000000000..e7ec24c5b7e
--- /dev/null
+++ b/spec/support/shared_examples/application_setting_examples.rb
@@ -0,0 +1,252 @@
+# frozen_string_literal: true
+
+RSpec.shared_examples 'application settings examples' do
+ context 'restricted signup domains' do
+ it 'sets single domain' do
+ setting.domain_whitelist_raw = 'example.com'
+ expect(setting.domain_whitelist).to eq(['example.com'])
+ end
+
+ it 'sets multiple domains with spaces' do
+ setting.domain_whitelist_raw = 'example.com *.example.com'
+ expect(setting.domain_whitelist).to eq(['example.com', '*.example.com'])
+ end
+
+ it 'sets multiple domains with newlines and a space' do
+ setting.domain_whitelist_raw = "example.com\n *.example.com"
+ expect(setting.domain_whitelist).to eq(['example.com', '*.example.com'])
+ end
+
+ it 'sets multiple domains with commas' do
+ setting.domain_whitelist_raw = "example.com, *.example.com"
+ expect(setting.domain_whitelist).to eq(['example.com', '*.example.com'])
+ end
+ end
+
+ context 'blacklisted signup domains' do
+ it 'sets single domain' do
+ setting.domain_blacklist_raw = 'example.com'
+ expect(setting.domain_blacklist).to contain_exactly('example.com')
+ end
+
+ it 'sets multiple domains with spaces' do
+ setting.domain_blacklist_raw = 'example.com *.example.com'
+ expect(setting.domain_blacklist).to contain_exactly('example.com', '*.example.com')
+ end
+
+ it 'sets multiple domains with newlines and a space' do
+ setting.domain_blacklist_raw = "example.com\n *.example.com"
+ expect(setting.domain_blacklist).to contain_exactly('example.com', '*.example.com')
+ end
+
+ it 'sets multiple domains with commas' do
+ setting.domain_blacklist_raw = "example.com, *.example.com"
+ expect(setting.domain_blacklist).to contain_exactly('example.com', '*.example.com')
+ end
+
+ it 'sets multiple domains with semicolon' do
+ setting.domain_blacklist_raw = "example.com; *.example.com"
+ expect(setting.domain_blacklist).to contain_exactly('example.com', '*.example.com')
+ end
+
+ it 'sets multiple domains with mixture of everything' do
+ setting.domain_blacklist_raw = "example.com; *.example.com\n test.com\sblock.com yes.com"
+ expect(setting.domain_blacklist).to contain_exactly('example.com', '*.example.com', 'test.com', 'block.com', 'yes.com')
+ end
+
+ it 'sets multiple domain with file' do
+ setting.domain_blacklist_file = File.open(Rails.root.join('spec/fixtures/', 'domain_blacklist.txt'))
+ expect(setting.domain_blacklist).to contain_exactly('example.com', 'test.com', 'foo.bar')
+ end
+ end
+
+ describe 'usage ping settings' do
+ context 'when the usage ping is disabled in gitlab.yml' do
+ before do
+ allow(Settings.gitlab).to receive(:usage_ping_enabled).and_return(false)
+ end
+
+ it 'does not allow the usage ping to be configured' do
+ expect(setting.usage_ping_can_be_configured?).to be_falsey
+ end
+
+ context 'when the usage ping is disabled in the DB' do
+ before do
+ setting.usage_ping_enabled = false
+ end
+
+ it 'returns false for usage_ping_enabled' do
+ expect(setting.usage_ping_enabled).to be_falsey
+ end
+ end
+
+ context 'when the usage ping is enabled in the DB' do
+ before do
+ setting.usage_ping_enabled = true
+ end
+
+ it 'returns false for usage_ping_enabled' do
+ expect(setting.usage_ping_enabled).to be_falsey
+ end
+ end
+ end
+
+ context 'when the usage ping is enabled in gitlab.yml' do
+ before do
+ allow(Settings.gitlab).to receive(:usage_ping_enabled).and_return(true)
+ end
+
+ it 'allows the usage ping to be configured' do
+ expect(setting.usage_ping_can_be_configured?).to be_truthy
+ end
+
+ context 'when the usage ping is disabled in the DB' do
+ before do
+ setting.usage_ping_enabled = false
+ end
+
+ it 'returns false for usage_ping_enabled' do
+ expect(setting.usage_ping_enabled).to be_falsey
+ end
+ end
+
+ context 'when the usage ping is enabled in the DB' do
+ before do
+ setting.usage_ping_enabled = true
+ end
+
+ it 'returns true for usage_ping_enabled' do
+ expect(setting.usage_ping_enabled).to be_truthy
+ end
+ end
+ end
+ end
+
+ describe '#allowed_key_types' do
+ it 'includes all key types by default' do
+ expect(setting.allowed_key_types).to contain_exactly(*described_class::SUPPORTED_KEY_TYPES)
+ end
+
+ it 'excludes disabled key types' do
+ expect(setting.allowed_key_types).to include(:ed25519)
+
+ setting.ed25519_key_restriction = described_class::FORBIDDEN_KEY_VALUE
+
+ expect(setting.allowed_key_types).not_to include(:ed25519)
+ end
+ end
+
+ describe '#key_restriction_for' do
+ it 'returns the restriction value for recognised types' do
+ setting.rsa_key_restriction = 1024
+
+ expect(setting.key_restriction_for(:rsa)).to eq(1024)
+ end
+
+ it 'allows types to be passed as a string' do
+ setting.rsa_key_restriction = 1024
+
+ expect(setting.key_restriction_for('rsa')).to eq(1024)
+ end
+
+ it 'returns forbidden for unrecognised type' do
+ expect(setting.key_restriction_for(:foo)).to eq(described_class::FORBIDDEN_KEY_VALUE)
+ end
+ end
+
+ describe '#allow_signup?' do
+ it 'returns true' do
+ expect(setting.allow_signup?).to be_truthy
+ end
+
+ it 'returns false if signup is disabled' do
+ allow(setting).to receive(:signup_enabled?).and_return(false)
+
+ expect(setting.allow_signup?).to be_falsey
+ end
+
+ it 'returns false if password authentication is disabled for the web interface' do
+ allow(setting).to receive(:password_authentication_enabled_for_web?).and_return(false)
+
+ expect(setting.allow_signup?).to be_falsey
+ end
+ end
+
+ describe '#pick_repository_storage' do
+ it 'uses Array#sample to pick a random storage' do
+ array = double('array', sample: 'random')
+ expect(setting).to receive(:repository_storages).and_return(array)
+
+ expect(setting.pick_repository_storage).to eq('random')
+ end
+ end
+
+ describe '#user_default_internal_regex_enabled?' do
+ using RSpec::Parameterized::TableSyntax
+
+ where(:user_default_external, :user_default_internal_regex, :result) do
+ false | nil | false
+ false | '' | false
+ false | '^(?:(?!\.ext@).)*$\r?\n?' | false
+ true | '' | false
+ true | nil | false
+ true | '^(?:(?!\.ext@).)*$\r?\n?' | true
+ end
+
+ with_them do
+ before do
+ setting.user_default_external = user_default_external
+ setting.user_default_internal_regex = user_default_internal_regex
+ end
+
+ subject { setting.user_default_internal_regex_enabled? }
+
+ it { is_expected.to eq(result) }
+ end
+ end
+
+ describe '#archive_builds_older_than' do
+ subject { setting.archive_builds_older_than }
+
+ context 'when the archive_builds_in_seconds is set' do
+ before do
+ setting.archive_builds_in_seconds = 3600
+ end
+
+ it { is_expected.to be_within(1.minute).of(1.hour.ago) }
+ end
+
+ context 'when the archive_builds_in_seconds is set' do
+ before do
+ setting.archive_builds_in_seconds = nil
+ end
+
+ it { is_expected.to be_nil }
+ end
+ end
+
+ describe '#commit_email_hostname' do
+ context 'when the value is provided' do
+ before do
+ setting.commit_email_hostname = 'localhost'
+ end
+
+ it 'returns the provided value' do
+ expect(setting.commit_email_hostname).to eq('localhost')
+ end
+ end
+
+ context 'when the value is not provided' do
+ it 'returns the default from the class' do
+ expect(setting.commit_email_hostname)
+ .to eq(described_class.default_commit_email_hostname)
+ end
+ end
+ end
+
+ it 'predicate method changes when value is updated' do
+ setting.password_authentication_enabled_for_web = false
+
+ expect(setting.password_authentication_enabled_for_web?).to be_falsey
+ end
+end