From ffc14e499a12717fea96127d3cd5cd38f3ec41c4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Javi=20Mart=C3=ADn?= Date: Tue, 22 Mar 2022 18:56:20 +0100 Subject: [PATCH] Upgrade to Rails 6.0 All the code in the `bin/` and the `config/` folders has been generated running `rake app:update`. The only exception is the code in `config/application.rb` where we've excluded the engines that Rails 6.0 has added, since we don't use them. There are a few changes in Active Storage which aren't compatible with the code we were using until now. Since the method to assign an attachment in ActiveStorage has changed and is incompatible with the hack we used to allow assigning `nil` attachments, and since ActiveStorage now supports assigning `nil` attachments, we're removing the mentioned hack. This makes the HasAttachment module redundant, so we're removing it. Another change in ActiveStorage is files are no longer saved before saving the `ActiveStorage::Attachment` record. This means we need to manually upload the file when using direct uploads. We also have to change the width and height validations we used for images; however, doing so results in very complex code, and we currently have to write that code for both images and site customization images. So, for now, we're just uploading the file before checking its dimensions. Not ideal, though. We might use active_storage_validations in the future to fix this issue (when they support a proc/lambda, as mentioned in commit 600f5c35e). We also need to update a couple of tests due to a small change in response headers. Now the content disposition returns something like: ``` attachment; filename="budget_investments.csv"; filename*=UTF-8''budget_investments.csv ``` So we're updating regular expression we use to check the filename. Finally, Rails 6.0.1 changed the way the host is set in integration tests [1] and so both `Capybara.app_host` and `Capybara.default_host` were ignored when generating URLs in the relationable examples. The only way I've found to make it work is to explicitely assign the host to the integration session. Rails 6.1 will change this setup again, so maybe then we can remove this hack. [1] https://github.com/rails/rails/pull/36283/commits/fe00711e9 --- Gemfile | 2 +- Gemfile.lock | 112 ++++++++++-------- app/models/concerns/attachable.rb | 3 +- app/models/concerns/has_attachment.rb | 17 --- app/models/direct_upload.rb | 1 + app/models/image.rb | 5 +- app/models/site_customization/image.rb | 10 +- bin/setup | 10 +- config/application.rb | 17 ++- config/environments/development.rb | 7 +- config/environments/production.rb | 32 ++++- config/environments/staging.rb | 31 ++++- config/environments/test.rb | 21 ++-- .../initializers/content_security_policy.rb | 3 + .../new_framework_defaults_6_0.rb | 45 +++++++ ..._attachments_for_blob_id.active_storage.rb | 10 ++ db/schema.rb | 10 +- spec/lib/tasks/files_spec.rb | 4 + spec/shared/system/relationable.rb | 6 +- spec/system/admin/budget_investments_spec.rb | 2 +- .../admin/emails/emails_download_spec.rb | 2 +- 21 files changed, 241 insertions(+), 109 deletions(-) delete mode 100644 app/models/concerns/has_attachment.rb create mode 100644 config/initializers/new_framework_defaults_6_0.rb create mode 100644 db/migrate/20210924194527_add_foreign_key_constraint_to_active_storage_attachments_for_blob_id.active_storage.rb diff --git a/Gemfile b/Gemfile index 6becfaf42..20ed8d928 100644 --- a/Gemfile +++ b/Gemfile @@ -1,6 +1,6 @@ source "https://rubygems.org" -gem "rails", "5.2.8.1" +gem "rails", "6.0.5.1" gem "acts-as-taggable-on", "~> 8.1.0" gem "acts_as_votable", "~> 0.13.1" diff --git a/Gemfile.lock b/Gemfile.lock index bfc8bd2ac..14f5f5934 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -2,47 +2,61 @@ GEM remote: https://rubygems.org/ remote: https://rails-assets.org/ specs: - actioncable (5.2.8.1) - actionpack (= 5.2.8.1) + actioncable (6.0.5.1) + actionpack (= 6.0.5.1) nio4r (~> 2.0) websocket-driver (>= 0.6.1) - actionmailer (5.2.8.1) - actionpack (= 5.2.8.1) - actionview (= 5.2.8.1) - activejob (= 5.2.8.1) + actionmailbox (6.0.5.1) + actionpack (= 6.0.5.1) + activejob (= 6.0.5.1) + activerecord (= 6.0.5.1) + activestorage (= 6.0.5.1) + activesupport (= 6.0.5.1) + mail (>= 2.7.1) + actionmailer (6.0.5.1) + actionpack (= 6.0.5.1) + actionview (= 6.0.5.1) + activejob (= 6.0.5.1) mail (~> 2.5, >= 2.5.4) rails-dom-testing (~> 2.0) - actionpack (5.2.8.1) - actionview (= 5.2.8.1) - activesupport (= 5.2.8.1) + actionpack (6.0.5.1) + actionview (= 6.0.5.1) + activesupport (= 6.0.5.1) rack (~> 2.0, >= 2.0.8) rack-test (>= 0.6.3) rails-dom-testing (~> 2.0) - rails-html-sanitizer (~> 1.0, >= 1.0.2) - actionview (5.2.8.1) - activesupport (= 5.2.8.1) + rails-html-sanitizer (~> 1.0, >= 1.2.0) + actiontext (6.0.5.1) + actionpack (= 6.0.5.1) + activerecord (= 6.0.5.1) + activestorage (= 6.0.5.1) + activesupport (= 6.0.5.1) + nokogiri (>= 1.8.5) + actionview (6.0.5.1) + activesupport (= 6.0.5.1) builder (~> 3.1) erubi (~> 1.4) rails-dom-testing (~> 2.0) - rails-html-sanitizer (~> 1.0, >= 1.0.3) - activejob (5.2.8.1) - activesupport (= 5.2.8.1) + rails-html-sanitizer (~> 1.1, >= 1.2.0) + activejob (6.0.5.1) + activesupport (= 6.0.5.1) globalid (>= 0.3.6) - activemodel (5.2.8.1) - activesupport (= 5.2.8.1) - activerecord (5.2.8.1) - activemodel (= 5.2.8.1) - activesupport (= 5.2.8.1) - arel (>= 9.0) - activestorage (5.2.8.1) - actionpack (= 5.2.8.1) - activerecord (= 5.2.8.1) - marcel (~> 1.0.0) - activesupport (5.2.8.1) + activemodel (6.0.5.1) + activesupport (= 6.0.5.1) + activerecord (6.0.5.1) + activemodel (= 6.0.5.1) + activesupport (= 6.0.5.1) + activestorage (6.0.5.1) + actionpack (= 6.0.5.1) + activejob (= 6.0.5.1) + activerecord (= 6.0.5.1) + marcel (~> 1.0) + activesupport (6.0.5.1) concurrent-ruby (~> 1.0, >= 1.0.2) i18n (>= 0.7, < 2) minitest (~> 5.1) tzinfo (~> 1.1) + zeitwerk (~> 2.2, >= 2.2.2) acts-as-taggable-on (8.1.0) activerecord (>= 5.0, < 6.2) acts_as_votable (0.13.1) @@ -64,7 +78,6 @@ GEM nokogiri ancestry (4.1.0) activerecord (>= 5.2.6) - arel (9.0.0) ast (2.4.2) audited (5.0.1) activerecord (>= 5.0, < 6.2) @@ -145,7 +158,7 @@ GEM coffee-script-source execjs coffee-script-source (1.12.2) - concurrent-ruby (1.1.9) + concurrent-ruby (1.1.10) coveralls (0.8.23) json (>= 1.8, < 3) simplecov (~> 0.16.1) @@ -276,7 +289,7 @@ GEM gitlab (4.17.0) httparty (~> 0.18) terminal-table (~> 1.5, >= 1.5.1) - globalid (0.5.2) + globalid (1.0.0) activesupport (>= 5.0) globalize (6.0.1) activemodel (>= 4.2, < 7.0) @@ -469,18 +482,20 @@ GEM rack rack-test (1.1.0) rack (>= 1.0, < 3) - rails (5.2.8.1) - actioncable (= 5.2.8.1) - actionmailer (= 5.2.8.1) - actionpack (= 5.2.8.1) - actionview (= 5.2.8.1) - activejob (= 5.2.8.1) - activemodel (= 5.2.8.1) - activerecord (= 5.2.8.1) - activestorage (= 5.2.8.1) - activesupport (= 5.2.8.1) + rails (6.0.5.1) + actioncable (= 6.0.5.1) + actionmailbox (= 6.0.5.1) + actionmailer (= 6.0.5.1) + actionpack (= 6.0.5.1) + actiontext (= 6.0.5.1) + actionview (= 6.0.5.1) + activejob (= 6.0.5.1) + activemodel (= 6.0.5.1) + activerecord (= 6.0.5.1) + activestorage (= 6.0.5.1) + activesupport (= 6.0.5.1) bundler (>= 1.3.0) - railties (= 5.2.8.1) + railties (= 6.0.5.1) sprockets-rails (>= 2.0.0) rails-assets-leaflet (1.5.1) rails-assets-markdown-it (9.0.1) @@ -489,15 +504,15 @@ GEM nokogiri (>= 1.6) rails-html-sanitizer (1.4.3) loofah (~> 2.3) - rails-i18n (5.1.3) + rails-i18n (6.0.0) i18n (>= 0.7, < 2) - railties (>= 5.0, < 6) - railties (5.2.8.1) - actionpack (= 5.2.8.1) - activesupport (= 5.2.8.1) + railties (>= 6.0.0, < 7) + railties (6.0.5.1) + actionpack (= 6.0.5.1) + activesupport (= 6.0.5.1) method_source rake (>= 0.8.7) - thor (>= 0.19.0, < 2.0) + thor (>= 0.20.3, < 2.0) rainbow (3.0.0) rake (13.0.6) rb-fsevent (0.10.4) @@ -627,7 +642,7 @@ GEM unicode-display_width (~> 1.1, >= 1.1.1) terrapin (0.6.0) climate_control (>= 0.0.3, < 1.0) - thor (1.1.0) + thor (1.2.1) thread_safe (0.3.6) tilt (2.0.10) tins (1.25.0) @@ -680,6 +695,7 @@ GEM wkhtmltopdf-binary (0.12.6.5) xpath (3.2.0) nokogiri (~> 1.8) + zeitwerk (2.6.0) PLATFORMS ruby @@ -753,7 +769,7 @@ DEPENDENCIES pronto-rubocop (~> 0.11.1) pronto-scss (~> 0.11.0) puma (~> 4.3.12) - rails (= 5.2.8.1) + rails (= 6.0.5.1) rails-assets-leaflet! rails-assets-markdown-it (~> 9.0.1)! recipient_interceptor (~> 0.3.0) diff --git a/app/models/concerns/attachable.rb b/app/models/concerns/attachable.rb index ac6c1e33a..cc457f934 100644 --- a/app/models/concerns/attachable.rb +++ b/app/models/concerns/attachable.rb @@ -1,9 +1,8 @@ module Attachable - include HasAttachment extend ActiveSupport::Concern included do - has_attachment :attachment + has_one_attached :attachment attr_accessor :cached_attachment validate :attachment_presence diff --git a/app/models/concerns/has_attachment.rb b/app/models/concerns/has_attachment.rb deleted file mode 100644 index 2ffbd931b..000000000 --- a/app/models/concerns/has_attachment.rb +++ /dev/null @@ -1,17 +0,0 @@ -module HasAttachment - extend ActiveSupport::Concern - - class_methods do - def has_attachment(attribute) - has_one_attached attribute - - define_method :"#{attribute}=" do |file| - if file.nil? - send(attribute).detach - else - send(attribute).attach(file) - end - end - end - end -end diff --git a/app/models/direct_upload.rb b/app/models/direct_upload.rb index cd562ca07..6d6eb7470 100644 --- a/app/models/direct_upload.rb +++ b/app/models/direct_upload.rb @@ -35,6 +35,7 @@ class DirectUpload def save_attachment @relation.attachment.blob.save! + @relation.attachment_changes["attachment"].upload end def persisted? diff --git a/app/models/image.rb b/app/models/image.rb index eda89ecc8..2f4cac7de 100644 --- a/app/models/image.rb +++ b/app/models/image.rb @@ -61,7 +61,10 @@ class Image < ApplicationRecord if accepted_content_types.include?(attachment_content_type) return true if imageable_class == Widget::Card - attachment.analyze unless attachment.analyzed? + unless attachment.analyzed? + attachment_changes["attachment"].upload + attachment.analyze + end width = attachment.metadata[:width] height = attachment.metadata[:height] diff --git a/app/models/site_customization/image.rb b/app/models/site_customization/image.rb index 7d69f74c1..ca68c0288 100644 --- a/app/models/site_customization/image.rb +++ b/app/models/site_customization/image.rb @@ -1,6 +1,4 @@ class SiteCustomization::Image < ApplicationRecord - include HasAttachment - VALID_IMAGES = { "logo_header" => [260, 80], "social_media_icon" => [470, 246], @@ -22,7 +20,7 @@ class SiteCustomization::Image < ApplicationRecord image/x-icon ].freeze - has_attachment :image + has_one_attached :image validates :name, presence: true, uniqueness: true, inclusion: { in: ->(*) { VALID_IMAGES.keys }} validates :image, file_content_type: { allow: ->(*) { VALID_MIME_TYPES }, if: -> { image.attached? }} @@ -61,7 +59,11 @@ class SiteCustomization::Image < ApplicationRecord def check_image return unless image.attached? - image.analyze unless image.analyzed? + unless image.analyzed? + attachment_changes["image"].upload + image.analyze + end + width = image.metadata[:width] height = image.metadata[:height] diff --git a/bin/setup b/bin/setup index aa921f10d..5635f8ec1 100755 --- a/bin/setup +++ b/bin/setup @@ -1,6 +1,5 @@ #!/usr/bin/env ruby require "fileutils" -include FileUtils # path to your application root. APP_ROOT = File.expand_path("..", __dir__) @@ -9,8 +8,9 @@ def system!(*args) system(*args) || abort("\n== Command #{args} failed ==") end -chdir APP_ROOT do - # This script is a starting point to setup your application. +FileUtils.chdir APP_ROOT do + # This script is a way to setup or update your development environment automatically. + # This script is idempotent, so that you can run it at anytime and get an expectable outcome. # Add necessary setup steps to this file. puts "== Installing dependencies ==" @@ -19,11 +19,11 @@ chdir APP_ROOT do # puts "\n== Copying sample files ==" # unless File.exist?('config/database.yml') - # cp 'config/database.yml.sample', 'config/database.yml' + # FileUtils.cp 'config/database.yml.sample', 'config/database.yml' # end puts "\n== Preparing database ==" - system! "bin/rails db:setup" + system! "bin/rails db:prepare" puts "\n== Removing old logs and tempfiles ==" system! "bin/rails log:clear tmp:clear" diff --git a/config/application.rb b/config/application.rb index a0de876cb..3d0b55b0f 100644 --- a/config/application.rb +++ b/config/application.rb @@ -1,6 +1,19 @@ require_relative "boot" -require "rails/all" +require "rails" +# Pick the frameworks you want: +require "active_model/railtie" +require "active_job/railtie" +require "active_record/railtie" +require "active_storage/engine" +require "action_controller/railtie" +require "action_mailer/railtie" +# require "action_mailbox/engine" +# require "action_text/engine" +require "action_view/railtie" +require "action_cable/engine" +require "sprockets/railtie" +require "rails/test_unit/railtie" # Require the gems listed in Gemfile, including any gems # you've limited to :test, :development, or :production. @@ -27,7 +40,7 @@ module Consul # Handle custom exceptions config.action_dispatch.rescue_responses["FeatureFlags::FeatureDisabled"] = :forbidden - # Store files locally. + # Store uploaded files on the local file system (see config/storage.yml for options). config.active_storage.service = :local # Set Time.zone default to the specified zone and make Active Record auto-convert to this zone. diff --git a/config/environments/development.rb b/config/environments/development.rb index 3b37e1e85..72d7ec69b 100644 --- a/config/environments/development.rb +++ b/config/environments/development.rb @@ -16,6 +16,7 @@ Rails.application.configure do # Run rails dev:cache to toggle caching. if Rails.root.join("tmp", "caching-dev.txt").exist? config.action_controller.perform_caching = true + config.action_controller.enable_fragment_cache_logging = true config.cache_store = :memory_store config.public_file_server.headers = { @@ -50,14 +51,10 @@ Rails.application.configure do # number of complex assets. config.assets.debug = false - # Adds additional error checking when serving assets at runtime. - # Checks for improperly declared sprockets dependencies. - # Raises helpful error messages. - config.assets.raise_runtime_errors = true # Suppress logger output for asset requests. config.assets.quiet = true - # Raises error for missing translations + # Raises error for missing translations. # config.action_view.raise_on_missing_translations = true config.action_mailer.preview_path = "#{Rails.root}/spec/mailers/previews" diff --git a/config/environments/production.rb b/config/environments/production.rb index cb680f167..9c8f2e683 100644 --- a/config/environments/production.rb +++ b/config/environments/production.rb @@ -19,6 +19,10 @@ Rails.application.configure do config.consider_all_requests_local = false config.action_controller.perform_caching = true + # Ensures that a master key has been made available in either ENV["RAILS_MASTER_KEY"] + # or in config/master.key. This key is used to decrypt credentials (and other encrypted files). + # config.require_master_key = true + # Disable serving static files from the `/public` folder by default since # Apache or NGINX already handles this. config.public_file_server.enabled = ENV["RAILS_SERVE_STATIC_FILES"].present? @@ -37,7 +41,7 @@ Rails.application.configure do # config.action_dispatch.x_sendfile_header = "X-Sendfile" # for Apache # config.action_dispatch.x_sendfile_header = "X-Accel-Redirect" # for NGINX - # Mount Action Cable outside main process or domain + # Mount Action Cable outside main process or domain. # config.action_cable.mount_path = nil # config.action_cable.url = "wss://example.com/cable" # config.action_cable.allowed_request_origins = [ "http://example.com", /http:\/\/example.*/ ] @@ -56,9 +60,10 @@ Rails.application.configure do # Use a different cache store in production. config.cache_store = :mem_cache_store - # Use a real queuing backend for Active Job (and separate queues per environment) + # Use a real queuing backend for Active Job (and separate queues per environment). # config.active_job.queue_adapter = :resque # config.active_job.queue_name_prefix = "consul_#{Rails.env}" + config.action_mailer.perform_caching = false # Ignore bad email addresses and do not raise email delivery errors. @@ -90,9 +95,30 @@ Rails.application.configure do if ENV["RAILS_LOG_TO_STDOUT"].present? logger = ActiveSupport::Logger.new(STDOUT) logger.formatter = config.log_formatter - config.logger = ActiveSupport::TaggedLogging.new(logger) + config.logger = ActiveSupport::TaggedLogging.new(logger) end # Do not dump schema after migrations. config.active_record.dump_schema_after_migration = false + + # Inserts middleware to perform automatic connection switching. + # The `database_selector` hash is used to pass options to the DatabaseSelector + # middleware. The `delay` is used to determine how long to wait after a write + # to send a subsequent read to the primary. + # + # The `database_resolver` class is used by the middleware to determine which + # database is appropriate to use based on the time delay. + # + # The `database_resolver_context` class is used by the middleware to set + # timestamps for the last write to the primary. The resolver uses the context + # class timestamps to determine how long to wait before reading from the + # replica. + # + # By default Rails will store a last write timestamp in the session. The + # DatabaseSelector middleware is designed as such you can define your own + # strategy for connection switching and pass that into the middleware through + # these configuration options. + # config.active_record.database_selector = { delay: 2.seconds } + # config.active_record.database_resolver = ActiveRecord::Middleware::DatabaseSelector::Resolver + # config.active_record.database_resolver_context = ActiveRecord::Middleware::DatabaseSelector::Resolver::Session end diff --git a/config/environments/staging.rb b/config/environments/staging.rb index d84df4300..f05d0a6ee 100644 --- a/config/environments/staging.rb +++ b/config/environments/staging.rb @@ -19,6 +19,10 @@ Rails.application.configure do config.consider_all_requests_local = false config.action_controller.perform_caching = true + # Ensures that a master key has been made available in either ENV["RAILS_MASTER_KEY"] + # or in config/master.key. This key is used to decrypt credentials (and other encrypted files). + # config.require_master_key = true + # Disable serving static files from the `/public` folder by default since # Apache or NGINX already handles this. config.public_file_server.enabled = ENV["RAILS_SERVE_STATIC_FILES"].present? @@ -37,7 +41,7 @@ Rails.application.configure do # config.action_dispatch.x_sendfile_header = "X-Sendfile" # for Apache # config.action_dispatch.x_sendfile_header = "X-Accel-Redirect" # for NGINX - # Mount Action Cable outside main process or domain + # Mount Action Cable outside main process or domain. # config.action_cable.mount_path = nil # config.action_cable.url = "wss://example.com/cable" # config.action_cable.allowed_request_origins = [ "http://example.com", /http:\/\/example.*/ ] @@ -56,7 +60,7 @@ Rails.application.configure do # Use a different cache store in production. config.cache_store = :mem_cache_store - # Use a real queuing backend for Active Job (and separate queues per environment) + # Use a real queuing backend for Active Job (and separate queues per environment). # config.active_job.queue_adapter = :resque # config.active_job.queue_name_prefix = "consul_#{Rails.env}" config.action_mailer.perform_caching = false @@ -90,9 +94,30 @@ Rails.application.configure do if ENV["RAILS_LOG_TO_STDOUT"].present? logger = ActiveSupport::Logger.new(STDOUT) logger.formatter = config.log_formatter - config.logger = ActiveSupport::TaggedLogging.new(logger) + config.logger = ActiveSupport::TaggedLogging.new(logger) end # Do not dump schema after migrations. config.active_record.dump_schema_after_migration = false + + # Inserts middleware to perform automatic connection switching. + # The `database_selector` hash is used to pass options to the DatabaseSelector + # middleware. The `delay` is used to determine how long to wait after a write + # to send a subsequent read to the primary. + # + # The `database_resolver` class is used by the middleware to determine which + # database is appropriate to use based on the time delay. + # + # The `database_resolver_context` class is used by the middleware to set + # timestamps for the last write to the primary. The resolver uses the context + # class timestamps to determine how long to wait before reading from the + # replica. + # + # By default Rails will store a last write timestamp in the session. The + # DatabaseSelector middleware is designed as such you can define your own + # strategy for connection switching and pass that into the middleware through + # these configuration options. + # config.active_record.database_selector = { delay: 2.seconds } + # config.active_record.database_resolver = ActiveRecord::Middleware::DatabaseSelector::Resolver + # config.active_record.database_resolver_context = ActiveRecord::Middleware::DatabaseSelector::Resolver::Session end diff --git a/config/environments/test.rb b/config/environments/test.rb index 23ac6efa3..463b25f08 100644 --- a/config/environments/test.rb +++ b/config/environments/test.rb @@ -1,3 +1,8 @@ +# The test environment is used exclusively to run your application's +# test suite. You never need to work with it otherwise. Remember that +# 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! + Rails.application.configure do # Settings specified here will take precedence over those in config/application.rb. @@ -6,10 +11,6 @@ Rails.application.configure do config.i18n.default_locale = :en config.i18n.available_locales = %w[de en es fr nl pt-BR zh-CN] - # The test environment is used exclusively to run your application's - # test suite. You never need to work with it otherwise. Remember that - # 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! config.cache_classes = true # Do not eager load code on boot. This avoids loading your whole application @@ -26,12 +27,17 @@ Rails.application.configure do # Show full error reports and disable caching. config.consider_all_requests_local = true config.action_controller.perform_caching = false + config.cache_store = :null_store # Raise exceptions instead of rendering exception templates. config.action_dispatch.show_exceptions = false # Disable request forgery protection in test environment. config.action_controller.allow_forgery_protection = false + + # Store uploaded files on the local file system in a temporary directory. + config.active_storage.service = :test + config.action_mailer.perform_caching = false # Tell Action Mailer not to deliver emails to the real world. @@ -44,14 +50,9 @@ Rails.application.configure do # Print deprecation notices to the stderr. config.active_support.deprecation = :stderr - # Raises error for missing translations + # Raises error for missing translations. # config.action_view.raise_on_missing_translations = true - # Store files in tmp folders. - config.active_storage.service = :test - - config.cache_store = :null_store - config.after_initialize do Bullet.enable = true Bullet.bullet_logger = true diff --git a/config/initializers/content_security_policy.rb b/config/initializers/content_security_policy.rb index d3bcaa5ec..41c43016f 100644 --- a/config/initializers/content_security_policy.rb +++ b/config/initializers/content_security_policy.rb @@ -19,6 +19,9 @@ # If you are using UJS then enable automatic nonce generation # Rails.application.config.content_security_policy_nonce_generator = -> request { SecureRandom.base64(16) } +# Set the nonce only to specific directives +# Rails.application.config.content_security_policy_nonce_directives = %w(script-src) + # Report CSP violations to a specified URI # For further information see the following documentation: # https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy-Report-Only diff --git a/config/initializers/new_framework_defaults_6_0.rb b/config/initializers/new_framework_defaults_6_0.rb new file mode 100644 index 000000000..92240ef5f --- /dev/null +++ b/config/initializers/new_framework_defaults_6_0.rb @@ -0,0 +1,45 @@ +# Be sure to restart your server when you modify this file. +# +# This file contains migration options to ease your Rails 6.0 upgrade. +# +# Once upgraded flip defaults one by one to migrate to the new default. +# +# Read the Guide for Upgrading Ruby on Rails for more info on each option. + +# Don't force requests from old versions of IE to be UTF-8 encoded. +# Rails.application.config.action_view.default_enforce_utf8 = false + +# Embed purpose and expiry metadata inside signed and encrypted +# cookies for increased security. +# +# This option is not backwards compatible with earlier Rails versions. +# It's best enabled when your entire app is migrated and stable on 6.0. +# Rails.application.config.action_dispatch.use_cookies_with_metadata = true + +# Change the return value of `ActionDispatch::Response#content_type` to Content-Type header without modification. +# Rails.application.config.action_dispatch.return_only_media_type_on_content_type = false + +# Return false instead of self when enqueuing is aborted from a callback. +# Rails.application.config.active_job.return_false_on_aborted_enqueue = true + +# Send Active Storage analysis and purge jobs to dedicated queues. +# Rails.application.config.active_storage.queues.analysis = :active_storage_analysis +# Rails.application.config.active_storage.queues.purge = :active_storage_purge + +# When assigning to a collection of attachments declared via `has_many_attached`, replace existing +# attachments instead of appending. Use #attach to add new attachments without replacing existing ones. +# Rails.application.config.active_storage.replace_on_assign_to_many = true + +# Use ActionMailer::MailDeliveryJob for sending parameterized and normal mail. +# +# The default delivery jobs (ActionMailer::Parameterized::DeliveryJob, ActionMailer::DeliveryJob), +# will be removed in Rails 6.1. This setting is not backwards compatible with earlier Rails versions. +# If you send mail in the background, job workers need to have a copy of +# MailDeliveryJob to ensure all delivery jobs are processed properly. +# Make sure your entire app is migrated and stable on 6.0 before using this setting. +# Rails.application.config.action_mailer.delivery_job = "ActionMailer::MailDeliveryJob" + +# Enable the same cache key to be reused when the object being cached of type +# `ActiveRecord::Relation` changes by moving the volatile information (max updated at and count) +# of the relation's cache key into the cache version to support recycling cache key. +# Rails.application.config.active_record.collection_cache_versioning = true diff --git a/db/migrate/20210924194527_add_foreign_key_constraint_to_active_storage_attachments_for_blob_id.active_storage.rb b/db/migrate/20210924194527_add_foreign_key_constraint_to_active_storage_attachments_for_blob_id.active_storage.rb new file mode 100644 index 000000000..ff5d72c7e --- /dev/null +++ b/db/migrate/20210924194527_add_foreign_key_constraint_to_active_storage_attachments_for_blob_id.active_storage.rb @@ -0,0 +1,10 @@ +# This migration comes from active_storage (originally 20180723000244) +class AddForeignKeyConstraintToActiveStorageAttachmentsForBlobId < ActiveRecord::Migration[6.0] + def up + return if foreign_key_exists?(:active_storage_attachments, column: :blob_id) + + if table_exists?(:active_storage_blobs) + add_foreign_key :active_storage_attachments, :active_storage_blobs, column: :blob_id + end + end +end diff --git a/db/schema.rb b/db/schema.rb index 8d87806d6..b3cac4d02 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -2,11 +2,11 @@ # of editing this file, please use the migrations feature of Active Record to # incrementally modify your database, and then regenerate this schema definition. # -# Note that this schema.rb definition is the authoritative source for your -# database schema. If you need to create the application database on another -# system, you should be using db:schema:load, not running all the migrations -# from scratch. The latter is a flawed and unsustainable approach (the more migrations -# you'll amass, the slower it'll run and the greater likelihood for issues). +# This file is the source Rails uses to define your schema when running `rails +# db:schema:load`. When creating a new database, `rails db:schema:load` tends to +# be faster and is potentially less error prone than running all of your +# migrations from scratch. Old migrations may fail to apply correctly if those +# migrations use external dependencies or application code. # # It's strongly recommended that you check this file into your version control system. diff --git a/spec/lib/tasks/files_spec.rb b/spec/lib/tasks/files_spec.rb index 4d55334bb..5671aa208 100644 --- a/spec/lib/tasks/files_spec.rb +++ b/spec/lib/tasks/files_spec.rb @@ -12,7 +12,9 @@ describe "files tasks" do document = build(:document) image.attachment.blob.save! + image.attachment_changes["attachment"].upload document.attachment.blob.save! + document.attachment_changes["attachment"].upload travel_to(2.days.from_now) { run_rake_task } @@ -25,7 +27,9 @@ describe "files tasks" do document = build(:document) image.attachment.blob.save! + image.attachment_changes["attachment"].upload document.attachment.blob.save! + document.attachment_changes["attachment"].upload travel_to(2.minutes.from_now) { run_rake_task } diff --git a/spec/shared/system/relationable.rb b/spec/shared/system/relationable.rb index 5eb40de4f..50246fb29 100644 --- a/spec/shared/system/relationable.rb +++ b/spec/shared/system/relationable.rb @@ -3,7 +3,11 @@ shared_examples "relationable" do |relationable_model_name| let(:related1) { create([:proposal, :debate, :budget_investment].sample) } let(:related2) { create([:proposal, :debate, :budget_investment].sample) } let(:user) { create(:user) } - before { Setting["url"] = Capybara.app_host } + + before do + integration_session.host = Capybara.app_host # TODO: remove after upgrading to Rails 6.1 + Setting["url"] = Capybara.app_host + end scenario "related contents are listed" do create(:related_content, parent_relationable: relationable, child_relationable: related1, author: build(:user)) diff --git a/spec/system/admin/budget_investments_spec.rb b/spec/system/admin/budget_investments_spec.rb index 6430f62da..82af1feb0 100644 --- a/spec/system/admin/budget_investments_spec.rb +++ b/spec/system/admin/budget_investments_spec.rb @@ -1709,7 +1709,7 @@ describe "Admin budget investments", :admin do header = page.response_headers["Content-Disposition"] expect(header).to match(/^attachment/) - expect(header).to match(/filename="budget_investments.csv"$/) + expect(header).to match(/filename="budget_investments.csv"/) csv_contents = "ID,Title,Supports,Administrator,Valuator,Valuation Group,Scope of operation,"\ "Feasibility,Val. Fin.,Selected,Show to valuators,Author username\n"\ diff --git a/spec/system/admin/emails/emails_download_spec.rb b/spec/system/admin/emails/emails_download_spec.rb index 26facab75..cabfcf5c3 100644 --- a/spec/system/admin/emails/emails_download_spec.rb +++ b/spec/system/admin/emails/emails_download_spec.rb @@ -32,7 +32,7 @@ describe "Admin download user emails" do header = page.response_headers["Content-Disposition"] expect(header).to match(/^attachment/) - expect(header).to match(/filename="Administrators.csv"$/) + expect(header).to match(/filename="Administrators.csv"/) file_contents = page.body.split(",") expect(file_contents).to match_array ["admin_news1@consul.dev", "admin_news2@consul.dev"]