From 97e7a9605b29be0cf7db0652c8abb3844f64846f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Oliver=20G=C3=BCnther?= Date: Thu, 12 Jan 2023 09:26:46 +0100 Subject: [PATCH] Add description field to settings --- config/constants/settings/definition.rb | 19 ++- config/constants/settings/definitions.rb | 142 ++++++++++++++++++----- lib/tasks/setting.rake | 3 +- 3 files changed, 132 insertions(+), 32 deletions(-) diff --git a/config/constants/settings/definition.rb b/config/constants/settings/definition.rb index 952444e64e..5749125176 100644 --- a/config/constants/settings/definition.rb +++ b/config/constants/settings/definition.rb @@ -36,10 +36,12 @@ module Settings :env_alias attr_writer :value, + :description, :allowed def initialize(name, default:, + description: nil, format: nil, writable: true, allowed: nil, @@ -52,6 +54,7 @@ module Settings self.writable = writable self.allowed = allowed self.env_alias = env_alias + self.description = description.presence || :"setting_#{name}" end def default @@ -62,6 +65,14 @@ module Settings cast(@value) end + def description + if @description.is_a?(Symbol) + I18n.t(@description, default: nil) + else + @description + end + end + def serialized? %i[array hash].include?(format) end @@ -124,6 +135,7 @@ module Settings # @param [Object] default The default value the setting has if not overridden. # @param [nil] format The format the value is in e.g. symbol, array, hash, string. If a value is present, # the format is deferred. + # @param [nil] description A human-readable description of this setting. # @param [TrueClass] writable Whether the value can be set in the UI. In case the value is set via file or ENV var, # this will be set to false later on and UI elements that refer to the definition will be disabled. # @param [nil] allowed The array of allowed values that can be assigned to the definition. @@ -136,6 +148,7 @@ module Settings def add(name, default:, format: nil, + description: nil, writable: true, allowed: nil, env_alias: nil) @@ -145,6 +158,7 @@ module Settings definition = new(name, format:, + description:, default:, writable:, allowed:, @@ -274,8 +288,8 @@ module Settings env_var_hash_part .scan(/(?:[a-zA-Z0-9]|__)+/) .map do |seg| - unescape_underscores(seg.downcase) - end + unescape_underscores(seg.downcase) + end end # takes the path provided and transforms it into a deeply nested hash @@ -329,6 +343,7 @@ module Settings env_name_alias(definition) ].compact end + public :possible_env_names def env_name_nested(definition) diff --git a/config/constants/settings/definitions.rb b/config/constants/settings/definitions.rb index cb8569221c..b3c3f235b9 100644 --- a/config/constants/settings/definitions.rb +++ b/config/constants/settings/definitions.rb @@ -39,24 +39,29 @@ Settings::Definition.define do add :after_first_login_redirect_url, format: :string, + description: 'URL users logging in for the first time will be redirected to (e.g., a help screen)', default: nil, writable: false add :after_login_default_redirect_url, + description: 'Override URL to which logged in users are redirected instead of the My page', format: :string, default: nil, writable: false add :apiv3_cors_enabled, + description: 'Enable CORS headers for APIv3 server responses', default: false add :apiv3_cors_origins, default: [] add :apiv3_docs_enabled, + description: 'Enable interactive APIv3 documentation as part of the application', default: true add :apiv3_enable_basic_auth, + description: 'Enable API token or global basic authentication for APIv3 requests', default: true, writable: false @@ -77,21 +82,25 @@ Settings::Definition.define do # Carrierwave storage type. Possible values are, among others, :file and :fog. # The latter requires further configuration. add :attachments_storage, + description: 'File storage configuration', default: :file, format: :symbol, allowed: %i[file fog], writable: false add :attachments_storage_path, + description: 'File storage disk location (only applicable for local file storage)', format: :string, default: nil, writable: false add :attachments_grace_period, + description: 'Time to wait before uploaded files not attached to any container are removed', default: 180, writable: false add :auth_source_sso, + description: 'Configuration for Header-based Single Sign-On', format: :hash, default: nil, writable: false @@ -104,6 +113,7 @@ Settings::Definition.define do # user: admin # password: 123456 add :authentication, + description: 'Configuration options for global basic auth', format: :hash, default: nil, writable: false @@ -117,14 +127,17 @@ Settings::Definition.define do default: 0 add :autologin_cookie_name, + description: 'Cookie name for autologin cookie', default: 'autologin', writable: false add :autologin_cookie_path, + description: 'Cookie path for autologin cookie', default: '/', writable: false add :autologin_cookie_secure, + description: 'Cookie secure mode for autologin cookie', default: false, writable: false @@ -134,32 +147,39 @@ Settings::Definition.define do allowed: -> { Redmine::I18n.all_languages } add :avatar_link_expiry_seconds, + description: 'Cache duration for avatar image API responses', default: 24.hours.to_i, writable: false # Allow users with the required permissions to create backups via the web interface or API. add :backup_enabled, + description: 'Enable application backups through the UI', default: true, writable: false add :backup_daily_limit, + description: 'Maximum number of application backups allowed per day', default: 3, writable: false add :backup_initial_waiting_period, + description: 'Wait time before newly created backup tokens are usable', default: 24.hours, format: :integer, writable: false add :backup_include_attachments, + description: 'Allow inclusion of attachments in application backups', default: true, writable: false add :backup_attachment_size_max_sum_mb, + description: 'Maximum limit of attachment size to include into application backups', default: 1024, writable: false add :blacklisted_routes, + description: 'Blocked routes to prevent access to certain modules or pages', default: [], writable: false @@ -167,15 +187,19 @@ Settings::Definition.define do default: true add :boards_demo_data_available, + description: 'Internal setting determining availability of demo seed data', default: false add :brute_force_block_minutes, + description: 'Number of minutes to block users after presumed brute force attack', default: 30 add :brute_force_block_after_failed_logins, + description: 'Number of login attempts per user before assuming brute force attack', default: 20 add :cache_expires_in_seconds, + description: 'Expiration time for memcache entries, empty for no expiry be default', format: :integer, default: nil, writable: false @@ -185,39 +209,47 @@ Settings::Definition.define do # use dalli defaults for memcache add :cache_memcache_server, + description: 'The memcache server host and IP', format: :string, default: nil, writable: false add :cache_namespace, format: :string, + description: 'Namespace for cache keys, useful when multiple applications use a single memcache server', default: nil, writable: false add :commit_fix_done_ratio, + description: 'Progress to apply when commit fixes work package', default: 100 add :commit_fix_keywords, + description: 'Keywords to look for in commit for fixing work packages', default: 'fixes,closes' add :commit_fix_status_id, + description: 'Assigned status when fixing keyword is found', format: :integer, default: nil, allowed: -> { Status.pluck(:id) + [nil] } - # encoding used to convert commit logs to UTF-8 add :commit_logs_encoding, + description: "Encoding used to convert commit logs to UTF-8", default: 'UTF-8' add :commit_logtime_activity_id, + description: :setting_commit_logtime_activity_id, format: :integer, default: nil, allowed: -> { TimeEntryActivity.pluck(:id) + [nil] } add :commit_logtime_enabled, + description: "Allow logging time through commit message", default: false add :commit_ref_keywords, + description: "Keywords used in commits for referencing work packages", default: 'refs,references,IssueID' add :consent_decline_mail, @@ -234,7 +266,7 @@ Settings::Definition.define do add :consent_info, default: { en: "## Consent\n\nYou need to agree to the [privacy and security policy]" + - "(https://www.openproject.org/data-privacy-and-security/) of this OpenProject instance." + "(https://www.openproject.org/data-privacy-and-security/) of this OpenProject instance." } # Indicates whether or not users need to consent to something such as privacy policy. @@ -246,10 +278,12 @@ Settings::Definition.define do # Allow in-context translations to be loaded with CSP add :crowdin_in_context_translations, + description: 'Add crowdin in-context translations helper', default: true, writable: false add :database_cipher_key, + description: 'Encryption key for repository credentials', format: :string, default: nil, writable: false @@ -270,10 +304,12 @@ Settings::Definition.define do ].freeze add :default_auto_hide_popups, + description: 'Whether to automatically hide success notifications by default', default: true # user configuration add :default_comment_sort_order, + description: 'Default sort order for activities', default: 'asc', writable: false @@ -299,55 +335,60 @@ Settings::Definition.define do add :diff_max_lines_displayed, default: 1500 - # only applicable in conjunction with fog (effectively S3) attachments - # which will be uploaded directly to the cloud storage rather than via OpenProject's - # server process. add :direct_uploads, + description: 'Enable direct uploads to AWS S3. Only applicable with enabled Fog / AWS S3 configuration', default: true, writable: false add :disable_browser_cache, + description: 'Prevent browser from caching any logged-in responses for security reasons', default: true, writable: false # allow to disable default modules add :disabled_modules, + description: 'A list of module names to prevent access to in the application', default: [], + allowed: -> { OpenProject::AccessControl.available_project_modules.map(&:to_s) }, writable: false add :disable_password_choice, + description: "If enabled a user's password cannot be set to an arbitrary value, but can only be randomized.", default: false, writable: false add :disable_password_login, + description: 'Disable internal logins and instead only allow SSO through OmniAuth.', default: false, writable: false add :display_subprojects_work_packages, default: true - # Destroy all sessions for current_user on logout add :drop_old_sessions_on_logout, + description: 'Destroy all sessions for current_user on logout', default: true, writable: false - # Destroy all sessions for current_user on login add :drop_old_sessions_on_login, + description: 'Destroy all sessions for current_user on login', default: false, writable: false add :edition, format: :string, default: 'standard', + description: 'OpenProject edition mode', writable: false, allowed: %w[standard bim] add :ee_manager_visible, + description: 'Show or hide the Enterprise configuration page and enterprise banners', default: true, writable: false - # Enable internal asset server add :enable_internal_assets_server, + description: 'Serve assets through the Rails internal asset server', default: false, writable: false @@ -386,14 +427,17 @@ Settings::Definition.define do # Allow connections for trial creation and booking add :enterprise_trial_creation_host, + description: 'Host for EE trial service', default: 'https://augur.openproject.com', writable: false add :enterprise_chargebee_site, + description: 'Site name for EE trial service', default: 'openproject-enterprise', writable: false add :enterprise_plan, + description: 'Default EE selected plan', default: 'enterprise-on-premises---euro---1-year', writable: false @@ -413,26 +457,30 @@ Settings::Definition.define do format: :integer, allowed: [1, 4] - # Configure fog, e.g. when using an S3 uploader add :fog, + description: 'Configure fog, e.g. when using an S3 uploader', default: {} add :fog_download_url_expires_in, + description: 'Expiration time in seconds of created shared presigned URLs', default: 21600, # 6h by default as 6 hours is max in S3 when using IAM roles writable: false # Additional / overridden help links add :force_help_link, + description: 'You can set a custom URL for the help button in application header menu.', format: :string, default: nil, writable: false add :force_formatting_help_link, + description: 'You can set a custom URL for the help button in the WYSIWYG editor.', format: :string, default: nil, writable: false add :forced_single_page_size, + description: 'Forced page size for manually sorted work package views', default: 250 add :host_name, @@ -440,6 +488,7 @@ Settings::Definition.define do # Health check configuration add :health_checks_authentication_password, + description: 'Add an authentication challenge for the /health_check endpoint', format: :string, default: nil, writable: false @@ -447,18 +496,21 @@ Settings::Definition.define do # Maximum number of backed up jobs (that are not yet executed) # before health check fails add :health_checks_jobs_queue_count_threshold, + description: 'Set threshold of backed up background jobs to fail health check', format: :integer, default: 50, writable: false ## Maximum number of minutes that jobs have not yet run after their designated 'run_at' time add :health_checks_jobs_never_ran_minutes_ago, + description: 'Set threshold of outstanding background jobs to fail health check', format: :integer, default: 5, writable: false ## Maximum number of unprocessed requests in puma's backlog. add :health_checks_backlog_threshold, + description: 'Set threshold of outstanding HTTP requests to fail health check', format: :integer, default: 20, writable: false @@ -466,15 +518,17 @@ Settings::Definition.define do # Default gravatar image, set to something other than 404 # to ensure a default is returned add :gravatar_fallback_image, + description: 'Set default gravatar image fallback', default: '404', writable: false add :hidden_menu_items, + description: 'Hide menu items in the menu sidebar for each main menu (such as Administration and Projects).', default: {}, writable: false - # Impressum link to be set, nil by default (= hidden) add :impressum_link, + description: 'Impressum link to be set, hidden by default', format: :string, default: nil, writable: false @@ -488,6 +542,7 @@ Settings::Definition.define do default: nil add :internal_password_confirmation, + description: 'Require password confirmations for certain administrative actions', default: true, writable: false @@ -497,24 +552,24 @@ Settings::Definition.define do add :journal_aggregation_time_minutes, default: 5 - # Allow override of LDAP options add :ldap_force_no_page, + description: 'Force LDAP to respond as a single page, in case paged responses do not work with your server.', format: :string, default: nil, writable: false - # Allow users to manually sync groups in a different way - # than the provided job using their own cron add :ldap_groups_disable_sync_job, + description: 'Deactivate regular synchronization job for groups in case scheduled as a separate cronjob', default: false, writable: false add :ldap_users_disable_sync_job, + description: 'Deactive user attributes synchronization from LDAP', default: false, writable: false - # Update users' status through the synchronization job add :ldap_users_sync_status, + description: 'Enable user status (locked/unlocked) synchronization from LDAP', format: :boolean, default: false, writable: false @@ -525,7 +580,9 @@ Settings::Definition.define do writable: true add :log_level, + description: 'Set the OpenProject logger level', default: Rails.env.development? ? 'debug' : 'info', + allowed: %w[debug info warn error fatal], writable: false add :log_requesting_user, @@ -533,6 +590,7 @@ Settings::Definition.define do # Use lograge to format logs, off by default add :lograge_formatter, + description: 'Use lograge formatter for outputting logs', default: nil, format: :string, writable: false @@ -541,6 +599,7 @@ Settings::Definition.define do default: false add :lost_password, + description: 'Activate or deactivate lost password form', default: true add :mail_from, @@ -564,10 +623,13 @@ Settings::Definition.define do add :main_content_language, default: 'english', - writable: false + description: 'Main content language for PostgreSQL full text features', + writable: false, + allowed: %w[danish dutch english finnish french german hungarian + italian norwegian portuguese romanian russian simple spanish swedish turkish] - # Check for missing migrations in internal errors add :migration_check_on_exceptions, + description: 'Check for missing migrations in internal errors', default: true, writable: false @@ -578,14 +640,18 @@ Settings::Definition.define do allowed: -> { Role.pluck(:id) } add :oauth_allow_remapping_of_existing_users, + description: 'When set to false, prevent users from other identity providers to take over accounts connected ' \ + 'to another identity provider.', default: true add :omniauth_direct_login_provider, + description: 'Clicking on login sends a login request to the specified OmniAuth provider.', format: :string, default: nil, writable: false add :override_bcrypt_cost_factor, + description: "Set a custom BCrypt cost factor for deriving a user's bcrypt hash.", format: :string, default: nil, writable: false @@ -597,10 +663,12 @@ Settings::Definition.define do default: '08:00' add :onboarding_video_url, + description: 'Onboarding guide instructional video URL', default: 'https://player.vimeo.com/video/163426858?autoplay=1', writable: false add :onboarding_enabled, + description: 'Enable or disable onboarding guided tour for new users', default: true, writable: false @@ -634,30 +702,31 @@ Settings::Definition.define do format: :string add :rails_asset_host, + description: 'Custom asset hostname for serving assets (e.g., Cloudfront)', format: :string, default: nil, writable: false add :rails_cache_store, + description: 'Set cache store implemenation to use with OpenProject', format: :symbol, default: :file_store, writable: false, allowed: %i[file_store memcache] - # url-path prefix add :rails_relative_url_root, + description: 'Set a URL prefix / base path to run OpenProject under, e.g., host.tld/openproject', default: '', writable: false - # Assume we're running in an TLS terminated connection. add :https, + description: 'Set assumed connection security for the Rails processes', format: :boolean, default: -> { Rails.env.production? }, writable: false - # Allow disabling of HSTS headers and http -> https redirects - # for non-localhost hosts add :hsts, + description: 'Allow disabling of HSTS headers and http -> https redirects', format: :boolean, default: true, writable: false @@ -668,7 +737,9 @@ Settings::Definition.define do }, writable: false - add :report_incoming_email_errors, default: true + add :report_incoming_email_errors, + description: 'Respond to incoming mails with error details', + default: true add :repositories_automatic_managed_vendor, default: nil, @@ -726,6 +797,7 @@ Settings::Definition.define do default: true add :security_badge_url, + description: 'URL of the update check badge', default: "https://releases.openproject.com/v1/check.svg", writable: false @@ -733,11 +805,13 @@ Settings::Definition.define do default: 2 add :sendmail_arguments, + description: 'Arguments to call sendmail with in case it is configured as outgoing email setup', format: :string, default: "-i", writable: false add :sendmail_location, + description: 'Location of sendmail to call if it is configured as outgoing email setup', format: :string, default: "/usr/sbin/sendmail" @@ -745,14 +819,16 @@ Settings::Definition.define do add :appsignal_frontend_key, format: :string, default: nil, + description: 'Appsignal API key for JavaScript error reporting', writable: false add :session_cookie_name, + description: 'Set session cookie name', default: '_open_project_session', writable: false - # where to store session data add :session_store, + description: 'Where to store session data', default: :active_record_store, writable: false @@ -763,28 +839,28 @@ Settings::Definition.define do default: 120 add :show_community_links, + description: 'Enable or disable links to OpenProject community instances', default: true, writable: false - # Show pending migrations as warning bar add :show_pending_migrations_warning, + description: 'Enable or disable warning bar in case of pending migrations', default: true, writable: false - # Show mismatched protocol/hostname warning - # in settings where they must differ this can be disabled add :show_setting_mismatch_warning, + description: 'Show mismatched protocol/hostname warning. In cases where they must differ this can be disabled', default: true, writable: false # Render storage information add :show_storage_information, + description: 'Show available and taken storage information under administration / info', default: true, writable: false - # Render warning bars (pending migrations, deprecation, unsupported browsers) - # Set to false to globally disable this for all users! add :show_warning_bars, + description: 'Render warning bars (pending migrations, deprecation, unsupported browsers)', default: true, writable: false @@ -799,6 +875,7 @@ Settings::Definition.define do env_alias: 'SMTP_ENABLE_STARTTLS_AUTO' add :smtp_openssl_verify_mode, + description: 'Globally set verify mode for OpenSSL. Careful: Setting to none will disable any SSL verification!', format: :string, default: "peer", allowed: %w[none peer client_once fail_if_no_peer_cert], @@ -835,13 +912,15 @@ Settings::Definition.define do env_alias: 'SMTP_PASSWORD' add :software_name, + description: 'Override software application name', default: 'OpenProject' add :software_url, + description: 'Override software application URL', default: 'https://www.openproject.org/' - # Slow query logging threshold in ms add :sql_slow_query_threshold, + description: 'Time limit in ms after which queries will be logged as slow queries', default: 2000, writable: false @@ -850,8 +929,8 @@ Settings::Definition.define do format: :integer, allowed: [1, 6, 7] - # enable statsd metrics (currently puma only) by configuring host add :statsd, + description: 'enable statsd metrics (currently puma only) by configuring host', default: { 'host' => nil, 'port' => 8125 @@ -859,9 +938,11 @@ Settings::Definition.define do writable: false add :sys_api_enabled, + description: 'Enable internal system API for setting up managed repositories', default: false add :sys_api_key, + description: 'Internal system API key for setting up managed repositories', default: nil, format: :string @@ -889,6 +970,7 @@ Settings::Definition.define do allowed: -> { User::USER_FORMATS_STRUCTURE.keys } add :web, + description: 'Web worker count and threads configuration', default: { 'workers' => 2, 'timeout' => 120, @@ -936,11 +1018,13 @@ Settings::Definition.define do default: false add :working_days, + description: 'Set working days of the week (Array of 1 to 7, where 1=Monday, 7=Sunday)', format: :array, allowed: Array(1..7), default: Array(1..5) # Sat, Sun being non-working days add :youtube_channel, + description: 'Link to YouTube channel in help menu', default: 'https://www.youtube.com/c/OpenProjectCommunity', writable: false end diff --git a/lib/tasks/setting.rake b/lib/tasks/setting.rake index 2d9a252ad9..f59f962da5 100644 --- a/lib/tasks/setting.rake +++ b/lib/tasks/setting.rake @@ -62,7 +62,8 @@ namespace :setting do desc 'List the supported environment variables to override settings' task available_envs: :environment do Settings::Definition.all.sort_by(&:name).each do |definition| - puts "#{Settings::Definition.possible_env_names(definition).first} (default=#{definition.default.inspect})" + puts "#{Settings::Definition.possible_env_names(definition).first}" \ + " (default=#{definition.default.inspect}) #{definition.description}" end end end