diff --git a/.rubocop.yml b/.rubocop.yml index 700b4d3b2..3c034fbab 100644 --- a/.rubocop.yml +++ b/.rubocop.yml @@ -10,13 +10,13 @@ AllCops: Exclude: - 'db/**/*' - 'bin/**/*' - - 'config/**/*' - 'lib/tasks/**/*' - 'lib/generators/**/*' - 'features/**/*' - 'vendor/**/*' - 'tmp/**/*' - 'node_modules/**/*' + - !ruby/regexp /^(?!.*\.rb$).*/ #################################### ## Customization for this project ## diff --git a/config/application.rb b/config/application.rb index c2fab2023..af009bde8 100644 --- a/config/application.rb +++ b/config/application.rb @@ -32,7 +32,7 @@ class Application < Rails::Application # NOTE: govuk_design_system_formbuilder monkey patch in lib folder is not # autoloaded because it the gem itself uses a non-standard/convention filename # to classname pattern. - config.autoload_lib(ignore: %w(assets tasks govuk_design_system_formbuilder)) + config.autoload_lib(ignore: %w[assets tasks govuk_design_system_formbuilder]) # Configuration for the application, engines, and railties goes here. # @@ -56,13 +56,13 @@ class Application < Rails::Application config.active_job.queue_adapter = :sidekiq config.action_mailer.deliver_later_queue_name = :mailers - config.exceptions_app = ->(env) { + config.exceptions_app = lambda { |env| ErrorsController.action(:show).call(env) } config.active_model.i18n_customize_full_message = true - config.assets.paths << Rails.root.join("node_modules/govuk-frontend/dist/govuk/assets") + config.assets.paths << Rails.root.join('node_modules/govuk-frontend/dist/govuk/assets') config.x.contact.support_email = 'CRM457@digital.justice.gov.uk' config.x.application.name = 'Assess a crime form' @@ -72,11 +72,11 @@ class Application < Rails::Application config.x.analytics.analytics_consent_expiration = 1.year config.x.rfi.working_day_window = 10 config.x.redis_url = if ENV['REDIS_HOST'].present? && ENV['REDIS_PASSWORD'].present? - protocol = ENV.fetch("REDIS_PROTOCOL", "rediss") - password = ENV.fetch('REDIS_PASSWORD') - host = ENV.fetch('REDIS_HOST') - "#{protocol}://:#{password}@#{host}:6379" - end + protocol = ENV.fetch('REDIS_PROTOCOL', 'rediss') + password = ENV.fetch('REDIS_PASSWORD') + host = ENV.fetch('REDIS_HOST') + "#{protocol}://:#{password}@#{host}:6379" + end config.x.contact.feedback_url = 'tbc' end diff --git a/config/environments/development.rb b/config/environments/development.rb index 4809ffed1..02f2ad9c8 100644 --- a/config/environments/development.rb +++ b/config/environments/development.rb @@ -2,6 +2,7 @@ require 'active_support/core_ext/integer/time' +# rubocop:disable Metrics/BlockLength Rails.application.configure do # Settings specified here will take precedence over those in config/application.rb. @@ -85,3 +86,4 @@ config.logstasher.suppress_app_log = false config.logstasher.source = 'laa-assess-crime-forms-dev' end +# rubocop:enable Metrics/BlockLength diff --git a/config/environments/production.rb b/config/environments/production.rb index 93e897cc4..531a1bf8a 100644 --- a/config/environments/production.rb +++ b/config/environments/production.rb @@ -2,6 +2,7 @@ require 'active_support/core_ext/integer/time' +# rubocop:disable Metrics/BlockLength Rails.application.configure do # Settings specified here will take precedence over those in config/application.rb. @@ -56,23 +57,23 @@ # Can be used together with config.force_ssl for Strict-Transport-Security and secure cookies. # config.assume_ssl = true - if ENV["RAILS_LOG_TO_STDOUT"].present? - config.logger = ActiveSupport::Logger.new(STDOUT) - .tap { |logger| logger.formatter = ::Logger::Formatter.new } - .then { |logger| ActiveSupport::TaggedLogging.new(logger) } + if ENV['RAILS_LOG_TO_STDOUT'].present? + config.logger = ActiveSupport::Logger.new($stdout) + .tap { |logger| logger.formatter = Logger::Formatter.new } + .then { |logger| ActiveSupport::TaggedLogging.new(logger) } end # Info include generic and useful information about system operation, but avoids logging too much # information to avoid inadvertent exposure of personally identifiable information (PII). If you # want to log everything, set the level to "debug". - config.log_level = ENV.fetch("RAILS_LOG_LEVEL", "info") + config.log_level = ENV.fetch('RAILS_LOG_LEVEL', 'info') # Prepend all log lines with the following tags. config.log_tags = [:request_id] # Use a different cache store in production. config.cache_store = :solid_cache_store, { - error_handler: -> (method:, returning:, exception:) do + error_handler: lambda do |_method:, _returning:, exception:| # We want to make sure that if something goes wrong retrieving information from the # session/cache both we and the end user know that something is amiss - we definitely # don't want to just treat it as a cache miss and move on, as that's a poor UX. @@ -108,7 +109,7 @@ config.active_record.dump_schema_after_migration = false # Enable DNS rebinding protection and other `Host` header attacks. - config.hosts = (ENV["HOSTS"]&.split(',') || []) + [ENV.fetch('INTERNAL_HOST_NAME', nil)].compact + config.hosts = (ENV['HOSTS']&.split(',') || []) + [ENV.fetch('INTERNAL_HOST_NAME', nil)].compact # Skip DNS rebinding protection for the default health check endpoint. config.host_authorization = { exclude: ->(request) { request.path == '/ping' } } @@ -118,3 +119,4 @@ config.logstasher.suppress_app_log = false config.logstasher.source = 'laa-assess-crime-forms-prod' end +# rubocop:enable Metrics/BlockLength diff --git a/config/environments/test.rb b/config/environments/test.rb index db9794158..e39a2a8e1 100644 --- a/config/environments/test.rb +++ b/config/environments/test.rb @@ -7,6 +7,7 @@ # your test database is "scratch space" for the test suite and is wiped # and recreated between test runs. Don't rely on the data there! +# rubocop:disable Metrics/BlockLength Rails.application.configure do # Settings specified here will take precedence over those in config/application.rb. @@ -82,3 +83,4 @@ config.logstasher.suppress_app_log = false config.logstasher.source = 'laa-assess-crime-forms-test' end +# rubocop:enable Metrics/BlockLength diff --git a/config/initializers/content_security_policy.rb b/config/initializers/content_security_policy.rb index f9444f350..870e05f32 100644 --- a/config/initializers/content_security_policy.rb +++ b/config/initializers/content_security_policy.rb @@ -21,7 +21,7 @@ # Sentry creates workers from "blobs" in order to report on errors, so we allow that policy.worker_src :blob - policy.frame_src ENV["METABASE_URL"] + policy.frame_src ENV.fetch('METABASE_URL', nil) end # Generate session nonces for permitted importmap and inline scripts diff --git a/config/initializers/date_and_time_formats.rb b/config/initializers/date_and_time_formats.rb index f836e82a1..a73c9e5da 100644 --- a/config/initializers/date_and_time_formats.rb +++ b/config/initializers/date_and_time_formats.rb @@ -5,5 +5,5 @@ # Date::DATE_FORMATS[:stamp] = '%-d %B %Y' # DD MONTH YYYY Time::DATE_FORMATS[:stamp] = '%-d %B %Y' # DD MONTH YYYY -Date::DATE_FORMATS[:date_picker] = "%-d/%-m/%Y" # d/m/yyyy +Date::DATE_FORMATS[:date_picker] = '%-d/%-m/%Y' # d/m/yyyy Time::DATE_FORMATS[:time_of_day] = '%-I:%M%P' # H:MM with am/pm diff --git a/config/initializers/devise.rb b/config/initializers/devise.rb index d310eaa8a..ef78f7737 100644 --- a/config/initializers/devise.rb +++ b/config/initializers/devise.rb @@ -2,6 +2,7 @@ require Rails.root.join('app/lib/feature_flags') require Rails.root.join('app/lib/omni_auth/strategies/dev_auth') +# rubocop:disable Metrics/BlockLength Devise.setup do |config| require 'devise/orm/active_record' @@ -41,8 +42,8 @@ # # Uses the DevAuth strategy if local/docker env and feature flag for dev_auth is true - unless HostEnv.local? || ENV.key?('IS_LOCAL_DOCKER_ENV') - raise "The DevAuth strategy must not be used in this environment" if FeatureFlags.dev_auth.enabled? + if !(HostEnv.local? || ENV.key?('IS_LOCAL_DOCKER_ENV')) && FeatureFlags.dev_auth.enabled? + raise 'The DevAuth strategy must not be used in this environment' end strategy_class = FeatureFlags.dev_auth.enabled? ? OmniAuth::Strategies::DevAuth : OmniAuth::Strategies::OpenIDConnect @@ -67,3 +68,4 @@ OmniAuth.config.logger = Rails.logger end +# rubocop:enable Metrics/BlockLength diff --git a/config/initializers/gov_uk_notify.rb b/config/initializers/gov_uk_notify.rb index 0f43eb86e..2706cb92c 100644 --- a/config/initializers/gov_uk_notify.rb +++ b/config/initializers/gov_uk_notify.rb @@ -1,4 +1,4 @@ # frozen_string_literal: true ActionMailer::Base.add_delivery_method :govuk_notify, GovukNotifyRails::Delivery, - api_key: ENV.fetch('GOVUK_NOTIFY_API_KEY', nil) \ No newline at end of file + api_key: ENV.fetch('GOVUK_NOTIFY_API_KEY', nil) diff --git a/config/initializers/inflections.rb b/config/initializers/inflections.rb index 6c78420e7..9e049dcc9 100644 --- a/config/initializers/inflections.rb +++ b/config/initializers/inflections.rb @@ -1,4 +1,5 @@ # frozen_string_literal: true + # Be sure to restart your server when you modify this file. # Add new inflection rules using the following format. Inflections diff --git a/config/initializers/pagy.rb b/config/initializers/pagy.rb index 35a43ee6e..50c61e29c 100644 --- a/config/initializers/pagy.rb +++ b/config/initializers/pagy.rb @@ -1,4 +1,4 @@ require 'pagy/extras/array' Pagy::DEFAULT[:limit] = 10 -Pagy::I18n.load(locale: "en", filepath: Rails.root.join("config/locales/en/pagy.yml")) +Pagy::I18n.load(locale: 'en', filepath: Rails.root.join('config/locales/en/pagy.yml')) diff --git a/config/initializers/permissions_policy.rb b/config/initializers/permissions_policy.rb index 94637b4d5..6f382e444 100644 --- a/config/initializers/permissions_policy.rb +++ b/config/initializers/permissions_policy.rb @@ -1,4 +1,5 @@ # frozen_string_literal: true + # Define an application-wide HTTP permissions policy. For further # information see: https://developers.google.com/web/updates/2018/06/feature-policy diff --git a/config/initializers/prometheus.rb b/config/initializers/prometheus.rb index 18671ecfc..2ae0b838c 100644 --- a/config/initializers/prometheus.rb +++ b/config/initializers/prometheus.rb @@ -1,12 +1,12 @@ # The below is heavily cribbed from ministryofjustice/laa-apply-for-criminal-legal-aid -return unless ENV.fetch("ENABLE_PROMETHEUS_EXPORTER", "false") == "true" +return unless ENV.fetch('ENABLE_PROMETHEUS_EXPORTER', 'false') == 'true' -require "prometheus_exporter/server" -require "prometheus_exporter/instrumentation" -require "prometheus_exporter/middleware" +require 'prometheus_exporter/server' +require 'prometheus_exporter/instrumentation' +require 'prometheus_exporter/middleware' -DEFAULT_PREFIX = "ruby_".freeze -DEFAULT_BIND_ADDRESS = "0.0.0.0".freeze +DEFAULT_PREFIX = 'ruby_'.freeze +DEFAULT_BIND_ADDRESS = '0.0.0.0'.freeze DEFAULT_PORT = 9394 # We are running puma in single process mode, so this is safe @@ -14,24 +14,24 @@ # exporter process separately (`bundle exec prometheus_exporter`) def start_prometheus_server server = PrometheusExporter::Server::WebServer.new( - bind: ENV.fetch("PROMETHEUS_EXPORTER_HOST", DEFAULT_BIND_ADDRESS), - port: ENV.fetch("PROMETHEUS_EXPORTER_PORT", DEFAULT_PORT).to_i, - verbose: ENV.fetch("PROMETHEUS_EXPORTER_VERBOSE", "false") == "true" + bind: ENV.fetch('PROMETHEUS_EXPORTER_HOST', DEFAULT_BIND_ADDRESS), + port: ENV.fetch('PROMETHEUS_EXPORTER_PORT', DEFAULT_PORT).to_i, + verbose: ENV.fetch('PROMETHEUS_EXPORTER_VERBOSE', 'false') == 'true' ) server.start server rescue Errno::EADDRINUSE - warn "[PrometheusExporter] Server port already in use." + warn '[PrometheusExporter] Server port already in use.' false end -Rails.logger.info("[PrometheusExporter] Starting server....") +Rails.logger.info('[PrometheusExporter] Starting server....') server = start_prometheus_server return unless server Rails.logger.info("[PrometheusExporter] server started on #{JSON.parse(server.to_json).fetch_values('port', 'bind')}!") -Rails.logger.info("[PrometheusExporter] Initialising standard instrumentation middleware...") +Rails.logger.info('[PrometheusExporter] Initialising standard instrumentation middleware...') # Metrics will be prefixed, for example `ruby_http_requests_total` PrometheusExporter::Metric::Base.default_prefix = DEFAULT_PREFIX @@ -48,7 +48,7 @@ def start_prometheus_server # means it is instrumenting the master process. # see config/puma.rb after_work_boot for more # - PrometheusExporter::Instrumentation::Process.start(type: "master") + PrometheusExporter::Instrumentation::Process.start(type: 'master') PrometheusExporter::Instrumentation::Puma.start unless PrometheusExporter::Instrumentation::Puma.started? PrometheusExporter::Instrumentation::ActiveRecord.start diff --git a/config/initializers/sentry.rb b/config/initializers/sentry.rb index 5c13131b6..98d2011a3 100644 --- a/config/initializers/sentry.rb +++ b/config/initializers/sentry.rb @@ -3,7 +3,7 @@ if ENV.fetch('SENTRY_DSN', nil).present? Sentry.init do |config| config.environment = HostEnv.env_name - config.dsn = ENV['SENTRY_DSN'] + config.dsn = ENV.fetch('SENTRY_DSN', nil) config.breadcrumbs_logger = [:active_support_logger] config.release = ENV.fetch('BUILD_TAG', 'unknown') diff --git a/config/initializers/sidekiq.rb b/config/initializers/sidekiq.rb index 54bd7f394..43d08d687 100644 --- a/config/initializers/sidekiq.rb +++ b/config/initializers/sidekiq.rb @@ -16,7 +16,7 @@ # Perform Sidekiq jobs immediately in development, # so you don't have to run a separate process. # You'll also benefit from code reloading. -if ENV.fetch('RUN_SIDEKIQ_IN_TEST_MODE', false) == "true" +if ENV.fetch('RUN_SIDEKIQ_IN_TEST_MODE', false) == 'true' require 'sidekiq/testing' Sidekiq::Testing.inline! end @@ -25,22 +25,22 @@ module Dashboard; end -Rails.logger.info("[Sidekiq] Application config initialising...") +Rails.logger.info('[Sidekiq] Application config initialising...') Sidekiq.configure_client do |config| redis_url = 'redis://localhost:6379/2' if HostEnv.local? - Rails.logger.info("[SidekiqClient] configuring sidekiq client...") + Rails.logger.info('[SidekiqClient] configuring sidekiq client...') config.redis = { url: redis_url } if redis_url end Sidekiq.configure_server do |config| redis_url = 'redis://localhost:6379/2' if HostEnv.local? - Rails.logger.info("[SidekiqServer] configuring sidekiq server...") + Rails.logger.info('[SidekiqServer] configuring sidekiq server...') config.redis = { url: redis_url } if redis_url - return unless ENV.fetch("ENABLE_PROMETHEUS_EXPORTER", "false") == "true" + break unless ENV.fetch('ENABLE_PROMETHEUS_EXPORTER', 'false') == 'true' require 'prometheus_exporter/client' require 'prometheus_exporter/instrumentation' @@ -48,12 +48,12 @@ module Dashboard; end # Taken from https://github.com/discourse/prometheus_exporter?tab=readme-ov-file#sidekiq-metrics # config.server_middleware do |chain| - Rails.logger.info "[SidekiqPrometheusExporter] Chaining middleware..." + Rails.logger.info '[SidekiqPrometheusExporter] Chaining middleware...' chain.add PrometheusExporter::Instrumentation::Sidekiq end config.death_handlers << PrometheusExporter::Instrumentation::Sidekiq.death_handler config.on :startup do - Rails.logger.info "[SidekiqPrometheusExporter] Startup instrumention details..." + Rails.logger.info '[SidekiqPrometheusExporter] Startup instrumention details...' PrometheusExporter::Instrumentation::Process.start type: 'sidekiq' PrometheusExporter::Instrumentation::SidekiqProcess.start diff --git a/config/puma.rb b/config/puma.rb index 36592a736..9f2498b13 100644 --- a/config/puma.rb +++ b/config/puma.rb @@ -2,7 +2,7 @@ # If this is set to a positive number, Puma will launch in cluster mode. # Note that on Mac you may need to also have env var `OBJC_DISABLE_INITIALIZE_FORK_SAFETY=YES` -workers ENV.fetch("WORKERS", 0) +workers ENV.fetch('WORKERS', 0) # Puma can serve each request in a thread from an internal thread pool. # The `threads` method setting takes two numbers: a minimum and maximum. diff --git a/config/routes.rb b/config/routes.rb index f0893e0ce..7db766d7a 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -1,18 +1,22 @@ # frozen_string_literal: true + require 'sidekiq/web' +# rubocop:disable Metrics/BlockLength Rails.application.routes.draw do Sidekiq::Web.use Rack::Auth::Basic do |username, password| # Protect against timing attacks: # - See https://codahale.com/a-lesson-in-timing-attacks/ # - See https://web.archive.org/web/20180709235757/https://thisdata.com/blog/timing-attacks-against-string-comparison/ # - Use & (do not use &&) so that it doesn't short circuit. - ActiveSupport::SecurityUtils.secure_compare(::Digest::SHA256.hexdigest(username), ::Digest::SHA256.hexdigest(ENV["SIDEKIQ_WEB_UI_USERNAME"])) & - ActiveSupport::SecurityUtils.secure_compare(::Digest::SHA256.hexdigest(password), ::Digest::SHA256.hexdigest(ENV["SIDEKIQ_WEB_UI_PASSWORD"])) + ActiveSupport::SecurityUtils.secure_compare(Digest::SHA256.hexdigest(username), + Digest::SHA256.hexdigest(ENV.fetch('SIDEKIQ_WEB_UI_USERNAME', nil))) & + ActiveSupport::SecurityUtils.secure_compare(Digest::SHA256.hexdigest(password), + Digest::SHA256.hexdigest(ENV.fetch('SIDEKIQ_WEB_UI_PASSWORD', nil))) end - mount Sidekiq::Web => "/sidekiq" + mount Sidekiq::Web => '/sidekiq' - root "home#index" + root 'home#index' get :ping, to: 'healthcheck#ping' @@ -23,11 +27,11 @@ } ) - get "users/auth/failure", to: "errors#forbidden" + get 'users/auth/failure', to: 'errors#forbidden' devise_scope :user do if FeatureFlags.dev_auth.enabled? - get "dev_auth", to: "users/dev_auth#new", as: :new_user_session + get 'dev_auth', to: 'users/dev_auth#new', as: :new_user_session else get 'unauthorized', to: 'errors#forbidden', as: :new_user_session end @@ -44,7 +48,7 @@ end namespace :nsm do - root to: "claims#your" + root to: 'claims#your' resources :claims, only: [:create] do collection do get :your @@ -107,7 +111,7 @@ end namespace :prior_authority do - root to: "applications#your" + root to: 'applications#your' resources :applications, only: [:new, :show] do collection do get :your @@ -138,7 +142,8 @@ resource :search, only: %i[new show] end - get "robots.txt", to: "robots#index" + get 'robots.txt', to: 'robots#index' resource :dashboard, only: %i[new show] end +# rubocop:enable Metrics/BlockLength