From 3dee4fe03640f73672e1cb63acaab45344ae195f Mon Sep 17 00:00:00 2001 From: Tomasz Subik Date: Thu, 22 Feb 2024 14:32:27 +0100 Subject: [PATCH 01/10] bump ruby version --- .ruby-version | 2 +- Gemfile | 2 +- Gemfile.lock | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.ruby-version b/.ruby-version index be94e6f53..b347b11ea 100644 --- a/.ruby-version +++ b/.ruby-version @@ -1 +1 @@ -3.2.2 +3.2.3 diff --git a/Gemfile b/Gemfile index 86c792330..ea0c14187 100644 --- a/Gemfile +++ b/Gemfile @@ -2,7 +2,7 @@ source "https://rubygems.org" -ruby "3.2.2" +ruby "3.2.3" git_source(:github) do |repo_name| repo_name = "#{repo_name}/#{repo_name}" unless repo_name.include?("/") diff --git a/Gemfile.lock b/Gemfile.lock index d213e12c7..872c738f6 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -749,7 +749,7 @@ DEPENDENCIES webmock RUBY VERSION - ruby 3.2.2p53 + ruby 3.2.3p157 BUNDLED WITH 2.4.10 From 1e0a2d8e412a34382248fba49285caae6c7303b8 Mon Sep 17 00:00:00 2001 From: Tomasz Subik Date: Thu, 22 Feb 2024 14:33:49 +0100 Subject: [PATCH 02/10] update bundler --- Gemfile.lock | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Gemfile.lock b/Gemfile.lock index 872c738f6..416df2ec2 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -752,4 +752,4 @@ RUBY VERSION ruby 3.2.3p157 BUNDLED WITH - 2.4.10 + 2.5.6 From cf4155f12a93d46d1fb1f8a6ddb13b07e115b086 Mon Sep 17 00:00:00 2001 From: Tomasz Subik Date: Thu, 22 Feb 2024 14:35:13 +0100 Subject: [PATCH 03/10] bundle update --- Gemfile.lock | 208 ++++++++++++++++++++++++++------------------------- 1 file changed, 106 insertions(+), 102 deletions(-) diff --git a/Gemfile.lock b/Gemfile.lock index 416df2ec2..ecbb9cdfe 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -54,47 +54,47 @@ GIT GEM remote: https://rubygems.org/ specs: - actioncable (7.0.8) - actionpack (= 7.0.8) - activesupport (= 7.0.8) + actioncable (7.0.8.1) + actionpack (= 7.0.8.1) + activesupport (= 7.0.8.1) nio4r (~> 2.0) websocket-driver (>= 0.6.1) - actionmailbox (7.0.8) - actionpack (= 7.0.8) - activejob (= 7.0.8) - activerecord (= 7.0.8) - activestorage (= 7.0.8) - activesupport (= 7.0.8) + actionmailbox (7.0.8.1) + actionpack (= 7.0.8.1) + activejob (= 7.0.8.1) + activerecord (= 7.0.8.1) + activestorage (= 7.0.8.1) + activesupport (= 7.0.8.1) mail (>= 2.7.1) net-imap net-pop net-smtp - actionmailer (7.0.8) - actionpack (= 7.0.8) - actionview (= 7.0.8) - activejob (= 7.0.8) - activesupport (= 7.0.8) + actionmailer (7.0.8.1) + actionpack (= 7.0.8.1) + actionview (= 7.0.8.1) + activejob (= 7.0.8.1) + activesupport (= 7.0.8.1) mail (~> 2.5, >= 2.5.4) net-imap net-pop net-smtp rails-dom-testing (~> 2.0) - actionpack (7.0.8) - actionview (= 7.0.8) - activesupport (= 7.0.8) + actionpack (7.0.8.1) + actionview (= 7.0.8.1) + activesupport (= 7.0.8.1) rack (~> 2.0, >= 2.2.4) rack-test (>= 0.6.3) rails-dom-testing (~> 2.0) rails-html-sanitizer (~> 1.0, >= 1.2.0) - actiontext (7.0.8) - actionpack (= 7.0.8) - activerecord (= 7.0.8) - activestorage (= 7.0.8) - activesupport (= 7.0.8) + actiontext (7.0.8.1) + actionpack (= 7.0.8.1) + activerecord (= 7.0.8.1) + activestorage (= 7.0.8.1) + activesupport (= 7.0.8.1) globalid (>= 0.6.0) nokogiri (>= 1.8.5) - actionview (7.0.8) - activesupport (= 7.0.8) + actionview (7.0.8.1) + activesupport (= 7.0.8.1) builder (~> 3.1) erubi (~> 1.4) rails-dom-testing (~> 2.0) @@ -119,27 +119,27 @@ GEM xdan-datetimepicker-rails (~> 2.5.1) activeadmin_quill_editor (1.1.0) activeadmin (>= 2.0, < 4) - activejob (7.0.8) - activesupport (= 7.0.8) + activejob (7.0.8.1) + activesupport (= 7.0.8.1) globalid (>= 0.3.6) - activemodel (7.0.8) - activesupport (= 7.0.8) - activerecord (7.0.8) - activemodel (= 7.0.8) - activesupport (= 7.0.8) + activemodel (7.0.8.1) + activesupport (= 7.0.8.1) + activerecord (7.0.8.1) + activemodel (= 7.0.8.1) + activesupport (= 7.0.8.1) activerecord-import (1.5.1) activerecord (>= 4.2) activerecord-postgis-adapter (8.0.3) activerecord (~> 7.0.0) rgeo-activerecord (~> 7.0.0) - activestorage (7.0.8) - actionpack (= 7.0.8) - activejob (= 7.0.8) - activerecord (= 7.0.8) - activesupport (= 7.0.8) + activestorage (7.0.8.1) + actionpack (= 7.0.8.1) + activejob (= 7.0.8.1) + activerecord (= 7.0.8.1) + activesupport (= 7.0.8.1) marcel (~> 1.0) mini_mime (>= 1.1.0) - activesupport (7.0.8) + activesupport (7.0.8.1) concurrent-ruby (~> 1.0, >= 1.0.2) i18n (>= 1.6, < 2) minitest (>= 5.1) @@ -158,12 +158,13 @@ GEM ruby2_keywords (>= 0.0.2) ast (2.4.2) attr_extras (7.1.0) + base64 (0.2.0) bcrypt (3.1.20) bigdecimal (3.1.6) bindex (0.8.1) - bootsnap (1.17.1) + bootsnap (1.18.3) msgpack (~> 1.2) - brakeman (6.1.1) + brakeman (6.1.2) racc builder (3.2.4) bullet (7.1.6) @@ -193,11 +194,11 @@ GEM capistrano-rvm (0.1.2) capistrano (~> 3.0) sshkit (~> 1.2) - capybara (3.39.2) + capybara (3.40.0) addressable matrix mini_mime (>= 0.1.3) - nokogiri (~> 1.8) + nokogiri (~> 1.11) rack (>= 1.6.0) rack-test (>= 0.6.3) regexp_parser (>= 1.5, < 3.0) @@ -217,9 +218,10 @@ GEM choice (0.2.0) concurrent-ruby (1.2.3) connection_pool (2.4.1) - countries (5.7.1) + countries (6.0.0) unaccent (~> 0.3) - crack (0.4.5) + crack (1.0.0) + bigdecimal rexml crass (1.0.6) cuprite (0.15) @@ -241,7 +243,7 @@ GEM railties (>= 4.1.0) responders warden (~> 1.2.3) - diff-lcs (1.5.0) + diff-lcs (1.5.1) docile (1.4.0) domain_name (0.6.20240107) dotenv (2.8.1) @@ -254,7 +256,7 @@ GEM mail (~> 2.7) erubi (1.12.0) execjs (2.9.1) - factory_bot (6.4.5) + factory_bot (6.4.6) activesupport (>= 5.0.0) factory_bot_rails (6.4.3) factory_bot (~> 6.4) @@ -286,11 +288,12 @@ GEM activesupport (>= 5.2) hashdiff (1.1.0) htmlentities (4.3.4) - http (5.1.1) + http (5.2.0) addressable (~> 2.8) + base64 (~> 0.1) http-cookie (~> 1.0) http-form_data (~> 2.2) - llhttp-ffi (~> 0.4.0) + llhttp-ffi (~> 0.5.0) http-cookie (1.0.5) domain_name (~> 0.5) http-form_data (2.3.0) @@ -309,7 +312,7 @@ GEM responders (>= 2) interactor (3.1.2) io-console (0.7.2) - irb (1.11.1) + irb (1.11.2) rdoc reline (>= 0.4.2) jquery-rails (4.6.0) @@ -321,7 +324,8 @@ GEM activerecord (>= 4.1) concurrent-ruby railties (>= 4.1) - jwt (2.7.1) + jwt (2.8.0) + base64 kaminari (1.2.2) activesupport (>= 4.1.0) kaminari-actionview (= 1.2.2) @@ -337,7 +341,7 @@ GEM language_server-protocol (3.17.0.3) launchy (2.5.2) addressable (~> 2.8) - letter_opener (1.8.1) + letter_opener (1.9.0) launchy (>= 2.2, < 3) letter_opener_web (2.0.0) actionmailer (>= 5.2) @@ -345,7 +349,7 @@ GEM railties (>= 5.2) rexml lint_roller (1.1.0) - llhttp-ffi (0.4.0) + llhttp-ffi (0.5.0) ffi-compiler (~> 1.0) rake (~> 13.0) loofah (2.22.0) @@ -361,16 +365,16 @@ GEM method_source (1.0.0) mime-types (3.5.2) mime-types-data (~> 3.2015) - mime-types-data (3.2023.1205) + mime-types-data (3.2024.0206) mini_magick (4.12.0) mini_mime (1.1.5) mini_portile2 (2.8.5) - minitest (5.21.2) - mjml-rails (4.10.0) + minitest (5.22.2) + mjml-rails (4.10.1) msgpack (1.7.2) mustache (1.1.1) mutex_m (0.2.0) - net-imap (0.4.9.1) + net-imap (0.4.10) date net-protocol net-pop (0.1.2) @@ -385,10 +389,10 @@ GEM net-protocol net-ssh (7.2.1) nio4r (2.7.0) - nokogiri (1.16.0) + nokogiri (1.16.2) mini_portile2 (~> 2.8.2) racc (~> 1.4) - nokogiri (1.16.0-x86_64-linux) + nokogiri (1.16.2-x86_64-linux) racc (~> 1.4) oj (3.16.3) bigdecimal (>= 3.0) @@ -401,19 +405,19 @@ GEM parallel (1.24.0) paranoia (2.5.3) activerecord (>= 5.1, < 7.1) - parser (3.3.0.4) + parser (3.3.0.5) ast (~> 2.4.1) racc patience_diff (1.2.0) optimist (~> 3.0) - pg (1.5.4) + pg (1.5.5) psych (5.1.2) stringio public_suffix (5.0.4) puma (6.4.2) nio4r (~> 2.0) racc (1.7.3) - rack (2.2.8) + rack (2.2.8.1) rack-cors (2.0.1) rack (>= 2.0.0) rack-mini-profiler (2.3.4) @@ -422,20 +426,20 @@ GEM rack (< 3) rack-test (2.1.0) rack (>= 1.3) - rails (7.0.8) - actioncable (= 7.0.8) - actionmailbox (= 7.0.8) - actionmailer (= 7.0.8) - actionpack (= 7.0.8) - actiontext (= 7.0.8) - actionview (= 7.0.8) - activejob (= 7.0.8) - activemodel (= 7.0.8) - activerecord (= 7.0.8) - activestorage (= 7.0.8) - activesupport (= 7.0.8) + rails (7.0.8.1) + actioncable (= 7.0.8.1) + actionmailbox (= 7.0.8.1) + actionmailer (= 7.0.8.1) + actionpack (= 7.0.8.1) + actiontext (= 7.0.8.1) + actionview (= 7.0.8.1) + activejob (= 7.0.8.1) + activemodel (= 7.0.8.1) + activerecord (= 7.0.8.1) + activestorage (= 7.0.8.1) + activesupport (= 7.0.8.1) bundler (>= 1.15.0) - railties (= 7.0.8) + railties (= 7.0.8.1) rails-dom-testing (2.2.0) activesupport (>= 5.0.0) minitest @@ -448,9 +452,9 @@ GEM rails-html-sanitizer (1.6.0) loofah (~> 2.21) nokogiri (~> 1.14) - railties (7.0.8) - actionpack (= 7.0.8) - activesupport (= 7.0.8) + railties (7.0.8.1) + actionpack (= 7.0.8.1) + activesupport (= 7.0.8.1) method_source rake (>= 12.2) thor (~> 1.0) @@ -463,7 +467,7 @@ GEM i18n rdoc (6.6.2) psych (>= 4.0.0) - redis (5.0.8) + redis (5.1.0) redis-client (>= 0.17.0) redis-actionpack (5.4.0) actionpack (>= 5, < 8) @@ -472,7 +476,7 @@ GEM redis-activesupport (5.3.0) activesupport (>= 3, < 8) redis-store (>= 1.3, < 2) - redis-client (0.19.1) + redis-client (0.20.0) connection_pool redis-rack (3.0.0) rack-session (>= 0.2.0) @@ -486,7 +490,7 @@ GEM regexp_parser (2.9.0) reline (0.4.2) io-console (~> 0.5) - request_store (1.5.1) + request_store (1.6.0) rack (>= 1.4) require_all (3.0.0) responders (3.1.1) @@ -499,22 +503,22 @@ GEM rgeo (>= 1.0.0) rgeo-geojson (2.1.1) rgeo (>= 1.0.0) - rspec (3.12.0) - rspec-core (~> 3.12.0) - rspec-expectations (~> 3.12.0) - rspec-mocks (~> 3.12.0) + rspec (3.13.0) + rspec-core (~> 3.13.0) + rspec-expectations (~> 3.13.0) + rspec-mocks (~> 3.13.0) rspec-activejob (0.6.1) activejob (>= 4.2) rspec-mocks - rspec-core (3.12.2) - rspec-support (~> 3.12.0) - rspec-expectations (3.12.3) + rspec-core (3.13.0) + rspec-support (~> 3.13.0) + rspec-expectations (3.13.0) diff-lcs (>= 1.2.0, < 2.0) - rspec-support (~> 3.12.0) - rspec-mocks (3.12.6) + rspec-support (~> 3.13.0) + rspec-mocks (3.13.0) diff-lcs (>= 1.2.0, < 2.0) - rspec-support (~> 3.12.0) - rspec-rails (6.1.0) + rspec-support (~> 3.13.0) + rspec-rails (6.1.1) actionpack (>= 6.1) activesupport (>= 6.1) railties (>= 6.1) @@ -522,18 +526,18 @@ GEM rspec-expectations (~> 3.12) rspec-mocks (~> 3.12) rspec-support (~> 3.12) - rspec-support (3.12.1) + rspec-support (3.13.0) rswag-api (2.13.0) activesupport (>= 3.1, < 7.2) railties (>= 3.1, < 7.2) rswag-ui (2.13.0) actionpack (>= 3.1, < 7.2) railties (>= 3.1, < 7.2) - rubocop (1.59.0) + rubocop (1.60.2) json (~> 2.3) language_server-protocol (>= 3.17.0) parallel (~> 1.10) - parser (>= 3.2.2.4) + parser (>= 3.3.0.2) rainbow (>= 2.2.2, < 4.0) regexp_parser (>= 1.8, < 3.0) rexml (>= 3.2.5, < 4.0) @@ -553,7 +557,7 @@ GEM ruby-graphviz (1.2.5) rexml ruby-progressbar (1.13.0) - ruby-vips (2.2.0) + ruby-vips (2.2.1) ffi (~> 1.12) ruby2_keywords (0.0.5) ruby_http_client (3.5.5) @@ -580,11 +584,11 @@ GEM concurrent-ruby (~> 1.0, >= 1.0.2) shoulda-matchers (4.0.1) activesupport (>= 4.2.0) - sidekiq (7.2.0) + sidekiq (7.2.2) concurrent-ruby (< 2) connection_pool (>= 2.3.0) rack (>= 2.2.4) - redis-client (>= 0.14.0) + redis-client (>= 0.19.0) simplecov (0.22.0) docile (~> 1.1) simplecov-html (~> 0.11) @@ -604,10 +608,10 @@ GEM net-sftp (>= 2.1.2) net-ssh (>= 2.8.0) ssrf_filter (1.1.2) - standard (1.33.0) + standard (1.34.0) language_server-protocol (~> 3.17.0.2) lint_roller (~> 1.0) - rubocop (~> 1.59.0) + rubocop (~> 1.60) standard-custom (~> 1.0.0) standard-performance (~> 1.3) standard-custom (1.0.2) @@ -617,7 +621,7 @@ GEM lint_roller (~> 1.1) rubocop-performance (~> 1.20.2) stringio (3.1.0) - super_diff (0.10.0) + super_diff (0.11.0) attr_extras (>= 6.2.4) diff-lcs patience_diff @@ -626,7 +630,7 @@ GEM timeout (0.4.1) tzinfo (2.0.6) concurrent-ruby (~> 1.0) - tzinfo-data (1.2023.4) + tzinfo-data (1.2024.1) tzinfo (>= 1.0.0) uglifier (4.2.0) execjs (>= 0.3.0, < 3) @@ -643,7 +647,7 @@ GEM activemodel (>= 6.0.0) bindex (>= 0.4.0) railties (>= 6.0.0) - webmock (3.19.1) + webmock (3.22.0) addressable (>= 2.8.0) crack (>= 0.3.2) hashdiff (>= 0.4.0, < 2.0.0) @@ -656,7 +660,7 @@ GEM rails (>= 3.2.16) xpath (3.2.0) nokogiri (~> 1.8) - zeitwerk (2.6.12) + zeitwerk (2.6.13) PLATFORMS ruby From e5554ac0badd8f69e8cfdcfee92531e0e32a79e2 Mon Sep 17 00:00:00 2001 From: Tomasz Subik Date: Thu, 22 Feb 2024 16:22:11 +0100 Subject: [PATCH 04/10] refactor and update paranoia --- Gemfile | 5 +---- Gemfile.lock | 6 +++--- app/models/operator_document.rb | 33 +++++++++++++++------------------ 3 files changed, 19 insertions(+), 25 deletions(-) diff --git a/Gemfile b/Gemfile index ea0c14187..19428b274 100644 --- a/Gemfile +++ b/Gemfile @@ -37,10 +37,7 @@ gem "groupdate" gem "devise" # Soft Delete -# version 2.6.0 will not work in this app because until the way operator document is regenerated after destroy is changed -# here is the reason https://github.com/rubysherpas/paranoia/pull/485/files#diff-11d24643784dae175b47e4df1207f1184300711d4f728e730c06fbecf300cd7fR76-R77 -# if model is not deleted in destroy action then everything is rolled back -gem "paranoia", "~> 2.5.3" +gem "paranoia" # Rails and DB gem "activerecord-postgis-adapter" diff --git a/Gemfile.lock b/Gemfile.lock index ecbb9cdfe..ea01a2e2c 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -403,8 +403,8 @@ GEM activerecord (>= 5.2) request_store (~> 1.1) parallel (1.24.0) - paranoia (2.5.3) - activerecord (>= 5.1, < 7.1) + paranoia (2.6.3) + activerecord (>= 5.1, < 7.2) parser (3.3.0.5) ast (~> 2.4.1) racc @@ -717,7 +717,7 @@ DEPENDENCIES oj oj_mimic_json paper_trail - paranoia (~> 2.5.3) + paranoia pg puma rack-cors diff --git a/app/models/operator_document.rb b/app/models/operator_document.rb index 46a6dc2c9..01fd622a9 100644 --- a/app/models/operator_document.rb +++ b/app/models/operator_document.rb @@ -53,7 +53,7 @@ class OperatorDocument < ApplicationRecord before_save :set_type before_create :delete_previous_pending_document - after_destroy :regenerate + after_destroy :create_history after_destroy :recalculate_scores after_save :create_history, if: :saved_changes? after_save :recalculate_scores, if: :saved_change_to_score_related_attributes? @@ -142,27 +142,13 @@ def name_with_fmu "#{required_operator_document.name} (#{fmu.name})" end - private - - def recalculate_scores - return if skip_score_recalculation - - ScoreOperatorDocument.recalculate!(operator) - end - - def saved_change_to_score_related_attributes? - saved_change_to_status? || (!operator.approved? && saved_change_to_public?) - end - - def regenerate + def destroy # rubocop:disable Rails/ActiveRecordOverride # It only allows for (soft) deletion of the operator documents when: # 1 - The Operator was deleted (destroyed_by_association) # 2 - The Fmu was deleted (destroyed_by_association) # 3 - The Required Operator Document was deleted (destroyed_by_association) # 4 - The Operator is no longer active for this Fmu - - create_history and return if destroyed_by_association - create_history and return if fmu_id && (operator_id != fmu.operator&.id) + return super if destroyed_by_association || (fmu_id && (operator_id != fmu.operator&.id)) update!( status: OperatorDocument.statuses[:doc_not_provided], @@ -170,7 +156,18 @@ def regenerate deleted_at: nil, uploaded_by: nil, user_id: nil, reason: nil, note: nil, response_date: nil, source: nil, source_info: nil, document_file_id: nil ) - self.skip_score_recalculation = true + end + + private + + def recalculate_scores + return if skip_score_recalculation + + ScoreOperatorDocument.recalculate!(operator) + end + + def saved_change_to_score_related_attributes? + saved_change_to_status? || (!operator.approved? && saved_change_to_public?) end def set_type From 0dbf6379508dfe5760bfbf8fbc896b221e01b887 Mon Sep 17 00:00:00 2001 From: Tomasz Subik Date: Thu, 22 Feb 2024 16:32:54 +0100 Subject: [PATCH 05/10] update globalize --- Gemfile.lock | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/Gemfile.lock b/Gemfile.lock index ea01a2e2c..4141f4b03 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -26,12 +26,12 @@ GIT GIT remote: https://github.com/tsubik/activeadmin-globalize.git - revision: e1f619939db718bcdb48018c06484508fdc092ed + revision: 6740d360a45c1e36741adc536e402c35e11a39a9 branch: custom specs: activeadmin-globalize (1.0.0.pre) activeadmin (>= 1.0, < 4.0) - globalize (>= 3.1.0, <= 6.2.1) + globalize (>= 3.1.0, <= 6.3) GIT remote: https://github.com/tsubik/rspec-request_snapshot.git @@ -277,9 +277,9 @@ GEM formtastic_i18n (0.7.0) globalid (1.2.1) activesupport (>= 6.1) - globalize (6.2.1) - activemodel (>= 4.2, < 7.1) - activerecord (>= 4.2, < 7.1) + globalize (6.3.0) + activemodel (>= 4.2, < 7.2) + activerecord (>= 4.2, < 7.2) request_store (~> 1.0) groupdate (6.4.0) activesupport (>= 6.1) From 66f574ec0206767408e7017cfd5153f5ed9ff30e Mon Sep 17 00:00:00 2001 From: Tomasz Subik Date: Thu, 22 Feb 2024 17:15:19 +0100 Subject: [PATCH 06/10] WIP: Rails 7.1 upgrade --- .dockerignore | 50 ++++-- .gitignore | 11 ++ .rubocop.yml | 1 + Dockerfile | 97 ++++++----- Gemfile | 2 +- Gemfile.lock | 150 ++++++++++-------- bin/docker-entrypoint | 8 + bin/setup | 2 +- config/application.rb | 11 +- config/environments/development.rb | 10 +- config/environments/e2e.rb | 38 +++-- config/environments/production.rb | 38 +++-- config/environments/staging.rb | 38 +++-- config/environments/test.rb | 24 ++- .../initializers/content_security_policy.rb | 4 +- .../initializers/filter_parameter_logging.rb | 8 +- config/initializers/permissions_policy.rb | 20 +-- spec/models/observation_spec.rb | 2 - spec/rails_helper.rb | 5 + 19 files changed, 326 insertions(+), 193 deletions(-) create mode 100644 bin/docker-entrypoint diff --git a/.dockerignore b/.dockerignore index 49d0c1749..1efbfc9a0 100644 --- a/.dockerignore +++ b/.dockerignore @@ -1,10 +1,42 @@ -.git -.gitignore -.bundle -.gems -.rbenv-gemsets -db/*.sqlite3 -log/* -tmp/* -vendor/bundle +# See https://docs.docker.com/engine/reference/builder/#dockerignore-file for more about ignoring files. + +# Ignore git directory. +/.git/ + +# Ignore bundler config. +/.bundle + +# Ignore all environment files (except templates). +/.env* +!/.env*.erb + +# Ignore all default key files. +/config/master.key +/config/credentials/*.key + +# Ignore all logfiles and tempfiles. +/log/* +/tmp/* +!/log/.keep +!/tmp/.keep + +# Ignore pidfiles, but keep the directory. +/tmp/pids/* +!/tmp/pids/.keep + +# Ignore storage (uploaded files in development and any SQLite databases). +/storage/* +!/storage/.keep +/tmp/storage/* +!/tmp/storage/.keep + +# Ignore assets. +/node_modules/ +/app/assets/builds/* +!/app/assets/builds/.keep +/public/assets + +# coverage /coverage + +/db/files/.~* diff --git a/.gitignore b/.gitignore index bace5d355..89c3afe8a 100644 --- a/.gitignore +++ b/.gitignore @@ -38,6 +38,7 @@ spec/.DS_Store /dev.env # Ignore the default SQLite database. +# TODO: remove /db/*.sqlite3 /db/*.sqlite3-journal @@ -52,6 +53,13 @@ erd.png /db/dumps/* !/db/dumps/.keep +# Ignore storage (uploaded files in development and any SQLite databases). +/storage/* +!/storage/.keep +/tmp/storage/* +!/tmp/storage/ +!/tmp/storage/.keep + # Ignore IDE files .idea .dir-locals.el @@ -63,3 +71,6 @@ erd.png /spec/support/uploads node_modules + +# Ignore master key for decrypting credentials and more. +/config/master.key diff --git a/.rubocop.yml b/.rubocop.yml index a5880d61a..3993de747 100644 --- a/.rubocop.yml +++ b/.rubocop.yml @@ -15,6 +15,7 @@ AllCops: - 'db/schema.rb' - 'tmp/**/*' - 'bin/**/*' + - 'config/initializers/new_framework_defaults_*' Rails/UnknownEnv: Environments: diff --git a/Dockerfile b/Dockerfile index d5070339e..466a28a0e 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,39 +1,62 @@ -FROM ruby:2.4-alpine -MAINTAINER Sebastian Schkudlara "sebastian.schkudlara@vizzuality.com" - -ENV BUILD_PACKAGES bash curl-dev \ - build-base \ - git \ - libxml2-dev \ - libxslt-dev \ - postgresql-dev \ - nodejs \ - imagemagick-dev \ - xvfb \ - qt5-qtwebkit-dev - -# Update and install all of the required packages. -# At the end, remove the apk cache -RUN apk update && \ - apk upgrade && \ - apk add $BUILD_PACKAGES && \ - rm -rf /var/cache/apk/* - -RUN gem install bundler --no-ri --no-rdoc -RUN QMAKE=/usr/lib/qt5/bin/qmake gem install capybara-webkit --no-ri --no-rdoc - -# Use libxml2, libxslt a packages from alpine for building nokogiri -RUN bundle config build.nokogiri - -RUN mkdir /fti_api - -WORKDIR /fti_api -COPY Gemfile Gemfile -COPY Gemfile.lock Gemfile.lock -RUN bundle install --jobs 20 --retry 5 - -ADD . /fti_api +# syntax = docker/dockerfile:1 -EXPOSE 3000 +# Make sure RUBY_VERSION matches the Ruby version in .ruby-version and Gemfile +ARG RUBY_VERSION=your-ruby-version +FROM registry.docker.com/library/ruby:$RUBY_VERSION-slim as base + +# Rails app lives here +WORKDIR /rails + +# Set production environment +ENV RAILS_ENV="production" \ + BUNDLE_DEPLOYMENT="1" \ + BUNDLE_PATH="/usr/local/bundle" \ + BUNDLE_WITHOUT="development" + + +# Throw-away build stage to reduce size of final image +FROM base as build + +# Install packages needed to build gems +RUN apt-get update -qq && \ + apt-get install --no-install-recommends -y build-essential git libvips pkg-config + +# Install application gems +COPY Gemfile Gemfile.lock ./ +RUN bundle install && \ + rm -rf ~/.bundle/ "${BUNDLE_PATH}"/ruby/*/cache "${BUNDLE_PATH}"/ruby/*/bundler/gems/*/.git && \ + bundle exec bootsnap precompile --gemfile + +# Copy application code +COPY . . + +# Precompile bootsnap code for faster boot times +RUN bundle exec bootsnap precompile app/ lib/ -ENTRYPOINT ["./entrypoint.sh"] +# Precompiling assets for production without requiring secret RAILS_MASTER_KEY +RUN SECRET_KEY_BASE_DUMMY=1 ./bin/rails assets:precompile + + +# Final stage for app image +FROM base + +# Install packages needed for deployment +RUN apt-get update -qq && \ + apt-get install --no-install-recommends -y curl libsqlite3-0 libvips && \ + rm -rf /var/lib/apt/lists /var/cache/apt/archives + +# Copy built artifacts: gems, application +COPY --from=build /usr/local/bundle /usr/local/bundle +COPY --from=build /rails /rails + +# Run and own only the runtime files as a non-root user for security +RUN useradd rails --create-home --shell /bin/bash && \ + chown -R rails:rails db log storage tmp +USER rails:rails + +# Entrypoint prepares the database. +ENTRYPOINT ["/rails/bin/docker-entrypoint"] + +# Start the server by default, this can be overwritten at runtime +EXPOSE 3000 +CMD ["./bin/rails", "server"] diff --git a/Gemfile b/Gemfile index 19428b274..79d578bdd 100644 --- a/Gemfile +++ b/Gemfile @@ -42,7 +42,7 @@ gem "paranoia" # Rails and DB gem "activerecord-postgis-adapter" gem "pg" -gem "rails", "~> 7.0.4" +gem "rails", "~> 7.1.3" gem "rgeo" gem "rgeo-geojson" diff --git a/Gemfile.lock b/Gemfile.lock index 4141f4b03..873888911 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -54,51 +54,55 @@ GIT GEM remote: https://rubygems.org/ specs: - actioncable (7.0.8.1) - actionpack (= 7.0.8.1) - activesupport (= 7.0.8.1) + actioncable (7.1.3.2) + actionpack (= 7.1.3.2) + activesupport (= 7.1.3.2) nio4r (~> 2.0) websocket-driver (>= 0.6.1) - actionmailbox (7.0.8.1) - actionpack (= 7.0.8.1) - activejob (= 7.0.8.1) - activerecord (= 7.0.8.1) - activestorage (= 7.0.8.1) - activesupport (= 7.0.8.1) + zeitwerk (~> 2.6) + actionmailbox (7.1.3.2) + actionpack (= 7.1.3.2) + activejob (= 7.1.3.2) + activerecord (= 7.1.3.2) + activestorage (= 7.1.3.2) + activesupport (= 7.1.3.2) mail (>= 2.7.1) net-imap net-pop net-smtp - actionmailer (7.0.8.1) - actionpack (= 7.0.8.1) - actionview (= 7.0.8.1) - activejob (= 7.0.8.1) - activesupport (= 7.0.8.1) + actionmailer (7.1.3.2) + actionpack (= 7.1.3.2) + actionview (= 7.1.3.2) + activejob (= 7.1.3.2) + activesupport (= 7.1.3.2) mail (~> 2.5, >= 2.5.4) net-imap net-pop net-smtp - rails-dom-testing (~> 2.0) - actionpack (7.0.8.1) - actionview (= 7.0.8.1) - activesupport (= 7.0.8.1) - rack (~> 2.0, >= 2.2.4) + rails-dom-testing (~> 2.2) + actionpack (7.1.3.2) + actionview (= 7.1.3.2) + activesupport (= 7.1.3.2) + nokogiri (>= 1.8.5) + racc + rack (>= 2.2.4) + rack-session (>= 1.0.1) rack-test (>= 0.6.3) - rails-dom-testing (~> 2.0) - rails-html-sanitizer (~> 1.0, >= 1.2.0) - actiontext (7.0.8.1) - actionpack (= 7.0.8.1) - activerecord (= 7.0.8.1) - activestorage (= 7.0.8.1) - activesupport (= 7.0.8.1) + rails-dom-testing (~> 2.2) + rails-html-sanitizer (~> 1.6) + actiontext (7.1.3.2) + actionpack (= 7.1.3.2) + activerecord (= 7.1.3.2) + activestorage (= 7.1.3.2) + activesupport (= 7.1.3.2) globalid (>= 0.6.0) nokogiri (>= 1.8.5) - actionview (7.0.8.1) - activesupport (= 7.0.8.1) + actionview (7.1.3.2) + activesupport (= 7.1.3.2) builder (~> 3.1) - erubi (~> 1.4) - rails-dom-testing (~> 2.0) - rails-html-sanitizer (~> 1.1, >= 1.2.0) + erubi (~> 1.11) + rails-dom-testing (~> 2.2) + rails-html-sanitizer (~> 1.6) active_material (1.5.2) active_skin (0.0.13) activeadmin (3.2.0) @@ -119,30 +123,35 @@ GEM xdan-datetimepicker-rails (~> 2.5.1) activeadmin_quill_editor (1.1.0) activeadmin (>= 2.0, < 4) - activejob (7.0.8.1) - activesupport (= 7.0.8.1) + activejob (7.1.3.2) + activesupport (= 7.1.3.2) globalid (>= 0.3.6) - activemodel (7.0.8.1) - activesupport (= 7.0.8.1) - activerecord (7.0.8.1) - activemodel (= 7.0.8.1) - activesupport (= 7.0.8.1) + activemodel (7.1.3.2) + activesupport (= 7.1.3.2) + activerecord (7.1.3.2) + activemodel (= 7.1.3.2) + activesupport (= 7.1.3.2) + timeout (>= 0.4.0) activerecord-import (1.5.1) activerecord (>= 4.2) - activerecord-postgis-adapter (8.0.3) - activerecord (~> 7.0.0) + activerecord-postgis-adapter (9.0.1) + activerecord (~> 7.1.0) rgeo-activerecord (~> 7.0.0) - activestorage (7.0.8.1) - actionpack (= 7.0.8.1) - activejob (= 7.0.8.1) - activerecord (= 7.0.8.1) - activesupport (= 7.0.8.1) + activestorage (7.1.3.2) + actionpack (= 7.1.3.2) + activejob (= 7.1.3.2) + activerecord (= 7.1.3.2) + activesupport (= 7.1.3.2) marcel (~> 1.0) - mini_mime (>= 1.1.0) - activesupport (7.0.8.1) + activesupport (7.1.3.2) + base64 + bigdecimal concurrent-ruby (~> 1.0, >= 1.0.2) + connection_pool (>= 2.2.5) + drb i18n (>= 1.6, < 2) minitest (>= 5.1) + mutex_m tzinfo (~> 2.0) acts_as_list (1.1.0) activerecord (>= 4.2) @@ -250,6 +259,8 @@ GEM dotenv-rails (2.8.1) dotenv (= 2.8.1) railties (>= 3.2) + drb (2.2.0) + ruby2_keywords email_spec (2.2.2) htmlentities (~> 4.3.3) launchy (~> 2.1) @@ -362,7 +373,6 @@ GEM net-smtp marcel (1.0.2) matrix (0.4.2) - method_source (1.0.0) mime-types (3.5.2) mime-types-data (~> 3.2015) mime-types-data (3.2024.0206) @@ -426,20 +436,23 @@ GEM rack (< 3) rack-test (2.1.0) rack (>= 1.3) - rails (7.0.8.1) - actioncable (= 7.0.8.1) - actionmailbox (= 7.0.8.1) - actionmailer (= 7.0.8.1) - actionpack (= 7.0.8.1) - actiontext (= 7.0.8.1) - actionview (= 7.0.8.1) - activejob (= 7.0.8.1) - activemodel (= 7.0.8.1) - activerecord (= 7.0.8.1) - activestorage (= 7.0.8.1) - activesupport (= 7.0.8.1) + rackup (1.0.0) + rack (< 3) + webrick + rails (7.1.3.2) + actioncable (= 7.1.3.2) + actionmailbox (= 7.1.3.2) + actionmailer (= 7.1.3.2) + actionpack (= 7.1.3.2) + actiontext (= 7.1.3.2) + actionview (= 7.1.3.2) + activejob (= 7.1.3.2) + activemodel (= 7.1.3.2) + activerecord (= 7.1.3.2) + activestorage (= 7.1.3.2) + activesupport (= 7.1.3.2) bundler (>= 1.15.0) - railties (= 7.0.8.1) + railties (= 7.1.3.2) rails-dom-testing (2.2.0) activesupport (>= 5.0.0) minitest @@ -452,13 +465,14 @@ GEM rails-html-sanitizer (1.6.0) loofah (~> 2.21) nokogiri (~> 1.14) - railties (7.0.8.1) - actionpack (= 7.0.8.1) - activesupport (= 7.0.8.1) - method_source + railties (7.1.3.2) + actionpack (= 7.1.3.2) + activesupport (= 7.1.3.2) + irb + rackup (>= 1.0.0) rake (>= 12.2) - thor (~> 1.0) - zeitwerk (~> 2.5) + thor (~> 1.0, >= 1.2.2) + zeitwerk (~> 2.6) rainbow (3.1.1) rake (13.1.0) ransack (4.1.1) @@ -722,7 +736,7 @@ DEPENDENCIES puma rack-cors rack-mini-profiler (~> 2.0) - rails (~> 7.0.4) + rails (~> 7.1.3) rails-erd redis-rails rgeo diff --git a/bin/docker-entrypoint b/bin/docker-entrypoint new file mode 100644 index 000000000..67ef49314 --- /dev/null +++ b/bin/docker-entrypoint @@ -0,0 +1,8 @@ +#!/bin/bash -e + +# If running the rails server then create or migrate existing database +if [ "${1}" == "./bin/rails" ] && [ "${2}" == "server" ]; then + ./bin/rails db:prepare +fi + +exec "${@}" diff --git a/bin/setup b/bin/setup index ec47b79b3..3cd5a9d78 100755 --- a/bin/setup +++ b/bin/setup @@ -5,7 +5,7 @@ require "fileutils" APP_ROOT = File.expand_path("..", __dir__) def system!(*args) - system(*args) || abort("\n== Command #{args} failed ==") + system(*args, exception: true) end FileUtils.chdir APP_ROOT do diff --git a/config/application.rb b/config/application.rb index dbb67d349..94984d021 100644 --- a/config/application.rb +++ b/config/application.rb @@ -27,15 +27,17 @@ module FtiApi class Application < Rails::Application - config.autoload_paths << Rails.root.join("lib") - config.eager_load_paths << Rails.root.join("lib") - config.load_defaults 7.0 + config.load_defaults 7.1 + # Please, add to the `ignore` list any other `lib` subdirectories that do + # not contain `.rb` files, or that should not be reloaded or eager loaded. + # Common ones are `templates`, `generators`, or `middleware`, for example. + config.autoload_lib(ignore: %w[tasks rack]) # ActiveJob config.active_job.queue_adapter = :sidekiq config.api_only = false - config.action_mailer.preview_path = "#{Rails.root}/spec/mailers/previews" + config.action_mailer.preview_paths << "#{Rails.root}/spec/mailers/previews" config.i18n.fallbacks = [I18n.default_locale] @@ -48,6 +50,7 @@ class Application < Rails::Application config.asset_host = app_url.to_s unless Rails.env.test? config.generators do |g| + g.system_tests nil g.template_engine nil g.test_framework :rspec, fixtures: true, diff --git a/config/environments/development.rb b/config/environments/development.rb index aef45a663..3aaceb0a2 100644 --- a/config/environments/development.rb +++ b/config/environments/development.rb @@ -8,7 +8,7 @@ # In the development environment your application's code is reloaded any time # it changes. This slows down response time but is perfect for development # since you don't have to restart the web server when you make code changes. - config.cache_classes = false + config.enable_reloading = true # Do not eager load code on boot. config.eager_load = false @@ -54,10 +54,13 @@ # Highlight code that triggered database queries in logs. config.active_record.verbose_query_logs = true + # Highlight code that enqueued background job in logs. + config.active_job.verbose_enqueue_logs = true + # Suppress logger output for asset requests. config.assets.quiet = true - # Raises error for missing translations + # Raises error for missing translations. # config.i18n.raise_on_missing_translations = true # Annotate rendered view with file names. @@ -65,4 +68,7 @@ # Uncomment if you wish to allow Action Cable access from any origin. # config.action_cable.disable_request_forgery_protection = true + + # Raise error when a before_action's only/except options reference missing actions + config.action_controller.raise_on_missing_callback_actions = true end diff --git a/config/environments/e2e.rb b/config/environments/e2e.rb index 208097dcb..aaa34d9b9 100644 --- a/config/environments/e2e.rb +++ b/config/environments/e2e.rb @@ -12,49 +12,53 @@ # your application in memory, allowing both threaded web servers # and those relying on copy on write to perform better. # Rake tasks automatically ignore this option for performance. - config.eager_load = true + config.enable_reloading = false # Full error reports are disabled and caching is turned on. 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). + # Ensures that a master key has been made available in ENV["RAILS_MASTER_KEY"], config/master.key, or an environment + # key such as config/credentials/production.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. + # Disable serving static files from `public/`, relying on NGINX/Apache to do so instead. config.public_file_server.enabled = ENV["RAILS_SERVE_STATIC_FILES"].present? # Compress JavaScripts and CSS. config.assets.js_compressor = Uglifier.new(harmony: true) # config.assets.css_compressor = :sass - # Do not fallback to assets pipeline if a precompiled asset is missed. + # Do not fall back to assets pipeline if a precompiled asset is missed. config.assets.compile = false # Enable serving of images, stylesheets, and JavaScripts from an asset server. # config.asset_host = "http://assets.example.com" # Specifies the header that your server uses for sending files. - # config.action_dispatch.x_sendfile_header = 'X-Sendfile' # for Apache - # config.action_dispatch.x_sendfile_header = 'X-Accel-Redirect' # for NGINX + # 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 # 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.*/ ] + # Assume all access to the app is happening through a SSL-terminating reverse proxy. + # Can be used together with config.force_ssl for Strict-Transport-Security and secure cookies. + # config.assume_ssl = true + # Force all access to the app over SSL, use Strict-Transport-Security, and use secure cookies. # config.force_ssl = true - # Include generic and useful information about system operation, but avoid logging too much - # information to avoid inadvertent exposure of personally identifiable information (PII). - config.log_level = :info - # Prepend all log lines with the following tags. config.log_tags = [:request_id] + # "info" includes 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") + # Use a different cache store in production. # config.cache_store = :mem_cache_store config.cache_store = :file_store, "#{Rails.root}/tmp/cache-e2e/" @@ -63,7 +67,7 @@ } config.public_file_server.enabled = true - # 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 = "sc_api_test_#{Rails.env}" config.action_mailer.raise_delivery_errors = false @@ -96,4 +100,12 @@ # Do not dump schema after migrations. config.active_record.dump_schema_after_migration = false + + # Enable DNS rebinding protection and other `Host` header attacks. + # config.hosts = [ + # "example.com", # Allow requests from example.com + # /.*\.example\.com/ # Allow requests from subdomains like `www.example.com` + # ] + # Skip DNS rebinding protection for the default health check endpoint. + # config.host_authorization = { exclude: ->(request) { request.path == "/up" } } end diff --git a/config/environments/production.rb b/config/environments/production.rb index 2dbedddaf..ca3623fd0 100644 --- a/config/environments/production.rb +++ b/config/environments/production.rb @@ -12,53 +12,57 @@ # your application in memory, allowing both threaded web servers # and those relying on copy on write to perform better. # Rake tasks automatically ignore this option for performance. - config.eager_load = true + config.enable_reloading = false # Full error reports are disabled and caching is turned on. 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). + # Ensures that a master key has been made available in ENV["RAILS_MASTER_KEY"], config/master.key, or an environment + # key such as config/credentials/production.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. + # Disable serving static files from `public/`, relying on NGINX/Apache to do so instead. config.public_file_server.enabled = ENV["RAILS_SERVE_STATIC_FILES"].present? # Compress JavaScripts and CSS. config.assets.js_compressor = Uglifier.new(harmony: true) # config.assets.css_compressor = :sass - # Do not fallback to assets pipeline if a precompiled asset is missed. + # Do not fall back to assets pipeline if a precompiled asset is missed. config.assets.compile = false # Enable serving of images, stylesheets, and JavaScripts from an asset server. # config.asset_host = "http://assets.example.com" # Specifies the header that your server uses for sending files. - # config.action_dispatch.x_sendfile_header = 'X-Sendfile' # for Apache - # config.action_dispatch.x_sendfile_header = 'X-Accel-Redirect' # for NGINX + # 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 # 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.*/ ] + # Assume all access to the app is happening through a SSL-terminating reverse proxy. + # Can be used together with config.force_ssl for Strict-Transport-Security and secure cookies. + # config.assume_ssl = true + # Force all access to the app over SSL, use Strict-Transport-Security, and use secure cookies. # config.force_ssl = true - # Include generic and useful information about system operation, but avoid logging too much - # information to avoid inadvertent exposure of personally identifiable information (PII). - config.log_level = :info - # Prepend all log lines with the following tags. config.log_tags = [:request_id] + # "info" includes 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") + # 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 = "sc_api_test_#{Rails.env}" config.action_mailer.perform_caching = false @@ -94,4 +98,12 @@ # Do not dump schema after migrations. config.active_record.dump_schema_after_migration = false + + # Enable DNS rebinding protection and other `Host` header attacks. + # config.hosts = [ + # "example.com", # Allow requests from example.com + # /.*\.example\.com/ # Allow requests from subdomains like `www.example.com` + # ] + # Skip DNS rebinding protection for the default health check endpoint. + # config.host_authorization = { exclude: ->(request) { request.path == "/up" } } end diff --git a/config/environments/staging.rb b/config/environments/staging.rb index 70fc1984a..7b5acbb7b 100644 --- a/config/environments/staging.rb +++ b/config/environments/staging.rb @@ -12,25 +12,24 @@ # your application in memory, allowing both threaded web servers # and those relying on copy on write to perform better. # Rake tasks automatically ignore this option for performance. - config.eager_load = true + config.enable_reloading = false # Full error reports are disabled and caching is turned on. 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). + # Ensures that a master key has been made available in ENV["RAILS_MASTER_KEY"], config/master.key, or an environment + # key such as config/credentials/production.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. + # Disable serving static files from `public/`, relying on NGINX/Apache to do so instead. config.public_file_server.enabled = ENV["RAILS_SERVE_STATIC_FILES"].present? # Compress JavaScripts and CSS. config.assets.js_compressor = Uglifier.new(harmony: true) # config.assets.css_compressor = :sass - # Do not fallback to assets pipeline if a precompiled asset is missed. + # Do not fall back to assets pipeline if a precompiled asset is missed. config.assets.compile = false # `config.assets.precompile` and `config.assets.version` have moved to config/initializers/assets.rb @@ -39,28 +38,33 @@ # config.asset_host = 'http://assets.example.com' # Specifies the header that your server uses for sending files. - # config.action_dispatch.x_sendfile_header = 'X-Sendfile' # for Apache - # config.action_dispatch.x_sendfile_header = 'X-Accel-Redirect' # for NGINX + # 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 # 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.*/ ] + # Assume all access to the app is happening through a SSL-terminating reverse proxy. + # Can be used together with config.force_ssl for Strict-Transport-Security and secure cookies. + # config.assume_ssl = true + # Force all access to the app over SSL, use Strict-Transport-Security, and use secure cookies. # config.force_ssl = true - # Include generic and useful information about system operation, but avoid logging too much - # information to avoid inadvertent exposure of personally identifiable information (PII). - config.log_level = :info - # Prepend all log lines with the following tags. config.log_tags = [:request_id] + # "info" includes 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") + # 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 = "sc_api_test_#{Rails.env}" config.action_mailer.perform_caching = false @@ -93,4 +97,12 @@ # Do not dump schema after migrations. config.active_record.dump_schema_after_migration = false + + # Enable DNS rebinding protection and other `Host` header attacks. + # config.hosts = [ + # "example.com", # Allow requests from example.com + # /.*\.example\.com/ # Allow requests from subdomains like `www.example.com` + # ] + # Skip DNS rebinding protection for the default health check endpoint. + # config.host_authorization = { exclude: ->(request) { request.path == "/up" } } end diff --git a/config/environments/test.rb b/config/environments/test.rb index d96bd657f..433d14f97 100644 --- a/config/environments/test.rb +++ b/config/environments/test.rb @@ -9,19 +9,14 @@ Rails.application.configure do # Settings specified here will take precedence over those in config/application.rb. - # Turn false under Spring and add config.action_view.cache_template_loading = true. - # config.cache_classes = true - - config.cache_classes = false + # While tests run files are not watched, reloading is not necessary. + config.enable_reloading = false config.action_view.cache_template_loading = true - # Do not eager load code on boot. This avoids loading your whole application - # just for the purpose of running a single test. If you are using a tool that - # preloads Rails for running tests, you may have to set it to true. - # Eager loading loads your whole application. When running a single test locally, - # this probably isn't necessary. It's a good idea to do in a continuous integration - # system, or in some way before deploying your code. + # this is usually not necessary, and can slow down your test suite. However, it's + # recommended that you enable it in continuous integration systems to ensure eager + # loading is working properly before deploying your code. config.eager_load = ENV["CI"].present? # Configure public file server for tests with Cache-Control for performance. @@ -35,8 +30,8 @@ config.action_controller.perform_caching = false config.cache_store = :null_store - # Raise exceptions instead of rendering exception templates. - config.action_dispatch.show_exceptions = false + # Render exception templates for rescuable exceptions and raise for other exceptions. + config.action_dispatch.show_exceptions = :rescuable # Disable request forgery protection in test environment. config.action_controller.allow_forgery_protection = false @@ -69,10 +64,11 @@ end end - # Raises error for missing translations - # config.action_view.raise_on_missing_translations = true config.active_job.queue_adapter = :test # Annotate rendered view with file names. # config.action_view.annotate_rendered_view_with_filenames = true + + # Raise error when a before_action's only/except options reference missing actions + config.action_controller.raise_on_missing_callback_actions = true end diff --git a/config/initializers/content_security_policy.rb b/config/initializers/content_security_policy.rb index 54f47cf15..b3076b38f 100644 --- a/config/initializers/content_security_policy.rb +++ b/config/initializers/content_security_policy.rb @@ -16,9 +16,9 @@ # # policy.report_uri "/csp-violation-report-endpoint" # end # -# # Generate session nonces for permitted importmap and inline scripts +# # Generate session nonces for permitted importmap, inline scripts, and inline styles. # config.content_security_policy_nonce_generator = ->(request) { request.session.id.to_s } -# config.content_security_policy_nonce_directives = %w(script-src) +# config.content_security_policy_nonce_directives = %w(script-src style-src) # # # Report violations without enforcing the policy. # # config.content_security_policy_report_only = true diff --git a/config/initializers/filter_parameter_logging.rb b/config/initializers/filter_parameter_logging.rb index ca55f952d..c2d89e28a 100644 --- a/config/initializers/filter_parameter_logging.rb +++ b/config/initializers/filter_parameter_logging.rb @@ -1,10 +1,8 @@ -# frozen_string_literal: true - # Be sure to restart your server when you modify this file. -# Configure parameters to be filtered from the log file. Use this to limit dissemination of -# sensitive information. See the ActiveSupport::ParameterFilter documentation for supported -# notations and behaviors. +# Configure parameters to be partially matched (e.g. passw matches password) and filtered from the log file. +# Use this to limit dissemination of sensitive information. +# See the ActiveSupport::ParameterFilter documentation for supported notations and behaviors. Rails.application.config.filter_parameters += [ :passw, :secret, :token, :_key, :crypt, :salt, :certificate, :otp, :ssn ] diff --git a/config/initializers/permissions_policy.rb b/config/initializers/permissions_policy.rb index 00f64d71b..7db3b9577 100644 --- a/config/initializers/permissions_policy.rb +++ b/config/initializers/permissions_policy.rb @@ -1,11 +1,13 @@ +# Be sure to restart your server when you modify this file. + # Define an application-wide HTTP permissions policy. For further -# information see https://developers.google.com/web/updates/2018/06/feature-policy -# -# Rails.application.config.permissions_policy do |f| -# f.camera :none -# f.gyroscope :none -# f.microphone :none -# f.usb :none -# f.fullscreen :self -# f.payment :self, "https://secure.example.com" +# information see: https://developers.google.com/web/updates/2018/06/feature-policy + +# Rails.application.config.permissions_policy do |policy| +# policy.camera :none +# policy.gyroscope :none +# policy.microphone :none +# policy.usb :none +# policy.fullscreen :self +# policy.payment :self, "https://secure.example.com" # end diff --git a/spec/models/observation_spec.rb b/spec/models/observation_spec.rb index f77022bd7..a9652fa16 100644 --- a/spec/models/observation_spec.rb +++ b/spec/models/observation_spec.rb @@ -39,8 +39,6 @@ require "rails_helper" -RSpec::Matchers.define_negated_matcher :have_not_enqueued_mail, :have_enqueued_mail - RSpec.describe Observation, type: :model do subject(:observation) { build(:observation) } diff --git a/spec/rails_helper.rb b/spec/rails_helper.rb index 72e91818e..37b7cda8c 100644 --- a/spec/rails_helper.rb +++ b/spec/rails_helper.rb @@ -22,6 +22,11 @@ ActiveRecord::Migration.maintain_test_schema! +# TODO: try to remove the line below the comment after some time, not sure why this still not working +# see https://github.com/rails/rails/issues/49958 +RSpec::Matchers::AliasedNegatedMatcher.undef_method(:with) +RSpec::Matchers.define_negated_matcher :have_not_enqueued_mail, :have_enqueued_mail + # Configuration for Shoulda::Matchers Shoulda::Matchers.configure do |config| config.integrate do |with| From e57278b4e8783f6e90ac5e3f16f4b9842f1a7fa7 Mon Sep 17 00:00:00 2001 From: Tomasz Subik Date: Fri, 23 Feb 2024 11:24:47 +0100 Subject: [PATCH 07/10] keep old cache format for a while --- config/application.rb | 3 +++ 1 file changed, 3 insertions(+) diff --git a/config/application.rb b/config/application.rb index 94984d021..47b767487 100644 --- a/config/application.rb +++ b/config/application.rb @@ -33,6 +33,9 @@ class Application < Rails::Application # Common ones are `templates`, `generators`, or `middleware`, for example. config.autoload_lib(ignore: %w[tasks rack]) + # TODO: remove next line later after Rails 7.1 is deployed to prod with no intention to rollback + config.active_support.cache_format_version = 7.0 + # ActiveJob config.active_job.queue_adapter = :sidekiq From e970ebacdb7ac15f99777dadf8066311369d9223 Mon Sep 17 00:00:00 2001 From: Tomasz Subik Date: Fri, 23 Feb 2024 11:40:25 +0100 Subject: [PATCH 08/10] raise error on missing translations in dev/test, fix rspec deprecations --- config/environments/development.rb | 2 +- config/environments/test.rb | 2 +- spec/rails_helper.rb | 2 +- spec/support/importer_helper.rb | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/config/environments/development.rb b/config/environments/development.rb index 3aaceb0a2..1c4fe3ed3 100644 --- a/config/environments/development.rb +++ b/config/environments/development.rb @@ -61,7 +61,7 @@ config.assets.quiet = true # Raises error for missing translations. - # config.i18n.raise_on_missing_translations = true + config.i18n.raise_on_missing_translations = true # Annotate rendered view with file names. # config.action_view.annotate_rendered_view_with_filenames = true diff --git a/config/environments/test.rb b/config/environments/test.rb index 433d14f97..985b07f16 100644 --- a/config/environments/test.rb +++ b/config/environments/test.rb @@ -54,7 +54,7 @@ config.active_support.disallowed_deprecation_warnings = [] # Raises error for missing translations - # config.i18n.raise_on_missing_translations = true + config.i18n.raise_on_missing_translations = true if ENV["BULLET"] == "enabled" config.after_initialize do diff --git a/spec/rails_helper.rb b/spec/rails_helper.rb index 37b7cda8c..eb9ddf8a9 100644 --- a/spec/rails_helper.rb +++ b/spec/rails_helper.rb @@ -58,7 +58,7 @@ config.include ImporterHelper, type: :importer config.extend APIDocsHelpers - config.fixture_path = "#{::Rails.root}/spec/fixtures" + config.fixture_paths = ["#{::Rails.root}/spec/fixtures"] config.request_snapshots_dir = "spec/fixtures/snapshots" # adding dynamic attributes for snapshots, small medium original are for active storage links diff --git a/spec/support/importer_helper.rb b/spec/support/importer_helper.rb index a472afd3f..a18324b01 100644 --- a/spec/support/importer_helper.rb +++ b/spec/support/importer_helper.rb @@ -1,7 +1,7 @@ module ImporterHelper def fixture_file_upload(path, mime_type = nil, binary = false) unless File.exist?(path) - path = File.join(self.class.fixture_path, "data_import", path) unless File.exist?(path) + path = File.join(self.class.fixture_paths.first, "data_import", path) unless File.exist?(path) end Rack::Test::UploadedFile.new(path, mime_type, binary) From 6a5da19f17a4dd35d5a92c54bcc043716a9d005c Mon Sep 17 00:00:00 2001 From: Tomasz Subik Date: Fri, 23 Feb 2024 12:20:57 +0100 Subject: [PATCH 09/10] raise errors in local env when checking old versions --- app/controllers/concerns/versionable.rb | 1 + 1 file changed, 1 insertion(+) diff --git a/app/controllers/concerns/versionable.rb b/app/controllers/concerns/versionable.rb index fdb09f578..b43075843 100644 --- a/app/controllers/concerns/versionable.rb +++ b/app/controllers/concerns/versionable.rb @@ -15,6 +15,7 @@ def show resource = @versions[params[:version].to_i].reify if params[:version] rescue => e Sentry.capture_exception e + raise if Rails.env.local? end # not sure why sometimes id is nil after reify resource.id = current.id if resource.id.nil? From d70131ac08595c6316ed8a8c46b0368acce1a5c0 Mon Sep 17 00:00:00 2001 From: Tomasz Subik Date: Fri, 23 Feb 2024 12:37:11 +0100 Subject: [PATCH 10/10] upgrade paper_trail --- Gemfile | 2 +- Gemfile.lock | 28 ++++++++++++++-------------- config/initializers/paper_trail.rb | 11 +++++++++++ 3 files changed, 26 insertions(+), 15 deletions(-) diff --git a/Gemfile b/Gemfile index 79d578bdd..4f1ae0148 100644 --- a/Gemfile +++ b/Gemfile @@ -86,7 +86,7 @@ gem "sendgrid-actionmailer" gem "rubyzip", "~> 2.3.0" # Changes monitoring -gem "globalize-versioning", github: "globalize/globalize-versioning", branch: "main" +gem "globalize-versioning", github: "tsubik/globalize-versioning", branch: "custom" gem "paper_trail" # Interactors diff --git a/Gemfile.lock b/Gemfile.lock index 873888911..2dc6a101d 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -5,17 +5,6 @@ GIT active_admin_sidebar (2.0.0) activeadmin -GIT - remote: https://github.com/globalize/globalize-versioning.git - revision: 5d92ddbf838e2bffc4c1229cab02b34bb96ad46f - branch: main - specs: - globalize-versioning (0.5.0) - activemodel (>= 4.2.0, < 8.0) - activerecord (>= 4.2.0, < 8.0) - globalize (>= 5.1.0, < 7) - paper_trail (>= 8, < 13) - GIT remote: https://github.com/tsubik/active_admin_paranoia.git revision: 3f3fd26962ae4d8aee139a3b8f7256e2d1d340dc @@ -33,6 +22,17 @@ GIT activeadmin (>= 1.0, < 4.0) globalize (>= 3.1.0, <= 6.3) +GIT + remote: https://github.com/tsubik/globalize-versioning.git + revision: 7b13908044e79fa975155bb1b4941fdeffd6682b + branch: custom + specs: + globalize-versioning (0.5.0) + activemodel (>= 4.2.0, < 8.0) + activerecord (>= 4.2.0, < 8.0) + globalize (>= 5.1.0, < 7) + paper_trail (>= 8, < 16) + GIT remote: https://github.com/tsubik/rspec-request_snapshot.git revision: 86775ed811110a71df75605440ca41deae07cf26 @@ -409,9 +409,9 @@ GEM oj_mimic_json (1.0.1) optimist (3.1.0) orm_adapter (0.5.0) - paper_trail (12.3.0) - activerecord (>= 5.2) - request_store (~> 1.1) + paper_trail (15.1.0) + activerecord (>= 6.1) + request_store (~> 1.4) parallel (1.24.0) paranoia (2.6.3) activerecord (>= 5.1, < 7.2) diff --git a/config/initializers/paper_trail.rb b/config/initializers/paper_trail.rb index 0579225d5..393c25df3 100644 --- a/config/initializers/paper_trail.rb +++ b/config/initializers/paper_trail.rb @@ -6,3 +6,14 @@ on: %i[create update destroy] } PaperTrail.config.version_limit = nil + +# TODO: switch to jsonb columns instead of text columns and yaml serialization +::ActiveRecord.yaml_column_permitted_classes = [ + ::ActiveRecord::Type::Time::Value, + ::ActiveSupport::TimeWithZone, + ::ActiveSupport::TimeZone, + ::BigDecimal, + ::Date, + ::Symbol, + ::Time +]