diff --git a/.rubocop.yml b/.rubocop.yml index 2cf085d92..9941c7659 100644 --- a/.rubocop.yml +++ b/.rubocop.yml @@ -253,7 +253,6 @@ Rails/OutputSafety: Severity: warning Exclude: - app/helpers/text_with_links_helper.rb - - config/initializers/escape_javascript_fix.rb Rails/PluralizationGrammar: Enabled: true diff --git a/Gemfile b/Gemfile index 806cd94c5..32e1f6f0a 100644 --- a/Gemfile +++ b/Gemfile @@ -1,6 +1,6 @@ source "https://rubygems.org" -gem "rails", "5.1.7" +gem "rails", "5.2.4.4" gem "acts-as-taggable-on", "~> 6.5.0" gem "acts_as_votable", "~> 0.12.1" diff --git a/Gemfile.lock b/Gemfile.lock index 7c6df00e9..89922ea49 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -10,39 +10,43 @@ GEM remote: https://rubygems.org/ remote: https://rails-assets.org/ specs: - actioncable (5.1.7) - actionpack (= 5.1.7) + actioncable (5.2.4.4) + actionpack (= 5.2.4.4) nio4r (~> 2.0) - websocket-driver (~> 0.6.1) - actionmailer (5.1.7) - actionpack (= 5.1.7) - actionview (= 5.1.7) - activejob (= 5.1.7) + websocket-driver (>= 0.6.1) + actionmailer (5.2.4.4) + actionpack (= 5.2.4.4) + actionview (= 5.2.4.4) + activejob (= 5.2.4.4) mail (~> 2.5, >= 2.5.4) rails-dom-testing (~> 2.0) - actionpack (5.1.7) - actionview (= 5.1.7) - activesupport (= 5.1.7) - rack (~> 2.0) + actionpack (5.2.4.4) + actionview (= 5.2.4.4) + activesupport (= 5.2.4.4) + 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.1.7) - activesupport (= 5.1.7) + actionview (5.2.4.4) + activesupport (= 5.2.4.4) builder (~> 3.1) erubi (~> 1.4) rails-dom-testing (~> 2.0) rails-html-sanitizer (~> 1.0, >= 1.0.3) - activejob (5.1.7) - activesupport (= 5.1.7) + activejob (5.2.4.4) + activesupport (= 5.2.4.4) globalid (>= 0.3.6) - activemodel (5.1.7) - activesupport (= 5.1.7) - activerecord (5.1.7) - activemodel (= 5.1.7) - activesupport (= 5.1.7) - arel (~> 8.0) - activesupport (5.1.7) + activemodel (5.2.4.4) + activesupport (= 5.2.4.4) + activerecord (5.2.4.4) + activemodel (= 5.2.4.4) + activesupport (= 5.2.4.4) + arel (>= 9.0) + activestorage (5.2.4.4) + actionpack (= 5.2.4.4) + activerecord (= 5.2.4.4) + marcel (~> 0.3.1) + activesupport (5.2.4.4) concurrent-ruby (~> 1.0, >= 1.0.2) i18n (>= 0.7, < 2) minitest (~> 5.1) @@ -73,7 +77,7 @@ GEM nokogiri ancestry (3.2.1) activerecord (>= 4.2.0) - arel (8.0.0) + arel (9.0.0) ast (2.4.1) audited (4.9.0) activerecord (>= 4.2, < 6.1) @@ -338,6 +342,8 @@ GEM nokogiri (>= 1.5.9) mail (2.7.1) mini_mime (>= 0.1.1) + marcel (0.3.3) + mimemagic (~> 0.3.2) mdl (0.11.0) kramdown (~> 2.3) kramdown-parser-gfm (~> 1.1) @@ -427,17 +433,18 @@ GEM rack rack-test (1.1.0) rack (>= 1.0, < 3) - rails (5.1.7) - actioncable (= 5.1.7) - actionmailer (= 5.1.7) - actionpack (= 5.1.7) - actionview (= 5.1.7) - activejob (= 5.1.7) - activemodel (= 5.1.7) - activerecord (= 5.1.7) - activesupport (= 5.1.7) + rails (5.2.4.4) + actioncable (= 5.2.4.4) + actionmailer (= 5.2.4.4) + actionpack (= 5.2.4.4) + actionview (= 5.2.4.4) + activejob (= 5.2.4.4) + activemodel (= 5.2.4.4) + activerecord (= 5.2.4.4) + activestorage (= 5.2.4.4) + activesupport (= 5.2.4.4) bundler (>= 1.3.0) - railties (= 5.1.7) + railties (= 5.2.4.4) sprockets-rails (>= 2.0.0) rails-assets-leaflet (1.5.1) rails-assets-markdown-it (9.0.1) @@ -449,12 +456,12 @@ GEM rails-i18n (5.1.3) i18n (>= 0.7, < 2) railties (>= 5.0, < 6) - railties (5.1.7) - actionpack (= 5.1.7) - activesupport (= 5.1.7) + railties (5.2.4.4) + actionpack (= 5.2.4.4) + activesupport (= 5.2.4.4) method_source rake (>= 0.8.7) - thor (>= 0.18.1, < 2.0) + thor (>= 0.19.0, < 2.0) rainbow (3.0.0) rake (13.0.1) rb-fsevent (0.10.4) @@ -615,7 +622,7 @@ GEM nokogiri (~> 1.6) rubyzip (>= 1.3.0) selenium-webdriver (>= 3.0, < 4.0) - websocket-driver (0.6.5) + websocket-driver (0.7.3) websocket-extensions (>= 0.1.0) websocket-extensions (0.1.5) whenever (1.0.0) @@ -694,7 +701,7 @@ DEPENDENCIES pg (~> 1.0.0) pg_search (~> 2.3.0) puma (~> 4.3.6) - rails (= 5.1.7) + rails (= 5.2.4.4) rails-assets-leaflet! rails-assets-markdown-it (~> 9.0.1)! recipient_interceptor (~> 0.2.0) diff --git a/app/controllers/admin/geozones_controller.rb b/app/controllers/admin/geozones_controller.rb index 6e3b0843a..1b924d444 100644 --- a/app/controllers/admin/geozones_controller.rb +++ b/app/controllers/admin/geozones_controller.rb @@ -4,7 +4,7 @@ class Admin::GeozonesController < Admin::BaseController load_and_authorize_resource def index - @geozones = Geozone.all.order("LOWER(name)") + @geozones = Geozone.all.order(Arel.sql("LOWER(name)")) end def new diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb index 32cdbb135..5b74ae2e7 100644 --- a/app/controllers/application_controller.rb +++ b/app/controllers/application_controller.rb @@ -7,7 +7,6 @@ class ApplicationController < ActionController::Base include AccessDeniedHandler default_form_builder ConsulFormBuilder - protect_from_forgery with: :exception before_action :authenticate_http_basic, if: :http_basic_auth_site? diff --git a/app/controllers/legislation/annotations_controller.rb b/app/controllers/legislation/annotations_controller.rb index a238e064e..1d26211c2 100644 --- a/app/controllers/legislation/annotations_controller.rb +++ b/app/controllers/legislation/annotations_controller.rb @@ -61,7 +61,7 @@ class Legislation::AnnotationsController < Legislation::BaseController end def search - @annotations = @draft_version.annotations.order("LENGTH(quote) DESC") + @annotations = @draft_version.annotations.order(Arel.sql("LENGTH(quote) DESC")) annotations_hash = { total: @annotations.size, rows: @annotations } render json: annotations_hash.to_json(methods: :weight) end diff --git a/app/controllers/management/base_controller.rb b/app/controllers/management/base_controller.rb index 6a2788718..d0180b0a7 100644 --- a/app/controllers/management/base_controller.rb +++ b/app/controllers/management/base_controller.rb @@ -2,7 +2,6 @@ class Management::BaseController < ActionController::Base include GlobalizeFallbacks layout "management" default_form_builder ConsulFormBuilder - protect_from_forgery with: :exception before_action :verify_manager before_action :set_locale diff --git a/app/controllers/management/sessions_controller.rb b/app/controllers/management/sessions_controller.rb index d2fdfe3eb..84d9d1265 100644 --- a/app/controllers/management/sessions_controller.rb +++ b/app/controllers/management/sessions_controller.rb @@ -4,7 +4,6 @@ class Management::SessionsController < ActionController::Base include GlobalizeFallbacks include AccessDeniedHandler default_form_builder ConsulFormBuilder - protect_from_forgery with: :exception def create destroy_session diff --git a/app/models/application_record.rb b/app/models/application_record.rb index 4c7aa15dc..50235a9ca 100644 --- a/app/models/application_record.rb +++ b/app/models/application_record.rb @@ -3,9 +3,9 @@ class ApplicationRecord < ActiveRecord::Base def self.sample(count = 1) if count == 1 - reorder("RANDOM()").first + reorder(Arel.sql("RANDOM()")).first else - reorder("RANDOM()").limit(count) + reorder(Arel.sql("RANDOM()")).limit(count) end end end diff --git a/app/models/comment.rb b/app/models/comment.rb index 7af862a73..f6607a849 100644 --- a/app/models/comment.rb +++ b/app/models/comment.rb @@ -49,7 +49,7 @@ class Comment < ApplicationRecord scope :sort_by_most_voted, -> { order(confidence_score: :desc, created_at: :desc) } scope :sort_descendants_by_most_voted, -> { order(confidence_score: :desc, created_at: :asc) } - scope :sort_by_supports, -> { order("cached_votes_up - cached_votes_down DESC") } + scope :sort_by_supports, -> { order(Arel.sql("cached_votes_up - cached_votes_down DESC")) } scope :sort_by_newest, -> { order(created_at: :desc) } scope :sort_descendants_by_newest, -> { order(created_at: :desc) } diff --git a/app/models/poll/question.rb b/app/models/poll/question.rb index 3e95997df..6f489c8d8 100644 --- a/app/models/poll/question.rb +++ b/app/models/poll/question.rb @@ -28,7 +28,7 @@ class Poll::Question < ApplicationRecord scope :by_poll_id, ->(poll_id) { where(poll_id: poll_id) } - scope :sort_for_list, -> { order("poll_questions.proposal_id IS NULL", :created_at) } + scope :sort_for_list, -> { order(Arel.sql("poll_questions.proposal_id IS NULL"), :created_at) } scope :for_render, -> { includes(:author, :proposal) } def self.search(params) diff --git a/bin/bundle b/bin/bundle index fe1874509..67efc37fb 100755 --- a/bin/bundle +++ b/bin/bundle @@ -1,3 +1,3 @@ #!/usr/bin/env ruby -ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../../Gemfile", __FILE__) +ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../Gemfile", __dir__) load Gem.bin_path("bundler", "bundle") diff --git a/bin/setup b/bin/setup index 4ccb4facf..aa921f10d 100755 --- a/bin/setup +++ b/bin/setup @@ -1,10 +1,9 @@ #!/usr/bin/env ruby -require "pathname" require "fileutils" include FileUtils # path to your application root. -APP_ROOT = Pathname.new File.expand_path("../../", __FILE__) +APP_ROOT = File.expand_path("..", __dir__) def system!(*args) system(*args) || abort("\n== Command #{args} failed ==") diff --git a/bin/update b/bin/update index 770b84062..80e5352ad 100755 --- a/bin/update +++ b/bin/update @@ -1,10 +1,9 @@ #!/usr/bin/env ruby -require "pathname" require "fileutils" include FileUtils # path to your application root. -APP_ROOT = Pathname.new File.expand_path("../../", __FILE__) +APP_ROOT = File.expand_path("..", __dir__) def system!(*args) system(*args) || abort("\n== Command #{args} failed ==") diff --git a/config/application.rb b/config/application.rb index feb4c8664..819918788 100644 --- a/config/application.rb +++ b/config/application.rb @@ -1,6 +1,17 @@ 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_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. @@ -8,7 +19,7 @@ Bundler.require(*Rails.groups) module Consul class Application < Rails::Application - config.load_defaults 5.1 + config.load_defaults 5.2 # Keep belongs_to fields optional by default, because that's the way # Rails 4 models worked @@ -17,6 +28,14 @@ module Consul # Use local forms with `form_with`, so it works like `form_for` config.action_view.form_with_generates_remote_forms = false + # Keep disabling cache versioning until we verify it's compatible + # with `:dalli_store` and with the way we cache stats + config.active_record.cache_versioning = false + + # Keep using AES-256-CBC for message encryption in case it's used + # in any CONSUL installations + config.active_support.use_authenticated_message_encryption = false + # Set Time.zone default to the specified zone and make Active Record auto-convert to this zone. # Run "rake -D time" for a list of tasks for finding time zone names. Default is UTC. # config.time_zone = 'Central Time (US & Canada)' diff --git a/config/environments/development.rb b/config/environments/development.rb index 07840b58c..646ee316d 100644 --- a/config/environments/development.rb +++ b/config/environments/development.rb @@ -13,12 +13,13 @@ Rails.application.configure do config.consider_all_requests_local = true # Enable/disable caching. By default caching is disabled. - if Rails.root.join("tmp/caching-dev.txt").exist? + # Run rails dev:cache to toggle caching. + if Rails.root.join("tmp", "caching-dev.txt").exist? config.action_controller.perform_caching = true config.cache_store = :memory_store config.public_file_server.headers = { - "Cache-Control" => "public, max-age=172800" + "Cache-Control" => "public, max-age=#{2.days.to_i}" } else config.action_controller.perform_caching = false @@ -41,6 +42,9 @@ Rails.application.configure do # Raise an error on page load if there are pending migrations. config.active_record.migration_error = :page_load + # Highlight code that triggered database queries in logs. + config.active_record.verbose_query_logs = true + # Debug mode disables concatenation and preprocessing of assets. # This option may cause significant delays in view rendering with a large # number of complex assets. diff --git a/config/environments/test.rb b/config/environments/test.rb index c7059f5c1..6ebbecbfc 100644 --- a/config/environments/test.rb +++ b/config/environments/test.rb @@ -20,7 +20,7 @@ Rails.application.configure do # Configure public file server for tests with Cache-Control for performance. config.public_file_server.enabled = true config.public_file_server.headers = { - "Cache-Control" => "public, max-age=3600" + "Cache-Control" => "public, max-age=#{1.hour.to_i}" } # Show full error reports and disable caching. diff --git a/config/initializers/application_controller_renderer.rb b/config/initializers/application_controller_renderer.rb index 51639b67a..89d2efab2 100644 --- a/config/initializers/application_controller_renderer.rb +++ b/config/initializers/application_controller_renderer.rb @@ -1,6 +1,8 @@ # Be sure to restart your server when you modify this file. -# ApplicationController.renderer.defaults.merge!( -# http_host: 'example.org', -# https: false -# ) +# ActiveSupport::Reloader.to_prepare do +# ApplicationController.renderer.defaults.merge!( +# http_host: 'example.org', +# https: false +# ) +# end diff --git a/config/initializers/content_security_policy.rb b/config/initializers/content_security_policy.rb new file mode 100644 index 000000000..d3bcaa5ec --- /dev/null +++ b/config/initializers/content_security_policy.rb @@ -0,0 +1,25 @@ +# Be sure to restart your server when you modify this file. + +# Define an application-wide content security policy +# For further information see the following documentation +# https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy + +# Rails.application.config.content_security_policy do |policy| +# policy.default_src :self, :https +# policy.font_src :self, :https, :data +# policy.img_src :self, :https, :data +# policy.object_src :none +# policy.script_src :self, :https +# policy.style_src :self, :https + +# # Specify URI for violation reports +# # policy.report_uri "/csp-violation-report-endpoint" +# end + +# If you are using UJS then enable automatic nonce generation +# Rails.application.config.content_security_policy_nonce_generator = -> request { SecureRandom.base64(16) } + +# 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 +# Rails.application.config.content_security_policy_report_only = true diff --git a/config/initializers/escape_javascript_fix.rb b/config/initializers/escape_javascript_fix.rb deleted file mode 100644 index 0f693fdf6..000000000 --- a/config/initializers/escape_javascript_fix.rb +++ /dev/null @@ -1,25 +0,0 @@ -# Code taken from https://github.com/rails/rails/security/advisories/GHSA-65cv-r6x7-79hv -# Remove this code after upgrading to Rails 5.2 -ActionView::Helpers::JavaScriptHelper::JS_ESCAPE_MAP.merge!( - { - "`" => "\\`", - "$" => "\\$" - } -) - -module ActionView::Helpers::JavaScriptHelper - alias :old_ej :escape_javascript - alias :old_j :j - - def escape_javascript(javascript) - javascript = javascript.to_s - if javascript.empty? - result = "" - else - result = javascript.gsub(/(\\|<\/|\r\n|\342\200\250|\342\200\251|[\n\r"']|[`]|[$])/u, JS_ESCAPE_MAP) - end - javascript.html_safe? ? result.html_safe : result - end - - alias :j :escape_javascript -end diff --git a/db/schema.rb b/db/schema.rb index fa1e0aa14..31ebc6540 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -10,12 +10,12 @@ # # It's strongly recommended that you check this file into your version control system. -ActiveRecord::Schema.define(version: 20200908084257) do +ActiveRecord::Schema.define(version: 2020_09_08_084257) do # These are extensions that must be enabled in order to support this database + enable_extension "pg_trgm" enable_extension "plpgsql" enable_extension "unaccent" - enable_extension "pg_trgm" create_table "active_poll_translations", id: :serial, force: :cascade do |t| t.integer "active_poll_id", null: false diff --git a/spec/controllers/legislation/processes_controller_spec.rb b/spec/controllers/legislation/processes_controller_spec.rb index c15a293f3..98dd33ec9 100644 --- a/spec/controllers/legislation/processes_controller_spec.rb +++ b/spec/controllers/legislation/processes_controller_spec.rb @@ -8,6 +8,6 @@ describe Legislation::ProcessesController do get :summary, params: { id: legislation_process, format: :xlsx } - expect(response).to be_success + expect(response).to be_successful end end diff --git a/spec/rails_helper.rb b/spec/rails_helper.rb index 3de8fd85d..c4756dd02 100644 --- a/spec/rails_helper.rb +++ b/spec/rails_helper.rb @@ -19,18 +19,6 @@ Warden.test_mode! ActiveRecord::Migration.maintain_test_schema! -# Monkey patch from https://github.com/rails/rails/pull/32293 -# Remove when we upgrade to Rails 5.2 -require "action_dispatch/system_testing/test_helpers/setup_and_teardown" -module ActionDispatch::SystemTesting::TestHelpers::SetupAndTeardown - def after_teardown - take_failed_screenshot - Capybara.reset_sessions! - ensure - super - end -end - RSpec.configure do |config| config.infer_spec_type_from_file_location! config.after do diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index 7aa19aac4..5a775065f 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -82,12 +82,8 @@ RSpec.configure do |config| .to receive(:available_locales).and_return(I18n.available_locales.map(&:to_s)) end - config.before(:each, :with_frozen_time) do - travel_to Time.current # TODO: use `freeze_time` after migrating to Rails 5.2. - end - - config.after(:each, :with_frozen_time) do - travel_back + config.around(:each, :with_frozen_time) do |example| + freeze_time { example.run } end config.before(:each, :application_zone_west_of_system_zone) do