Class: ApplicationSetting

Inherits:
ApplicationRecord show all
Includes:
ApplicationSettingImplementation, CacheMarkdownField, CacheableAttributes, ChronicDurationAttribute, IgnorableColumns, Sanitizable, TokenAuthenticatable
Defined in:
app/models/application_setting.rb,
app/models/application_setting/term.rb,
app/policies/application_setting/term_policy.rb

Defined Under Namespace

Classes: Term, TermPolicy

Constant Summary collapse

INSTANCE_REVIEW_MIN_USERS =
50
GRAFANA_URL_ERROR_MESSAGE =
'Please check your Grafana URL setting in ' \
'Admin Area > Settings > Metrics and profiling > Metrics - Grafana'
KROKI_URL_ERROR_MESSAGE =
'Please check your Kroki URL setting in ' \
'Admin Area > Settings > General > Kroki'
Recursion =
Class.new(RuntimeError)

Constants included from ApplicationSettingImplementation

ApplicationSettingImplementation::DEFAULT_MINIMUM_PASSWORD_LENGTH, ApplicationSettingImplementation::DEFAULT_PROTECTED_PATHS, ApplicationSettingImplementation::FORBIDDEN_KEY_VALUE, ApplicationSettingImplementation::STRING_LIST_SEPARATOR, ApplicationSettingImplementation::VALID_RUNNER_REGISTRAR_TYPES

Constants included from CacheMarkdownField

CacheMarkdownField::INVALIDATED_BY

Constants inherited from ApplicationRecord

ApplicationRecord::MAX_PLUCK

Class Method Summary collapse

Instance Method Summary collapse

Methods included from ApplicationSettingImplementation

#add_to_outbound_local_requests_whitelist, #allow_signup?, #allowed_key_types, #archive_builds_older_than, #asset_proxy_allowlist, #asset_proxy_whitelist=, #commit_email_hostname, #default_group_visibility=, #default_project_visibility=, #default_snippet_visibility=, #disabled_oauth_sign_in_sources=, #domain_allowlist_raw, #domain_allowlist_raw=, #domain_denylist_file=, #domain_denylist_raw, #domain_denylist_raw=, #health_check_access_token, #help_page_support_url_column_exists?, #home_page_url_column_exists?, #key_restriction_for, #latest_terms, #normalized_repository_storage_weights, #notes_create_limit_allowlist_raw, #notes_create_limit_allowlist_raw=, #outbound_local_requests_allowlist_arrays, #outbound_local_requests_allowlist_raw, #outbound_local_requests_allowlist_raw=, #password_authentication_enabled?, #performance_bar_allowed_group, #performance_bar_enabled, #pick_repository_storage, #protected_paths_raw, #protected_paths_raw=, #repository_storages, #reset_memoized_terms, #restricted_visibility_levels=, #runners_registration_token, #static_objects_external_storage_auth_token=, #static_objects_external_storage_enabled?, #usage_ping_can_be_configured?, #usage_ping_enabled, #usage_ping_features_enabled?, #user_default_internal_regex_enabled?, #user_default_internal_regex_instance, #users_get_by_id_limit_allowlist_raw, #users_get_by_id_limit_allowlist_raw=, #web_ide_clientside_preview_bundler_url

Methods included from Gitlab::Utils::StrongMemoize

#clear_memoization, #strong_memoize, #strong_memoized?

Methods included from ChronicDurationAttribute

#chronic_duration_attributes, #output_chronic_duration_attribute

Methods included from CacheMarkdownField

#attribute_invalidated?, #banzai_render_context, #cached_html_for, #cached_html_up_to_date?, #can_cache_field?, #invalidated_markdown_cache?, #latest_cached_markdown_version, #local_version, #mentionable_attributes_changed?, #parent_user, #refresh_markdown_cache, #refresh_markdown_cache!, #rendered_field_content, #skip_project_check?, #store_mentions!, #updated_cached_html_for

Methods included from CacheableAttributes

#cache!

Methods inherited from ApplicationRecord

cached_column_list, #create_or_load_association, declarative_enum, default_select_columns, id_in, id_not_in, iid_in, pluck_primary_key, primary_key_in, #readable_by?, safe_ensure_unique, safe_find_or_create_by, safe_find_or_create_by!, #to_ability_name, underscore, where_exists, where_not_exists, with_fast_read_statement_timeout, without_order

Methods included from SensitiveSerializableHash

#serializable_hash

Class Method Details

.cache_backendObject

By default, the backend is Rails.cache, which uses ActiveSupport::Cache::RedisStore. Since loading ApplicationSetting can cause a significant amount of load on Redis, let's cache it in memory.


723
724
725
# File 'app/models/application_setting.rb', line 723

def self.cache_backend
  Gitlab::ProcessMemoryCache.cache_backend
end

.check_schema!Object

Due to the frequency with which settings are accessed, it is likely that during a backup restore a running GitLab process will insert a new `application_settings` row before the constraints have been added to the table. This would add an extra row with ID 1 and prevent the primary key constraint from being added, which made ActiveRecord throw a IrreversibleOrderError anytime the settings were accessed (gitlab.com/gitlab-org/gitlab/-/issues/36405). To prevent this from happening, we do a sanity check that the primary key constraint is present before inserting a new entry.


713
714
715
716
717
# File 'app/models/application_setting.rb', line 713

def self.check_schema!
  return if connection.primary_key(self.table_name).present?

  raise "The `#{self.table_name}` table is missing a primary key constraint in the database schema"
end

.create_from_defaultsObject


678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
# File 'app/models/application_setting.rb', line 678

def self.create_from_defaults
  # this is posssible if calls to create the record depend on application
  # settings themselves. This was seen in the case of a feature flag called by
  # `transaction` that ended up requiring application settings to determine metrics behavior.
  # If something like that happens, we break the loop here, and let the caller decide how to manage it.
  raise Recursion if Thread.current[:application_setting_create_from_defaults]

  Thread.current[:application_setting_create_from_defaults] = true

  check_schema!

  transaction(requires_new: true) do # rubocop:disable Performance/ActiveRecordSubtransactions
    super
  end
rescue ActiveRecord::RecordNotUnique
  # We already have an ApplicationSetting record, so just return it.
  current_without_cache
ensure
  Thread.current[:application_setting_create_from_defaults] = nil
end

.find_or_create_without_cacheObject


699
700
701
# File 'app/models/application_setting.rb', line 699

def self.find_or_create_without_cache
  current_without_cache || create_from_defaults
end

.kroki_formats_attributesObject


41
42
43
44
45
46
47
48
49
50
51
52
53
# File 'app/models/application_setting.rb', line 41

def self.kroki_formats_attributes
  {
    blockdiag: {
      label: 'BlockDiag (includes BlockDiag, SeqDiag, ActDiag, NwDiag, PacketDiag, and RackDiag)'
    },
    bpmn: {
      label: 'BPMN'
    },
    excalidraw: {
      label: 'Excalidraw'
    }
  }
end

Instance Method Details

#grafana_url_absolute?Boolean

Returns:

  • (Boolean)

648
649
650
# File 'app/models/application_setting.rb', line 648

def grafana_url_absolute?
  parsed_grafana_url&.absolute?
end

#instance_review_permitted?Boolean

Returns:

  • (Boolean)

668
669
670
671
672
673
674
# File 'app/models/application_setting.rb', line 668

def instance_review_permitted?
  users_count = Rails.cache.fetch('limited_users_count', expires_in: 1.day) do
    ::User.limit(INSTANCE_REVIEW_MIN_USERS + 1).count(:all)
  end

  users_count >= INSTANCE_REVIEW_MIN_USERS
end

#kroki_format_supported?(diagram_type) ⇒ Boolean

Returns:

  • (Boolean)

737
738
739
740
741
742
743
744
745
746
747
748
# File 'app/models/application_setting.rb', line 737

def kroki_format_supported?(diagram_type)
  case diagram_type
  when 'excalidraw'
    return kroki_formats_excalidraw
  when 'bpmn'
    return kroki_formats_bpmn
  end

  return kroki_formats_blockdiag if ::Gitlab::Kroki::BLOCKDIAG_FORMATS.include?(diagram_type)

  ::AsciidoctorExtensions::Kroki::SUPPORTED_DIAGRAM_NAMES.include?(diagram_type)
end

#kroki_url_absolute?Boolean

Returns:

  • (Boolean)

656
657
658
# File 'app/models/application_setting.rb', line 656

def kroki_url_absolute?
  parsed_kroki_url&.absolute?
end

#normalize_default_branch_nameObject


664
665
666
# File 'app/models/application_setting.rb', line 664

def normalize_default_branch_name
  self.default_branch_name = default_branch_name.presence
end

#recaptcha_or_login_protection_enabledObject


727
728
729
# File 'app/models/application_setting.rb', line 727

def 
  recaptcha_enabled || 
end

#sourcegraph_url_is_com?Boolean

Returns:

  • (Boolean)

660
661
662
# File 'app/models/application_setting.rb', line 660

def sourcegraph_url_is_com?
  !!(sourcegraph_url =~ %r{\Ahttps://(www\.)?sourcegraph\.com})
end

#validate_grafana_urlObject


644
645
646
# File 'app/models/application_setting.rb', line 644

def validate_grafana_url
  validate_url(parsed_grafana_url, :grafana_url, GRAFANA_URL_ERROR_MESSAGE)
end

#validate_kroki_urlObject


652
653
654
# File 'app/models/application_setting.rb', line 652

def validate_kroki_url
  validate_url(parsed_kroki_url, :kroki_url, KROKI_URL_ERROR_MESSAGE)
end